复件 yDES.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <memory.h>
  4. #include <string.h>
  5. #include "yDES.h"
  6. // 初始置换表
  7. const static char IP_Table[64] = {
  8. 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
  9. 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
  10. 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
  11. 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
  12. };
  13. // 逆初始置换表
  14. const static char IPR_Table[64] = {
  15. 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
  16. 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
  17. 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
  18. 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
  19. };
  20. // 扩展置换表
  21. static const char Extension_Table[48] = {
  22. 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
  23. 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
  24. 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
  25. 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
  26. };
  27. // P盒置换表
  28. const static char P_Table[32] = {
  29. 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
  30. 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
  31. };
  32. // 密钥置换表
  33. const static char PCK_Table[56] = {
  34. 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
  35. 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
  36. 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
  37. 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
  38. };
  39. // 压缩置换表
  40. const static char PCC_Table[48] = {
  41. 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
  42. 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
  43. 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
  44. 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
  45. };
  46. // 每轮移动的位数
  47. const static char LOOP_Table[16] = {
  48. 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
  49. };
  50. // S盒设计
  51. const static char S_Box[8][4][16] = {
  52. // S盒1
  53. 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  54. 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  55. 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  56. 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
  57. // S盒2
  58. 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  59. 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  60. 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  61. 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
  62. // S盒3
  63. 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  64. 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  65. 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  66. 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
  67. // S盒4
  68. 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  69. 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  70. 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  71. 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
  72. // S盒5
  73. 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  74. 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  75. 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  76. 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
  77. // S盒6
  78. 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  79. 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  80. 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  81. 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
  82. // S盒7
  83. 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  84. 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  85. 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  86. 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
  87. // S盒8
  88. 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  89. 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  90. 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  91. 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
  92. };
  93. // 字节转换函数
  94. void yDES::ByteToBit(bool *Out, const char *In, int bits)
  95. {
  96. for(int i=0; i<bits; ++i)
  97. Out[i] = ( In[i>>3] >> (i&7) ) & 1;
  98. }
  99. // 比特转换函数
  100. void yDES::BitToByte(char *Out, const bool *In, int bits)
  101. {
  102. memset(Out, 0, bits>>3);
  103. for(int i=0; i<bits; ++i)
  104. Out[i>>3] |= In[i]<<(i&7);
  105. }
  106. // 变换函数
  107. void yDES::Transform(bool *Out, bool *In, const char *Table, int len)
  108. {
  109. for(int i=0; i<len; ++i)
  110. Tmp[i] = In[ Table[i]-1 ];
  111. memcpy(Out, Tmp, len);
  112. }
  113. // 异或函数的实现
  114. void yDES::Xor(bool *InA, const bool *InB, int len)
  115. {
  116. for(int i=0; i<len; ++i)
  117. InA[i] ^= InB[i];
  118. }
  119. // 轮转函数
  120. void yDES::RotateL(bool *In, int len, int loop)
  121. {
  122. memcpy(Tmp, In, loop);
  123. memcpy(In, In+loop, len-loop);
  124. memcpy(In+len-loop, Tmp, loop);
  125. }
  126. // S函数的实现
  127. void yDES::S_func(bool Out[32], const bool In[48])
  128. {
  129. for(char i=0,j,k; i<8; ++i,In+=6,Out+=4) {
  130. j = (In[0]<<1) + In[5];
  131. k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];
  132. ByteToBit(Out, &S_Box[i][j][k], 4);
  133. }
  134. }
  135. // F函数的实现
  136. void yDES::F_func(bool In[32], const bool Ki[48])
  137. {
  138. static bool MR[48];
  139. Transform(MR, In, Extension_Table, 48);
  140. Xor(MR, Ki, 48);
  141. S_func(In, MR);
  142. Transform(In, In, P_Table, 32);
  143. }
  144. // 设置子密钥
  145. void yDES::SetSubKey(PSubKey pSubKey, const char Key[8])
  146. {
  147. static bool K[64], *KL=&K[0], *KR=&K[28];
  148. ByteToBit(K, Key, 64); //转换格式
  149. Transform(K, K, PCK_Table, 56);
  150. // 由56位密钥产生48位子密钥
  151. for(int i=0; i<16; ++i) {
  152. RotateL(KL, 28, LOOP_Table[i]);
  153. RotateL(KR, 28, LOOP_Table[i]);
  154. Transform((*pSubKey)[i], K, PCC_Table, 48);
  155. }
  156. }
  157. // 设置密钥
  158. void yDES::SetKey(const char* Key, int len)
  159. {
  160. memset(deskey, 0, 16);
  161. memcpy(deskey, Key, len>16?16:len);
  162. SetSubKey(&SubKey[0], &deskey[0]);
  163. Is3DES = len>8 ? (SetSubKey(&SubKey[1], &deskey[8]), true) : false;
  164. }
  165. // DES加解密函数
  166. void yDES::DES(char Out[8],const char *In/*[8]*/, const PSubKey pSubKey, bool Type)
  167. {
  168. static bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
  169. ByteToBit(M, In, 64);
  170. Transform(M, M, IP_Table, 64);
  171. if( Type == ENCRYPT ){
  172. for(int i=0; i<16; ++i) {
  173. memcpy(tmp, Ri, 32);
  174. F_func(Ri, (*pSubKey)[i]); // 调用F函数
  175. Xor(Ri, Li, 32);
  176. memcpy(Li, tmp, 32);
  177. }
  178. }else{
  179. for(int i=15; i>=0; --i) {
  180. memcpy(tmp, Li, 32);
  181. F_func(Li, (*pSubKey)[i]);
  182. Xor(Li, Ri, 32);
  183. memcpy(Ri, tmp, 32);
  184. }
  185. }
  186. Transform(M, M, IPR_Table, 64);
  187. BitToByte(Out, M, 64);
  188. }
  189. // DES加解密函数(可以对长明文分段加密)
  190. bool yDES::DES_Act(char *Out,const char *In, size_t datalen, const char *Key, int keylen, bool Type)
  191. {
  192. if( !( Out && In && Key && (datalen=(datalen+7)&0xfffffff8) ) )
  193. return false;
  194. SetKey(Key, keylen);
  195. if( !Is3DES ) { // 1次DES
  196. for(long i = 0,j = datalen>>3; i < j; ++i, Out += 8,In += 8)
  197. DES(Out, In, &SubKey[0], Type);
  198. } else{ // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0)
  199. for(long i=0,j=datalen>>3; i<j; ++i,Out+=8,In+=8) {
  200. DES(Out, In, &SubKey[0], Type);
  201. DES(Out, Out, &SubKey[1], !Type);
  202. DES(Out, Out, &SubKey[0], Type);
  203. }
  204. }
  205. return true;
  206. }