fork download
  1. #include <array>
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <memory>
  5.  
  6. using namespace std;
  7.  
  8. class DES;
  9.  
  10. class DES {
  11. public:
  12. DES(const unsigned long long& key);
  13. unsigned long long encipher(const unsigned long long& plane_data);
  14. unsigned long long decipher(const unsigned long long& cipher_data);
  15. protected:
  16. shared_ptr<array<unsigned long long, 16> > en_subkeys;
  17. shared_ptr<array<unsigned long long, 16> > de_subkeys;
  18. DES(const DES& des);
  19. DES& operator =(const DES& des);
  20. static const unsigned int PC_1C_TABLE[28];
  21. static const unsigned int PC_1D_TABLE[28];
  22. static const unsigned int PC_2_TABLE[48];
  23. static const unsigned int SUBKEY_SHIFT_AMOUNTS[16];
  24. static const unsigned int IP_TABLE[64];
  25. static const unsigned int IIP_TABLE[64];
  26. static const unsigned int E_TABLE[48];
  27. static const unsigned int S_TABLE[8][4][16];
  28. static const unsigned int P_TABLE[32];
  29. static unsigned long long appendParityBits(const unsigned long long& key);
  30. static unsigned long long execute(const unsigned long long& data, const shared_ptr<array<unsigned long long, 16> >& subkeys);
  31. static unsigned long f(const unsigned long& r, const unsigned long long& subkey);
  32. static unsigned char s(const unsigned char& t, const unsigned int tab[4][16]);
  33. template <class D, class S> static D choice(const S& src, const unsigned int& src_len, const unsigned int* tab, const unsigned int& tab_len);
  34. };
  35.  
  36. template <class X> X rotateLeft(const X& x, const unsigned int& n, const unsigned int& w = (sizeof(X) << 3));
  37.  
  38. #define ASSERT(pred) assert(#pred, pred);
  39.  
  40. extern void assert(const char* pred_str, const bool& pred_res);
  41.  
  42. const unsigned int DES::PC_1C_TABLE[28] = {
  43. 57, 49, 41, 33, 25, 17, 9,
  44. 1, 58, 50, 42, 34, 26, 18,
  45. 10, 2, 59, 51, 43, 35, 27,
  46. 19, 11, 3, 60, 52, 44, 36,
  47. };
  48.  
  49. const unsigned int DES::PC_1D_TABLE[28] = {
  50. 63, 55, 47, 39, 31, 23, 15,
  51. 7, 62, 54, 46, 38, 30, 22,
  52. 14, 6, 61, 53, 45, 37, 29,
  53. 21, 13, 5, 28, 20, 12, 4,
  54. };
  55.  
  56. const unsigned int DES::PC_2_TABLE[48] = {
  57. 14, 17, 11, 24, 1, 5,
  58. 3, 28, 15, 6, 21, 10,
  59. 23, 19, 12, 4, 26, 8,
  60. 16, 7, 27, 20, 13, 2,
  61. 41, 52, 31, 37, 47, 55,
  62. 30, 40, 51, 45, 33, 48,
  63. 44, 49, 39, 56, 34, 53,
  64. 46, 42, 50, 36, 29, 32,
  65. };
  66.  
  67. const unsigned int DES::SUBKEY_SHIFT_AMOUNTS[16] = {
  68. 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
  69. };
  70.  
  71. const unsigned int DES::IP_TABLE[64] = {
  72. 58, 50, 42, 34, 26, 18, 10, 2,
  73. 60, 52, 44, 36, 28, 20, 12, 4,
  74. 62, 54, 46, 38, 30, 22, 14, 6,
  75. 64, 56, 48, 40, 32, 24, 16, 8,
  76. 57, 49, 41, 33, 25, 17, 9, 1,
  77. 59, 51, 43, 35, 27, 19, 11, 3,
  78. 61, 53, 45, 37, 29, 21, 13, 5,
  79. 63, 55, 47, 39, 31, 23, 15, 7,
  80. };
  81.  
  82. const unsigned int DES::IIP_TABLE[64] = {
  83. 40, 8, 48, 16, 56, 24, 64, 32,
  84. 39, 7, 47, 15, 55, 23, 63, 31,
  85. 38, 6, 46, 14, 54, 22, 62, 30,
  86. 37, 5, 45, 13, 53, 21, 61, 29,
  87. 36, 4, 44, 12, 52, 20, 60, 28,
  88. 35, 3, 43, 11, 51, 19, 59, 27,
  89. 34, 2, 42, 10, 50, 18, 58, 26,
  90. 33, 1, 41, 9, 49, 17, 57, 25,
  91. };
  92.  
  93. const unsigned int DES::E_TABLE[48] = {
  94. 32, 1, 2, 3, 4, 5,
  95. 4, 5, 6, 7, 8, 9,
  96. 8, 9, 10, 11, 12, 13,
  97. 12, 13, 14, 15, 16, 17,
  98. 16, 17, 18, 19, 20, 21,
  99. 20, 21, 22, 23, 24, 25,
  100. 24, 25, 26, 27, 28, 29,
  101. 28, 29, 30, 31, 32, 1,
  102. };
  103.  
  104. const unsigned int DES::S_TABLE[8][4][16] = {
  105. {
  106. {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, },
  107. { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, },
  108. { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, },
  109. {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, },
  110. },
  111. {
  112. {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, },
  113. { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, },
  114. { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, },
  115. {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, },
  116. },
  117. {
  118. {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, },
  119. {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, },
  120. {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, },
  121. { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, },
  122. },
  123. {
  124. {7 , 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, },
  125. {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, },
  126. {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, },
  127. { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, },
  128. },
  129. {
  130. { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, },
  131. {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, },
  132. { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, },
  133. {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, },
  134. },
  135. {
  136. {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, },
  137. {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, },
  138. { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, },
  139. { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, },
  140. },
  141. {
  142. { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, },
  143. {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, },
  144. { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, },
  145. { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, },
  146. },
  147. {
  148. {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, },
  149. { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, },
  150. { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, },
  151. { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, },
  152. },
  153. };
  154.  
  155. const unsigned int DES::P_TABLE[32] = {
  156. 16, 7, 20, 21,
  157. 29, 12, 28, 17,
  158. 1, 15, 23, 26,
  159. 5, 18, 31, 10,
  160. 2, 8, 24, 14,
  161. 32, 27, 3, 9,
  162. 19, 13, 30, 6,
  163. 22, 11, 4, 25,
  164. };
  165.  
  166. DES::DES(const unsigned long long& key) {
  167. unsigned long long act_key = appendParityBits(key);
  168. this->en_subkeys.reset(new array<unsigned long long, 16>);
  169. this->de_subkeys.reset(new array<unsigned long long, 16>);
  170. unsigned long c = choice<unsigned long>(act_key, 64, PC_1C_TABLE, 28);
  171. unsigned long d = choice<unsigned long>(act_key, 64, PC_1D_TABLE, 28);
  172. for (unsigned int i = 0; i < 16; i++) {
  173. c = rotateLeft(c, SUBKEY_SHIFT_AMOUNTS[i], 28);
  174. d = rotateLeft(d, SUBKEY_SHIFT_AMOUNTS[i], 28);
  175. this->en_subkeys->at(i) = choice<unsigned long long>(c << 28 | d, 56, PC_2_TABLE, 48);
  176. this->de_subkeys->at(16 - 1 - i) = this->en_subkeys->at(i);
  177. }
  178. }
  179.  
  180. unsigned long long DES::encipher(const unsigned long long& plane_data) {
  181. return execute(plane_data, this->en_subkeys);
  182. }
  183.  
  184. unsigned long long DES::decipher(const unsigned long long& cipher_data) {
  185. return execute(cipher_data, this->de_subkeys);
  186. }
  187.  
  188. unsigned long long DES::appendParityBits(const unsigned long long& key) {
  189. unsigned long long res = 0;
  190. unsigned int par_bit = 1;
  191. for (unsigned int i = 0; i < 56; i++) {
  192. res <<= 1;
  193. unsigned int bit = (key >> (56 - 1 - i)) & 1;
  194. res |= bit;
  195. par_bit ^= bit;
  196. if ((i + 1) % 7 == 0) {
  197. res <<= 1;
  198. res |= par_bit;
  199. par_bit = 1;
  200. }
  201. }
  202. return res;
  203. }
  204.  
  205. unsigned long long DES::execute(const unsigned long long& data, const shared_ptr<array<unsigned long long, 16> >& subkeys) {
  206. unsigned long long ip_data = choice<unsigned long long>(data, 64, IP_TABLE, 64);
  207. unsigned long l = ip_data >> 32;
  208. unsigned long r = ip_data & 0xffffffff;
  209. for (unsigned int i = 0; i < 16; i++) {
  210. unsigned long t = r;
  211. r = l ^ f(r, subkeys->at(i));
  212. l = t;
  213. }
  214. return choice<unsigned long long>(((unsigned long long)r << 32) | l, 64, IIP_TABLE, 64);
  215. }
  216.  
  217. unsigned long DES::f(const unsigned long& r, const unsigned long long& subkey) {
  218. unsigned long long t = choice<unsigned long long>(r, 32, E_TABLE, 48) ^ subkey;
  219. unsigned long long u = 0;
  220. for (unsigned int i = 0; i < 8; i++) {
  221. u <<= 4;
  222. u |= s((t >> (48 - 6 * (i + 1))) & 0x3f, S_TABLE[i]);
  223. }
  224. return choice<unsigned long>(u, 32, P_TABLE, 32);
  225. }
  226.  
  227. unsigned char DES::s(const unsigned char& t, const unsigned int tab[4][16]) {
  228. unsigned int row = ((t >> (6 - 1)) << 1) | (t & 1);
  229. unsigned int col = (t >> (2 - 1)) & 0xf;
  230. return tab[row][col];
  231. }
  232.  
  233. template <class D, class S> D DES::choice(const S& src, const unsigned int& src_len, const unsigned int* tab, const unsigned int& tab_len) {
  234. D dest = 0;
  235. for (unsigned int i = 0; i < tab_len; i++) {
  236. dest <<= 1;
  237. dest |= (src >> (src_len - tab[i])) & 1;
  238. }
  239. return dest;
  240. }
  241.  
  242. template <class X> X rotateLeft(const X& x, const unsigned int& n, const unsigned int& w) {
  243. return (x << n) | (x >> (w - n));
  244. }
  245.  
  246. void assert(const char* pred_str, const bool& pred_res) {
  247. if (pred_res) {
  248. cout << "アサート成功: " << pred_str << endl;
  249. }
  250. else {
  251. cerr << "アサート失敗: " << pred_str << endl;
  252. exit(1);
  253. }
  254. }
  255.  
  256. int main() {
  257. {
  258. DES des(0x1234567812345678);
  259. ASSERT(des.encipher(0x1234567812345678) == 0x941eddd882714d98)
  260. ASSERT(des.decipher(0x941eddd882714d98) == 0x1234567812345678)
  261. ASSERT(des.encipher(0x8765432187654321) == 0x084cd9754e5f3058)
  262. ASSERT(des.decipher(0x084cd9754e5f3058) == 0x8765432187654321)
  263. }
  264. {
  265. DES des(0x8765432187654321);
  266. ASSERT(des.encipher(0x1234567812345678) == 0x5b3a1ef3f29089a1)
  267. ASSERT(des.decipher(0x5b3a1ef3f29089a1) == 0x1234567812345678)
  268. ASSERT(des.encipher(0x8765432187654321) == 0x46f4a70e6ff7166c)
  269. ASSERT(des.decipher(0x46f4a70e6ff7166c) == 0x8765432187654321)
  270. }
  271. return 0;
  272. }
  273.  
Success #stdin #stdout 0s 3436KB
stdin
Standard input is empty
stdout
アサート成功: des.encipher(0x1234567812345678) == 0x941eddd882714d98
アサート成功: des.decipher(0x941eddd882714d98) == 0x1234567812345678
アサート成功: des.encipher(0x8765432187654321) == 0x084cd9754e5f3058
アサート成功: des.decipher(0x084cd9754e5f3058) == 0x8765432187654321
アサート成功: des.encipher(0x1234567812345678) == 0x5b3a1ef3f29089a1
アサート成功: des.decipher(0x5b3a1ef3f29089a1) == 0x1234567812345678
アサート成功: des.encipher(0x8765432187654321) == 0x46f4a70e6ff7166c
アサート成功: des.decipher(0x46f4a70e6ff7166c) == 0x8765432187654321