fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. string permute(string key, int arr[], int len) {
  5. string permutation_key = "";
  6. for (int i = 0; i < len; i++) {
  7. permutation_key = permutation_key + key[arr[i] - 1]; // arr[i] tidak zero indexed (1..n)
  8. }
  9. return permutation_key;
  10. }
  11.  
  12. string hex_to_bin(string s) {
  13. char str[16 + 5] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  14. string hex[16 + 5] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
  15. string ret = "";
  16. for (int i = 0; i < s.length(); i++) {
  17. for (int j = 0; j < 16; j++) {
  18. if (s[i] == str[j]) {
  19. ret = ret + hex[j];
  20. break;
  21. }
  22. }
  23. }
  24. return ret;
  25. }
  26.  
  27. string bin_to_hex(string s) {
  28. char str[16 + 5] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  29. string hex[16 + 5] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
  30. string ret = "";
  31. for (int i = 0; i < s.length(); i += 4) {
  32. string four_bits = "";
  33. for (int j = i; j < i + 4; j++) {
  34. four_bits = four_bits + s[j];
  35. }
  36. for (int j = 0; j < 16; j++) {
  37. if (four_bits == hex[j]) {
  38. ret = ret + str[j];
  39. break;
  40. }
  41. }
  42. }
  43. return ret;
  44. }
  45.  
  46. int bin_to_dec(string s) {
  47. int decimal = 0;
  48. int power = 0;
  49. for (int i = s.length() - 1; i >= 0; i--) {
  50. if (s[i] == '1') {
  51. decimal += pow(2, power);
  52. }
  53. power++;
  54. }
  55. return decimal;
  56. }
  57.  
  58. string dec_to_bin(int n) {
  59. string ret = "";
  60. while (n != 0) {
  61. if (n % 2 == 0) {
  62. ret = ret + "0";
  63. } else {
  64. ret = ret + "1";
  65. }
  66. n /= 2;
  67. }
  68. while (ret.length() < 4) {
  69. ret = ret + "0";
  70. }
  71. reverse(ret.begin(), ret.end());
  72. return ret;
  73. }
  74.  
  75. string xor_f(string a, string b) {
  76. string ret = "";
  77. for (int i = 0; i < a.length(); i++) {
  78. if (a[i] == b[i]) {
  79. ret = ret + "0";
  80. } else {
  81. ret = ret + "1";
  82. }
  83. }
  84. return ret;
  85. }
  86.  
  87. string generate_key() {
  88. srand(time({}));
  89. int range_ascii[] = {48, 57, 65, 70};
  90. string key = "";
  91. for (int i = 0; i < 16; i++) {
  92. char c = rand() % (range_ascii[3] + 1 - range_ascii[0]) + range_ascii[0];
  93. if (c > range_ascii[1] && c < range_ascii[2]) {
  94. i--;
  95. continue;
  96. }
  97. key = key + c;
  98. }
  99. return key;
  100. }
  101.  
  102. string parity_bit_drop_key(string key) {
  103. int parity_table[] = {
  104. 57, 49, 41, 33, 25, 17, 9,
  105. 1, 58, 50, 42, 34, 26, 18,
  106. 10, 2, 59, 51, 43, 35, 27,
  107. 19, 11, 3, 60, 52, 44, 36,
  108. 63, 55, 47, 39, 31, 23, 15,
  109. 7, 62, 54, 46, 38, 30, 22,
  110. 14, 6, 61, 53, 45, 37, 29,
  111. 21, 13, 5, 28, 20, 12, 4
  112. };
  113. return (permute(key, parity_table, 56));
  114. }
  115.  
  116. string compression_56_to_48(string key) {
  117. int compression_table[] = {
  118. 14, 17, 11, 24, 1, 5,
  119. 3, 28, 15, 6, 21, 10,
  120. 23, 19, 12, 4, 26, 8,
  121. 16, 7, 27, 20, 13, 2,
  122. 41, 52, 31, 37, 47, 55,
  123. 30, 40, 51, 45, 33, 48,
  124. 44, 49, 39, 56, 34, 53,
  125. 46, 42, 50, 36, 29, 32
  126. };
  127. return (permute(key, compression_table, 48));
  128. }
  129.  
  130. void split_string(string str, string &left, string &right) {
  131. for (int i = 0; i < str.length() / 2; i++) {
  132. left = left + str[i];
  133. right = right + str[str.length() / 2 + i];
  134. }
  135. }
  136.  
  137. string shift_left(string key, int n_shifts) {
  138. int shift_table[] = {
  139. 1, 1, 2, 2,
  140. 2, 2, 2, 2,
  141. 1, 2, 2, 2,
  142. 2, 2, 2, 1
  143. };
  144.  
  145. string shifted_key = "";
  146. for (int i = 0; i < shift_table[n_shifts]; i++) {
  147. for (int j = 1; j < key.length(); j++) {
  148. shifted_key = shifted_key + key[j];
  149. }
  150. shifted_key = shifted_key + key[0];
  151. key = shifted_key;
  152. shifted_key = "";
  153. }
  154. return key;
  155. }
  156.  
  157. struct round_keys {
  158. string random_hex;
  159. string round_keys_bin[16 + 5];
  160. string round_keys_hex[16 + 5];
  161. };
  162.  
  163. round_keys generate_round_keys(string option, string key = "") {
  164. round_keys ret;
  165. if (option == "encryption_scheme") {
  166. ret.random_hex = "AABB09182736CCDD";
  167. } else {
  168. ret.random_hex = key;
  169. }
  170. string key_bin = hex_to_bin(ret.random_hex);
  171. string key_bin_56 = parity_bit_drop_key(key_bin);
  172.  
  173. string key_left;
  174. string key_right;
  175. split_string(key_bin_56, key_left, key_right);
  176.  
  177. for (int i = 0; i < 16; i++) {
  178. key_left = shift_left(key_left, i);
  179. key_right = shift_left(key_right, i);
  180. string combined_key = key_left + key_right;
  181. string round_key = compression_56_to_48(combined_key);
  182. ret.round_keys_bin[i] = round_key;
  183. ret.round_keys_hex[i] = bin_to_hex(round_key);
  184. }
  185. return ret;
  186. }
  187.  
  188. string initial_permutation(string text) {
  189. int IP_table[] = {
  190. 58, 50, 42, 34, 26, 18, 10, 2,
  191. 60, 52, 44, 36, 28, 20, 12, 4,
  192. 62, 54, 46, 38, 30, 22, 14, 6,
  193. 64, 56, 48, 40, 32, 24, 16, 8,
  194. 57, 49, 41, 33, 25, 17, 9, 1,
  195. 59, 51, 43, 35, 27, 19, 11, 3,
  196. 61, 53, 45, 37, 29, 21, 13, 5,
  197. 63, 55, 47, 39, 31, 23, 15, 7
  198. };
  199. return (permute(text, IP_table, 64));
  200. }
  201.  
  202. string expansion(string text) {
  203. int expansion_table[] = {
  204. 32, 1, 2, 3, 4, 5, 4, 5,
  205. 6, 7, 8, 9, 8, 9, 10, 11,
  206. 12, 13, 12, 13, 14, 15, 16, 17,
  207. 16, 17, 18, 19, 20, 21, 20, 21,
  208. 22, 23, 24, 25, 24, 25, 26, 27,
  209. 28, 29, 28, 29, 30, 31, 32, 1
  210. };
  211. return (permute(text, expansion_table, 48));
  212. }
  213.  
  214. string sbox_operation(string text) {
  215. int sbox[8 + 5][4 + 5][16 + 5] = {
  216. {
  217. {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
  218. {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
  219. {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
  220. {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
  221. },
  222.  
  223. {
  224. {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
  225. {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
  226. {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
  227. {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
  228. },
  229.  
  230. {
  231. {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
  232. {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
  233. {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
  234. {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
  235. },
  236.  
  237. {
  238. {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
  239. {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
  240. {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
  241. {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
  242. },
  243.  
  244. {
  245. {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
  246. {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
  247. {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
  248. {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
  249. },
  250.  
  251. {
  252. {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
  253. {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
  254. {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
  255. {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
  256. },
  257.  
  258. {
  259. {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
  260. {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
  261. {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
  262. {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
  263. },
  264.  
  265. {
  266. {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
  267. {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
  268. {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
  269. {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
  270. }
  271. };
  272.  
  273. string ret = "";
  274. for (int i = 0; i < 8; i++) {
  275. string outer = "";
  276. string inner = "";
  277. outer = outer + text[i * 6] + text[i * 6 + 5];
  278. inner = inner + text[i * 6 + 1] + text[i * 6 + 2] + text[i * 6 + 3] + text[i * 6 + 4];
  279. int val = sbox[i][bin_to_dec(outer)][bin_to_dec(inner)];
  280. ret = ret + dec_to_bin(val);
  281. }
  282. return ret;
  283. }
  284.  
  285. string per(string text) {
  286. int per[] = {
  287. 16, 7, 20, 21,
  288. 29, 12, 28, 17,
  289. 1, 15, 23, 26,
  290. 5, 18, 31, 10,
  291. 2, 8, 24, 14,
  292. 32, 27, 3, 9,
  293. 19, 13, 30, 6,
  294. 22, 11, 4, 25
  295. };
  296. return permute(text, per, 32);
  297. }
  298.  
  299. string final_permutation(string text) {
  300. int final_perm[] = {
  301. 40, 8, 48, 16, 56, 24, 64, 32,
  302. 39, 7, 47, 15, 55, 23, 63, 31,
  303. 38, 6, 46, 14, 54, 22, 62, 30,
  304. 37, 5, 45, 13, 53, 21, 61, 29,
  305. 36, 4, 44, 12, 52, 20, 60, 28,
  306. 35, 3, 43, 11, 51, 19, 59, 27,
  307. 34, 2, 42, 10, 50, 18, 58, 26,
  308. 33, 1, 41, 9, 49, 17, 57, 25
  309. };
  310. return permute(text, final_perm, 64);
  311. }
  312.  
  313. string DES_encrypt(string plain_text, round_keys key) {
  314. plain_text = hex_to_bin(plain_text);
  315. plain_text = initial_permutation(plain_text);
  316.  
  317. string chiper_left;
  318. string chiper_right;
  319.  
  320. // THE FUNCTION
  321. split_string(plain_text, chiper_left, chiper_right);
  322.  
  323. for (int i = 0; i < 16; i++) {
  324. string chiper_right_expanded = expansion(chiper_right);
  325.  
  326. string first_xor = xor_f(chiper_right_expanded, key.round_keys_bin[i]);
  327.  
  328. string sbox_str = sbox_operation(first_xor);
  329. sbox_str = per(sbox_str);
  330. string result = xor_f(chiper_left, sbox_str);
  331.  
  332. chiper_left = result;
  333.  
  334. if (i != 15) {
  335. swap(chiper_left, chiper_right);
  336. }
  337. }
  338. string chiper_text = chiper_left + chiper_right;
  339. chiper_text = final_permutation(chiper_text);
  340.  
  341. cout << "Initial permutation : " << bin_to_hex(plain_text) << "\n";
  342. cout << "Final chipper text : " << bin_to_hex(chiper_text) << "\n";
  343.  
  344. return bin_to_hex(chiper_text);
  345. }
  346.  
  347. string DES_decrypt(string chiper_text, string key_hex) {
  348. round_keys key = generate_round_keys("decryption_scheme", key_hex);
  349. round_keys reversed_key;
  350. for (int i = 15; i >= 0; i--) {
  351. reversed_key.round_keys_bin[15 - i] = key.round_keys_bin[i];
  352. reversed_key.round_keys_hex[15 - i] = key.round_keys_hex[i];
  353. }
  354. return DES_encrypt(chiper_text, reversed_key);
  355. }
  356.  
  357. vector<string> input_encrypt() {
  358. // This function is used for converting literal string into hexadecimal
  359. string input_text;
  360. cout << "Input plain text:" << "\n";
  361. cout << ">> ";
  362. cin.ignore();
  363. getline(cin, input_text);
  364. vector<string> plain_text(1);
  365.  
  366. int k = 0;
  367. for (int i = 0; i < input_text.length(); i++) {
  368. string character = "";
  369. for(int j = 7; j >= 0; j--) {
  370. bool is_set = input_text[i] & (1 << j);
  371. if (is_set == 1) {
  372. character = character + "1";
  373. } else {
  374. character = character + "0";
  375. }
  376. }
  377. string character_left, character_right;
  378. split_string(character, character_left, character_right);
  379. if (plain_text[k].length() == 16) {
  380. k++;
  381. plain_text.push_back("" );
  382. }
  383. plain_text[k] = plain_text[k] + bin_to_hex(character_left);
  384. plain_text[k] = plain_text[k] + bin_to_hex(character_right);
  385. }
  386.  
  387. if (plain_text[k].length() != 16) {
  388. for (int i = plain_text[k].length(); i < 16; i++) {
  389. plain_text[k] = plain_text[k] + '0';
  390. }
  391. }
  392. return plain_text;
  393. }
  394.  
  395. string output_decrypt(vector<string> plain_text_hex) {
  396. string ret = "";
  397. for (int i = 0; i < plain_text_hex.size(); i++) {
  398. for (int j = 0; j < 16; j += 2) {
  399. string two_hex = plain_text_hex[i].substr(j, 2);
  400. int value = stoi(two_hex, 0, 16);
  401. if (value != 0) {
  402. ret += (char)value;
  403. }
  404. }
  405. }
  406. return ret;
  407. }
  408.  
  409. int main() {
  410. while (1) {
  411. int menu;
  412. cout << "||======================" << "||" << '\n';
  413. cout << "|| Wellcome to DES" << "\t" << "||" << '\n';
  414. cout << "|| Choose Menu:" << "\t\t" << "||" << '\n';
  415. cout << "|| 1: Encrypt Text" << "\t" << "||" << '\n';
  416. cout << "|| 2: Decrypt Text" << "\t" << "||" << '\n';
  417. cout << "|| 0: Exit" << "\t\t" << "||" << '\n';
  418. cout << "|| >> ";
  419. cin >> menu;
  420. cout << "||======================" << "||" << '\n' << '\n';
  421.  
  422. if (menu == 1) {
  423. cout << "========================================================================================================================" << '\n';
  424. vector<string> plain_text = input_encrypt();
  425. const int message_size = plain_text.size();
  426. round_keys key = generate_round_keys("encryption_scheme");
  427. vector<string> chiper_text;
  428.  
  429. cout << "\n" << "Encrypting plain text..." << "\n";
  430. for (int i = 0; i < message_size; i++) {
  431. chiper_text.push_back(DES_encrypt(plain_text[i], key));
  432. cout << "Plain text encrypted [" << i + 1 << "/" << message_size << "]" << '\n' << '\n';
  433. }
  434. cout << "Key = " << key.random_hex << '\n';
  435. cout << "Chiper text = {" << '\n';
  436. for (int i = 0; i < message_size; i++) {
  437. cout << chiper_text[i];
  438. }
  439. cout << '\n' << "}" << '\n';
  440. cout << "========================================================================================================================" << '\n' << '\n';
  441. } else if (menu == 2) {
  442. cout << "========================================================================================================================" << '\n';
  443. string key, chiper_text;
  444. vector<string> plain_text_hex;
  445. cout << "Input key:" << '\n' << ">> ";
  446. cin >> key;
  447. cout << "Input chiper text:" << '\n' << ">> ";
  448. cin >> chiper_text;
  449. const int message_size = chiper_text.length() / 16;
  450. cout << "\n" << "Decrypting chiper text..." << "\n";
  451. for (int i = 0; i < chiper_text.length(); i += 16) {
  452. string chiper_text_partition = chiper_text.substr(i, 16);
  453. plain_text_hex.push_back(DES_decrypt(chiper_text_partition, key));
  454. cout << "Chiper text decrypted [" << i / 16 + 1 << "/" << message_size << "]" << '\n' << '\n';
  455. }
  456. string plain_text = output_decrypt(plain_text_hex);
  457. cout << plain_text << '\n';
  458. cout << "========================================================================================================================" << '\n' << '\n';
  459. } else if (menu == 0) {
  460. break;
  461. } else {
  462. cout << "Invalid command" << '\n' << '\n';
  463. }
  464. }
  465.  
  466. return 0;
  467. }
Success #stdin #stdout 0.01s 5324KB
stdin
Halo dunia
stdout
||======================||
|| Wellcome to DES	||
|| Choose Menu:		||
|| 1: Encrypt Text	||
|| 2: Decrypt Text	||
|| 0: Exit		||
|| >> ||======================||