andrew4582

SHA-1 JavaScript

Feb 8th, 2012
485
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. // The SHA-1 code in this section was copied from:
  3. // A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS PUB 180-1
  4. // Version 2.1a Copyright Paul Johnston 2000 - 2002.
  5. // Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
  6. // Distributed under the BSD License
  7. // See http://pajhome.org.uk/crypt/md5 for details.
  8. function b64_sha1(s) {
  9.     return binb2b64(core_sha1(str2binb(s), s.length * 8));
  10. }
  11.  
  12. function b64_hmac_sha1(key, data) {
  13.     return binb2b64(core_hmac_sha1(key, data));
  14. }
  15.  
  16. // Calculate the SHA-1 of an array of big-endian words, and a bit length
  17. function core_sha1(x, len) {
  18.     x[len >> 5] |= 0x80 << (24 - len % 32); // append padding
  19.     x[((len + 64 >> 9) << 4) + 15] = len;
  20.  
  21.     var w = Array(80);
  22.     var a = 1732584193;
  23.     var b = -271733879;
  24.     var c = -1732584194;
  25.     var d = 271733878;
  26.     var e = -1009589776;
  27.  
  28.     for (var i = 0; i < x.length; i += 16) {
  29.         var olda = a;
  30.         var oldb = b;
  31.         var oldc = c;
  32.         var oldd = d;
  33.         var olde = e;
  34.  
  35.         for (var j = 0; j < 80; j++) {
  36.             if (j < 16) {
  37.                 w[j] = x[i + j];
  38.             } else {
  39.                 w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
  40.             }
  41.  
  42.             var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
  43.             e = d;
  44.             d = c;
  45.             c = rol(b, 30);
  46.             b = a;
  47.             a = t;
  48.         }
  49.  
  50.         a = safe_add(a, olda);
  51.         b = safe_add(b, oldb);
  52.         c = safe_add(c, oldc);
  53.         d = safe_add(d, oldd);
  54.         e = safe_add(e, olde);
  55.     }
  56.  
  57.     return Array(a, b, c, d, e);
  58. }
  59.  
  60. // Perform the appropriate triplet combination function for the current iteration
  61. function sha1_ft(t, b, c, d) {
  62.     if (t < 20) {
  63.         return (b & c) | ((~b) & d);
  64.     }
  65.  
  66.     if (t < 40) {
  67.         return b ^ c ^ d;
  68.     }
  69.  
  70.     if (t < 60) {
  71.         return (b & c) | (b & d) | (c & d);
  72.     }
  73.  
  74.     return b ^ c ^ d;
  75. }
  76.  
  77. // Determine the appropriate additive constant for the current iteration
  78. function sha1_kt(t) {
  79.     return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514;
  80. }
  81.  
  82. // Calculate the HMAC-SHA1 of a key and some data
  83. function core_hmac_sha1(key, data) {
  84.     var bkey = str2binb(key);
  85.     if (bkey.length > 16) {
  86.         bkey = core_sha1(bkey, key.length * 8);
  87.     }
  88.  
  89.     var ipad = Array(16),
  90.             opad = Array(16);
  91.     for (var i = 0; i < 16; i++) {
  92.         ipad[i] = bkey[i] ^ 0x36363636;
  93.         opad[i] = bkey[i] ^ 0x5C5C5C5C;
  94.     }
  95.  
  96.     var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * 8);
  97.     return core_sha1(opad.concat(hash), 512 + 160);
  98. }
  99.  
  100. // Add integers, wrapping at 2^32. This uses 16-bit operations internally
  101. // to work around bugs in some JS interpreters.
  102. function safe_add(x, y) {
  103.     var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  104.     var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  105.     return (msw << 16) | (lsw & 0xFFFF);
  106. }
  107.  
  108. // Bitwise rotate a 32-bit number to the left.
  109. function rol(num, cnt) {
  110.     return (num << cnt) | (num >>> (32 - cnt));
  111. }
  112.  
  113.  
  114. // Convert an 8-bit string to an array of big-endian words
  115. // Characters > 255 have their hi-byte silently ignored.
  116. function str2binb(str) {
  117.     var bin = Array();
  118.     var mask = (1 << 8) - 1;
  119.     for (var i = 0; i < str.length * 8; i += 8) {
  120.         bin[i >> 5] |= (str.charCodeAt(i / 8) & mask) << (32 - 8 - i % 32);
  121.     }
  122.  
  123.     return bin;
  124. }
  125.  
  126. // Convert an array of big-endian words to a string
  127. function binb2str(bin) {
  128.     var str = "";
  129.     var mask = (1 << 8) - 1;
  130.     for (var i = 0; i < bin.length * 32; i += 8) {
  131.         str += String.fromCharCode((bin[i >> 5] >>> (32 - 8 - i % 32)) & mask);
  132.     }
  133.  
  134.     return str;
  135. }
  136.  
  137. // Convert an array of big-endian words to a base-64 string
  138. function binb2b64(binarray) {
  139.     var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  140.     var str = "";
  141.     for (var i = 0; i < binarray.length * 4; i += 3) {
  142.         var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
  143.  
  144.         for (var j = 0; j < 4; j++) {
  145.             if (i * 8 + j * 6 > binarray.length * 32) {
  146.                 str += '=';
  147.             } else {
  148.                 str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
  149.             }
  150.         }
  151.     }
  152.  
  153.     return str;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment