UNPKG

39.6 kBJavaScriptView Raw
1/**
2* @license Gibberish-AES
3* A lightweight Javascript Libray for OpenSSL compatible AES CBC encryption.
4*
5* Author: Mark Percival
6* Email: mark@mpercival.com
7* Copyright: Mark Percival - http://mpercival.com 2008
8*
9* With thanks to:
10* Josh Davis - http://www.josh-davis.org/ecmaScrypt
11* Chris Veness - http://www.movable-type.co.uk/scripts/aes.html
12* Michel I. Gallant - http://www.jensign.com/
13* Jean-Luc Cooke <jlcooke@certainkey.com> 2012-07-12: added strhex + invertArr to compress G2X/G3X/G9X/GBX/GEX/SBox/SBoxInv/Rcon saving over 7KB, and added encString, decString, also made the MD5 routine more easlier compressible using yuicompressor.
14*
15* License: MIT
16*
17* Usage: GibberishAES.enc("secret", "password")
18* Outputs: AES Encrypted text encoded in Base64
19*/
20
21
22var GibberishAES = (function(){
23 var Nr = 14,
24 /* Default to 256 Bit Encryption */
25 Nk = 8,
26 Decrypt = false,
27
28 enc_utf8 = function(s)
29 {
30 try {
31 return unescape(encodeURIComponent(s));
32 }
33 catch(e) {
34 throw 'Error on UTF-8 encode';
35 }
36 },
37
38 dec_utf8 = function(s)
39 {
40 try {
41 return decodeURIComponent(escape(s));
42 }
43 catch(e) {
44 throw ('Bad Key');
45 }
46 },
47
48 padBlock = function(byteArr)
49 {
50 var array = [], cpad, i;
51 if (byteArr.length < 16) {
52 cpad = 16 - byteArr.length;
53 array = [cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad];
54 }
55 for (i = 0; i < byteArr.length; i++)
56 {
57 array[i] = byteArr[i];
58 }
59 return array;
60 },
61
62 block2s = function(block, lastBlock)
63 {
64 lastBlock = false;
65 var string = '', padding, i;
66 if (lastBlock) {
67 padding = block[15];
68 if (padding > 16) {
69 throw ('Decryption error: Maybe bad key');
70 }
71 if (padding == 16) {
72 return '';
73 }
74 for (i = 0; i < 16 - padding; i++) {
75 string += String.fromCharCode(block[i]);
76 }
77 } else {
78 for (i = 0; i < 16; i++) {
79 string += String.fromCharCode(block[i]);
80 }
81 }
82 return string;
83 },
84
85 a2h = function(numArr)
86 {
87 var string = '', i;
88 for (i = 0; i < numArr.length; i++) {
89 string += (numArr[i] < 16 ? '0': '') + numArr[i].toString(16);
90 }
91 return string;
92 },
93
94 h2a = function(s)
95 {
96 var ret = [];
97 s.replace(/(..)/g,
98 function(s) {
99 ret.push(parseInt(s, 16));
100 });
101 return ret;
102 },
103
104 s2a = function(string, binary) {
105 var array = [], i;
106
107 if (! binary) {
108 string = enc_utf8(string);
109 }
110
111 for (i = 0; i < string.length; i++)
112 {
113 array[i] = string.charCodeAt(i);
114 }
115
116 return array;
117 },
118
119 size = function(newsize)
120 {
121 switch (newsize)
122 {
123 case 128:
124 Nr = 10;
125 Nk = 4;
126 break;
127 case 192:
128 Nr = 12;
129 Nk = 6;
130 break;
131 case 256:
132 Nr = 14;
133 Nk = 8;
134 break;
135 default:
136 throw ('Invalid Key Size Specified:' + newsize);
137 }
138 },
139
140 randArr = function(num) {
141 var result = [], i;
142 for (i = 0; i < num; i++) {
143 result = result.concat(Math.floor(Math.random() * 256));
144 }
145 return result;
146 },
147
148 openSSLKey = function(passwordArr, saltArr) {
149 // Number of rounds depends on the size of the AES in use
150 // 3 rounds for 256
151 // 2 rounds for the key, 1 for the IV
152 // 2 rounds for 128
153 // 1 round for the key, 1 round for the IV
154 // 3 rounds for 192 since it's not evenly divided by 128 bits
155 var rounds = Nr >= 12 ? 3: 2,
156 key = [],
157 iv = [],
158 md5_hash = [],
159 result = [],
160 data00 = passwordArr.concat(saltArr),
161 i;
162 md5_hash[0] = GibberishAES.Hash.MD5(data00);
163 result = md5_hash[0];
164 for (i = 1; i < rounds; i++) {
165 md5_hash[i] = GibberishAES.Hash.MD5(md5_hash[i - 1].concat(data00));
166 result = result.concat(md5_hash[i]);
167 }
168 key = result.slice(0, 4 * Nk);
169 iv = result.slice(4 * Nk, 4 * Nk + 16);
170 return {
171 key: key,
172 iv: iv
173 };
174 },
175
176 rawEncrypt = function(plaintext, key, iv) {
177 // plaintext, key and iv as byte arrays
178 key = expandKey(key);
179 var numBlocks = Math.ceil(plaintext.length / 16),
180 blocks = [],
181 i,
182 cipherBlocks = [];
183 for (i = 0; i < numBlocks; i++) {
184 blocks[i] = plaintext.slice(i * 16, i * 16 + 16);
185 // blocks[i] = padBlock(plaintext.slice(i * 16, i * 16 + 16));
186 }
187 if (plaintext.length % 16 === 0) {
188 // blocks.push([16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]);
189 // CBC OpenSSL padding scheme
190 // numBlocks++;
191 }
192 for (i = 0; i < blocks.length; i++) {
193 blocks[i] = (i === 0) ? xorBlocks(blocks[i], iv) : xorBlocks(blocks[i], cipherBlocks[i - 1]);
194 cipherBlocks[i] = encryptBlock(blocks[i], key);
195 }
196 return cipherBlocks;
197 },
198
199 rawDecrypt = function(cryptArr, key, iv, binary) {
200 // cryptArr, key and iv as byte arrays
201 key = expandKey(key);
202 var numBlocks = cryptArr.length / 16,
203 cipherBlocks = [],
204 i,
205 plainBlocks = [],
206 string = '';
207 for (i = 0; i < numBlocks; i++) {
208 cipherBlocks.push(cryptArr.slice(i * 16, (i + 1) * 16));
209 }
210 for (i = cipherBlocks.length - 1; i >= 0; i--) {
211 plainBlocks[i] = decryptBlock(cipherBlocks[i], key);
212 plainBlocks[i] = (i === 0) ? xorBlocks(plainBlocks[i], iv) : xorBlocks(plainBlocks[i], cipherBlocks[i - 1]);
213 }
214 for (i = 0; i < numBlocks - 1; i++) {
215 string += block2s(plainBlocks[i]);
216 }
217 string += block2s(plainBlocks[i], true);
218 return binary ? string : dec_utf8(string);
219 },
220
221 encryptBlock = function(block, words) {
222 Decrypt = false;
223 var state = addRoundKey(block, words, 0),
224 round;
225 for (round = 1; round < (Nr + 1); round++) {
226 state = subBytes(state);
227 state = shiftRows(state);
228 if (round < Nr) {
229 state = mixColumns(state);
230 }
231 //last round? don't mixColumns
232 state = addRoundKey(state, words, round);
233 }
234
235 return state;
236 },
237
238 decryptBlock = function(block, words) {
239 Decrypt = true;
240 var state = addRoundKey(block, words, Nr),
241 round;
242 for (round = Nr - 1; round > -1; round--) {
243 state = shiftRows(state);
244 state = subBytes(state);
245 state = addRoundKey(state, words, round);
246 if (round > 0) {
247 state = mixColumns(state);
248 }
249 //last round? don't mixColumns
250 }
251
252 return state;
253 },
254
255 subBytes = function(state) {
256 var S = Decrypt ? SBoxInv: SBox,
257 temp = [],
258 i;
259 for (i = 0; i < 16; i++) {
260 temp[i] = S[state[i]];
261 }
262 return temp;
263 },
264
265 shiftRows = function(state) {
266 var temp = [],
267 shiftBy = Decrypt ? [0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3] : [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11],
268 i;
269 for (i = 0; i < 16; i++) {
270 temp[i] = state[shiftBy[i]];
271 }
272 return temp;
273 },
274
275 mixColumns = function(state) {
276 var t = [],
277 c;
278 if (!Decrypt) {
279 for (c = 0; c < 4; c++) {
280 t[c * 4] = G2X[state[c * 4]] ^ G3X[state[1 + c * 4]] ^ state[2 + c * 4] ^ state[3 + c * 4];
281 t[1 + c * 4] = state[c * 4] ^ G2X[state[1 + c * 4]] ^ G3X[state[2 + c * 4]] ^ state[3 + c * 4];
282 t[2 + c * 4] = state[c * 4] ^ state[1 + c * 4] ^ G2X[state[2 + c * 4]] ^ G3X[state[3 + c * 4]];
283 t[3 + c * 4] = G3X[state[c * 4]] ^ state[1 + c * 4] ^ state[2 + c * 4] ^ G2X[state[3 + c * 4]];
284 }
285 }else {
286 for (c = 0; c < 4; c++) {
287 t[c*4] = GEX[state[c*4]] ^ GBX[state[1+c*4]] ^ GDX[state[2+c*4]] ^ G9X[state[3+c*4]];
288 t[1+c*4] = G9X[state[c*4]] ^ GEX[state[1+c*4]] ^ GBX[state[2+c*4]] ^ GDX[state[3+c*4]];
289 t[2+c*4] = GDX[state[c*4]] ^ G9X[state[1+c*4]] ^ GEX[state[2+c*4]] ^ GBX[state[3+c*4]];
290 t[3+c*4] = GBX[state[c*4]] ^ GDX[state[1+c*4]] ^ G9X[state[2+c*4]] ^ GEX[state[3+c*4]];
291 }
292 }
293
294 return t;
295 },
296
297 addRoundKey = function(state, words, round) {
298 var temp = [],
299 i;
300 for (i = 0; i < 16; i++) {
301 temp[i] = state[i] ^ words[round][i];
302 }
303 return temp;
304 },
305
306 xorBlocks = function(block1, block2) {
307 var temp = [],
308 i;
309 for (i = 0; i < 16; i++) {
310 temp[i] = block1[i] ^ block2[i];
311 }
312 return temp;
313 },
314
315 expandKey = function(key) {
316 // Expects a 1d number array
317 var w = [],
318 temp = [],
319 i,
320 r,
321 t,
322 flat = [],
323 j;
324
325 for (i = 0; i < Nk; i++) {
326 r = [key[4 * i], key[4 * i + 1], key[4 * i + 2], key[4 * i + 3]];
327 w[i] = r;
328 }
329
330 for (i = Nk; i < (4 * (Nr + 1)); i++) {
331 w[i] = [];
332 for (t = 0; t < 4; t++) {
333 temp[t] = w[i - 1][t];
334 }
335 if (i % Nk === 0) {
336 temp = subWord(rotWord(temp));
337 temp[0] ^= Rcon[i / Nk - 1];
338 } else if (Nk > 6 && i % Nk == 4) {
339 temp = subWord(temp);
340 }
341 for (t = 0; t < 4; t++) {
342 w[i][t] = w[i - Nk][t] ^ temp[t];
343 }
344 }
345 for (i = 0; i < (Nr + 1); i++) {
346 flat[i] = [];
347 for (j = 0; j < 4; j++) {
348 flat[i].push(w[i * 4 + j][0], w[i * 4 + j][1], w[i * 4 + j][2], w[i * 4 + j][3]);
349 }
350 }
351 return flat;
352 },
353
354 subWord = function(w) {
355 // apply SBox to 4-byte word w
356 for (var i = 0; i < 4; i++) {
357 w[i] = SBox[w[i]];
358 }
359 return w;
360 },
361
362 rotWord = function(w) {
363 // rotate 4-byte word w left by one byte
364 var tmp = w[0],
365 i;
366 for (i = 0; i < 4; i++) {
367 w[i] = w[i + 1];
368 }
369 w[3] = tmp;
370 return w;
371 },
372
373// jlcooke: 2012-07-12: added strhex + invertArr to compress G2X/G3X/G9X/GBX/GEX/SBox/SBoxInv/Rcon saving over 7KB, and added encString, decString
374 strhex = function(str,size) {
375 var ret = [];
376 for (i=0; i<str.length; i+=size)
377 ret[i/size] = parseInt(str.substr(i,size), 16);
378 return ret;
379 },
380 invertArr = function(arr) {
381 var ret = [];
382 for (i=0; i<arr.length; i++)
383 ret[arr[i]] = i;
384 return ret;
385 },
386 Gxx = function(a, b) {
387 var i, ret;
388
389 ret = 0;
390 for (i=0; i<8; i++) {
391 ret = ((b&1)==1) ? ret^a : ret;
392 /* xmult */
393 a = (a>0x7f) ? 0x11b^(a<<1) : (a<<1);
394 b >>>= 1;
395 }
396
397 return ret;
398 },
399 Gx = function(x) {
400 var r = [];
401 for (var i=0; i<256; i++)
402 r[i] = Gxx(x, i);
403 return r;
404 },
405
406 // S-box
407/*
408 SBox = [
409 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171,
410 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
411 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113,
412 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
413 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214,
414 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
415 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69,
416 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
417 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68,
418 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
419 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,
420 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
421 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37,
422 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
423 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,
424 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
425 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187,
426 22], //*/ SBox = strhex('637c777bf26b6fc53001672bfed7ab76ca82c97dfa5947f0add4a2af9ca472c0b7fd9326363ff7cc34a5e5f171d8311504c723c31896059a071280e2eb27b27509832c1a1b6e5aa0523bd6b329e32f8453d100ed20fcb15b6acbbe394a4c58cfd0efaafb434d338545f9027f503c9fa851a3408f929d38f5bcb6da2110fff3d2cd0c13ec5f974417c4a77e3d645d197360814fdc222a908846eeb814de5e0bdbe0323a0a4906245cc2d3ac629195e479e7c8376d8dd54ea96c56f4ea657aae08ba78252e1ca6b4c6e8dd741f4bbd8b8a703eb5664803f60e613557b986c11d9ee1f8981169d98e949b1e87e9ce5528df8ca1890dbfe6426841992d0fb054bb16',2),
427
428 // Precomputed lookup table for the inverse SBox
429/* SBoxInv = [
430 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215,
431 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
432 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66,
433 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
434 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92,
435 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
436 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,
437 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
438 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220,
439 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
440 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29,
441 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
442 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168,
443 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
444 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160,
445 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
446 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12,
447 125], //*/ SBoxInv = invertArr(SBox),
448
449 // Rijndael Rcon
450/*
451 Rcon = [1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94,
452 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145],
453//*/ Rcon = strhex('01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc591',2),
454
455/*
456 G2X = [
457 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
458 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
459 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
460 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
461 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,
462 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
463 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,
464 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
465 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,
466 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
467 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,
468 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
469 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,
470 0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,
471 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,
472 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
473 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,
474 0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,
475 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,
476 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
477 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,
478 0xe3, 0xe1, 0xe7, 0xe5
479 ], //*/ G2X = Gx(2),
480
481/* G3X = [
482 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,
483 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,
484 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,
485 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
486 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,
487 0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,
488 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,
489 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
490 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,
491 0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,
492 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,
493 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
494 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,
495 0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,
496 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,
497 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
498 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,
499 0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,
500 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,
501 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
502 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,
503 0x1f, 0x1c, 0x19, 0x1a
504 ], //*/ G3X = Gx(3),
505
506/*
507 G9X = [
508 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53,
509 0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
510 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20,
511 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
512 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8,
513 0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
514 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd,
515 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
516 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e,
517 0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
518 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7,
519 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
520 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f,
521 0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
522 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c,
523 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
524 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9,
525 0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
526 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba,
527 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
528 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62,
529 0x5d, 0x54, 0x4f, 0x46
530 ], //*/ G9X = Gx(9),
531
532/* GBX = [
533 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45,
534 0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
535 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66,
536 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
537 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e,
538 0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
539 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b,
540 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
541 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8,
542 0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
543 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea,
544 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
545 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02,
546 0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
547 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21,
548 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
549 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44,
550 0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
551 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67,
552 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
553 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f,
554 0xbe, 0xb5, 0xa8, 0xa3
555 ], //*/ GBX = Gx(0xb),
556
557/*
558 GDX = [
559 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f,
560 0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
561 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac,
562 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
563 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14,
564 0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
565 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa,
566 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
567 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9,
568 0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
569 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd,
570 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
571 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75,
572 0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
573 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6,
574 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
575 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8,
576 0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
577 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b,
578 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
579 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3,
580 0x80, 0x8d, 0x9a, 0x97
581 ], //*/ GDX = Gx(0xd),
582
583/*
584 GEX = [
585 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62,
586 0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
587 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9,
588 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
589 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59,
590 0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
591 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f,
592 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
593 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14,
594 0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
595 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53,
596 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
597 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3,
598 0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
599 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68,
600 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
601 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e,
602 0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
603 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25,
604 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
605 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5,
606 0x9f, 0x91, 0x83, 0x8d
607 ], //*/ GEX = Gx(0xe),
608
609 enc = function(string, pass, binary) {
610 // string, password in plaintext
611 var salt = randArr(8),
612 pbe = openSSLKey(s2a(pass, binary), salt),
613 key = pbe.key,
614 iv = pbe.iv,
615 cipherBlocks,
616 saltBlock = [[83, 97, 108, 116, 101, 100, 95, 95].concat(salt)];
617 string = s2a(string, binary);
618 console.log(string, key, iv)
619 cipherBlocks = rawEncrypt(string, key, iv);
620 // Spells out 'Salted__'
621 cipherBlocks = saltBlock.concat(cipherBlocks);
622 return Base64.encode(cipherBlocks);
623 },
624
625 dec = function(string, pass, binary) {
626 // string, password in plaintext
627 var cryptArr = Base64.decode(string),
628 salt = cryptArr.slice(8, 16),
629 pbe = openSSLKey(s2a(pass, binary), salt),
630 key = pbe.key,
631 iv = pbe.iv;
632 cryptArr = cryptArr.slice(16, cryptArr.length);
633 // Take off the Salted__ffeeddcc
634 console.log(cryptArr, key, iv)
635 string = rawDecrypt(cryptArr, key, iv, binary);
636 return string;
637 },
638
639 MD5 = function(numArr) {
640
641 function rotateLeft(lValue, iShiftBits) {
642 return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
643 }
644
645 function addUnsigned(lX, lY) {
646 var lX4,
647 lY4,
648 lX8,
649 lY8,
650 lResult;
651 lX8 = (lX & 0x80000000);
652 lY8 = (lY & 0x80000000);
653 lX4 = (lX & 0x40000000);
654 lY4 = (lY & 0x40000000);
655 lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
656 if (lX4 & lY4) {
657 return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
658 }
659 if (lX4 | lY4) {
660 if (lResult & 0x40000000) {
661 return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
662 } else {
663 return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
664 }
665 } else {
666 return (lResult ^ lX8 ^ lY8);
667 }
668 }
669
670 function f(x, y, z) {
671 return (x & y) | ((~x) & z);
672 }
673 function g(x, y, z) {
674 return (x & z) | (y & (~z));
675 }
676 function h(x, y, z) {
677 return (x ^ y ^ z);
678 }
679 function funcI(x, y, z) {
680 return (y ^ (x | (~z)));
681 }
682
683 function ff(a, b, c, d, x, s, ac) {
684 a = addUnsigned(a, addUnsigned(addUnsigned(f(b, c, d), x), ac));
685 return addUnsigned(rotateLeft(a, s), b);
686 }
687
688 function gg(a, b, c, d, x, s, ac) {
689 a = addUnsigned(a, addUnsigned(addUnsigned(g(b, c, d), x), ac));
690 return addUnsigned(rotateLeft(a, s), b);
691 }
692
693 function hh(a, b, c, d, x, s, ac) {
694 a = addUnsigned(a, addUnsigned(addUnsigned(h(b, c, d), x), ac));
695 return addUnsigned(rotateLeft(a, s), b);
696 }
697
698 function ii(a, b, c, d, x, s, ac) {
699 a = addUnsigned(a, addUnsigned(addUnsigned(funcI(b, c, d), x), ac));
700 return addUnsigned(rotateLeft(a, s), b);
701 }
702
703 function convertToWordArray(numArr) {
704 var lWordCount,
705 lMessageLength = numArr.length,
706 lNumberOfWords_temp1 = lMessageLength + 8,
707 lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64,
708 lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16,
709 lWordArray = [],
710 lBytePosition = 0,
711 lByteCount = 0;
712 while (lByteCount < lMessageLength) {
713 lWordCount = (lByteCount - (lByteCount % 4)) / 4;
714 lBytePosition = (lByteCount % 4) * 8;
715 lWordArray[lWordCount] = (lWordArray[lWordCount] | (numArr[lByteCount] << lBytePosition));
716 lByteCount++;
717 }
718 lWordCount = (lByteCount - (lByteCount % 4)) / 4;
719 lBytePosition = (lByteCount % 4) * 8;
720 lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
721 lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
722 lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
723 return lWordArray;
724 }
725
726 function wordToHex(lValue) {
727 var lByte,
728 lCount,
729 wordToHexArr = [];
730 for (lCount = 0; lCount <= 3; lCount++) {
731 lByte = (lValue >>> (lCount * 8)) & 255;
732 wordToHexArr = wordToHexArr.concat(lByte);
733 }
734 return wordToHexArr;
735 }
736
737 /*function utf8Encode(string) {
738 string = string.replace(/\r\n/g, "\n");
739 var utftext = "",
740 n,
741 c;
742
743 for (n = 0; n < string.length; n++) {
744
745 c = string.charCodeAt(n);
746
747 if (c < 128) {
748 utftext += String.fromCharCode(c);
749 }
750 else if ((c > 127) && (c < 2048)) {
751 utftext += String.fromCharCode((c >> 6) | 192);
752 utftext += String.fromCharCode((c & 63) | 128);
753 }
754 else {
755 utftext += String.fromCharCode((c >> 12) | 224);
756 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
757 utftext += String.fromCharCode((c & 63) | 128);
758 }
759
760 }
761
762 return utftext;
763 }*/
764
765 var x = [],
766 k,
767 AA,
768 BB,
769 CC,
770 DD,
771 a,
772 b,
773 c,
774 d,
775 rnd = strhex('67452301efcdab8998badcfe10325476d76aa478e8c7b756242070dbc1bdceeef57c0faf4787c62aa8304613fd469501698098d88b44f7afffff5bb1895cd7be6b901122fd987193a679438e49b40821f61e2562c040b340265e5a51e9b6c7aad62f105d02441453d8a1e681e7d3fbc821e1cde6c33707d6f4d50d87455a14eda9e3e905fcefa3f8676f02d98d2a4c8afffa39428771f6816d9d6122fde5380ca4beea444bdecfa9f6bb4b60bebfbc70289b7ec6eaa127fad4ef308504881d05d9d4d039e6db99e51fa27cf8c4ac5665f4292244432aff97ab9423a7fc93a039655b59c38f0ccc92ffeff47d85845dd16fa87e4ffe2ce6e0a30143144e0811a1f7537e82bd3af2352ad7d2bbeb86d391',8);
776
777 x = convertToWordArray(numArr);
778
779 a = rnd[0];
780 b = rnd[1];
781 c = rnd[2];
782 d = rnd[3]
783
784 for (k = 0; k < x.length; k += 16) {
785 AA = a;
786 BB = b;
787 CC = c;
788 DD = d;
789 a = ff(a, b, c, d, x[k + 0], 7, rnd[4]);
790 d = ff(d, a, b, c, x[k + 1], 12, rnd[5]);
791 c = ff(c, d, a, b, x[k + 2], 17, rnd[6]);
792 b = ff(b, c, d, a, x[k + 3], 22, rnd[7]);
793 a = ff(a, b, c, d, x[k + 4], 7, rnd[8]);
794 d = ff(d, a, b, c, x[k + 5], 12, rnd[9]);
795 c = ff(c, d, a, b, x[k + 6], 17, rnd[10]);
796 b = ff(b, c, d, a, x[k + 7], 22, rnd[11]);
797 a = ff(a, b, c, d, x[k + 8], 7, rnd[12]);
798 d = ff(d, a, b, c, x[k + 9], 12, rnd[13]);
799 c = ff(c, d, a, b, x[k + 10], 17, rnd[14]);
800 b = ff(b, c, d, a, x[k + 11], 22, rnd[15]);
801 a = ff(a, b, c, d, x[k + 12], 7, rnd[16]);
802 d = ff(d, a, b, c, x[k + 13], 12, rnd[17]);
803 c = ff(c, d, a, b, x[k + 14], 17, rnd[18]);
804 b = ff(b, c, d, a, x[k + 15], 22, rnd[19]);
805 a = gg(a, b, c, d, x[k + 1], 5, rnd[20]);
806 d = gg(d, a, b, c, x[k + 6], 9, rnd[21]);
807 c = gg(c, d, a, b, x[k + 11], 14, rnd[22]);
808 b = gg(b, c, d, a, x[k + 0], 20, rnd[23]);
809 a = gg(a, b, c, d, x[k + 5], 5, rnd[24]);
810 d = gg(d, a, b, c, x[k + 10], 9, rnd[25]);
811 c = gg(c, d, a, b, x[k + 15], 14, rnd[26]);
812 b = gg(b, c, d, a, x[k + 4], 20, rnd[27]);
813 a = gg(a, b, c, d, x[k + 9], 5, rnd[28]);
814 d = gg(d, a, b, c, x[k + 14], 9, rnd[29]);
815 c = gg(c, d, a, b, x[k + 3], 14, rnd[30]);
816 b = gg(b, c, d, a, x[k + 8], 20, rnd[31]);
817 a = gg(a, b, c, d, x[k + 13], 5, rnd[32]);
818 d = gg(d, a, b, c, x[k + 2], 9, rnd[33]);
819 c = gg(c, d, a, b, x[k + 7], 14, rnd[34]);
820 b = gg(b, c, d, a, x[k + 12], 20, rnd[35]);
821 a = hh(a, b, c, d, x[k + 5], 4, rnd[36]);
822 d = hh(d, a, b, c, x[k + 8], 11, rnd[37]);
823 c = hh(c, d, a, b, x[k + 11], 16, rnd[38]);
824 b = hh(b, c, d, a, x[k + 14], 23, rnd[39]);
825 a = hh(a, b, c, d, x[k + 1], 4, rnd[40]);
826 d = hh(d, a, b, c, x[k + 4], 11, rnd[41]);
827 c = hh(c, d, a, b, x[k + 7], 16, rnd[42]);
828 b = hh(b, c, d, a, x[k + 10], 23, rnd[43]);
829 a = hh(a, b, c, d, x[k + 13], 4, rnd[44]);
830 d = hh(d, a, b, c, x[k + 0], 11, rnd[45]);
831 c = hh(c, d, a, b, x[k + 3], 16, rnd[46]);
832 b = hh(b, c, d, a, x[k + 6], 23, rnd[47]);
833 a = hh(a, b, c, d, x[k + 9], 4, rnd[48]);
834 d = hh(d, a, b, c, x[k + 12], 11, rnd[49]);
835 c = hh(c, d, a, b, x[k + 15], 16, rnd[50]);
836 b = hh(b, c, d, a, x[k + 2], 23, rnd[51]);
837 a = ii(a, b, c, d, x[k + 0], 6, rnd[52]);
838 d = ii(d, a, b, c, x[k + 7], 10, rnd[53]);
839 c = ii(c, d, a, b, x[k + 14], 15, rnd[54]);
840 b = ii(b, c, d, a, x[k + 5], 21, rnd[55]);
841 a = ii(a, b, c, d, x[k + 12], 6, rnd[56]);
842 d = ii(d, a, b, c, x[k + 3], 10, rnd[57]);
843 c = ii(c, d, a, b, x[k + 10], 15, rnd[58]);
844 b = ii(b, c, d, a, x[k + 1], 21, rnd[59]);
845 a = ii(a, b, c, d, x[k + 8], 6, rnd[60]);
846 d = ii(d, a, b, c, x[k + 15], 10, rnd[61]);
847 c = ii(c, d, a, b, x[k + 6], 15, rnd[62]);
848 b = ii(b, c, d, a, x[k + 13], 21, rnd[63]);
849 a = ii(a, b, c, d, x[k + 4], 6, rnd[64]);
850 d = ii(d, a, b, c, x[k + 11], 10, rnd[65]);
851 c = ii(c, d, a, b, x[k + 2], 15, rnd[66]);
852 b = ii(b, c, d, a, x[k + 9], 21, rnd[67]);
853 a = addUnsigned(a, AA);
854 b = addUnsigned(b, BB);
855 c = addUnsigned(c, CC);
856 d = addUnsigned(d, DD);
857 }
858
859 return wordToHex(a).concat(wordToHex(b), wordToHex(c), wordToHex(d));
860 },
861
862 encString = function(plaintext, key, iv) {
863 plaintext = s2a(plaintext);
864
865 key = s2a(key);
866 for (var i=key.length; i<32; i++)
867 key[i] = 0;
868
869 if (iv == null) {
870 iv = genIV();
871 } else {
872 iv = s2a(iv);
873 for (var i=iv.length; i<16; i++)
874 iv[i] = 0;
875 }
876
877 var ct = rawEncrypt(plaintext, key, iv);
878 var ret = [iv];
879 for (var i=0; i<ct.length; i++)
880 ret[ret.length] = ct[i];
881 return Base64.encode(ret);
882 },
883
884 decString = function(ciphertext, key) {
885 var tmp = Base64.decode(ciphertext);
886 var iv = tmp.slice(0, 16);
887 var ct = tmp.slice(16, tmp.length);
888
889 key = s2a(key);
890 for (var i=key.length; i<32; i++)
891 key[i] = 0;
892
893 var pt = rawDecrypt(ct, key, iv, false);
894 return pt;
895 },
896
897 Base64 = (function(){
898 // Takes a Nx16x1 byte array and converts it to Base64
899 var _chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
900 chars = _chars.split(''),
901
902 encode = function(b, withBreaks) {
903 var flatArr = [],
904 b64 = '',
905 i,
906 broken_b64;
907 totalChunks = Math.floor(b.length * 16 / 3);
908 for (i = 0; i < b.length * 16; i++) {
909 flatArr.push(b[Math.floor(i / 16)][i % 16]);
910 }
911 for (i = 0; i < flatArr.length; i = i + 3) {
912 b64 += chars[flatArr[i] >> 2];
913 b64 += chars[((flatArr[i] & 3) << 4) | (flatArr[i + 1] >> 4)];
914 if (! (flatArr[i + 1] === undefined)) {
915 b64 += chars[((flatArr[i + 1] & 15) << 2) | (flatArr[i + 2] >> 6)];
916 } else {
917 b64 += '=';
918 }
919 if (! (flatArr[i + 2] === undefined)) {
920 b64 += chars[flatArr[i + 2] & 63];
921 } else {
922 b64 += '=';
923 }
924 }
925 if (withBreaks !== false) {
926 // OpenSSL is super particular about line breaks
927 broken_b64 = b64.slice(0, 64) + '\n';
928 for (i = 1; i < (Math.ceil(b64.length / 64)); i++) {
929 broken_b64 += b64.slice(i * 64, i * 64 + 64) + (Math.ceil(b64.length / 64) == i + 1 ? '': '\n');
930 }
931 return broken_b64;
932 }
933 return b64;
934 },
935
936 decode = function(string) {
937 string = string.replace(/\n/g, '');
938 var flatArr = [],
939 c = [],
940 b = [],
941 i;
942 for (i = 0; i < string.length; i = i + 4) {
943 c[0] = _chars.indexOf(string.charAt(i));
944 c[1] = _chars.indexOf(string.charAt(i + 1));
945 c[2] = _chars.indexOf(string.charAt(i + 2));
946 c[3] = _chars.indexOf(string.charAt(i + 3));
947
948 b[0] = (c[0] << 2) | (c[1] >> 4);
949 b[1] = ((c[1] & 15) << 4) | (c[2] >> 2);
950 b[2] = ((c[2] & 3) << 6) | c[3];
951 flatArr.push(b[0], b[1], b[2]);
952 }
953 flatArr = flatArr.slice(0, flatArr.length - (flatArr.length % 16));
954 return flatArr;
955 };
956
957 //internet explorer
958 if(typeof Array.indexOf === "function") {
959 _chars = chars;
960 }
961
962 /*
963 //other way to solve internet explorer problem
964 if(!Array.indexOf){
965 Array.prototype.indexOf = function(obj){
966 for(var i=0; i<this.length; i++){
967 if(this[i]===obj){
968 return i;
969 }
970 }
971 return -1;
972 }
973 }
974 */
975
976
977 return {
978 "encode": encode,
979 "decode": decode
980 };
981 })();
982
983 return {
984 "size": size,
985 "h2a":h2a,
986 "expandKey":expandKey,
987 "encryptBlock":encryptBlock,
988 "decryptBlock":decryptBlock,
989 "Decrypt":Decrypt,
990 "s2a":s2a,
991 "rawEncrypt":rawEncrypt,
992 "rawDecrypt":rawDecrypt,
993 "dec":dec,
994 "openSSLKey":openSSLKey,
995 "a2h":a2h,
996 "enc":enc,
997 "Hash":{"MD5":MD5},
998 "Base64":Base64
999 };
1000
1001})();
1002
1003if ( typeof define === "function" ) {
1004 define(function () { return GibberishAES; });
1005}
1006if ( typeof module !== "undefined" && module !== null ) {
1007 module.exports = GibberishAES;
1008}