python 有限域函数库_有限域GF(2^8)内乘法代码实现以及原理
在密碼學中經常用到有限域的乘法,一般在AES中用到的是GF(2^8)有限域內乘法。什么是有限域呢?有限域通俗的講就是函數的運算結果全都包含在一個域中,不同于實數域,有限域有一個最大值,所有超過這個最大值的數都會經過一定的方法使他回到這個域中,在密碼學中應用很廣泛,2^8意味著這個域的最大值是256.
以下代碼是GF(2^8)有限域內乘法的C代碼實現:
unsignedcharXTIME(unsignedcharx)?{
return((x?<
}
unsigned?charmultiply(unsignedchara,?unsignedcharb)?{
unsigned?chartemp[8]?=?{?a?};
unsigned?chartempmultiply?=?0x00;
inti?=?0;
for(i?=?1;?i?
temp[i]?=?XTIME(temp[i?-?1]);
}
tempmultiply?=?(b?&?0x01)?*?a;
for(i?=?1;?i?<=?7;?i++)?{
tempmultiply?^=?(((b?>>?i)?&?0x01)?*?temp[i]);
}
returntempmultiply;
}
以下講一下乘法的原理:
在二進制中,所有的數都能用0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80異或得到,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80的二進制表示如下:
后一個分別是前一個的2倍。假設任意一個數a,他的二進制表示為10101101,可以由以下組合組成:
而任何一個數x和a相乘都可以表示為
所以只要計算出
一切乘法的結果都可以得到。
XTIME函數的含義是求一個數x與0x02的乘積,一般求一個數的2倍,都是作移一位,在有限域內,要計算有限域的乘法,必須先確定一個GF上的8次不可約多項式,Rijndael密碼中,這個多項式確定為x^8+x^4+x^3+x+1,如果最高位是1的話,左移一位的同時要異或0x1B,是因為最高位是1的話,再繼續左移會超出域的最大值,這個時候需要取除以同余式,也就是異或0x1B。
for(i?=?1;?i?
temp[i]?=?XTIME(temp[i?-?1]);
}
經過這個循環可以得到一串包含8個字符的數組,分別是0x01*x,0x02*x,0x04*x,0x08*x,0x10*x,0x20*x,0x40*x,,0x80*x,放在temp這個數組內。接下來通過這個循環
for(i?=?1;?i?<=?7;?i++)?{
tempmultiply?^=?(((b?>>?i)?&?0x01)?*?temp[i]);
}
另一個乘數b右移一位和0x01與運算,分別和這8個字符相乘,再把相乘的結果異或。就得到了a和b相乘的結果。
接下來舉個例子:
求0x3a*0x24?
首先0x3a=00111010,分別求
0x24=00100100,所以0x3a*0x24=0x3a*00100100=0x04*0x3a^0x20*0x3a=0xe8^0x01=0xe9.
是正確結果。
如果要提高算法的計算效率,還可以這么做。
如果一個乘數的二進制可以表示為
一個乘數表示為
那么a的倍數關系可表示為:
那么他的乘積可以表示為
其中
所以乘法可以表示為
所以還有一種計算方法,那就是按照上面這個矩陣乘法。
#include?
#include?
#include?
voidprint_bit(bool*hexbit,intlen)?{
inti?=?0;
for(i?=?0;?i?
printf("%x?",?hexbit[i]);
}
}
voidprint_matrix(boolmatrix[8][8])?{
inti?=?0;
for(i?=?0;?i?
print_bit(matrix[i],?8);
printf("\n");
}
}
voidconvertto_bit(unsignedcharcipher,bool*hexbit,intlen)?{
len?=?8;
inti?=?0;
for(i?=?0;?i?
if(cipher?&?0x80)?{
hexbit[i]?=?true;
}
cipher?=?cipher?<
}
}
voidconvertto_matrix(boolhexbit[8],boolmatrix[8][8])?{
matrix[0][0]?=?hexbit[0];
matrix[0][1]?=?hexbit[1];
matrix[0][2]?=?hexbit[2];
matrix[0][3]?=?hexbit[3];
matrix[0][4]?=?hexbit[0]?^?hexbit[4];
matrix[0][5]?=?hexbit[0]?^?hexbit[1]?^?hexbit[5];
matrix[0][6]?=?hexbit[1]?^?hexbit[2]?^?hexbit[6];
matrix[0][7]?=?hexbit[0]?^?hexbit[2]?^?hexbit[3]?^?hexbit[7];
matrix[1][0]?=?hexbit[1];
matrix[1][1]?=?hexbit[2];
matrix[1][2]?=?hexbit[3];
matrix[1][3]?=?matrix[0][4];
matrix[1][4]?=?matrix[0][5];
matrix[1][5]?=?matrix[0][6];
matrix[1][6]?=?hexbit[0]?^?hexbit[2]?^?hexbit[3]?^?hexbit[7];
matrix[1][7]?=?hexbit[1]?^?hexbit[3]?^?hexbit[4];
matrix[2][0]?=?hexbit[2];
matrix[2][1]?=?hexbit[3];
matrix[2][2]?=?matrix[1][3];
matrix[2][3]?=?matrix[1][4];
matrix[2][4]?=?matrix[1][5];
matrix[2][5]?=?matrix[1][6];
matrix[2][6]?=?matrix[1][7];
matrix[2][7]?=?hexbit[2]?^?hexbit[4]?^?hexbit[5];
matrix[3][0]?=?hexbit[3];
matrix[3][1]?=?matrix[2][2];
matrix[3][2]?=?matrix[2][3];
matrix[3][3]?=?matrix[2][4];
matrix[3][4]?=?matrix[2][5];
matrix[3][5]?=?matrix[2][6];
matrix[3][6]?=?matrix[2][7];
matrix[3][7]?=?hexbit[0]?^?hexbit[3]?^?hexbit[5]?^?hexbit[6];
matrix[4][0]?=?hexbit[4];
matrix[4][1]?=?hexbit[0]?^?hexbit[5];
matrix[4][2]?=?hexbit[1]?^?hexbit[6];
matrix[4][3]?=?hexbit[0]?^?hexbit[2]?^?hexbit[7];
matrix[4][4]?=?hexbit[0]?^?hexbit[1]?^?hexbit[3];
matrix[4][5]?=?hexbit[0]?^?hexbit[1]?^?hexbit[2]?^?hexbit[4];
matrix[4][6]?=?hexbit[0]?^?hexbit[1]?^?hexbit[2]?^?hexbit[3]?^?hexbit[5];
matrix[4][7]?=?hexbit[0]?^?hexbit[1]?^?hexbit[2]?^?hexbit[3]?^?hexbit[4]
^?hexbit[6];
matrix[5][0]?=?hexbit[5];
matrix[5][1]?=?hexbit[6];
matrix[5][2]?=?hexbit[0]?^?hexbit[7];
matrix[5][3]?=?hexbit[0]?^?hexbit[1];
matrix[5][4]?=?hexbit[1]?^?hexbit[2];
matrix[5][5]?=?hexbit[2]?^?hexbit[3];
matrix[5][6]?=?hexbit[0]?^?hexbit[3]?^?hexbit[4];
matrix[5][7]?=?hexbit[1]?^?hexbit[4]?^?hexbit[5];
matrix[6][0]?=?hexbit[6];
matrix[6][1]?=?matrix[5][2];
matrix[6][2]?=?matrix[5][3];
matrix[6][3]?=?matrix[5][4];
matrix[6][4]?=?matrix[5][5];
matrix[6][5]?=?matrix[5][6];
matrix[6][6]?=?matrix[5][7];
matrix[6][7]?=?hexbit[0]?^?hexbit[2]?^?hexbit[5]?^?hexbit[6];
matrix[7][0]?=?hexbit[7];
matrix[7][1]?=?hexbit[0];
matrix[7][2]?=?hexbit[1];
matrix[7][3]?=?hexbit[2];
matrix[7][4]?=?hexbit[3];
matrix[7][5]?=?matrix[2][2];
matrix[7][6]?=?matrix[2][3];
matrix[7][7]?=?matrix[2][4];
return;
}
unsigned?charXTIME(unsignedcharx)?{
return((x?<
}
unsigned?charmultiply(unsignedchara,?unsignedcharb)?{
unsigned?chartemp[8]?=?{?a?};
unsigned?chartempmultiply?=?0x00;
inti?=?0;
for(i?=?1;?i?
temp[i]?=?XTIME(temp[i?-?1]);
}
tempmultiply?=?(b?&?0x01)?*?a;
for(i?=?1;?i?<=?7;?i++)?{
tempmultiply?^=?(((b?>>?i)?&?0x01)?*?temp[i]);
}
returntempmultiply;
}
unsigned?charmultiply_bit(unsignedcharplaintext,?unsignedcharkey)?{
intret_len?=?0;
boolplaintext_hexbit[8]?=?{false,false,false,false,false,false,
false,false};
boolkey_hexbit[8]?=?{false,false,false,false,false,false,false,
false};
boolcipher_hexbit[8]?=?{false,false,false,false,false,false,false,
false};
//把plaintext轉換成二進制
convertto_bit(plaintext,?plaintext_hexbit,?ret_len);
boolmatrix[8][8]?=?{?};
convertto_matrix(plaintext_hexbit,?matrix);
//把key轉換成二進制
convertto_bit(key,?key_hexbit,?ret_len);
//print_matrix(matrix);
//printf("\n");
//print_bit(key_hexbit,?sizeof(key_hexbit));
//printf("\n");
inti?=?0;
intj?=?0;
for(i?=?0;?i?
cipher_hexbit[i]?=?false;
for(j?=?0;j?
if(key_hexbit[j]){
cipher_hexbit[i]?^=matrix[i][7-j];
}
}
}
//print_bit(cipher_hexbit,?sizeof(cipher_hexbit));
unsigned?charoutcome?=?0;
for(i?=?0;?i?
if(cipher_hexbit[i])?{
outcome?^=?0x01?<
}
}
returnoutcome;
}
intmain(intargc,char*?argv[])?{
unsigned?charplaintext?=?0x49;
unsigned?charkey?=?0x24;
printf("%#x",?multiply_bit(plaintext,?key));
printf("\n");
//??unsigned?char?plaintext1?=?0x01;
//??unsigned?char?key1?=?0x21;
printf("%#x",?multiply(plaintext,?key));
return0;
}
輸出結果是
結果一樣,是正確的
經過測試,后一種方法比第一種方法效率慢很多,原因是其中代碼計算矩陣和矩陣乘法比第一種方法復雜。但是第二種提供另外一種思路。
轉載出處:http://blog.csdn.net/bupt073114/article/details/27382533
總結
以上是生活随笔為你收集整理的python 有限域函数库_有限域GF(2^8)内乘法代码实现以及原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: useGeneratedKeys的用法
- 下一篇: 几个python小程序