L1=R0
R1=L0 XOR F(R0,K1)
我们得到了新的L1和R1,重复操作,直至得到L16和R16,操作公式为:
R1=L0 XOR F(R0,K1)
Li = R i-1
Ri = L i-1 XOR F(Ri-1,Ki)
A:Ki的获取
Ri = L i-1 XOR F(Ri-1,Ki)
在这个过程中,我们每次运算的操作需要得到新的ki进行参与。下面将介绍如何从K0依次16个获取Ki(K1-K16)。K0是一个56bits的数据,我们将其存贮56个字节的key数组中。这56个比特均分为2组,第一组0-27,第二组28-55。
左移偏移量:
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
对于Ki,从左移偏移量选择对应的偏移量,例如K1=1,K4=2。将两组28位的比特分别左移指定的便宜量。例如对于K1,经过左移后,第一组为 1-27,0,第二组为29-55,28。得到一个新的56比特的数据,请保留这个新的序列,记做K1',这个数据根据下面进行序列重排:
|14 17 11 24 1 5|
| 3 28 15 6 21 10|
|23 19 12 4 26 8|
|16 7 27 20 13 2|
|41 52 31 37 47 55|
|30 40 51 45 33 48|
|44 49 39 56 34 53|
|46 42 50 36 29 32|
经过重新排序后,我们得到48比特的数据,这个就是K1。由此我们获得了第一个参与运算的K1。
对于Ki,将Ki-1',例如计算K2,将上次我们得到的K1',分为两组,进行相应的左移操作,得到Ki’,例如计算K2是,我们将K1’分为两组,每组左移1为,得到K2’,将Ki’进行同样排序,得到Ki。
通过这样的操作,我们依次得到16个Ki,代码如下:
static int key_offset[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
static int ip_key[] ={
14,17,11,24,1,5,
3,28,15,6,21,10,
23,19,12,4,26,8,
16,7,27,20,13,2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32};
//左移操作
static void getkey(IN OUT unsigned char * key,int offset){
unsigned char temp[28];
memcpy(temp,key + offset,28-offset);
memcpy(temp + 28 - offset, key , offset);
memcpy(key,temp,28);
memcpy(temp,key + 28 + offset,28-offset);
memcpy(temp + 28 - offset, key + 28 , offset);
memcpy(key + 28,temp,28);
}
void algorithm_des(IN unsigned char * src, IN unsigned char * secrect,
OUT unsigned char * dst){
......
//步骤二:
//获取原始的L0和R0
memcpy(L,s,32);
memcpy(R,s+32,32);
//进行16次计算
for(i = 0; i < 16 ; i++){
//获取Ki'仍然放置在key中
getkey(key,key_offset[i]);
//获取Ki,放置在K中
initail_permutation(key,ip_key,48,K);
}
}
B:F计算
我们已经有R0,对于每次计算Ri,都将有Ri-1,根据A的步骤,我们已经有了K1,对于每次计算,我们也有Ki。在这个步骤中,我们将实现F(Ri-1,Ki)。
step B.1:
对于Ri-1进行序列交换,生成一个48比特的数据,排序方式如下:
| 32 1 2 3 4 5 |
| 4 5 6 7 8 9 |
| 8 9 10 11 12 13 |
| 12 13 14 15 16 17 |
| 16 17 18 19 20 21 |
| 20 21 22 23 24 25 |
| 24 25 26 27 28 29 |
| 28 29 30 31 32 1 |
这组48比特的数据和Ki进行异或(XOR),得到一组新的48bite的数据,我们暂时记做E.
step B.2: S box的运算
48比特的数据均分为8份,每份6比特,我们分别根据S-box的变换,每份产生4比特的数据,生成一个32bite的数据。
1、从6比特的数据中获取一个行号m和一个列号n。
m=b0b5,n=b1b2b3b4
例如6比特的数据为100101,则m=11(3),n=0010(2)
2、根据行号和列号,在S-box的序列中,查到相应的数值。48比特分为8组,每组查询的S-box是不一样的,分别为S1, S2, S3, S4, S5, S6, S7,S8具体如下:
S1: 0列 1列 2列 3列 4列 5列 6列 7列 8列 9列 A列 B列 C列 D列 E列 F列
0行 14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7
1行 0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8
2行 4 1 14 8 13 6 2 11 15 12 9 7 3 10 5 0
3行 15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13
S2:
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
S3:
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
S4
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
S5
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
S6
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
S7
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
S8
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
我们仍以100101为例子,假设它的第一组6比特,得到m=3,n=2,我们查询S1,在第3行,第2列中查得8,将其翻译为二进制,则转换为4比特 的数据1000,这样我们得到了新的第一组4比特,如此类推,我们得到了8组4比特的数据,按顺序组合成一个32比特的数据,暂时记为E'。
stepB.3:更换顺序
将32比特的E’根据下面进行序列更换,得到新的32位数据。
|16 7 20 21|
|29 12 28 17|
|1 15 23 26|
|5 18 31 10|
|2 8 24 14|
|32 27 3 9 |
|19 13 30 6 |
|22 11 4 25|
至此我们完成了F运算。
C:获得新的Ri和Li
这步骤比较简单,如下
Li = R i-1
Ri = L i-1 XOR F(Ri-1,Ki)
D:重复16次计算,得到L16和R16
static int ip_e[] = {相关链接:我的网络通信相关文章
32,1,2,3,4,5,
4,5,6,7,8,9,
8,9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32,1};
static int ip_p[] = {
16,7,20,21,29,12,28,17,
1,15,23,26,5,18,31,10,
2,8,24,14,32,27,3,9,
19,13,30,6,22,11,4,25};
static unsigned char s1[64] = {
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 };
static unsigned char s2[64] = {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 };
static unsigned char s3[64] = {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 };
static unsigned char s4[64] = {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 };
static unsigned char s5[64] = {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 };
static unsigned char s6[64] = {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 };
static unsigned char s7[64] = {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 };
static unsigned char s8[64] = {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 };
static void s_box_function(IN unsigned char * data,IN unsigned char * sbox,
OUT unsigned char * dst){
int m = data[0] * 2 + data[5];
int n = data[1] * 8 + data[2] * 4 + data[3] * 2 + data[4];
unsigned char c = sbox[m* 16 + n];
if(c >= 8){
dst[0] = 1;
c = c-8;
}else{
dst[0] = 0;
}
if(c >= 4){
dst[1] = 1;
c = c-4;
}else{
dst[1] = 0;
}
if(c >= 2){
dst[2] = 1;
c = c-2;
}else{
dst[2] = 0;
}
dst[3] = c;
}
void algorithm_des(IN unsigned char * src, IN unsigned char * secrect,
OUT unsigned char * dst){
......
//步骤二:
//获取原始的L0和R0
memcpy(L,s,32);
memcpy(R,s+32,32);
//进行16次计算
for(i = 0; i < 16 ; i++){
//获取Ki
getkey(key,key_offset[i]);
initail_permutation(key,ip_key,48,K);
//F计算
initail_permutation(R,ip_e,48,E);
xorbit(E,K,48,E);
s_box_function(E,s1,E);
s_box_function(E + 6,s2,E + 4);
s_box_function(E + 12,s3,E + 8);
s_box_function(E + 18,s4,E + 12);
s_box_function(E + 24,s5,E + 16);
s_box_function(E + 30,s6,E + 20);
s_box_function(E + 36,s7,E + 24);
s_box_function(E + 42,s8,E + 28);
initail_permutation(E,ip_p,32,E);
//更换序列
xorbit(E,L,32,E);
memcpy(L,R,32);
memcpy(R,E,32);
}
}