|
|
|
|
@ -1,148 +1,256 @@
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <bitset>
|
|
|
|
|
|
|
|
|
|
// 为64位的二进制数据块定义一个新的类型别名Block,方便后续代码中使用
|
|
|
|
|
typedef std::bitset<64> Block ;
|
|
|
|
|
// 为56位的二进制密钥定义一个新的类型别名Key,方便后续代码中使用
|
|
|
|
|
typedef std::bitset<56> Key ;
|
|
|
|
|
// 为48位的二进制数据(例如子密钥等)定义一个新的类型别名Code,方便后续代码中使用
|
|
|
|
|
typedef std::bitset<48> Code ;
|
|
|
|
|
|
|
|
|
|
// 为32位的二进制数据块定义一个新的类型别名HBlock,通常用于表示数据块的一半等情况,方便后续代码中使用
|
|
|
|
|
typedef std::bitset<32> HBlock ;
|
|
|
|
|
// 为28位的二进制数据(可能用于密钥处理过程中的中间数据)定义一个新的类型别名HKey,方便后续代码中使用
|
|
|
|
|
typedef std::bitset<28> HKey ;
|
|
|
|
|
// 为24位的二进制数据(可能用于某些中间处理情况)定义一个新的类型别名HCode,方便后续代码中使用
|
|
|
|
|
typedef std::bitset<24> HCode ;
|
|
|
|
|
|
|
|
|
|
// 定义一个枚举类型Method,用于表示加解密的操作模式,e表示加密,d表示解密
|
|
|
|
|
typedef enum { e, d } Method ;
|
|
|
|
|
typedef enum { e , d } Method ;
|
|
|
|
|
|
|
|
|
|
// 函数声明,用于对数据块进行初始置换,将其分为左右两部分,后续会有具体定义
|
|
|
|
|
int ip(const Block & block, HBlock & left, HBlock & right) ;
|
|
|
|
|
// 函数声明,执行一轮的DES加解密基本操作(不包含左右部分交换操作),后续会有具体定义
|
|
|
|
|
int des_turn(HBlock & left, HBlock & right, const Code & subkey) ;
|
|
|
|
|
// 函数声明,用于交换数据块的左右两部分,后续会有具体定义
|
|
|
|
|
int exchange(HBlock & left, HBlock & right) ;
|
|
|
|
|
// 函数声明,将处理后的左右两部分数据合并进行末置换,还原成最终的数据块,后续会有具体定义
|
|
|
|
|
int rip(const HBlock & left, const HBlock & right, Block & block) ;
|
|
|
|
|
// 函数声明,根据给定的轮数和原始64位密钥,生成对应轮数的48位子密钥,后续会有具体定义
|
|
|
|
|
Code getkey(const unsigned int n, const Block & bkey) ;
|
|
|
|
|
// 函数声明,整体的DES加解密函数,根据指定的方法(加密或解密)对数据块进行处理,后续会有具体定义
|
|
|
|
|
int des(Block & block, Block & bkey, const Method method) ;
|
|
|
|
|
int ip(const Block & block , HBlock & left , HBlock & right) ;
|
|
|
|
|
int des_turn(HBlock & left , HBlock & right , const Code & subkey) ;
|
|
|
|
|
int exchange(HBlock & left , HBlock & right) ;
|
|
|
|
|
int rip(const HBlock & left , const HBlock & right , Block & block) ;
|
|
|
|
|
Code getkey(const unsigned int n , const Block & bkey) ;
|
|
|
|
|
int des(Block & block , Block & bkey , const Method method) ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//初始置换表
|
|
|
|
|
// 这个表定义了数据块在初始置换(Initial Permutation,IP)时的位置映射关系,用于打乱输入数据的顺序
|
|
|
|
|
const static unsigned char ip_table[64] = {
|
|
|
|
|
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
|
|
|
|
|
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
|
|
|
|
|
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
|
|
|
|
|
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
|
|
|
|
|
58 , 50 , 42 , 34 , 26 , 18 , 10 , 2 , 60 , 52 , 44 , 36 , 28 , 20 , 12 , 4 ,
|
|
|
|
|
62 , 54 , 46 , 38 , 30 , 22 , 14 , 6 , 64 , 56 , 48 , 40 , 32 , 24 , 16 , 8 ,
|
|
|
|
|
57 , 49 , 41 , 33 , 25 , 17 , 9 , 1 , 59 , 51 , 43 , 35 , 27 , 19 , 11 , 3 ,
|
|
|
|
|
61 , 53 , 45 , 37 , 29 , 21 , 13 , 5 , 63 , 55 , 47 , 39 , 31 , 23 , 15 , 7
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//扩展置换,将数据从32位扩展为48位
|
|
|
|
|
// 该表定义了扩展置换(Expansion Permutation)的规则,用于把32位的数据扩展成48位,以便后续与子密钥进行异或操作等
|
|
|
|
|
static const unsigned char expa_perm[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
|
|
|
|
|
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
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//S盒子代替
|
|
|
|
|
// 这是一个二维数组,代表8个不同的S盒(Substitution Boxes),每个S盒用于对数据进行非线性替换操作,是DES算法中增加安全性的关键部分
|
|
|
|
|
const static unsigned char sbox[8][64]={
|
|
|
|
|
{ //S1盒子
|
|
|
|
|
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
|
|
|
|
|
},
|
|
|
|
|
{ //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
|
|
|
|
|
}
|
|
|
|
|
{//S1盒子
|
|
|
|
|
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
|
|
|
|
|
} ,
|
|
|
|
|
{//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
|
|
|
|
|
}
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//P盒置换
|
|
|
|
|
// 定义了P盒置换(Permutation)的规则,对经过S盒替换后的数据进行重新排列,进一步打乱数据顺序
|
|
|
|
|
const static unsigned char p_table[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
|
|
|
|
|
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
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//末置换
|
|
|
|
|
// 末置换(Inverse Initial Permutation,IP逆置换)表,用于将经过加密或解密中间处理后的左右两部分数据还原成最终的数据块顺序
|
|
|
|
|
const static unsigned char ipr_table[64] = {
|
|
|
|
|
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
|
|
|
|
|
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
|
|
|
|
|
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
|
|
|
|
|
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
|
|
|
|
|
40 , 8 , 48 , 16 , 56 , 24 , 64 , 32 , 39 , 7 , 47 , 15 , 55 , 23 , 63 , 31 ,
|
|
|
|
|
38 , 6 , 46 , 14 , 54 , 22 , 62 , 30 , 37 , 5 , 45 , 13 , 53 , 21 , 61 , 29 ,
|
|
|
|
|
36 , 4 , 44 , 12 , 52 , 20 , 60 , 28 , 35 , 3 , 43 , 11 , 51 , 19 , 59 , 27 ,
|
|
|
|
|
34 , 2 , 42 , 10 , 50 , 18 , 58 , 26 , 33 , 1 , 41 , 9 , 49 , 17 , 57 , 25
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//将数据块初始置换为左右两个部分
|
|
|
|
|
// 函数功能:根据初始置换表ip_table对输入的数据块block进行置换,将其分为左右两部分left和right
|
|
|
|
|
// 参数说明:
|
|
|
|
|
// - block:输入的数据块,类型为Block(可能是自定义的某种数据类型,表示一块数据)
|
|
|
|
|
// - left、right:输出参数,分别存储置换后的左半部分和右半部分数据,类型为HBlock(同样可能是自定义类型)
|
|
|
|
|
// 返回值:总是返回0,表示函数执行成功(通常用于错误处理机制较简单的情况)
|
|
|
|
|
int ip(const Block & block, HBlock & left, HBlock & right)
|
|
|
|
|
int ip(const Block & block , HBlock & left , HBlock & right)
|
|
|
|
|
{
|
|
|
|
|
// 循环遍历right部分的每个元素位置,根据初始置换表ip_table获取置换后的数据放入right中
|
|
|
|
|
for(size_t i = 0 ; i < right.size() ; ++i)
|
|
|
|
|
right[i] = block[ip_table[i] - 1] ;//获取置换后的右半部分
|
|
|
|
|
// 循环遍历left部分的每个元素位置,根据初始置换表ip_table获取置换后的数据放入left中
|
|
|
|
|
// 这里注意索引要加上left.size(),是因为ip_table是针对整个64位数据块的映射,要正确获取左半部分数据
|
|
|
|
|
for(size_t i = 0 ; i < left.size() ; ++i)
|
|
|
|
|
left[i] = block[ip_table[i + left.size()] - 1] ;//获取置换后的左半部分
|
|
|
|
|
return 0 ;
|
|
|
|
|
for(size_t i = 0 ; i < right.size() ; ++i)
|
|
|
|
|
right[i] = block[ip_table[i] - 1] ;//获取置换后的右半部分
|
|
|
|
|
for(size_t i = 0 ; i < left.size() ; ++i)
|
|
|
|
|
left[i] = block[ip_table[i + left.size()] - 1] ;//获取置换后的左半部分
|
|
|
|
|
return 0 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//一轮加解密运算,不带交换
|
|
|
|
|
// 函数功能:执行一轮的DES加解密基本操作(不包含左右部分交换操作),包括扩展置换、与子密钥异或、S盒替换、P盒置换以及与左半部分异或等步骤
|
|
|
|
|
// 参数说明:
|
|
|
|
|
// - left、right:输入输出参数,分别表示当前数据块的左半部分和右半部分,类型为HBlock,在函数中会被修改
|
|
|
|
|
// - subkey:本轮使用的子密钥,类型为Code(自定义类型,可能表示密钥相关的数据结构)
|
|
|
|
|
// 返回值:总是返回0,表示函数执行成功
|
|
|
|
|
int des_turn(HBlock & left, HBlock & right, const Code & subkey)
|
|
|
|
|
int des_turn(HBlock & left , HBlock & right , const Code & subkey)
|
|
|
|
|
{
|
|
|
|
|
Code code ;//48位数据块
|
|
|
|
|
HBlock pcode ;//32位数据块
|
|
|
|
|
//将右半部分扩展为48位
|
|
|
|
|
for(size_t i = 0 ; i < code.size() ; ++i)
|
|
|
|
|
code[i] = right[expa_perm[i] - 1] ;//扩展置换
|
|
|
|
|
code ^= subkey ;//与子密钥异或
|
|
|
|
|
//S盒代替
|
|
|
|
|
std::bitset<4> col ;//S盒的列
|
|
|
|
|
std::bitset<2> row ;//S盒的行
|
|
|
|
|
for(size_t i = 0 ; i < 8 ; ++i)
|
|
|
|
|
{//8个盒子
|
|
|
|
|
row[0] = code[6 * i] ;//获取行标
|
|
|
|
|
row[1] = code[6 * i + 5] ;
|
|
|
|
|
col[0] = code[6 * i + 1] ;//获取列标
|
|
|
|
|
col[1] = code[6 * i + 2] ;
|
|
|
|
|
col[2] = code[6 * i + 3] ;
|
|
|
|
|
col[4] = code[6 * i + 4] ;
|
|
|
|
|
std::bitset<4> temp(sbox[i][row.to_ulong() * 16 + col.to_ulong()]) ;
|
|
|
|
|
for(size_t j = 0 ; j < temp.size() ; ++j)
|
|
|
|
|
code[4 * i + j] = temp[j] ;//将32位暂存于48位中
|
|
|
|
|
}
|
|
|
|
|
for(size_t i = 0 ; i < pcode.size() ; ++i)
|
|
|
|
|
pcode[i] = code[p_table[i] - 1] ;//P盒置换
|
|
|
|
|
left ^= pcode ;//异或
|
|
|
|
|
return 0 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//交换左右两个部分
|
|
|
|
|
int exchange(HBlock & left , HBlock & right)
|
|
|
|
|
{
|
|
|
|
|
HBlock temp ;
|
|
|
|
|
for(size_t i = 0 ; i < temp.size() ; ++i)
|
|
|
|
|
temp[i] = left[i] ;
|
|
|
|
|
for(size_t i = 0 ; i < left.size() ; ++i)
|
|
|
|
|
left[i] = right[i] ;
|
|
|
|
|
for(size_t i = 0 ; i < right.size() ; ++i)
|
|
|
|
|
right[i] = temp[i] ;
|
|
|
|
|
return 0 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//将左右两部分数据进行末置换形成一个数据块
|
|
|
|
|
int rip(const HBlock & left , const HBlock & right , Block & block)
|
|
|
|
|
{
|
|
|
|
|
Code code ;// 48位数据块,用于临时存储扩展置换后以及后续处理的数据
|
|
|
|
|
HBlock
|
|
|
|
|
for(size_t i = 0 ; i < block.size() ; ++i)
|
|
|
|
|
{
|
|
|
|
|
if(ipr_table[i] <= 32)
|
|
|
|
|
block[i] = right[ipr_table[i] - 1] ;//从right部分获取数据
|
|
|
|
|
else
|
|
|
|
|
block[i] = left[ipr_table[i] - 32 - 1] ;//从left部分获取数据
|
|
|
|
|
}
|
|
|
|
|
return 0 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//密钥置换表,将64位密钥置换压缩置换为56位
|
|
|
|
|
const static unsigned char key_table[56] = {
|
|
|
|
|
57 , 49 , 41 , 33 , 25 , 17 , 9 , 1 ,
|
|
|
|
|
58 , 50 , 42 , 34 , 26 , 18 , 10 , 2 ,
|
|
|
|
|
59 , 51 , 43 , 35 , 27 , 19 , 11 , 3 ,
|
|
|
|
|
60 , 52 , 44 , 36 , 63 , 55 , 47 , 39 ,
|
|
|
|
|
31 , 23 , 15 , 7 , 62 , 54 , 46 , 38 ,
|
|
|
|
|
30 , 22 , 14 , 6 , 61 , 53 , 45 , 37 ,
|
|
|
|
|
29 , 21 , 13 , 5 , 28 , 20 , 12 , 4
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//每轮移动的位数
|
|
|
|
|
const static unsigned char bit_shift[16] = {
|
|
|
|
|
1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//压缩置换表,56位密钥压缩位48位密钥
|
|
|
|
|
const static unsigned char comp_perm[48] = {
|
|
|
|
|
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
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
//获取bkey产生的第n轮子密钥
|
|
|
|
|
Code getkey(const unsigned int n , const Block & bkey)
|
|
|
|
|
{//n在区间[0,15]之间取值,bkey为64位密钥
|
|
|
|
|
Code result ;//返回值,48位子密钥
|
|
|
|
|
Key key ;//56位密钥
|
|
|
|
|
unsigned int klen = key.size() , rlen = result.size() ;//分别为56和48
|
|
|
|
|
//获取56位密钥
|
|
|
|
|
for(size_t i = 0 ; i < key.size() ; ++i)
|
|
|
|
|
key[i] = bkey[key_table[i] - 1] ;//密钥置换
|
|
|
|
|
for(size_t i = 0 ; i <= n ; ++i)
|
|
|
|
|
{//循环移位
|
|
|
|
|
for(size_t j = 0 ; j < bit_shift[i] ; ++j)
|
|
|
|
|
{
|
|
|
|
|
//将密钥循环位暂存在result中
|
|
|
|
|
result[rlen - bit_shift[i] + j] = key[klen - bit_shift[i] + j] ;
|
|
|
|
|
result[rlen / 2 - bit_shift[i] + j] = key[klen / 2 - bit_shift[i] + j] ;
|
|
|
|
|
}
|
|
|
|
|
key <<= bit_shift[i] ;//移位
|
|
|
|
|
for(size_t j = 0 ; j < bit_shift[i] ; ++j)
|
|
|
|
|
{
|
|
|
|
|
//写回key中
|
|
|
|
|
key[klen / 2 + j] = result[rlen - bit_shift[i] + j] ;
|
|
|
|
|
key[j] = result[rlen / 2 - bit_shift[i] + j] ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//压缩置换
|
|
|
|
|
for(size_t i = 0 ; i < result.size() ; ++i)
|
|
|
|
|
result[i] = key[comp_perm[i] - 1] ;
|
|
|
|
|
return result ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//加解密运算
|
|
|
|
|
int des(Block & block , Block & bkey , const Method method)
|
|
|
|
|
{//block为数据块,bkey为64位密钥
|
|
|
|
|
HBlock left , right ;//左右部分
|
|
|
|
|
ip(block , left , right) ;//初始置换
|
|
|
|
|
switch(method)
|
|
|
|
|
{
|
|
|
|
|
case e://加密
|
|
|
|
|
for(char i = 0 ; i < 16 ; ++i)
|
|
|
|
|
{
|
|
|
|
|
Code key = getkey(i , bkey) ;
|
|
|
|
|
des_turn(left , right , key) ;
|
|
|
|
|
if(i != 15) exchange(left , right) ;
|
|
|
|
|
}
|
|
|
|
|
break ;
|
|
|
|
|
case d://解密
|
|
|
|
|
for(char i = 15 ; i >= 0 ; --i)
|
|
|
|
|
{
|
|
|
|
|
Code key = getkey(i , bkey) ;
|
|
|
|
|
des_turn(left , right , key) ;
|
|
|
|
|
if(i != 0) exchange(left , right) ;
|
|
|
|
|
}
|
|
|
|
|
break ;
|
|
|
|
|
default:
|
|
|
|
|
break ;
|
|
|
|
|
}
|
|
|
|
|
rip(left , right , block) ;//末置换
|
|
|
|
|
return 0 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|