@alexberardi/jarvis-admin 0.1.21 → 0.1.22

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