AES-Rijndael有限域(Galois Field)GF(2^8)運算的介紹與實現(PHP版)
阿新 • • 發佈:2022-04-21
1.前言
最近做微信小程式開發,小程式裡面對敏感資料的加密採用了 AES -128-CBC的對稱加密方式。所以想寫一篇介紹AES-Rijndael演算法的文章,此篇文章為AES作鋪墊,因為它的列混淆演算法的運算操作用到了有限域的概念。
2.有限域的介紹
Galois Field 在國內有兩個翻譯別名:伽羅華域、伽羅瓦域(我也不知道為什麼沒能統一一個翻譯)。在數學中,有限域是一個包含有限元素的域。通過GF(2^M)來表示域中含有2^M個元素。每一個域中有多個本原多項式,當M=8時,常見的本原多項式為P(x)=x^8+x^4+x^3+x^2+1,AES中的本原多項式為不可約多項式(irreducible polynomial):P(x)=x^8+x^4+x^3+x^1+1。
3. 有限域的加法與乘法運算
有限域中的運算方式需要先把數值轉化成多項式的形式,然後再進行相關運算。其中加法操作可以直接進行運算。 加法:計算機異或運算 加法例子:4+3 展開多項式為: x^2 + (x^1 + x^0) => 2^2 + 2^1 + 1 => 4 + 2 + 1 => 4 ^ 2 ^ 1 = 7 直接計算:4^3 = 7 乘法:通過乘法結合律展開多項式,如果x的最高指數大於7,那麼需要對本原多項式取餘數(初二多項式除法運算),否則就是展開後的多項式做加法操作。 取餘操作有一個演算法,參考《密碼編碼學與網路安全學原理》一書中提到的公式: 已知GF(2^8)最長的多項式f(x)=b7*x^7+b6*x^6+b5*x^5+b4*x^4+b3*x^3+b2*x^2+b1*x^1+b0*x^0 x*f(x)= b7*x^8+b6*x^7+b5*x^6+b4*x^5+b3*x^4+b2*x^3+b1*x^2+b0*x^1 x*f(x)的情況如下: 當b7=0時,最高指數為7不需要取餘,直接做異或加法運算。 當b7=1時,最高指數為8,大於7,則需要取m(x)的餘數,推導如下: f(x) = ( b7*x^8+b6*x^7+b5*x^6+b4*x^5+b3*x^4+b2*x^3+b1*x^2+b0*x^1 )mod m(x); 這裡有另外一個等式:x^8 mod m(x) = [m(x) – x^8] = (x^4 + x^3 + x + 1) 所以根據上面的等式可以化簡f(x) = b6*x^7+b5*x^6+b4*x^5+b3*x^4+b2*x^3+b1*x^2+b0*x^1 + x^4 + x^3 + x +1 而x^4 + x^3 + x + 1 就是十六程序的0x1B(因為2^4+2^3+2+1=27),因此本原多項式取餘的操作就等價於 異或本原多項式。公式如下: 圖片來源: 《密碼編碼學與網路安全學原理》 第88頁 高階的x可以重複使用這個公式,在程式實現部分會詳細介紹下。 乘法例子:7*4 展開多項式為:(x^2+x^1+x^0)*(x^2) => x^4 + x^2 + x^2 => 2^4 + 2^2 + 2^2 = 16 ^ 4 ^ 4 = 16 乘法例子:130*3 展開多項式為:(x^7+x^1)*(x^1+x^0) => x^8 + x^7 + x^1 + x^1 => x^8 + x^7 +( x^8+x^4+x^3+x^1+x^0 ) ( 不可約多項式 ) => x^7 + x^4+x^3+x^1+x^0 => 2^7 + 2^4 + 2^3 + 2^1 + 1 = 128 ^ 16 ^ 8 ^ 2 ^ 1 = 1554. 程式的實現
4.1 PHP實現AES列混合有限域乘積計算
PHP實現AES列混合有限域乘積計算
function aes_multi($a, $b = 0)
{
if ($a >= 2 ** 8 || 2 ** 8 <= $b) {
exit('只支援GF(2^8)域的計算');
}
$binMulti = [];
$result = 0;
for ($i = 0; $i < 8; $i++) {
$a = ($a & 0x100) ? (($a & 0xFF) ^ 0x1B) : $a;
$binMulti[] = $a;
$a = $a << 1;
}
$binString = str_pad(base_convert($b, 10, 2), 8, 0, STR_PAD_LEFT);
for ($i = 0; $i < 8; $i++) {
if ($binString{$i} === '1') {
$pos = strlen(substr($binString, $i)) - 1;
$result ^= $binMulti[$pos];
}
}
return $result;
}
var_dump(aes_multi(0x57, 0x13));
5.參考
官方文件 https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf