GF(28)的乘法运算

#include <stdio.h>

unsigned char XTIME(unsigned char x) {
	return ((x << 1) ^ ((x & 0x80) ? 0x1b : 0x00));
}
unsigned char multiply(unsigned char a, unsigned char b) {
	unsigned char temp[8] = { a };
	unsigned char tempmultiply = 0x00;
	int i = 0;
	for (i = 1; i < 8; i++) {
		temp[i] = XTIME(temp[i - 1]);
	}
	tempmultiply = (b & 0x01) * a;
	for (i = 1; i <= 7; i++) {
		tempmultiply ^= (((b >> i) & 0x01) * temp[i]);
	}
	return tempmultiply;
}

int main()
{
    unsigned char a = 0x57;
    unsigned char b = 0x83;
    printf("%d", multiply(a,b));   //结果是193
}

 

以下讲一下乘法的原理:

          在二进制中,所有的数都能用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 < 8; 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=0x20^0x04

所以0x3a*0x24=0x3a*00100100=0x04*0x3a^0x20*0x3a=0xe8^0x01=0xe9.
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值