為什麼最後一輪 AES 中省略了 MixColumns?
AES(和 Rijndael)的所有輪次都有一個 MixColumns 步驟,保存最後一輪省略它。DES 有一個相似的特點,最後一輪略有不同。如果我沒記錯的話,其基本原理是“使密碼反向看起來與正向相似”。
為什麼這會使 AES $ ^{-1} $ 看起來類似於 AES?這對實現分組密碼有何幫助?
昨天剛從圖書館拿了Rijndael 的設計,我也看了這個問題。Fixee 在評論中寫道:
但是,我的問題不在於安全隱患,而在於“遺漏 MixColumns 如何使逆密碼與密碼相似?” 和“這對實現密碼有何幫助?”
加密在每一輪中都有這些步驟(列表 3.2,第 34 頁),在開始時有一個額外的 AddRoundKey,在結束時有一個較短的輪:
Round(State, ExpandedKey[i]) { SubBytes(State); ShiftRows(State); MixColumns(State); AddRoundKey(State, ExpandedKey[i]); }
解密看起來是這樣的,當以簡單的方式完成時(列表 3.5,第 47 頁)(初始回合較短):
InvRound(State, ExpandedKey[i]) { AddRoundKey(State, ExpandedKey[i]); InvMixColumns(State); InvShiftRows(State); InvSubBytes(State); }
正如評論中提到的,如果沒有省略一個 MixColumns 步驟,所有 10 輪將是相同的(如上面的那些),我們可以將總加密和解密作為
AddRoundKey(ExpandedKey[0]) for i = 1 .. 10: Round(State, ExpandedKey[i]) for i = 10 .. 1: InvRound(State, ExpandedKey[i]) AddRoundKey(ExpandedKey[0])
如果我們將 AddRoundKey 移到反函式的末尾,它看起來像這樣:
InvRound'(State, ExpandedKey[i]) { InvMixColumns(State); InvShiftRows(State); InvSubBytes(State); AddRoundKey(State, ExpandedKey[i]); } AddRoundKey(ExpandedKey[10]) for i = 9 .. 0: InvRound'(State, ExpandedKey[i])
在這種形式下,我們將有類似的加密和函式的全域結構,但加密和解密的輪函式在結構上仍然不同。我們(作為 Rijndael 的假設再發明者)可以做得更好。
回到我們的(幼稚的)反圓函式:
InvRound(State, ExpandedKey[i]) { AddRoundKey(State, ExpandedKey[i]); InvMixColumns(State); InvShiftRows(State); InvSubBytes(State); }
通過用修改後的 ExpandedKey 交換 InvMixColumns 和 AddRoundKey 並交換 InvShiftRows 和 InvSubBytes (因為其中一個單獨處理每個字節,另一個只轉置整個字節),我們看到這等效於這個:
InvRound(State, ExpandedKey[i]) { InvMixColumns(State); AddRoundKey(State, InvMixColumns(ExpandedKey[i])); InvSubBytes(State); InvShiftRows(State); }
(我們在開始時仍然有一個較短的組,最後是一個 AddRoundKey。)
現在,通過使用在回合結束時同時使用
InvMixColums
和的分組,我們將交換with的位置並交換 with 的位置,以得到這個等效的描述(列表 3.8,第 49 頁),最後一輪更短,和一個初始:AddRoundKey``InvSubBytes``InvShiftRows``InvMixColumns``AddRoundKey``AddRoundKey
EqRound (State, EqExpandedKey[i]) { InvSubBytes(State); InvShiftRows(State); InvMixColumns(State); AddRoundKey(State, EqExpandedKey[i]); }
但就目前而言,這個輪結構與初始 相結合
AddRoundKey
,並不是加密的逆。MixColumns
加密的最後一個沒有對應關係,解密InvMixColumns
的最後一個也沒有對應關係。我們將通過省略最後一輪加密的步驟和最後一輪解密的步驟來解決這個問題。隨著這一變化,由於加密和解密都省略了最後一輪的/步驟,所以它們的輪結構保持不變,解密是加密的逆過程。InvMixColumns``MixColumns``MixColumns``InvMixColums``MixColumns``InvMixColumns
這種替換、行移位和列混合(按此順序)的組合看起來與加密的操作序列非常相似,並且現在假設比直接反轉中使用的逆序列更有效地實現。
此外,我們可以共享一些程式碼(用於軟體實現)或晶片面積(用於硬體實現)用於加密和解密。
當然,我們現在需要對解密的密鑰調度進行調整:對每個輪密鑰應用 InvMixColumns,而不是第一個和最後一個。由於許多塊的密鑰調度只執行一次,這不是很大的成本。
在具有一些快速記憶體(或 ROM)的 32 位(或更大)處理器上,可以通過查找來實現每個 32 位列的替換、行移位和列混合(獨立於任何鍵)序列四個 1kB 查找表中的四個 32 位值(取決於舊狀態中的不同字節)並將它們異或在一起。通過在查找後使用不同的旋轉,我們可以只使用其中一個表 (1 kB)。(詳細資訊在本書第 58/59 頁的第 4.2 節中。)該表格的一部分也可用於最後一輪(沒有列混合)。
在這裡,我們可以使用具有不同(組)表的相同程式碼進行解密和加密。(這些表不會隨著不同的鍵而改變,所以我們把它們放在 ROM 中,或者在第一次需要時計算它們。)
(如果這些查找表不完全適合處理器記憶體,和/或被同時執行的其他程序從記憶體中刪除,則這些查找表為定時攻擊開闢了道路。)