fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.*;
  4.  
  5. class Main {
  6. private static class DES {
  7. // CONSTANTS
  8. // Initial Permutation Table
  9. int[] IP = { 58, 50, 42, 34, 26, 18,
  10. 10, 2, 60, 52, 44, 36, 28, 20,
  11. 12, 4, 62, 54, 46, 38,
  12. 30, 22, 14, 6, 64, 56,
  13. 48, 40, 32, 24, 16, 8,
  14. 57, 49, 41, 33, 25, 17,
  15. 9, 1, 59, 51, 43, 35, 27,
  16. 19, 11, 3, 61, 53, 45,
  17. 37, 29, 21, 13, 5, 63, 55,
  18. 47, 39, 31, 23, 15, 7 };
  19.  
  20. // Inverse Initial Permutation Table
  21. int[] IP1 = { 40, 8, 48, 16, 56, 24, 64,
  22. 32, 39, 7, 47, 15, 55,
  23. 23, 63, 31, 38, 6, 46,
  24. 14, 54, 22, 62, 30, 37,
  25. 5, 45, 13, 53, 21, 61,
  26. 29, 36, 4, 44, 12, 52,
  27. 20, 60, 28, 35, 3, 43,
  28. 11, 51, 19, 59, 27, 34,
  29. 2, 42, 10, 50, 18, 58,
  30. 26, 33, 1, 41, 9, 49,
  31. 17, 57, 25 };
  32.  
  33. // first key-hePermutation Table
  34. int[] PC1 = { 57, 49, 41, 33, 25,
  35. 17, 9, 1, 58, 50, 42, 34, 26,
  36. 18, 10, 2, 59, 51, 43, 35, 27,
  37. 19, 11, 3, 60, 52, 44, 36, 63,
  38. 55, 47, 39, 31, 23, 15, 7, 62,
  39. 54, 46, 38, 30, 22, 14, 6, 61,
  40. 53, 45, 37, 29, 21, 13, 5, 28,
  41. 20, 12, 4 };
  42.  
  43. // second key-Permutation Table
  44. int[] PC2 = { 14, 17, 11, 24, 1, 5, 3,
  45. 28, 15, 6, 21, 10, 23, 19, 12,
  46. 4, 26, 8, 16, 7, 27, 20, 13, 2,
  47. 41, 52, 31, 37, 47, 55, 30, 40,
  48. 51, 45, 33, 48, 44, 49, 39, 56,
  49. 34, 53, 46, 42, 50, 36, 29, 32 };
  50.  
  51. // Expansion D-box Table
  52. int[] EP = { 32, 1, 2, 3, 4, 5, 4,
  53. 5, 6, 7, 8, 9, 8, 9, 10,
  54. 11, 12, 13, 12, 13, 14, 15,
  55. 16, 17, 16, 17, 18, 19, 20,
  56. 21, 20, 21, 22, 23, 24, 25,
  57. 24, 25, 26, 27, 28, 29, 28,
  58. 29, 30, 31, 32, 1 };
  59.  
  60. // Straight Permutation Table
  61. int[] P = { 16, 7, 20, 21, 29, 12, 28,
  62. 17, 1, 15, 23, 26, 5, 18,
  63. 31, 10, 2, 8, 24, 14, 32,
  64. 27, 3, 9, 19, 13, 30, 6,
  65. 22, 11, 4, 25 };
  66.  
  67. // S-box Table
  68. int[][][] sbox = {
  69. { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
  70. { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
  71. { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
  72. { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },
  73.  
  74. { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
  75. { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
  76. { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
  77. { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },
  78. { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
  79. { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
  80. { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
  81. { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },
  82. { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
  83. { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
  84. { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
  85. { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },
  86. { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
  87. { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
  88. { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
  89. { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },
  90. { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
  91. { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
  92. { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
  93. { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },
  94. { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
  95. { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
  96. { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
  97. { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },
  98. { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
  99. { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
  100. { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
  101. { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }
  102. };
  103. int[] shiftBits = { 1, 1, 2, 2, 2, 2, 2, 2,
  104. 1, 2, 2, 2, 2, 2, 2, 1 };
  105.  
  106. // hexadecimal to binary conversion
  107. String hextoBin(String input)
  108. {
  109. int n = input.length() * 4;
  110. input = Long.toBinaryString(
  111. Long.parseUnsignedLong(input, 16));
  112. while (input.length() < n)
  113. input = "0" + input;
  114. return input;
  115. }
  116.  
  117. // binary to hexadecimal conversion
  118. String binToHex(String input)
  119. {
  120. int n = (int)input.length() / 4;
  121. input = Long.toHexString(
  122. Long.parseUnsignedLong(input, 2));
  123. while (input.length() < n)
  124. input = "0" + input;
  125. return input;
  126. }
  127.  
  128. // per-mutate input hexadecimal
  129. // according to specified sequence
  130. String permutation(int[] sequence, String input)
  131. {
  132. String output = "";
  133. input = hextoBin(input);
  134. for (int i = 0; i < sequence.length; i++)
  135. output += input.charAt(sequence[i] - 1);
  136. output = binToHex(output);
  137. return output;
  138. }
  139.  
  140. // xor 2 hexadecimal strings
  141. String xor(String a, String b)
  142. {
  143. // hexadecimal to decimal(base 10)
  144. long t_a = Long.parseUnsignedLong(a, 16);
  145. // hexadecimal to decimal(base 10)
  146. long t_b = Long.parseUnsignedLong(b, 16);
  147. // xor
  148. t_a = t_a ^ t_b;
  149. // decimal to hexadecimal
  150. a = Long.toHexString(t_a);
  151. // prepend 0's to maintain length
  152. while (a.length() < b.length())
  153. a = "0" + a;
  154. return a;
  155. }
  156.  
  157. // left Circular Shifting bits
  158. String leftCircularShift(String input, int numBits)
  159. {
  160. int n = input.length() * 4;
  161. int perm[] = new int[n];
  162. for (int i = 0; i < n - 1; i++)
  163. perm[i] = (i + 2);
  164. perm[n - 1] = 1;
  165. while (numBits-- > 0)
  166. input = permutation(perm, input);
  167. return input;
  168. }
  169.  
  170. // preparing 16 keys for 16 rounds
  171. String[] getKeys(String key)
  172. {
  173. String keys[] = new String[16];
  174. // first key permutation
  175. key = permutation(PC1, key);
  176. for (int i = 0; i < 16; i++) {
  177. key = leftCircularShift(
  178. key.substring(0, 7), shiftBits[i])
  179. + leftCircularShift(key.substring(7, 14),
  180. shiftBits[i]);
  181. // second key permutation
  182. keys[i] = permutation(PC2, key);
  183. }
  184. return keys;
  185. }
  186.  
  187. // s-box lookup
  188. String sBox(String input)
  189. {
  190. String output = "";
  191. input = hextoBin(input);
  192. for (int i = 0; i < 48; i += 6) {
  193. String temp = input.substring(i, i + 6);
  194. int num = i / 6;
  195. int row = Integer.parseInt(
  196. temp.charAt(0) + "" + temp.charAt(5), 2);
  197. int col = Integer.parseInt(
  198. temp.substring(1, 5), 2);
  199. output += Integer.toHexString(
  200. sbox[num][row][col]);
  201. }
  202. return output;
  203. }
  204.  
  205. String round(String input, String key, int num)
  206. {
  207. // fk
  208. String left = input.substring(0, 8);
  209. String temp = input.substring(8, 16);
  210. String right = temp;
  211. // Expansion permutation
  212. temp = permutation(EP, temp);
  213. // xor temp and round key
  214. temp = xor(temp, key);
  215. // lookup in s-box table
  216. temp = sBox(temp);
  217. // Straight D-box
  218. temp = permutation(P, temp);
  219. // xor
  220. left = xor(left, temp);
  221. System.out.println("Round "
  222. + (num + 1) + " "
  223. + right.toUpperCase()
  224. + " " + left.toUpperCase() + " "
  225. + key.toUpperCase());
  226.  
  227. // swapper
  228. return right + left;
  229. }
  230.  
  231. String encrypt(String plainText, String key)
  232. {
  233. int i;
  234. // get round keys
  235. String keys[] = getKeys(key);
  236.  
  237. // initial permutation
  238. plainText = permutation(IP, plainText);
  239. System.out.println(
  240. "After initial permutation: "
  241. + plainText.toUpperCase());
  242. System.out.println(
  243. "After splitting: L0="
  244. + plainText.substring(0, 8).toUpperCase()
  245. + " R0="
  246. + plainText.substring(8, 16).toUpperCase() + "\n");
  247.  
  248. // 16 rounds
  249. for (i = 0; i < 16; i++) {
  250. plainText = round(plainText, keys[i], i);
  251. }
  252.  
  253. // 32-bit swap
  254. plainText = plainText.substring(8, 16)
  255. + plainText.substring(0, 8);
  256.  
  257. // final permutation
  258. plainText = permutation(IP1, plainText);
  259. return plainText;
  260. }
  261.  
  262. String decrypt(String plainText, String key)
  263. {
  264. int i;
  265. // get round keys
  266. String keys[] = getKeys(key);
  267.  
  268. // initial permutation
  269. plainText = permutation(IP, plainText);
  270. System.out.println(
  271. "After initial permutation: "
  272. + plainText.toUpperCase());
  273. System.out.println(
  274. "After splitting: L0="
  275. + plainText.substring(0, 8).toUpperCase()
  276. + " R0=" + plainText.substring(8, 16).toUpperCase()
  277. + "\n");
  278.  
  279. // 16-rounds
  280. for (i = 15; i > -1; i--) {
  281. plainText = round(plainText, keys[i], 15 - i);
  282. }
  283.  
  284. // 32-bit swap
  285. plainText = plainText.substring(8, 16)
  286. + plainText.substring(0, 8);
  287. plainText = permutation(IP1, plainText);
  288. return plainText;
  289. }
  290. }
  291. public static void main(String args[])
  292. {
  293. String text = "123456ABCD132536";
  294. String key = "656173795F457841";
  295.  
  296. DES cipher = new DES();
  297. System.out.println("Encryption:\n");
  298. text = cipher.encrypt(text, key);
  299. System.out.println(
  300. "\nCipher Text: " + text.toUpperCase() + "\n");
  301. System.out.println("Decryption\n");
  302. text = cipher.decrypt(text, key);
  303. System.out.println(
  304. "\nPlain Text: "
  305. + text.toUpperCase());
  306. }
  307. }
  308. // code contributed by Abhay Bhat
  309.  
Success #stdin #stdout 0.3s 54412KB
stdin
Standard input is empty
stdout
Encryption:

After initial permutation: 14A7D67818CA18AD
After splitting: L0=14A7D678 R0=18CA18AD

Round 1 18CA18AD 609703BE E0BA4E687240
Round 2 609703BE ACBCD0C8 B036F65A8831
Round 3 ACBCD0C8 F414FFC5 F45654034D1C
Round 4 F414FFC5 B5FE47B6 46D374093190
Round 5 B5FE47B6 057ACC32 8ED177E14025
Round 6 057ACC32 7F2333C0 AF436B420A8E
Round 7 7F2333C0 68FBE1FE AB53A994119D
Round 8 68FBE1FE B3BB6E96 991BD90312E1
Round 9 B3BB6E96 D19A5CDC 3B48DA6862C2
Round 10 D19A5CDC DD22D2F7 3C699C34C00F
Round 11 DD22D2F7 4FF65C8C 162D1D8614C2
Round 12 4FF65C8C 4891DE6D 4F2C358CA361
Round 13 4891DE6D AA2F199E CFACAC32CE40
Round 14 AA2F199E 8459165C DAA6AA588512
Round 15 8459165C 75F87671 F89E2A8D6408
Round 16 75F87671 981EDEEC B1BAA2011EE1

Cipher Text: 821C9D75FEABAF65

Decryption

After initial permutation: 981EDEEC75F87671
After splitting: L0=981EDEEC R0=75F87671

Round 1 75F87671 8459165C B1BAA2011EE1
Round 2 8459165C AA2F199E F89E2A8D6408
Round 3 AA2F199E 4891DE6D DAA6AA588512
Round 4 4891DE6D 4FF65C8C CFACAC32CE40
Round 5 4FF65C8C DD22D2F7 4F2C358CA361
Round 6 DD22D2F7 D19A5CDC 162D1D8614C2
Round 7 D19A5CDC B3BB6E96 3C699C34C00F
Round 8 B3BB6E96 68FBE1FE 3B48DA6862C2
Round 9 68FBE1FE 7F2333C0 991BD90312E1
Round 10 7F2333C0 057ACC32 AB53A994119D
Round 11 057ACC32 B5FE47B6 AF436B420A8E
Round 12 B5FE47B6 F414FFC5 8ED177E14025
Round 13 F414FFC5 ACBCD0C8 46D374093190
Round 14 ACBCD0C8 609703BE F45654034D1C
Round 15 609703BE 18CA18AD B036F65A8831
Round 16 18CA18AD 14A7D678 E0BA4E687240

Plain Text: 123456ABCD132536