📄 diffattack.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 + -