日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 有限域函数库_有限域GF(2^8)内乘法代码实现以及原理

發布時間:2023/12/10 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)内乘法代码实现以及原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。