Figure 6 對 State 進行 ShiftRows 操作
MixColumns 是一個代替操作,它是理解 AES 算法時最具技巧(或者說是最需要動腦筋的部分)的部分。它用 State 字節列的值進行數學域加和域乘的結果代替每個字節。我將在下一節中 詳細解釋專門的域加和域乘細節。
假設 State[0,1]的值是0x09,並且列1上的其它值分別為0x60,0xe1和0x04,那麼State[0,1]的新值計算如下:
State[0,1] = (State[0,1] * 0x01) + (State[1,1] * 0x02) +(State[2,1] * 0x03) +(State[3,1] * 0x01)
= (0x09 * 0x01) + (0x60 * 0x02) + (0xe1 * 0x03) +(0x04 * 0x01)
= 0x57
此處加法和乘法是專門的數學域操作,而不是平常整數的加法和乘法。
SubBytes、ShiftRows、MixColumns和AddRoundKey 四個操作在一個執行 Nr 次的循環裡被調用,Nr 為給定密鑰大小的輪數減 1。加密算法使用的輪數要麼是10,12,要麼是14,這依賴於種子密鑰長度是128位、192 位還是 256 位。在這個例子中,因為Nr 等於12, 則這四個操作被調用11次。該迭代完成後,在拷貝 State 矩陣到輸出參數前,加密算法調用 SubBytes、ShiftRows和AddRoundKey 後結束。
大致說來,AES 加密算法的核心有四個操作。AddRoundKey 使用從種子密鑰值中生成的輪密鑰代替 4 組字節。SubBytes 替換用一個代替表 替換單個字節。ShiftRows 通過旋轉 4字節行的 4 組字節進行序列置換。MixColumns 用域加和域乘的組合來替換字節。
有限域GF(28)的加法和乘法
正如你所看到的,AES 加密算法使用相當簡單明了的技術來代替和置換,除 MixColumns 例程以外。MixColumns 使用特殊的加法和乘法。AES 所用的加法和乘法是基於數學(譯者注:近世代數)的域論。尤其是 AES 基於有限域GF(28)。
GF(28)由一組從 0x00 到 0xff的256個值組成,加上加法和乘法,因此是(28)。GF代表伽羅瓦域,以發明這一理論的數學家的名字命名。GF(28)的一個特性是一個加法或乘法的操作的結果必須是在{0x00 ... 0xff}這組數中。雖然域論是相當深奧的,但GF(28)加法的最終結果卻很簡單。GF(28) 加法就是異或(XOR)操作。
然而,GF(28)的乘法有點繁難。正如你稍後將在C# 實現中所看到的,AES的加密和解密例程需要知道怎樣只用七個常量 0x01、0x02、0x03、0x09、0x0b、0x0d和0x0e 來相乘。所以我不全面介紹GF(28)的乘法,而只是針對這七種特殊情況進行說明。
在GF(28)中用0x01的乘法是特殊的;它相當於普通算術中用1做乘法並且結果也同樣—任何值乘0x01等於其自身。
現在讓我們看看用0x02做乘法。和加法的情況相同,理論是深奧的,但最終結果十分簡單。只要被乘的值小於0x80,這時乘法的結果就是該值左移1比特位。如果被乘的值大於或等於0x80,這時乘法的結果就是左移1比特位再用值0x1b異或。它防止了“域溢出”並保持乘法的乘積在范圍以內。
一旦你在GF(28)中用0x02建立了加法和乘法,你就可以用任何常量去定義乘法。用0x03做乘法時,你可以將 0x03 分解為2的冪之和。為了用 0x03 乘以任意字節b, 因為0x03 = 0x02 + 0x01,因此:
b * 0x03 = b * (0x02 + 0x01)
= (b * 0x02) + (b * 0x01)
這是可以行得通的,因為你知道如何用 0x02和0x01 相乘和相加,同哩,用0x0d去乘以任意字節b可以這樣做:
b * 0x0d = b * (0x08 + 0x04 + 0x01)
= (b * 0x08) + (b * 0x04) + (b * 0x01)
= (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01)
在加解密算法中,AES MixColumns 例程的其它乘法遵循大體相同的模式,如下所示:
b * 0x09 = b * (0x08 + 0x01)
= (b * 0x02 * 0x02 * 0x02) + (b * 0x01)
b * 0x0b = b * (0x08 + 0x02 + 0x01)
= (b * 0x02 * 0x02 * 0x02) + (b * 0x02) + (b * 0x01)
b * 0x0e = b * (0x08 + 0x04 + 0x02)
= (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x02)
總之,在GF(28)中,加法是異或操作。其乘法將分解成加法和用0x02做的乘法,而用0x02做的乘法是一個有條件的左移1比特位。AES規范中包括大量 有關GF(28)操作的附加信息。