/jquery.jcryption.js

https://github.com/madhavvyas/jCryption · JavaScript · 2487 lines · 1694 code · 258 blank · 535 comment · 243 complexity · 8997094fff36d06072f499554a26655e MD5 · raw file

  1. /*
  2. * jCryption JavaScript data encryption v1.2
  3. * http://www.jcryption.org/
  4. *
  5. * Copyright (c) 2010 Daniel Griesser
  6. * Dual licensed under the MIT and GPL licenses.
  7. * http://www.opensource.org/licenses/mit-license.php
  8. * http://www.opensource.org/licenses/gpl-2.0.php
  9. *
  10. * If you need any further information about this plugin please
  11. * visit my homepage or contact me under daniel.griesser@jcryption.org
  12. */
  13. (function($) {
  14. $.jCryption = function(el, options) {
  15. var base = this;
  16. base.$el = $(el);
  17. base.el = el;
  18. base.$el.data("jCryption", base);
  19. base.$el.data("salt", null);
  20. base.$el.data("key", null);
  21. base.init = function() {
  22. base.options = $.extend({}, $.jCryption.defaultOptions, options);
  23. // Making a good random salt
  24. base.$el.bind('mousemove', function(e) {
  25. if (base.$el.data("salt") === null) {
  26. base.$el.data("salt", (e.pageX + e.pageY) * Math.random());
  27. } else {
  28. base.$el.unbind('mousemove');
  29. }
  30. });
  31. $encryptedElement = $("<input />",{
  32. type:'hidden',
  33. name:base.options.postVariable
  34. });
  35. if (base.options.submitElement !== false) {
  36. var $submitElement = base.options.submitElement;
  37. } else {
  38. var $submitElement = base.$el.find(":input:submit");
  39. }
  40. $submitElement.bind(base.options.submitEvent, function() {
  41. $(this).attr("disabled", true);
  42. if (base.options.beforeEncryption()) {
  43. base.authenticate(
  44. function(AESEncryptionKey) {
  45. var toEncrypt = base.$el.serialize();
  46. if ($submitElement.is(":submit")) {
  47. toEncrypt = toEncrypt + "&" + $submitElement.attr("name") + "=" + $submitElement.val();
  48. }
  49. $encryptedElement.val($.jCryption.encrypt(toEncrypt, AESEncryptionKey));
  50. $(base.$el).find(base.options.formFieldSelector)
  51. .attr("disabled", true).end()
  52. .append($encryptedElement).submit();
  53. },
  54. function() {
  55. // Authentication with AES Failed ... sending form without protection
  56. $(base.$el).submit();
  57. }
  58. );
  59. }
  60. return false;
  61. });
  62. };
  63. base.init();
  64. /**
  65. * Creates a random string(key) for use in the AES algorithm
  66. */
  67. base.getKey = function() {
  68. if (base.$el.data("key") !== null) {
  69. return base.$el.data("key");
  70. }
  71. // no good salt available
  72. var seed = base.$el.data("salt");
  73. if (seed === null) {
  74. // generating weak seed
  75. seed = Math.floor(Math.random() * Math.random());
  76. }
  77. var hashObj = new jsSHA(seed.toString(), "ASCII");
  78. base.$el.data("key", hashObj.getHash("SHA-512", "HEX"));
  79. return base.getKey();
  80. };
  81. /**
  82. * Authenticate with the server (One way)
  83. * @param {function} success The function to call if the operation was successfull
  84. * @param {function} failure The function to call if an error has occurred
  85. */
  86. base.authenticate = function(success, failure) {
  87. var key = base.getKey();
  88. $.jCryption.authenticate(key, base.options.getKeysURL, base.options.handshakeURL, success, failure);
  89. };
  90. };
  91. /**
  92. * Authenticates with the server
  93. * @param {string} AESEncryptionKey The AES key
  94. * @param {string} publicKeyURL The public key URL
  95. * @param {string} handshakeURL The handshake URL
  96. * @param {function} success The function to call if the operation was successfull
  97. * @param {function} failure The function to call if an error has occurred
  98. */
  99. $.jCryption.authenticate = function(AESEncryptionKey, publicKeyURL, handshakeURL, success, failure) {
  100. $.jCryption.getKeys(publicKeyURL, function(keys) {
  101. $.jCryption.encryptKey(AESEncryptionKey, keys, function(encryptedKey) {
  102. $.jCryption.handshake(handshakeURL, encryptedKey, function(response) {
  103. if ($.jCryption.challenge(response.challenge, AESEncryptionKey)) {
  104. success.call(this, AESEncryptionKey);
  105. } else {
  106. failure.call(this);
  107. }
  108. });
  109. });
  110. });
  111. };
  112. /**
  113. * Gets the RSA keys from the specified url, and saves it into a RSA keypair
  114. * @param {string} url The url to contact
  115. * @param {function} callback The function to call when the operation has finshed
  116. */
  117. $.jCryption.getKeys = function(url, callback) {
  118. var jCryptionKeyPair = function(encryptionExponent, modulus, maxdigits) {
  119. setMaxDigits(parseInt(maxdigits,10));
  120. this.e = biFromHex(encryptionExponent);
  121. this.m = biFromHex(modulus);
  122. this.chunkSize = 2 * biHighIndex(this.m);
  123. this.radix = 16;
  124. this.barrett = new BarrettMu(this.m);
  125. };
  126. /**
  127. * Gets the data from the specified url, and converts it into a RSA keypair
  128. * @param {string} url The URL to contact
  129. * @param {string} data The JSON data
  130. */
  131. $.getJSON(url, function(data) {
  132. var keys = new jCryptionKeyPair(data.e, data.n, data.maxdigits);
  133. if($.isFunction(callback)) {
  134. callback.call(this, keys);
  135. }
  136. });
  137. };
  138. /**
  139. * Decrypts data using AES 256
  140. * @param {string} data The data to decrypt(Ciphertext)
  141. * @param {string} key The AES key
  142. * @returns {string} The result of the decryption(Plaintext)
  143. */
  144. $.jCryption.decrypt = function(data, key) {
  145. return Aes.Ctr.decrypt(data, key , 256);
  146. };
  147. /**
  148. * Encrypts data using AES 256
  149. * @param {string} data The data to encrypt(Plaintext)
  150. * @param {string} key The AES key
  151. * @returns {string} The result of the encryption(Ciphertext)
  152. */
  153. $.jCryption.encrypt = function(data, key) {
  154. return Aes.Ctr.encrypt(data, key , 256);
  155. };
  156. /**
  157. * Makes sure that the challenge the client sent, is correct
  158. * @param {string} challenge The challenge string
  159. * @param {string} key The AES key
  160. */
  161. $.jCryption.challenge = function(challenge, key) {
  162. if ($.jCryption.decrypt(challenge, key) == key) {
  163. return true;
  164. }
  165. return false;
  166. };
  167. /**
  168. * Executes a handshake with the server
  169. * @param {string} url The url to connect to
  170. * @param {string} key The encrypted AES key
  171. * @param {function} callback The function to call when the handshaking has finished
  172. */
  173. $.jCryption.handshake = function(url, key, callback) {
  174. $.ajax({
  175. url: url,
  176. dataType: "json",
  177. type: "POST",
  178. data: {
  179. key: key
  180. },
  181. success: function(response) {
  182. callback.call(this, response);
  183. }
  184. });
  185. };
  186. /**
  187. * Encrypts the AES key using RSA
  188. * @param {string} string The AES key
  189. * @param {keypair} keyPair The RSA keypair to use
  190. * @param {function} callback The function to call when the encryption has finished
  191. */
  192. $.jCryption.encryptKey = function(string, keyPair, callback) {
  193. var charSum = 0;
  194. for(var i = 0; i < string.length; i++){
  195. charSum += string.charCodeAt(i);
  196. }
  197. var tag = '0123456789abcdef';
  198. var hex = '';
  199. hex += tag.charAt((charSum & 0xF0) >> 4) + tag.charAt(charSum & 0x0F);
  200. var taggedString = hex + string;
  201. var encrypt = [];
  202. var j = 0;
  203. while (j < taggedString.length) {
  204. encrypt[j] = taggedString.charCodeAt(j);
  205. j++;
  206. }
  207. while (encrypt.length % keyPair.chunkSize !== 0) {
  208. encrypt[j++] = 0;
  209. }
  210. function encryption(encryptObject) {
  211. var charCounter = 0;
  212. var j, block;
  213. var encrypted = "";
  214. function encryptChar() {
  215. block = new BigInt();
  216. j = 0;
  217. for (var k = charCounter; k < charCounter+keyPair.chunkSize; ++j) {
  218. block.digits[j] = encryptObject[k++];
  219. block.digits[j] += encryptObject[k++] << 8;
  220. }
  221. var crypt = keyPair.barrett.powMod(block, keyPair.e);
  222. var text = keyPair.radix == 16 ? biToHex(crypt) : biToString(crypt, keyPair.radix);
  223. encrypted += text + " ";
  224. charCounter += keyPair.chunkSize;
  225. if (charCounter < encryptObject.length) {
  226. setTimeout(encryptChar, 1)
  227. } else {
  228. var encryptedString = encrypted.substring(0, encrypted.length - 1);
  229. if($.isFunction(callback)) {
  230. callback(encryptedString);
  231. } else {
  232. return encryptedString;
  233. }
  234. }
  235. }
  236. setTimeout(encryptChar, 1);
  237. }
  238. encryption(encrypt);
  239. };
  240. $.jCryption.defaultOptions = {
  241. submitElement: false,
  242. submitEvent: "click",
  243. getKeysURL: "main.php?generateKeypair=true",
  244. handshakeURL: "main.php?handshake=true",
  245. beforeEncryption: function() { return true },
  246. postVariable: "jCryption",
  247. formFieldSelector: ":input"
  248. };
  249. $.fn.jCryption = function(options) {
  250. return this.each(function(){
  251. (new $.jCryption(this, options));
  252. });
  253. };
  254. })(jQuery);
  255. /*
  256. * BigInt, a suite of routines for performing multiple-precision arithmetic in
  257. * JavaScript.
  258. * BarrettMu, a class for performing Barrett modular reduction computations in
  259. * JavaScript.
  260. *
  261. *
  262. * Copyright 1998-2005 David Shapiro.
  263. * dave@ohdave.com
  264. *
  265. * changed and improved by Daniel Griesser
  266. * http://www.jcryption.org/
  267. * Daniel Griesser <daniel.griesser@jcryption.org>
  268. */
  269. var biRadixBase = 2;
  270. var biRadixBits = 16;
  271. var bitsPerDigit = biRadixBits;
  272. var biRadix = 1 << 16;
  273. var biHalfRadix = biRadix >>> 1;
  274. var biRadixSquared = biRadix * biRadix;
  275. var maxDigitVal = biRadix - 1;
  276. var maxInteger = 9999999999999998;
  277. var maxDigits;
  278. var ZERO_ARRAY;
  279. var bigZero, bigOne;
  280. var dpl10 = 15;
  281. var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800,
  282. 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
  283. 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF);
  284. var hexatrigesimalToChar = new Array(
  285. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  286. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
  287. 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  288. 'u', 'v', 'w', 'x', 'y', 'z'
  289. );
  290. var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  291. 'a', 'b', 'c', 'd', 'e', 'f');
  292. var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
  293. 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,
  294. 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF);
  295. function setMaxDigits(value) {
  296. maxDigits = value;
  297. ZERO_ARRAY = new Array(maxDigits);
  298. for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
  299. bigZero = new BigInt();
  300. bigOne = new BigInt();
  301. bigOne.digits[0] = 1;
  302. }
  303. function BigInt(flag) {
  304. if (typeof flag == "boolean" && flag == true) {
  305. this.digits = null;
  306. }
  307. else {
  308. this.digits = ZERO_ARRAY.slice(0);
  309. }
  310. this.isNeg = false;
  311. }
  312. function biFromDecimal(s) {
  313. var isNeg = s.charAt(0) == '-';
  314. var i = isNeg ? 1 : 0;
  315. var result;
  316. while (i < s.length && s.charAt(i) == '0') ++i;
  317. if (i == s.length) {
  318. result = new BigInt();
  319. }
  320. else {
  321. var digitCount = s.length - i;
  322. var fgl = digitCount % dpl10;
  323. if (fgl == 0) fgl = dpl10;
  324. result = biFromNumber(Number(s.substr(i, fgl)));
  325. i += fgl;
  326. while (i < s.length) {
  327. result = biAdd(biMultiply(result, biFromNumber(1000000000000000)),
  328. biFromNumber(Number(s.substr(i, dpl10))));
  329. i += dpl10;
  330. }
  331. result.isNeg = isNeg;
  332. }
  333. return result;
  334. }
  335. function biCopy(bi) {
  336. var result = new BigInt(true);
  337. result.digits = bi.digits.slice(0);
  338. result.isNeg = bi.isNeg;
  339. return result;
  340. }
  341. function biFromNumber(i) {
  342. var result = new BigInt();
  343. result.isNeg = i < 0;
  344. i = Math.abs(i);
  345. var j = 0;
  346. while (i > 0) {
  347. result.digits[j++] = i & maxDigitVal;
  348. i >>= biRadixBits;
  349. }
  350. return result;
  351. }
  352. function reverseStr(s) {
  353. var result = "";
  354. for (var i = s.length - 1; i > -1; --i) {
  355. result += s.charAt(i);
  356. }
  357. return result;
  358. }
  359. function biToString(x, radix) {
  360. var b = new BigInt();
  361. b.digits[0] = radix;
  362. var qr = biDivideModulo(x, b);
  363. var result = hexatrigesimalToChar[qr[1].digits[0]];
  364. while (biCompare(qr[0], bigZero) == 1) {
  365. qr = biDivideModulo(qr[0], b);
  366. digit = qr[1].digits[0];
  367. result += hexatrigesimalToChar[qr[1].digits[0]];
  368. }
  369. return (x.isNeg ? "-" : "") + reverseStr(result);
  370. }
  371. function biToDecimal(x) {
  372. var b = new BigInt();
  373. b.digits[0] = 10;
  374. var qr = biDivideModulo(x, b);
  375. var result = String(qr[1].digits[0]);
  376. while (biCompare(qr[0], bigZero) == 1) {
  377. qr = biDivideModulo(qr[0], b);
  378. result += String(qr[1].digits[0]);
  379. }
  380. return (x.isNeg ? "-" : "") + reverseStr(result);
  381. }
  382. function digitToHex(n) {
  383. var mask = 0xf;
  384. var result = "";
  385. for (i = 0; i < 4; ++i) {
  386. result += hexToChar[n & mask];
  387. n >>>= 4;
  388. }
  389. return reverseStr(result);
  390. }
  391. function biToHex(x) {
  392. var result = "";
  393. var n = biHighIndex(x);
  394. for (var i = biHighIndex(x); i > -1; --i) {
  395. result += digitToHex(x.digits[i]);
  396. }
  397. return result;
  398. }
  399. function charToHex(c) {
  400. var ZERO = 48;
  401. var NINE = ZERO + 9;
  402. var littleA = 97;
  403. var littleZ = littleA + 25;
  404. var bigA = 65;
  405. var bigZ = 65 + 25;
  406. var result;
  407. if (c >= ZERO && c <= NINE) {
  408. result = c - ZERO;
  409. } else if (c >= bigA && c <= bigZ) {
  410. result = 10 + c - bigA;
  411. } else if (c >= littleA && c <= littleZ) {
  412. result = 10 + c - littleA;
  413. } else {
  414. result = 0;
  415. }
  416. return result;
  417. }
  418. function hexToDigit(s) {
  419. var result = 0;
  420. var sl = Math.min(s.length, 4);
  421. for (var i = 0; i < sl; ++i) {
  422. result <<= 4;
  423. result |= charToHex(s.charCodeAt(i))
  424. }
  425. return result;
  426. }
  427. function biFromHex(s) {
  428. var result = new BigInt();
  429. var sl = s.length;
  430. for (var i = sl, j = 0; i > 0; i -= 4, ++j) {
  431. result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4)));
  432. }
  433. return result;
  434. }
  435. function biFromString(s, radix) {
  436. var isNeg = s.charAt(0) == '-';
  437. var istop = isNeg ? 1 : 0;
  438. var result = new BigInt();
  439. var place = new BigInt();
  440. place.digits[0] = 1; // radix^0
  441. for (var i = s.length - 1; i >= istop; i--) {
  442. var c = s.charCodeAt(i);
  443. var digit = charToHex(c);
  444. var biDigit = biMultiplyDigit(place, digit);
  445. result = biAdd(result, biDigit);
  446. place = biMultiplyDigit(place, radix);
  447. }
  448. result.isNeg = isNeg;
  449. return result;
  450. }
  451. function biDump(b) {
  452. return (b.isNeg ? "-" : "") + b.digits.join(" ");
  453. }
  454. function biAdd(x, y) {
  455. var result;
  456. if (x.isNeg != y.isNeg) {
  457. y.isNeg = !y.isNeg;
  458. result = biSubtract(x, y);
  459. y.isNeg = !y.isNeg;
  460. }
  461. else {
  462. result = new BigInt();
  463. var c = 0;
  464. var n;
  465. for (var i = 0; i < x.digits.length; ++i) {
  466. n = x.digits[i] + y.digits[i] + c;
  467. result.digits[i] = n & 0xffff;
  468. c = Number(n >= biRadix);
  469. }
  470. result.isNeg = x.isNeg;
  471. }
  472. return result;
  473. }
  474. function biSubtract(x, y) {
  475. var result;
  476. if (x.isNeg != y.isNeg) {
  477. y.isNeg = !y.isNeg;
  478. result = biAdd(x, y);
  479. y.isNeg = !y.isNeg;
  480. } else {
  481. result = new BigInt();
  482. var n, c;
  483. c = 0;
  484. for (var i = 0; i < x.digits.length; ++i) {
  485. n = x.digits[i] - y.digits[i] + c;
  486. result.digits[i] = n & 0xffff;
  487. if (result.digits[i] < 0) result.digits[i] += biRadix;
  488. c = 0 - Number(n < 0);
  489. }
  490. if (c == -1) {
  491. c = 0;
  492. for (var i = 0; i < x.digits.length; ++i) {
  493. n = 0 - result.digits[i] + c;
  494. result.digits[i] = n & 0xffff;
  495. if (result.digits[i] < 0) result.digits[i] += biRadix;
  496. c = 0 - Number(n < 0);
  497. }
  498. result.isNeg = !x.isNeg;
  499. } else {
  500. result.isNeg = x.isNeg;
  501. }
  502. }
  503. return result;
  504. }
  505. function biHighIndex(x) {
  506. var result = x.digits.length - 1;
  507. while (result > 0 && x.digits[result] == 0) --result;
  508. return result;
  509. }
  510. function biNumBits(x) {
  511. var n = biHighIndex(x);
  512. var d = x.digits[n];
  513. var m = (n + 1) * bitsPerDigit;
  514. var result;
  515. for (result = m; result > m - bitsPerDigit; --result) {
  516. if ((d & 0x8000) != 0) break;
  517. d <<= 1;
  518. }
  519. return result;
  520. }
  521. function biMultiply(x, y) {
  522. var result = new BigInt();
  523. var c;
  524. var n = biHighIndex(x);
  525. var t = biHighIndex(y);
  526. var u, uv, k;
  527. for (var i = 0; i <= t; ++i) {
  528. c = 0;
  529. k = i;
  530. for (j = 0; j <= n; ++j, ++k) {
  531. uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
  532. result.digits[k] = uv & maxDigitVal;
  533. c = uv >>> biRadixBits;
  534. }
  535. result.digits[i + n + 1] = c;
  536. }
  537. result.isNeg = x.isNeg != y.isNeg;
  538. return result;
  539. }
  540. function biMultiplyDigit(x, y) {
  541. var n, c, uv;
  542. var result = new BigInt();
  543. n = biHighIndex(x);
  544. c = 0;
  545. for (var j = 0; j <= n; ++j) {
  546. uv = result.digits[j] + x.digits[j] * y + c;
  547. result.digits[j] = uv & maxDigitVal;
  548. c = uv >>> biRadixBits;
  549. }
  550. result.digits[1 + n] = c;
  551. return result;
  552. }
  553. function arrayCopy(src, srcStart, dest, destStart, n) {
  554. var m = Math.min(srcStart + n, src.length);
  555. for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
  556. dest[j] = src[i];
  557. }
  558. }
  559. function biShiftLeft(x, n) {
  560. var digitCount = Math.floor(n / bitsPerDigit);
  561. var result = new BigInt();
  562. arrayCopy(x.digits, 0, result.digits, digitCount,result.digits.length - digitCount);
  563. var bits = n % bitsPerDigit;
  564. var rightBits = bitsPerDigit - bits;
  565. for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) {
  566. result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
  567. ((result.digits[i1] & highBitMasks[bits]) >>>
  568. (rightBits));
  569. }
  570. result.digits[0] = ((result.digits[i] << bits) & maxDigitVal);
  571. result.isNeg = x.isNeg;
  572. return result;
  573. }
  574. function biShiftRight(x, n) {
  575. var digitCount = Math.floor(n / bitsPerDigit);
  576. var result = new BigInt();
  577. arrayCopy(x.digits, digitCount, result.digits, 0,x.digits.length - digitCount);
  578. var bits = n % bitsPerDigit;
  579. var leftBits = bitsPerDigit - bits;
  580. for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) {
  581. result.digits[i] = (result.digits[i] >>> bits) |
  582. ((result.digits[i1] & lowBitMasks[bits]) << leftBits);
  583. }
  584. result.digits[result.digits.length - 1] >>>= bits;
  585. result.isNeg = x.isNeg;
  586. return result;
  587. }
  588. function biMultiplyByRadixPower(x, n) {
  589. var result = new BigInt();
  590. arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n);
  591. return result;
  592. }
  593. function biDivideByRadixPower(x, n)
  594. {
  595. var result = new BigInt();
  596. arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n);
  597. return result;
  598. }
  599. function biModuloByRadixPower(x, n)
  600. {
  601. var result = new BigInt();
  602. arrayCopy(x.digits, 0, result.digits, 0, n);
  603. return result;
  604. }
  605. function biCompare(x, y) {
  606. if (x.isNeg != y.isNeg) {
  607. return 1 - 2 * Number(x.isNeg);
  608. }
  609. for (var i = x.digits.length - 1; i >= 0; --i) {
  610. if (x.digits[i] != y.digits[i]) {
  611. if (x.isNeg) {
  612. return 1 - 2 * Number(x.digits[i] > y.digits[i]);
  613. } else {
  614. return 1 - 2 * Number(x.digits[i] < y.digits[i]);
  615. }
  616. }
  617. }
  618. return 0;
  619. }
  620. function biDivideModulo(x, y) {
  621. var nb = biNumBits(x);
  622. var tb = biNumBits(y);
  623. var origYIsNeg = y.isNeg;
  624. var q, r;
  625. if (nb < tb) {
  626. if (x.isNeg) {
  627. q = biCopy(bigOne);
  628. q.isNeg = !y.isNeg;
  629. x.isNeg = false;
  630. y.isNeg = false;
  631. r = biSubtract(y, x);
  632. x.isNeg = true;
  633. y.isNeg = origYIsNeg;
  634. } else {
  635. q = new BigInt();
  636. r = biCopy(x);
  637. }
  638. return new Array(q, r);
  639. }
  640. q = new BigInt();
  641. r = x;
  642. var t = Math.ceil(tb / bitsPerDigit) - 1;
  643. var lambda = 0;
  644. while (y.digits[t] < biHalfRadix) {
  645. y = biShiftLeft(y, 1);
  646. ++lambda;
  647. ++tb;
  648. t = Math.ceil(tb / bitsPerDigit) - 1;
  649. }
  650. r = biShiftLeft(r, lambda);
  651. nb += lambda;
  652. var n = Math.ceil(nb / bitsPerDigit) - 1;
  653. var b = biMultiplyByRadixPower(y, n - t);
  654. while (biCompare(r, b) != -1) {
  655. ++q.digits[n - t];
  656. r = biSubtract(r, b);
  657. }
  658. for (var i = n; i > t; --i) {
  659. var ri = (i >= r.digits.length) ? 0 : r.digits[i];
  660. var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
  661. var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
  662. var yt = (t >= y.digits.length) ? 0 : y.digits[t];
  663. var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
  664. if (ri == yt) {
  665. q.digits[i - t - 1] = maxDigitVal;
  666. } else {
  667. q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
  668. }
  669. var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
  670. var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
  671. while (c1 > c2) {
  672. --q.digits[i - t - 1];
  673. c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
  674. c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
  675. }
  676. b = biMultiplyByRadixPower(y, i - t - 1);
  677. r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1]));
  678. if (r.isNeg) {
  679. r = biAdd(r, b);
  680. --q.digits[i - t - 1];
  681. }
  682. }
  683. r = biShiftRight(r, lambda);
  684. q.isNeg = x.isNeg != origYIsNeg;
  685. if (x.isNeg) {
  686. if (origYIsNeg) {
  687. q = biAdd(q, bigOne);
  688. } else {
  689. q = biSubtract(q, bigOne);
  690. }
  691. y = biShiftRight(y, lambda);
  692. r = biSubtract(y, r);
  693. }
  694. if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false;
  695. return new Array(q, r);
  696. }
  697. function biDivide(x, y) {
  698. return biDivideModulo(x, y)[0];
  699. }
  700. function biModulo(x, y) {
  701. return biDivideModulo(x, y)[1];
  702. }
  703. function biMultiplyMod(x, y, m) {
  704. return biModulo(biMultiply(x, y), m);
  705. }
  706. function biPow(x, y) {
  707. var result = bigOne;
  708. var a = x;
  709. while (true) {
  710. if ((y & 1) != 0) result = biMultiply(result, a);
  711. y >>= 1;
  712. if (y == 0) break;
  713. a = biMultiply(a, a);
  714. }
  715. return result;
  716. }
  717. function biPowMod(x, y, m) {
  718. var result = bigOne;
  719. var a = x;
  720. var k = y;
  721. while (true) {
  722. if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m);
  723. k = biShiftRight(k, 1);
  724. if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
  725. a = biMultiplyMod(a, a, m);
  726. }
  727. return result;
  728. }
  729. function BarrettMu(m) {
  730. this.modulus = biCopy(m);
  731. this.k = biHighIndex(this.modulus) + 1;
  732. var b2k = new BigInt();
  733. b2k.digits[2 * this.k] = 1;
  734. this.mu = biDivide(b2k, this.modulus);
  735. this.bkplus1 = new BigInt();
  736. this.bkplus1.digits[this.k + 1] = 1;
  737. this.modulo = BarrettMu_modulo;
  738. this.multiplyMod = BarrettMu_multiplyMod;
  739. this.powMod = BarrettMu_powMod;
  740. }
  741. function BarrettMu_modulo(x) {
  742. var q1 = biDivideByRadixPower(x, this.k - 1);
  743. var q2 = biMultiply(q1, this.mu);
  744. var q3 = biDivideByRadixPower(q2, this.k + 1);
  745. var r1 = biModuloByRadixPower(x, this.k + 1);
  746. var r2term = biMultiply(q3, this.modulus);
  747. var r2 = biModuloByRadixPower(r2term, this.k + 1);
  748. var r = biSubtract(r1, r2);
  749. if (r.isNeg) {
  750. r = biAdd(r, this.bkplus1);
  751. }
  752. var rgtem = biCompare(r, this.modulus) >= 0;
  753. while (rgtem) {
  754. r = biSubtract(r, this.modulus);
  755. rgtem = biCompare(r, this.modulus) >= 0;
  756. }
  757. return r;
  758. }
  759. function BarrettMu_multiplyMod(x, y) {
  760. var xy = biMultiply(x, y);
  761. return this.modulo(xy);
  762. }
  763. function BarrettMu_powMod(x, y) {
  764. var result = new BigInt();
  765. result.digits[0] = 1;
  766. while (true) {
  767. if ((y.digits[0] & 1) != 0) result = this.multiplyMod(result, x);
  768. y = biShiftRight(y, 1);
  769. if (y.digits[0] == 0 && biHighIndex(y) == 0) break;
  770. x = this.multiplyMod(x, x);
  771. }
  772. return result;
  773. }
  774. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  775. /* AES implementation in JavaScript (c) Chris Veness 2005-2011 */
  776. /* - see http://csrc.nist.gov/publications/PubsFIPS.html#197 */
  777. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  778. var Aes = {}; // Aes namespace
  779. /**
  780. * AES Cipher function: encrypt 'input' state with Rijndael algorithm
  781. * applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage
  782. *
  783. * @param {Number[]} input 16-byte (128-bit) input state array
  784. * @param {Number[][]} w Key schedule as 2D byte-array (Nr+1 x Nb bytes)
  785. * @returns {Number[]} Encrypted output state array
  786. */
  787. Aes.cipher = function(input, w) { // main Cipher function [§5.1]
  788. var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES)
  789. var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
  790. var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input [§3.4]
  791. for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
  792. state = Aes.addRoundKey(state, w, 0, Nb);
  793. for (var round=1; round<Nr; round++) {
  794. state = Aes.subBytes(state, Nb);
  795. state = Aes.shiftRows(state, Nb);
  796. state = Aes.mixColumns(state, Nb);
  797. state = Aes.addRoundKey(state, w, round, Nb);
  798. }
  799. state = Aes.subBytes(state, Nb);
  800. state = Aes.shiftRows(state, Nb);
  801. state = Aes.addRoundKey(state, w, Nr, Nb);
  802. var output = new Array(4*Nb); // convert state to 1-d array before returning [§3.4]
  803. for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
  804. return output;
  805. }
  806. /**
  807. * Perform Key Expansion to generate a Key Schedule
  808. *
  809. * @param {Number[]} key Key as 16/24/32-byte array
  810. * @returns {Number[][]} Expanded key schedule as 2D byte-array (Nr+1 x Nb bytes)
  811. */
  812. Aes.keyExpansion = function(key) { // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]
  813. var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES)
  814. var Nk = key.length/4 // key length (in words): 4/6/8 for 128/192/256-bit keys
  815. var Nr = Nk + 6; // no of rounds: 10/12/14 for 128/192/256-bit keys
  816. var w = new Array(Nb*(Nr+1));
  817. var temp = new Array(4);
  818. for (var i=0; i<Nk; i++) {
  819. var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
  820. w[i] = r;
  821. }
  822. for (var i=Nk; i<(Nb*(Nr+1)); i++) {
  823. w[i] = new Array(4);
  824. for (var t=0; t<4; t++) temp[t] = w[i-1][t];
  825. if (i % Nk == 0) {
  826. temp = Aes.subWord(Aes.rotWord(temp));
  827. for (var t=0; t<4; t++) temp[t] ^= Aes.rCon[i/Nk][t];
  828. } else if (Nk > 6 && i%Nk == 4) {
  829. temp = Aes.subWord(temp);
  830. }
  831. for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
  832. }
  833. return w;
  834. }
  835. /*
  836. * ---- remaining routines are private, not called externally ----
  837. */
  838. Aes.subBytes = function(s, Nb) { // apply SBox to state S [§5.1.1]
  839. for (var r=0; r<4; r++) {
  840. for (var c=0; c<Nb; c++) s[r][c] = Aes.sBox[s[r][c]];
  841. }
  842. return s;
  843. }
  844. Aes.shiftRows = function(s, Nb) { // shift row r of state S left by r bytes [§5.1.2]
  845. var t = new Array(4);
  846. for (var r=1; r<4; r++) {
  847. for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb]; // shift into temp copy
  848. for (var c=0; c<4; c++) s[r][c] = t[c]; // and copy back
  849. } // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
  850. return s; // see asmaes.sourceforge.net/rijndael/rijndaelImplementation.pdf
  851. }
  852. Aes.mixColumns = function(s, Nb) { // combine bytes of each col of state S [§5.1.3]
  853. for (var c=0; c<4; c++) {
  854. var a = new Array(4); // 'a' is a copy of the current column from 's'
  855. var b = new Array(4); // 'b' is a•{02} in GF(2^8)
  856. for (var i=0; i<4; i++) {
  857. a[i] = s[i][c];
  858. b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;
  859. }
  860. // a[n] ^ b[n] is a•{03} in GF(2^8)
  861. s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3
  862. s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3
  863. s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3
  864. s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3
  865. }
  866. return s;
  867. }
  868. Aes.addRoundKey = function(state, w, rnd, Nb) { // xor Round Key into state S [§5.1.4]
  869. for (var r=0; r<4; r++) {
  870. for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
  871. }
  872. return state;
  873. }
  874. Aes.subWord = function(w) { // apply SBox to 4-byte word w
  875. for (var i=0; i<4; i++) w[i] = Aes.sBox[w[i]];
  876. return w;
  877. }
  878. Aes.rotWord = function(w) { // rotate 4-byte word w left by one byte
  879. var tmp = w[0];
  880. for (var i=0; i<3; i++) w[i] = w[i+1];
  881. w[3] = tmp;
  882. return w;
  883. }
  884. // sBox is pre-computed multiplicative inverse in GF(2^8) used in subBytes and keyExpansion [§5.1.1]
  885. Aes.sBox = [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
  886. 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
  887. 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
  888. 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
  889. 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
  890. 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
  891. 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
  892. 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
  893. 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
  894. 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
  895. 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
  896. 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
  897. 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
  898. 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
  899. 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
  900. 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];
  901. // rCon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
  902. Aes.rCon = [ [0x00, 0x00, 0x00, 0x00],
  903. [0x01, 0x00, 0x00, 0x00],
  904. [0x02, 0x00, 0x00, 0x00],
  905. [0x04, 0x00, 0x00, 0x00],
  906. [0x08, 0x00, 0x00, 0x00],
  907. [0x10, 0x00, 0x00, 0x00],
  908. [0x20, 0x00, 0x00, 0x00],
  909. [0x40, 0x00, 0x00, 0x00],
  910. [0x80, 0x00, 0x00, 0x00],
  911. [0x1b, 0x00, 0x00, 0x00],
  912. [0x36, 0x00, 0x00, 0x00] ];
  913. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  914. /* AES Counter-mode implementation in JavaScript (c) Chris Veness 2005-2011 */
  915. /* - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
  916. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  917. Aes.Ctr = {}; // Aes.Ctr namespace: a subclass or extension of Aes
  918. /**
  919. * Encrypt a text using AES encryption in Counter mode of operation
  920. *
  921. * Unicode multi-byte character safe
  922. *
  923. * @param {String} plaintext Source text to be encrypted
  924. * @param {String} password The password to use to generate a key
  925. * @param {Number} nBits Number of bits to be used in the key (128, 192, or 256)
  926. * @returns {string} Encrypted text
  927. */
  928. Aes.Ctr.encrypt = function(plaintext, password, nBits) {
  929. var blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
  930. if (!(nBits==128 || nBits==192 || nBits==256)) return ''; // standard allows 128/192/256 bit keys
  931. plaintext = Utf8.encode(plaintext);
  932. password = Utf8.encode(password);
  933. //var t = new Date(); // timer
  934. // use AES itself to encrypt password to get cipher key (using plain password as source for key
  935. // expansion) - gives us well encrypted key (though hashed key might be preferred for prod'n use)
  936. var nBytes = nBits/8; // no bytes in key (16/24/32)
  937. var pwBytes = new Array(nBytes);
  938. for (var i=0; i<nBytes; i++) { // use 1st 16/24/32 chars of password for key
  939. pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
  940. }
  941. var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes)); // gives us 16-byte key
  942. key = key.concat(key.slice(0, nBytes-16)); // expand key to 16/24/32 bytes long
  943. // initialise 1st 8 bytes of counter block with nonce (NIST SP800-38A §B.2): [0-1] = millisec,
  944. // [2-3] = random, [4-7] = seconds, together giving full sub-millisec uniqueness up to Feb 2106
  945. var counterBlock = new Array(blockSize);
  946. var nonce = (new Date()).getTime(); // timestamp: milliseconds since 1-Jan-1970
  947. var nonceMs = nonce%1000;
  948. var nonceSec = Math.floor(nonce/1000);
  949. var nonceRnd = Math.floor(Math.random()*0xffff);
  950. for (var i=0; i<2; i++) counterBlock[i] = (nonceMs >>> i*8) & 0xff;
  951. for (var i=0; i<2; i++) counterBlock[i+2] = (nonceRnd >>> i*8) & 0xff;
  952. for (var i=0; i<4; i++) counterBlock[i+4] = (nonceSec >>> i*8) & 0xff;
  953. // and convert it to a string to go on the front of the ciphertext
  954. var ctrTxt = '';
  955. for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);
  956. // generate key schedule - an expansion of the key into distinct Key Rounds for each round
  957. var keySchedule = Aes.keyExpansion(key);
  958. var blockCount = Math.ceil(plaintext.length/blockSize);
  959. var ciphertxt = new Array(blockCount); // ciphertext as array of strings
  960. for (var b=0; b<blockCount; b++) {
  961. // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
  962. // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
  963. for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
  964. for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)
  965. var cipherCntr = Aes.cipher(counterBlock, keySchedule); // -- encrypt counter block --
  966. // block size is reduced on final block
  967. var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
  968. var cipherChar = new Array(blockLength);
  969. for (var i=0; i<blockLength; i++) { // -- xor plaintext with ciphered counter char-by-char --
  970. cipherChar[i] = cipherCntr[i] ^ plaintext.charCodeAt(b*blockSize+i);
  971. cipherChar[i] = String.fromCharCode(cipherChar[i]);
  972. }
  973. ciphertxt[b] = cipherChar.join('');
  974. }
  975. // Array.join is more efficient than repeated string concatenation in IE
  976. var ciphertext = ctrTxt + ciphertxt.join('');
  977. ciphertext = Base64.encode(ciphertext); // encode in base64
  978. //alert((new Date()) - t);
  979. return ciphertext;
  980. }
  981. /**
  982. * Decrypt a text encrypted by AES in counter mode of operation
  983. *
  984. * @param {String} ciphertext Source text to be encrypted
  985. * @param {String} password The password to use to generate a key
  986. * @param {Number} nBits Number of bits to be used in the key (128, 192, or 256)
  987. * @returns {String} Decrypted text
  988. */
  989. Aes.Ctr.decrypt = function(ciphertext, password, nBits) {
  990. var blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
  991. if (!(nBits==128 || nBits==192 || nBits==256)) return ''; // standard allows 128/192/256 bit keys
  992. ciphertext = Base64.decode(ciphertext);
  993. password = Utf8.encode(password);
  994. //var t = new Date(); // timer
  995. // use AES to encrypt password (mirroring encrypt routine)
  996. var nBytes = nBits/8; // no bytes in key
  997. var pwBytes = new Array(nBytes);
  998. for (var i=0; i<nBytes; i++) {
  999. pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
  1000. }
  1001. var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes));
  1002. key = key.concat(key.slice(0, nBytes-16)); // expand key to 16/24/32 bytes long
  1003. // recover nonce from 1st 8 bytes of ciphertext
  1004. var counterBlock = new Array(8);
  1005. ctrTxt = ciphertext.slice(0, 8);
  1006. for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);
  1007. // generate key schedule
  1008. var keySchedule = Aes.keyExpansion(key);
  1009. // separate ciphertext into blocks (skipping past initial 8 bytes)
  1010. var nBlocks = Math.ceil((ciphertext.length-8) / blockSize);
  1011. var ct = new Array(nBlocks);
  1012. for (var b=0; b<nBlocks; b++) ct[b] = ciphertext.slice(8+b*blockSize, 8+b*blockSize+blockSize);
  1013. ciphertext = ct; // ciphertext is now array of block-length strings
  1014. // plaintext will get generated block-by-block into array of block-length strings
  1015. var plaintxt = new Array(ciphertext.length);
  1016. for (var b=0; b<nBlocks; b++) {
  1017. // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
  1018. for (var c=0; c<4; c++) counterBlock[15-c] = ((b) >>> c*8) & 0xff;
  1019. for (var c=0; c<4; c++) counterBlock[15-c-4] = (((b+1)/0x100000000-1) >>> c*8) & 0xff;
  1020. var cipherCntr = Aes.cipher(counterBlock, keySchedule); // encrypt counter block
  1021. var plaintxtByte = new Array(ciphertext[b].length);
  1022. for (var i=0; i<ciphertext[b].length; i++) {
  1023. // -- xor plaintxt with ciphered counter byte-by-byte --
  1024. plaintxtByte[i] = cipherCntr[i] ^ ciphertext[b].charCodeAt(i);
  1025. plaintxtByte[i] = String.fromCharCode(plaintxtByte[i]);
  1026. }
  1027. plaintxt[b] = plaintxtByte.join('');
  1028. }
  1029. // join array of blocks into single plaintext string
  1030. var plaintext = plaintxt.join('');
  1031. plaintext = Utf8.decode(plaintext); // decode from UTF8 back to Unicode multi-byte chars
  1032. //alert((new Date()) - t);
  1033. return plaintext;
  1034. }
  1035. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  1036. /* Base64 class: Base 64 encoding / decoding (c) Chris Veness 2002-2011 */
  1037. /* note: depends on Utf8 class */
  1038. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  1039. var Base64 = {}; // Base64 namespace
  1040. Base64.code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  1041. /**
  1042. * Encode string into Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
  1043. * (instance method extending String object). As per RFC 4648, no newlines are added.
  1044. *
  1045. * @param {String} str The string to be encoded as base-64
  1046. * @param {Boolean} [utf8encode=false] Flag to indicate whether str is Unicode string to be encoded
  1047. * to UTF8 before conversion to base64; otherwise string is assumed to be 8-bit characters
  1048. * @returns {String} Base64-encoded string
  1049. */
  1050. Base64.encode = function(str, utf8encode) { // http://tools.ietf.org/html/rfc4648
  1051. utf8encode = (typeof utf8encode == 'undefined') ? false : utf8encode;
  1052. var o1, o2, o3, bits, h1, h2, h3, h4, e=[], pad = '', c, plain, coded;
  1053. var b64 = Base64.code;
  1054. plain = utf8encode ? str.encodeUTF8() : str;
  1055. c = plain.length % 3; // pad string to length of multiple of 3
  1056. if (c > 0) { while (c++ < 3) { pad += '='; plain += '\0'; } }
  1057. // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars
  1058. for (c=0; c<plain.length; c+=3) { // pack three octets into four hexets
  1059. o1 = plain.charCodeAt(c);
  1060. o2 = plain.charCodeAt(c+1);
  1061. o3 = plain.charCodeAt(c+2);
  1062. bits = o1<<16 | o2<<8 | o3;
  1063. h1 = bits>>18 & 0x3f;
  1064. h2 = bits>>12 & 0x3f;
  1065. h3 = bits>>6 & 0x3f;
  1066. h4 = bits & 0x3f;
  1067. // use hextets to index into code string
  1068. e[c/3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  1069. }
  1070. coded = e.join(''); // join() is far faster than repeated string concatenation in IE
  1071. // replace 'A's from padded nulls with '='s
  1072. coded = coded.slice(0, coded.length-pad.length) + pad;
  1073. return coded;
  1074. }
  1075. /**
  1076. * Decode string from Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
  1077. * (instance method extending String object). As per RFC 4648, newlines are not catered for.
  1078. *
  1079. * @param {String} str The string to be decoded from base-64
  1080. * @param {Boolean} [utf8decode=false] Flag to indicate whether str is Unicode string to be decoded
  1081. * from UTF8 after conversion from base64
  1082. * @returns {String} decoded string
  1083. */
  1084. Base64.decode = function(str, utf8decode) {
  1085. utf8decode = (typeof utf8decode == 'undefined') ? false : utf8decode;
  1086. var o1, o2, o3, h1, h2, h3, h4, bits, d=[], plain, coded;
  1087. var b64 = Base64.code;
  1088. coded = utf8decode ? str.decodeUTF8() : str;
  1089. for (var c=0; c<coded.length; c+=4) { // unpack four hexets into three octets
  1090. h1 = b64.indexOf(coded.charAt(c));
  1091. h2 = b64.indexOf(coded.charAt(c+1));
  1092. h3 = b64.indexOf(coded.charAt(c+2));
  1093. h4 = b64.indexOf(coded.charAt(c+3));
  1094. bits = h1<<18 | h2<<12 | h3<<6 | h4;
  1095. o1 = bits>>>16 & 0xff;
  1096. o2 = bits>>>8 & 0xff;
  1097. o3 = bits & 0xff;
  1098. d[c/4] = String.fromCharCode(o1, o2, o3);
  1099. // check for padding
  1100. if (h4 == 0x40) d[c/4] = String.fromCharCode(o1, o2);
  1101. if (h3 == 0x40) d[c/4] = String.fromCharCode(o1);
  1102. }
  1103. plain = d.join(''); // join() is far faster than repeated string concatenation in IE
  1104. return utf8decode ? plain.decodeUTF8() : plain;
  1105. }
  1106. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  1107. /* Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple */
  1108. /* single-byte character encoding (c) Chris Veness 2002-2011 */
  1109. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  1110. var Utf8 = {}; // Utf8 namespace
  1111. /**
  1112. * Encode multi-byte Unicode string into utf-8 multiple single-byte characters
  1113. * (BMP / basic multilingual plane only)
  1114. *
  1115. * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars
  1116. *
  1117. * @param {String} strUni Unicode string to be encoded as UTF-8
  1118. * @returns {String} encoded string
  1119. */
  1120. Utf8.encode = function(strUni) {
  1121. // use regular expressions & String.replace callback function for better efficiency
  1122. // than procedural approaches
  1123. var strUtf = strUni.replace(
  1124. /[\u0080-\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz
  1125. function(c) {
  1126. var cc = c.charCodeAt(0);
  1127. return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }
  1128. );
  1129. strUtf = strUtf.replace(
  1130. /[\u0800-\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
  1131. function(c) {
  1132. var cc = c.charCodeAt(0);
  1133. return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }
  1134. );
  1135. return strUtf;
  1136. }
  1137. /**
  1138. * Decode utf-8 encoded string back into multi-byte Unicode characters
  1139. *
  1140. * @param {String} strUtf UTF-8 string to be decoded back to Unicode
  1141. * @returns {String} decoded string
  1142. */
  1143. Utf8.decode = function(strUtf) {
  1144. // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!
  1145. var strUni = strUtf.replace(
  1146. /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars
  1147. function(c) { // (note parentheses for precence)
  1148. var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f);
  1149. return String.fromCharCode(cc); }
  1150. );
  1151. strUni = strUni.replace(
  1152. /[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars
  1153. function(c) { // (note parentheses for precence)
  1154. var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
  1155. return String.fromCharCode(cc); }
  1156. );
  1157. return strUni;
  1158. }
  1159. /* A JavaScript implementation of the SHA family of hashes, as defined in FIPS
  1160. * PUB 180-2 as well as the corresponding HMAC implementation as defined in
  1161. * FIPS PUB 198a
  1162. *
  1163. * Version 1.3 Copyright Brian Turek 2008-2010
  1164. * Distributed under the BSD License
  1165. * See http://jssha.sourceforge.net/ for more information
  1166. *
  1167. * Several functions taken from Paul Johnson
  1168. */
  1169. /*
  1170. * Configurable variables. Defaults typically work
  1171. */
  1172. /* Number of Bits Per character (8 for ASCII, 16 for Unicode) */
  1173. var charSize = 8,
  1174. /* base-64 pad character. "=" for strict RFC compliance */
  1175. b64pad = "",
  1176. /* hex output format. 0 - lowercase; 1 - uppercase */
  1177. hexCase = 0,
  1178. /*
  1179. * Int_64 is a object for 2 32-bit numbers emulating a 64-bit number
  1180. *
  1181. * @constructor
  1182. * @param {Number} msint_32 The most significant 32-bits of a 64-bit number
  1183. * @param {Number} lsint_32 The least significant 32-bits of a 64-bit number
  1184. */
  1185. Int_64 = function (msint_32, lsint_32)
  1186. {
  1187. this.highOrder = msint_32;
  1188. this.lowOrder = lsint_32;
  1189. },
  1190. /*
  1191. * Convert a string to an array of big-endian words
  1192. * If charSize is ASCII, characters >255 have their hi-byte silently
  1193. * ignored.
  1194. *
  1195. * @param {String} str String to be converted to binary representation
  1196. * @return Integer array representation of the parameter
  1197. */
  1198. str2binb = function (str)
  1199. {
  1200. var bin = [], mask = (1 << charSize) - 1,
  1201. length = str.length * charSize, i;
  1202. for (i = 0; i < length; i += charSize)
  1203. {
  1204. bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) <<
  1205. (32 - charSize - (i % 32));
  1206. }
  1207. return bin;
  1208. },
  1209. /*
  1210. * Convert a hex string to an array of big-endian words
  1211. *
  1212. * @param {String} str String to be converted to binary representation
  1213. * @return Integer array representation of the parameter
  1214. */
  1215. hex2binb = function (str)
  1216. {
  1217. var bin = [], length = str.length, i, num;
  1218. for (i = 0; i < length; i += 2)
  1219. {
  1220. num = parseInt(str.substr(i, 2), 16);
  1221. if (!isNaN(num))
  1222. {
  1223. bin[i >> 3] |= num << (24 - (4 * (i % 8)));
  1224. }
  1225. else
  1226. {
  1227. return "INVALID HEX STRING";
  1228. }
  1229. }
  1230. return bin;
  1231. },
  1232. /*
  1233. * Convert an array of big-endian words to a hex string.
  1234. *
  1235. * @private
  1236. * @param {Array} binarray Array of integers to be converted to hexidecimal
  1237. * representation
  1238. * @return Hexidecimal representation of the parameter in String form
  1239. */
  1240. binb2hex = function (binarray)
  1241. {
  1242. var hex_tab = (hexCase) ? "0123456789ABCDEF" : "0123456789abcdef",
  1243. str = "", length = binarray.length * 4, i, srcByte;
  1244. for (i = 0; i < length; i += 1)
  1245. {
  1246. srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8);
  1247. str += hex_tab.charAt((srcByte >> 4) & 0xF) +
  1248. hex_tab.charAt(srcByte & 0xF);
  1249. }
  1250. return str;
  1251. },
  1252. /*
  1253. * Convert an array of big-endian words to a base-64 string
  1254. *
  1255. * @private
  1256. * @param {Array} binarray Array of integers to be converted to base-64
  1257. * representation
  1258. * @return Base-64 encoded representation of the parameter in String form
  1259. */
  1260. binb2b64 = function (binarray)
  1261. {
  1262. var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +
  1263. "0123456789+/", str = "", length = binarray.length * 4, i, j,
  1264. triplet;
  1265. for (i = 0; i < length; i += 3)
  1266. {
  1267. triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) |
  1268. (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) |
  1269. ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
  1270. for (j = 0; j < 4; j += 1)
  1271. {
  1272. if (i * 8 + j * 6 <= binarray.length * 32)
  1273. {
  1274. str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
  1275. }
  1276. else
  1277. {
  1278. str += b64pad;
  1279. }
  1280. }
  1281. }
  1282. return str;
  1283. },
  1284. /*
  1285. * The 32-bit implementation of circular rotate left
  1286. *
  1287. * @private
  1288. * @param {Number} x The 32-bit integer argument
  1289. * @param {Number} n The number of bits to shift
  1290. * @return The x shifted circularly by n bits
  1291. */
  1292. rotl_32 = function (x, n)
  1293. {
  1294. return (x << n) | (x >>> (32 - n));
  1295. },
  1296. /*
  1297. * The 32-bit implementation of circular rotate right
  1298. *
  1299. * @private
  1300. * @param {Number} x The 32-bit integer argument
  1301. * @param {Number} n The number of bits to shift
  1302. * @return The x shifted circularly by n bits
  1303. */
  1304. rotr_32 = function (x, n)
  1305. {
  1306. return (x >>> n) | (x << (32 - n));
  1307. },
  1308. /*
  1309. * The 64-bit implementation of circular rotate right
  1310. *
  1311. * @private
  1312. * @param {Int_64} x The 64-bit integer argument
  1313. * @param {Number} n The number of bits to shift
  1314. * @return The x shifted circularly by n bits
  1315. */
  1316. rotr_64 = function (x, n)
  1317. {
  1318. if (n <= 32)
  1319. {
  1320. return new Int_64(
  1321. (x.highOrder >>> n) | (x.lowOrder << (32 - n)),
  1322. (x.lowOrder >>> n) | (x.highOrder << (32 - n))
  1323. );
  1324. }
  1325. else
  1326. {
  1327. return new Int_64(
  1328. (x.lowOrder >>> n) | (x.highOrder << (32 - n)),
  1329. (x.highOrder >>> n) | (x.lowOrder << (32 - n))
  1330. );
  1331. }
  1332. },
  1333. /*
  1334. * The 32-bit implementation of shift right
  1335. *
  1336. * @private
  1337. * @param {Number} x The 32-bit integer argument
  1338. * @param {Number} n The number of bits to shift
  1339. * @return The x shifted by n bits
  1340. */
  1341. shr_32 = function (x, n)
  1342. {
  1343. return x >>> n;
  1344. },
  1345. /*
  1346. * The 64-bit implementation of shift right
  1347. *
  1348. * @private
  1349. * @param {Int_64} x The 64-bit integer argument
  1350. * @param {Number} n The number of bits to shift
  1351. * @return The x shifted by n bits
  1352. */
  1353. shr_64 = function (x, n)
  1354. {
  1355. if (n <= 32)
  1356. {
  1357. return new Int_64(
  1358. x.highOrder >>> n,
  1359. x.lowOrder >>> n | (x.highOrder << (32 - n))
  1360. );
  1361. }
  1362. else
  1363. {
  1364. return new Int_64(
  1365. 0,
  1366. x.highOrder << (32 - n)
  1367. );
  1368. }
  1369. },
  1370. /*
  1371. * The 32-bit implementation of the NIST specified Parity function
  1372. *
  1373. * @private
  1374. * @param {Number} x The first 32-bit integer argument
  1375. * @param {Number} y The second 32-bit integer argument
  1376. * @param {Number} z The third 32-bit integer argument
  1377. * @return The NIST specified output of the function
  1378. */
  1379. parity_32 = function (x, y, z)
  1380. {
  1381. return x ^ y ^ z;
  1382. },
  1383. /*
  1384. * The 32-bit implementation of the NIST specified Ch function
  1385. *
  1386. * @private
  1387. * @param {Number} x The first 32-bit integer argument
  1388. * @param {Number} y The second 32-bit integer argument
  1389. * @param {Number} z The third 32-bit integer argument
  1390. * @return The NIST specified output of the function
  1391. */
  1392. ch_32 = function (x, y, z)
  1393. {
  1394. return (x & y) ^ (~x & z);
  1395. },
  1396. /*
  1397. * The 64-bit implementation of the NIST specified Ch function
  1398. *
  1399. * @private
  1400. * @param {Int_64} x The first 64-bit integer argument
  1401. * @param {Int_64} y The second 64-bit integer argument
  1402. * @param {Int_64} z The third 64-bit integer argument
  1403. * @return The NIST specified output of the function
  1404. */
  1405. ch_64 = function (x, y, z)
  1406. {
  1407. return new Int_64(
  1408. (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder),
  1409. (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)
  1410. );
  1411. },
  1412. /*
  1413. * The 32-bit implementation of the NIST specified Maj function
  1414. *
  1415. * @private
  1416. * @param {Number} x The first 32-bit integer argument
  1417. * @param {Number} y The second 32-bit integer argument
  1418. * @param {Number} z The third 32-bit integer argument
  1419. * @return The NIST specified output of the function
  1420. */
  1421. maj_32 = function (x, y, z)
  1422. {
  1423. return (x & y) ^ (x & z) ^ (y & z);
  1424. },
  1425. /*
  1426. * The 64-bit implementation of the NIST specified Maj function
  1427. *
  1428. * @private
  1429. * @param {Int_64} x The first 64-bit integer argument
  1430. * @param {Int_64} y The second 64-bit integer argument
  1431. * @param {Int_64} z The third 64-bit integer argument
  1432. * @return The NIST specified output of the function
  1433. */
  1434. maj_64 = function (x, y, z)
  1435. {
  1436. return new Int_64(
  1437. (x.highOrder & y.highOrder) ^
  1438. (x.highOrder & z.highOrder) ^
  1439. (y.highOrder & z.highOrder),
  1440. (x.lowOrder & y.lowOrder) ^
  1441. (x.lowOrder & z.lowOrder) ^
  1442. (y.lowOrder & z.lowOrder)
  1443. );
  1444. },
  1445. /*
  1446. * The 32-bit implementation of the NIST specified Sigma0 function
  1447. *
  1448. * @private
  1449. * @param {Number} x The 32-bit integer argument
  1450. * @return The NIST specified output of the function
  1451. */
  1452. sigma0_32 = function (x)
  1453. {
  1454. return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22);
  1455. },
  1456. /*
  1457. * The 64-bit implementation of the NIST specified Sigma0 function
  1458. *
  1459. * @private
  1460. * @param {Int_64} x The 64-bit integer argument
  1461. * @return The NIST specified output of the function
  1462. */
  1463. sigma0_64 = function (x)
  1464. {
  1465. var rotr28 = rotr_64(x, 28), rotr34 = rotr_64(x, 34),
  1466. rotr39 = rotr_64(x, 39);
  1467. return new Int_64(
  1468. rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder,
  1469. rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder);
  1470. },
  1471. /*
  1472. * The 32-bit implementation of the NIST specified Sigma1 function
  1473. *
  1474. * @private
  1475. * @param {Number} x The 32-bit integer argument
  1476. * @return The NIST specified output of the function
  1477. */
  1478. sigma1_32 = function (x)
  1479. {
  1480. return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25);
  1481. },
  1482. /*
  1483. * The 64-bit implementation of the NIST specified Sigma1 function
  1484. *
  1485. * @private
  1486. * @param {Int_64} x The 64-bit integer argument
  1487. * @return The NIST specified output of the function
  1488. */
  1489. sigma1_64 = function (x)
  1490. {
  1491. var rotr14 = rotr_64(x, 14), rotr18 = rotr_64(x, 18),
  1492. rotr41 = rotr_64(x, 41);
  1493. return new Int_64(
  1494. rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder,
  1495. rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder);
  1496. },
  1497. /*
  1498. * The 32-bit implementation of the NIST specified Gamma0 function
  1499. *
  1500. * @private
  1501. * @param {Number} x The 32-bit integer argument
  1502. * @return The NIST specified output of the function
  1503. */
  1504. gamma0_32 = function (x)
  1505. {
  1506. return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3);
  1507. },
  1508. /*
  1509. * The 64-bit implementation of the NIST specified Gamma0 function
  1510. *
  1511. * @private
  1512. * @param {Int_64} x The 64-bit integer argument
  1513. * @return The NIST specified output of the function
  1514. */
  1515. gamma0_64 = function (x)
  1516. {
  1517. var rotr1 = rotr_64(x, 1), rotr8 = rotr_64(x, 8), shr7 = shr_64(x, 7);
  1518. return new Int_64(
  1519. rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder,
  1520. rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder
  1521. );
  1522. },
  1523. /*
  1524. * The 32-bit implementation of the NIST specified Gamma1 function
  1525. *
  1526. * @private
  1527. * @param {Number} x The 32-bit integer argument
  1528. * @return The NIST specified output of the function
  1529. */
  1530. gamma1_32 = function (x)
  1531. {
  1532. return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10);
  1533. },
  1534. /*
  1535. * The 64-bit implementation of the NIST specified Gamma1 function
  1536. *
  1537. * @private
  1538. * @param {Int_64} x The 64-bit integer argument
  1539. * @return The NIST specified output of the function
  1540. */
  1541. gamma1_64 = function (x)
  1542. {
  1543. var rotr19 = rotr_64(x, 19), rotr61 = rotr_64(x, 61),
  1544. shr6 = shr_64(x, 6);
  1545. return new Int_64(
  1546. rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder,
  1547. rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder
  1548. );
  1549. },
  1550. /*
  1551. * Add two 32-bit integers, wrapping at 2^32. This uses 16-bit operations
  1552. * internally to work around bugs in some JS interpreters.
  1553. *
  1554. * @private
  1555. * @param {Number} x The first 32-bit integer argument to be added
  1556. * @param {Number} y The second 32-bit integer argument to be added
  1557. * @return The sum of x + y
  1558. */
  1559. safeAdd_32_2 = function (x, y)
  1560. {
  1561. var lsw = (x & 0xFFFF) + (y & 0xFFFF),
  1562. msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16);
  1563. return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1564. },
  1565. /*
  1566. * Add four 32-bit integers, wrapping at 2^32. This uses 16-bit operations
  1567. * internally to work around bugs in some JS interpreters.
  1568. *
  1569. * @private
  1570. * @param {Number} a The first 32-bit integer argument to be added
  1571. * @param {Number} b The second 32-bit integer argument to be added
  1572. * @param {Number} c The third 32-bit integer argument to be added
  1573. * @param {Number} d The fourth 32-bit integer argument to be added
  1574. * @return The sum of a + b + c + d
  1575. */
  1576. safeAdd_32_4 = function (a, b, c, d)
  1577. {
  1578. var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF),
  1579. msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) +
  1580. (lsw >>> 16);
  1581. return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1582. },
  1583. /*
  1584. * Add five 32-bit integers, wrapping at 2^32. This uses 16-bit operations
  1585. * internally to work around bugs in some JS interpreters.
  1586. *
  1587. * @private
  1588. * @param {Number} a The first 32-bit integer argument to be added
  1589. * @param {Number} b The second 32-bit integer argument to be added
  1590. * @param {Number} c The third 32-bit integer argument to be added
  1591. * @param {Number} d The fourth 32-bit integer argument to be added
  1592. * @param {Number} e The fifth 32-bit integer argument to be added
  1593. * @return The sum of a + b + c + d + e
  1594. */
  1595. safeAdd_32_5 = function (a, b, c, d, e)
  1596. {
  1597. var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) +
  1598. (e & 0xFFFF),
  1599. msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) +
  1600. (e >>> 16) + (lsw >>> 16);
  1601. return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1602. },
  1603. /*
  1604. * Add two 64-bit integers, wrapping at 2^64. This uses 16-bit operations
  1605. * internally to work around bugs in some JS interpreters.
  1606. *
  1607. * @private
  1608. * @param {Int_64} x The first 64-bit integer argument to be added
  1609. * @param {Int_64} y The second 64-bit integer argument to be added
  1610. * @return The sum of x + y
  1611. */
  1612. safeAdd_64_2 = function (x, y)
  1613. {
  1614. var lsw, msw, lowOrder, highOrder;
  1615. lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF);
  1616. msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16);
  1617. lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1618. lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16);
  1619. msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16);
  1620. highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1621. return new Int_64(highOrder, lowOrder);
  1622. },
  1623. /*
  1624. * Add four 64-bit integers, wrapping at 2^64. This uses 16-bit operations
  1625. * internally to work around bugs in some JS interpreters.
  1626. *
  1627. * @private
  1628. * @param {Int_64} a The first 64-bit integer argument to be added
  1629. * @param {Int_64} b The second 64-bit integer argument to be added
  1630. * @param {Int_64} c The third 64-bit integer argument to be added
  1631. * @param {Int_64} d The fouth 64-bit integer argument to be added
  1632. * @return The sum of a + b + c + d
  1633. */
  1634. safeAdd_64_4 = function (a, b, c, d)
  1635. {
  1636. var lsw, msw, lowOrder, highOrder;
  1637. lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) +
  1638. (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF);
  1639. msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) +
  1640. (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16);
  1641. lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1642. lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) +
  1643. (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16);
  1644. msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) +
  1645. (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16);
  1646. highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1647. return new Int_64(highOrder, lowOrder);
  1648. },
  1649. /*
  1650. * Add five 64-bit integers, wrapping at 2^64. This uses 16-bit operations
  1651. * internally to work around bugs in some JS interpreters.
  1652. *
  1653. * @private
  1654. * @param {Int_64} a The first 64-bit integer argument to be added
  1655. * @param {Int_64} b The second 64-bit integer argument to be added
  1656. * @param {Int_64} c The third 64-bit integer argument to be added
  1657. * @param {Int_64} d The fouth 64-bit integer argument to be added
  1658. * @param {Int_64} e The fouth 64-bit integer argument to be added
  1659. * @return The sum of a + b + c + d + e
  1660. */
  1661. safeAdd_64_5 = function (a, b, c, d, e)
  1662. {
  1663. var lsw, msw, lowOrder, highOrder;
  1664. lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) +
  1665. (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) +
  1666. (e.lowOrder & 0xFFFF);
  1667. msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) +
  1668. (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) +
  1669. (lsw >>> 16);
  1670. lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1671. lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) +
  1672. (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) +
  1673. (e.highOrder & 0xFFFF) + (msw >>> 16);
  1674. msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) +
  1675. (c.highOrder >>> 16) + (d.highOrder >>> 16) +
  1676. (e.highOrder >>> 16) + (lsw >>> 16);
  1677. highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
  1678. return new Int_64(highOrder, lowOrder);
  1679. },
  1680. /*
  1681. * Calculates the SHA-1 hash of the string set at instantiation
  1682. *
  1683. * @private
  1684. * @param {Array} message The binary array representation of the string to
  1685. * hash
  1686. * @param {Number} messageLen The number of bits in the message
  1687. * @return The array of integers representing the SHA-1 hash of message
  1688. */
  1689. coreSHA1 = function (message, messageLen)
  1690. {
  1691. var W = [], a, b, c, d, e, T, ch = ch_32, parity = parity_32,
  1692. maj = maj_32, rotl = rotl_32, safeAdd_2 = safeAdd_32_2, i, t,
  1693. safeAdd_5 = safeAdd_32_5, appendedMessageLength,
  1694. H = [
  1695. 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
  1696. ],
  1697. K = [
  1698. 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
  1699. 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
  1700. 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
  1701. 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
  1702. 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
  1703. 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
  1704. 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
  1705. 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
  1706. 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
  1707. 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
  1708. 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
  1709. 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
  1710. 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
  1711. 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
  1712. 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
  1713. 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
  1714. 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
  1715. 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
  1716. 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
  1717. 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6
  1718. ];
  1719. /* Append '1' at the end of the binary string */
  1720. message[messageLen >> 5] |= 0x80 << (24 - (messageLen % 32));
  1721. /* Append length of binary string in the position such that the new
  1722. length is a multiple of 512. Logic does not work for even multiples
  1723. of 512 but there can never be even multiples of 512 */
  1724. message[(((messageLen + 65) >> 9) << 4) + 15] = messageLen;
  1725. appendedMessageLength = message.length;
  1726. for (i = 0; i < appendedMessageLength; i += 16)
  1727. {
  1728. a = H[0];
  1729. b = H[1];
  1730. c = H[2];
  1731. d = H[3];
  1732. e = H[4];
  1733. for (t = 0; t < 80; t += 1)
  1734. {
  1735. if (t < 16)
  1736. {
  1737. W[t] = message[t + i];
  1738. }
  1739. else
  1740. {
  1741. W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
  1742. }
  1743. if (t < 20)
  1744. {
  1745. T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, K[t], W[t]);
  1746. }
  1747. else if (t < 40)
  1748. {
  1749. T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]);
  1750. }
  1751. else if (t < 60)
  1752. {
  1753. T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, K[t], W[t]);
  1754. } else {
  1755. T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]);
  1756. }
  1757. e = d;
  1758. d = c;
  1759. c = rotl(b, 30);
  1760. b = a;
  1761. a = T;
  1762. }
  1763. H[0] = safeAdd_2(a, H[0]);
  1764. H[1] = safeAdd_2(b, H[1]);
  1765. H[2] = safeAdd_2(c, H[2]);
  1766. H[3] = safeAdd_2(d, H[3]);
  1767. H[4] = safeAdd_2(e, H[4]);
  1768. }
  1769. return H;
  1770. },
  1771. /*
  1772. * Calculates the desired SHA-2 hash of the string set at instantiation
  1773. *
  1774. * @private
  1775. * @param {Array} The binary array representation of the string to hash
  1776. * @param {Number} The number of bits in message
  1777. * @param {String} variant The desired SHA-2 variant
  1778. * @return The array of integers representing the SHA-2 hash of message
  1779. */
  1780. coreSHA2 = function (message, messageLen, variant)
  1781. {
  1782. var a, b, c, d, e, f, g, h, T1, T2, H, numRounds, lengthPosition, i, t,
  1783. binaryStringInc, binaryStringMult, safeAdd_2, safeAdd_4, safeAdd_5,
  1784. gamma0, gamma1, sigma0, sigma1, ch, maj, Int, K, W = [],
  1785. appendedMessageLength;
  1786. /* Set up the various function handles and variable for the specific
  1787. * variant */
  1788. if (variant === "SHA-224" || variant === "SHA-256")
  1789. {
  1790. /* 32-bit variant */
  1791. numRounds = 64;
  1792. lengthPosition = (((messageLen + 65) >> 9) << 4) + 15;
  1793. binaryStringInc = 16;
  1794. binaryStringMult = 1;
  1795. Int = Number;
  1796. safeAdd_2 = safeAdd_32_2;
  1797. safeAdd_4 = safeAdd_32_4;
  1798. safeAdd_5 = safeAdd_32_5;
  1799. gamma0 = gamma0_32;
  1800. gamma1 = gamma1_32;
  1801. sigma0 = sigma0_32;
  1802. sigma1 = sigma1_32;
  1803. maj = maj_32;
  1804. ch = ch_32;
  1805. K = [
  1806. 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
  1807. 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
  1808. 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
  1809. 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
  1810. 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
  1811. 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
  1812. 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
  1813. 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
  1814. 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
  1815. 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
  1816. 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
  1817. 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
  1818. 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
  1819. 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
  1820. 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
  1821. 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
  1822. ];
  1823. if (variant === "SHA-224")
  1824. {
  1825. H = [
  1826. 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
  1827. 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
  1828. ];
  1829. }
  1830. else
  1831. {
  1832. H = [
  1833. 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
  1834. 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
  1835. ];
  1836. }
  1837. }
  1838. else if (variant === "SHA-384" || variant === "SHA-512")
  1839. {
  1840. /* 64-bit variant */
  1841. numRounds = 80;
  1842. lengthPosition = (((messageLen + 128) >> 10) << 5) + 31;
  1843. binaryStringInc = 32;
  1844. binaryStringMult = 2;
  1845. Int = Int_64;
  1846. safeAdd_2 = safeAdd_64_2;
  1847. safeAdd_4 = safeAdd_64_4;
  1848. safeAdd_5 = safeAdd_64_5;
  1849. gamma0 = gamma0_64;
  1850. gamma1 = gamma1_64;
  1851. sigma0 = sigma0_64;
  1852. sigma1 = sigma1_64;
  1853. maj = maj_64;
  1854. ch = ch_64;
  1855. K = [
  1856. new Int(0x428a2f98, 0xd728ae22), new Int(0x71374491, 0x23ef65cd),
  1857. new Int(0xb5c0fbcf, 0xec4d3b2f), new Int(0xe9b5dba5, 0x8189dbbc),
  1858. new Int(0x3956c25b, 0xf348b538), new Int(0x59f111f1, 0xb605d019),
  1859. new Int(0x923f82a4, 0xaf194f9b), new Int(0xab1c5ed5, 0xda6d8118),
  1860. new Int(0xd807aa98, 0xa3030242), new Int(0x12835b01, 0x45706fbe),
  1861. new Int(0x243185be, 0x4ee4b28c), new Int(0x550c7dc3, 0xd5ffb4e2),
  1862. new Int(0x72be5d74, 0xf27b896f), new Int(0x80deb1fe, 0x3b1696b1),
  1863. new Int(0x9bdc06a7, 0x25c71235), new Int(0xc19bf174, 0xcf692694),
  1864. new Int(0xe49b69c1, 0x9ef14ad2), new Int(0xefbe4786, 0x384f25e3),
  1865. new Int(0x0fc19dc6, 0x8b8cd5b5), new Int(0x240ca1cc, 0x77ac9c65),
  1866. new Int(0x2de92c6f, 0x592b0275), new Int(0x4a7484aa, 0x6ea6e483),
  1867. new Int(0x5cb0a9dc, 0xbd41fbd4), new Int(0x76f988da, 0x831153b5),
  1868. new Int(0x983e5152, 0xee66dfab), new Int(0xa831c66d, 0x2db43210),
  1869. new Int(0xb00327c8, 0x98fb213f), new Int(0xbf597fc7, 0xbeef0ee4),
  1870. new Int(0xc6e00bf3, 0x3da88fc2), new Int(0xd5a79147, 0x930aa725),
  1871. new Int(0x06ca6351, 0xe003826f), new Int(0x14292967, 0x0a0e6e70),
  1872. new Int(0x27b70a85, 0x46d22ffc), new Int(0x2e1b2138, 0x5c26c926),
  1873. new Int(0x4d2c6dfc, 0x5ac42aed), new Int(0x53380d13, 0x9d95b3df),
  1874. new Int(0x650a7354, 0x8baf63de), new Int(0x766a0abb, 0x3c77b2a8),
  1875. new Int(0x81c2c92e, 0x47edaee6), new Int(0x92722c85, 0x1482353b),
  1876. new Int(0xa2bfe8a1, 0x4cf10364), new Int(0xa81a664b, 0xbc423001),
  1877. new Int(0xc24b8b70, 0xd0f89791), new Int(0xc76c51a3, 0x0654be30),
  1878. new Int(0xd192e819, 0xd6ef5218), new Int(0xd6990624, 0x5565a910),
  1879. new Int(0xf40e3585, 0x5771202a), new Int(0x106aa070, 0x32bbd1b8),
  1880. new Int(0x19a4c116, 0xb8d2d0c8), new Int(0x1e376c08, 0x5141ab53),
  1881. new Int(0x2748774c, 0xdf8eeb99), new Int(0x34b0bcb5, 0xe19b48a8),
  1882. new Int(0x391c0cb3, 0xc5c95a63), new Int(0x4ed8aa4a, 0xe3418acb),
  1883. new Int(0x5b9cca4f, 0x7763e373), new Int(0x682e6ff3, 0xd6b2b8a3),
  1884. new Int(0x748f82ee, 0x5defb2fc), new Int(0x78a5636f, 0x43172f60),
  1885. new Int(0x84c87814, 0xa1f0ab72), new Int(0x8cc70208, 0x1a6439ec),
  1886. new Int(0x90befffa, 0x23631e28), new Int(0xa4506ceb, 0xde82bde9),
  1887. new Int(0xbef9a3f7, 0xb2c67915), new Int(0xc67178f2, 0xe372532b),
  1888. new Int(0xca273ece, 0xea26619c), new Int(0xd186b8c7, 0x21c0c207),
  1889. new Int(0xeada7dd6, 0xcde0eb1e), new Int(0xf57d4f7f, 0xee6ed178),
  1890. new Int(0x06f067aa, 0x72176fba), new Int(0x0a637dc5, 0xa2c898a6),
  1891. new Int(0x113f9804, 0xbef90dae), new Int(0x1b710b35, 0x131c471b),
  1892. new Int(0x28db77f5, 0x23047d84), new Int(0x32caab7b, 0x40c72493),
  1893. new Int(0x3c9ebe0a, 0x15c9bebc), new Int(0x431d67c4, 0x9c100d4c),
  1894. new Int(0x4cc5d4be, 0xcb3e42b6), new Int(0x597f299c, 0xfc657e2a),
  1895. new Int(0x5fcb6fab, 0x3ad6faec), new Int(0x6c44198c, 0x4a475817)
  1896. ];
  1897. if (variant === "SHA-384")
  1898. {
  1899. H = [
  1900. new Int(0xcbbb9d5d, 0xc1059ed8), new Int(0x0629a292a, 0x367cd507),
  1901. new Int(0x9159015a, 0x3070dd17), new Int(0x0152fecd8, 0xf70e5939),
  1902. new Int(0x67332667, 0xffc00b31), new Int(0x98eb44a87, 0x68581511),
  1903. new Int(0xdb0c2e0d, 0x64f98fa7), new Int(0x047b5481d, 0xbefa4fa4)
  1904. ];
  1905. }
  1906. else
  1907. {
  1908. H = [
  1909. new Int(0x6a09e667, 0xf3bcc908), new Int(0xbb67ae85, 0x84caa73b),
  1910. new Int(0x3c6ef372, 0xfe94f82b), new Int(0xa54ff53a, 0x5f1d36f1),
  1911. new Int(0x510e527f, 0xade682d1), new Int(0x9b05688c, 0x2b3e6c1f),
  1912. new Int(0x1f83d9ab, 0xfb41bd6b), new Int(0x5be0cd19, 0x137e2179)
  1913. ];
  1914. }
  1915. }
  1916. /* Append '1' at the end of the binary string */
  1917. message[messageLen >> 5] |= 0x80 << (24 - messageLen % 32);
  1918. /* Append length of binary string in the position such that the new
  1919. * length is correct */
  1920. message[lengthPosition] = messageLen;
  1921. appendedMessageLength = message.length;
  1922. for (i = 0; i < appendedMessageLength; i += binaryStringInc)
  1923. {
  1924. a = H[0];
  1925. b = H[1];
  1926. c = H[2];
  1927. d = H[3];
  1928. e = H[4];
  1929. f = H[5];
  1930. g = H[6];
  1931. h = H[7];
  1932. for (t = 0; t < numRounds; t += 1)
  1933. {
  1934. if (t < 16)
  1935. {
  1936. /* Bit of a hack - for 32-bit, the second term is ignored */
  1937. W[t] = new Int(message[t * binaryStringMult + i],
  1938. message[t * binaryStringMult + i + 1]);
  1939. }
  1940. else
  1941. {
  1942. W[t] = safeAdd_4(
  1943. gamma1(W[t - 2]), W[t - 7],
  1944. gamma0(W[t - 15]), W[t - 16]
  1945. );
  1946. }
  1947. T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]);
  1948. T2 = safeAdd_2(sigma0(a), maj(a, b, c));
  1949. h = g;
  1950. g = f;
  1951. f = e;
  1952. e = safeAdd_2(d, T1);
  1953. d = c;
  1954. c = b;
  1955. b = a;
  1956. a = safeAdd_2(T1, T2);
  1957. }
  1958. H[0] = safeAdd_2(a, H[0]);
  1959. H[1] = safeAdd_2(b, H[1]);
  1960. H[2] = safeAdd_2(c, H[2]);
  1961. H[3] = safeAdd_2(d, H[3]);
  1962. H[4] = safeAdd_2(e, H[4]);
  1963. H[5] = safeAdd_2(f, H[5]);
  1964. H[6] = safeAdd_2(g, H[6]);
  1965. H[7] = safeAdd_2(h, H[7]);
  1966. }
  1967. switch (variant)
  1968. {
  1969. case "SHA-224":
  1970. return [
  1971. H[0], H[1], H[2], H[3],
  1972. H[4], H[5], H[6]
  1973. ];
  1974. case "SHA-256":
  1975. return H;
  1976. case "SHA-384":
  1977. return [
  1978. H[0].highOrder, H[0].lowOrder,
  1979. H[1].highOrder, H[1].lowOrder,
  1980. H[2].highOrder, H[2].lowOrder,
  1981. H[3].highOrder, H[3].lowOrder,
  1982. H[4].highOrder, H[4].lowOrder,
  1983. H[5].highOrder, H[5].lowOrder
  1984. ];
  1985. case "SHA-512":
  1986. return [
  1987. H[0].highOrder, H[0].lowOrder,
  1988. H[1].highOrder, H[1].lowOrder,
  1989. H[2].highOrder, H[2].lowOrder,
  1990. H[3].highOrder, H[3].lowOrder,
  1991. H[4].highOrder, H[4].lowOrder,
  1992. H[5].highOrder, H[5].lowOrder,
  1993. H[6].highOrder, H[6].lowOrder,
  1994. H[7].highOrder, H[7].lowOrder
  1995. ];
  1996. default:
  1997. /* This should never be reached */
  1998. return [];
  1999. }
  2000. },
  2001. /*
  2002. * jsSHA is the workhorse of the library. Instantiate it with the string to
  2003. * be hashed as the parameter
  2004. *
  2005. * @constructor
  2006. * @param {String} srcString The string to be hashed
  2007. * @param {String} inputFormat The format of srcString, ASCII or HEX
  2008. */
  2009. jsSHA = function (srcString, inputFormat)
  2010. {
  2011. this.sha1 = null;
  2012. this.sha224 = null;
  2013. this.sha256 = null;
  2014. this.sha384 = null;
  2015. this.sha512 = null;
  2016. this.strBinLen = null;
  2017. this.strToHash = null;
  2018. /* Convert the input string into the correct type */
  2019. if ("HEX" === inputFormat)
  2020. {
  2021. if (0 !== (srcString.length % 2))
  2022. {
  2023. return "TEXT MUST BE IN BYTE INCREMENTS";
  2024. }
  2025. this.strBinLen = srcString.length * 4;
  2026. this.strToHash = hex2binb(srcString);
  2027. }
  2028. else if (("ASCII" === inputFormat) ||
  2029. ('undefined' === typeof(inputFormat)))
  2030. {
  2031. this.strBinLen = srcString.length * charSize;
  2032. this.strToHash = str2binb(srcString);
  2033. }
  2034. else
  2035. {
  2036. return "UNKNOWN TEXT INPUT TYPE";
  2037. }
  2038. };
  2039. jsSHA.prototype = {
  2040. /*
  2041. * Returns the desired SHA hash of the string specified at instantiation
  2042. * using the specified parameters
  2043. *
  2044. * @param {String} variant The desired SHA variant (SHA-1, SHA-224,
  2045. * SHA-256, SHA-384, or SHA-512)
  2046. * @param {String} format The desired output formatting (B64 or HEX)
  2047. * @return The string representation of the hash in the format specified
  2048. */
  2049. getHash : function (variant, format)
  2050. {
  2051. var formatFunc = null, message = this.strToHash.slice();
  2052. switch (format)
  2053. {
  2054. case "HEX":
  2055. formatFunc = binb2hex;
  2056. break;
  2057. case "B64":
  2058. formatFunc = binb2b64;
  2059. break;
  2060. default:
  2061. return "FORMAT NOT RECOGNIZED";
  2062. }
  2063. switch (variant)
  2064. {
  2065. case "SHA-1":
  2066. if (null === this.sha1)
  2067. {
  2068. this.sha1 = coreSHA1(message, this.strBinLen);
  2069. }
  2070. return formatFunc(this.sha1);
  2071. case "SHA-224":
  2072. if (null === this.sha224)
  2073. {
  2074. this.sha224 = coreSHA2(message, this.strBinLen, variant);
  2075. }
  2076. return formatFunc(this.sha224);
  2077. case "SHA-256":
  2078. if (null === this.sha256)
  2079. {
  2080. this.sha256 = coreSHA2(message, this.strBinLen, variant);
  2081. }
  2082. return formatFunc(this.sha256);
  2083. case "SHA-384":
  2084. if (null === this.sha384)
  2085. {
  2086. this.sha384 = coreSHA2(message, this.strBinLen, variant);
  2087. }
  2088. return formatFunc(this.sha384);
  2089. case "SHA-512":
  2090. if (null === this.sha512)
  2091. {
  2092. this.sha512 = coreSHA2(message, this.strBinLen, variant);
  2093. }
  2094. return formatFunc(this.sha512);
  2095. default:
  2096. return "HASH NOT RECOGNIZED";
  2097. }
  2098. },
  2099. /*
  2100. * Returns the desired HMAC of the string specified at instantiation
  2101. * using the key and variant param.
  2102. *
  2103. * @param {String} key The key used to calculate the HMAC
  2104. * @param {String} inputFormat The format of key, ASCII or HEX
  2105. * @param {String} variant The desired SHA variant (SHA-1, SHA-224,
  2106. * SHA-256, SHA-384, or SHA-512)
  2107. * @param {String} outputFormat The desired output formatting
  2108. * (B64 or HEX)
  2109. * @return The string representation of the hash in the format specified
  2110. */
  2111. getHMAC : function (key, inputFormat, variant, outputFormat)
  2112. {
  2113. var formatFunc, keyToUse, blockByteSize, blockBitSize, i,
  2114. retVal, lastArrayIndex, keyBinLen, hashBitSize,
  2115. keyWithIPad = [], keyWithOPad = [];
  2116. /* Validate the output format selection */
  2117. switch (outputFormat)
  2118. {
  2119. case "HEX":
  2120. formatFunc = binb2hex;
  2121. break;
  2122. case "B64":
  2123. formatFunc = binb2b64;
  2124. break;
  2125. default:
  2126. return "FORMAT NOT RECOGNIZED";
  2127. }
  2128. /* Validate the hash variant selection and set needed variables */
  2129. switch (variant)
  2130. {
  2131. case "SHA-1":
  2132. blockByteSize = 64;
  2133. hashBitSize = 160;
  2134. break;
  2135. case "SHA-224":
  2136. blockByteSize = 64;
  2137. hashBitSize = 224;
  2138. break;
  2139. case "SHA-256":
  2140. blockByteSize = 64;
  2141. hashBitSize = 256;
  2142. break;
  2143. case "SHA-384":
  2144. blockByteSize = 128;
  2145. hashBitSize = 384;
  2146. break;
  2147. case "SHA-512":
  2148. blockByteSize = 128;
  2149. hashBitSize = 512;
  2150. break;
  2151. default:
  2152. return "HASH NOT RECOGNIZED";
  2153. }
  2154. /* Validate input format selection */
  2155. if ("HEX" === inputFormat)
  2156. {
  2157. /* Nibbles must come in pairs */
  2158. if (0 !== (key.length % 2))
  2159. {
  2160. return "KEY MUST BE IN BYTE INCREMENTS";
  2161. }
  2162. keyToUse = hex2binb(key);
  2163. keyBinLen = key.length * 4;
  2164. }
  2165. else if ("ASCII" === inputFormat)
  2166. {
  2167. keyToUse = str2binb(key);
  2168. keyBinLen = key.length * charSize;
  2169. }
  2170. else
  2171. {
  2172. return "UNKNOWN KEY INPUT TYPE";
  2173. }
  2174. /* These are used multiple times, calculate and store them */
  2175. blockBitSize = blockByteSize * 8;
  2176. lastArrayIndex = (blockByteSize / 4) - 1;
  2177. /* Figure out what to do with the key based on its size relative to
  2178. * the hash's block size */
  2179. if (blockByteSize < (keyBinLen / 8))
  2180. {
  2181. if ("SHA-1" === variant)
  2182. {
  2183. keyToUse = coreSHA1(keyToUse, keyBinLen);
  2184. }
  2185. else
  2186. {
  2187. keyToUse = coreSHA2(keyToUse, keyBinLen, variant);
  2188. }
  2189. /* For all variants, the block size is bigger than the output
  2190. * size so there will never be a useful byte at the end of the
  2191. * string */
  2192. keyToUse[lastArrayIndex] &= 0xFFFFFF00;
  2193. }
  2194. else if (blockByteSize > (keyBinLen / 8))
  2195. {
  2196. /* If the blockByteSize is greater than the key length, there
  2197. * will always be at LEAST one "useless" byte at the end of the
  2198. * string */
  2199. keyToUse[lastArrayIndex] &= 0xFFFFFF00;
  2200. }
  2201. /* Create ipad and opad */
  2202. for (i = 0; i <= lastArrayIndex; i += 1)
  2203. {
  2204. keyWithIPad[i] = keyToUse[i] ^ 0x36363636;
  2205. keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C;
  2206. }
  2207. /* Calculate the HMAC */
  2208. if ("SHA-1" === variant)
  2209. {
  2210. retVal = coreSHA1(
  2211. keyWithIPad.concat(this.strToHash),
  2212. blockBitSize + this.strBinLen);
  2213. retVal = coreSHA1(
  2214. keyWithOPad.concat(retVal),
  2215. blockBitSize + hashBitSize);
  2216. }
  2217. else
  2218. {
  2219. retVal = coreSHA2(
  2220. keyWithIPad.concat(this.strToHash),
  2221. blockBitSize + this.strBinLen, variant);
  2222. retVal = coreSHA2(
  2223. keyWithOPad.concat(retVal),
  2224. blockBitSize + hashBitSize, variant);
  2225. }
  2226. return (formatFunc(retVal));
  2227. }
  2228. };
  2229. window.jsSHA = jsSHA;