📄 des.c
字号:
/*
* 重新安排S-box中数据顺序,如果输入的六位是000101,按DES标准的查询方式则是
* 查第二行中的第三列数据。而此表中因为"000101"=5,则是查第六个数据得到"7"
*/
static unsigned char SBox_1[64]={
14,0,4,15,13,7,1,4,
2,14,15,2,11,13,8,1,
3,10,10,6,6,12,12,11,
5,9,9,5,0,3,7,8,
4,15,1,12,14,8,8,2,
13,4,6,9,2,1,11,7,
15,5,12,11,9,3,7,14,
3,10,10,0,5,6,0,13
};
static unsigned char SBox_2[64]={
15,3,1,13,8,4,14,7,
6,15,11,2,3,8,4,14,
9,12,7,0,2,1,13,10,
12,6,0,9,5,11,10,5,
0,13,14,8,7,10,11,1,
10,3,4,15,13,4,1,2,
5,11,8,6,12,7,6,12,
9,0,3,5,2,14,15,9
};
static unsigned char SBox_3[64]={
10,13,0,7,9,0,14,9,
6,3,3,4,15,6,5,10,
1,2,13,8,12,5,7,14,
11,12,4,11,2,15,8,1,
13,1,6,10,4,13,9,0,
8,6,15,9,3,8,0,7,
11,4,1,15,2,14,12,3,
5,11,10,5,14,2,7,12
};
static unsigned char SBox_4[64]={
7,13,13,8,14,11,3,5,
0,6,6,15,9,0,10,3,
1,4,2,7,8,2,5,12,
11,1,12,10,4,14,15,9,
10,3,6,15,9,0,0,6,
12,10,11,1,7,13,13,8,
15,9,1,4,3,5,14,11,
5,12,2,7,8,2,4,14
};
static unsigned char SBox_5[64]={
2,14,12,11,4,2,1,12,
7,4,10,7,11,13,6,1,
8,5,5,0,3,15,15,10,
13,3,0,9,14,8,9,6,
4,11,2,8,1,12,11,7,
10,1,13,14,7,2,8,13,
15,6,9,15,12,0,5,9,
6,10,3,4,0,5,14,3
};
static unsigned char SBox_6[64]={
12,10,1,15,10,4,15,2,
9,7,2,12,6,9,8,5,
0,6,13,1,3,13,4,14,
14,0,7,11,5,3,11,8,
9,4,14,3,15,2,5,12,
2,9,8,5,12,15,3,10,
7,11,0,14,4,1,10,7,
1,6,13,0,11,8,6,13
};
static unsigned char SBox_7[64]={
4,13,11,0,2,11,14,7,
15,4,0,9,8,1,13,10,
3,14,12,3,9,5,7,12,
5,2,10,15,6,8,1,6,
1,6,4,11,11,13,13,8,
12,1,3,4,7,10,14,7,
10,9,15,5,6,0,8,15,
0,14,5,2,9,3,2,12
};
static unsigned char SBox_8[64]={
13,1,2,15,8,13,4,8,
6,10,15,3,11,7,1,4,
10,12,9,5,3,6,14,11,
5,0,0,14,12,9,7,2,
7,2,11,1,4,14,1,7,
9,4,12,10,14,8,2,13,
0,15,6,12,10,9,13,0,
15,3,3,5,5,6,8,11
};
/*
* 0(行) 57,49,41,33,25,17, 9, 1,
* 1 58,50,42,34,26,18,10, 2,
* 2 59,51,43,35,27,19,11, 3,
* 3 60,52,44,36,63,55,47,39,
* 4 31,23,15, 7,62,54,46,38,
* 5 30,22,14, 6,61,53,45,37,
* 6 29,21,13, 5,28,20,12, 4
* 譬如1换到了第8位,在下面的数组中表示为是{0x00,0x01},0x00表示与新key数组中的
* 第"0"号key或运算,当然或上的是"0x01",即key[0x00] |= 0x01
* 转换算法中将采用左移位运算,每移一位则在下表中查询是否应“或”操作key数组中
* 的某一个key
*/
static unsigned char Key_64_To_56_Tab[64][2]={
{0x00,0x01}, // 1
{0x01,0x01}, // 2
{0x02,0x01}, // 3
{0x06,0x01}, // 4
{0x06,0x10}, // 5
{0x05,0x10}, // 6
{0x04,0x10}, // 7
{0x00,0x00}, // 8 no use
{0x00,0x02}, // 9
{0x01,0x02}, // 10
{0x02,0x02}, // 11
{0x06,0x02}, // 12
{0x06,0x20}, // 13
{0x05,0x20}, // 14
{0x04,0x20}, // 15
{0x00,0x00}, // 16
{0x00,0x04}, // 17
{0x01,0x04}, // 18
{0x02,0x04}, // 19
{0x06,0x04}, // 20
{0x06,0x40}, // 21
{0x05,0x40}, // 22
{0x04,0x40}, // 23
{0x00,0x00}, // 24
{0x00,0x08}, // 25
{0x01,0x08}, // 26
{0x02,0x08}, // 27
{0x06,0x08}, // 28
{0x06,0x80}, // 29
{0x05,0x80}, // 30
{0x04,0x80}, // 31
{0x00,0x00}, // 32
{0x00,0x10}, // 33
{0x01,0x10}, // 34
{0x02,0x10}, // 35
{0x03,0x10}, // 36
{0x05,0x01}, // 37
{0x04,0x01}, // 38
{0x03,0x01}, // 39
{0x00,0x00}, // 40
{0x00,0x20}, // 41
{0x01,0x20}, // 42
{0x02,0x20}, // 43
{0x03,0x20}, // 44
{0x05,0x02}, // 45
{0x04,0x02}, // 46
{0x03,0x02}, // 47
{0x00,0x00}, // 48
{0x00,0x40}, // 49
{0x01,0x40}, // 50
{0x02,0x40}, // 51
{0x03,0x40}, // 52
{0x05,0x04}, // 53
{0x04,0x04}, // 54
{0x03,0x04}, // 55
{0x00,0x00}, // 56
{0x00,0x80}, // 57
{0x01,0x80}, // 58
{0x02,0x80}, // 59
{0x03,0x80}, // 60
{0x05,0x08}, // 61
{0x04,0x08}, // 62
{0x03,0x08}, // 63
{0x00,0x00} // 64
};
/* 64-bit key convert to 56-bit key with compressed-convert */
extern void Key64_To_56(unsigned char Key_64[],unsigned char Key_56[]) {
unsigned char i,j,deal_data;
unsigned char index=0;
unsigned char NewKey_index,NewKey_data;
for (i=0;i<7;i++)
Key_56[i]=0;
for (i=0;i<8;i++) {
deal_data=Key_64[i];
for (j=0;j<7;j++) { // only cycle 7 times is enough
if ((deal_data & 0x80)==0x80) {
NewKey_index=Key_64_To_56_Tab[index][0];
NewKey_data=Key_64_To_56_Tab[index][1];
Key_56[NewKey_index] |= NewKey_data;
}
index++;
deal_data <<= 1;
}
index++;
}
}
/*
* 将56bits的key共7个字节分成左右两半各28 bits,然后分别循环"cyc_times"次,
* 循环方向由"di"值确定:
* 若di=0, 向左循环,用于加密
* di=1, 向右循环,用于解密
*/
void KeyRotate(unsigned char Key_56[],unsigned char cyc_times,unsigned char di) {
unsigned char temp1,temp2;
char i,j;
for (i=0;i<cyc_times;i++) {
if (di==0) { /* 向左循环 1 bit */
temp1=0;
for (j=6;j>=0;j--) {
temp2=Key_56[j];
Key_56[j]<<=1;
Key_56[j] |= ((temp1>>7) & 0x01);
temp1=temp2;
}
/* Key_56[6].0 must be 0, so not to add "Key[6] &= 0xfe" */
Key_56[6] |= ( (Key_56[3]>>4) & 0x01);
Key_56[3] &= 0xef;
Key_56[3] |= ( (temp2>>3) & 0x10);
}
else { /* 向右循环 1 bit */
temp1=0;
for (j=0;j<7;j++) {
temp2=Key_56[j];
Key_56[j]>>=1;
Key_56[j] |= ((temp1<<7) & 0x80);
temp1=temp2;
}
/* Key_56[0].7 must be 0, so not to add "Key[6] &= 0xfe" */
Key_56[0] |= ( (Key_56[3]<<4) & 0x80);
Key_56[3] &= 0xf7;
Key_56[3] |= ( (temp2<<3) & 0x08);
}
}
}
/*
* 0(行) 14,17,11,24, 1, 5, 3,28,
* 1 15, 6,21,10,23,19,12, 4,
* 2 26, 8,16, 7,27,20,13, 2,
* 3 41,52,31,37,47,55,30,40,
* 4 51,45,33,48,44,49,39,56,
* 5 34,53,46,42,50,36,29,32
*/
static unsigned char Key_56_To_48_Tab[56][2]={
{0x00,0x08}, /* 1 */
{0x02,0x01}, /* 2 */
{0x00,0x02}, /* 3 */
{0x01,0x01}, /* 4 */
{0x00,0x04}, /* 5 */
{0x01,0x40}, /* 6 */
{0x02,0x10}, /* 7 */
{0x02,0x40}, /* 8 */
{0x00,0x00},
{0x01,0x10}, /* 10 */
{0x00,0x20}, /* 11 */
{0x01,0x02}, /* 12 */
{0x02,0x02}, /* 13 */
{0x00,0x80}, /* 14 */
{0x01,0x80}, /* 15 */
{0x02,0x20}, /* 16 */
{0x00,0x40}, /* 17 */
{0x00,0x00},
{0x01,0x04}, /* 19 */
{0x02,0x04}, /* 20 */
{0x01,0x20}, /* 21 */
{0x00,0x00},
{0x01,0x08}, /* 23 */
{0x00,0x10}, /* 24 */
{0x00,0x00},
{0x02,0x80}, /* 26 */
{0x02,0x08}, /* 27 */
{0x00,0x01}, /* 28 */
{0x05,0x02}, /* 29 */
{0x03,0x02}, /* 30 */
{0x03,0x20}, /* 31 */
{0x05,0x01}, /* 32 */
{0x04,0x20}, /* 33 */
{0x05,0x80}, /* 34 */
{0x00,0x00},
{0x05,0x04}, /* 36 */
{0x03,0x10}, /* 37 */
{0x00,0x00},
{0x04,0x02}, /* 39 */
{0x03,0x01}, /* 40 */
{0x03,0x80}, /* 41 */
{0x05,0x10}, /* 42 */
{0x00,0x00},
{0x04,0x08}, /* 44 */
{0x04,0x40}, /* 45 */
{0x05,0x20}, /* 46 */
{0x03,0x80}, /* 47 */
{0x04,0x10}, /* 48 */
{0x04,0x04}, /* 49 */
{0x05,0x08}, /* 50 */
{0x04,0x80}, /* 51 */
{0x03,0x40}, /* 52 */
{0x05,0x40}, /* 53 */
{0x00,0x00},
{0x03,0x04}, /* 55 */
{0x04,0x01} /* 56 */
};
/*
* 56位的密码经过分组循环后,重新组成56位密码,然后通过压缩变换获得48位的
* 压缩置换密码,本函数目的就是为获得此压缩的48位密码,以便与通过S盒获得的
* 数进行"OR" 运算
*/
void Key_56_To_48(unsigned char Key_56[],unsigned char Key_48[]) {
unsigned char i,j,deal_data;
unsigned char index=0;
unsigned char NewKey_index,NewKey_data;
for (i=0;i<6;i++)
Key_48[i]=0;
for (i=0;i<7;i++) {
deal_data=Key_56[i];
for (j=0;j<8;j++) {
if ((deal_data & 0x80)==0x80) {
NewKey_index=Key_56_To_48_Tab[index][0];
NewKey_data=Key_56_To_48_Tab[index][1];
Key_48[NewKey_index] |= NewKey_data;
}
index++;
deal_data <<= 1;
}
}
}
unsigned char *SBox_Tab[]={
SBox_1,
SBox_2,
SBox_3,
SBox_4,
SBox_5,
SBox_6,
SBox_7,
SBox_8
};
/*
* 48-bits 输进S-盒,获得32-bits的输出
* 输出结果仍旧放进data[]
*/
extern void S_Box_Replace(unsigned char in_data[]) {
unsigned char out_data[8],temp_data;
unsigned char *ptr;
char i,j,k;
for (i=0;i<8;i++) { /* 分别处理8个S-盒*/
temp_data=(in_data[0]>>2);
temp_data &= 0x3f; /* 获得即将去查表的索引值 */
for (j=0;j<6;j++) { /* 准备向左循环6次 */
for (k=0;k<5;k++) { /* 每次循环6个bytes都要动 */
in_data[k]<<=1;
in_data[k]|=((in_data[k+1]>>7) & 0x01);
}
in_data[5]<<=1; /* 最后一个字节与前面的操作有区别*/
}
ptr=(unsigned char *)&SBox_Tab[i][0];
//*ptr=(unsigned char *)SBox_Tab[i]; /* 指向第i个S-盒的转换表*/
//out_data[i]=(*ptr)[temp_data]; /* 获得转换数据 */
out_data[i]=(ptr)[temp_data]; /* 获得转换数据 */
}
for (i=0;i<4;i++) {
in_data[i]=( (out_data[2*i]<<4) | out_data[2*i+1]);
}
}
/*
// 0 32 01 02 03 04 05 04 05
// 1 06 07 08 09 08 09 10 11
// 2 12 13 12 13 14 15 16 17
// 3 16 17 18 19 20 21 20 21
// 4 22 23 24 25 24 25 26 27
// 5 28 29 28 29 30 31 32 01
* ------------------------------------
* 01分别在第0行及第5行存在,第0行的最后要和0x40或,第5行的最后要和0x01或
*/
static unsigned char Data_32_To_48_Tab[32][4]={
{0x00,0x40,0x05,0x01}, /* 1 */
{0x00,0x20,0x00,0x00}, /* 2 */
{0x00,0x10,0x00,0x00}, /* 3 */
{0x00,0x08,0x00,0x02}, /* 4 */
{0x00,0x04,0x00,0x01}, /* 5 */
{0x01,0x80,0x00,0x00}, /* 6 */
{0x01,0x40,0x00,0x00}, /* 7 */
{0x01,0x20,0x01,0x08}, /* 8 */
{0x01,0x10,0x01,0x04}, /* 9 */
{0x01,0x02,0x00,0x00}, /* 10 */
{0x01,0x01,0x00,0x00}, /* 11 */
{0x02,0x80,0x02,0x20}, /* 12 */
{0x02,0x40,0x02,0x10}, /* 13 */
{0x02,0x08,0x00,0x00}, /* 14 */
{0x02,0x04,0x00,0x00}, /* 15 */
{0x02,0x02,0x03,0x80}, /* 16 */
{0x02,0x01,0x03,0x40}, /* 17 */
{0x03,0x20,0x00,0x00}, /* 18 */
{0x03,0x10,0x00,0x00}, /* 19 */
{0x03,0x08,0x03,0x02}, /* 20 */
{0x03,0x04,0x03,0x01}, /* 21 */
{0x04,0x80,0x00,0x00}, /* 22 */
{0x04,0x40,0x00,0x00}, /* 23 */
{0x04,0x20,0x04,0x08}, /* 24 */
{0x04,0x10,0x04,0x04}, /* 25 */
{0x04,0x02,0x00,0x00}, /* 26 */
{0x04,0x01,0x00,0x00}, /* 27 */
{0x05,0x80,0x05,0x20}, /* 28 */
{0x05,0x40,0x05,0x10}, /* 29 */
{0x05,0x08,0x00,0x00}, /* 30 */
{0x05,0x04,0x00,0x00}, /* 31 */
{0x05,0x02,0x00,0x80} /* 32 */
};
/*
* 将32-bits的数据扩展成48-bits的数据位准备与48-bits的密码异或
* 本函数正是为了扩展的目的 : 32-bits ==> 48-bits
* input : Plain_32[4]
* output : Plain_48[6]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -