/** * Created by Giovanni on 12/05/2015. */ var state; var Nr; var Nk; var w = []; 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); } 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]; } } 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]; } } } }; var word = function (b1,b2,b3,b4){ 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(); } }; 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"; } return ret; } function AddRoundKey(w){ for (var i = 0 ; i< 4 ;i++){ state[0][i] = xor_byte( state[0][i],w[i].byte0); state[1][i] = xor_byte( state[1][i],w[i].byte1); state[2][i] = xor_byte( state[2][i],w[i].byte2); 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++){ state[i][j] = new byte(hex_to_bin(SubBytesMatrix[hex_to_dec(state[i][j].hex().charAt(0))][hex_to_dec(state[i][j].hex().charAt(1))])); } } } 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"], ["B7","FD","93","26","36","3F","F7","CC","34","A5","E5","F1","71","D8","31","15"], ["04","C7","23","C3","18","96","05","9A","07","12","80","E2","EB","27","B2","75"], ["09","83","2C","1A","1B","6E","5A","A0","52","3B","D6","B3","29","E3","2F","84"], ["53","D1","00","ED","20","FC","B1","5B","6A","CB","BE","39","4A","4C","58","CF"], ["D0","EF","AA","FB","43","4D","33","85","45","F9","02","7F","50","3C","9F","A8"], ["51","A3","40","8F","92","9D","38","F5","BC","B6","DA","21","10","FF","F3","D2"], ["CD","0C","13","EC","5F","97","44","17","C4","A7","7E","3D","64","5D","19","73"], ["60","81","4F","DC","22","2A","90","88","46","EE","B8","14","DE","5E","0B","DB"], ["E0","32","3A","0A","49","06","24","5C","C2","D3","AC","62","91","95","E4","79"], ["E7","C8","37","6D","8D","D5","4E","A9","6C","56","F4","EA","65","7A","AE","08"], ["BA","78","25","2E","1C","A6","B4","C6","E8","DD","74","1F","4B","BD","8B","8A"], ["70","3E","B5","66","48","03","F6","0E","61","35","57","B9","86","C1","1D","9E"], ["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"] ]; 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"], ["08","0c","24","2c","34","38"],["0a","0f","2d","27","39","36"], ["0c","0a","36","3a","2e","24"],["0e","09","3f","31","23","2a"], ["10","18","48","58","68","70"],["12","1b","41","53","65","7e"], ["14","1e","5a","4e","72","6c"],["16","1d","53","45","7f","62"], ["18","14","6c","74","5c","48"],["1a","17","65","7f","51","46"], ["1c","12","7e","62","46","54"],["1e","11","77","69","4b","5a"], ["20","30","90","b0","d0","e0"],["22","33","99","bb","dd","ee"], ["24","36","82","a6","ca","fc"],["26","35","8b","ad","c7","f2"], ["28","3c","b4","9c","e4","d8"],["2a","3f","bd","97","e9","d6"], ["2c","3a","a6","8a","fe","c4"],["2e","39","af","81","f3","ca"], ["30","28","d8","e8","b8","90"],["32","2b","d1","e3","b5","9e"], ["34","2e","ca","fe","a2","8c"],["36","2d","c3","f5","af","82"], ["38","24","fc","c4","8c","a8"],["3a","27","f5","cf","81","a6"], ["3c","22","ee","d2","96","b4"],["3e","21","e7","d9","9b","ba"], ["40","60","3b","7b","bb","db"],["42","63","32","70","b6","d5"], ["44","66","29","6d","a1","c7"],["46","65","20","66","ac","c9"], ["48","6c","1f","57","8f","e3"],["4a","6f","16","5c","82","ed"], ["4c","6a","0d","41","95","ff"],["4e","69","04","4a","98","f1"], ["50","78","73","23","d3","ab"],["52","7b","7a","28","de","a5"], ["54","7e","61","35","c9","b7"],["56","7d","68","3e","c4","b9"], ["58","74","57","0f","e7","93"],["5a","77","5e","04","ea","9d"], ["5c","72","45","19","fd","8f"],["5e","71","4c","12","f0","81"], ["60","50","ab","cb","6b","3b"],["62","53","a2","c0","66","35"], ["64","56","b9","dd","71","27"],["66","55","b0","d6","7c","29"], ["68","5c","8f","e7","5f","03"],["6a","5f","86","ec","52","0d"], ["6c","5a","9d","f1","45","1f"],["6e","59","94","fa","48","11"], ["70","48","e3","93","03","4b"],["72","4b","ea","98","0e","45"], ["74","4e","f1","85","19","57"],["76","4d","f8","8e","14","59"], ["78","44","c7","bf","37","73"],["7a","47","ce","b4","3a","7d"], ["7c","42","d5","a9","2d","6f"],["7e","41","dc","a2","20","61"], ["80","c0","76","f6","6d","ad"],["82","c3","7f","fd","60","a3"], ["84","c6","64","e0","77","b1"],["86","c5","6d","eb","7a","bf"], ["88","cc","52","da","59","95"],["8a","cf","5b","d1","54","9b"], ["8c","ca","40","cc","43","89"],["8e","c9","49","c7","4e","87"], ["90","d8","3e","ae","05","dd"],["92","db","37","a5","08","d3"], ["94","de","2c","b8","1f","c1"],["96","dd","25","b3","12","cf"], ["98","d4","1a","82","31","e5"],["9a","d7","13","89","3c","eb"], ["9c","d2","08","94","2b","f9"],["9e","d1","01","9f","26","f7"], ["a0","f0","e6","46","bd","4d"],["a2","f3","ef","4d","b0","43"], ["a4","f6","f4","50","a7","51"],["a6","f5","fd","5b","aa","5f"], ["a8","fc","c2","6a","89","75"],["aa","ff","cb","61","84","7b"], ["ac","fa","d0","7c","93","69"],["ae","f9","d9","77","9e","67"], ["b0","e8","ae","1e","d5","3d"],["b2","eb","a7","15","d8","33"], ["b4","ee","bc","08","cf","21"],["b6","ed","b5","03","c2","2f"], ["b8","e4","8a","32","e1","05"],["ba","e7","83","39","ec","0b"], ["bc","e2","98","24","fb","19"],["be","e1","91","2f","f6","17"], ["c0","a0","4d","8d","d6","76"],["c2","a3","44","86","db","78"], ["c4","a6","5f","9b","cc","6a"],["c6","a5","56","90","c1","64"], ["c8","ac","69","a1","e2","4e"],["ca","af","60","aa","ef","40"], ["cc","aa","7b","b7","f8","52"],["ce","a9","72","bc","f5","5c"], ["d0","b8","05","d5","be","06"],["d2","bb","0c","de","b3","08"], ["d4","be","17","c3","a4","1a"],["d6","bd","1e","c8","a9","14"], ["d8","b4","21","f9","8a","3e"],["da","b7","28","f2","87","30"], ["dc","b2","33","ef","90","22"],["de","b1","3a","e4","9d","2c"], ["e0","90","dd","3d","06","96"],["e2","93","d4","36","0b","98"], ["e4","96","cf","2b","1c","8a"],["e6","95","c6","20","11","84"], ["e8","9c","f9","11","32","ae"],["ea","9f","f0","1a","3f","a0"], ["ec","9a","eb","07","28","b2"],["ee","99","e2","0c","25","bc"], ["f0","88","95","65","6e","e6"],["f2","8b","9c","6e","63","e8"], ["f4","8e","87","73","74","fa"],["f6","8d","8e","78","79","f4"], ["f8","84","b1","49","5a","de"],["fa","87","b8","42","57","d0"], ["fc","82","a3","5f","40","c2"],["fe","81","aa","54","4d","cc"], ["1b","9b","ec","f7","da","41"],["19","98","e5","fc","d7","4f"], ["1f","9d","fe","e1","c0","5d"],["1d","9e","f7","ea","cd","53"], ["13","97","c8","db","ee","79"],["11","94","c1","d0","e3","77"], ["17","91","da","cd","f4","65"],["15","92","d3","c6","f9","6b"], ["0b","83","a4","af","b2","31"],["09","80","ad","a4","bf","3f"], ["0f","85","b6","b9","a8","2d"],["0d","86","bf","b2","a5","23"], ["03","8f","80","83","86","09"],["01","8c","89","88","8b","07"], ["07","89","92","95","9c","15"],["05","8a","9b","9e","91","1b"], ["3b","ab","7c","47","0a","a1"],["39","a8","75","4c","07","af"], ["3f","ad","6e","51","10","bd"],["3d","ae","67","5a","1d","b3"], ["33","a7","58","6b","3e","99"],["31","a4","51","60","33","97"], ["37","a1","4a","7d","24","85"],["35","a2","43","76","29","8b"], ["2b","b3","34","1f","62","d1"],["29","b0","3d","14","6f","df"], ["2f","b5","26","09","78","cd"],["2d","b6","2f","02","75","c3"], ["23","bf","10","33","56","e9"],["21","bc","19","38","5b","e7"], ["27","b9","02","25","4c","f5"],["25","ba","0b","2e","41","fb"], ["5b","fb","d7","8c","61","9a"],["59","f8","de","87","6c","94"], ["5f","fd","c5","9a","7b","86"],["5d","fe","cc","91","76","88"], ["53","f7","f3","a0","55","a2"],["51","f4","fa","ab","58","ac"], ["57","f1","e1","b6","4f","be"],["55","f2","e8","bd","42","b0"], ["4b","e3","9f","d4","09","ea"],["49","e0","96","df","04","e4"], ["4f","e5","8d","c2","13","f6"],["4d","e6","84","c9","1e","f8"], ["43","ef","bb","f8","3d","d2"],["41","ec","b2","f3","30","dc"], ["47","e9","a9","ee","27","ce"],["45","ea","a0","e5","2a","c0"], ["7b","cb","47","3c","b1","7a"],["79","c8","4e","37","bc","74"], ["7f","cd","55","2a","ab","66"],["7d","ce","5c","21","a6","68"], ["73","c7","63","10","85","42"],["71","c4","6a","1b","88","4c"], ["77","c1","71","06","9f","5e"],["75","c2","78","0d","92","50"], ["6b","d3","0f","64","d9","0a"],["69","d0","06","6f","d4","04"], ["6f","d5","1d","72","c3","16"],["6d","d6","14","79","ce","18"], ["63","df","2b","48","ed","32"],["61","dc","22","43","e0","3c"], ["67","d9","39","5e","f7","2e"],["65","da","30","55","fa","20"], ["9b","5b","9a","01","b7","ec"],["99","58","93","0a","ba","e2"], ["9f","5d","88","17","ad","f0"],["9d","5e","81","1c","a0","fe"], ["93","57","be","2d","83","d4"],["91","54","b7","26","8e","da"], ["97","51","ac","3b","99","c8"],["95","52","a5","30","94","c6"], ["8b","43","d2","59","df","9c"],["89","40","db","52","d2","92"], ["8f","45","c0","4f","c5","80"],["8d","46","c9","44","c8","8e"], ["83","4f","f6","75","eb","a4"],["81","4c","ff","7e","e6","aa"], ["87","49","e4","63","f1","b8"],["85","4a","ed","68","fc","b6"], ["bb","6b","0a","b1","67","0c"],["b9","68","03","ba","6a","02"], ["bf","6d","18","a7","7d","10"],["bd","6e","11","ac","70","1e"], ["b3","67","2e","9d","53","34"],["b1","64","27","96","5e","3a"], ["b7","61","3c","8b","49","28"],["b5","62","35","80","44","26"], ["ab","73","42","e9","0f","7c"],["a9","70","4b","e2","02","72"], ["af","75","50","ff","15","60"],["ad","76","59","f4","18","6e"], ["a3","7f","66","c5","3b","44"],["a1","7c","6f","ce","36","4a"], ["a7","79","74","d3","21","58"],["a5","7a","7d","d8","2c","56"], ["db","3b","a1","7a","0c","37"],["d9","38","a8","71","01","39"], ["df","3d","b3","6c","16","2b"],["dd","3e","ba","67","1b","25"], ["d3","37","85","56","38","0f"],["d1","34","8c","5d","35","01"], ["d7","31","97","40","22","13"],["d5","32","9e","4b","2f","1d"], ["cb","23","e9","22","64","47"],["c9","20","e0","29","69","49"], ["cf","25","fb","34","7e","5b"],["cd","26","f2","3f","73","55"], ["c3","2f","cd","0e","50","7f"],["c1","2c","c4","05","5d","71"], ["c7","29","df","18","4a","63"],["c5","2a","d6","13","47","6d"], ["fb","0b","31","ca","dc","d7"],["f9","08","38","c1","d1","d9"], ["ff","0d","23","dc","c6","cb"],["fd","0e","2a","d7","cb","c5"], ["f3","07","15","e6","e8","ef"],["f1","04","1c","ed","e5","e1"], ["f7","01","07","f0","f2","f3"],["f5","02","0e","fb","ff","fd"], ["eb","13","79","92","b4","a7"],["e9","10","70","99","b9","a9"], ["ef","15","6b","84","ae","bb"],["ed","16","62","8f","a3","b5"], ["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; t1 = state[1][0]; state[1][0] = state[1][1]; state[1][1] = state[1][2]; state[1][2] = state[1][3]; state[1][3] = t1; t1 = state[2][0]; t2 = state[2][1]; state[2][0] = state[2][2]; state[2][1] = state[2][3]; state[2][2] = t1; state[2][3] = t2; t1 = state[3][0]; t2 = state[3][1]; t3 = state[3][2]; state[3][0] = state[3][3]; state[3][1] = t1; state[3][2] = t2; state[3][3] = 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 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){ if (key.length * 8 == 128) { Nk = 4; Nr = 10; } else if (key.length * 8 == 192){ Nk = 6; Nr = 12; }else { Nk=8; 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 ) { temp = xor_word(SubWord(RotWord(temp)), Rcon(i / Nk)); console.log("after xor with rcon " + temp.hex()); }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; }