]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/ohauth/ohauth.js
Update ohauth and switch to using the new headerGenerator method
[rails.git] / vendor / assets / ohauth / ohauth.js
1 (function(e){if("function"==typeof bootstrap)bootstrap("ohauth",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeOhauth=e}else"undefined"!=typeof window?window.ohauth=e():global.ohauth=e()})(function(){var define,ses,bootstrap,module,exports;
2 return (function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){
3 'use strict';
4
5 var hashes = require('jshashes'),
6     xtend = require('xtend'),
7     sha1 = new hashes.SHA1();
8
9 var ohauth = {};
10
11 ohauth.qsString = function(obj) {
12     return Object.keys(obj).sort().map(function(key) {
13         return ohauth.percentEncode(key) + '=' +
14             ohauth.percentEncode(obj[key]);
15     }).join('&');
16 };
17
18 ohauth.stringQs = function(str) {
19     return str.split('&').reduce(function(obj, pair){
20         var parts = pair.split('=');
21         obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
22             '' : decodeURIComponent(parts[1]);
23         return obj;
24     }, {});
25 };
26
27 ohauth.rawxhr = function(method, url, data, headers, callback) {
28     var xhr = new XMLHttpRequest(),
29         twoHundred = /^20\d$/;
30     xhr.onreadystatechange = function() {
31         if (4 == xhr.readyState && 0 !== xhr.status) {
32             if (twoHundred.test(xhr.status)) callback(null, xhr);
33             else return callback(xhr, null);
34         }
35     };
36     xhr.onerror = function(e) { return callback(e, null); };
37     xhr.open(method, url, true);
38     for (var h in headers) xhr.setRequestHeader(h, headers[h]);
39     xhr.send(data);
40 };
41
42 ohauth.xhr = function(method, url, auth, data, options, callback) {
43     var headers = (options && options.header) || {
44         'Content-Type': 'application/x-www-form-urlencoded'
45     };
46     headers.Authorization = 'OAuth ' + ohauth.authHeader(auth);
47     ohauth.rawxhr(method, url, data, headers, callback);
48 };
49
50 ohauth.nonce = function() {
51     for (var o = ''; o.length < 6;) {
52         o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
53     }
54     return o;
55 };
56
57 ohauth.authHeader = function(obj) {
58     return Object.keys(obj).sort().map(function(key) {
59         return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
60     }).join(', ');
61 };
62
63 ohauth.timestamp = function() { return ~~((+new Date()) / 1000); };
64
65 ohauth.percentEncode = function(s) {
66     return encodeURIComponent(s)
67         .replace(/\!/g, '%21').replace(/\'/g, '%27')
68         .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
69 };
70
71 ohauth.baseString = function(method, url, params) {
72     if (params.oauth_signature) delete params.oauth_signature;
73     return [
74         method,
75         ohauth.percentEncode(url),
76         ohauth.percentEncode(ohauth.qsString(params))].join('&');
77 };
78
79 ohauth.signature = function(oauth_secret, token_secret, baseString) {
80     return sha1.b64_hmac(
81         ohauth.percentEncode(oauth_secret) + '&' +
82         ohauth.percentEncode(token_secret),
83         baseString);
84 };
85
86 /**
87  * Takes an options object for configuration (consumer_key,
88  * consumer_secret, version, signature_method, token) and returns a
89  * function that generates the Authorization header for given data.
90  *
91  * The returned function takes these parameters:
92  * - method: GET/POST/...
93  * - uri: full URI with protocol, port, path and query string
94  * - extra_params: any extra parameters (that are passed in the POST data),
95  *   can be an object or a from-urlencoded string.
96  *
97  * Returned function returns full OAuth header with "OAuth" string in it.
98  */
99
100 ohauth.headerGenerator = function(options) {
101     options = options || {};
102     var consumer_key = options.consumer_key || '',
103         consumer_secret = options.consumer_secret || '',
104         signature_method = options.signature_method || 'HMAC-SHA1',
105         version = options.version || '1.0',
106         token = options.token || '',
107         token_secret = options.token_secret || '';
108
109     return function(method, uri, extra_params) {
110         method = method.toUpperCase();
111         if (typeof extra_params === 'string' && extra_params.length > 0) {
112             extra_params = ohauth.stringQs(extra_params);
113         }
114
115         var uri_parts = uri.split('?', 2),
116         base_uri = uri_parts[0];
117
118         var query_params = uri_parts.length === 2 ?
119             ohauth.stringQs(uri_parts[1]) : {};
120
121         var oauth_params = {
122             oauth_consumer_key: consumer_key,
123             oauth_signature_method: signature_method,
124             oauth_version: version,
125             oauth_timestamp: ohauth.timestamp(),
126             oauth_nonce: ohauth.nonce()
127         };
128
129         if (token) oauth_params.oauth_token = token;
130
131         var all_params = xtend({}, oauth_params, query_params, extra_params),
132             base_str = ohauth.baseString(method, base_uri, all_params);
133
134         oauth_params.oauth_signature = ohauth.signature(consumer_secret, token_secret, base_str);
135
136         return 'OAuth ' + ohauth.authHeader(oauth_params);
137     };
138 };
139
140 module.exports = ohauth;
141
142 },{"xtend":2,"jshashes":3}],2:[function(require,module,exports){
143 var Keys = Object.keys || objectKeys
144
145 module.exports = extend
146
147 function extend() {
148     var target = {}
149
150     for (var i = 0; i < arguments.length; i++) {
151         var source = arguments[i]
152
153         if (!isObject(source)) {
154             continue
155         }
156
157         var keys = Keys(source)
158
159         for (var j = 0; j < keys.length; j++) {
160             var name = keys[j]
161             target[name] = source[name]
162         }
163     }
164
165     return target
166 }
167
168 function objectKeys(obj) {
169     var keys = []
170     for (var k in obj) {
171         keys.push(k)
172     }
173     return keys
174 }
175
176 function isObject(obj) {
177     return obj !== null && typeof obj === "object"
178 }
179
180 },{}],3:[function(require,module,exports){
181 (function(global){/**
182  * jsHashes - A fast and independent hashing library pure JavaScript implemented (ES5 compliant) for both server and client side
183  * 
184  * @class Hashes
185  * @author Tomas Aparicio <tomas@rijndael-project.com>
186  * @license New BSD (see LICENSE file)
187  * @version 1.0.3
188  *
189  * Algorithms specification:
190  *
191  * MD5 <http://www.ietf.org/rfc/rfc1321.txt>
192  * RIPEMD-160 <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
193  * SHA1   <http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf>
194  * SHA256 <http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf>
195  * SHA512 <http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf>
196  * HMAC <http://www.ietf.org/rfc/rfc2104.txt>
197  *
198  */
199 (function(){
200   var Hashes;
201   
202   // private helper methods
203   function utf8Encode(input) {
204     var  x, y, output = '', i = -1, l = input.length;
205     while ((i+=1) < l) {
206       /* Decode utf-16 surrogate pairs */
207       x = input.charCodeAt(i);
208       y = i + 1 < l ? input.charCodeAt(i + 1) : 0;
209       if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
210           x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
211           i += 1;
212       }
213       /* Encode output as utf-8 */
214       if (x <= 0x7F) {
215           output += String.fromCharCode(x);
216       } else if (x <= 0x7FF) {
217           output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
218                       0x80 | ( x & 0x3F));
219       } else if (x <= 0xFFFF) {
220           output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
221                       0x80 | ((x >>> 6 ) & 0x3F),
222                       0x80 | ( x & 0x3F));
223       } else if (x <= 0x1FFFFF) {
224           output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
225                       0x80 | ((x >>> 12) & 0x3F),
226                       0x80 | ((x >>> 6 ) & 0x3F),
227                       0x80 | ( x & 0x3F));
228       }
229     }
230     return output;
231   }
232   
233   function utf8Decode(str_data) {
234     var i, ac, c1, c2, c3, arr = [], l = str_data.length;
235     i = ac = c1 = c2 = c3 = 0;
236     str_data += '';
237
238     while (i < l) {
239         c1 = str_data.charCodeAt(i);
240         ac += 1;
241         if (c1 < 128) {
242             arr[ac] = String.fromCharCode(c1);
243             i+=1;
244         } else if (c1 > 191 && c1 < 224) {
245             c2 = str_data.charCodeAt(i + 1);
246             arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
247             i += 2;
248         } else {
249             c2 = str_data.charCodeAt(i + 1);
250             c3 = str_data.charCodeAt(i + 2);
251             arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
252             i += 3;
253         }
254     }
255     return arr.join('');
256   }
257
258   /**
259    * Add integers, wrapping at 2^32. This uses 16-bit operations internally
260    * to work around bugs in some JS interpreters.
261    */
262   function safe_add(x, y) {
263     var lsw = (x & 0xFFFF) + (y & 0xFFFF),
264         msw = (x >> 16) + (y >> 16) + (lsw >> 16);
265     return (msw << 16) | (lsw & 0xFFFF);
266   }
267
268   /**
269    * Bitwise rotate a 32-bit number to the left.
270    */
271   function bit_rol(num, cnt) {
272     return (num << cnt) | (num >>> (32 - cnt));
273   }
274
275   /**
276    * Convert a raw string to a hex string
277    */
278   function rstr2hex(input, hexcase) {
279     var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
280         output = '', x, i = 0, l = input.length;
281     for (; i < l; i+=1) {
282       x = input.charCodeAt(i);
283       output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
284     }
285     return output;
286   }
287
288   /**
289    * Encode a string as utf-16
290    */
291   function str2rstr_utf16le(input) {
292     var i, l = input.length, output = '';
293     for (i = 0; i < l; i+=1) {
294       output += String.fromCharCode( input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF);
295     }
296     return output;
297   }
298
299   function str2rstr_utf16be(input) {
300     var i, l = input.length, output = '';
301     for (i = 0; i < l; i+=1) {
302       output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF);
303     }
304     return output;
305   }
306
307   /**
308    * Convert an array of big-endian words to a string
309    */
310   function binb2rstr(input) {
311     var i, l = input.length * 32, output = '';
312     for (i = 0; i < l; i += 8) {
313         output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
314     }
315     return output;
316   }
317
318   /**
319    * Convert an array of little-endian words to a string
320    */
321   function binl2rstr(input) {
322     var i, l = input.length * 32, output = '';
323     for (i = 0;i < l; i += 8) {
324       output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
325     }
326     return output;
327   }
328
329   /**
330    * Convert a raw string to an array of little-endian words
331    * Characters >255 have their high-byte silently ignored.
332    */
333   function rstr2binl(input) {
334     var i, l = input.length * 8, output = Array(input.length >> 2), lo = output.length;
335     for (i = 0; i < lo; i+=1) {
336       output[i] = 0;
337     }
338     for (i = 0; i < l; i += 8) {
339       output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
340     }
341     return output;
342   }
343   
344   /**
345    * Convert a raw string to an array of big-endian words 
346    * Characters >255 have their high-byte silently ignored.
347    */
348    function rstr2binb(input) {
349       var i, l = input.length * 8, output = Array(input.length >> 2), lo = output.length;
350       for (i = 0; i < lo; i+=1) {
351             output[i] = 0;
352         }
353       for (i = 0; i < l; i += 8) {
354             output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
355         }
356       return output;
357    }
358
359   /**
360    * Convert a raw string to an arbitrary string encoding
361    */
362   function rstr2any(input, encoding) {
363     var divisor = encoding.length,
364         remainders = Array(),
365         i, q, x, ld, quotient, dividend, output, full_length;
366   
367     /* Convert to an array of 16-bit big-endian values, forming the dividend */
368     dividend = Array(Math.ceil(input.length / 2));
369     ld = dividend.length;
370     for (i = 0; i < ld; i+=1) {
371       dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
372     }
373   
374     /**
375      * Repeatedly perform a long division. The binary array forms the dividend,
376      * the length of the encoding is the divisor. Once computed, the quotient
377      * forms the dividend for the next step. We stop when the dividend is zerHashes.
378      * All remainders are stored for later use.
379      */
380     while(dividend.length > 0) {
381       quotient = Array();
382       x = 0;
383       for (i = 0; i < dividend.length; i+=1) {
384         x = (x << 16) + dividend[i];
385         q = Math.floor(x / divisor);
386         x -= q * divisor;
387         if (quotient.length > 0 || q > 0) {
388           quotient[quotient.length] = q;
389         }
390       }
391       remainders[remainders.length] = x;
392       dividend = quotient;
393     }
394   
395     /* Convert the remainders to the output string */
396     output = '';
397     for (i = remainders.length - 1; i >= 0; i--) {
398       output += encoding.charAt(remainders[i]);
399     }
400   
401     /* Append leading zero equivalents */
402     full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
403     for (i = output.length; i < full_length; i+=1) {
404       output = encoding[0] + output;
405     }
406     return output;
407   }
408
409   /**
410    * Convert a raw string to a base-64 string
411    */
412   function rstr2b64(input, b64pad) {
413     var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
414         output = '',
415         len = input.length, i, j, triplet;
416     b64pad= b64pad || '=';
417     for (i = 0; i < len; i += 3) {
418       triplet = (input.charCodeAt(i) << 16)
419             | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
420             | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
421       for (j = 0; j < 4; j+=1) {
422         if (i * 8 + j * 6 > input.length * 8) { 
423           output += b64pad; 
424         } else { 
425           output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); 
426         }
427        }
428     }
429     return output;
430   }
431
432   Hashes = {
433   /**  
434    * @property {String} version
435    * @readonly
436    */
437   VERSION : '1.0.3',
438   /**
439    * @member Hashes
440    * @class Base64
441    * @constructor
442    */
443   Base64 : function () {
444     // private properties
445     var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
446         pad = '=', // default pad according with the RFC standard
447         url = false, // URL encoding support @todo
448         utf8 = true; // by default enable UTF-8 support encoding
449
450     // public method for encoding
451     this.encode = function (input) {
452       var i, j, triplet,
453           output = '', 
454           len = input.length;
455
456       pad = pad || '=';
457       input = (utf8) ? utf8Encode(input) : input;
458
459       for (i = 0; i < len; i += 3) {
460         triplet = (input.charCodeAt(i) << 16)
461               | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
462               | (i + 2 < len ? input.charCodeAt(i+2) : 0);
463         for (j = 0; j < 4; j+=1) {
464           if (i * 8 + j * 6 > len * 8) {
465               output += pad;
466           } else {
467               output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
468           }
469         }
470       }
471       return output;    
472     };
473
474     // public method for decoding
475     this.decode = function (input) {
476       // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
477       var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
478         dec = '',
479         arr = [];
480       if (!input) { return input; }
481
482       i = ac = 0;
483       input = input.replace(new RegExp('\\'+pad,'gi'),''); // use '='
484       //input += '';
485
486       do { // unpack four hexets into three octets using index points in b64
487         h1 = tab.indexOf(input.charAt(i+=1));
488         h2 = tab.indexOf(input.charAt(i+=1));
489         h3 = tab.indexOf(input.charAt(i+=1));
490         h4 = tab.indexOf(input.charAt(i+=1));
491
492         bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
493
494         o1 = bits >> 16 & 0xff;
495         o2 = bits >> 8 & 0xff;
496         o3 = bits & 0xff;
497         ac += 1;
498
499         if (h3 === 64) {
500           arr[ac] = String.fromCharCode(o1);
501         } else if (h4 === 64) {
502           arr[ac] = String.fromCharCode(o1, o2);
503         } else {
504           arr[ac] = String.fromCharCode(o1, o2, o3);
505         }
506       } while (i < input.length);
507
508       dec = arr.join('');
509       dec = (utf8) ? utf8Decode(dec) : dec;
510
511       return dec;
512     };
513
514     // set custom pad string
515     this.setPad = function (str) {
516         pad = str || pad;
517         return this;
518     };
519     // set custom tab string characters
520     this.setTab = function (str) {
521         tab = str || tab;
522         return this;
523     };
524     this.setUTF8 = function (bool) {
525         if (typeof bool === 'boolean') {
526           utf8 = bool;
527         }
528         return this;
529     };
530   },
531
532   /**
533    * CRC-32 calculation
534    * @member Hashes
535    * @method CRC32
536    * @static
537    * @param {String} str Input String
538    * @return {String}
539    */
540   CRC32 : function (str) {
541     var crc = 0, x = 0, y = 0, table, i, iTop;
542     str = utf8Encode(str);
543         
544     table = [ 
545         '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
546         '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
547         '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
548         '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
549         'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
550         '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
551         'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
552         '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
553         'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
554         '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
555         'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
556         '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
557         'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
558         '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
559         '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
560         '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
561         '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
562         'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ', 
563         '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
564         'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
565         '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
566         'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
567         '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
568         'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
569         '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
570         'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
571     ].join('');
572
573     crc = crc ^ (-1);
574     for (i = 0, iTop = str.length; i < iTop; i+=1 ) {
575         y = ( crc ^ str.charCodeAt( i ) ) & 0xFF;
576         x = '0x' + table.substr( y * 9, 8 );
577         crc = ( crc >>> 8 ) ^ x;
578     }
579     // always return a positive number (that's what >>> 0 does)
580     return (crc ^ (-1)) >>> 0;
581   },
582   /**
583    * @member Hashes
584    * @class MD5
585    * @constructor
586    * @param {Object} [config]
587    * 
588    * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
589    * Digest Algorithm, as defined in RFC 1321.
590    * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
591    * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
592    * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
593    */
594   MD5 : function (options) {  
595     /**
596      * Private config properties. You may need to tweak these to be compatible with
597      * the server-side, but the defaults work in most cases.
598      * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
599      */
600     var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
601         b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
602         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
603
604     // privileged (public) methods 
605     this.hex = function (s) { 
606       return rstr2hex(rstr(s, utf8), hexcase);
607     };
608     this.b64 = function (s) { 
609       return rstr2b64(rstr(s), b64pad);
610     };
611     this.any = function(s, e) { 
612       return rstr2any(rstr(s, utf8), e); 
613     };
614     this.hex_hmac = function (k, d) { 
615       return rstr2hex(rstr_hmac(k, d), hexcase); 
616     };
617     this.b64_hmac = function (k, d) { 
618       return rstr2b64(rstr_hmac(k,d), b64pad); 
619     };
620     this.any_hmac = function (k, d, e) { 
621       return rstr2any(rstr_hmac(k, d), e); 
622     };
623     /**
624      * Perform a simple self-test to see if the VM is working
625      * @return {String} Hexadecimal hash sample
626      */
627     this.vm_test = function () {
628       return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
629     };
630     /** 
631      * Enable/disable uppercase hexadecimal returned string 
632      * @param {Boolean} 
633      * @return {Object} this
634      */ 
635     this.setUpperCase = function (a) {
636       if (typeof a === 'boolean' ) {
637         hexcase = a;
638       }
639       return this;
640     };
641     /** 
642      * Defines a base64 pad string 
643      * @param {String} Pad
644      * @return {Object} this
645      */ 
646     this.setPad = function (a) {
647       b64pad = a || b64pad;
648       return this;
649     };
650     /** 
651      * Defines a base64 pad string 
652      * @param {Boolean} 
653      * @return {Object} [this]
654      */ 
655     this.setUTF8 = function (a) {
656       if (typeof a === 'boolean') { 
657         utf8 = a;
658       }
659       return this;
660     };
661
662     // private methods
663
664     /**
665      * Calculate the MD5 of a raw string
666      */
667     function rstr(s) {
668       s = (utf8) ? utf8Encode(s): s;
669       return binl2rstr(binl(rstr2binl(s), s.length * 8));
670     }
671     
672     /**
673      * Calculate the HMAC-MD5, of a key and some data (raw strings)
674      */
675     function rstr_hmac(key, data) {
676       var bkey, ipad, opad, hash, i;
677
678       key = (utf8) ? utf8Encode(key) : key;
679       data = (utf8) ? utf8Encode(data) : data;
680       bkey = rstr2binl(key);
681       if (bkey.length > 16) { 
682         bkey = binl(bkey, key.length * 8); 
683       }
684
685       ipad = Array(16), opad = Array(16); 
686       for (i = 0; i < 16; i+=1) {
687           ipad[i] = bkey[i] ^ 0x36363636;
688           opad[i] = bkey[i] ^ 0x5C5C5C5C;
689       }
690       hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
691       return binl2rstr(binl(opad.concat(hash), 512 + 128));
692     }
693
694     /**
695      * Calculate the MD5 of an array of little-endian words, and a bit length.
696      */
697     function binl(x, len) {
698       var i, olda, oldb, oldc, oldd,
699           a =  1732584193,
700           b = -271733879,
701           c = -1732584194,
702           d =  271733878;
703         
704       /* append padding */
705       x[len >> 5] |= 0x80 << ((len) % 32);
706       x[(((len + 64) >>> 9) << 4) + 14] = len;
707
708       for (i = 0; i < x.length; i += 16) {
709         olda = a;
710         oldb = b;
711         oldc = c;
712         oldd = d;
713
714         a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
715         d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
716         c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
717         b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
718         a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
719         d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
720         c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
721         b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
722         a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
723         d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
724         c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
725         b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
726         a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
727         d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
728         c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
729         b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
730
731         a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
732         d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
733         c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
734         b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
735         a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
736         d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
737         c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
738         b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
739         a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
740         d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
741         c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
742         b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
743         a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
744         d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
745         c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
746         b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
747
748         a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
749         d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
750         c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
751         b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
752         a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
753         d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
754         c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
755         b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
756         a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
757         d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
758         c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
759         b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
760         a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
761         d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
762         c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
763         b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
764
765         a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
766         d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
767         c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
768         b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
769         a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
770         d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
771         c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
772         b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
773         a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
774         d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
775         c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
776         b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
777         a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
778         d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
779         c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
780         b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
781
782         a = safe_add(a, olda);
783         b = safe_add(b, oldb);
784         c = safe_add(c, oldc);
785         d = safe_add(d, oldd);
786       }
787       return Array(a, b, c, d);
788     }
789
790     /**
791      * These functions implement the four basic operations the algorithm uses.
792      */
793     function md5_cmn(q, a, b, x, s, t) {
794       return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
795     }
796     function md5_ff(a, b, c, d, x, s, t) {
797       return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
798     }
799     function md5_gg(a, b, c, d, x, s, t) {
800       return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
801     }
802     function md5_hh(a, b, c, d, x, s, t) {
803       return md5_cmn(b ^ c ^ d, a, b, x, s, t);
804     }
805     function md5_ii(a, b, c, d, x, s, t) {
806       return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
807     }
808   },
809   /**
810    * @member Hashes
811    * @class Hashes.SHA1
812    * @param {Object} [config]
813    * @constructor
814    * 
815    * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
816    * Version 2.2 Copyright Paul Johnston 2000 - 2009.
817    * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
818    * See http://pajhome.org.uk/crypt/md5 for details.
819    */
820   SHA1 : function (options) {
821    /**
822      * Private config properties. You may need to tweak these to be compatible with
823      * the server-side, but the defaults work in most cases.
824      * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
825      */
826     var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
827         b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
828         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
829
830     // public methods
831     this.hex = function (s) { 
832         return rstr2hex(rstr(s, utf8), hexcase); 
833     };
834     this.b64 = function (s) { 
835         return rstr2b64(rstr(s, utf8), b64pad);
836     };
837     this.any = function (s, e) { 
838         return rstr2any(rstr(s, utf8), e);
839     };
840     this.hex_hmac = function (k, d) {
841         return rstr2hex(rstr_hmac(k, d));
842     };
843     this.b64_hmac = function (k, d) { 
844         return rstr2b64(rstr_hmac(k, d), b64pad); 
845     };
846     this.any_hmac = function (k, d, e) { 
847         return rstr2any(rstr_hmac(k, d), e);
848     };
849     /**
850      * Perform a simple self-test to see if the VM is working
851      * @return {String} Hexadecimal hash sample
852      * @public
853      */
854     this.vm_test = function () {
855       return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
856     };
857     /** 
858      * @description Enable/disable uppercase hexadecimal returned string 
859      * @param {boolean} 
860      * @return {Object} this
861      * @public
862      */ 
863     this.setUpperCase = function (a) {
864         if (typeof a === 'boolean') {
865         hexcase = a;
866       }
867         return this;
868     };
869     /** 
870      * @description Defines a base64 pad string 
871      * @param {string} Pad
872      * @return {Object} this
873      * @public
874      */ 
875     this.setPad = function (a) {
876       b64pad = a || b64pad;
877         return this;
878     };
879     /** 
880      * @description Defines a base64 pad string 
881      * @param {boolean} 
882      * @return {Object} this
883      * @public
884      */ 
885     this.setUTF8 = function (a) {
886         if (typeof a === 'boolean') {
887         utf8 = a;
888       }
889         return this;
890     };
891
892     // private methods
893
894     /**
895          * Calculate the SHA-512 of a raw string
896          */
897         function rstr(s) {
898       s = (utf8) ? utf8Encode(s) : s;
899       return binb2rstr(binb(rstr2binb(s), s.length * 8));
900         }
901
902     /**
903      * Calculate the HMAC-SHA1 of a key and some data (raw strings)
904      */
905     function rstr_hmac(key, data) {
906         var bkey, ipad, opad, i, hash;
907         key = (utf8) ? utf8Encode(key) : key;
908         data = (utf8) ? utf8Encode(data) : data;
909         bkey = rstr2binb(key);
910
911         if (bkey.length > 16) {
912         bkey = binb(bkey, key.length * 8);
913       }
914         ipad = Array(16), opad = Array(16);
915         for (i = 0; i < 16; i+=1) {
916                 ipad[i] = bkey[i] ^ 0x36363636;
917                 opad[i] = bkey[i] ^ 0x5C5C5C5C;
918         }
919         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
920         return binb2rstr(binb(opad.concat(hash), 512 + 160));
921     }
922
923     /**
924      * Calculate the SHA-1 of an array of big-endian words, and a bit length
925      */
926     function binb(x, len) {
927       var i, j, t, olda, oldb, oldc, oldd, olde,
928           w = Array(80),
929           a =  1732584193,
930           b = -271733879,
931           c = -1732584194,
932           d =  271733878,
933           e = -1009589776;
934
935       /* append padding */
936       x[len >> 5] |= 0x80 << (24 - len % 32);
937       x[((len + 64 >> 9) << 4) + 15] = len;
938
939       for (i = 0; i < x.length; i += 16) {
940         olda = a,
941         oldb = b;
942         oldc = c;
943         oldd = d;
944         olde = e;
945       
946         for (j = 0; j < 80; j+=1)       {
947           if (j < 16) { 
948             w[j] = x[i + j]; 
949           } else { 
950             w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); 
951           }
952           t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
953                                            safe_add(safe_add(e, w[j]), sha1_kt(j)));
954           e = d;
955           d = c;
956           c = bit_rol(b, 30);
957           b = a;
958           a = t;
959         }
960
961         a = safe_add(a, olda);
962         b = safe_add(b, oldb);
963         c = safe_add(c, oldc);
964         d = safe_add(d, oldd);
965         e = safe_add(e, olde);
966       }
967       return Array(a, b, c, d, e);
968     }
969
970     /**
971      * Perform the appropriate triplet combination function for the current
972      * iteration
973      */
974     function sha1_ft(t, b, c, d) {
975       if (t < 20) { return (b & c) | ((~b) & d); }
976       if (t < 40) { return b ^ c ^ d; }
977       if (t < 60) { return (b & c) | (b & d) | (c & d); }
978       return b ^ c ^ d;
979     }
980
981     /**
982      * Determine the appropriate additive constant for the current iteration
983      */
984     function sha1_kt(t) {
985       return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
986                  (t < 60) ? -1894007588 : -899497514;
987     }
988   },
989   /**
990    * @class Hashes.SHA256
991    * @param {config}
992    * 
993    * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
994    * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
995    * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
996    * See http://pajhome.org.uk/crypt/md5 for details.
997    * Also http://anmar.eu.org/projects/jssha2/
998    */
999   SHA256 : function (options) {
1000     /**
1001      * Private properties configuration variables. You may need to tweak these to be compatible with
1002      * the server-side, but the defaults work in most cases.
1003      * @see this.setUpperCase() method
1004      * @see this.setPad() method
1005      */
1006     var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase  */
1007               b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', /* base-64 pad character. Default '=' for strict RFC compliance   */
1008               utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, /* enable/disable utf8 encoding */
1009               sha256_K;
1010
1011     /* privileged (public) methods */
1012     this.hex = function (s) { 
1013       return rstr2hex(rstr(s, utf8)); 
1014     };
1015     this.b64 = function (s) { 
1016       return rstr2b64(rstr(s, utf8), b64pad);
1017     };
1018     this.any = function (s, e) { 
1019       return rstr2any(rstr(s, utf8), e); 
1020     };
1021     this.hex_hmac = function (k, d) { 
1022       return rstr2hex(rstr_hmac(k, d)); 
1023     };
1024     this.b64_hmac = function (k, d) { 
1025       return rstr2b64(rstr_hmac(k, d), b64pad);
1026     };
1027     this.any_hmac = function (k, d, e) { 
1028       return rstr2any(rstr_hmac(k, d), e); 
1029     };
1030     /**
1031      * Perform a simple self-test to see if the VM is working
1032      * @return {String} Hexadecimal hash sample
1033      * @public
1034      */
1035     this.vm_test = function () {
1036       return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
1037     };
1038     /** 
1039      * Enable/disable uppercase hexadecimal returned string 
1040      * @param {boolean} 
1041      * @return {Object} this
1042      * @public
1043      */ 
1044     this.setUpperCase = function (a) {
1045       if (typeof a === 'boolean') { 
1046         hexcase = a;
1047       }
1048       return this;
1049     };
1050     /** 
1051      * @description Defines a base64 pad string 
1052      * @param {string} Pad
1053      * @return {Object} this
1054      * @public
1055      */ 
1056     this.setPad = function (a) {
1057       b64pad = a || b64pad;
1058       return this;
1059     };
1060     /** 
1061      * Defines a base64 pad string 
1062      * @param {boolean} 
1063      * @return {Object} this
1064      * @public
1065      */ 
1066     this.setUTF8 = function (a) {
1067       if (typeof a === 'boolean') {
1068         utf8 = a;
1069       }
1070       return this;
1071     };
1072     
1073     // private methods
1074
1075     /**
1076      * Calculate the SHA-512 of a raw string
1077      */
1078     function rstr(s, utf8) {
1079       s = (utf8) ? utf8Encode(s) : s;
1080       return binb2rstr(binb(rstr2binb(s), s.length * 8));
1081     }
1082
1083     /**
1084      * Calculate the HMAC-sha256 of a key and some data (raw strings)
1085      */
1086     function rstr_hmac(key, data) {
1087       key = (utf8) ? utf8Encode(key) : key;
1088       data = (utf8) ? utf8Encode(data) : data;
1089       var hash, i = 0,
1090           bkey = rstr2binb(key), 
1091           ipad = Array(16), 
1092           opad = Array(16);
1093
1094       if (bkey.length > 16) { bkey = binb(bkey, key.length * 8); }
1095       
1096       for (; i < 16; i+=1) {
1097         ipad[i] = bkey[i] ^ 0x36363636;
1098         opad[i] = bkey[i] ^ 0x5C5C5C5C;
1099       }
1100       
1101       hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
1102       return binb2rstr(binb(opad.concat(hash), 512 + 256));
1103     }
1104     
1105     /*
1106      * Main sha256 function, with its support functions
1107      */
1108     function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
1109     function sha256_R (X, n) {return ( X >>> n );}
1110     function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
1111     function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
1112     function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
1113     function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
1114     function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
1115     function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
1116     function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
1117     function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
1118     function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
1119     function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
1120     
1121     sha256_K = [
1122       1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
1123       -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
1124       1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
1125       264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
1126       -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
1127       113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
1128       1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
1129       -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
1130       430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
1131       1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
1132       -1866530822, -1538233109, -1090935817, -965641998
1133     ];
1134     
1135     function binb(m, l) {
1136       var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
1137                  1359893119, -1694144372, 528734635, 1541459225];
1138       var W = new Array(64);
1139       var a, b, c, d, e, f, g, h;
1140       var i, j, T1, T2;
1141     
1142       /* append padding */
1143       m[l >> 5] |= 0x80 << (24 - l % 32);
1144       m[((l + 64 >> 9) << 4) + 15] = l;
1145     
1146       for (i = 0; i < m.length; i += 16)
1147       {
1148       a = HASH[0];
1149       b = HASH[1];
1150       c = HASH[2];
1151       d = HASH[3];
1152       e = HASH[4];
1153       f = HASH[5];
1154       g = HASH[6];
1155       h = HASH[7];
1156     
1157       for (j = 0; j < 64; j+=1)
1158       {
1159         if (j < 16) { 
1160           W[j] = m[j + i];
1161         } else { 
1162           W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
1163                           sha256_Gamma0256(W[j - 15])), W[j - 16]);
1164         }
1165     
1166         T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
1167                                   sha256_K[j]), W[j]);
1168         T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
1169         h = g;
1170         g = f;
1171         f = e;
1172         e = safe_add(d, T1);
1173         d = c;
1174         c = b;
1175         b = a;
1176         a = safe_add(T1, T2);
1177       }
1178     
1179       HASH[0] = safe_add(a, HASH[0]);
1180       HASH[1] = safe_add(b, HASH[1]);
1181       HASH[2] = safe_add(c, HASH[2]);
1182       HASH[3] = safe_add(d, HASH[3]);
1183       HASH[4] = safe_add(e, HASH[4]);
1184       HASH[5] = safe_add(f, HASH[5]);
1185       HASH[6] = safe_add(g, HASH[6]);
1186       HASH[7] = safe_add(h, HASH[7]);
1187       }
1188       return HASH;
1189     }
1190
1191   },
1192
1193   /**
1194    * @class Hashes.SHA512
1195    * @param {config}
1196    * 
1197    * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
1198    * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
1199    * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
1200    * See http://pajhome.org.uk/crypt/md5 for details. 
1201    */
1202   SHA512 : function (options) {
1203     /**
1204      * Private properties configuration variables. You may need to tweak these to be compatible with
1205      * the server-side, but the defaults work in most cases.
1206      * @see this.setUpperCase() method
1207      * @see this.setPad() method
1208      */
1209     var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false , /* hexadecimal output case format. false - lowercase; true - uppercase  */
1210         b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',  /* base-64 pad character. Default '=' for strict RFC compliance   */
1211         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, /* enable/disable utf8 encoding */
1212         sha512_k;
1213
1214     /* privileged (public) methods */
1215     this.hex = function (s) { 
1216       return rstr2hex(rstr(s)); 
1217     };
1218     this.b64 = function (s) { 
1219       return rstr2b64(rstr(s), b64pad);  
1220     };
1221     this.any = function (s, e) { 
1222       return rstr2any(rstr(s), e);
1223     };
1224     this.hex_hmac = function (k, d) {
1225       return rstr2hex(rstr_hmac(k, d));
1226     };
1227     this.b64_hmac = function (k, d) { 
1228       return rstr2b64(rstr_hmac(k, d), b64pad);
1229     };
1230     this.any_hmac = function (k, d, e) { 
1231       return rstr2any(rstr_hmac(k, d), e);
1232     };
1233     /**
1234      * Perform a simple self-test to see if the VM is working
1235      * @return {String} Hexadecimal hash sample
1236      * @public
1237      */
1238     this.vm_test = function () {
1239       return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
1240     };
1241     /** 
1242      * @description Enable/disable uppercase hexadecimal returned string 
1243      * @param {boolean} 
1244      * @return {Object} this
1245      * @public
1246      */ 
1247     this.setUpperCase = function (a) {
1248       if (typeof a === 'boolean') {
1249         hexcase = a;
1250       }
1251       return this;
1252     };
1253     /** 
1254      * @description Defines a base64 pad string 
1255      * @param {string} Pad
1256      * @return {Object} this
1257      * @public
1258      */ 
1259     this.setPad = function (a) {
1260       b64pad = a || b64pad;
1261       return this;
1262     };
1263     /** 
1264      * @description Defines a base64 pad string 
1265      * @param {boolean} 
1266      * @return {Object} this
1267      * @public
1268      */ 
1269     this.setUTF8 = function (a) {
1270       if (typeof a === 'boolean') {
1271         utf8 = a;
1272       }
1273       return this;
1274     };
1275
1276     /* private methods */
1277     
1278     /**
1279      * Calculate the SHA-512 of a raw string
1280      */
1281     function rstr(s) {
1282       s = (utf8) ? utf8Encode(s) : s;
1283       return binb2rstr(binb(rstr2binb(s), s.length * 8));
1284     }
1285     /*
1286      * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
1287      */
1288     function rstr_hmac(key, data) {
1289       key = (utf8) ? utf8Encode(key) : key;
1290       data = (utf8) ? utf8Encode(data) : data;
1291       
1292       var hash, i = 0, 
1293           bkey = rstr2binb(key),
1294           ipad = Array(32), opad = Array(32);
1295
1296       if (bkey.length > 32) { bkey = binb(bkey, key.length * 8); }
1297       
1298       for (; i < 32; i+=1) {
1299         ipad[i] = bkey[i] ^ 0x36363636;
1300         opad[i] = bkey[i] ^ 0x5C5C5C5C;
1301       }
1302       
1303       hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
1304       return binb2rstr(binb(opad.concat(hash), 1024 + 512));
1305     }
1306             
1307     /**
1308      * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
1309      */
1310     function binb(x, len) {
1311       var j, i, l,
1312           W = new Array(80),
1313           hash = new Array(16),
1314           //Initial hash values
1315           H = [
1316             new int64(0x6a09e667, -205731576),
1317             new int64(-1150833019, -2067093701),
1318             new int64(0x3c6ef372, -23791573),
1319             new int64(-1521486534, 0x5f1d36f1),
1320             new int64(0x510e527f, -1377402159),
1321             new int64(-1694144372, 0x2b3e6c1f),
1322             new int64(0x1f83d9ab, -79577749),
1323             new int64(0x5be0cd19, 0x137e2179)
1324           ],
1325           T1 = new int64(0, 0),
1326           T2 = new int64(0, 0),
1327           a = new int64(0,0),
1328           b = new int64(0,0),
1329           c = new int64(0,0),
1330           d = new int64(0,0),
1331           e = new int64(0,0),
1332           f = new int64(0,0),
1333           g = new int64(0,0),
1334           h = new int64(0,0),
1335           //Temporary variables not specified by the document
1336           s0 = new int64(0, 0),
1337           s1 = new int64(0, 0),
1338           Ch = new int64(0, 0),
1339           Maj = new int64(0, 0),
1340           r1 = new int64(0, 0),
1341           r2 = new int64(0, 0),
1342           r3 = new int64(0, 0);
1343
1344       if (sha512_k === undefined) {
1345           //SHA512 constants
1346           sha512_k = [
1347             new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
1348             new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
1349             new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
1350             new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
1351             new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
1352             new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
1353             new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
1354             new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
1355             new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
1356             new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
1357             new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
1358             new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
1359             new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
1360             new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
1361             new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
1362             new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
1363             new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
1364             new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
1365             new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
1366             new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
1367             new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
1368             new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
1369             new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
1370             new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
1371             new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
1372             new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
1373             new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
1374             new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
1375             new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
1376             new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
1377             new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
1378             new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
1379             new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
1380             new int64(-354779690, -840897762), new int64(-176337025, -294727304),
1381             new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
1382             new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
1383             new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
1384             new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
1385             new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
1386             new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
1387           ];
1388       }
1389   
1390       for (i=0; i<80; i+=1) {
1391         W[i] = new int64(0, 0);
1392       }
1393     
1394       // append padding to the source string. The format is described in the FIPS.
1395       x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
1396       x[((len + 128 >> 10)<< 5) + 31] = len;
1397       l = x.length;
1398       for (i = 0; i<l; i+=32) { //32 dwords is the block size
1399         int64copy(a, H[0]);
1400         int64copy(b, H[1]);
1401         int64copy(c, H[2]);
1402         int64copy(d, H[3]);
1403         int64copy(e, H[4]);
1404         int64copy(f, H[5]);
1405         int64copy(g, H[6]);
1406         int64copy(h, H[7]);
1407       
1408         for (j=0; j<16; j+=1) {
1409           W[j].h = x[i + 2*j];
1410           W[j].l = x[i + 2*j + 1];
1411         }
1412       
1413         for (j=16; j<80; j+=1) {
1414           //sigma1
1415           int64rrot(r1, W[j-2], 19);
1416           int64revrrot(r2, W[j-2], 29);
1417           int64shr(r3, W[j-2], 6);
1418           s1.l = r1.l ^ r2.l ^ r3.l;
1419           s1.h = r1.h ^ r2.h ^ r3.h;
1420           //sigma0
1421           int64rrot(r1, W[j-15], 1);
1422           int64rrot(r2, W[j-15], 8);
1423           int64shr(r3, W[j-15], 7);
1424           s0.l = r1.l ^ r2.l ^ r3.l;
1425           s0.h = r1.h ^ r2.h ^ r3.h;
1426       
1427           int64add4(W[j], s1, W[j-7], s0, W[j-16]);
1428         }
1429       
1430         for (j = 0; j < 80; j+=1) {
1431           //Ch
1432           Ch.l = (e.l & f.l) ^ (~e.l & g.l);
1433           Ch.h = (e.h & f.h) ^ (~e.h & g.h);
1434       
1435           //Sigma1
1436           int64rrot(r1, e, 14);
1437           int64rrot(r2, e, 18);
1438           int64revrrot(r3, e, 9);
1439           s1.l = r1.l ^ r2.l ^ r3.l;
1440           s1.h = r1.h ^ r2.h ^ r3.h;
1441       
1442           //Sigma0
1443           int64rrot(r1, a, 28);
1444           int64revrrot(r2, a, 2);
1445           int64revrrot(r3, a, 7);
1446           s0.l = r1.l ^ r2.l ^ r3.l;
1447           s0.h = r1.h ^ r2.h ^ r3.h;
1448       
1449           //Maj
1450           Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
1451           Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
1452       
1453           int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
1454           int64add(T2, s0, Maj);
1455       
1456           int64copy(h, g);
1457           int64copy(g, f);
1458           int64copy(f, e);
1459           int64add(e, d, T1);
1460           int64copy(d, c);
1461           int64copy(c, b);
1462           int64copy(b, a);
1463           int64add(a, T1, T2);
1464         }
1465         int64add(H[0], H[0], a);
1466         int64add(H[1], H[1], b);
1467         int64add(H[2], H[2], c);
1468         int64add(H[3], H[3], d);
1469         int64add(H[4], H[4], e);
1470         int64add(H[5], H[5], f);
1471         int64add(H[6], H[6], g);
1472         int64add(H[7], H[7], h);
1473       }
1474     
1475       //represent the hash as an array of 32-bit dwords
1476       for (i=0; i<8; i+=1) {
1477         hash[2*i] = H[i].h;
1478         hash[2*i + 1] = H[i].l;
1479       }
1480       return hash;
1481     }
1482     
1483     //A constructor for 64-bit numbers
1484     function int64(h, l) {
1485       this.h = h;
1486       this.l = l;
1487       //this.toString = int64toString;
1488     }
1489     
1490     //Copies src into dst, assuming both are 64-bit numbers
1491     function int64copy(dst, src) {
1492       dst.h = src.h;
1493       dst.l = src.l;
1494     }
1495     
1496     //Right-rotates a 64-bit number by shift
1497     //Won't handle cases of shift>=32
1498     //The function revrrot() is for that
1499     function int64rrot(dst, x, shift) {
1500       dst.l = (x.l >>> shift) | (x.h << (32-shift));
1501       dst.h = (x.h >>> shift) | (x.l << (32-shift));
1502     }
1503     
1504     //Reverses the dwords of the source and then rotates right by shift.
1505     //This is equivalent to rotation by 32+shift
1506     function int64revrrot(dst, x, shift) {
1507       dst.l = (x.h >>> shift) | (x.l << (32-shift));
1508       dst.h = (x.l >>> shift) | (x.h << (32-shift));
1509     }
1510     
1511     //Bitwise-shifts right a 64-bit number by shift
1512     //Won't handle shift>=32, but it's never needed in SHA512
1513     function int64shr(dst, x, shift) {
1514       dst.l = (x.l >>> shift) | (x.h << (32-shift));
1515       dst.h = (x.h >>> shift);
1516     }
1517     
1518     //Adds two 64-bit numbers
1519     //Like the original implementation, does not rely on 32-bit operations
1520     function int64add(dst, x, y) {
1521        var w0 = (x.l & 0xffff) + (y.l & 0xffff);
1522        var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
1523        var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
1524        var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
1525        dst.l = (w0 & 0xffff) | (w1 << 16);
1526        dst.h = (w2 & 0xffff) | (w3 << 16);
1527     }
1528     
1529     //Same, except with 4 addends. Works faster than adding them one by one.
1530     function int64add4(dst, a, b, c, d) {
1531        var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
1532        var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
1533        var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
1534        var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
1535        dst.l = (w0 & 0xffff) | (w1 << 16);
1536        dst.h = (w2 & 0xffff) | (w3 << 16);
1537     }
1538     
1539     //Same, except with 5 addends
1540     function int64add5(dst, a, b, c, d, e) {
1541       var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
1542           w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
1543           w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
1544           w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
1545        dst.l = (w0 & 0xffff) | (w1 << 16);
1546        dst.h = (w2 & 0xffff) | (w3 << 16);
1547     }
1548   },
1549   /**
1550    * @class Hashes.RMD160
1551    * @constructor
1552    * @param {Object} [config]
1553    * 
1554    * A JavaScript implementation of the RIPEMD-160 Algorithm
1555    * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
1556    * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
1557    * See http://pajhome.org.uk/crypt/md5 for details.
1558    * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
1559    */
1560   RMD160 : function (options) {
1561     /**
1562      * Private properties configuration variables. You may need to tweak these to be compatible with
1563      * the server-side, but the defaults work in most cases.
1564      * @see this.setUpperCase() method
1565      * @see this.setPad() method
1566      */
1567     var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,   /* hexadecimal output case format. false - lowercase; true - uppercase  */
1568         b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',  /* base-64 pad character. Default '=' for strict RFC compliance   */
1569         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, /* enable/disable utf8 encoding */
1570         rmd160_r1 = [
1571            0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
1572            7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
1573            3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
1574            1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
1575            4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13
1576         ],
1577         rmd160_r2 = [
1578            5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
1579            6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
1580           15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
1581            8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
1582           12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11
1583         ],
1584         rmd160_s1 = [
1585           11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
1586            7,  6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
1587           11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
1588           11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
1589            9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6
1590         ],
1591         rmd160_s2 = [
1592            8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
1593            9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
1594            9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
1595           15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
1596            8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11
1597         ];
1598
1599     /* privileged (public) methods */
1600     this.hex = function (s) {
1601       return rstr2hex(rstr(s, utf8)); 
1602     };
1603     this.b64 = function (s) {
1604       return rstr2b64(rstr(s, utf8), b64pad);
1605     };
1606     this.any = function (s, e) { 
1607       return rstr2any(rstr(s, utf8), e);
1608     };
1609     this.hex_hmac = function (k, d) { 
1610       return rstr2hex(rstr_hmac(k, d));
1611     };
1612     this.b64_hmac = function (k, d) { 
1613       return rstr2b64(rstr_hmac(k, d), b64pad);
1614     };
1615     this.any_hmac = function (k, d, e) { 
1616       return rstr2any(rstr_hmac(k, d), e); 
1617     };
1618     /**
1619      * Perform a simple self-test to see if the VM is working
1620      * @return {String} Hexadecimal hash sample
1621      * @public
1622      */
1623     this.vm_test = function () {
1624       return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
1625     };
1626     /** 
1627      * @description Enable/disable uppercase hexadecimal returned string 
1628      * @param {boolean} 
1629      * @return {Object} this
1630      * @public
1631      */ 
1632     this.setUpperCase = function (a) {
1633       if (typeof a === 'boolean' ) { hexcase = a; }
1634       return this;
1635     };
1636     /** 
1637      * @description Defines a base64 pad string 
1638      * @param {string} Pad
1639      * @return {Object} this
1640      * @public
1641      */ 
1642     this.setPad = function (a) {
1643       if (typeof a !== 'undefined' ) { b64pad = a; }
1644       return this;
1645     };
1646     /** 
1647      * @description Defines a base64 pad string 
1648      * @param {boolean} 
1649      * @return {Object} this
1650      * @public
1651      */ 
1652     this.setUTF8 = function (a) {
1653       if (typeof a === 'boolean') { utf8 = a; }
1654       return this;
1655     };
1656
1657     /* private methods */
1658
1659     /**
1660      * Calculate the rmd160 of a raw string
1661      */
1662     function rstr(s) {
1663       s = (utf8) ? utf8Encode(s) : s;
1664       return binl2rstr(binl(rstr2binl(s), s.length * 8));
1665     }
1666
1667     /**
1668      * Calculate the HMAC-rmd160 of a key and some data (raw strings)
1669      */
1670     function rstr_hmac(key, data) {
1671       key = (utf8) ? utf8Encode(key) : key;
1672       data = (utf8) ? utf8Encode(data) : data;
1673       var i, hash,
1674           bkey = rstr2binl(key),
1675           ipad = Array(16), opad = Array(16);
1676
1677       if (bkey.length > 16) { 
1678         bkey = binl(bkey, key.length * 8); 
1679       }
1680       
1681       for (i = 0; i < 16; i+=1) {
1682         ipad[i] = bkey[i] ^ 0x36363636;
1683         opad[i] = bkey[i] ^ 0x5C5C5C5C;
1684       }
1685       hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
1686       return binl2rstr(binl(opad.concat(hash), 512 + 160));
1687     }
1688
1689     /**
1690      * Convert an array of little-endian words to a string
1691      */
1692     function binl2rstr(input) {
1693       var i, output = '', l = input.length * 32;
1694       for (i = 0; i < l; i += 8) {
1695         output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
1696       }
1697       return output;
1698     }
1699
1700     /**
1701      * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
1702      */
1703     function binl(x, len) {
1704       var T, j, i, l,
1705           h0 = 0x67452301,
1706           h1 = 0xefcdab89,
1707           h2 = 0x98badcfe,
1708           h3 = 0x10325476,
1709           h4 = 0xc3d2e1f0,
1710           A1, B1, C1, D1, E1,
1711           A2, B2, C2, D2, E2;
1712
1713       /* append padding */
1714       x[len >> 5] |= 0x80 << (len % 32);
1715       x[(((len + 64) >>> 9) << 4) + 14] = len;
1716       l = x.length;
1717       
1718       for (i = 0; i < l; i+=16) {
1719         A1 = A2 = h0; B1 = B2 = h1; C1 = C2 = h2; D1 = D2 = h3; E1 = E2 = h4;
1720         for (j = 0; j <= 79; j+=1) {
1721           T = safe_add(A1, rmd160_f(j, B1, C1, D1));
1722           T = safe_add(T, x[i + rmd160_r1[j]]);
1723           T = safe_add(T, rmd160_K1(j));
1724           T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
1725           A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T;
1726           T = safe_add(A2, rmd160_f(79-j, B2, C2, D2));
1727           T = safe_add(T, x[i + rmd160_r2[j]]);
1728           T = safe_add(T, rmd160_K2(j));
1729           T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
1730           A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T;
1731         }
1732
1733         T = safe_add(h1, safe_add(C1, D2));
1734         h1 = safe_add(h2, safe_add(D1, E2));
1735         h2 = safe_add(h3, safe_add(E1, A2));
1736         h3 = safe_add(h4, safe_add(A1, B2));
1737         h4 = safe_add(h0, safe_add(B1, C2));
1738         h0 = T;
1739       }
1740       return [h0, h1, h2, h3, h4];
1741     }
1742
1743     // specific algorithm methods 
1744     function rmd160_f(j, x, y, z) {
1745       return ( 0 <= j && j <= 15) ? (x ^ y ^ z) :
1746          (16 <= j && j <= 31) ? (x & y) | (~x & z) :
1747          (32 <= j && j <= 47) ? (x | ~y) ^ z :
1748          (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
1749          (64 <= j && j <= 79) ? x ^ (y | ~z) :
1750          'rmd160_f: j out of range';
1751     }
1752
1753     function rmd160_K1(j) {
1754       return ( 0 <= j && j <= 15) ? 0x00000000 :
1755          (16 <= j && j <= 31) ? 0x5a827999 :
1756          (32 <= j && j <= 47) ? 0x6ed9eba1 :
1757          (48 <= j && j <= 63) ? 0x8f1bbcdc :
1758          (64 <= j && j <= 79) ? 0xa953fd4e :
1759          'rmd160_K1: j out of range';
1760     }
1761
1762     function rmd160_K2(j){
1763       return ( 0 <= j && j <= 15) ? 0x50a28be6 :
1764          (16 <= j && j <= 31) ? 0x5c4dd124 :
1765          (32 <= j && j <= 47) ? 0x6d703ef3 :
1766          (48 <= j && j <= 63) ? 0x7a6d76e9 :
1767          (64 <= j && j <= 79) ? 0x00000000 :
1768          'rmd160_K2: j out of range';
1769     }
1770   }
1771 };
1772
1773   // exposes Hashes
1774   (function( window, undefined ) {
1775     var freeExports = false;
1776     if (typeof exports === 'object' ) {
1777       freeExports = exports;
1778       if (exports && typeof global === 'object' && global && global === global.global ) { window = global; }
1779     }
1780
1781     if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
1782       // define as an anonymous module, so, through path mapping, it can be aliased
1783       define(function () { return Hashes; });
1784     }
1785     else if ( freeExports ) {
1786       // in Node.js or RingoJS v0.8.0+
1787       if ( typeof module === 'object' && module && module.exports === freeExports ) {
1788         module.exports = Hashes;
1789       }
1790       // in Narwhal or RingoJS v0.7.0-
1791       else {
1792         freeExports.Hashes = Hashes;
1793       }
1794     }
1795     else {
1796       // in a browser or Rhino
1797       window.Hashes = Hashes;
1798     }
1799   }( this ));
1800 }()); // IIFE
1801 })(window)
1802 },{}]},{},[1])(1)
1803 });
1804 ;