Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / t / crypto-sha1.js
1 /*
2  * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
3  * in FIPS PUB 180-1
4  * Version 2.1a Copyright Paul Johnston 2000 - 2002.
5  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
6  * Distributed under the BSD License
7  * See http://pajhome.org.uk/crypt/md5 for details.
8  */
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 var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
17
18 /*
19  * These are the functions you'll usually want to call
20  * They take string arguments and return either hex or base-64 encoded strings
21  */
22 function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
23 function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
24 function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
25 function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
26 function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
27 function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
28
29 /*
30  * Perform a simple self-test to see if the VM is working
31  */
32 function sha1_vm_test()
33 {
34   return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
35 }
36
37 /*
38  * Calculate the SHA-1 of an array of big-endian words, and a bit length
39  */
40 function core_sha1(x, len)
41 {
42   /* append padding */
43   x[len >> 5] |= 0x80 << (24 - len % 32);
44   x[((len + 64 >> 9) << 4) + 15] = len;
45
46   var w = Array(80);
47   var a =  1732584193;
48   var b = -271733879;
49   var c = -1732584194;
50   var d =  271733878;
51   var e = -1009589776;
52
53   for(var i = 0; i < x.length; i += 16)
54   {
55     var olda = a;
56     var oldb = b;
57     var oldc = c;
58     var oldd = d;
59     var olde = e;
60
61     for(var j = 0; j < 80; j++)
62     {
63       if(j < 16) w[j] = x[i + j];
64       else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
65       var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
66                        safe_add(safe_add(e, w[j]), sha1_kt(j)));
67       e = d;
68       d = c;
69       c = rol(b, 30);
70       b = a;
71       a = t;
72     }
73
74     a = safe_add(a, olda);
75     b = safe_add(b, oldb);
76     c = safe_add(c, oldc);
77     d = safe_add(d, oldd);
78     e = safe_add(e, olde);
79   }
80   return Array(a, b, c, d, e);
81
82 }
83
84 /*
85  * Perform the appropriate triplet combination function for the current
86  * iteration
87  */
88 function sha1_ft(t, b, c, d)
89 {
90   if(t < 20) return (b & c) | ((~b) & d);
91   if(t < 40) return b ^ c ^ d;
92   if(t < 60) return (b & c) | (b & d) | (c & d);
93   return b ^ c ^ d;
94 }
95
96 /*
97  * Determine the appropriate additive constant for the current iteration
98  */
99 function sha1_kt(t)
100 {
101   return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
102          (t < 60) ? -1894007588 : -899497514;
103 }
104
105 /*
106  * Calculate the HMAC-SHA1 of a key and some data
107  */
108 function core_hmac_sha1(key, data)
109 {
110   var bkey = str2binb(key);
111   if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
112
113   var ipad = Array(16), opad = Array(16);
114   for(var i = 0; i < 16; i++)
115   {
116     ipad[i] = bkey[i] ^ 0x36363636;
117     opad[i] = bkey[i] ^ 0x5C5C5C5C;
118   }
119
120   var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
121   return core_sha1(opad.concat(hash), 512 + 160);
122 }
123
124 /*
125  * Add integers, wrapping at 2^32. This uses 16-bit operations internally
126  * to work around bugs in some JS interpreters.
127  */
128 function safe_add(x, y)
129 {
130   var lsw = (x & 0xFFFF) + (y & 0xFFFF);
131   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
132   return (msw << 16) | (lsw & 0xFFFF);
133 }
134
135 /*
136  * Bitwise rotate a 32-bit number to the left.
137  */
138 function rol(num, cnt)
139 {
140   return (num << cnt) | (num >>> (32 - cnt));
141 }
142
143 /*
144  * Convert an 8-bit or 16-bit string to an array of big-endian words
145  * In 8-bit function, characters >255 have their hi-byte silently ignored.
146  */
147 function str2binb(str)
148 {
149   var bin = Array();
150   var mask = (1 << chrsz) - 1;
151   for(var i = 0; i < str.length * chrsz; i += chrsz)
152     bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
153   return bin;
154 }
155
156 /*
157  * Convert an array of big-endian words to a string
158  */
159 function binb2str(bin)
160 {
161   var str = "";
162   var mask = (1 << chrsz) - 1;
163   for(var i = 0; i < bin.length * 32; i += chrsz)
164     str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
165   return str;
166 }
167
168 /*
169  * Convert an array of big-endian words to a hex string.
170  */
171 function binb2hex(binarray)
172 {
173   var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
174   var str = "";
175   for(var i = 0; i < binarray.length * 4; i++)
176   {
177     str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
178            hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
179   }
180   return str;
181 }
182
183 /*
184  * Convert an array of big-endian words to a base-64 string
185  */
186 function binb2b64(binarray)
187 {
188   var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
189   var str = "";
190   for(var i = 0; i < binarray.length * 4; i += 3)
191   {
192     var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
193                 | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
194                 |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
195     for(var j = 0; j < 4; j++)
196     {
197       if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
198       else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
199     }
200   }
201   return str;
202 }
203
204
205 var plainText = "Two households, both alike in dignity,\n\
206 In fair Verona, where we lay our scene,\n\
207 From ancient grudge break to new mutiny,\n\
208 Where civil blood makes civil hands unclean.\n\
209 From forth the fatal loins of these two foes\n\
210 A pair of star-cross'd lovers take their life;\n\
211 Whole misadventured piteous overthrows\n\
212 Do with their death bury their parents' strife.\n\
213 The fearful passage of their death-mark'd love,\n\
214 And the continuance of their parents' rage,\n\
215 Which, but their children's end, nought could remove,\n\
216 Is now the two hours' traffic of our stage;\n\
217 The which if you with patient ears attend,\n\
218 What here shall miss, our toil shall strive to mend.";
219
220 for (var i = 0; i <4; i++) {
221     plainText += plainText;
222 }
223
224 var sha1Output = hex_sha1(plainText);