Corrected error in file permissions
[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
4  *
5  * Version 1.3 Copyright Brian Turek 2008-2010
6  * Distributed under the BSD License
7  * See http://jssha.sourceforge.net/ for more information
8  *
9  * Several functions taken from Paul Johnson
10  */
11 (function ()
13         /*
14          * Configurable variables. Defaults typically work
15          */
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, 
23         /*
24          * Int_64 is a object for 2 32-bit numbers emulating a 64-bit number
25          *
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
29          */
30         Int_64 = function (msint_32, lsint_32)
31         {
32                 this.highOrder = msint_32;
33                 this.lowOrder = lsint_32;
34         },
36         /*
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.
40          *
41          * @param {String} str String to be converted to binary representation
42          * @return Integer array representation of the parameter
43          */
44         str2binb = function (str)
45         {
46                 var bin = [], mask = (1 << charSize) - 1,
47                         length = str.length * charSize, i;
49                 for (i = 0; i < length; i += charSize)
50                 {
51                         bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) <<
52                                 (32 - charSize - (i % 32));
53                 }
55                 return bin;
56         },
58         /*
59          * Convert a hex string to an array of big-endian words
60          *
61          * @param {String} str String to be converted to binary representation
62          * @return Integer array representation of the parameter
63          */
64         hex2binb = function (str)
65         {
66                 var bin = [], length = str.length, i, num;
68                 for (i = 0; i < length; i += 2)
69                 {
70                         num = parseInt(str.substr(i, 2), 16);
71                         if (!isNaN(num))
72                         {
73                                 bin[i >> 3] |= num << (24 - (4 * (i % 8)));
74                         }
75                         else
76                         {
77                                 return "INVALID HEX STRING";
78                         }
79                 }
81                 return bin;
82         },
84         /*
85          * Convert an array of big-endian words to a hex string.
86          *
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
91          */
92         binb2hex = function (binarray)
93         {
94                 var hex_tab = (hexCase) ? "0123456789ABCDEF" : "0123456789abcdef",
95                         str = "", length = binarray.length * 4, i, srcByte;
97                 for (i = 0; i < length; i += 1)
98                 {
99                         srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8);
100                         str += hex_tab.charAt((srcByte >> 4) & 0xF) +
101                                 hex_tab.charAt(srcByte & 0xF);
102                 }
104                 return str;
105         },
107         /*
108          * Convert an array of big-endian words to a base-64 string
109          *
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
114          */
115         binb2b64 = function (binarray)
116         {
117                 var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +
118                         "0123456789+/", str = "", length = binarray.length * 4, i, j,
119                         triplet;
121                 for (i = 0; i < length; i += 3)
122                 {
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)
127                         {
128                                 if (i * 8 + j * 6 <= binarray.length * 32)
129                                 {
130                                         str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
131                                 }
132                                 else
133                                 {
134                                         str += b64pad;
135                                 }
136                         }
137                 }
138                 return str;
139         },
141         /*
142          * The 32-bit implementation of circular rotate left
143          *
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
148          */
149         rotl_32 = function (x, n)
150         {
151                 return (x << n) | (x >>> (32 - n));
152         },
154         /*
155          * The 32-bit implementation of circular rotate right
156          *
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
161          */
162         rotr_32 = function (x, n)
163         {
164                 return (x >>> n) | (x << (32 - n));
165         },
167         /*
168          * The 64-bit implementation of circular rotate right
169          *
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
174          */
175         rotr_64 = function (x, n)
176         {
177                 if (n <= 32)
178                 {
179                         return new Int_64(
180                                         (x.highOrder >>> n) | (x.lowOrder << (32 - n)),
181                                         (x.lowOrder >>> n) | (x.highOrder << (32 - n))
182                                 );
183                 }
184                 else
185                 {
186                         return new Int_64(
187                                         (x.lowOrder >>> n) | (x.highOrder << (32 - n)),
188                                         (x.highOrder >>> n) | (x.lowOrder << (32 - n))
189                                 );
190                 }
191         },
193         /*
194          * The 32-bit implementation of shift right
195          *
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
200          */
201         shr_32 = function (x, n)
202         {
203                 return x >>> n;
204         },
206         /*
207          * The 64-bit implementation of shift right
208          *
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
213          */
214         shr_64 = function (x, n)
215         {
216                 if (n <= 32)
217                 {
218                         return new Int_64(
219                                         x.highOrder >>> n,
220                                         x.lowOrder >>> n | (x.highOrder << (32 - n))
221                                 );
222                 }
223                 else
224                 {
225                         return new Int_64(
226                                         0,
227                                         x.highOrder << (32 - n)
228                                 );
229                 }
230         },
232         /*
233          * The 32-bit implementation of the NIST specified Parity function
234          *
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
240          */
241         parity_32 = function (x, y, z)
242         {
243                 return x ^ y ^ z;
244         },
246         /*
247          * The 32-bit implementation of the NIST specified Ch function
248          *
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
254          */
255         ch_32 = function (x, y, z)
256         {
257                 return (x & y) ^ (~x & z);
258         },
260         /*
261          * The 64-bit implementation of the NIST specified Ch function
262          *
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
268          */
269         ch_64 = function (x, y, z)
270         {
271                 return new Int_64(
272                                 (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder),
273                                 (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)
274                         );
275         },
277         /*
278          * The 32-bit implementation of the NIST specified Maj function
279          *
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
285          */
286         maj_32 = function (x, y, z)
287         {
288                 return (x & y) ^ (x & z) ^ (y & z);
289         },
291         /*
292          * The 64-bit implementation of the NIST specified Maj function
293          *
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
299          */
300         maj_64 = function (x, y, z)
301         {
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)
309                         );
310         },
312         /*
313          * The 32-bit implementation of the NIST specified Sigma0 function
314          *
315          * @private
316          * @param {Number} x The 32-bit integer argument
317          * @return The NIST specified output of the function
318          */
319         sigma0_32 = function (x)
320         {
321                 return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22);
322         },
324         /*
325          * The 64-bit implementation of the NIST specified Sigma0 function
326          *
327          * @private
328          * @param {Int_64} x The 64-bit integer argument
329          * @return The NIST specified output of the function
330          */
331         sigma0_64 = function (x)
332         {
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);
339         },
341         /*
342          * The 32-bit implementation of the NIST specified Sigma1 function
343          *
344          * @private
345          * @param {Number} x The 32-bit integer argument
346          * @return The NIST specified output of the function
347          */
348         sigma1_32 = function (x)
349         {
350                 return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25);
351         },
353         /*
354          * The 64-bit implementation of the NIST specified Sigma1 function
355          *
356          * @private
357          * @param {Int_64} x The 64-bit integer argument
358          * @return The NIST specified output of the function
359          */
360         sigma1_64 = function (x)
361         {
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);
368         },
370         /*
371          * The 32-bit implementation of the NIST specified Gamma0 function
372          *
373          * @private
374          * @param {Number} x The 32-bit integer argument
375          * @return The NIST specified output of the function
376          */
377         gamma0_32 = function (x)
378         {
379                 return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3);
380         },
382         /*
383          * The 64-bit implementation of the NIST specified Gamma0 function
384          *
385          * @private
386          * @param {Int_64} x The 64-bit integer argument
387          * @return The NIST specified output of the function
388          */
389         gamma0_64 = function (x)
390         {
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
396                         );
397         },
399         /*
400          * The 32-bit implementation of the NIST specified Gamma1 function
401          *
402          * @private
403          * @param {Number} x The 32-bit integer argument
404          * @return The NIST specified output of the function
405          */
406         gamma1_32 = function (x)
407         {
408                 return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10);
409         },
411         /*
412          * The 64-bit implementation of the NIST specified Gamma1 function
413          *
414          * @private
415          * @param {Int_64} x The 64-bit integer argument
416          * @return The NIST specified output of the function
417          */
418         gamma1_64 = function (x)
419         {
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
426                         );
427         },
429         /*
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.
432          *
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
437          */
438         safeAdd_32_2 = function (x, y)
439         {
440                 var lsw = (x & 0xFFFF) + (y & 0xFFFF),
441                         msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16);
443                 return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
444         },
446         /*
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.
449          *
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
456          */
457         safeAdd_32_4 = function (a, b, c, d)
458         {
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);
464         },
466         /*
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.
469          *
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
477          */
478         safeAdd_32_5 = function (a, b, c, d, e)
479         {
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);
486         },
488         /*
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.
491          *
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
496          */
497         safeAdd_64_2 = function (x, y)
498         {
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);
510         },
512         /*
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.
515          *
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
522          */
523         safeAdd_64_4 = function (a, b, c, d)
524         {
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);
540         },
542         /*
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.
545          *
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
553          */
554         safeAdd_64_5 = function (a, b, c, d, e)
555         {
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);
575         },
577         /*
578          * Calculates the SHA-1 hash of the string set at instantiation
579          *
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
585          */
586         coreSHA1 = function (message, messageLen)
587         {
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
593                         ],
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
615                         ];
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)
627                 {
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)
635                         {
636                                 if (t < 16)
637                                 {
638                                         W[t] = message[t + i];
639                                 }
640                                 else
641                                 {
642                                         W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
643                                 }
645                                 if (t < 20)
646                                 {
647                                         T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, K[t], W[t]);
648                                 }
649                                 else if (t < 40)
650                                 {
651                                         T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]);
652                                 }
653                                 else if (t < 60)
654                                 {
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]);
658                                 }
660                                 e = d;
661                                 d = c;
662                                 c = rotl(b, 30);
663                                 b = a;
664                                 a = T;
665                         }
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]);
672                 }
674                 return H;
675         },
677         /*
678          * Calculates the desired SHA-2 hash of the string set at instantiation
679          *
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
685          */
686         coreSHA2 = function (message, messageLen, variant)
687         {
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")
696                 {
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
729                                 ];
731                         if (variant === "SHA-224")
732                         {
733                                 H = [
734                                                 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
735                                                 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
736                                         ];
737                         }
738                         else
739                         {
740                                 H = [
741                                                 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
742                                                 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
743                                         ];
744                         }
745                 }
746                 else if (variant === "SHA-384" || variant === "SHA-512")
747                 {
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)
805                         ];
807                         if (variant === "SHA-384")
808                         {
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)
814                                 ];
815                         }
816                         else
817                         {
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)
823                                 ];
824                         }
825                 }
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)
836                 {
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)
847                         {
848                                 if (t < 16)
849                                 {
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]);
853                                 }
854                                 else
855                                 {
856                                         W[t] = safeAdd_4(
857                                                         gamma1(W[t - 2]), W[t - 7],
858                                                         gamma0(W[t - 15]), W[t - 16]
859                                                 );
860                                 }
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);
872                         }
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]);
882                 }
884                 switch (variant)
885                 {
886                 case "SHA-224":
887                         return  [
888                                 H[0], H[1], H[2], H[3],
889                                 H[4], H[5], H[6]
890                         ];
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
901                         ];
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
912                         ];
913                 default:
914                         /* This should never be reached */
915                         return []; 
916                 }
917         },
919         /*
920          * jsSHA is the workhorse of the library.  Instantiate it with the string to
921          * be hashed as the parameter
922          *
923          * @constructor
924          * @param {String} srcString The string to be hashed
925          * @param {String} inputFormat The format of srcString, ASCII or HEX
926          */
927         jsSHA = function (srcString, inputFormat)
928         {
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)
941                 {
942                         if (0 !== (srcString.length % 2))
943                         {
944                                 return "TEXT MUST BE IN BYTE INCREMENTS";
945                         }
946                         this.strBinLen = srcString.length * 4;
947                         this.strToHash = hex2binb(srcString);
948                 }
949                 else if (("ASCII" === inputFormat) ||
950                          ('undefined' === typeof(inputFormat)))
951                 {
952                         this.strBinLen = srcString.length * charSize;
953                         this.strToHash = str2binb(srcString);
954                 }
955                 else
956                 {
957                         return "UNKNOWN TEXT INPUT TYPE";
958                 }
959         };
961         jsSHA.prototype = {
962                 /*
963                  * Returns the desired SHA hash of the string specified at instantiation
964                  * using the specified parameters
965                  *
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
970                  */
971                 getHash : function (variant, format)
972                 {
973                         var formatFunc = null, message = this.strToHash.slice();
975                         switch (format)
976                         {
977                         case "HEX":
978                                 formatFunc = binb2hex;
979                                 break;
980                         case "B64":
981                                 formatFunc = binb2b64;
982                                 break;
983                         default:
984                                 return "FORMAT NOT RECOGNIZED";
985                         }
987                         switch (variant)
988                         {
989                         case "SHA-1":
990                                 if (null === this.sha1)
991                                 {
992                                         this.sha1 = coreSHA1(message, this.strBinLen);
993                                 }
994                                 return formatFunc(this.sha1);
995                         case "SHA-224":
996                                 if (null === this.sha224)
997                                 {
998                                         this.sha224 = coreSHA2(message, this.strBinLen, variant);
999                                 }
1000                                 return formatFunc(this.sha224);
1001                         case "SHA-256":
1002                                 if (null === this.sha256)
1003                                 {
1004                                         this.sha256 = coreSHA2(message, this.strBinLen, variant);
1005                                 }
1006                                 return formatFunc(this.sha256);
1007                         case "SHA-384":
1008                                 if (null === this.sha384)
1009                                 {
1010                                         this.sha384 = coreSHA2(message, this.strBinLen, variant);
1011                                 }
1012                                 return formatFunc(this.sha384);
1013                         case "SHA-512":
1014                                 if (null === this.sha512)
1015                                 {
1016                                         this.sha512 = coreSHA2(message, this.strBinLen, variant);
1017                                 }
1018                                 return formatFunc(this.sha512);
1019                         default:
1020                                 return "HASH NOT RECOGNIZED";
1021                         }
1022                 },
1024                 /*
1025                  * Returns the desired HMAC of the string specified at instantiation
1026                  * using the key and variant param.
1027                  *
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
1035                  */
1036                 getHMAC : function (key, inputFormat, variant, outputFormat)
1037                 {
1038                         var formatFunc, keyToUse, blockByteSize, blockBitSize, i,
1039                                 retVal, lastArrayIndex, keyBinLen, hashBitSize,
1040                                 keyWithIPad = [], keyWithOPad = [];
1042                         /* Validate the output format selection */
1043                         switch (outputFormat)
1044                         {
1045                         case "HEX":
1046                                 formatFunc = binb2hex;
1047                                 break;
1048                         case "B64":
1049                                 formatFunc = binb2b64;
1050                                 break;
1051                         default:
1052                                 return "FORMAT NOT RECOGNIZED";
1053                         }
1055                         /* Validate the hash variant selection and set needed variables */
1056                         switch (variant)
1057                         {
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";
1080                         }
1082                         /* Validate input format selection */
1083                         if ("HEX" === inputFormat)
1084                         {
1085                                 /* Nibbles must come in pairs */
1086                                 if (0 !== (key.length % 2))
1087                                 {
1088                                         return "KEY MUST BE IN BYTE INCREMENTS";
1089                                 }
1090                                 keyToUse = hex2binb(key);
1091                                 keyBinLen = key.length * 4;
1092                         }
1093                         else if ("ASCII" === inputFormat)
1094                         {
1095                                 keyToUse = str2binb(key);
1096                                 keyBinLen = key.length * charSize;
1097                         }
1098                         else
1099                         {
1100                                 return "UNKNOWN KEY INPUT TYPE";
1101                         }
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))
1110                         {
1111                                 if ("SHA-1" === variant)
1112                                 {
1113                                         keyToUse = coreSHA1(keyToUse, keyBinLen);
1114                                 }
1115                                 else
1116                                 {
1117                                         keyToUse = coreSHA2(keyToUse, keyBinLen, variant);
1118                                 }
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;
1123                         }
1124                         else if (blockByteSize > (keyBinLen / 8))
1125                         {
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;
1130                         }
1132                         /* Create ipad and opad */
1133                         for (i = 0; i <= lastArrayIndex; i += 1)
1134                         {
1135                                 keyWithIPad[i] = keyToUse[i] ^ 0x36363636;
1136                                 keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C;
1137                         }
1139                         /* Calculate the HMAC */
1140                         if ("SHA-1" === variant)
1141                         {
1142                                 retVal = coreSHA1(
1143                                                         keyWithIPad.concat(this.strToHash),
1144                                                         blockBitSize + this.strBinLen);
1145                                 retVal = coreSHA1(
1146                                                         keyWithOPad.concat(retVal),
1147                                                         blockBitSize + hashBitSize);
1148                         }
1149                         else
1150                         {
1151                                 retVal = coreSHA2(
1152                                                         keyWithIPad.concat(this.strToHash),
1153                                                         blockBitSize + this.strBinLen, variant);
1154                                 retVal = coreSHA2(
1155                                                         keyWithOPad.concat(retVal),
1156                                                         blockBitSize + hashBitSize, variant);
1157                         }
1159                         return (formatFunc(retVal));
1160                 }
1161         };
1163         window.jsSHA = jsSHA;
1164 }());