ComSec作业二:AES

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

(1)按字节值的升序逐行初始化S-Box,第一行是{00},{01},…{0F};第二行是{10},{11},…{1F}等,因此,在行y列x的字节值是{yx}。

(2)把S-Box中的每个字节映射为它在有限域 G F ( 2 8 ) GF(2^8) GF(28)中的逆,其中{00}被映射为它自身{00}。

(3)把S-Box中的每个字节的8个构成位记为 ( b 7 , b 6 , b 5 , b 4 , b 3 , b 2 , b 1 , b 0 ) (b_7,b_6,b_5,b_4,b_3,b_2,b_1,b_0) (b7,b6,b5,b4,b3,b2,b1,b0)。对S-Box的每个字节的每个位做如下变换:

b i ′ = b i ⊕ b ( i + 4 ) m o d 8 ⊕ b ( i + 5 ) m o d 8 ⊕ b ( i + 6 ) m o d 8 ⊕ b ( i + 7 ) m o d 8 ⊕ c i b_i'=b_i\oplus b_{(i+4)mod8}\oplus b_{(i+5)mod8}\oplus b_{(i+6)mod8}\oplus b_{(i+7)mod8}\oplus c_i bi=bib(i+4)mod8b(i+5)mod8b(i+6)mod8b(i+7)mod8ci

这里的 c i c_i ci是指值为{63}的字节c的第i位,即 ( c 7 c 6 c 5 c 4 c 3 c 2 c 1 c 0 ) = ( 01100011 ) (c_7 c_6 c_5 c_4 c_3 c_2 c_1 c_0)=(01100011) (c7c6c5c4c3c2c1c0)=(01100011)。用矩阵形式表示为:

[ b 0 ′ b 1 ′ b 2 ′ b 3 ′ b 4 ′ b 5 ′ b 6 ′ b 7 ′ ] = [ 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 ] [ b 0 b 1 b 2 b 3 b 4 b 5 b 6 b 7 ] + [ 1 1 0 0 0 1 1 0 ] \begin{bmatrix}b_0'\\ b_1' \\ b_2'\\b_3'\\b_4'\\b_5'\\b_6'\\b_7' \end{bmatrix}=\begin{bmatrix}1 & 0 & 0 & 0 & 1 & 1 & 1 & 1\\ 1 & 1 & 0 & 0 & 0 & 1 & 1 & 1\\ 1 & 1 & 1 & 0 & 0 & 0 & 1 & 1 \\ 1 & 1 & 1 & 1 & 0 & 0 & 0 & 1\\ 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0\\ 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0\\ 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0\\ 0 & 0 & 0 & 1 & 1 & 1 & 1 & 1\end{bmatrix} \begin{bmatrix}b_0\\ b_1 \\ b_2\\b_3\\b_4\\b_5\\b_6\\b_7 \end{bmatrix}+\begin{bmatrix}1\\ 1 \\ 0\\0\\0\\1\\1\\0 \end{bmatrix} b0b1b2b3b4b5b6b7 = 1111100001111100001111100001111110001111110001111110001111110001 b0b1b2b3b4b5b6b7 + 11000110

最终S-Box为:
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

对于 s 0 , j ′ s'_{0,j} s0,j,在6.9中,其可以化为:

s 0 , j ′ = s 0 , j ⊕ T m p ⊕ [ 2 ⋅ ( s 0 , j ⊕ s 1 , j ) ] s'_{0,j}=s_{0,j}\oplus Tmp\oplus [2·(s_{0,j}\oplus s_{1,j})] s0,j=s0,jTmp[2(s0,js1,j)]

= s 0 , j ⊕ ( s 0 , j ⊕ s 1 , j ⊕ s 2 , j ⊕ s 3 , j ) ⊕ [ 2 ⋅ ( s 0 , j ⊕ s 1 , j ) ] =s_{0,j}\oplus (s_{0,j}\oplus s_{1,j}\oplus s_{2,j}\oplus s_{3,j})\oplus [2·(s_{0,j}\oplus s_{1,j})] =s0,j(s0,js1,js2,js3,j)[2(s0,js1,j)]

= s 1 , j ⊕ s 2 , j ⊕ s 3 , j ⊕ [ 2 ⋅ ( s 0 , j ⊕ s 1 , j ) ] =s_{1,j}\oplus s_{2,j}\oplus s_{3,j}\oplus [2·(s_{0,j}\oplus s_{1,j})] =s1,js2,js3,j[2(s0,js1,j)]

= ( 2 ⋅ s 0 , j ) ⊕ ( 3 ⋅ s 1 , j ) ⊕ s 2 , j ⊕ s 3 , j =(2·s_{0,j})\oplus (3·s_{1,j})\oplus s_{2,j}\oplus s_{3,j} =(2s0,j)(3s1,j)s2,js3,j

对于 s 1 , j ′ s'_{1,j} s1,j,在6.9中,其可以化为:

s 1 , j ′ = s 1 , j ⊕ T m p ⊕ [ 2 ⋅ ( s 1 , j ⊕ s 2 , j ) ] s'_{1,j}=s_{1,j}\oplus Tmp\oplus [2·(s_{1,j}\oplus s_{2,j})] s1,j=s1,jTmp[2(s1,js2,j)]

= s 1 , j ⊕ ( s 0 , j ⊕ s 1 , j ⊕ s 2 , j ⊕ s 3 , j ) ⊕ [ 2 ⋅ ( s 1 , j ⊕ s 2 , j ) ] =s_{1,j}\oplus (s_{0,j}\oplus s_{1,j}\oplus s_{2,j}\oplus s_{3,j})\oplus [2·(s_{1,j}\oplus s_{2,j})] =s1,j(s0,js1,js2,js3,j)[2(s1,js2,j)]

= s 0 , j ⊕ s 2 , j ⊕ s 3 , j ⊕ [ 2 ⋅ ( s 1 , j ⊕ s 2 , j ) ] =s_{0,j}\oplus s_{2,j}\oplus s_{3,j}\oplus [2·(s_{1,j}\oplus s_{2,j})] =s0,js2,js3,j[2(s1,js2,j)]

= s 0 , j ⊕ ( 2 ⋅ s 1 , j ) ⊕ ( 3 ⋅ s 2 , j ) ⊕ s 3 , j =s_{0,j}\oplus (2·s_{1,j})\oplus (3·s_{2,j})\oplus s_{3,j} =s0,j(2s1,j)(3s2,j)s3,j

对于 s 2 , j ′ s'_{2,j} s2,j,在6.9中,其可以化为:

s 2 , j ′ = s 2 , j ⊕ T m p ⊕ [ 2 ⋅ ( s 2 , j ⊕ s 3 , j ) ] s'_{2,j}=s_{2,j}\oplus Tmp\oplus [2·(s_{2,j}\oplus s_{3,j})] s2,j=s2,jTmp[2(s2,js3,j)]

= s 2 , j ⊕ ( s 0 , j ⊕ s 1 , j ⊕ s 2 , j ⊕ s 3 , j ) ⊕ [ 2 ⋅ ( s 2 , j ⊕ s 3 , j ) ] =s_{2,j}\oplus (s_{0,j}\oplus s_{1,j}\oplus s_{2,j}\oplus s_{3,j})\oplus [2·(s_{2,j}\oplus s_{3,j})] =s2,j(s0,js1,js2,js3,j)[2(s2,js3,j)]

= s 0 , j ⊕ s 1 , j ⊕ s 3 , j ⊕ [ 2 ⋅ ( s 2 , j ⊕ s 3 , j ) ] =s_{0,j}\oplus s_{1,j}\oplus s_{3,j}\oplus [2·(s_{2,j}\oplus s_{3,j})] =s0,js1,js3,j[2(s2,js3,j)]

= s 0 , j ⊕ s 1 , j ⊕ ( 2 ⋅ s 2 , j ) ⊕ ( 2 ⋅ s 3 , j ) =s_{0,j}\oplus s_{1,j}\oplus (2·s_{2,j})\oplus (2·s_{3,j}) =s0,js1,j(2s2,j)(2s3,j)

对于 s 3 , j ′ s'_{3,j} s3,j,在6.9中,其可以化为:

s 3 , j ′ = s 3 , j ⊕ T m p ⊕ [ 2 ⋅ ( s 3 , j ⊕ s 0 , j ) ] s'_{3,j}=s_{3,j}\oplus Tmp\oplus [2·(s_{3,j}\oplus s_{0,j})] s3,j=s3,jTmp[2(s3,js0,j)]

= s 3 , j ⊕ ( s 0 , j ⊕ s 1 , j ⊕ s 2 , j ⊕ s 3 , j ) ⊕ [ 2 ⋅ ( s 3 , j ⊕ s 0 , j ) ] =s_{3,j}\oplus (s_{0,j}\oplus s_{1,j}\oplus s_{2,j}\oplus s_{3,j})\oplus [2·(s_{3,j}\oplus s_{0,j})] =s3,j(s0,js1,js2,js3,j)[2(s3,js0,j)]

= s 0 , j ⊕ s 1 , j ⊕ s 2 , j ⊕ [ 2 ⋅ ( s 3 , j ⊕ s 0 , j ) ] =s_{0,j}\oplus s_{1,j}\oplus s_{2,j}\oplus [2·(s_{3,j}\oplus s_{0,j})] =s0,js1,js2,j[2(s3,js0,j)]

= ( 3 ⋅ s 0 , j ) ⊕ s 1 , j ⊕ s 2 , j ⊕ ( 2 ⋅ s 3 , j ) =(3·s_{0,j})\oplus s_{1,j}\oplus s_{2,j}\oplus (2·s_{3,j}) =(3s0,j)s1,js2,j(2s3,j)

由此可见,公式 6.9 与 公式 6.4 等价。

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

#include<iostream>
using namespace std;

unsigned char Doublenum(unsigned char x);     //求x与2的乘积,实际上是左移
unsigned char Mul(unsigned char a, unsigned char b);  //GF(2^8)的乘法函数

int main()
{
	int a, b;
	cout << "输入 a 和 b 的值" << endl;
	cin>>a>>b;
	cout << "a*b = ";
	//最后用16进制来表示结果
	printf("%#X", Mul(a, b));
	cout << endl;
    
    return 0;
}


unsigned char Doublenum(unsigned char x) 
{
	//判断x的最高位是否为1,若是1的话还要异或上00011011
	return ((x << 1) ^ ((x & 0x80) ? 0x1b : 0x00));
}

unsigned char Mul(unsigned char a, unsigned char b) 
{
	unsigned char array_a[8] = { a };			//用来存储a每次左移的结果,a的2^n次
	unsigned char product = 0x00;
	int i = 0;
	for (i = 1; i < 8; i++) 
	{
		array_a[i] = Doublenum(array_a[i - 1]);
	}

	//如果b的最低位是1,则先加上a
	product = (b & 0x01) * a;

	//通过对b的右移,将a左移的结果加到product里,乘法的本质就是累加和
	for (i = 1; i <= 7; i++) 
	{
		product ^= (((b >> i) & 0x01) * array_a[i]);
	}
	return product;
}


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

#include<iostream>
#include <cstdio>
using namespace std;

unsigned char S_box[16][16];
void initialize();                       //初始化 S-Box[i][j] <- {ij} 
unsigned char msb(unsigned short num);   //找到非零最高位并返回
unsigned char divide(unsigned short a, unsigned char b, unsigned char& r);    //多项式除法,返回a/b
unsigned char Mul(unsigned char a, unsigned char b);    //GF(2^8)乘法,返回a * b 
unsigned char inverse(unsigned char b);   //扩展欧几里得算法求b在GF(2^8)的乘法逆元
unsigned char map(unsigned char a);      //映射 

int main()
{
	initialize();
	unsigned char i, j;
	for (i = 0; i <= 0xF; i++)
	{
		for (j = 0; j <= 0xF; j++)
		{
			S_box[i][j] = map(S_box[i][j]);
			printf("%02X ", S_box[i][j]);
		}

		printf("\n");
	}

	return 0;
}

//扩展欧几里得算法求b在GF(2^8)的乘法逆元
void initialize()
{
	unsigned char i, j;
	for (i = 0; i <= 0xF; i++)
	{
		for (j = 0; j <= 0xF; j++)
		{
			S_box[i][j] = inverse((i << 4) + j);  //使第i行第j列的元素为{xj}

		}
	}
}

//找到非零最高位并返回
unsigned char msb(unsigned short num)
{
	unsigned char i;
	for (i = 0; i <= 8; i++)
	{
		if (!(num >> (i + 1)))
		{
			return i;
		}
	}
}


//多项式除法,返回a/b
unsigned char divide(unsigned short a, unsigned char b, unsigned char& r)
{
	unsigned char a_msb = msb(a);
	unsigned char b_msb = msb(b);
	if (a < b)
	{
		r = a;
		return 0;
	}
	unsigned char bit = a_msb - b_msb;
	unsigned short temp = b;
	temp = temp << bit;
	a = a ^ temp;
	return (1 << bit) | divide(a, b, r);
}

//GF(2^8)乘法,返回a * b 
unsigned char Doublenum(unsigned char x)
{
	//判断x的最高位是否为1,若是1的话还要异或上00011011
	return ((x << 1) ^ ((x & 0x80) ? 0x1b : 0x00));
}

unsigned char Mul(unsigned char a, unsigned char b)
{
	unsigned char array_a[8] = { a };			//用来存储a每次左移的结果,a的2^n次
	unsigned char product = 0x00;
	int i = 0;
	for (i = 1; i < 8; i++)
	{
		array_a[i] = Doublenum(array_a[i - 1]);
	}

	//如果b的最低位是1,则先加上a
	product = (b & 0x01) * a;

	//通过对b的右移,将a左移的结果加到product里,乘法的本质就是累加和
	for (i = 1; i <= 7; i++)
	{
		product ^= (((b >> i) & 0x01) * array_a[i]);
	}
	return product;
}

//扩展欧几里得算法求b在GF(2^8)的乘法逆元
unsigned char inverse(unsigned char b)
{
	if (b == 0)
		return 0;

	short r0 = 0x11B;
	unsigned char r1 = b, r2, q;

	unsigned char w0 = 0, w1 = 1, w2;
	q = divide(r0, r1, r2);
	w2 = w0 ^ Mul(q, w1);
	while (1)
	{
		if (r2 == 0)
			break;
		r0 = r1;
		r1 = r2;
		q = divide(r0, r1, r2);

		w0 = w1;
		w1 = w2;
		w2 = w0 ^ Mul(q, w1);
	}
	return w1;
}

//映射
unsigned char map(unsigned char a)
{
	unsigned char c = 0x63;
	unsigned char res = 0x0;
	unsigned char temp = 0x0;
	unsigned char i;
	for (i = 0; i < 8; i++)
	{
		temp = temp ^ ((a >> i) & 0x1) ^ ((a >> ((i + 4) % 8)) & 0x1);//优先级>> 高于 & 
		temp = temp ^ ((a >> ((i + 5) % 8)) & 0x1) ^ ((a >> ((i + 6) % 8)) & 0x1);
		temp = temp ^ ((a >> ((i + 7) % 8)) & 0x1) ^ ((c >> i) & 0x1);
		res = res | (temp << i);
		temp = 0x0;
	}
	return res;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值