Added USEFAT and spaces to filenames
[CGIscriptor.git] / JavaScript / sha.js
blob9ee68a4c1950552a27f0bc0ddf7426f512399598
1 /* A JavaScript implementation of the SHA family of hashes, as defined in FIPS
2 * PUB 180-2 as well as the corresponding HMAC implementation as defined in
3 * FIPS PUB 198a
5 * Version 1.3 Copyright Brian Turek 2008-2010
6 * Distributed under the BSD License
7 * See http://jssha.sourceforge.net/ for more information
9 * Several functions taken from Paul Johnson
11 (function ()
14 * Configurable variables. Defaults typically work
16 /* Number of Bits Per character (8 for ASCII, 16 for Unicode) */
17 var charSize = 8,
18 /* base-64 pad character. "=" for strict RFC compliance */
19 b64pad = "",
20 /* hex output format. 0 - lowercase; 1 - uppercase */
21 hexCase = 0,
24 * Int_64 is a object for 2 32-bit numbers emulating a 64-bit number
26 * @constructor
27 * @param {Number} msint_32 The most significant 32-bits of a 64-bit number
28 * @param {Number} lsint_32 The least significant 32-bits of a 64-bit number
30 Int_64 = function (msint_32, lsint_32)
32 this.highOrder = msint_32;
33 this.lowOrder = lsint_32;
37 * Convert a string to an array of big-endian words
38 * If charSize is ASCII, characters >255 have their hi-byte silently
39 * ignored.
41 * @param {String} str String to be converted to binary representation
42 * @return Integer array representation of the parameter
44 str2binb = function (str)
46 var bin = [], mask = (1 << charSize) - 1,
47 length = str.length * charSize, i;
49 for (i = 0; i < length; i += charSize)
51 bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) <<
52 (32 - charSize - (i % 32));
55 return bin;
59 * Convert a hex string to an array of big-endian words
61 * @param {String} str String to be converted to binary representation
62 * @return Integer array representation of the parameter
64 hex2binb = function (str)
66 var bin = [], length = str.length, i, num;
68 for (i = 0; i < length; i += 2)
70 num = parseInt(str.substr(i, 2), 16);
71 if (!isNaN(num))
73 bin[i >> 3] |= num << (24 - (4 * (i % 8)));
75 else
77 return "INVALID HEX STRING";
81 return bin;
85 * Convert an array of big-endian words to a hex string.
87 * @private
88 * @param {Array} binarray Array of integers to be converted to hexidecimal
89 * representation
90 * @return Hexidecimal representation of the parameter in String form
92 binb2hex = function (binarray)
94 var hex_tab = (hexCase) ? "0123456789ABCDEF" : "0123456789abcdef",
95 str = "", length = binarray.length * 4, i, srcByte;
97 for (i = 0; i < length; i += 1)
99 srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8);
100 str += hex_tab.charAt((srcByte >> 4) & 0xF) +
101 hex_tab.charAt(srcByte & 0xF);
104 return str;
108 * Convert an array of big-endian words to a base-64 string
110 * @private
111 * @param {Array} binarray Array of integers to be converted to base-64
112 * representation
113 * @return Base-64 encoded representation of the parameter in String form
115 binb2b64 = function (binarray)
117 var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +
118 "0123456789+/", str = "", length = binarray.length * 4, i, j,
119 triplet;
121 for (i = 0; i < length; i += 3)
123 triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) |
124 (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) |
125 ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
126 for (j = 0; j < 4; j += 1)
128 if (i * 8 + j * 6 <= binarray.length * 32)
130 str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
132 else
134 str += b64pad;
138 return str;
142 * The 32-bit implementation of circular rotate left
144 * @private
145 * @param {Number} x The 32-bit integer argument
146 * @param {Number} n The number of bits to shift
147 * @return The x shifted circularly by n bits
149 rotl_32 = function (x, n)
151 return (x << n) | (x >>> (32 - n));
155 * The 32-bit implementation of circular rotate right
157 * @private
158 * @param {Number} x The 32-bit integer argument
159 * @param {Number} n The number of bits to shift
160 * @return The x shifted circularly by n bits
162 rotr_32 = function (x, n)
164 return (x >>> n) | (x << (32 - n));
168 * The 64-bit implementation of circular rotate right
170 * @private
171 * @param {Int_64} x The 64-bit integer argument
172 * @param {Number} n The number of bits to shift
173 * @return The x shifted circularly by n bits
175 rotr_64 = function (x, n)
177 if (n <= 32)
179 return new Int_64(
180 (x.highOrder >>> n) | (x.lowOrder << (32 - n)),
181 (x.lowOrder >>> n) | (x.highOrder << (32 - n))
184 else
186 return new Int_64(
187 (x.lowOrder >>> n) | (x.highOrder << (32 - n)),
188 (x.highOrder >>> n) | (x.lowOrder << (32 - n))
194 * The 32-bit implementation of shift right
196 * @private
197 * @param {Number} x The 32-bit integer argument
198 * @param {Number} n The number of bits to shift
199 * @return The x shifted by n bits
201 shr_32 = function (x, n)
203 return x >>> n;
207 * The 64-bit implementation of shift right
209 * @private
210 * @param {Int_64} x The 64-bit integer argument
211 * @param {Number} n The number of bits to shift
212 * @return The x shifted by n bits
214 shr_64 = function (x, n)
216 if (n <= 32)
218 return new Int_64(
219 x.highOrder >>> n,
220 x.lowOrder >>> n | (x.highOrder << (32 - n))
223 else
225 return new Int_64(
227 x.highOrder << (32 - n)
233 * The 32-bit implementation of the NIST specified Parity function
235 * @private
236 * @param {Number} x The first 32-bit integer argument
237 * @param {Number} y The second 32-bit integer argument
238 * @param {Number} z The third 32-bit integer argument
239 * @return The NIST specified output of the function
241 parity_32 = function (x, y, z)
243 return x ^ y ^ z;
247 * The 32-bit implementation of the NIST specified Ch function
249 * @private
250 * @param {Number} x The first 32-bit integer argument
251 * @param {Number} y The second 32-bit integer argument
252 * @param {Number} z The third 32-bit integer argument
253 * @return The NIST specified output of the function
255 ch_32 = function (x, y, z)
257 return (x & y) ^ (~x & z);
261 * The 64-bit implementation of the NIST specified Ch function
263 * @private
264 * @param {Int_64} x The first 64-bit integer argument
265 * @param {Int_64} y The second 64-bit integer argument
266 * @param {Int_64} z The third 64-bit integer argument
267 * @return The NIST specified output of the function
269 ch_64 = function (x, y, z)
271 return new Int_64(
272 (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder),
273 (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)
278 * The 32-bit implementation of the NIST specified Maj function
280 * @private
281 * @param {Number} x The first 32-bit integer argument
282 * @param {Number} y The second 32-bit integer argument
283 * @param {Number} z The third 32-bit integer argument
284 * @return The NIST specified output of the function
286 maj_32 = function (x, y, z)
288 return (x & y) ^ (x & z) ^ (y & z);
292 * The 64-bit implementation of the NIST specified Maj function
294 * @private
295 * @param {Int_64} x The first 64-bit integer argument
296 * @param {Int_64} y The second 64-bit integer argument
297 * @param {Int_64} z The third 64-bit integer argument
298 * @return The NIST specified output of the function
300 maj_64 = function (x, y, z)
302 return new Int_64(
303 (x.highOrder & y.highOrder) ^
304 (x.highOrder & z.highOrder) ^
305 (y.highOrder & z.highOrder),
306 (x.lowOrder & y.lowOrder) ^
307 (x.lowOrder & z.lowOrder) ^
308 (y.lowOrder & z.lowOrder)
313 * The 32-bit implementation of the NIST specified Sigma0 function
315 * @private
316 * @param {Number} x The 32-bit integer argument
317 * @return The NIST specified output of the function
319 sigma0_32 = function (x)
321 return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22);
325 * The 64-bit implementation of the NIST specified Sigma0 function
327 * @private
328 * @param {Int_64} x The 64-bit integer argument
329 * @return The NIST specified output of the function
331 sigma0_64 = function (x)
333 var rotr28 = rotr_64(x, 28), rotr34 = rotr_64(x, 34),
334 rotr39 = rotr_64(x, 39);
336 return new Int_64(
337 rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder,
338 rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder);
342 * The 32-bit implementation of the NIST specified Sigma1 function
344 * @private
345 * @param {Number} x The 32-bit integer argument
346 * @return The NIST specified output of the function
348 sigma1_32 = function (x)
350 return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25);
354 * The 64-bit implementation of the NIST specified Sigma1 function
356 * @private
357 * @param {Int_64} x The 64-bit integer argument
358 * @return The NIST specified output of the function
360 sigma1_64 = function (x)
362 var rotr14 = rotr_64(x, 14), rotr18 = rotr_64(x, 18),
363 rotr41 = rotr_64(x, 41);
365 return new Int_64(
366 rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder,
367 rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder);
371 * The 32-bit implementation of the NIST specified Gamma0 function
373 * @private
374 * @param {Number} x The 32-bit integer argument
375 * @return The NIST specified output of the function
377 gamma0_32 = function (x)
379 return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3);
383 * The 64-bit implementation of the NIST specified Gamma0 function
385 * @private
386 * @param {Int_64} x The 64-bit integer argument
387 * @return The NIST specified output of the function
389 gamma0_64 = function (x)
391 var rotr1 = rotr_64(x, 1), rotr8 = rotr_64(x, 8), shr7 = shr_64(x, 7);
393 return new Int_64(
394 rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder,
395 rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder
400 * The 32-bit implementation of the NIST specified Gamma1 function
402 * @private
403 * @param {Number} x The 32-bit integer argument
404 * @return The NIST specified output of the function
406 gamma1_32 = function (x)
408 return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10);
412 * The 64-bit implementation of the NIST specified Gamma1 function
414 * @private
415 * @param {Int_64} x The 64-bit integer argument
416 * @return The NIST specified output of the function
418 gamma1_64 = function (x)
420 var rotr19 = rotr_64(x, 19), rotr61 = rotr_64(x, 61),
421 shr6 = shr_64(x, 6);
423 return new Int_64(
424 rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder,
425 rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder
430 * Add two 32-bit integers, wrapping at 2^32. This uses 16-bit operations
431 * internally to work around bugs in some JS interpreters.
433 * @private
434 * @param {Number} x The first 32-bit integer argument to be added
435 * @param {Number} y The second 32-bit integer argument to be added
436 * @return The sum of x + y
438 safeAdd_32_2 = function (x, y)
440 var lsw = (x & 0xFFFF) + (y & 0xFFFF),
441 msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16);
443 return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
447 * Add four 32-bit integers, wrapping at 2^32. This uses 16-bit operations
448 * internally to work around bugs in some JS interpreters.
450 * @private
451 * @param {Number} a The first 32-bit integer argument to be added
452 * @param {Number} b The second 32-bit integer argument to be added
453 * @param {Number} c The third 32-bit integer argument to be added
454 * @param {Number} d The fourth 32-bit integer argument to be added
455 * @return The sum of a + b + c + d
457 safeAdd_32_4 = function (a, b, c, d)
459 var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF),
460 msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) +
461 (lsw >>> 16);
463 return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
467 * Add five 32-bit integers, wrapping at 2^32. This uses 16-bit operations
468 * internally to work around bugs in some JS interpreters.
470 * @private
471 * @param {Number} a The first 32-bit integer argument to be added
472 * @param {Number} b The second 32-bit integer argument to be added
473 * @param {Number} c The third 32-bit integer argument to be added
474 * @param {Number} d The fourth 32-bit integer argument to be added
475 * @param {Number} e The fifth 32-bit integer argument to be added
476 * @return The sum of a + b + c + d + e
478 safeAdd_32_5 = function (a, b, c, d, e)
480 var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) +
481 (e & 0xFFFF),
482 msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) +
483 (e >>> 16) + (lsw >>> 16);
485 return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
489 * Add two 64-bit integers, wrapping at 2^64. This uses 16-bit operations
490 * internally to work around bugs in some JS interpreters.
492 * @private
493 * @param {Int_64} x The first 64-bit integer argument to be added
494 * @param {Int_64} y The second 64-bit integer argument to be added
495 * @return The sum of x + y
497 safeAdd_64_2 = function (x, y)
499 var lsw, msw, lowOrder, highOrder;
501 lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF);
502 msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16);
503 lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
505 lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16);
506 msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16);
507 highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
509 return new Int_64(highOrder, lowOrder);
513 * Add four 64-bit integers, wrapping at 2^64. This uses 16-bit operations
514 * internally to work around bugs in some JS interpreters.
516 * @private
517 * @param {Int_64} a The first 64-bit integer argument to be added
518 * @param {Int_64} b The second 64-bit integer argument to be added
519 * @param {Int_64} c The third 64-bit integer argument to be added
520 * @param {Int_64} d The fouth 64-bit integer argument to be added
521 * @return The sum of a + b + c + d
523 safeAdd_64_4 = function (a, b, c, d)
525 var lsw, msw, lowOrder, highOrder;
527 lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) +
528 (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF);
529 msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) +
530 (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16);
531 lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
533 lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) +
534 (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16);
535 msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) +
536 (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16);
537 highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
539 return new Int_64(highOrder, lowOrder);
543 * Add five 64-bit integers, wrapping at 2^64. This uses 16-bit operations
544 * internally to work around bugs in some JS interpreters.
546 * @private
547 * @param {Int_64} a The first 64-bit integer argument to be added
548 * @param {Int_64} b The second 64-bit integer argument to be added
549 * @param {Int_64} c The third 64-bit integer argument to be added
550 * @param {Int_64} d The fouth 64-bit integer argument to be added
551 * @param {Int_64} e The fouth 64-bit integer argument to be added
552 * @return The sum of a + b + c + d + e
554 safeAdd_64_5 = function (a, b, c, d, e)
556 var lsw, msw, lowOrder, highOrder;
558 lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) +
559 (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) +
560 (e.lowOrder & 0xFFFF);
561 msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) +
562 (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) +
563 (lsw >>> 16);
564 lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
566 lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) +
567 (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) +
568 (e.highOrder & 0xFFFF) + (msw >>> 16);
569 msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) +
570 (c.highOrder >>> 16) + (d.highOrder >>> 16) +
571 (e.highOrder >>> 16) + (lsw >>> 16);
572 highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
574 return new Int_64(highOrder, lowOrder);
578 * Calculates the SHA-1 hash of the string set at instantiation
580 * @private
581 * @param {Array} message The binary array representation of the string to
582 * hash
583 * @param {Number} messageLen The number of bits in the message
584 * @return The array of integers representing the SHA-1 hash of message
586 coreSHA1 = function (message, messageLen)
588 var W = [], a, b, c, d, e, T, ch = ch_32, parity = parity_32,
589 maj = maj_32, rotl = rotl_32, safeAdd_2 = safeAdd_32_2, i, t,
590 safeAdd_5 = safeAdd_32_5, appendedMessageLength,
591 H = [
592 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
594 K = [
595 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
596 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
597 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
598 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
599 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
600 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
601 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
602 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
603 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
604 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
605 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
606 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
607 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
608 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
609 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
610 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
611 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
612 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
613 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
614 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6
617 /* Append '1' at the end of the binary string */
618 message[messageLen >> 5] |= 0x80 << (24 - (messageLen % 32));
619 /* Append length of binary string in the position such that the new
620 length is a multiple of 512. Logic does not work for even multiples
621 of 512 but there can never be even multiples of 512 */
622 message[(((messageLen + 65) >> 9) << 4) + 15] = messageLen;
624 appendedMessageLength = message.length;
626 for (i = 0; i < appendedMessageLength; i += 16)
628 a = H[0];
629 b = H[1];
630 c = H[2];
631 d = H[3];
632 e = H[4];
634 for (t = 0; t < 80; t += 1)
636 if (t < 16)
638 W[t] = message[t + i];
640 else
642 W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
645 if (t < 20)
647 T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, K[t], W[t]);
649 else if (t < 40)
651 T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]);
653 else if (t < 60)
655 T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, K[t], W[t]);
656 } else {
657 T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]);
660 e = d;
661 d = c;
662 c = rotl(b, 30);
663 b = a;
664 a = T;
667 H[0] = safeAdd_2(a, H[0]);
668 H[1] = safeAdd_2(b, H[1]);
669 H[2] = safeAdd_2(c, H[2]);
670 H[3] = safeAdd_2(d, H[3]);
671 H[4] = safeAdd_2(e, H[4]);
674 return H;
678 * Calculates the desired SHA-2 hash of the string set at instantiation
680 * @private
681 * @param {Array} The binary array representation of the string to hash
682 * @param {Number} The number of bits in message
683 * @param {String} variant The desired SHA-2 variant
684 * @return The array of integers representing the SHA-2 hash of message
686 coreSHA2 = function (message, messageLen, variant)
688 var a, b, c, d, e, f, g, h, T1, T2, H, numRounds, lengthPosition, i, t,
689 binaryStringInc, binaryStringMult, safeAdd_2, safeAdd_4, safeAdd_5,
690 gamma0, gamma1, sigma0, sigma1, ch, maj, Int, K, W = [],
691 appendedMessageLength;
693 /* Set up the various function handles and variable for the specific
694 * variant */
695 if (variant === "SHA-224" || variant === "SHA-256")
697 /* 32-bit variant */
698 numRounds = 64;
699 lengthPosition = (((messageLen + 65) >> 9) << 4) + 15;
700 binaryStringInc = 16;
701 binaryStringMult = 1;
702 Int = Number;
703 safeAdd_2 = safeAdd_32_2;
704 safeAdd_4 = safeAdd_32_4;
705 safeAdd_5 = safeAdd_32_5;
706 gamma0 = gamma0_32;
707 gamma1 = gamma1_32;
708 sigma0 = sigma0_32;
709 sigma1 = sigma1_32;
710 maj = maj_32;
711 ch = ch_32;
712 K = [
713 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
714 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
715 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
716 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
717 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
718 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
719 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
720 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
721 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
722 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
723 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
724 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
725 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
726 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
727 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
728 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
731 if (variant === "SHA-224")
733 H = [
734 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
735 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
738 else
740 H = [
741 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
742 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
746 else if (variant === "SHA-384" || variant === "SHA-512")
748 /* 64-bit variant */
749 numRounds = 80;
750 lengthPosition = (((messageLen + 128) >> 10) << 5) + 31;
751 binaryStringInc = 32;
752 binaryStringMult = 2;
753 Int = Int_64;
754 safeAdd_2 = safeAdd_64_2;
755 safeAdd_4 = safeAdd_64_4;
756 safeAdd_5 = safeAdd_64_5;
757 gamma0 = gamma0_64;
758 gamma1 = gamma1_64;
759 sigma0 = sigma0_64;
760 sigma1 = sigma1_64;
761 maj = maj_64;
762 ch = ch_64;
764 K = [
765 new Int(0x428a2f98, 0xd728ae22), new Int(0x71374491, 0x23ef65cd),
766 new Int(0xb5c0fbcf, 0xec4d3b2f), new Int(0xe9b5dba5, 0x8189dbbc),
767 new Int(0x3956c25b, 0xf348b538), new Int(0x59f111f1, 0xb605d019),
768 new Int(0x923f82a4, 0xaf194f9b), new Int(0xab1c5ed5, 0xda6d8118),
769 new Int(0xd807aa98, 0xa3030242), new Int(0x12835b01, 0x45706fbe),
770 new Int(0x243185be, 0x4ee4b28c), new Int(0x550c7dc3, 0xd5ffb4e2),
771 new Int(0x72be5d74, 0xf27b896f), new Int(0x80deb1fe, 0x3b1696b1),
772 new Int(0x9bdc06a7, 0x25c71235), new Int(0xc19bf174, 0xcf692694),
773 new Int(0xe49b69c1, 0x9ef14ad2), new Int(0xefbe4786, 0x384f25e3),
774 new Int(0x0fc19dc6, 0x8b8cd5b5), new Int(0x240ca1cc, 0x77ac9c65),
775 new Int(0x2de92c6f, 0x592b0275), new Int(0x4a7484aa, 0x6ea6e483),
776 new Int(0x5cb0a9dc, 0xbd41fbd4), new Int(0x76f988da, 0x831153b5),
777 new Int(0x983e5152, 0xee66dfab), new Int(0xa831c66d, 0x2db43210),
778 new Int(0xb00327c8, 0x98fb213f), new Int(0xbf597fc7, 0xbeef0ee4),
779 new Int(0xc6e00bf3, 0x3da88fc2), new Int(0xd5a79147, 0x930aa725),
780 new Int(0x06ca6351, 0xe003826f), new Int(0x14292967, 0x0a0e6e70),
781 new Int(0x27b70a85, 0x46d22ffc), new Int(0x2e1b2138, 0x5c26c926),
782 new Int(0x4d2c6dfc, 0x5ac42aed), new Int(0x53380d13, 0x9d95b3df),
783 new Int(0x650a7354, 0x8baf63de), new Int(0x766a0abb, 0x3c77b2a8),
784 new Int(0x81c2c92e, 0x47edaee6), new Int(0x92722c85, 0x1482353b),
785 new Int(0xa2bfe8a1, 0x4cf10364), new Int(0xa81a664b, 0xbc423001),
786 new Int(0xc24b8b70, 0xd0f89791), new Int(0xc76c51a3, 0x0654be30),
787 new Int(0xd192e819, 0xd6ef5218), new Int(0xd6990624, 0x5565a910),
788 new Int(0xf40e3585, 0x5771202a), new Int(0x106aa070, 0x32bbd1b8),
789 new Int(0x19a4c116, 0xb8d2d0c8), new Int(0x1e376c08, 0x5141ab53),
790 new Int(0x2748774c, 0xdf8eeb99), new Int(0x34b0bcb5, 0xe19b48a8),
791 new Int(0x391c0cb3, 0xc5c95a63), new Int(0x4ed8aa4a, 0xe3418acb),
792 new Int(0x5b9cca4f, 0x7763e373), new Int(0x682e6ff3, 0xd6b2b8a3),
793 new Int(0x748f82ee, 0x5defb2fc), new Int(0x78a5636f, 0x43172f60),
794 new Int(0x84c87814, 0xa1f0ab72), new Int(0x8cc70208, 0x1a6439ec),
795 new Int(0x90befffa, 0x23631e28), new Int(0xa4506ceb, 0xde82bde9),
796 new Int(0xbef9a3f7, 0xb2c67915), new Int(0xc67178f2, 0xe372532b),
797 new Int(0xca273ece, 0xea26619c), new Int(0xd186b8c7, 0x21c0c207),
798 new Int(0xeada7dd6, 0xcde0eb1e), new Int(0xf57d4f7f, 0xee6ed178),
799 new Int(0x06f067aa, 0x72176fba), new Int(0x0a637dc5, 0xa2c898a6),
800 new Int(0x113f9804, 0xbef90dae), new Int(0x1b710b35, 0x131c471b),
801 new Int(0x28db77f5, 0x23047d84), new Int(0x32caab7b, 0x40c72493),
802 new Int(0x3c9ebe0a, 0x15c9bebc), new Int(0x431d67c4, 0x9c100d4c),
803 new Int(0x4cc5d4be, 0xcb3e42b6), new Int(0x597f299c, 0xfc657e2a),
804 new Int(0x5fcb6fab, 0x3ad6faec), new Int(0x6c44198c, 0x4a475817)
807 if (variant === "SHA-384")
809 H = [
810 new Int(0xcbbb9d5d, 0xc1059ed8), new Int(0x0629a292a, 0x367cd507),
811 new Int(0x9159015a, 0x3070dd17), new Int(0x0152fecd8, 0xf70e5939),
812 new Int(0x67332667, 0xffc00b31), new Int(0x98eb44a87, 0x68581511),
813 new Int(0xdb0c2e0d, 0x64f98fa7), new Int(0x047b5481d, 0xbefa4fa4)
816 else
818 H = [
819 new Int(0x6a09e667, 0xf3bcc908), new Int(0xbb67ae85, 0x84caa73b),
820 new Int(0x3c6ef372, 0xfe94f82b), new Int(0xa54ff53a, 0x5f1d36f1),
821 new Int(0x510e527f, 0xade682d1), new Int(0x9b05688c, 0x2b3e6c1f),
822 new Int(0x1f83d9ab, 0xfb41bd6b), new Int(0x5be0cd19, 0x137e2179)
827 /* Append '1' at the end of the binary string */
828 message[messageLen >> 5] |= 0x80 << (24 - messageLen % 32);
829 /* Append length of binary string in the position such that the new
830 * length is correct */
831 message[lengthPosition] = messageLen;
833 appendedMessageLength = message.length;
835 for (i = 0; i < appendedMessageLength; i += binaryStringInc)
837 a = H[0];
838 b = H[1];
839 c = H[2];
840 d = H[3];
841 e = H[4];
842 f = H[5];
843 g = H[6];
844 h = H[7];
846 for (t = 0; t < numRounds; t += 1)
848 if (t < 16)
850 /* Bit of a hack - for 32-bit, the second term is ignored */
851 W[t] = new Int(message[t * binaryStringMult + i],
852 message[t * binaryStringMult + i + 1]);
854 else
856 W[t] = safeAdd_4(
857 gamma1(W[t - 2]), W[t - 7],
858 gamma0(W[t - 15]), W[t - 16]
862 T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]);
863 T2 = safeAdd_2(sigma0(a), maj(a, b, c));
864 h = g;
865 g = f;
866 f = e;
867 e = safeAdd_2(d, T1);
868 d = c;
869 c = b;
870 b = a;
871 a = safeAdd_2(T1, T2);
874 H[0] = safeAdd_2(a, H[0]);
875 H[1] = safeAdd_2(b, H[1]);
876 H[2] = safeAdd_2(c, H[2]);
877 H[3] = safeAdd_2(d, H[3]);
878 H[4] = safeAdd_2(e, H[4]);
879 H[5] = safeAdd_2(f, H[5]);
880 H[6] = safeAdd_2(g, H[6]);
881 H[7] = safeAdd_2(h, H[7]);
884 switch (variant)
886 case "SHA-224":
887 return [
888 H[0], H[1], H[2], H[3],
889 H[4], H[5], H[6]
891 case "SHA-256":
892 return H;
893 case "SHA-384":
894 return [
895 H[0].highOrder, H[0].lowOrder,
896 H[1].highOrder, H[1].lowOrder,
897 H[2].highOrder, H[2].lowOrder,
898 H[3].highOrder, H[3].lowOrder,
899 H[4].highOrder, H[4].lowOrder,
900 H[5].highOrder, H[5].lowOrder
902 case "SHA-512":
903 return [
904 H[0].highOrder, H[0].lowOrder,
905 H[1].highOrder, H[1].lowOrder,
906 H[2].highOrder, H[2].lowOrder,
907 H[3].highOrder, H[3].lowOrder,
908 H[4].highOrder, H[4].lowOrder,
909 H[5].highOrder, H[5].lowOrder,
910 H[6].highOrder, H[6].lowOrder,
911 H[7].highOrder, H[7].lowOrder
913 default:
914 /* This should never be reached */
915 return [];
920 * jsSHA is the workhorse of the library. Instantiate it with the string to
921 * be hashed as the parameter
923 * @constructor
924 * @param {String} srcString The string to be hashed
925 * @param {String} inputFormat The format of srcString, ASCII or HEX
927 jsSHA = function (srcString, inputFormat)
930 this.sha1 = null;
931 this.sha224 = null;
932 this.sha256 = null;
933 this.sha384 = null;
934 this.sha512 = null;
936 this.strBinLen = null;
937 this.strToHash = null;
939 /* Convert the input string into the correct type */
940 if ("HEX" === inputFormat)
942 if (0 !== (srcString.length % 2))
944 return "TEXT MUST BE IN BYTE INCREMENTS";
946 this.strBinLen = srcString.length * 4;
947 this.strToHash = hex2binb(srcString);
949 else if (("ASCII" === inputFormat) ||
950 ('undefined' === typeof(inputFormat)))
952 this.strBinLen = srcString.length * charSize;
953 this.strToHash = str2binb(srcString);
955 else
957 return "UNKNOWN TEXT INPUT TYPE";
961 jsSHA.prototype = {
963 * Returns the desired SHA hash of the string specified at instantiation
964 * using the specified parameters
966 * @param {String} variant The desired SHA variant (SHA-1, SHA-224,
967 * SHA-256, SHA-384, or SHA-512)
968 * @param {String} format The desired output formatting (B64 or HEX)
969 * @return The string representation of the hash in the format specified
971 getHash : function (variant, format)
973 var formatFunc = null, message = this.strToHash.slice();
975 switch (format)
977 case "HEX":
978 formatFunc = binb2hex;
979 break;
980 case "B64":
981 formatFunc = binb2b64;
982 break;
983 default:
984 return "FORMAT NOT RECOGNIZED";
987 switch (variant)
989 case "SHA-1":
990 if (null === this.sha1)
992 this.sha1 = coreSHA1(message, this.strBinLen);
994 return formatFunc(this.sha1);
995 case "SHA-224":
996 if (null === this.sha224)
998 this.sha224 = coreSHA2(message, this.strBinLen, variant);
1000 return formatFunc(this.sha224);
1001 case "SHA-256":
1002 if (null === this.sha256)
1004 this.sha256 = coreSHA2(message, this.strBinLen, variant);
1006 return formatFunc(this.sha256);
1007 case "SHA-384":
1008 if (null === this.sha384)
1010 this.sha384 = coreSHA2(message, this.strBinLen, variant);
1012 return formatFunc(this.sha384);
1013 case "SHA-512":
1014 if (null === this.sha512)
1016 this.sha512 = coreSHA2(message, this.strBinLen, variant);
1018 return formatFunc(this.sha512);
1019 default:
1020 return "HASH NOT RECOGNIZED";
1025 * Returns the desired HMAC of the string specified at instantiation
1026 * using the key and variant param.
1028 * @param {String} key The key used to calculate the HMAC
1029 * @param {String} inputFormat The format of key, ASCII or HEX
1030 * @param {String} variant The desired SHA variant (SHA-1, SHA-224,
1031 * SHA-256, SHA-384, or SHA-512)
1032 * @param {String} outputFormat The desired output formatting
1033 * (B64 or HEX)
1034 * @return The string representation of the hash in the format specified
1036 getHMAC : function (key, inputFormat, variant, outputFormat)
1038 var formatFunc, keyToUse, blockByteSize, blockBitSize, i,
1039 retVal, lastArrayIndex, keyBinLen, hashBitSize,
1040 keyWithIPad = [], keyWithOPad = [];
1042 /* Validate the output format selection */
1043 switch (outputFormat)
1045 case "HEX":
1046 formatFunc = binb2hex;
1047 break;
1048 case "B64":
1049 formatFunc = binb2b64;
1050 break;
1051 default:
1052 return "FORMAT NOT RECOGNIZED";
1055 /* Validate the hash variant selection and set needed variables */
1056 switch (variant)
1058 case "SHA-1":
1059 blockByteSize = 64;
1060 hashBitSize = 160;
1061 break;
1062 case "SHA-224":
1063 blockByteSize = 64;
1064 hashBitSize = 224;
1065 break;
1066 case "SHA-256":
1067 blockByteSize = 64;
1068 hashBitSize = 256;
1069 break;
1070 case "SHA-384":
1071 blockByteSize = 128;
1072 hashBitSize = 384;
1073 break;
1074 case "SHA-512":
1075 blockByteSize = 128;
1076 hashBitSize = 512;
1077 break;
1078 default:
1079 return "HASH NOT RECOGNIZED";
1082 /* Validate input format selection */
1083 if ("HEX" === inputFormat)
1085 /* Nibbles must come in pairs */
1086 if (0 !== (key.length % 2))
1088 return "KEY MUST BE IN BYTE INCREMENTS";
1090 keyToUse = hex2binb(key);
1091 keyBinLen = key.length * 4;
1093 else if ("ASCII" === inputFormat)
1095 keyToUse = str2binb(key);
1096 keyBinLen = key.length * charSize;
1098 else
1100 return "UNKNOWN KEY INPUT TYPE";
1103 /* These are used multiple times, calculate and store them */
1104 blockBitSize = blockByteSize * 8;
1105 lastArrayIndex = (blockByteSize / 4) - 1;
1107 /* Figure out what to do with the key based on its size relative to
1108 * the hash's block size */
1109 if (blockByteSize < (keyBinLen / 8))
1111 if ("SHA-1" === variant)
1113 keyToUse = coreSHA1(keyToUse, keyBinLen);
1115 else
1117 keyToUse = coreSHA2(keyToUse, keyBinLen, variant);
1119 /* For all variants, the block size is bigger than the output
1120 * size so there will never be a useful byte at the end of the
1121 * string */
1122 keyToUse[lastArrayIndex] &= 0xFFFFFF00;
1124 else if (blockByteSize > (keyBinLen / 8))
1126 /* If the blockByteSize is greater than the key length, there
1127 * will always be at LEAST one "useless" byte at the end of the
1128 * string */
1129 keyToUse[lastArrayIndex] &= 0xFFFFFF00;
1132 /* Create ipad and opad */
1133 for (i = 0; i <= lastArrayIndex; i += 1)
1135 keyWithIPad[i] = keyToUse[i] ^ 0x36363636;
1136 keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C;
1139 /* Calculate the HMAC */
1140 if ("SHA-1" === variant)
1142 retVal = coreSHA1(
1143 keyWithIPad.concat(this.strToHash),
1144 blockBitSize + this.strBinLen);
1145 retVal = coreSHA1(
1146 keyWithOPad.concat(retVal),
1147 blockBitSize + hashBitSize);
1149 else
1151 retVal = coreSHA2(
1152 keyWithIPad.concat(this.strToHash),
1153 blockBitSize + this.strBinLen, variant);
1154 retVal = coreSHA2(
1155 keyWithOPad.concat(retVal),
1156 blockBitSize + hashBitSize, variant);
1159 return (formatFunc(retVal));
1163 window.jsSHA = jsSHA;
1164 }());