使用“標準”操作實現恆定時間(無表)AES 的已知方法?
有幾種已知的方法可以使用 SIMD 操作在恆定時間內實現 AES,主要基於快速字節混洗(例如Hamburg和Kasper/Schwabe)。是否有任何類似的方法允許僅使用標準 C 操作來實現恆定時間 AES?我見過的最接近的是這種面向字節的AES 實現,但它使用與輸入相關的循環來計算 sbox 的對數和指數。
一般來說,查找表可以通過將其視為硬體電路來在恆定時間內實現。
考慮一個多路復用器:這是一個接受三個輸入的電路 $ a $ , $ b $ 和 $ c $ ,並產生一個輸出 $ d $ 這等於 $ a $ 如果 $ c = 0 $ , 到 $ b $ 否則(我在這裡談論的是單位值)。多路復用器可用於實現一個 $ 1\rightarrow1 $ 查找表:設置 $ a $ 為“0”輸入的表的值, $ b $ 為“1”輸入的值,並設置 $ c $ 到您要轉換的實際輸入。
如果將單個位值儲存在變數中,則相應的 C 程式碼如下所示:
d = (a & ~c) | (b & c);
它具有恆定的執行時間。
如果你知道如何實施 $ n\rightarrow1 $ 具有恆定時間程式碼的查找表,a $ n+1\rightarrow1 $ 查找表是通過隔離最後一位獲得的:您考慮這兩個 $ n\rightarrow1 $ 子表,第一個是通過將最後一位分別設置為 0 或 1 獲得的表。然後你使用這兩個子表的輸出作為 $ a $ 和 $ b $ 由最後一個輸入位控制的額外多路復用器的輸入。這意味著一個 $ n+1\rightarrow1 $ 表只是一對 $ n\rightarrow1 $ 表和額外的位,它決定了我們實際談論的兩個表中的哪一個。
有了這種結構, $ 8\rightarrow1 $ table 可以實現為 255 個多路復用器的樹,如上面的那個。AES S-box 是一個 $ 8\rightarrow8 $ 表,並在每輪並行應用於 16 個值,因此您最終不得不評估 $ 128\times255 $ 每輪多路復用器。
但是,使用上面的 C 程式碼,您實際上是在並行計算*多個多路復用器。*如果 C 變數是 64 位值,那麼您同時執行 64 個多路復用器:索引 0 的位與索引 0 的其他位通信,索引 1 上的位與索引 1 的位,依此類推,直到索引 63 的位. 這稱為位切片。由於 AES 中結構的相似性,您可以使用它來減少多路復用器評估的數量 $ 4\times 255 $ 每輪:僅僅一千……
使用這些技術,您最終可以得到一個恆定時間的純 C AES 實現,它應該在 20000 個時鐘週期內評估一個塊。這非常慢,但仍然可行。然而,這僅僅是開始。有許多優化可以應用於這種結構(例如,您可以用不完全是多路復用器的結構“
a ^ (b & c)
”替換多路復用器,它在 $ a $ 和 $ a \oplus b $ ( $ a $ 自由 $ b $ ),並且足以實現查找表;此外,樹中的第一行多路復用器通常可以折疊,因為它的輸入是已知值 0 或 1)。對於 DES S 盒(八個不同的 $ 6\rightarrow4 $ 表),非常優化的位切片實現是由Matthew Kwan在 1998 年設計的。此外,AES S-box 具有內部代數結構,可能可以進一步利用。Google搜尋“bitslice implementation AES”連結到一些研究論文,但顯然沒有一個可以公開下載。