UNPKG

56.9 kBJavaScriptView Raw
1/*
2 Copyright (c) 2012 Nevins Bartolomeo <nevins.bartolomeo@gmail.com>
3 Copyright (c) 2012 Shane Girish <shaneGirish@gmail.com>
4 Copyright (c) 2014 Daniel Wirtz <dcode@dcode.io>
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. The name of the author may not be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @license bcrypt.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
31 * Released under the Apache License, Version 2.0
32 * see: https://github.com/dcodeIO/bcrypt.js for details
33 */
34(function(global, factory) {
35
36 /* AMD */ if (typeof define === 'function' && define["amd"])
37 define([], factory);
38 /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
39 module["exports"] = factory();
40 /* Global */ else
41 (global["dcodeIO"] = global["dcodeIO"] || {})["bcrypt"] = factory();
42
43}(this, function() {
44 "use strict";
45
46 /**
47 * bcrypt namespace.
48 * @type {Object.<string,*>}
49 */
50 var bcrypt = {};
51
52 /**
53 * The random implementation to use as a fallback.
54 * @type {?function(number):!Array.<number>}
55 * @inner
56 */
57 var randomFallback = null;
58
59 /**
60 * Generates cryptographically secure random bytes.
61 * @function
62 * @param {number} len Bytes length
63 * @returns {!Array.<number>} Random bytes
64 * @throws {Error} If no random implementation is available
65 * @inner
66 */
67 function random(len) {
68 /* node */ if (typeof module !== 'undefined' && module && module['exports'])
69 try {
70 return require("crypto")['randomBytes'](len);
71 } catch (e) {}
72 /* WCA */ try {
73 var a; (self['crypto']||self['msCrypto'])['getRandomValues'](a = new Uint32Array(len));
74 return Array.prototype.slice.call(a);
75 } catch (e) {}
76 /* fallback */ if (!randomFallback)
77 throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative");
78 return randomFallback(len);
79 }
80
81 // Test if any secure randomness source is available
82 var randomAvailable = false;
83 try {
84 random(1);
85 randomAvailable = true;
86 } catch (e) {}
87
88 // Default fallback, if any
89 randomFallback = null;
90 /**
91 * Sets the pseudo random number generator to use as a fallback if neither node's `crypto` module nor the Web Crypto
92 * API is available. Please note: It is highly important that the PRNG used is cryptographically secure and that it
93 * is seeded properly!
94 * @param {?function(number):!Array.<number>} random Function taking the number of bytes to generate as its
95 * sole argument, returning the corresponding array of cryptographically secure random byte values.
96 * @see http://nodejs.org/api/crypto.html
97 * @see http://www.w3.org/TR/WebCryptoAPI/
98 */
99 bcrypt.setRandomFallback = function(random) {
100 randomFallback = random;
101 };
102
103 /**
104 * Synchronously generates a salt.
105 * @param {number=} rounds Number of rounds to use, defaults to 10 if omitted
106 * @param {number=} seed_length Not supported.
107 * @returns {string} Resulting salt
108 * @throws {Error} If a random fallback is required but not set
109 * @expose
110 */
111 bcrypt.genSaltSync = function(rounds, seed_length) {
112 rounds = rounds || GENSALT_DEFAULT_LOG2_ROUNDS;
113 if (typeof rounds !== 'number')
114 throw Error("Illegal arguments: "+(typeof rounds)+", "+(typeof seed_length));
115 if (rounds < 4)
116 rounds = 4;
117 else if (rounds > 31)
118 rounds = 31;
119 var salt = [];
120 salt.push("$2a$");
121 if (rounds < 10)
122 salt.push("0");
123 salt.push(rounds.toString());
124 salt.push('$');
125 salt.push(base64_encode(random(BCRYPT_SALT_LEN), BCRYPT_SALT_LEN)); // May throw
126 return salt.join('');
127 };
128
129 /**
130 * Asynchronously generates a salt.
131 * @param {(number|function(Error, string=))=} rounds Number of rounds to use, defaults to 10 if omitted
132 * @param {(number|function(Error, string=))=} seed_length Not supported.
133 * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting salt
134 * @returns {!Promise} If `callback` has been omitted
135 * @throws {Error} If `callback` is present but not a function
136 * @expose
137 */
138 bcrypt.genSalt = function(rounds, seed_length, callback) {
139 if (typeof seed_length === 'function')
140 callback = seed_length,
141 seed_length = undefined; // Not supported.
142 if (typeof rounds === 'function')
143 callback = rounds,
144 rounds = undefined;
145 if (typeof rounds === 'undefined')
146 rounds = GENSALT_DEFAULT_LOG2_ROUNDS;
147 else if (typeof rounds !== 'number')
148 throw Error("illegal arguments: "+(typeof rounds));
149
150 function _async(callback) {
151 nextTick(function() { // Pretty thin, but salting is fast enough
152 try {
153 callback(null, bcrypt.genSaltSync(rounds));
154 } catch (err) {
155 callback(err);
156 }
157 });
158 }
159
160 if (callback) {
161 if (typeof callback !== 'function')
162 throw Error("Illegal callback: "+typeof(callback));
163 _async(callback);
164 } else
165 return new Promise(function(resolve, reject) {
166 _async(function(err, res) {
167 if (err) {
168 reject(err);
169 return;
170 }
171 resolve(res);
172 });
173 });
174 };
175
176 /**
177 * Synchronously generates a hash for the given string.
178 * @param {string} s String to hash
179 * @param {(number|string)=} salt Salt length to generate or salt to use, default to 10
180 * @returns {string} Resulting hash
181 * @expose
182 */
183 bcrypt.hashSync = function(s, salt) {
184 if (typeof salt === 'undefined')
185 salt = GENSALT_DEFAULT_LOG2_ROUNDS;
186 if (typeof salt === 'number')
187 salt = bcrypt.genSaltSync(salt);
188 if (typeof s !== 'string' || typeof salt !== 'string')
189 throw Error("Illegal arguments: "+(typeof s)+', '+(typeof salt));
190 return _hash(s, salt);
191 };
192
193 /**
194 * Asynchronously generates a hash for the given string.
195 * @param {string} s String to hash
196 * @param {number|string} salt Salt length to generate or salt to use
197 * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash
198 * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed
199 * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
200 * @returns {!Promise} If `callback` has been omitted
201 * @throws {Error} If `callback` is present but not a function
202 * @expose
203 */
204 bcrypt.hash = function(s, salt, callback, progressCallback) {
205
206 function _async(callback) {
207 if (typeof s === 'string' && typeof salt === 'number')
208 bcrypt.genSalt(salt, function(err, salt) {
209 _hash(s, salt, callback, progressCallback);
210 });
211 else if (typeof s === 'string' && typeof salt === 'string')
212 _hash(s, salt, callback, progressCallback);
213 else
214 nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof salt))));
215 }
216
217 if (callback) {
218 if (typeof callback !== 'function')
219 throw Error("Illegal callback: "+typeof(callback));
220 _async(callback);
221 } else
222 return new Promise(function(resolve, reject) {
223 _async(function(err, res) {
224 if (err) {
225 reject(err);
226 return;
227 }
228 resolve(res);
229 });
230 });
231 };
232
233 /**
234 * Compares two strings of the same length in constant time.
235 * @param {string} known Must be of the correct length
236 * @param {string} unknown Must be the same length as `known`
237 * @returns {boolean}
238 * @inner
239 */
240 function safeStringCompare(known, unknown) {
241 var right = 0,
242 wrong = 0;
243 for (var i=0, k=known.length; i<k; ++i) {
244 if (known.charCodeAt(i) === unknown.charCodeAt(i))
245 ++right;
246 else
247 ++wrong;
248 }
249 // Prevent removal of unused variables (never true, actually)
250 if (right < 0)
251 return false;
252 return wrong === 0;
253 }
254
255 /**
256 * Synchronously tests a string against a hash.
257 * @param {string} s String to compare
258 * @param {string} hash Hash to test against
259 * @returns {boolean} true if matching, otherwise false
260 * @throws {Error} If an argument is illegal
261 * @expose
262 */
263 bcrypt.compareSync = function(s, hash) {
264 if (typeof s !== "string" || typeof hash !== "string")
265 throw Error("Illegal arguments: "+(typeof s)+', '+(typeof hash));
266 if (hash.length !== 60)
267 return false;
268 return safeStringCompare(bcrypt.hashSync(s, hash.substr(0, hash.length-31)), hash);
269 };
270
271 /**
272 * Asynchronously compares the given data against the given hash.
273 * @param {string} s Data to compare
274 * @param {string} hash Data to be compared to
275 * @param {function(Error, boolean)=} callback Callback receiving the error, if any, otherwise the result
276 * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed
277 * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
278 * @returns {!Promise} If `callback` has been omitted
279 * @throws {Error} If `callback` is present but not a function
280 * @expose
281 */
282 bcrypt.compare = function(s, hash, callback, progressCallback) {
283
284 function _async(callback) {
285 if (typeof s !== "string" || typeof hash !== "string") {
286 nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof hash))));
287 return;
288 }
289 if (hash.length !== 60) {
290 nextTick(callback.bind(this, null, false));
291 return;
292 }
293 bcrypt.hash(s, hash.substr(0, 29), function(err, comp) {
294 if (err)
295 callback(err);
296 else
297 callback(null, safeStringCompare(comp, hash));
298 }, progressCallback);
299 }
300
301 if (callback) {
302 if (typeof callback !== 'function')
303 throw Error("Illegal callback: "+typeof(callback));
304 _async(callback);
305 } else
306 return new Promise(function(resolve, reject) {
307 _async(function(err, res) {
308 if (err) {
309 reject(err);
310 return;
311 }
312 resolve(res);
313 });
314 });
315 };
316
317 /**
318 * Gets the number of rounds used to encrypt the specified hash.
319 * @param {string} hash Hash to extract the used number of rounds from
320 * @returns {number} Number of rounds used
321 * @throws {Error} If `hash` is not a string
322 * @expose
323 */
324 bcrypt.getRounds = function(hash) {
325 if (typeof hash !== "string")
326 throw Error("Illegal arguments: "+(typeof hash));
327 return parseInt(hash.split("$")[2], 10);
328 };
329
330 /**
331 * Gets the salt portion from a hash. Does not validate the hash.
332 * @param {string} hash Hash to extract the salt from
333 * @returns {string} Extracted salt part
334 * @throws {Error} If `hash` is not a string or otherwise invalid
335 * @expose
336 */
337 bcrypt.getSalt = function(hash) {
338 if (typeof hash !== 'string')
339 throw Error("Illegal arguments: "+(typeof hash));
340 if (hash.length !== 60)
341 throw Error("Illegal hash length: "+hash.length+" != 60");
342 return hash.substring(0, 29);
343 };
344
345 /**
346 * Continues with the callback on the next tick.
347 * @function
348 * @param {function(...[*])} callback Callback to execute
349 * @inner
350 */
351 var nextTick = typeof process !== 'undefined' && process && typeof process.nextTick === 'function'
352 ? (typeof setImmediate === 'function' ? setImmediate : process.nextTick)
353 : setTimeout;
354
355 /**
356 * Converts a JavaScript string to UTF8 bytes.
357 * @param {string} str String
358 * @returns {!Array.<number>} UTF8 bytes
359 * @inner
360 */
361 function stringToBytes(str) {
362 var out = [],
363 i = 0;
364 utfx.encodeUTF16toUTF8(function() {
365 if (i >= str.length) return null;
366 return str.charCodeAt(i++);
367 }, function(b) {
368 out.push(b);
369 });
370 return out;
371 }
372
373 // A base64 implementation for the bcrypt algorithm. This is partly non-standard.
374
375 /**
376 * bcrypt's own non-standard base64 dictionary.
377 * @type {!Array.<string>}
378 * @const
379 * @inner
380 **/
381 var BASE64_CODE = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split('');
382
383 /**
384 * @type {!Array.<number>}
385 * @const
386 * @inner
387 **/
388 var BASE64_INDEX = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
389 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
390 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,
391 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1,
392 -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
393 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30,
394 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
395 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1];
396
397 /**
398 * @type {!function(...number):string}
399 * @inner
400 */
401 var stringFromCharCode = String.fromCharCode;
402
403 /**
404 * Encodes a byte array to base64 with up to len bytes of input.
405 * @param {!Array.<number>} b Byte array
406 * @param {number} len Maximum input length
407 * @returns {string}
408 * @inner
409 */
410 function base64_encode(b, len) {
411 var off = 0,
412 rs = [],
413 c1, c2;
414 if (len <= 0 || len > b.length)
415 throw Error("Illegal len: "+len);
416 while (off < len) {
417 c1 = b[off++] & 0xff;
418 rs.push(BASE64_CODE[(c1 >> 2) & 0x3f]);
419 c1 = (c1 & 0x03) << 4;
420 if (off >= len) {
421 rs.push(BASE64_CODE[c1 & 0x3f]);
422 break;
423 }
424 c2 = b[off++] & 0xff;
425 c1 |= (c2 >> 4) & 0x0f;
426 rs.push(BASE64_CODE[c1 & 0x3f]);
427 c1 = (c2 & 0x0f) << 2;
428 if (off >= len) {
429 rs.push(BASE64_CODE[c1 & 0x3f]);
430 break;
431 }
432 c2 = b[off++] & 0xff;
433 c1 |= (c2 >> 6) & 0x03;
434 rs.push(BASE64_CODE[c1 & 0x3f]);
435 rs.push(BASE64_CODE[c2 & 0x3f]);
436 }
437 return rs.join('');
438 }
439
440 /**
441 * Decodes a base64 encoded string to up to len bytes of output.
442 * @param {string} s String to decode
443 * @param {number} len Maximum output length
444 * @returns {!Array.<number>}
445 * @inner
446 */
447 function base64_decode(s, len) {
448 var off = 0,
449 slen = s.length,
450 olen = 0,
451 rs = [],
452 c1, c2, c3, c4, o, code;
453 if (len <= 0)
454 throw Error("Illegal len: "+len);
455 while (off < slen - 1 && olen < len) {
456 code = s.charCodeAt(off++);
457 c1 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
458 code = s.charCodeAt(off++);
459 c2 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
460 if (c1 == -1 || c2 == -1)
461 break;
462 o = (c1 << 2) >>> 0;
463 o |= (c2 & 0x30) >> 4;
464 rs.push(stringFromCharCode(o));
465 if (++olen >= len || off >= slen)
466 break;
467 code = s.charCodeAt(off++);
468 c3 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
469 if (c3 == -1)
470 break;
471 o = ((c2 & 0x0f) << 4) >>> 0;
472 o |= (c3 & 0x3c) >> 2;
473 rs.push(stringFromCharCode(o));
474 if (++olen >= len || off >= slen)
475 break;
476 code = s.charCodeAt(off++);
477 c4 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1;
478 o = ((c3 & 0x03) << 6) >>> 0;
479 o |= c4;
480 rs.push(stringFromCharCode(o));
481 ++olen;
482 }
483 var res = [];
484 for (off = 0; off<olen; off++)
485 res.push(rs[off].charCodeAt(0));
486 return res;
487 }
488
489 /**
490 * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
491 * Released under the Apache License, Version 2.0
492 * see: https://github.com/dcodeIO/utfx for details
493 */
494 var utfx = function() {
495 "use strict";
496
497 /**
498 * utfx namespace.
499 * @inner
500 * @type {!Object.<string,*>}
501 */
502 var utfx = {};
503
504 /**
505 * Maximum valid code point.
506 * @type {number}
507 * @const
508 */
509 utfx.MAX_CODEPOINT = 0x10FFFF;
510
511 /**
512 * Encodes UTF8 code points to UTF8 bytes.
513 * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
514 * respectively `null` if there are no more code points left or a single numeric code point.
515 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
516 */
517 utfx.encodeUTF8 = function(src, dst) {
518 var cp = null;
519 if (typeof src === 'number')
520 cp = src,
521 src = function() { return null; };
522 while (cp !== null || (cp = src()) !== null) {
523 if (cp < 0x80)
524 dst(cp&0x7F);
525 else if (cp < 0x800)
526 dst(((cp>>6)&0x1F)|0xC0),
527 dst((cp&0x3F)|0x80);
528 else if (cp < 0x10000)
529 dst(((cp>>12)&0x0F)|0xE0),
530 dst(((cp>>6)&0x3F)|0x80),
531 dst((cp&0x3F)|0x80);
532 else
533 dst(((cp>>18)&0x07)|0xF0),
534 dst(((cp>>12)&0x3F)|0x80),
535 dst(((cp>>6)&0x3F)|0x80),
536 dst((cp&0x3F)|0x80);
537 cp = null;
538 }
539 };
540
541 /**
542 * Decodes UTF8 bytes to UTF8 code points.
543 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
544 * are no more bytes left.
545 * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
546 * @throws {RangeError} If a starting byte is invalid in UTF8
547 * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
548 * remaining bytes.
549 */
550 utfx.decodeUTF8 = function(src, dst) {
551 var a, b, c, d, fail = function(b) {
552 b = b.slice(0, b.indexOf(null));
553 var err = Error(b.toString());
554 err.name = "TruncatedError";
555 err['bytes'] = b;
556 throw err;
557 };
558 while ((a = src()) !== null) {
559 if ((a&0x80) === 0)
560 dst(a);
561 else if ((a&0xE0) === 0xC0)
562 ((b = src()) === null) && fail([a, b]),
563 dst(((a&0x1F)<<6) | (b&0x3F));
564 else if ((a&0xF0) === 0xE0)
565 ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
566 dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
567 else if ((a&0xF8) === 0xF0)
568 ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
569 dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
570 else throw RangeError("Illegal starting byte: "+a);
571 }
572 };
573
574 /**
575 * Converts UTF16 characters to UTF8 code points.
576 * @param {!function():number|null} src Characters source as a function returning the next char code respectively
577 * `null` if there are no more characters left.
578 * @param {!function(number)} dst Code points destination as a function successively called with each converted code
579 * point.
580 */
581 utfx.UTF16toUTF8 = function(src, dst) {
582 var c1, c2 = null;
583 while (true) {
584 if ((c1 = c2 !== null ? c2 : src()) === null)
585 break;
586 if (c1 >= 0xD800 && c1 <= 0xDFFF) {
587 if ((c2 = src()) !== null) {
588 if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
589 dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
590 c2 = null; continue;
591 }
592 }
593 }
594 dst(c1);
595 }
596 if (c2 !== null) dst(c2);
597 };
598
599 /**
600 * Converts UTF8 code points to UTF16 characters.
601 * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
602 * respectively `null` if there are no more code points left or a single numeric code point.
603 * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
604 * @throws {RangeError} If a code point is out of range
605 */
606 utfx.UTF8toUTF16 = function(src, dst) {
607 var cp = null;
608 if (typeof src === 'number')
609 cp = src, src = function() { return null; };
610 while (cp !== null || (cp = src()) !== null) {
611 if (cp <= 0xFFFF)
612 dst(cp);
613 else
614 cp -= 0x10000,
615 dst((cp>>10)+0xD800),
616 dst((cp%0x400)+0xDC00);
617 cp = null;
618 }
619 };
620
621 /**
622 * Converts and encodes UTF16 characters to UTF8 bytes.
623 * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
624 * if there are no more characters left.
625 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
626 */
627 utfx.encodeUTF16toUTF8 = function(src, dst) {
628 utfx.UTF16toUTF8(src, function(cp) {
629 utfx.encodeUTF8(cp, dst);
630 });
631 };
632
633 /**
634 * Decodes and converts UTF8 bytes to UTF16 characters.
635 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
636 * are no more bytes left.
637 * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
638 * @throws {RangeError} If a starting byte is invalid in UTF8
639 * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
640 */
641 utfx.decodeUTF8toUTF16 = function(src, dst) {
642 utfx.decodeUTF8(src, function(cp) {
643 utfx.UTF8toUTF16(cp, dst);
644 });
645 };
646
647 /**
648 * Calculates the byte length of an UTF8 code point.
649 * @param {number} cp UTF8 code point
650 * @returns {number} Byte length
651 */
652 utfx.calculateCodePoint = function(cp) {
653 return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
654 };
655
656 /**
657 * Calculates the number of UTF8 bytes required to store UTF8 code points.
658 * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
659 * `null` if there are no more code points left.
660 * @returns {number} The number of UTF8 bytes required
661 */
662 utfx.calculateUTF8 = function(src) {
663 var cp, l=0;
664 while ((cp = src()) !== null)
665 l += utfx.calculateCodePoint(cp);
666 return l;
667 };
668
669 /**
670 * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
671 * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
672 * `null` if there are no more characters left.
673 * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
674 */
675 utfx.calculateUTF16asUTF8 = function(src) {
676 var n=0, l=0;
677 utfx.UTF16toUTF8(src, function(cp) {
678 ++n; l += utfx.calculateCodePoint(cp);
679 });
680 return [n,l];
681 };
682
683 return utfx;
684 }();
685
686 Date.now = Date.now || function() { return +new Date; };
687
688 /**
689 * @type {number}
690 * @const
691 * @inner
692 */
693 var BCRYPT_SALT_LEN = 16;
694
695 /**
696 * @type {number}
697 * @const
698 * @inner
699 */
700 var GENSALT_DEFAULT_LOG2_ROUNDS = 10;
701
702 /**
703 * @type {number}
704 * @const
705 * @inner
706 */
707 var BLOWFISH_NUM_ROUNDS = 16;
708
709 /**
710 * @type {number}
711 * @const
712 * @inner
713 */
714 var MAX_EXECUTION_TIME = 100;
715
716 /**
717 * @type {Array.<number>}
718 * @const
719 * @inner
720 */
721 var P_ORIG = [
722 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822,
723 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377,
724 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5,
725 0xb5470917, 0x9216d5d9, 0x8979fb1b
726 ];
727
728 /**
729 * @type {Array.<number>}
730 * @const
731 * @inner
732 */
733 var S_ORIG = [
734 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed,
735 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7,
736 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3,
737 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
738 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023,
739 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
740 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda,
741 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
742 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af,
743 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6,
744 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381,
745 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
746 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d,
747 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5,
748 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a,
749 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
750 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c,
751 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
752 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3,
753 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
754 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724,
755 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b,
756 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd,
757 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
758 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f,
759 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd,
760 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39,
761 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
762 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df,
763 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
764 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e,
765 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
766 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98,
767 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565,
768 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341,
769 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
770 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0,
771 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64,
772 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191,
773 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
774 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0,
775 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
776 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5,
777 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
778 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b,
779 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f,
780 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968,
781 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
782 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5,
783 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6,
784 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799,
785 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
786 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71,
787 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29,
788 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6,
789 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
790 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f,
791 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286,
792 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec,
793 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
794 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9,
795 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
796 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e,
797 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
798 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290,
799 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810,
800 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6,
801 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
802 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847,
803 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451,
804 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6,
805 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
806 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570,
807 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
808 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978,
809 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
810 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708,
811 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883,
812 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185,
813 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
814 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830,
815 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239,
816 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab,
817 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
818 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19,
819 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
820 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1,
821 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
822 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef,
823 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3,
824 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15,
825 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
826 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2,
827 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492,
828 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174,
829 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
830 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759,
831 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
832 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc,
833 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
834 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465,
835 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a,
836 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c,
837 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
838 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e,
839 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
840 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0,
841 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
842 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462,
843 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c,
844 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399,
845 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
846 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74,
847 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397,
848 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7,
849 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
850 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802,
851 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
852 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4,
853 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
854 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2,
855 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1,
856 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c,
857 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
858 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341,
859 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8,
860 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b,
861 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
862 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88,
863 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
864 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc,
865 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
866 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659,
867 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f,
868 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8,
869 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
870 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be,
871 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2,
872 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255,
873 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
874 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1,
875 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
876 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025,
877 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
878 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01,
879 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641,
880 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa,
881 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
882 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409,
883 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9,
884 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3,
885 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
886 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234,
887 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf,
888 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740,
889 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
890 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f,
891 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d,
892 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8,
893 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
894 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba,
895 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
896 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69,
897 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
898 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a,
899 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b,
900 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd,
901 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
902 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4,
903 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2,
904 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb,
905 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
906 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751,
907 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
908 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369,
909 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
910 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd,
911 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45,
912 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae,
913 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
914 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08,
915 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d,
916 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b,
917 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
918 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e,
919 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
920 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c,
921 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
922 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361,
923 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c,
924 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be,
925 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
926 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d,
927 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891,
928 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5,
929 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
930 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292,
931 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
932 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2,
933 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
934 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c,
935 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8,
936 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4,
937 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
938 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
939 ];
940
941 /**
942 * @type {Array.<number>}
943 * @const
944 * @inner
945 */
946 var C_ORIG = [
947 0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944,
948 0x6f756274
949 ];
950
951 /**
952 * @param {Array.<number>} lr
953 * @param {number} off
954 * @param {Array.<number>} P
955 * @param {Array.<number>} S
956 * @returns {Array.<number>}
957 * @inner
958 */
959 function _encipher(lr, off, P, S) { // This is our bottleneck: 1714/1905 ticks / 90% - see profile.txt
960 var n,
961 l = lr[off],
962 r = lr[off + 1];
963
964 l ^= P[0];
965
966 /*
967 for (var i=0, k=BLOWFISH_NUM_ROUNDS-2; i<=k;)
968 // Feistel substitution on left word
969 n = S[l >>> 24],
970 n += S[0x100 | ((l >> 16) & 0xff)],
971 n ^= S[0x200 | ((l >> 8) & 0xff)],
972 n += S[0x300 | (l & 0xff)],
973 r ^= n ^ P[++i],
974 // Feistel substitution on right word
975 n = S[r >>> 24],
976 n += S[0x100 | ((r >> 16) & 0xff)],
977 n ^= S[0x200 | ((r >> 8) & 0xff)],
978 n += S[0x300 | (r & 0xff)],
979 l ^= n ^ P[++i];
980 */
981
982 //The following is an unrolled version of the above loop.
983 //Iteration 0
984 n = S[l >>> 24];
985 n += S[0x100 | ((l >> 16) & 0xff)];
986 n ^= S[0x200 | ((l >> 8) & 0xff)];
987 n += S[0x300 | (l & 0xff)];
988 r ^= n ^ P[1];
989 n = S[r >>> 24];
990 n += S[0x100 | ((r >> 16) & 0xff)];
991 n ^= S[0x200 | ((r >> 8) & 0xff)];
992 n += S[0x300 | (r & 0xff)];
993 l ^= n ^ P[2];
994 //Iteration 1
995 n = S[l >>> 24];
996 n += S[0x100 | ((l >> 16) & 0xff)];
997 n ^= S[0x200 | ((l >> 8) & 0xff)];
998 n += S[0x300 | (l & 0xff)];
999 r ^= n ^ P[3];
1000 n = S[r >>> 24];
1001 n += S[0x100 | ((r >> 16) & 0xff)];
1002 n ^= S[0x200 | ((r >> 8) & 0xff)];
1003 n += S[0x300 | (r & 0xff)];
1004 l ^= n ^ P[4];
1005 //Iteration 2
1006 n = S[l >>> 24];
1007 n += S[0x100 | ((l >> 16) & 0xff)];
1008 n ^= S[0x200 | ((l >> 8) & 0xff)];
1009 n += S[0x300 | (l & 0xff)];
1010 r ^= n ^ P[5];
1011 n = S[r >>> 24];
1012 n += S[0x100 | ((r >> 16) & 0xff)];
1013 n ^= S[0x200 | ((r >> 8) & 0xff)];
1014 n += S[0x300 | (r & 0xff)];
1015 l ^= n ^ P[6];
1016 //Iteration 3
1017 n = S[l >>> 24];
1018 n += S[0x100 | ((l >> 16) & 0xff)];
1019 n ^= S[0x200 | ((l >> 8) & 0xff)];
1020 n += S[0x300 | (l & 0xff)];
1021 r ^= n ^ P[7];
1022 n = S[r >>> 24];
1023 n += S[0x100 | ((r >> 16) & 0xff)];
1024 n ^= S[0x200 | ((r >> 8) & 0xff)];
1025 n += S[0x300 | (r & 0xff)];
1026 l ^= n ^ P[8];
1027 //Iteration 4
1028 n = S[l >>> 24];
1029 n += S[0x100 | ((l >> 16) & 0xff)];
1030 n ^= S[0x200 | ((l >> 8) & 0xff)];
1031 n += S[0x300 | (l & 0xff)];
1032 r ^= n ^ P[9];
1033 n = S[r >>> 24];
1034 n += S[0x100 | ((r >> 16) & 0xff)];
1035 n ^= S[0x200 | ((r >> 8) & 0xff)];
1036 n += S[0x300 | (r & 0xff)];
1037 l ^= n ^ P[10];
1038 //Iteration 5
1039 n = S[l >>> 24];
1040 n += S[0x100 | ((l >> 16) & 0xff)];
1041 n ^= S[0x200 | ((l >> 8) & 0xff)];
1042 n += S[0x300 | (l & 0xff)];
1043 r ^= n ^ P[11];
1044 n = S[r >>> 24];
1045 n += S[0x100 | ((r >> 16) & 0xff)];
1046 n ^= S[0x200 | ((r >> 8) & 0xff)];
1047 n += S[0x300 | (r & 0xff)];
1048 l ^= n ^ P[12];
1049 //Iteration 6
1050 n = S[l >>> 24];
1051 n += S[0x100 | ((l >> 16) & 0xff)];
1052 n ^= S[0x200 | ((l >> 8) & 0xff)];
1053 n += S[0x300 | (l & 0xff)];
1054 r ^= n ^ P[13];
1055 n = S[r >>> 24];
1056 n += S[0x100 | ((r >> 16) & 0xff)];
1057 n ^= S[0x200 | ((r >> 8) & 0xff)];
1058 n += S[0x300 | (r & 0xff)];
1059 l ^= n ^ P[14];
1060 //Iteration 7
1061 n = S[l >>> 24];
1062 n += S[0x100 | ((l >> 16) & 0xff)];
1063 n ^= S[0x200 | ((l >> 8) & 0xff)];
1064 n += S[0x300 | (l & 0xff)];
1065 r ^= n ^ P[15];
1066 n = S[r >>> 24];
1067 n += S[0x100 | ((r >> 16) & 0xff)];
1068 n ^= S[0x200 | ((r >> 8) & 0xff)];
1069 n += S[0x300 | (r & 0xff)];
1070 l ^= n ^ P[16];
1071
1072 lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
1073 lr[off + 1] = l;
1074 return lr;
1075 }
1076
1077 /**
1078 * @param {Array.<number>} data
1079 * @param {number} offp
1080 * @returns {{key: number, offp: number}}
1081 * @inner
1082 */
1083 function _streamtoword(data, offp) {
1084 for (var i = 0, word = 0; i < 4; ++i)
1085 word = (word << 8) | (data[offp] & 0xff),
1086 offp = (offp + 1) % data.length;
1087 return { key: word, offp: offp };
1088 }
1089
1090 /**
1091 * @param {Array.<number>} key
1092 * @param {Array.<number>} P
1093 * @param {Array.<number>} S
1094 * @inner
1095 */
1096 function _key(key, P, S) {
1097 var offset = 0,
1098 lr = [0, 0],
1099 plen = P.length,
1100 slen = S.length,
1101 sw;
1102 for (var i = 0; i < plen; i++)
1103 sw = _streamtoword(key, offset),
1104 offset = sw.offp,
1105 P[i] = P[i] ^ sw.key;
1106 for (i = 0; i < plen; i += 2)
1107 lr = _encipher(lr, 0, P, S),
1108 P[i] = lr[0],
1109 P[i + 1] = lr[1];
1110 for (i = 0; i < slen; i += 2)
1111 lr = _encipher(lr, 0, P, S),
1112 S[i] = lr[0],
1113 S[i + 1] = lr[1];
1114 }
1115
1116 /**
1117 * Expensive key schedule Blowfish.
1118 * @param {Array.<number>} data
1119 * @param {Array.<number>} key
1120 * @param {Array.<number>} P
1121 * @param {Array.<number>} S
1122 * @inner
1123 */
1124 function _ekskey(data, key, P, S) {
1125 var offp = 0,
1126 lr = [0, 0],
1127 plen = P.length,
1128 slen = S.length,
1129 sw;
1130 for (var i = 0; i < plen; i++)
1131 sw = _streamtoword(key, offp),
1132 offp = sw.offp,
1133 P[i] = P[i] ^ sw.key;
1134 offp = 0;
1135 for (i = 0; i < plen; i += 2)
1136 sw = _streamtoword(data, offp),
1137 offp = sw.offp,
1138 lr[0] ^= sw.key,
1139 sw = _streamtoword(data, offp),
1140 offp = sw.offp,
1141 lr[1] ^= sw.key,
1142 lr = _encipher(lr, 0, P, S),
1143 P[i] = lr[0],
1144 P[i + 1] = lr[1];
1145 for (i = 0; i < slen; i += 2)
1146 sw = _streamtoword(data, offp),
1147 offp = sw.offp,
1148 lr[0] ^= sw.key,
1149 sw = _streamtoword(data, offp),
1150 offp = sw.offp,
1151 lr[1] ^= sw.key,
1152 lr = _encipher(lr, 0, P, S),
1153 S[i] = lr[0],
1154 S[i + 1] = lr[1];
1155 }
1156
1157 /**
1158 * Internaly crypts a string.
1159 * @param {Array.<number>} b Bytes to crypt
1160 * @param {Array.<number>} salt Salt bytes to use
1161 * @param {number} rounds Number of rounds
1162 * @param {function(Error, Array.<number>=)=} callback Callback receiving the error, if any, and the resulting bytes. If
1163 * omitted, the operation will be performed synchronously.
1164 * @param {function(number)=} progressCallback Callback called with the current progress
1165 * @returns {!Array.<number>|undefined} Resulting bytes if callback has been omitted, otherwise `undefined`
1166 * @inner
1167 */
1168 function _crypt(b, salt, rounds, callback, progressCallback) {
1169 var cdata = C_ORIG.slice(),
1170 clen = cdata.length,
1171 err;
1172
1173 // Validate
1174 if (rounds < 4 || rounds > 31) {
1175 err = Error("Illegal number of rounds (4-31): "+rounds);
1176 if (callback) {
1177 nextTick(callback.bind(this, err));
1178 return;
1179 } else
1180 throw err;
1181 }
1182 if (salt.length !== BCRYPT_SALT_LEN) {
1183 err =Error("Illegal salt length: "+salt.length+" != "+BCRYPT_SALT_LEN);
1184 if (callback) {
1185 nextTick(callback.bind(this, err));
1186 return;
1187 } else
1188 throw err;
1189 }
1190 rounds = (1 << rounds) >>> 0;
1191
1192 var P, S, i = 0, j;
1193
1194 //Use typed arrays when available - huge speedup!
1195 if (Int32Array) {
1196 P = new Int32Array(P_ORIG);
1197 S = new Int32Array(S_ORIG);
1198 } else {
1199 P = P_ORIG.slice();
1200 S = S_ORIG.slice();
1201 }
1202
1203 _ekskey(salt, b, P, S);
1204
1205 /**
1206 * Calcualtes the next round.
1207 * @returns {Array.<number>|undefined} Resulting array if callback has been omitted, otherwise `undefined`
1208 * @inner
1209 */
1210 function next() {
1211 if (progressCallback)
1212 progressCallback(i / rounds);
1213 if (i < rounds) {
1214 var start = Date.now();
1215 for (; i < rounds;) {
1216 i = i + 1;
1217 _key(b, P, S);
1218 _key(salt, P, S);
1219 if (Date.now() - start > MAX_EXECUTION_TIME)
1220 break;
1221 }
1222 } else {
1223 for (i = 0; i < 64; i++)
1224 for (j = 0; j < (clen >> 1); j++)
1225 _encipher(cdata, j << 1, P, S);
1226 var ret = [];
1227 for (i = 0; i < clen; i++)
1228 ret.push(((cdata[i] >> 24) & 0xff) >>> 0),
1229 ret.push(((cdata[i] >> 16) & 0xff) >>> 0),
1230 ret.push(((cdata[i] >> 8) & 0xff) >>> 0),
1231 ret.push((cdata[i] & 0xff) >>> 0);
1232 if (callback) {
1233 callback(null, ret);
1234 return;
1235 } else
1236 return ret;
1237 }
1238 if (callback)
1239 nextTick(next);
1240 }
1241
1242 // Async
1243 if (typeof callback !== 'undefined') {
1244 next();
1245
1246 // Sync
1247 } else {
1248 var res;
1249 while (true)
1250 if (typeof(res = next()) !== 'undefined')
1251 return res || [];
1252 }
1253 }
1254
1255 /**
1256 * Internally hashes a string.
1257 * @param {string} s String to hash
1258 * @param {?string} salt Salt to use, actually never null
1259 * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash. If omitted,
1260 * hashing is perormed synchronously.
1261 * @param {function(number)=} progressCallback Callback called with the current progress
1262 * @returns {string|undefined} Resulting hash if callback has been omitted, otherwise `undefined`
1263 * @inner
1264 */
1265 function _hash(s, salt, callback, progressCallback) {
1266 var err;
1267 if (typeof s !== 'string' || typeof salt !== 'string') {
1268 err = Error("Invalid string / salt: Not a string");
1269 if (callback) {
1270 nextTick(callback.bind(this, err));
1271 return;
1272 }
1273 else
1274 throw err;
1275 }
1276
1277 // Validate the salt
1278 var minor, offset;
1279 if (salt.charAt(0) !== '$' || salt.charAt(1) !== '2') {
1280 err = Error("Invalid salt version: "+salt.substring(0,2));
1281 if (callback) {
1282 nextTick(callback.bind(this, err));
1283 return;
1284 }
1285 else
1286 throw err;
1287 }
1288 if (salt.charAt(2) === '$')
1289 minor = String.fromCharCode(0),
1290 offset = 3;
1291 else {
1292 minor = salt.charAt(2);
1293 if ((minor !== 'a' && minor !== 'b' && minor !== 'y') || salt.charAt(3) !== '$') {
1294 err = Error("Invalid salt revision: "+salt.substring(2,4));
1295 if (callback) {
1296 nextTick(callback.bind(this, err));
1297 return;
1298 } else
1299 throw err;
1300 }
1301 offset = 4;
1302 }
1303
1304 // Extract number of rounds
1305 if (salt.charAt(offset + 2) > '$') {
1306 err = Error("Missing salt rounds");
1307 if (callback) {
1308 nextTick(callback.bind(this, err));
1309 return;
1310 } else
1311 throw err;
1312 }
1313 var r1 = parseInt(salt.substring(offset, offset + 1), 10) * 10,
1314 r2 = parseInt(salt.substring(offset + 1, offset + 2), 10),
1315 rounds = r1 + r2,
1316 real_salt = salt.substring(offset + 3, offset + 25);
1317 s += minor >= 'a' ? "\x00" : "";
1318
1319 var passwordb = stringToBytes(s),
1320 saltb = base64_decode(real_salt, BCRYPT_SALT_LEN);
1321
1322 /**
1323 * Finishes hashing.
1324 * @param {Array.<number>} bytes Byte array
1325 * @returns {string}
1326 * @inner
1327 */
1328 function finish(bytes) {
1329 var res = [];
1330 res.push("$2");
1331 if (minor >= 'a')
1332 res.push(minor);
1333 res.push("$");
1334 if (rounds < 10)
1335 res.push("0");
1336 res.push(rounds.toString());
1337 res.push("$");
1338 res.push(base64_encode(saltb, saltb.length));
1339 res.push(base64_encode(bytes, C_ORIG.length * 4 - 1));
1340 return res.join('');
1341 }
1342
1343 // Sync
1344 if (typeof callback == 'undefined')
1345 return finish(_crypt(passwordb, saltb, rounds));
1346
1347 // Async
1348 else {
1349 _crypt(passwordb, saltb, rounds, function(err, bytes) {
1350 if (err)
1351 callback(err, null);
1352 else
1353 callback(null, finish(bytes));
1354 }, progressCallback);
1355 }
1356 }
1357
1358 /**
1359 * Encodes a byte array to base64 with up to len bytes of input, using the custom bcrypt alphabet.
1360 * @function
1361 * @param {!Array.<number>} b Byte array
1362 * @param {number} len Maximum input length
1363 * @returns {string}
1364 * @expose
1365 */
1366 bcrypt.encodeBase64 = base64_encode;
1367
1368 /**
1369 * Decodes a base64 encoded string to up to len bytes of output, using the custom bcrypt alphabet.
1370 * @function
1371 * @param {string} s String to decode
1372 * @param {number} len Maximum output length
1373 * @returns {!Array.<number>}
1374 * @expose
1375 */
1376 bcrypt.decodeBase64 = base64_decode;
1377
1378 return bcrypt;
1379}));