jshash-2.2_sha256.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
  3. * in FIPS 180-2
  4. * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
  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. * Also http://anmar.eu.org/projects/jssha2/
  9. */
  10. /*
  11. * Configurable variables. You may need to tweak these to be compatible with
  12. * the server-side, but the defaults work in most cases.
  13. */
  14. var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
  15. var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
  16. /*
  17. * These are the functions you'll usually want to call
  18. * They take string arguments and return either hex or base-64 encoded strings
  19. */
  20. function hex_sha256(s) { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
  21. function b64_sha256(s) { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
  22. function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
  23. function hex_hmac_sha256(k, d)
  24. { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
  25. function b64_hmac_sha256(k, d)
  26. { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
  27. function any_hmac_sha256(k, d, e)
  28. { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
  29. /*
  30. * Perform a simple self-test to see if the VM is working
  31. */
  32. function sha256_vm_test()
  33. {
  34. return hex_sha256("abc").toLowerCase() ==
  35. "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
  36. }
  37. /*
  38. * Calculate the sha256 of a raw string
  39. */
  40. function rstr_sha256(s)
  41. {
  42. return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
  43. }
  44. /*
  45. * Calculate the HMAC-sha256 of a key and some data (raw strings)
  46. */
  47. function rstr_hmac_sha256(key, data)
  48. {
  49. var bkey = rstr2binb(key);
  50. if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
  51. var ipad = Array(16), opad = Array(16);
  52. for(var i = 0; i < 16; i++)
  53. {
  54. ipad[i] = bkey[i] ^ 0x36363636;
  55. opad[i] = bkey[i] ^ 0x5C5C5C5C;
  56. }
  57. var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
  58. return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
  59. }
  60. /*
  61. * Convert a raw string to a hex string
  62. */
  63. function rstr2hex(input)
  64. {
  65. try { hexcase } catch(e) { hexcase=0; }
  66. var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  67. var output = "";
  68. var x;
  69. for(var i = 0; i < input.length; i++)
  70. {
  71. x = input.charCodeAt(i);
  72. output += hex_tab.charAt((x >>> 4) & 0x0F)
  73. + hex_tab.charAt( x & 0x0F);
  74. }
  75. return output;
  76. }
  77. /*
  78. * Convert a raw string to a base-64 string
  79. */
  80. function rstr2b64(input)
  81. {
  82. try { b64pad } catch(e) { b64pad=''; }
  83. var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  84. var output = "";
  85. var len = input.length;
  86. for(var i = 0; i < len; i += 3)
  87. {
  88. var triplet = (input.charCodeAt(i) << 16)
  89. | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
  90. | (i + 2 < len ? input.charCodeAt(i+2) : 0);
  91. for(var j = 0; j < 4; j++)
  92. {
  93. if(i * 8 + j * 6 > input.length * 8) output += b64pad;
  94. else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
  95. }
  96. }
  97. return output;
  98. }
  99. /*
  100. * Convert a raw string to an arbitrary string encoding
  101. */
  102. function rstr2any(input, encoding)
  103. {
  104. var divisor = encoding.length;
  105. var remainders = Array();
  106. var i, q, x, quotient;
  107. /* Convert to an array of 16-bit big-endian values, forming the dividend */
  108. var dividend = Array(Math.ceil(input.length / 2));
  109. for(i = 0; i < dividend.length; i++)
  110. {
  111. dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
  112. }
  113. /*
  114. * Repeatedly perform a long division. The binary array forms the dividend,
  115. * the length of the encoding is the divisor. Once computed, the quotient
  116. * forms the dividend for the next step. We stop when the dividend is zero.
  117. * All remainders are stored for later use.
  118. */
  119. while(dividend.length > 0)
  120. {
  121. quotient = Array();
  122. x = 0;
  123. for(i = 0; i < dividend.length; i++)
  124. {
  125. x = (x << 16) + dividend[i];
  126. q = Math.floor(x / divisor);
  127. x -= q * divisor;
  128. if(quotient.length > 0 || q > 0)
  129. quotient[quotient.length] = q;
  130. }
  131. remainders[remainders.length] = x;
  132. dividend = quotient;
  133. }
  134. /* Convert the remainders to the output string */
  135. var output = "";
  136. for(i = remainders.length - 1; i >= 0; i--)
  137. output += encoding.charAt(remainders[i]);
  138. /* Append leading zero equivalents */
  139. var full_length = Math.ceil(input.length * 8 /
  140. (Math.log(encoding.length) / Math.log(2)))
  141. for(i = output.length; i < full_length; i++)
  142. output = encoding[0] + output;
  143. return output;
  144. }
  145. /*
  146. * Encode a string as utf-8.
  147. * For efficiency, this assumes the input is valid utf-16.
  148. */
  149. function str2rstr_utf8(input)
  150. {
  151. var output = "";
  152. var i = -1;
  153. var x, y;
  154. while(++i < input.length)
  155. {
  156. /* Decode utf-16 surrogate pairs */
  157. x = input.charCodeAt(i);
  158. y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
  159. if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
  160. {
  161. x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
  162. i++;
  163. }
  164. /* Encode output as utf-8 */
  165. if(x <= 0x7F)
  166. output += String.fromCharCode(x);
  167. else if(x <= 0x7FF)
  168. output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
  169. 0x80 | ( x & 0x3F));
  170. else if(x <= 0xFFFF)
  171. output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
  172. 0x80 | ((x >>> 6 ) & 0x3F),
  173. 0x80 | ( x & 0x3F));
  174. else if(x <= 0x1FFFFF)
  175. output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
  176. 0x80 | ((x >>> 12) & 0x3F),
  177. 0x80 | ((x >>> 6 ) & 0x3F),
  178. 0x80 | ( x & 0x3F));
  179. }
  180. return output;
  181. }
  182. /*
  183. * Encode a string as utf-16
  184. */
  185. function str2rstr_utf16le(input)
  186. {
  187. var output = "";
  188. for(var i = 0; i < input.length; i++)
  189. output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
  190. (input.charCodeAt(i) >>> 8) & 0xFF);
  191. return output;
  192. }
  193. function str2rstr_utf16be(input)
  194. {
  195. var output = "";
  196. for(var i = 0; i < input.length; i++)
  197. output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
  198. input.charCodeAt(i) & 0xFF);
  199. return output;
  200. }
  201. /*
  202. * Convert a raw string to an array of big-endian words
  203. * Characters >255 have their high-byte silently ignored.
  204. */
  205. function rstr2binb(input)
  206. {
  207. var output = Array(input.length >> 2);
  208. for(var i = 0; i < output.length; i++)
  209. output[i] = 0;
  210. for(var i = 0; i < input.length * 8; i += 8)
  211. output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
  212. return output;
  213. }
  214. /*
  215. * Convert an array of big-endian words to a string
  216. */
  217. function binb2rstr(input)
  218. {
  219. var output = "";
  220. for(var i = 0; i < input.length * 32; i += 8)
  221. output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
  222. return output;
  223. }
  224. /*
  225. * Main sha256 function, with its support functions
  226. */
  227. function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
  228. function sha256_R (X, n) {return ( X >>> n );}
  229. function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
  230. function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
  231. function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
  232. function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
  233. function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
  234. function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
  235. function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
  236. function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
  237. function sha256_Gamma0512(x) {return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
  238. function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
  239. var sha256_K = new Array
  240. (
  241. 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
  242. -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
  243. 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
  244. 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
  245. -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
  246. 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
  247. 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
  248. -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
  249. 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
  250. 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
  251. -1866530822, -1538233109, -1090935817, -965641998
  252. );
  253. function binb_sha256(m, l)
  254. {
  255. var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
  256. 1359893119, -1694144372, 528734635, 1541459225);
  257. var W = new Array(64);
  258. var a, b, c, d, e, f, g, h;
  259. var i, j, T1, T2;
  260. /* append padding */
  261. m[l >> 5] |= 0x80 << (24 - l % 32);
  262. m[((l + 64 >> 9) << 4) + 15] = l;
  263. for(i = 0; i < m.length; i += 16)
  264. {
  265. a = HASH[0];
  266. b = HASH[1];
  267. c = HASH[2];
  268. d = HASH[3];
  269. e = HASH[4];
  270. f = HASH[5];
  271. g = HASH[6];
  272. h = HASH[7];
  273. for(j = 0; j < 64; j++)
  274. {
  275. if (j < 16) W[j] = m[j + i];
  276. else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
  277. sha256_Gamma0256(W[j - 15])), W[j - 16]);
  278. T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
  279. sha256_K[j]), W[j]);
  280. T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
  281. h = g;
  282. g = f;
  283. f = e;
  284. e = safe_add(d, T1);
  285. d = c;
  286. c = b;
  287. b = a;
  288. a = safe_add(T1, T2);
  289. }
  290. HASH[0] = safe_add(a, HASH[0]);
  291. HASH[1] = safe_add(b, HASH[1]);
  292. HASH[2] = safe_add(c, HASH[2]);
  293. HASH[3] = safe_add(d, HASH[3]);
  294. HASH[4] = safe_add(e, HASH[4]);
  295. HASH[5] = safe_add(f, HASH[5]);
  296. HASH[6] = safe_add(g, HASH[6]);
  297. HASH[7] = safe_add(h, HASH[7]);
  298. }
  299. return HASH;
  300. }
  301. function safe_add (x, y)
  302. {
  303. var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  304. var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  305. return (msw << 16) | (lsw & 0xFFFF);
  306. }