计算机安全学作业2:AES

计算机安全学作业2

一、描述AES中S-box的生成

  1. 按照字节值的升序逐行初始化S盒,第一行是{00},{01},{02}…{0F};第二行是{10},{11}…{1F},所以第x行y列的字节值是{xy}。

  2. 将S盒子中的每一个字节映射为他在有限域GF(2^8)中的逆,{00}映射为自身。

  3. 把S盒子的每一个字节的8位记为(b7,b6,b5,b4,b3,b2,b1,b0),对S盒子每一个字节的每一位做如下变换:

在这里插入图片描述

其中,ci为字节63的第i位,即(c7c6c5c4c3c2c1c0)=(01100011)。

在有限域GF(28)中,不可约多项式为 a ( x ) = x 8 + x 4 + x 3 + x + 1 a(x)=x^8+x^4+x^3+x+1 a(x)=x8+x4+x3+x+1,假设我们要求 b ( x ) b(x) b(x)的逆,使用扩展欧几里得算法可以得到
a ( x ) v ( x ) + v ( x ) w ( x ) = d ( x ) a(x)v(x)+v(x)w(x)=d(x) a(x)v(x)+v(x)w(x)=d(x)

其中, d ( x ) d(x) d(x)为1, w ( x ) w(x) w(x) b ( x ) b(x) b(x) a ( x ) a(x) a(x)的乘法逆。

我们以{83}为例,首先求16进制数{83}在有限域GF(28)上的逆元。

计算过程如下:

irqvw
-1{1 0001 1011}10
0{1000 0011}01
1{0001 1101}{0000 0010}{0000 0001}{0000 0010}
2{0000 0010}{0000 1101}{0000 1101}{0001 1011}
3{0000 0001}{0000 1110}{0100 0111}{1000 0000}
4{0000 0000}{0000 0010}{1000 0011}{1 0001 1011}
5{0000 0001}{1000 0000}

得到{83}的 乘法逆元为{80},即(x7+x+1)(x7)=1(mod(x8+x4+x3+x+1))

再对16进制数{80}做变换,操作如下:

B={80}={1000 0000}

C={63}={0110 0011}

B’=b’7b’6b’5b’4b’3b’2b’1b’0

根据上面的公式定义:

b ′ 0 = b 0 ⊕ b 4 ⊕ b 5 ⊕ b 6 ⊕ b 7 ⊕ c 0 = 0 b'0=b0\oplus b4\oplus b5\oplus b6 \oplus b7 \oplus c0=0 b0=b0b4b5b6b7c0=0

b ′ 1 = b 1 ⊕ b 5 ⊕ b 6 ⊕ b 7 ⊕ b 8 ⊕ c 1 = 0 b'1=b1\oplus b5\oplus b6\oplus b7 \oplus b8 \oplus c1=0 b1=b1b5b6b7b8c1=0

b ′ 2 = b 2 ⊕ b 6 ⊕ b 7 ⊕ b 0 ⊕ b 7 ⊕ c 2 = 1 b'2=b2\oplus b6\oplus b7\oplus b0 \oplus b7 \oplus c2=1 b2=b2b6b7b0b7c2=1

b ′ 3 = b 3 ⊕ b 7 ⊕ b 0 ⊕ b 1 ⊕ b 2 ⊕ c 3 = 1 b'3=b3\oplus b7\oplus b0\oplus b1 \oplus b2 \oplus c3=1 b3=b3b7b0b1b2c3=1

b ′ 4 = b 4 ⊕ b 0 ⊕ b 1 ⊕ b 2 ⊕ b 3 ⊕ c 4 = 0 b'4=b4\oplus b0\oplus b1\oplus b2 \oplus b3 \oplus c4=0 b4=b4b0b1b2b3c4=0

b ′ 5 = b 5 ⊕ b 4 ⊕ b 5 ⊕ b 6 ⊕ b 7 ⊕ c 5 = 1 b'5=b5\oplus b4\oplus b5\oplus b6 \oplus b7 \oplus c5=1 b5=b5b4b5b6b7c5=1

b ′ 6 = b 6 ⊕ b 2 ⊕ b 3 ⊕ b 4 ⊕ b 5 ⊕ c 6 = 1 b'6=b6\oplus b2\oplus b3\oplus b4 \oplus b5 \oplus c6=1 b6=b6b2b3b4b5c6=1

b ′ 7 = b 7 ⊕ b 3 ⊕ b 4 ⊕ b 5 ⊕ b 6 ⊕ c 7 = 1 b'7=b7\oplus b3\oplus b4\oplus b5 \oplus b6 \oplus c7=1 b7=b7b3b4b5b6c7=1

所以B‘=1110 1100={EC},在S盒子中第8行,第3列对应值为{EC}。

求逆元的方法二

可以用生成元g的幂表示有限域GF(28)内的元素,某个元素可以表示为gk。因为元素是有限的,有255个,因此可以构造一个正表,对于k属于[0,254],可以求出每一个k对应的值。同时可以构造一个反表,通过多项式值gk,求k值。

对于逆元表,若a和b互为逆元,则有ab = e。用生成元表示为:g^n g^m = e = 1。又因为e = g^0 = g255。所以g^k * g(255-k) = g^(k + 255 -k) = e。于是g^k 和 g^(255-k)互为逆元。对于多项式值val,求其逆元。可以先求val对应的g幂次是多少,即g的多少次方等于val,可以通过反向表查询, 设为k。那么其逆元的幂次为255-k。此时再通过正向表查询即可。

二、证明公式6.9和公式6.4等价

在这里插入图片描述

解:
s 0 , j ′ = s 0 , j ⊕ s 0 , j ⊕ s 1 , j ⊕ s 2 , j ⊕ s 3 , j ⊕ [ 2 ⋅ ( s 0 , j ⊕ s 1 , j ) ] = s 1 , j ⊕ s 2 , j ⊕ s 3 , j ⊕ ( 2 ⋅ s 0 , j ) ⊕ ( 2 ⋅ s 1 , j ) = ( 2 ⋅ s 0 , j ) ⊕ ( 3 ⋅ s 1 , j ) ⊕ s 2 , j ⊕ s 3 , j s^{'}_{0,j}=s_{0,j}\oplus s_{0,j} \oplus s_{1,j} \oplus s_{2,j} \oplus s_{3,j} \oplus [2 \cdot(s_{0,j} \oplus s_{1,j})]=\\s_{1,j} \oplus s_{2,j} \oplus s_{3,j} \oplus(2\cdot s_{0,j})\oplus(2\cdot s_{1,j})=\\(2\cdot s_{0,j})\oplus(3\cdot s_{1,j}) \oplus s_{2,j} \oplus s_{3,j} s0,j=s0,js0,js1,js2,js3,j[2(s0,js1,j)]=s1,js2,js3,j(2s0,j)(2s1,j)=(2s0,j)(3s1,j)s2,js3,j
同理可得其他三项,所以6.4和6.9等价

三、写一个GF(2^8)的乘法函数Mul

#include<bits/stdc++.h>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include <stdlib.h>
#include<string>
using namespace std; 
#define ll long long
#define speed ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
vector<int> v;
int table[256];
int arcTable[256];
int invTable[256];
/*可以用生成元g的幂表示有限域GF(2^8)内的元素,某个元素可以表示为g^k。因为元素是有限的,有255个,
因此可以构造一个正表,
对于k属于[0,254],可以求出每一个k对应的值。同时可以构造一个反表,通过多项式值gk,求k值。*/
void getTable(){//由指数求结果 
	table[0] = 1;//g^0
	for(int i = 1; i < 255; ++i)//生成元为x + 1
	{
	table[i] = (table[i-1] << 1 );//table[i-1]*x
	if( table[i] & 0x100 )
	{
		table[i] ^= 0x11B;//左移一位,如果b7=1,则异或 
	}
	table[i] ^= table[i-1];
}
} 
void getArcTable(){//由结果求指数 
	for(int i = 0; i < 255; ++i)
		arcTable[ table[i] ] = i;//下标是g^n,内容是n 
}
void getInvTable(){//求逆元
//g^m * g^n = e = g^255,所以g^k和g^(255-k)互为逆元 
	for(int i = 0; i < 255; ++i){	
		int k;
		k = arcTable[i];
		k = 255 - k;
		k %= 255;//table的取值范围为 [0, 254]
		invTable[i] = table[k];
	}
}
int mul(int x, int y)//乘法查表 
{
	if( !x || !y )
		return 0;
	return table[ (arcTable[x] + arcTable[y]) % 255];
}
int trans2oct(string str){//转十进制 
	int n = str.size();
	int delta = 8-n;
	if(delta<0)return -1;
	if(delta!=0){
		for (int i=1;i<=delta;++i){
			str="0"+str;
		}
	}
	int ans =0;
	for(int i=n-1;i>=0;--i){
		int t = int(str[i])-48;
		//cout<<pow(2,7-i)<<" "<<t<<endl;
		ans+=t*pow(2,7-i);
	}
	//cout<<ans<<endl;
	return ans;
}
string trans2bin(int x){//转二进制 
	//cout<<x<<endl;
	int a[10]={1,2,4,8,16,32,64,128};
	string str="";
	for(int i=7;i>=0;--i){
		if(x-a[i]>=0){
			str+="1";
			x-=a[i];
		}
		else str+="0";
	}
	return str;
}
int main(){
	speed;
	getTable();
	getArcTable();
	getInvTable(); 
	string a,b;
	cout<<"输入两个二进制数"<<endl; 
	//cin>>a>>b;
	//cout<<trans2bin(mul(trans2oct(a),trans2oct(b)));
	cout<<trans2bin(invTable[trans2oct("10110010")]);
	return 0;
	
} 

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

#include<bits/stdc++.h>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include <stdlib.h>
#include<string>
using namespace std; 
#define ll long long
#define speed ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
vector<int> v;
int table[256];
int arcTable[256];
int invTable[256];
void getTable(){//由指数求结果 
	table[0] = 1;//g^0
	for(int i = 1; i < 255; ++i)//生成元为x + 1
	{
	table[i] = (table[i-1] << 1 );//table[i-1]*x
	if( table[i] & 0x100 )
	{
		table[i] ^= 0x11B;//左移一位,如果b7=1,则异或 
	}
	table[i] ^= table[i-1];
}
} 
void getArcTable(){//由结果求指数 
	for(int i = 0; i < 255; ++i)
		arcTable[ table[i] ] = i;//下标是g^n,内容是n 
}
void getInvTable(){//求逆元
//g^m * g^n = e = g^255,所以g^k和g^(255-k)互为逆元 
	for(int i = 0; i < 255; ++i){	
		int k;
		k = arcTable[i];
		k = 255 - k;
		k %= 255;//table的取值范围为 [0, 254]
		invTable[i] = table[k];
	}
}
int mul(int x, int y)//乘法查表 
{
	if( !x || !y )
		return 0;
	return table[ (arcTable[x] + arcTable[y]) % 255];
}
int trans2oct(string str){//转十进制 
	int n = str.size();
	int delta = 8-n;
	if(delta<0)return -1;
	if(delta!=0){
		for (int i=1;i<=delta;++i){
			str="0"+str;
		}
	}
	int ans =0;
	for(int i=7;i>=0;--i){
		int t = int(str[i])-48;
		//cout<<pow(2,7-i)<<" "<<t<<endl;
		ans+=t*pow(2,7-i);
	}
	//cout<<ans<<endl;
	return ans;
}
string trans2bin(int x){//转二进制 
	//cout<<x<<endl;
	int a[10]={1,2,4,8,16,32,64,128};
	string str="";
	for(int i=7;i>=0;--i){
		if(x-a[i]>=0){
			str+="1";
			x-=a[i];
		}
		else str+="0";
	}
	return str;
}
string fx(string str){
	string c63 = "01100011";
	int n,a[10],c[10];
	n = str.size();
	string ans="";
	for(int i=n-1;i>=0;--i){
		c[7-i]=int(c63[i])-48;
	}
	for(int i=n-1;i>=0;--i){
		a[7-i]=int(str[i])-48;
		//cout<<"a:"<<a[7-i]<<endl;
	}
	for(int i=n-1;i>=0;--i){//仿射变换
		int b = a[7-i];
		int btmp,j;
		j = 7-i;
		btmp = b ^ a[(j+4)%8] ^ a[(j+5)%8] ^ a[(j+6)%8] ^ a[(j+7)%8] ^ c[j];
		ans=to_string(btmp)+ans;
	}
	//cout<<"fx:"<<ans<<endl;
	return ans;
} 
string hex2bin(string str){
	string ans="",fans=""; 
	for(int i=0;i<=1;++i){
		if(str[i]=='A') 
			ans = trans2bin(10);
		else if(str[i]=='B') 
			ans = trans2bin(11);
		else if(str[i]=='C') 
			ans = trans2bin(12);
		else if(str[i]=='D') 
			ans = trans2bin(13);
		else if(str[i]=='E') 
			ans = trans2bin(14);	
		else if(str[i]=='F') 
			ans = trans2bin(15);
		else ans = trans2bin(int(str[i])-48);
		ans = ans.substr(4,4);
		fans=fans+ans;
		
	}
	//cout<<fans<<endl;
	return fans;
}
string mapp(int x){
	if(x==10)return "A";
	if(x==11)return "B";
	if(x==12)return "C";
	if(x==13)return "D";
	if(x==14)return "E";
	if(x==15)return "F";
	return to_string(x); 
}
string bin2hex(string str){
	//cout<<str<<endl;
	string ans=""; 
	int a,b;
	a = trans2oct(str.substr(0,4));
	//cout<<a<<endl;
	b = trans2oct(str.substr(4,4));
	//cout<<b<<endl;
	ans = mapp(a)+mapp(b);
	return ans;
}

int main(){
	speed;
	getTable();
	getArcTable();
	getInvTable(); 
	string a,b;
	string word[20]={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
	for(int i=0;i<=15;++i){
		for(int j=0;j<=15;++j){
			a=word[i]+word[j];
			if(i==0&&j==0)cout<<"00 "; 
			else cout<<bin2hex(fx(trans2bin(invTable[trans2oct(hex2bin(a))])))<<" ";
		}
		cout<<endl;
	}
	//cout<<bin2hex(fx(trans2bin(invTable[trans2oct(hex2bin("83"))])));
	return 0;
	
} 
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值