index.js 41 KB

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