Skip to content

Instantly share code, notes, and snippets.

@mfrazi
Last active April 18, 2016 03:46
Show Gist options
  • Save mfrazi/1fddbe98d19094afe741aaf701b79dfc to your computer and use it in GitHub Desktop.
Save mfrazi/1fddbe98d19094afe741aaf701b79dfc to your computer and use it in GitHub Desktop.
BEAUTIFUL_VIEW = 1;
PC_1 = [ 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 ];
iteration_ls = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];
PC_2 = [ 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 ];
IP = [ 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 ];
IP_INVERSE = [ 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 ];
E_BIT_SELECTION = [ 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 ];
s_box = [
[
[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]
]
];
P = [ 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 ];
function convert_string_to_binary(input){
var output = "";
for(var i=0; i< input.length; i++){
var tmp = input[i].charCodeAt(0).toString(2);
while(tmp.length < 8){
tmp = '0'+tmp;
}
output += tmp;
}
return output;
}
function convert_number_to_binary(input, length){
var tmp = input.toString(2);
while(tmp.length < length){
tmp = '0'+tmp;
}
return tmp;
}
function convert_binary_to_string(input, length_bit_per_char){
var result = "";
for(var i=0; i<input.length; i+=length_bit_per_char){
result += String.fromCharCode(parseInt(input.substring(i,i+length_bit_per_char), 2));
}
return result;
}
function string_permutation(string, matrix){
var result = "";
for(var i=0; i<matrix.length; i++){
result += string[matrix[i]-1];
}
return result;
}
function beautiful_bit_view(input, block_size){
if(BEAUTIFUL_VIEW == 0)
return input;
var result = "";
for(var i=0; i<input.length; i+=block_size){
result += input.substring(i, i+block_size);
if(i < input.length-block_size)
result += " ";
}
return result;
}
function create_keys(K_E_Y){
var result = {};
result.key_create_process = "KEY\t\t\t= " + beautiful_bit_view(K_E_Y, 8) + "\n";
var permutation_key = string_permutation(K_E_Y, PC_1);
result.key_create_process += "KEY > PC_1\t= " + beautiful_bit_view(permutation_key, 7) + "\n\n";
var left = [permutation_key.substring(0,28)];
var right = [permutation_key.substring(28,56)];
var keys = [];
result.key_create_process += "C0\t\t= " + beautiful_bit_view(left[0], 4) + " || D0 = " + beautiful_bit_view(right[0], 4) + "\n\n";
for(var i=0; i<16; i++){
left.push(left[i].substring(iteration_ls[i],28)+left[i].substring(0,iteration_ls[i]));
right.push(right[i].substring(iteration_ls[i],28)+right[i].substring(0,iteration_ls[i]));
result.key_create_process += "C" + (i+1) + "\t\t= " + beautiful_bit_view(left[i+1], 4) + " || D" + (i+1) + " = " + beautiful_bit_view(right[i+1], 4) + "\n";
var tmp_key = left[i+1]+right[i+1];
result.key_create_process += "C" + (i+1) + "D" + (i+1) + "\t= " + beautiful_bit_view(tmp_key, 7) + "\n";
var tmp_permutation_key = string_permutation(tmp_key, PC_2);
keys.push(tmp_permutation_key);
result.key_create_process += "K" + (i+1) + "\t\t= " + beautiful_bit_view(tmp_permutation_key, 6) + "\n\n";
}
result.keys = keys;
return result;
}
function xor_binary_string(string1, string2, length){
while(string1.length < length)
string1 = '0' + string1;
while(string2.length < length)
string2 = '0' + string2;
var result = "";
for(var i=0; i<length; i++){
result += (parseInt(string1[i])^parseInt(string2[i])).toString();
}
return result;
}
function do_sbox_function(input){
var result = "";
for(var i=0; i<48; i+=6){
var row = (input[i]-'0')*2+(input[i+5]-'0');
var col = (input[i+1]-'0')*8+(input[i+2]-'0')*4+(input[i+3]-'0')*2+(input[i+4]-'0');
var Bx = s_box[parseInt(i/6)][row][col];
result += convert_number_to_binary(Bx, 4);
}
return result;
}
// M_O_D_E => 0 for encrypt
// M_O_D_E => 1 for decrypt
function DES(M_E_S_S_A_G_E, keys, M_O_D_E){
var result = {};
result.des_create_process = "Message CBC\t\t= " + beautiful_bit_view(M_E_S_S_A_G_E, 8) + "\n";
var permutation_message = string_permutation(M_E_S_S_A_G_E, IP);
result.des_create_process += "Message > IP\t= " + beautiful_bit_view(permutation_message, 8) + "\n\n";
var side1 = permutation_message.substring(0, 32);
var side2 = permutation_message.substring(32, 64);
result.des_create_process += "L = " + beautiful_bit_view(side1, 4) + " || R = " + beautiful_bit_view(side2, 4) + "\n";
if(M_O_D_E == 0){
var from = 0;
var to = 15;
}
else if(M_O_D_E == 1){
from = 15;
to = 0;
}
var round = 1;
for(var i=from;;){
if((M_O_D_E == 0 && i>to) || (M_O_D_E == 1 && i<0)) break;
result.des_create_process += "\nROUND " + round + " :\n";
var tmp_side1 = side1;
side1 = side2;
result.des_create_process += "L" + round + "\t\t\t\t= " + beautiful_bit_view(side1, 4) + "\n";
side2 = string_permutation(side2, E_BIT_SELECTION);
result.des_create_process += "E bit selection\t= " + beautiful_bit_view(side2, 6) + "\n";
var side2_xor_key = xor_binary_string(side2, keys[i], 48);
result.des_create_process += "E XOR K\t\t\t= " + beautiful_bit_view(side2_xor_key, 6) + "\n";
var s_box_result = do_sbox_function(side2_xor_key);
result.des_create_process += "SBox \t\t\t= " + beautiful_bit_view(s_box_result, 4) + "\n";
var permutation_sbox_result = string_permutation(s_box_result, P);
result.des_create_process += "SBox > P\t\t= " + beautiful_bit_view(permutation_sbox_result, 4) + "\n";
side2 = xor_binary_string(tmp_side1, permutation_sbox_result, 32);
result.des_create_process += "R" + round + "\t\t\t\t= " + beautiful_bit_view(side2, 4) + "\n";
M_O_D_E == 0 ? i++ : i--;
round ++;
}
var tmp = side2+side1;
result.des_create_process += "\nR + L\t\t\t= " + beautiful_bit_view(tmp, 8) + "\n";
var tmp_result = string_permutation(tmp, IP_INVERSE);
result.des_create_process += "RL > IP INVERSE\t= " + beautiful_bit_view(tmp_result, 8) + "\n";
result.des_create_process += "Result DES\t\t= " + beautiful_bit_view(tmp_result, 8) + "\n";
result.des_create_process += "DES ASCII\t\t= " + convert_binary_to_string(tmp_result, 8) + "\n";
result.des_binner_result = tmp_result;
return result;
}
/**
* @return {{}}
*/
function DES_CBC_ENCRYPT(M_E_S_S_A_G_E, K_E_Y, V_E_C_T_O_R){
var result = {};
var create_keys_data = create_keys(K_E_Y);
result.key_create_process = create_keys_data.key_create_process;
var keys = create_keys_data.keys;
var message_in_binner = convert_string_to_binary(M_E_S_S_A_G_E);
result.des_create_process = "";
result.des_binner = "";
while(message_in_binner.length%64 != 0){
message_in_binner += '0';
}
for(var i=0; i<message_in_binner.length; i+=64){
result.des_create_process += "\nBLOCK " + (i/64+1) + " :\n";
result.des_create_process += "Message\t\t\t= " + beautiful_bit_view(message_in_binner.substring(i, i+64), 8) + "\n";
result.des_create_process += "Vector\t\t\t= " + beautiful_bit_view(V_E_C_T_O_R, 8) + "\n";
var input_message = xor_binary_string(V_E_C_T_O_R, message_in_binner.substring(i, i+64), 64);
var des_data = DES(input_message, keys, 0);
V_E_C_T_O_R = des_data.des_binner_result;
result.des_binner += des_data.des_binner_result;
result.des_create_process += des_data.des_create_process;
}
result.des = convert_binary_to_string(result.des_binner, 8);
return result;
}
/**
* @return {{}}
*/
function DES_CBC_DECRYPT(M_E_S_S_A_G_E, K_E_Y, V_E_C_T_O_R){
var result = {};
var create_keys_data = create_keys(K_E_Y);
result.key_create_process = create_keys_data.key_create_process;
var keys = create_keys_data.keys;
var message_in_binner = convert_string_to_binary(M_E_S_S_A_G_E);
result.des_create_process = "";
result.des_binner = "";
while(message_in_binner.length%64 != 0){
message_in_binner += '0';
}
for(var i=0; i<message_in_binner.length; i+=64){
result.des_create_process += "\nBLOCK " + (i/64+1) + " :\n";
result.des_create_process += "Message\t\t\t= " + beautiful_bit_view(message_in_binner.substring(i, i+64), 8) + "\n";
result.des_create_process += "Vector\t\t\t= " + beautiful_bit_view(V_E_C_T_O_R, 8) + "\n";
var des_data = DES(message_in_binner.substring(i, i+64), keys, 1);
result.des_create_process += des_data.des_create_process;
var des_message = des_data.des_binner_result;
result.des_binner += xor_binary_string(V_E_C_T_O_R, des_message, 64);
result.des_create_process += "Result CBC\t\t= " + beautiful_bit_view(xor_binary_string(V_E_C_T_O_R, des_message, 64), 8) + "\n";
V_E_C_T_O_R = message_in_binner.substring(i, i+64);
}
result.des = convert_binary_to_string(result.des_binner, 8);
return result;
}
//Example Usage
// Key must be 64 bits or 8 character
K_E_Y = '0001001100110100010101110111100110011011101111001101111111110001';
// K_E_Y = convert_string_to_binary('12345678');
// Vector must be 64 bit length or 8 character
V_E_C_T_O_R = '0000100010001100011001110101110110010001111110001010101100110111';
// V_E_C_T_O_R = convert_string_to_binary('09876543');
M_E_S_S_A_G_E = 'Hei there, how are you?';
var x = DES_CBC_ENCRYPT(M_E_S_S_A_G_E, K_E_Y, V_E_C_T_O_R);
console.log("Key Create Process\n" + x.key_create_process);
console.log("DES Create Process\n" + x.des_create_process);
console.log("DES Binner\n" + beautiful_bit_view(x.des_binner, 8) + "\n");
console.log("Encrypted message\n" + x.des);
var y = DES_CBC_DECRYPT(x.des, K_E_Y, V_E_C_T_O_R);
console.log("Key Create Process\n" + y.key_create_process);
console.log("DES Create Process\n" + y.des_create_process);
console.log("DES Binner\n" + beautiful_bit_view(y.des_binner, 8) + "\n");
console.log("Decrypted message\n" + y.des);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment