计算机安全学第二次作业AES

目录

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

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

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

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


一、描述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)。

可以用生成元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等价。

公式6.9:

 公式6.4

 证明:

 

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

#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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值