ComSec作业二: AES

ComSec作业二: AES

1、描述AES中S-Box的生成过程。

(1)初始化s-box。用两个十六进制数表示为xy,x为行数,y为列数(从第0行第0列开始)
(2)将s-box中的值映射成其乘法逆元。
(3)R(b_i) = b_i ⊕ b_[(i+4) mod 8] ⊕ b_[(i+5) mod 8] ⊕ b_[(i+6) mod 8] ⊕ b_[(i+7) mod 8] ⊕ c_i
其中c_i为固定字节{63}的第i位。

2、证明公式6.9与公式6.4等价。

在这里插入图片描述在这里插入图片描述
由6.9式:s0,j=s0,j⊕s0,j⊕s1,j⊕s2,j⊕s3,j⊕[2·(s0,j⊕s1,j)]
=s1,j⊕s2,j⊕s3,j⊕[2·(s0,j⊕s1,j)]
=2·s0,j+3·s1,j⊕s2,j⊕s3,j
其它行道理亦然。

3、写一个GF(28) 的乘法函数Mul,输入GF(28)的两个元素a、b,输出a * b 。提示:回忆CINTA的Simple Multiplication。

#include<iostream>
using namespace std;
//乘2
unsigned char cheng2(unsigned char x)
{
	bool maxWei = false;;//最高位是否为1
	if (x >> 7)maxWei = true;
	x = x << 1;
	if (maxWei)
	x = x ^ 0x1b;
	return x;
}

unsigned char mutiply(unsigned char a, unsigned char b)
{
	unsigned char c = 0x0,temp=int(a);
	//cout <<"temp:"<< int(temp) << endl;
	//a不变,拆b
	for (int i = 0; i < 8; i++)
	{
		//查看该位上是否是1,如果是一,经过该变换,if语句为true,否则为false
		int num = int(((b >> i) << 7));
		while (num >= 256)num -= 256;
		if (unsigned char(num))//
			c =c^ temp;
 		temp = cheng2(temp);
	}
	return c;
}

原理比较简单,对于a*b,将b的二进制诸位拆分分别与a相乘(即左移),如果有溢出(最高位位 1),则还要异或0x1b,最后将结果相加即可

4、写一个程序,生成AES算法中的S-Box。

#include<iostream>
#include<iomanip>
#include<bitset>
using namespace std;

unsigned char sBox[16][16];
//乘2
unsigned char cheng2(unsigned char x)
{
	bool maxWei = false;;//最高位是否为1
	if (x >> 7)maxWei = true;
	x = x << 1;
	if (maxWei)
		x = x ^ 0x1b;
	return x;
}

unsigned char mutiply(unsigned char a, unsigned char b)
{
	unsigned char c = 0x0, temp = int(a);
	//cout <<"temp:"<< int(temp) << endl;
	//a不变,拆b
	for (int i = 0; i < 8; i++)
	{
		//查看该位上是否是1,如果是一,经过该变换,if语句为true,否则为false
		int num = int(((b >> i) << 7));
		while (num >= 256)num -= 256;
		if (unsigned char(num))//
			c = c ^ temp;
		temp = cheng2(temp);
	}
	return c;
}

//初始化s-box,使其第i行第j列为ij
void initialize()
{
	unsigned char i = 0;
	for (i=0; i <= 0x0f; i++)
	{
		for (unsigned char j=0; j<= 0x0f; j++)
		{
			sBox[i][j] = (i << 4) + j;
		}
	}
}

void showSBox()
{
	cout << endl;
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			cout << setw(5) <<hex<< int(sBox[i][j]);//
		}
		cout << endl;
	}
}

//用egcd算法求a mod b 的逆元,b=0x11b
//a mod b, b > a,a,b 互素
//w1 = 1 	        w2 = 0 	        b
//q1 = 0 	        q2 = 1 	        a            k = b / a
//temp1=w1 - kq1 	temp2=w2 - kq2 	temp3=b - ka  (== 1)out, 取w2 - kq2
int egcd(int a,int b=283)
{
	int c = b;
	if (a == 0)return 0;
	if (a == 1)return 1;
	int  w1 = 1, w2 = 0;
	int q1 = 0, q2 = 1;
	while (true)
	{
		int k = int(b / a);
		int temp1 = w1 - k * q1, temp2 = w2 - k * q2, temp3 = b - k * a;
		if (temp3 == 1)
		{
			if (temp2 > 0)return temp2;
			else return int( temp2+c );
			
		}
		w1 = q1; w2 = q2; b = a;
		q1 = temp1; q2 = temp2; a = temp3;
	}
}

//B'=X*B xor {63}
void initialize2()
{
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j < 16; j++)
		{

			int temp = egcd(int(sBox[i][j]));
			unsigned char ch = temp;
			sBox[i][j] = ch;
		}
	
	}
}
unsigned char chengJuZhen(unsigned char a)//乘一个矩阵
{
	//R(b_i) = b_i ⊕ b_[(i + 4) mod 8] ⊕ b_[(i + 5) mod 8] ⊕ b_[(i + 6) mod 8] ⊕ b_[(i + 7) mod 8] ⊕ c_i
	bitset<8> bi(a);
	bitset<8> r(a);
	bitset<8> c("01100011");
	for (int i = 0; i < 8; i++)
	{
		r[i] = bi[(i + 4) % 8] ^ bi[(i + 5) % 8] ^ bi[(i + 6) % 8] ^ bi[(i + 7) % 8] ^ c[i];
	}

	unsigned char rech = r.to_ulong();
	return rech;
}

void initialize3()
{
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			sBox[i][j] = chengJuZhen(sBox[i][j]);
		}

	}
}

求s-box的第一步和第三步比较好实现,直接套公式就行了,主要是第二部求逆元,这就要想到之前学习的内容了,经判断,这是一个求mod m(x)的逆元的问题,m(x)=x8+x4+x3+x+1,运用到拓展欧几里得即可解出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值