diff --git a/aes.js b/aes.js index 3685660..4dec7db 100644 --- a/aes.js +++ b/aes.js @@ -1,127 +1,102 @@ /** * Created by Giovanni on 12/05/2015. */ - - var state; var Nr; var Nk; var w = []; +function encrypt (hex){ + var inp = input(hex); -function dec_to_hex ( input ) { - var t = input.toString(16); - if (t.length == 1 ) - return "0" + t; - return t; -} -function bin_to_hex ( input ) { - return dec_to_hex(parseInt(input,2)); -} -function dec_to_bin ( input ) { - var t = input.toString(2); - var ret=t; - if (t.length < 8 ) - for (var i = 0 ; i < (8 - t.length) ; i++){ - ret = "0" + ret; - } - return ret; -} -function hex_to_bin (input) { - return dec_to_bin(parseInt(input, 16)); -} -function hex_to_dec(input){ - return parseInt(input, 16); -} -function bin_to_dec(input){ - return parseInt(input, 2); -} + //////////////////////////////////// begin state = in byte + // state[4,Nb] + //state = in - -function matchExact(r, str) { - var match = str.match(r); - return match != null && str == match[0]; -} - - -var byte = function (string){ - - if (string == undefined || string.length > 8 || !matchExact(/((?:[0-1]+)*)/,string)) - this.content= ["0","0","0","0","0","0","0","0"]; - else - { - this.content= []; - for (var i = 0; i < (8 - string.length); i++) { - this.content[i] = 0; - } - for (; i < 8; i++) { - this.content[i] = string[i - 8 + string.length]; - } + state = new Array(4); + for (var i = 0 ;i< 4; i++){ + state[i] = new Array(4); } - this.hex = function (){return dec_to_hex(this.dec())}; - this.bin=function (){ - var t=""; - for (var i = 0 ; i< 8 ; i++){ - t = t + this.content[i]; - } - return t; - }; - this.dec =function(){return bin_to_dec(this.bin())}; - this.set = function(string){ - if (string == undefined || string.length > 8 || !matchExact(/((?:[0-1]+)*)/,string)) - this.content= ["0","0","0","0","0","0","0","0"]; - else - { - this.content= []; - for (var i = 0; i < (8 - string.length); i++) { - this.content[i] = 0; - } - for (; i < 8; i++) { - this.content[i] = string[i - 8 + string.length]; - } + for (var r = 0 ; r < 4; r++){ + for (var c = 0 ; c < 4; c++){ + state[r][c]= inp[ r + 4*c]; } } - }; + /////////////////////////////////////////////////////// -var word = function (b1,b2,b3,b4){ + //Initiation + AddRoundKey(w.slice(0,4)); - if (arguments.length !=4 ) { - this.byte0 = new byte(); - this.byte1 = new byte(); - this.byte2 = new byte(); - this.byte3 = new byte(); - } else { - this.byte0 = new byte(b1); - this.byte1 = new byte(b2); - this.byte2 = new byte(b3); - this.byte3 = new byte(b4); - } - this.bin = function(){ - return this.byte0.bin() + this.byte1.bin() + this.byte2.bin() + this.byte3.bin(); - } - this.hex = function(){ - return this.byte0.hex() + this.byte1.hex() + this.byte2.hex() + this.byte3.hex(); + //Rounds 0 to n-1 + for (var round = 1; round < Nr ; round++) { + SubBytes(); + ShiftRows(); + MixColumns(); + AddRoundKey(w.slice(round * 4, ((round + 1) * 4))); } -}; + //Last round + SubBytes(); + ShiftRows(); + AddRoundKey(w.slice(Nr*4, ((Nr+1)*4))); + // end last round - - - - -function xor_byte (first,second){ - var ret = new byte(); - for (var i = 0; i< 8; i++){ - if ( (first.content[i] == "0" && second.content[i] == "0" ) || (first.content[i] == "1" && second.content[i] == "1" )) - ret.content[i] = "0"; - else - ret.content[i] = "1"; + //out = state + //byte out[16] + var out = new Array(16); + for ( r = 0 ; r < 4; r++){ + for ( c = 0 ; c < 4; c++){ + out[r + 4*c] = state[r][c]; + } } - return ret; + + return output(out); } +function decrypt (hex) { + + var inp = input(hex); + + //////////////////////////////////// begin state = in byte + // state[4,Nb] + //state = in + + state = new Array(4); + for (var i = 0 ;i< 4; i++){ + state[i] = new Array(4); + } + + for (var r = 0 ; r < 4; r++){ + for (var c = 0 ; c < 4; c++){ + state[r][c]= inp[ r + 4*c]; + } + } + /////////////////////////////////////////////////////// + + AddRoundKey(w.slice(Nr * 4, (Nr + 1) * 4)); + for (var round = Nr - 1; round > 0; round--){ + InvShiftRows(); + InvSubBytes(); + AddRoundKey(w.slice(round * 4, (round + 1) * 4)); + InvMixColumns(); + } + InvShiftRows(); + InvSubBytes(); + AddRoundKey(w.slice(0,4)); + + //out = state + //byte out[16] + var out = new Array(16); + for ( r = 0 ; r < 4; r++){ + for ( c = 0 ; c < 4; c++){ + out[r + 4*c] = state[r][c]; + } + } + + return output(out); +} function AddRoundKey(w){ for (var i = 0 ; i< 4 ;i++){ state[0][i] = xor_byte( state[0][i],w[i].byte0); @@ -130,8 +105,6 @@ function AddRoundKey(w){ state[3][i] = xor_byte( state[3][i],w[i].byte3); } } - - function SubBytes(){ for (var i = 0 ; i< 4 ;i++){ for (var j = 0 ; j< 4 ;j++){ @@ -139,8 +112,6 @@ function SubBytes(){ } } } - - var SubBytesMatrix = [ ["63","7C","77","7B","F2","6B","6F","C5","30","01","67","2B","FE","D7","AB","76"], ["CA","82","C9","7D","FA","59","47","F0","AD","D4","A2","AF","9C","A4","72","C0"], @@ -159,8 +130,59 @@ var SubBytesMatrix = [ ["E1","F8","98","11","69","D9","8E","94","9B","1E","87","E9","CE","55","28","DF"], ["8C","A1","89","0D","BF","E6","42","68","41","99","2D","0F","B0","54","BB","16"] ]; +function InvSubBytes(){ + for (var i = 0 ; i< 4 ;i++){ + for (var j = 0 ; j< 4 ;j++){ + state[i][j] = new byte(hex_to_bin(InvSubBytesMatrix[hex_to_dec(state[i][j].hex().charAt(0))][hex_to_dec(state[i][j].hex().charAt(1))])); + } + } +} +var InvSubBytesMatrix =[ + ["52","09","6A","D5","30","36","A5","38","BF","40","A3","9E","81","F3","D7","FB"], + ["7C","E3","39","82","9B","2F","FF","87","34","8E","43","44","C4","DE","E9","CB"], + ["54","7B","94","32","A6","C2","23","3D","EE","4C","95","0B","42","FA","C3","4E"], + ["08","2E","A1","66","28","D9","24","B2","76","5B","A2","49","6D","8B","D1","25"], + ["72","F8","F6","64","86","68","98","16","D4","A4","5C","CC","5D","65","B6","92"], + ["6C","70","48","50","FD","ED","B9","DA","5E","15","46","57","A7","8D","9D","84"], + ["90","D8","AB","00","8C","BC","D3","0A","F7","E4","58","05","B8","B3","45","06"], + ["D0","2C","1E","8F","CA","3F","0F","02","C1","AF","BD","03","01","13","8A","6B"], + ["3A","91","11","41","4F","67","DC","EA","97","F2","CF","CE","F0","B4","E6","73"], + ["96","AC","74","22","E7","AD","35","85","E2","F9","37","E8","1C","75","DF","6E"], + ["47","F1","1A","71","1D","29","C5","89","6F","B7","62","0E","AA","18","BE","1B"], + ["FC","56","3E","4B","C6","D2","79","20","9A","DB","C0","FE","78","CD","5A","F4"], + ["1F","DD","A8","33","88","07","C7","31","B1","12","10","59","27","80","EC","5F"], + ["60","51","7F","A9","19","B5","4A","0D","2D","E5","7A","9F","93","C9","9C","EF"], + ["A0","E0","3B","4D","AE","2A","F5","B0","C8","EB","BB","3C","83","53","99","61"], + ["17","2B","04","7E","BA","77","D6","26","E1","69","14","63","55","21","0C","7D"] +]; +function MixColumns(){ + + for (var i = 0 ; i< 4 ;i++){ + var first = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][1])) ) , state[2][i] ) , state[3][i] ); + var second = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][1])) ) , state[0][i] ) , state[3][i] ); + var third = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][1])) ) , state[0][i] ) , state[1][i] ); + var fourth = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][1])) ) , state[1][i] ) , state[2][i] ); + state[0][i] = first; + state[1][i] = second; + state[2][i] = third; + state[3][i] = fourth; + } +} +function InvMixColumns(){ + + for (var i = 0 ; i< 4 ;i++){ + var first = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][5])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][3])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][4])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][2])) ); + var second = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][2])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][5])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][3])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][4])) ); + var third = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][4])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][2])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][5])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][3])) ); + var fourth = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][3])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][4])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][2])) ) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][5])) ); + state[0][i] = first; + state[1][i] = second; + state[2][i] = third; + state[3][i] = fourth; + } +} var MixColumnsMatrix =[ ["00","00","00","00","00","00"],["02","03","09","0b","0d","0e"], ["04","06","12","16","1a","1c"],["06","05","1b","1d","17","12"], @@ -291,8 +313,6 @@ var MixColumnsMatrix =[ ["e3","1f","5d","be","80","9f"],["e1","1c","54","b5","8d","91"], ["e7","19","4f","a8","9a","83"],["e5","1a","46","a3","97","8d"] ]; - - function ShiftRows() { var t1,t2,t3; @@ -318,103 +338,38 @@ function ShiftRows() { state[3][3] = t3; } +function InvShiftRows(){ + + + var t1,t2,t3; + t1 = state[1][3]; + state[1][3] = state[1][2]; + state[1][2] = state[1][1]; + state[1][1] = state[1][0]; + state[1][0] = t1; + + t1 = state[2][3]; + t2 = state[2][2]; + state[2][3] = state[2][1]; + state[2][2] = state[2][0]; + state[2][1] = t1; + state[2][0] = t2; + + t1 = state[3][3]; + t2 = state[3][2]; + t3 = state[3][1]; + state[3][3] = state[3][0]; + state[3][2] = t1; + state[3][1] = t2; + state[3][0] = t3; -function MixColumns(){ - for (var i = 0 ; i< 4 ;i++){ - var first = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][1])) ) , state[2][i] ) , state[3][i] ); - var second = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[1][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][1])) ) , state[0][i] ) , state[3][i] ); - var third = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[2][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][1])) ) , state[0][i] ) , state[1][i] ); - var fourth = xor_byte( xor_byte ( xor_byte( new byte( hex_to_bin(MixColumnsMatrix[hex_to_dec(state[3][i].hex())][0])) , new byte(hex_to_bin(MixColumnsMatrix[hex_to_dec(state[0][i].hex())][1])) ) , state[1][i] ) , state[2][i] ); - state[0][i] = first; - state[1][i] = second; - state[2][i] = third; - state[3][i] = fourth; - } } +function KeyExpansion(hex){ - -function print_state(){ - - var ret = ""; - for (var r = 0 ; r < 4; r++){ - for (var c = 0 ; c < 4; c++){ - ret += state[r][c].hex(); - } - } - return ret; -} - -//Cipher(byte in[16], byte out[16], word w[4*(Nr+1)]) -function encrypt (inp){ - - //////////////////////////////////// begin state = in byte - // state[4,Nb] - //state = in - - state = new Array(4); - for (var i = 0 ;i< 4; i++){ - state[i] = new Array(4); - } - - for (var r = 0 ; r < 4; r++){ - for (var c = 0 ; c < 4; c++){ - state[r][c]= inp[ r + 4*c]; - } - } - /////////////////////////////////////////////////////// - - //Initiation - AddRoundKey(w.slice(0,4)); - console.log("begin round " + print_state()); - - //Rounds 0 to n-1 - for (var round = 1; round < Nr ; round++) { - SubBytes(); - console.log("round "+ round + " SubBytes " + print_state()); - ShiftRows(); - console.log("round "+ round + " ShiftRow " + print_state()); - MixColumns(); - console.log("round "+ round + " MixColumns " + print_state()); - AddRoundKey(w.slice(round * 4, ((round + 1) * 4))); - console.log("round "+ round + " AddRoundKey " + print_state()); - } - - //Last round - SubBytes(); - console.log("round "+ round + " SubBytes " + print_state()); - ShiftRows(); - console.log("round "+ round + " ShiftRow " + print_state()); - AddRoundKey(w.slice(Nr*4, ((Nr+1)*4))); - console.log("round "+ round + " AddRoundKey " + print_state()); - // end last round - - //out = state - //byte out[16] - var out = new Array(16); - for ( r = 0 ; r < 4; r++){ - for ( c = 0 ; c < 4; c++){ - out[r + 4*c] = state[r][c]; - } - } - - return out; -} - - -function print_result (out){ - var ret=""; - for (var i=0;i < out.length;i++){ - ret+=out[i].hex(); - } - return ret; -} - - -//byte key[4*Nk], word w[4*(Nr+1)] -function KeyExpansion(key){ + var key = input(hex); if (key.length * 8 == 128) { Nk = 4; @@ -427,77 +382,51 @@ function KeyExpansion(key){ Nr = 14; } - console.log("nk " + Nk); - console.log("nr " + Nr); - - //word temp var temp; var i = 0; while (i < Nk) { w[i] = new word(key[4 * i].bin(), key[4 * i + 1].bin(), key[4 * i + 2].bin(), key[4 * i + 3].bin()); - console.log("w" + i +" " + w[i].hex()); i++; } i = Nk; while (i < 4 * (Nr+1)) { temp = w[i - 1]; - console.log("temp" + temp.hex()); - if ( (i % Nk) == 0 ) { + if ( (i % Nk) == 0 ) temp = xor_word(SubWord(RotWord(temp)), Rcon(i / Nk)); - console.log("after xor with rcon " + temp.hex()); - }else if ((Nk > 6 ) && ((i % Nk) == 4 ) ) + else if ((Nk > 6 ) && ((i % Nk) == 4 ) ) temp = SubWord(temp); w[i] = xor_word(w[i - Nk],temp); - console.log("w[i - Nk] " + w[i - Nk].hex()); - console.log("w[i] " + w[i].hex()); i++; } } - function SubWord( input_word){ - var byte0 = new byte(hex_to_bin(SubBytesMatrix[hex_to_dec(input_word.byte0.hex().charAt(0))][hex_to_dec(input_word.byte0.hex().charAt(1))])); var byte1 = new byte(hex_to_bin(SubBytesMatrix[hex_to_dec(input_word.byte1.hex().charAt(0))][hex_to_dec(input_word.byte1.hex().charAt(1))])); var byte2 = new byte(hex_to_bin(SubBytesMatrix[hex_to_dec(input_word.byte2.hex().charAt(0))][hex_to_dec(input_word.byte2.hex().charAt(1))])); var byte3 = new byte(hex_to_bin(SubBytesMatrix[hex_to_dec(input_word.byte3.hex().charAt(0))][hex_to_dec(input_word.byte3.hex().charAt(1))])); - var ret = new word(byte0.bin(),byte1.bin(),byte2.bin(),byte3.bin()); - console.log("subword " + ret.hex()); return ret; - } - function Rcon (input){ - console.log("rcon input " + input); var value="01"; for (var i = 0;i < input -1; i++){ value = MixColumnsMatrix[hex_to_dec(value)][0]; } var ret = new word( hex_to_bin(value),hex_to_bin("00"),hex_to_bin("00"),hex_to_bin("00") ); - console.log("rcon " + ret.hex()); return ret; } - function RotWord ( input){ var ret = new word(); ret.byte0 = input.byte1; ret.byte1 = input.byte2; ret.byte2 = input.byte3; ret.byte3 = input.byte0; - console.log("rotword " + ret.hex()); return ret; } -function xor_word (first,second){ - var byte0 = xor_byte(first.byte0,second.byte0); - var byte1 = xor_byte(first.byte1,second.byte1); - var byte2 = xor_byte(first.byte2,second.byte2); - var byte3 = xor_byte(first.byte3,second.byte3); - var ret = new word(byte0.bin(),byte1.bin(),byte2.bin(),byte3.bin()); - return ret; -} + diff --git a/index.html b/index.html index 2f68692..430e806 100644 --- a/index.html +++ b/index.html @@ -6,55 +6,19 @@
+