SMS4分析实验报告附C++实现代码Word文件下载.docx
《SMS4分析实验报告附C++实现代码Word文件下载.docx》由会员分享,可在线阅读,更多相关《SMS4分析实验报告附C++实现代码Word文件下载.docx(22页珍藏版)》请在冰豆网上搜索。
2.S盒替换
使用16x16位的S盒,以输入高位为行号、低位为列号取对应表中数值作为输出。
3.L变换
以输入与其循环左移2,10,18,24次的值的异或值作为输出。
(密钥扩展里用到的L'
变换的左移次数为13,23次)
4.轮函数F
四个S盒并行替换后做L变换称作T变换。
F函数的输出为输入数据X1~3与子密钥IK的异或值的T变换得到的值再与输入数据X0的异或值。
5.加密算法
明文作为第一轮F的输入,之后的输入为前一轮输入的后三项与前一轮F变换的结果,子密钥为IK0~31。
32轮变换后,最后四轮的输出分别作为密文的第4到第1项。
6.解密算法
解密算法与加密相同,但子密钥的使用顺序为IK31~0。
每次测试先随机产生原始输入,之后每次随机改变一位,与前一次输出比较改变位数。
每次测试做1000次改变,取平均数。
见图(四)。
多次统计取平均结果为:
63.63位
见图(三)。
S:
3.98位
L:
5位
S盒公有256种输入,对每个输入做连续S变换,直到输出与输入相同。
对于每个S盒结果为定值。
部分见图(四)。
对于附1中的代码实现时所用S盒的计算结果为:
(XX:
YXX=输入Y=S盒替换次数)
00:
12001:
2402:
12003:
2404:
5605:
12006:
12007:
56
08:
5609:
1200A:
560B:
560C:
1200D:
350E:
560F:
120
10:
2411:
12012:
12013:
12014:
5615:
12016:
5617:
18:
12019:
1201A:
1201B:
351C:
1201D:
1201E:
1201F:
20:
2421:
12022:
12023:
12024:
925:
12026:
3527:
28:
12029:
1202A:
562B:
242C:
562D:
32E:
352F:
30:
12031:
12032:
12033:
12034:
3535:
5636:
637:
35
38:
12039:
243A:
1203B:
563C:
353D:
1203E:
353F:
40:
12041:
5642:
12043:
2444:
12045:
12046:
5647:
48:
12049:
1204A:
354B:
1204C:
564D:
1204E:
94F:
9
50:
12051:
5652:
5653:
3554:
12055:
12056:
5657:
58:
659:
1205A:
1205B:
1205C:
355D:
565E:
1205F:
60:
12061:
962:
5663:
12064:
12065:
666:
3567:
68:
12069:
1206A:
1206B:
566C:
246D:
1206E:
566F:
70:
3571:
12072:
5673:
12074:
3575:
3576:
12077:
78:
5679:
67A:
1207B:
1207C:
1207D:
567E:
1207F:
80:
12081:
5682:
5683:
12084:
12085:
12086:
12087:
88:
3589:
248A:
568B:
1208C:
1208D:
98E:
1208F:
90:
2491:
992:
5693:
5694:
12095:
3596:
12097:
98:
3599:
569A:
1209B:
1209C:
249D:
1209E:
1209F:
A0:
120A1:
120A2:
120A3:
35A4:
56A5:
35A6:
35A7:
A8:
9A9:
120AA:
120AB:
1AC:
35AD:
35AE:
9AF:
B0:
24B1:
120B2:
35B3:
120B4:
2B5:
56B6:
120B7:
B8:
24B9:
120BA:
120BB:
56BC:
120BD:
24BE:
120BF:
C0:
9C1:
35C2:
56C3:
56C4:
56C5:
120C6:
120C7:
C8:
120C9:
35CA:
35CB:
56CC:
56CD:
24CE:
120CF:
3
D0:
56D1:
35D2:
120D3:
35D4:
35D5:
24D6:
120D7:
24
D8:
3D9:
35DA:
56DB:
120DC:
24DD:
120DE:
2DF:
E0:
24E1:
120E2:
120E3:
35E4:
120E5:
120E6:
56E7:
E8:
6E9:
120EA:
120EB:
120EC:
120ED:
56EE:
120EF:
F0:
120F1:
120F2:
56F3:
120F4:
120F5:
24F6:
120F7:
F8:
6F9:
120FA:
56FB:
35FC:
24FD:
56FE:
24FF:
表
(一)S变换循环测试
//10385001丁雅博SMS4密码算法VC++6.0编译
#include<
iostream>
cstring>
ctime>
cstdlib>
stdio.h>
stdlib.h>
usingnamespacestd;
intS_box[16][16]={{0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},
{0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},
{0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},
{0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},
{0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},
{0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},
{0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},
{0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},
{0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},
{0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},
{0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},
{0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},
{0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},
{0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},
{0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},
{0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}};
unsignedintck[32]={0x00070e15,0x1c232a31,0x383f464d,0x545b6269,0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,0x30373e45,0x4c535a61,0x686f767d,0x848b9299,0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,0x10171e25,0x2c333a41,0x484f565d,0x646b7279};
unsignedintfk[4]={0xa3b1bac6,0x56aa335,0x677d9197,0xb27022dc};
voidpri(chara[],intn)//数组输出
{
for(inti=0;
i<
n;
i++)
{
cout<
<
a[i];
}
cout<
endl;
}
voidpri_(chara[],intn)//16进制输出
intm=n/4;
m;
intk=i*4;
inttemp=(a[k]-'
0'
)*8+(a[k+1]-'
)*4+(a[k+2]-'
)*2+(a[k+3]-'
);
if(temp<
10)
{
cout<
temp;
}
else
chartemp_=temp-10+'
A'
;
temp_;
voidpri__(chara[],intn)//二进制转字符输出
intm=n/8;
inttemp=0,k=i*8;
for(intj=0;
j<
8;
j++)
temp=temp*2;
temp=temp+a[k+j]-'
char(temp);
voidgetbi(chara[],charre[],intn)//获得二进制码
intsb=a[i];
re[i*8+7-j]=sb%2+'
sb=sb/2;
voidgiv(chara[32],charre[32])//赋值
32;
re[i]=a[i];
voidxor(chara[32],charb[32],charre[32])//异或
if(a[i]==b[i])
re[i]='
1'
voidzy(chara[32],intn)//循环左移
while(n--)
chartemp=a[0];
for(inti=0;
31;
a[i]=a[i+1];
a[31]=temp;
voidd_to_b(unsignedinta,charre[32])//十进制转二进制
for(inti=1;
=32;
re[32-i]=a%2+'
a=a/2;
voidh_to_b(chara[32],charre[4][32])//十六进制转二进制
inti,j;
charb[128];
for(i=0;
intd;
if(a[i]>
='
)
d=a[i]-'
+10;
for(j=0;
4;
b[i*4+3-j]=d%2+'
d=d/2;
re[i][j]=b[i*32+j];
voidS_change(chara[32],charre[32])//4个S盒并行置换
intxtemp=0;
intytemp=0;
xtemp=xtemp*2+a[8*i+j]-'
ytemp=ytemp*2+a[8*i+j+4]-'
inttemp=S_box[xtemp][ytemp];
for(intk=0;
k<
k++)
re[i*8+7-k]=temp%2+'
temp=temp/2;
voidL_change(chara[32],charre[32])//L置换
chartemp[32];
giv(a,temp);
zy(temp,2);
xor(a,temp,re);
zy(temp,8);
xor(re,temp,re);
zy(temp,6);
voidkey_LC(chara[32],charre[32])//L*置换
zy(temp,13);
zy(temp,10);
voidF_change(chara[32],charb[32],charc[32],chard[32],charrk[32],charre[32])//F变换
xor(b,c,re);
xor(re,d,re);
xor(re,rk,re);
S_change(re,re);
L_change(re,re);
xor(a,re,re);
voidkey_ex(chara[4][32],charre[32][32])//密钥扩展
inti;
charK[36][32];
charFK[4][32];
d_to_b(fk[i],FK[i]);
xor(a[i],FK[i],K[i]);
charCK[32][32];
d_to_b(ck[i],CK[i]);
chartemp[32];
xor(K[i+1],K[i+2],temp);
xor(temp,K[i+3],temp);
xor(temp,CK[i],temp);
S_change(temp,temp);
key_LC(temp,temp);
xor(K[i],temp,re[i]);
giv(re[i],K[i+4]);
voidpu_to_pr(chara[4][32],charb[32][32],charre[4][32])//加密
inti=0;
charX[36][32];
giv(a[i],X[i]);
F_change(X[i],X[i+1],X[i+2],X[i+3],b[i],X[i+4]);
giv(X[35-i],re[i]);
voidpr_to_pu(chara[4][32],charb[32][32],charre[4][32])//解密
F_change(X[i],X[i+1],X[i+2],X[i+3],b[31-i],X[i+4]);
doublecomp(chara[],charb[],intn)//比较俩数组不同的位数
doublere=0;
if(a[i]!
=b[i])
re++;
returnre;
doublecomp_Z(chara[4][32],charb[32][32])//输入改变一位,输出平均改变位数
charpr[4][32],pr_[4][32];
pu_to_pr(a,b,pr);
srand(time(0));
1000;
intp=rand()%128;
if(a[p/32][128%32]=='
a[p/32][128%32]='
a[p/32]