1563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
2563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
3563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Digest Algorithm, as defined in RFC 1321.
4563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
5563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
6563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Distributed under the BSD License
7563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * See http://pajhome.org.uk/crypt/md5 for more info.
8563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
9563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
10563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
11563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Configurable variables. You may need to tweak these to be compatible with
12563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * the server-side, but the defaults work in most cases.
13563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
14563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkvar hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
15563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkvar b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
16563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkvar chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
17563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
18563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
19563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * These are the functions you'll usually want to call
20563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * They take string arguments and return either hex or base-64 encoded strings
21563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
22563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
23563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
24563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
25563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
26563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
27563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
28563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
29563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
30563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Perform a simple self-test to see if the VM is working
31563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
32563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction md5_vm_test()
33563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
34563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
35563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
36563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
37563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
38563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Calculate the MD5 of an array of little-endian words, and a bit length
39563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
40563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction core_md5(x, len)
41563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
42563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  /* append padding */
43563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  x[len >> 5] |= 0x80 << ((len) % 32);
44563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  x[(((len + 64) >>> 9) << 4) + 14] = len;
45563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
46563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var a =  1732584193;
47563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var b = -271733879;
48563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var c = -1732584194;
49563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var d =  271733878;
50563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
51563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  for(var i = 0; i < x.length; i += 16)
52563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  {
53563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    var olda = a;
54563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    var oldb = b;
55563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    var oldc = c;
56563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    var oldd = d;
57563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
59563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
60563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
61563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
62563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
63563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
64563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
65563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
66563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
67563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
68563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
69563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
70563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
71563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
72563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
73563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
74563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
75563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
76563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
77563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
78563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
79563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
80563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
81563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
82563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
83563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
84563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
85563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
86563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
87563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
88563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
89563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
90563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
91563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
92563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
93563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
94563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
95563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
96563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
97563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
98563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
99563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
100563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
101563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
102563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
103563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
104563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
105563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
106563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
107563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
108563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
109563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
110563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
111563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
112563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
113563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
114563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
115563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
116563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
117563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
118563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
119563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
120563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
121563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
122563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
123563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
124563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
125563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
126563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    a = safe_add(a, olda);
127563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    b = safe_add(b, oldb);
128563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    c = safe_add(c, oldc);
129563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    d = safe_add(d, oldd);
130563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  }
131563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return Array(a, b, c, d);
132563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
133563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
134563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
135563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
136563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * These functions implement the four basic operations the algorithm uses.
137563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
138563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction md5_cmn(q, a, b, x, s, t)
139563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
140563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
141563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
142563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction md5_ff(a, b, c, d, x, s, t)
143563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
144563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
145563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
146563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction md5_gg(a, b, c, d, x, s, t)
147563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
148563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
149563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
150563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction md5_hh(a, b, c, d, x, s, t)
151563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
152563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
153563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
154563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction md5_ii(a, b, c, d, x, s, t)
155563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
156563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
157563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
158563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
159563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
160563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Calculate the HMAC-MD5, of a key and some data
161563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
162563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction core_hmac_md5(key, data)
163563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
164563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var bkey = str2binl(key);
165563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
166563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
167563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var ipad = Array(16), opad = Array(16);
168563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  for(var i = 0; i < 16; i++)
169563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  {
170563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    ipad[i] = bkey[i] ^ 0x36363636;
171563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    opad[i] = bkey[i] ^ 0x5C5C5C5C;
172563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  }
173563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
174563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
175563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return core_md5(opad.concat(hash), 512 + 128);
176563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
177563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
178563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
179563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Add integers, wrapping at 2^32. This uses 16-bit operations internally
180563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * to work around bugs in some JS interpreters.
181563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
182563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction safe_add(x, y)
183563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
184563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
185563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
186563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return (msw << 16) | (lsw & 0xFFFF);
187563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
188563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
189563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
190563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Bitwise rotate a 32-bit number to the left.
191563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
192563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction bit_rol(num, cnt)
193563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
194563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return (num << cnt) | (num >>> (32 - cnt));
195563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
196563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
197563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
198563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Convert a string to an array of little-endian words
199563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
200563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
201563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction str2binl(str)
202563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
203563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var bin = Array();
204563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var mask = (1 << chrsz) - 1;
205563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  for(var i = 0; i < str.length * chrsz; i += chrsz)
206563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
207563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return bin;
208563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
209563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
210563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
211563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Convert an array of little-endian words to a string
212563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
213563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction binl2str(bin)
214563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
215563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var str = "";
216563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var mask = (1 << chrsz) - 1;
217563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  for(var i = 0; i < bin.length * 32; i += chrsz)
218563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
219563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return str;
220563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
221563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
222563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
223563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Convert an array of little-endian words to a hex string.
224563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
225563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction binl2hex(binarray)
226563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
227563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
228563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var str = "";
229563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  for(var i = 0; i < binarray.length * 4; i++)
230563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  {
231563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
232563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
233563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  }
234563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return str;
235563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
236563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
237563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
238563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Convert an array of little-endian words to a base-64 string
239563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
240563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfunction binl2b64(binarray)
241563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
242563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
243563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  var str = "";
244563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  for(var i = 0; i < binarray.length * 4; i += 3)
245563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  {
246563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
247563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
248563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
249563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    for(var j = 0; j < 4; j++)
250563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    {
251563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
252563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
253563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
254563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  }
255563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark  return str;
256563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
257563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
258563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkvar plainText = "Rebellious subjects, enemies to peace,\n\
259563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkProfaners of this neighbour-stained steel,--\n\
260563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkWill they not hear? What, ho! you men, you beasts,\n\
261563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkThat quench the fire of your pernicious rage\n\
262563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkWith purple fountains issuing from your veins,\n\
263563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkOn pain of torture, from those bloody hands\n\
264563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkThrow your mistemper'd weapons to the ground,\n\
265563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkAnd hear the sentence of your moved prince.\n\
266563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkThree civil brawls, bred of an airy word,\n\
267563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkBy thee, old Capulet, and Montague,\n\
268563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHave thrice disturb'd the quiet of our streets,\n\
269563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkAnd made Verona's ancient citizens\n\
270563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkCast by their grave beseeming ornaments,\n\
271563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkTo wield old partisans, in hands as old,\n\
272563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkCanker'd with peace, to part your canker'd hate:\n\
273563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkIf ever you disturb our streets again,\n\
274563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkYour lives shall pay the forfeit of the peace.\n\
275563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkFor this time, all the rest depart away:\n\
276563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkYou Capulet; shall go along with me:\n\
277563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkAnd, Montague, come you this afternoon,\n\
278563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkTo know our further pleasure in this case,\n\
279563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkTo old Free-town, our common judgment-place.\n\
280563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkOnce more, on pain of death, all men depart."
281563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
282563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkfor (var i = 0; i <4; i++) {
283563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    plainText += plainText;
284563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
285563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
286563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkvar md5Output = hex_md5(plainText);
287