Skip to content

Instantly share code, notes, and snippets.

@heartofrevel
Last active September 27, 2023 15:05
Show Gist options
  • Save heartofrevel/41a66a833af32c02cbb1d8197279763c to your computer and use it in GitHub Desktop.
Save heartofrevel/41a66a833af32c02cbb1d8197279763c to your computer and use it in GitHub Desktop.
DES Algorithm
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
public class Main {
public final static int[] pc1Table = new int[]{ 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};
public final static int[] pc2Table = new int[]{ 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};
public final static int[] initialPermutationTable = new int[] { 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};
public final static int[] eBoxTable = new int[] { 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};
private final static int[][][] sBoxes = new int[][][] { {
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
}};
private final static int[] pBoxTable = new int[]{ 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};
private final static int[] finalPermutationTable = new int[]{ 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};
public final static int[] keyRotationTable = new int[]{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
public static void main(String[] args) {
String input = "1111111111111111";
String key = "0123456789ABCDEF";
String[] subKeys = generateSubKeys(key);
System.out.println("#####ENCRYPTION PROCESS - START#####");
String cipherText = encrypt(input, subKeys);
System.out.println("#####ENCRYPTION PROCESS - END#####");
Collections.reverse(Arrays.asList(subKeys));
System.out.println("#####DECRYPTION PROCESS - START#####");
encrypt(cipherText, subKeys);
System.out.println("#####DECRYPTION PROCESS - END#####");
}
private static String[] generateSubKeys(String key) {
System.out.println("#####GENERATING SUB KEYS - START#####");
String keyBin = hexToBin(key);
System.out.println("Initial Key: "+keyBin+" | "+key);
String pc1PermutedKey = permute(keyBin, pc1Table, 56);
System.out.println("PC-1 Permuted Key: "+ pc1PermutedKey+" | "+ binToHex(pc1PermutedKey, 14));
String[] subKeys = new String[16];
String keyLeftHalf = pc1PermutedKey.substring(0, 28);
String keyRightHalf = pc1PermutedKey.substring(28, 56);
for (int i=0; i<16; i++){
keyLeftHalf = rotateLeft(keyLeftHalf, keyRotationTable[i]);
keyRightHalf = rotateLeft(keyRightHalf, keyRotationTable[i]);
String concatenatedKey = keyLeftHalf+keyRightHalf;
subKeys[i] = permute(concatenatedKey, pc2Table, 48);
System.out.println("Subkey "+(i+1)+": "+subKeys[i]+" | "+ binToHex(subKeys[i], 12));
}
System.out.println("#####GENERATING SUB KEYS - END#####");
return subKeys;
}
private static String encrypt(String data, String[] subkeys){
String dataBinary = hexToBin(data);
System.out.println("Input Data: "+dataBinary + " | "+data);
String dataAfterIP = permute(dataBinary, initialPermutationTable, 64);
System.out.println("Data after IP: "+ dataAfterIP + " | "+ binToHex(dataAfterIP, 16));
String dataLeftHalf = dataAfterIP.substring(0, 32);
String dataRightHalf = dataAfterIP.substring(32, 64);
for(int i=0; i<16; i++){
System.out.println("Round "+(i+1)+" - L"+i+": "+dataLeftHalf+" ("+ binToHex(dataLeftHalf, 8)+")"+" | R"+i+": "+dataRightHalf+" ("+ binToHex(dataRightHalf, 8)+") | Key"+(i+1)+": "+subkeys[i]+" ("+ binToHex(subkeys[i], 12)+")");
String fiestelFuncOutput = feistelFunction(dataRightHalf, subkeys[i]);
dataLeftHalf = xor(dataLeftHalf, fiestelFuncOutput, 32);
if(i!=15){
String temp = dataRightHalf;
dataRightHalf = dataLeftHalf;
dataLeftHalf = temp;
}
}
String fiestelNetworkOutput = dataLeftHalf+dataRightHalf;
System.out.println("Feistel Output - "+dataLeftHalf+dataRightHalf+" | "+ binToHex(dataLeftHalf+dataRightHalf, 16));
String output = permute(fiestelNetworkOutput, finalPermutationTable, 64);
System.out.println("Final Output: "+output+" | "+binToHex(output, 16));
return binToHex(output, 16);
}
private static String feistelFunction(String input, String key){
String expandedInput = permute(input, eBoxTable, 48);
String xorWithSubkey = xor(expandedInput, key, 48);
String sBoxOutput = sBoxesFunction(xorWithSubkey);
return permute(sBoxOutput, pBoxTable, 32);
}
private static String sBoxesFunction(String input){
StringBuilder output = new StringBuilder();
int sBoxNum = 0;
for(int i=0; i<48; i+=6){
String inputPart = input.substring(i, i+6);
int rowNum = Integer.parseInt(String.valueOf(inputPart.charAt(0))+String.valueOf(inputPart.charAt(5)), 2);
int columnNum = Integer.parseInt(inputPart.substring(1,5),2);
int sboxEntry = sBoxes[sBoxNum][rowNum][columnNum];
String binarySboxEntry = String.format("%4s", Integer.toBinaryString(sboxEntry)).replace(' ', '0');
output.append(binarySboxEntry);
sBoxNum++;
}
return output.toString();
}
private static String permute(String input, int[] table, int length){
StringBuilder result = new StringBuilder();
for(int i=0; i<length; i++){
result.append(input.charAt(table[i] - 1));
}
return result.toString();
}
private static String hexToBin(String hex){
hex = hex.replaceAll("0", "0000");
hex = hex.replaceAll("1", "0001");
hex = hex.replaceAll("2", "0010");
hex = hex.replaceAll("3", "0011");
hex = hex.replaceAll("4", "0100");
hex = hex.replaceAll("5", "0101");
hex = hex.replaceAll("6", "0110");
hex = hex.replaceAll("7", "0111");
hex = hex.replaceAll("8", "1000");
hex = hex.replaceAll("9", "1001");
hex = hex.replaceAll("A", "1010");
hex = hex.replaceAll("B", "1011");
hex = hex.replaceAll("C", "1100");
hex = hex.replaceAll("D", "1101");
hex = hex.replaceAll("E", "1110");
hex = hex.replaceAll("F", "1111");
return hex;
}
private static String binToHex(String bin, int length){
return String.format("%0"+length+"x", new BigInteger(bin, 2)).toUpperCase();
}
private static String xor(String a, String b, int n){
StringBuilder output = new StringBuilder();
for (int i = 0; i < n; i++) {
// If the Character matches
if (a.charAt(i) == b.charAt(i))
output.append("0");
else
output.append("1");
}
return output.toString();
}
private static String rotateLeft(String binInput, int shifts){
String output = binInput;
for(int i=0; i<shifts; i++){
output = output.substring(1) + output.charAt(0);
}
return output;
}
}
#####GENERATING SUB KEYS - START#####
Initial Key: 0000000100100011010001010110011110001001101010111100110111101111 | 0123456789ABCDEF
PC-1 Permuted Key: 11110000110011001010101000001010101011001100111100000000 | F0CCAA0AACCF00
Subkey 1: 000010110000001001100111100110110100100110100101 | 0B02679B49A5
Subkey 2: 011010011010011001011001001001010110101000100110 | 69A659256A26
Subkey 3: 010001011101010010001010101101000010100011010010 | 45D48AB428D2
Subkey 4: 011100101000100111010010101001011000001001010111 | 7289D2A58257
Subkey 5: 001111001110100000000011000101111010011011000010 | 3CE80317A6C2
Subkey 6: 001000110010010100011110001111001000010101000101 | 23251E3C8545
Subkey 7: 011011000000010010010101000010101110010011000110 | 6C04950AE4C6
Subkey 8: 010101111000100000111000011011001110010110000001 | 5788386CE581
Subkey 9: 110000001100100111101001001001101011100000111001 | C0C9E926B839
Subkey 10: 100100011110001100000111011000110001110101110010 | 91E307631D72
Subkey 11: 001000010001111110000011000011011000100100111010 | 211F830D893A
Subkey 12: 011100010011000011100101010001010101110001010100 | 7130E5455C54
Subkey 13: 100100011100010011010000010010011000000011111100 | 91C4D04980FC
Subkey 14: 010101000100001110110110100000011101110010001101 | 5443B681DC8D
Subkey 15: 101101101001000100000101000010100001011010110101 | B691050A16B5
Subkey 16: 110010100011110100000011101110000111000000110010 | CA3D03B87032
#####GENERATING SUB KEYS - END#####
#####ENCRYPTION PROCESS - START#####
Input Data: 0001000100010001000100010001000100010001000100010001000100010001 | 1111111111111111
Data after IP: 0000000011111111000000001111111100000000000000000000000000000000 | 00FF00FF00000000
Round 1 - L0: 00000000111111110000000011111111 (00FF00FF) | R0: 00000000000000000000000000000000 (00000000) | Key1: 000010110000001001100111100110110100100110100101 (0B02679B49A5)
Round 2 - L1: 00000000000000000000000000000000 (00000000) | R1: 00101111101011011101000001000010 (2FADD042) | Key2: 011010011010011001011001001001010110101000100110 (69A659256A26)
Round 3 - L2: 00101111101011011101000001000010 (2FADD042) | R2: 10111111101001100001100011010100 (BFA618D4) | Key3: 010001011101010010001010101101000010100011010010 (45D48AB428D2)
Round 4 - L3: 10111111101001100001100011010100 (BFA618D4) | R3: 11111010110101011101110101111001 (FAD5DD79) | Key4: 011100101000100111010010101001011000001001010111 (7289D2A58257)
Round 5 - L4: 11111010110101011101110101111001 (FAD5DD79) | R4: 11001101000110101100100010111001 (CD1AC8B9) | Key5: 001111001110100000000011000101111010011011000010 (3CE80317A6C2)
Round 6 - L5: 11001101000110101100100010111001 (CD1AC8B9) | R5: 10110111100100100110011110010110 (B7926796) | Key6: 001000110010010100011110001111001000010101000101 (23251E3C8545)
Round 7 - L6: 10110111100100100110011110010110 (B7926796) | R6: 10100000011100100000001100111010 (A072033A) | Key7: 011011000000010010010101000010101110010011000110 (6C04950AE4C6)
Round 8 - L7: 10100000011100100000001100111010 (A072033A) | R7: 01111110101011100010001111100000 (7EAE23E0) | Key8: 010101111000100000111000011011001110010110000001 (5788386CE581)
Round 9 - L8: 01111110101011100010001111100000 (7EAE23E0) | R8: 00100010110101110010111011100100 (22D72EE4) | Key9: 110000001100100111101001001001101011100000111001 (C0C9E926B839)
Round 10 - L9: 00100010110101110010111011100100 (22D72EE4) | R9: 10000100000000000111101101010111 (84007B57) | Key10: 100100011110001100000111011000110001110101110010 (91E307631D72)
Round 11 - L10: 10000100000000000111101101010111 (84007B57) | R10: 10101111111011101111000101110000 (AFEEF170) | Key11: 001000010001111110000011000011011000100100111010 (211F830D893A)
Round 12 - L11: 10101111111011101111000101110000 (AFEEF170) | R11: 00011001010000110100100100101001 (19434929) | Key12: 011100010011000011100101010001010101110001010100 (7130E5455C54)
Round 13 - L12: 00011001010000110100100100101001 (19434929) | R12: 00101001000000100010000010000011 (29022083) | Key13: 100100011100010011010000010010011000000011111100 (91C4D04980FC)
Round 14 - L13: 00101001000000100010000010000011 (29022083) | R13: 00111110010001000100010011111101 (3E4444FD) | Key14: 010101000100001110110110100000011101110010001101 (5443B681DC8D)
Round 15 - L14: 00111110010001000100010011111101 (3E4444FD) | R14: 00101000101010111101010100000110 (28ABD506) | Key15: 101101101001000100000101000010100001011010110101 (B691050A16B5)
Round 16 - L15: 00101000101010111101010100000110 (28ABD506) | R15: 00101100100110101000110001110011 (2C9A8C73) | Key16: 110010100011110100000011101110000111000000110010 (CA3D03B87032)
Feistel Output - 0101101001111001100011111100010100101100100110101000110001110011 | 5A798FC52C9A8C73
Final Output: 0001011101100110100011011111110001110010100100100101001100101101 | 17668DFC7292532D
#####ENCRYPTION PROCESS - END#####
#####DECRYPTION PROCESS - START#####
Input Data: 0001011101100110100011011111110001110010100100100101001100101101 | 17668DFC7292532D
Data after IP: 0101101001111001100011111100010100101100100110101000110001110011 | 5A798FC52C9A8C73
Round 1 - L0: 01011010011110011000111111000101 (5A798FC5) | R0: 00101100100110101000110001110011 (2C9A8C73) | Key1: 110010100011110100000011101110000111000000110010 (CA3D03B87032)
Round 2 - L1: 00101100100110101000110001110011 (2C9A8C73) | R1: 00101000101010111101010100000110 (28ABD506) | Key2: 101101101001000100000101000010100001011010110101 (B691050A16B5)
Round 3 - L2: 00101000101010111101010100000110 (28ABD506) | R2: 00111110010001000100010011111101 (3E4444FD) | Key3: 010101000100001110110110100000011101110010001101 (5443B681DC8D)
Round 4 - L3: 00111110010001000100010011111101 (3E4444FD) | R3: 00101001000000100010000010000011 (29022083) | Key4: 100100011100010011010000010010011000000011111100 (91C4D04980FC)
Round 5 - L4: 00101001000000100010000010000011 (29022083) | R4: 00011001010000110100100100101001 (19434929) | Key5: 011100010011000011100101010001010101110001010100 (7130E5455C54)
Round 6 - L5: 00011001010000110100100100101001 (19434929) | R5: 10101111111011101111000101110000 (AFEEF170) | Key6: 001000010001111110000011000011011000100100111010 (211F830D893A)
Round 7 - L6: 10101111111011101111000101110000 (AFEEF170) | R6: 10000100000000000111101101010111 (84007B57) | Key7: 100100011110001100000111011000110001110101110010 (91E307631D72)
Round 8 - L7: 10000100000000000111101101010111 (84007B57) | R7: 00100010110101110010111011100100 (22D72EE4) | Key8: 110000001100100111101001001001101011100000111001 (C0C9E926B839)
Round 9 - L8: 00100010110101110010111011100100 (22D72EE4) | R8: 01111110101011100010001111100000 (7EAE23E0) | Key9: 010101111000100000111000011011001110010110000001 (5788386CE581)
Round 10 - L9: 01111110101011100010001111100000 (7EAE23E0) | R9: 10100000011100100000001100111010 (A072033A) | Key10: 011011000000010010010101000010101110010011000110 (6C04950AE4C6)
Round 11 - L10: 10100000011100100000001100111010 (A072033A) | R10: 10110111100100100110011110010110 (B7926796) | Key11: 001000110010010100011110001111001000010101000101 (23251E3C8545)
Round 12 - L11: 10110111100100100110011110010110 (B7926796) | R11: 11001101000110101100100010111001 (CD1AC8B9) | Key12: 001111001110100000000011000101111010011011000010 (3CE80317A6C2)
Round 13 - L12: 11001101000110101100100010111001 (CD1AC8B9) | R12: 11111010110101011101110101111001 (FAD5DD79) | Key13: 011100101000100111010010101001011000001001010111 (7289D2A58257)
Round 14 - L13: 11111010110101011101110101111001 (FAD5DD79) | R13: 10111111101001100001100011010100 (BFA618D4) | Key14: 010001011101010010001010101101000010100011010010 (45D48AB428D2)
Round 15 - L14: 10111111101001100001100011010100 (BFA618D4) | R14: 00101111101011011101000001000010 (2FADD042) | Key15: 011010011010011001011001001001010110101000100110 (69A659256A26)
Round 16 - L15: 00101111101011011101000001000010 (2FADD042) | R15: 00000000000000000000000000000000 (00000000) | Key16: 000010110000001001100111100110110100100110100101 (0B02679B49A5)
Feistel Output - 0000000011111111000000001111111100000000000000000000000000000000 | 00FF00FF00000000
Final Output: 0001000100010001000100010001000100010001000100010001000100010001 | 1111111111111111
#####DECRYPTION PROCESS - END#####
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment