⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diffattack.h

📁 spn算法加密和解密
💻 H
字号:
#ifndef _DIFFATTACK_H_
#define _DIFFATTACK_H_

#include <stdio.h>

/*差分分布表生成函数
S盒的输入为m位数,输出为n位数*/
void GenNDbox(unsigned int **NDbox,unsigned int *Sbox,int m=4,int n=4){
	unsigned int i, j, a=1<<m, b=1<<n;
	for(i=0;i<a;i++){
		for(j=0;j<b;j++)
			NDbox[i][j]=0;
	}
	for(i=0;i<a;i++){
		for(j=0;j<a;j++)
			NDbox[i][Sub(j,Sbox)^Sub(i^j,Sbox)]++;
	}
}

//输出查看差分分布表
void ViewNDbox(unsigned int *Sbox){
	//产生差分逼近表ND(a,b)
	unsigned int **NDBox=new unsigned int * [16];
	for(int i=0;i<16;i++)
		NDBox[i]=new unsigned int [16];
	GenNDbox(NDBox,Sbox);
	for(i=0;i<16;i++){
		for(int j=0;j<16;j++)
			cout<<NDBox[i][j]<<" ";
		cout<<endl;
	}
	for(i=0;i<16;i++)
		delete [] NDBox[i];
	delete [] NDBox;
}

//破解第layer层的子密钥subkey
unsigned int XNorVal(int layer,unsigned int subkey){
	if(layer==5||layer==4){
		if(subkey==0xf0f0)  //破解key1、key3
			return 0x0500;
		else return 0x0b00; //破解key2、key4
	}
	return 0;
}

//破解子密钥的判断条件1,判断符合明文的差分条件。
int Condition1(unsigned int x,unsigned int x1,int layer,unsigned int subkey){
	if(layer==5||layer==4){
		if(subkey==0xf0f0){   //破解key1、key3
			if((x^x1)==0x0500)
				return 1;
			else return 0;
		}
		else {                //破解key2、key4
			if((x^x1)==0x0b00)
				return 1;
			else return 0;
		}
	}
	return -1;
}

//破解子密钥的判断条件2,判断是否符合密文对的条件。
int Condition2(unsigned int y,unsigned int y1,int layer,unsigned int subkey){
	if(layer==5||layer==4){
		if(subkey==0xf0f0){  //破解key1、key3
			if((y&0x0f0f)==(y1&0x0f0f)) 
				return 1;
			else return 0;            
		}
		else {		         //破解key2、key4
			if((y&0xf0f0)==(y1&0xf0f0)) 
				return 1;
			else return 0;              			
		}
	}
	return -1;
}

//获取所求子密钥的一部分
unsigned int SubKey(unsigned int i,unsigned int j,
					int layer,unsigned int subkey){
    if(layer==5||layer==4){
		if(subkey==0xf0f0)     //破解key1、key3
			return (i<<12)|(j<<4);
		else return (i<<8)|j;  //破解key2、key4	      
	}
	return 0;
}

//随机变量函数,判断是否符合密文的差分条件。
int RandomVariable(unsigned int u,int layer,unsigned int subkey){
	if(layer==5){
		if(subkey==0xf0f0){  //破解key1、key3
			if((u&0xf0f0)==0x6060)
				return 1;
			else return 0;
		}
		else {               //破解key2、key4
			if((u&0x0f0f)==0x0606)
				return 1;
			else return 0;
		}
	}
	if(layer==4){
		if(subkey==0xf0f0){  //破解key1、key3
			if((u&0x0ff0)==0x0110)
				return 1;
			else return 0;
		}
		else {               //破解key2、key4
			if((u&0x0ff0)==0x0220)
				return 1;
			else return 0;
		}
	}
    return -1;
}

/*差分攻击最底层子密钥的特定部分subkey。
CrackFileName破解所需特定已知明文文件,CipherFileName为密文文件,
iSbox为S逆盒,iPbox为P逆盒,AppKey为破解出的密钥,Nr+1为迭代次数,
layer为破解层数,subkey为第layer层的部分密钥。
view为1时输出各个候选子密钥对应的x'产生u4'的概率表,默认为0,不输出。*/
unsigned int DiffAttack(char *CrackFileName,char *CipherFileName,
						unsigned int *iSbox,unsigned int *iPbox,
						int Nr,int layer,unsigned int subkey,int view=0){
	if(subkey==0x0f0f) printf("正在破解第%d层子密钥的key2、key4...",layer);
	if(subkey==0xf0f0) printf("正在破解第%d层子密钥的key1、key3...",layer);

	ifstream fin1(CrackFileName,ios::nocreate|ios::binary);
	ifstream fin2(CipherFileName,ios::nocreate|ios::binary);
	if(fin1==NULL||fin2==NULL){
		cout<<"Open file erro!\n";
		exit(0);
	}
	unsigned int i, j;
	long int Count[16][16], T, T1;
	for(i=0;i<16;i++){
		for(j=0;j<16;j++)
			Count[i][j]=0;
	}	
	for(T1=T=0;fin1.peek()!=EOF;T++){	
		unsigned char c1, c2;
		unsigned int x, x1, y, y1;
		fin1.get(c1); fin1.get(c2);
		x=Int(c1,c2);
		fin1.get(c1); fin1.get(c2);
		x1=Int(c1,c2);

		fin2.get(c1); fin2.get(c2);
		y=Int(c1,c2);
		fin2.get(c1); fin2.get(c2);
		y1=Int(c1,c2);

		if(Condition1(x,x1,layer,subkey)==1&&Condition2(y,y1,layer,subkey)==1){
			T1++;
			for(i=0;i<16;i++){
				for(j=0;j<16;j++){
					unsigned int k, u;
					k=SubKey(i,j,layer,subkey);
					u=Sub(y^k,iSbox)^Sub(y1^k,iSbox);
					if(RandomVariable(u,layer,subkey)==1)
						Count[i][j]++;
				}
			}
		}
	}

	long int max=-1, secdmax;
	unsigned int maxkey, secdkey;	

	printf("\n\n");
	if(view) printf("256个候选子钥对应的x'产生u4'的概率表:\n\n");

	for(i=0;i<16;i++){
		if(view) printf("第%2d行:",i+1);
		for(j=0;j<16;j++){
			if(Count[i][j]>max){
				secdmax=max;
				max=Count[i][j];
				secdkey=maxkey;
				maxkey=SubKey(i,j,layer,subkey);
			}
			if(view){
				if(j==8) printf("\n        ");			
				printf("%.5f ",(double)Count[i][j]/T1);
			}
		}
		if(view) printf("\n");
	}

	if(view){
		printf("\n\n统计结果:\n");
		printf("4重组总数为:%d\n",T);
		printf("有效的4重组:%d\n",T1);
		printf("SPN前三轮的差分链的一个扩散率为:");
		if(subkey==0x0f0f) printf("27/1024=%.5f\n",27.0/1024);
		if(subkey==0xf0f0) printf("3/512=%.5f\n",3.0/512);
		printf("最大偏差:");
		printf("%.5f \n",(double)max/T1);
		printf("第二大偏差:");
		printf("%.5f \n\n\n",(double)secdmax/T1);
	}

	fin1.close();
	fin2.close();
	return maxkey;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -