aes用到的矩阵及验证程序

A = ( 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 ) A= \begin{pmatrix} 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{pmatrix} A=1111100001111100001111100001111110001111110001111110001111110001
有一步反序
A = ( F 1 , E 3 , C 7 , 8 F , 1 F , 3 E , 7 C , F 8 ) A= \begin{pmatrix} F1,E3,C7,8F,1F,3E,7C,F8 \end{pmatrix} A=(F1,E3,C7,8F,1F,3E,7C,F8)

A − 1 = ( 0 0 1 0 0 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 0 ) A^{-1} = \begin{pmatrix} 0 &0 &1 &0 &0 &1 &0 &1\\ 1 &0 &0 &1 &0 &0 &1 &0\\ 0 &1 &0 &0 &1 &0 &0 &1\\ 1 &0 &1 &0 &0 &1 &0 &0\\ 0 &1 &0 &1 &0 &0 &1 &0\\ 0 &0 &1 &0 &1 &0 &0 &1 \\ 1 &0 &0 &1 &0 &1 &0 &0\\ 0 &1 &0 &0 &1 &0 &1 &0 \end{pmatrix} A1=0101001000101001100101000100101000100101100100100100100110100100

A − 1 = ( A 4 , 49 , 92 , 25 , 4 A , 94 , 29 , 52 ) A^{-1} = \begin{pmatrix} A4,49,92,25,4A,94,29,52 \end{pmatrix} A1=(A4,49,92,25,4A,94,29,52)

b = ( 1 1 0 0 0 1 1 0 ) b = \begin{pmatrix} &1\\ &1 \\&0 \\&0 \\&0 \\&1 \\&1 \\&0 \end{pmatrix} b=11000110
b = 63 b=63 b=63
aes博客,写得很棒
aes博客
求A的逆矩阵用到的算法
高斯消元法求解异或线性方程组

遇到的大坑,字节序,intel的cpu是小字节序,这一点一定要注意,假设有 a a , b b , c c , d d aa,bb,cc,dd aa,bb,cc,dd四个字节那么如果当成一个32位的数,它会反过来变成 d d , c c , b b , a a dd,cc,bb,aa dd,cc,bb,aa。上边的左移变成了下边的右移,密钥扩展的Rcon异或的是低位。字节操作是不受影响的。

密钥扩展:
1.字循环,即左移一个字节,在小端序下为右移一个字节
2.取逆元
3.异或一个与轮数有关的值 "abcd"的情况下,是异或在a上,小端序下0x04,
大端序下就会变成0x04000000

正常流程:
g f ( 2 8 ) gf(2^8) gf(28)上取逆元,矩阵乘,加上一个偏移
行移位,简单平移,注意大端小端
列混淆,模 f ( x ) = x 4 + 1 f(x)=x^4+1 f(x)=x4+1上序数为 g f ( 2 8 ) gf(2^8) gf(28)上的乘积运算,乘以 3 x 3 + 1 x 2 + 1 x + 2 3x^3+1x^2+1^x+2 3x3+1x2+1x+2的运算
数据与扩展密钥异或

#include<vector>
#include<iostream>
using namespace std;
union M {
    
    
	unsigned char chars[4][4];
	uint32_t i32[4];
};
int tb[256];
int rtb[256];
int S[16][16];
int rS[16][16];
int A[] = {
    
     0xF1,0xE3,0xC7,0x8F,0x1F,0x3E,0x7C,0xF8 };
int A_[] = {
    
     0xA4,0x49,0x92,0x25,0x4A,0x94,0x29,0x52 };
int b = 0x63;
int Mixtb[4][4] = {
    
    
	{
    
    0x02,0x03,0x01,0x01},
	{
    
    0x01,0x02,0x03,0x01},
	{
    
    0x01,0x01,0x02,0x03},
	{
    
    0x03,0x01,0x01,0x02}
};
int rMixtb[4][4] = {
    
    
	{
    
    0x0e,0x0b,0x0d,0x09},
	{
    
    0x09,0x0e,0x0b,0x0d},
	{
    
    0x0d,0x09,0x0e,0x0b},
	{
    
    0x0b,0x0d,0x09,0x0e}
};



constexpr uint32_t Rcon[11] = {
    
     0x00000000, 0x01, 0x02,
	0x04, 0x08,
	0x10, 0x20,
	0x40, 0x80,
	0x1b, 0x36 };

uint32_t rev(uint32_t val) {
    
    
	uint8_t* p = (uint8_t*)&val;
	swap(p[0], p[3]);
	swap(p[1], p[2]);
	return val;
}
//xtimes实现乘法
int GFmul(int a, int b) {
    
    
	int ans = 0;
	while (b) {
    
    
		if (b & 1) {
    
    
			ans ^= a;
		}
		if (a > 127)
			a = (a << 1) ^ 0x1b;
		else
			a <<= 1;
		a &= 0xff;
		b >>= 1;
	}
	return ans;
}

//用生成元三生成表
void g3() {
    
    
	tb[0] = rtb[0] = 0;
	tb[1] = rtb[1] = 1;
	int g = 3;
	int ans = 1;
	for (int i = 2; i < 256; i++) {
    
    
		ans = GFmul(ans, g);
		tb[i] = ans;
		rtb[ans] = i;
	}
}
//查表乘法
int GFtbMul(int a, int b) {
    
    
	if (!a || !b)return 0;
	else return tb[(rtb[a] + rtb[b] - 2) % 255 + 1];
}
//查表求逆元
int GFinver(int a) {
    
    
	if (a < 2)return a;
	else {
    
    
		return tb[257 - rtb[a]];
	}
}

//实现GF矩阵乘法
int GFMatrixMul(int* matrix, int val) {
    
    
	int ans = 0;
	for (int i = 0; i < 8; i++) {
    
    
		int t = matrix[i] & val;
		int k = 0;
		while (t) {
    
    
			k++;
			t -= (t & -t);
		}
		ans |= (k % 2) << (i);
	}
	return ans;
}
//求S盒
void gS() {
    
    
	for (int i = 0; i < 16; i++) {
    
    
		for (int j = 0; j < 16; j++) {
    
    
			int element = i << 4 | j;
			int relement = GFinver(element);
			S[i][j] = GFMatrixMul(A, relement) ^ b;
			//printf("%2x ", S[i][j]);
		}//cout << endl;
	}
}
void grS() {
    
    
	for (int i = 0; i < 16; i++) {
    
    
		for (int j = 0; j < 16; j++) {
    
    
			int element = i << 4 | j;
			element ^= b;
			rS[i][j] = GFinver(GFMatrixMul(A_, element));
			//printf("%2x ", rS[i][j]);
		}//cout << endl;
	}
}

uint32_t subByte(uint32_t val) {
    
    
	unsigned char* t = (unsigned char*)&val;
	for (int i = 0; i < 4; i++) {
    
    
		uint32_t tmp = *(t + i);
		*(t + i) = S[tmp >> 4][tmp & 0xf];
	}
	return val;
}
uint32_t rsubByte(uint32_t val) {
    
    
	unsigned char* t = (unsigned char*)&val;
	for (int i = 0; i < 4; i++) {
    
    
		uint32_t tmp = *(t + i);
		*(t + i) = rS[tmp >> 4][tmp & 0xf];
	}
	return val;
}


uint32_t shiftL(uint32_t val,int t) {
    
    
	//printf("%x %x %x\n",val, val << t, val >> (32 - t));

	val = (val >> t) | (val << (32-t));
	return val;
}
uint32_t RotByte(uint32_t val) {
    
    
	val = val >> 8 | val << 24;
	return val;
}
//将四个字节同时替换
uint32_t SubByte(uint32_t val) {
    
    
	unsigned char* t = (unsigned char*)&val;
	for (int i = 0; i < 4; i++){
    
    
		uint32_t tmp = *(t + i);
		*(t + i) = S[tmp >> 4][tmp & 0xf];
	}
	return val;
}

uint32_t rSubByte(uint32_t val) {
    
    
	unsigned char* t = (unsigned char*)&val;
	for (int i = 0; i < 4; i++) {
    
    
		uint32_t tmp = *(t + i);
		*(t + i) = rS[tmp >> 4][tmp & 0xf];
	}
	return val;
}
vector<uint32_t> expandKey(vector<uint32_t> key) {
    
    
	int Nb = 4;//分组长度32bit aes标准限定128
	int Nk = key.size();
	int Nr;
	if (Nk == 4)Nr = 10;
	else if (Nk == 6)Nr = 12;
	else Nr = 14;
	int len = Nb * (Nr + 1);
	vector<uint32_t> ans(len);
	for (int i = 0; i < Nk; i++) {
    
    
		ans[i] = (key[i]);
	}
	for (int i = Nk; i < len; i++) {
    
    
		int temp = ans[i - 1];
		if (i % Nk == 0) {
    
    
			temp = SubByte(RotByte(temp)) ^ Rcon[i / Nk];
		}
		else if (i % Nk == 4 && Nk > 6)temp = SubByte(temp);
		ans[i] = ans[i - Nk] ^ temp;
	}
	//for (int i = 0; i < len; i++)ans[i] = rev(ans[i]);
	return ans;
}
#if 0
#define PRINT
#else
#define PRINT do{
      
      \
	for(int gi=0;gi<4;gi++){
      
      \
		for(int gj=0;gj<4;gj++){
      
      \
			printf("%02x ",d->chars[gi][gj]);\
		}\
	}puts("");\
}while(0);
#endif
void AddRoundKey(M* p,M* k) {
    
    
	for (int i = 0; i < 4; i++) {
    
    
		p->i32[i]^=k->i32[i];
	}
}
void subBytes(M* p) {
    
    
	for (int i = 0; i < 4; i++) {
    
    
		for (int j = 0; j < 4; j++) {
    
    
			uint32_t t = p->chars[i][j];
			p->chars[i][j] = S[t >> 4][t & 0xf];
		}
	}
}
void trans(M* t) {
    
    
	for (int i = 0; i < 4; i++) {
    
    
		for (int j = i+1; j < 4; j++) {
    
    
			swap(t->chars[i][j], t->chars[j][i]);
		}
	}
}
void shiftRows(M* p) {
    
    
	for (int i = 1; i < 4; i++) {
    
    
		p->i32[i] = shiftL(p->i32[i], i << 3);
	}
}
void mixColumns(M* p) {
    
    
	M tmp;
	for (int i = 0; i < 4; i++) {
    
    
		for (int j = 0; j < 4; j++) {
    
    
			uint32_t ans = 0;
			for (int k = 0; k < 4; k++) {
    
    
				ans ^= GFtbMul(Mixtb[i][k], p->chars[k][j]);
				//printf("%02x %02x %02x\n",Mixtb[i][k] ,p->chars[k][j], ans);
			}
			
			tmp.chars[i][j] = ans;
		}
	}
	for (int i = 0; i < 4; i++) {
    
    
		p->i32[i] = tmp.i32[i];
	}
}
vector<uint32_t> AES_128_en(vector<uint32_t>& data, vector<uint32_t>& expkey) {
    
    
	int n = data.size();
	vector<uint32_t> ans(data.begin(), data.end());

	if (n % 4) {
    
    
		cout << "error" << endl;
		return ans;
	}
	for (int i = 0; i < n; i += 4) {
    
    
		//AddRoundKey

		M* d = (M*)&ans[i];
		M* key = (M*)&expkey[0];
		trans(d); trans(key);
		//PRINT
		AddRoundKey(d, key);
		//PRINT
		for (int j = 1; j <= 9; j++) {
    
    
			//字节替换
			subBytes(d);
			//PRINT
			//行移位
			shiftRows(d);
			//PRINT
			//列混淆
			mixColumns(d);
			//PRINT
			//轮密钥加
			key =(M*) &expkey[j << 2];

			trans(key);
			
			AddRoundKey(d, key);
			//PRINT
		}
		//字节替换
		subBytes(d);
		//行移位
		shiftRows(d);
		//轮密钥加
		key = (M*)&expkey[10 << 2];

		trans(key);

		AddRoundKey(d, key);
		trans(d); 
		PRINT
	}
	return ans;
}

int main() {
    
    
	g3();
	gS(); cout << endl;
	grS();
	unsigned char a[2048] = "123asdfsafa4345kjasdf";
	unsigned char keya[2048] = "aaaaaaaaaaaaaaaa";
	uint32_t *pa = (uint32_t*)a;
	uint32_t* pkeya = (uint32_t*)keya;
	vector<uint32_t> data = {
    
    pa[0],pa[1],pa[2],pa[3] };///ABCDEFGHIJKLMNOP
	vector<uint32_t> key = {
    
     pkeya[0],pkeya[1],pkeya[2],pkeya[3] };
	auto expkey = expandKey(key);
	auto ans = AES_128_en(data, expkey);

}

猜你喜欢

转载自blog.csdn.net/weixin_39057744/article/details/119860709
AES