├── bcrypt.png ├── donate.png ├── .gitignore ├── .npmignore ├── dist ├── bcrypt.min.js.gz ├── README.md ├── bcrypt.min.js ├── bcrypt.min.map └── bcrypt.js ├── .travis.yml ├── src ├── bcrypt │ ├── prng │ │ ├── README.md │ │ ├── accum.js │ │ └── isaac.js │ ├── util.js │ ├── util │ │ └── base64.js │ └── impl.js ├── bower.json └── bcrypt.js ├── bower.json ├── bin └── bcrypt ├── scripts └── build.js ├── index.js ├── externs ├── minimal-env.js └── bcrypt.js ├── tests ├── bench.js ├── quickbrown.txt └── suite.js ├── package.json ├── LICENSE └── README.md /bcrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no-problemo/bcrypt.js/master/bcrypt.png -------------------------------------------------------------------------------- /donate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no-problemo/bcrypt.js/master/donate.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | .idea/ 4 | doco/ 5 | src/bcrypt.c 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | .idea/ 4 | doco/ 5 | tests/bench.js 6 | *.png 7 | -------------------------------------------------------------------------------- /dist/bcrypt.min.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no-problemo/bcrypt.js/master/dist/bcrypt.min.js.gz -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.8 4 | - 0.10 5 | before_script: npm -g install testjs 6 | -------------------------------------------------------------------------------- /src/bcrypt/prng/README.md: -------------------------------------------------------------------------------- 1 | Because of [reasonable security doubts](https://github.com/dcodeIO/bcrypt.js/issues/16), these files, which used to be 2 | a part of bcrypt-isaac.js, are no longer used but are kept here for reference only. 3 | 4 | What is required instead is a proper way to collect entropy sources (using an intermediate stream cipher) which is then 5 | used to seed the CSPRNG. Pick one and use `bcrypt.setRandomFallback` instead. 6 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bcryptjs", 3 | "description": "Optimized bcrypt in plain JavaScript with zero dependencies.", 4 | "version": "2.1.0", 5 | "main": "dist/bcrypt-isaac.js", 6 | "license": "New-BSD", 7 | "homepage": "http://dcode.io/", 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/dcodeIO/bcrypt.js.git" 11 | }, 12 | "keywords": ["bcrypt", "password", "auth", "authentication", "encryption", "crypt", "crypto"], 13 | "dependencies": {}, 14 | "devDependencies": {}, 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bcryptjs", 3 | "description": "Optimized bcrypt in plain JavaScript with zero dependencies.", 4 | "version": /*?== VERSION */, 5 | "main": "dist/bcrypt-isaac.js", 6 | "license": "New-BSD", 7 | "homepage": "http://dcode.io/", 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/dcodeIO/bcrypt.js.git" 11 | }, 12 | "keywords": ["bcrypt", "password", "auth", "authentication", "encryption", "crypt", "crypto"], 13 | "dependencies": {}, 14 | "devDependencies": {}, 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dist/README.md: -------------------------------------------------------------------------------- 1 | Distributions 2 | ============= 3 | bcrypt.js is available as the following distributions: 4 | 5 | * **[bcrypt.js](https://github.com/dcodeIO/bcrypt.js/blob/master/dist/bcrypt.js)** 6 | contains the commented source code. 7 | 8 | * **[bcrypt.min.js](https://github.com/dcodeIO/bcrypt.js/blob/master/dist/bcrypt.min.js)** 9 | has been compiled with Closure Compiler using advanced optimizations. 10 | 11 | * **[bcrypt.min.map](https://github.com/dcodeIO/bcrypt.js/blob/master/dist/bcrypt.min.map)** 12 | contains the source map generated by Closure Compiler. 13 | 14 | * **[bcrypt.min.js.gz](https://github.com/dcodeIO/bcrypt.js/blob/master/dist/bcrypt.min.js.gz)** 15 | has also been gzipped using `-9`. 16 | -------------------------------------------------------------------------------- /bin/bcrypt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var path = require("path"), 4 | bcrypt = require(path.join(__dirname, '..', 'index.js')), 5 | pkg = require(path.join(__dirname, '..', 'package.json')); 6 | 7 | if (process.argv.length < 3) { 8 | process.stderr.write([ // No dependencies, so we do it from hand. 9 | "", 10 | " |_ _ _ _ |_", 11 | " |_)(_| \\/|_)|_ v"+pkg['version']+" (c) "+pkg['author'], 12 | " / | " 13 | ].join('\n')+'\n\n'+" Usage: "+path.basename(process.argv[1])+" [salt]\n"); 14 | process.exit(1); 15 | } else { 16 | process.stdout.write(bcrypt.hashSync(process.argv[2], process.argv.length > 3 ? process.argv[3] : bcrypt.genSaltSync())+"\n"); 17 | } 18 | -------------------------------------------------------------------------------- /src/bcrypt/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Continues with the callback on the next tick. 3 | * @function 4 | * @param {function(...[*])} callback Callback to execute 5 | * @inner 6 | */ 7 | var nextTick = typeof process !== 'undefined' && process && typeof process.nextTick === 'function' 8 | ? (typeof setImmediate === 'function' ? setImmediate : process.nextTick) 9 | : setTimeout; 10 | 11 | /** 12 | * Converts a JavaScript string to UTF8 bytes. 13 | * @param {string} str String 14 | * @returns {!Array.} UTF8 bytes 15 | * @inner 16 | */ 17 | function stringToBytes(str) { 18 | var out = [], 19 | i = 0; 20 | utfx.encodeUTF16toUTF8(function() { 21 | if (i >= str.length) return null; 22 | return str.charCodeAt(i++); 23 | }, function(b) { 24 | out.push(b); 25 | }); 26 | return out; 27 | } 28 | 29 | //? include("util/base64.js"); 30 | 31 | //? include("../../node_modules/utfx/dist/utfx-embeddable.js"); 32 | 33 | Date.now = Date.now || function() { return +new Date; }; 34 | -------------------------------------------------------------------------------- /scripts/build.js: -------------------------------------------------------------------------------- 1 | var MetaScript = require("metascript"), 2 | path = require("path"), 3 | fs = require("fs"); 4 | 5 | var rootDir = path.join(__dirname, ".."), 6 | srcDir = path.join(rootDir, "src"), 7 | distDir = path.join(rootDir, "dist"), 8 | pkg = require(path.join(rootDir, "package.json")), 9 | filename; 10 | 11 | var scope = { 12 | VERSION: pkg.version, 13 | ISAAC: false 14 | }; 15 | 16 | // Make standard build 17 | console.log("Building bcrypt.js with scope", JSON.stringify(scope, null, 2)); 18 | fs.writeFileSync( 19 | path.join(distDir, "bcrypt.js"), 20 | MetaScript.transform(fs.readFileSync(filename = path.join(srcDir, "bcrypt.js")), filename, scope, srcDir) 21 | ); 22 | 23 | // Make isaac build - see: https://github.com/dcodeIO/bcrypt.js/issues/16 24 | /* scope.ISAAC = true; 25 | console.log("Building bcrypt-isaac.js with scope", JSON.stringify(scope, null, 2)); 26 | fs.writeFileSync( 27 | path.join(distDir, "bcrypt-isaac.js"), 28 | MetaScript.transform(fs.readFileSync(filename = path.join(srcDir, "bcrypt.js")), filename, scope, srcDir) 29 | ); */ 30 | 31 | // Update bower.json 32 | scope = { VERSION: pkg.version }; 33 | console.log("Updating bower.json with scope", JSON.stringify(scope, null, 2)); 34 | fs.writeFileSync( 35 | path.join(rootDir, "bower.json"), 36 | MetaScript.transform(fs.readFileSync(filename = path.join(srcDir, "bower.json")), filename, scope, srcDir) 37 | ); 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Nevins Bartolomeo 3 | Copyright (c) 2012 Shane Girish 4 | Copyright (c) 2013 Daniel Wirtz 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 | module.exports = require("./dist/bcrypt.js"); 30 | -------------------------------------------------------------------------------- /externs/minimal-env.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Minimal environment for bcrypt.js. 3 | * @externs 4 | */ 5 | 6 | /** 7 | * @param {string} moduleName 8 | * returns {*} 9 | */ 10 | function require(moduleName) {} 11 | 12 | /** 13 | * @constructor 14 | * @private 15 | */ 16 | var Module = function() {}; 17 | 18 | /** 19 | * @type {*} 20 | */ 21 | Module.prototype.exports; 22 | 23 | /** 24 | * @type {Module} 25 | */ 26 | var module; 27 | 28 | /** 29 | * @type {string} 30 | */ 31 | var __dirname; 32 | 33 | /** 34 | * @type {Object.} 35 | */ 36 | var process = {}; 37 | 38 | /** 39 | * @param {function()} func 40 | */ 41 | process.nextTick = function(func) {}; 42 | 43 | /** 44 | * @param {string} s 45 | * @constructor 46 | * @extends Array 47 | */ 48 | var Buffer = function(s) {}; 49 | 50 | /** 51 | BEGIN_NODE_INCLUDE 52 | var crypto = require('crypto'); 53 | END_NODE_INCLUDE 54 | */ 55 | 56 | /** 57 | * @type {Object.} 58 | */ 59 | var crypto = {}; 60 | 61 | /** 62 | * @param {number} n 63 | * @returns {Array.} 64 | */ 65 | crypto.randomBytes = function(n) {}; 66 | 67 | /** 68 | * @type {Object.} 69 | */ 70 | window.crypto = {}; 71 | 72 | /** 73 | * @param {Uint8Array|Int8Array|Uint16Array|Int16Array|Uint32Array|Int32Array} array 74 | */ 75 | window.crypto.getRandomValues = function(array) {}; 76 | 77 | /** 78 | * @param {string} name 79 | * @param {function(...[*]):*} constructor 80 | */ 81 | var define = function(name, constructor) {}; 82 | 83 | /** 84 | * @type {boolean} 85 | */ 86 | define.amd; 87 | 88 | /** 89 | * @param {...*} var_args 90 | * @returns {string} 91 | */ 92 | String.fromCodePoint = function(var_args) {}; 93 | 94 | /** 95 | * @param {number} offset 96 | * @returns {number} 97 | */ 98 | String.prototype.codePointAt = function(offset) {}; 99 | -------------------------------------------------------------------------------- /tests/bench.js: -------------------------------------------------------------------------------- 1 | var bcrypt = require("bcrypt"), 2 | bcryptjs = require("../index.js"), 3 | pass = "ä☺𠜎️☁", 4 | testRounds = [8, 9, 10, 11, 12, 13, 14, 15]; 5 | 6 | function testSync(name, salt, impl) { 7 | var res; 8 | console.time(name); 9 | res = impl.hashSync(pass, salt); 10 | console.timeEnd(name); 11 | console.log("`"+res+"` "); 12 | } 13 | 14 | function testAsync(name, salt, impl, cb) { 15 | console.time(name); 16 | impl.hash(pass, salt, function(err, res) { 17 | console.timeEnd(name); 18 | console.log("`"+res+"` "); 19 | if (cb) cb(); 20 | }); 21 | } 22 | 23 | function testMax(name, impl) { 24 | var s = "", 25 | salt = bcryptjs.genSaltSync(4), 26 | last = null; 27 | while (s.length < 100) { 28 | s += "0"; 29 | var hash = impl.hashSync(s, salt); 30 | if (hash === last) { 31 | console.log(name+" maximum input length is: "+(s.length-1)); 32 | break; 33 | } 34 | last = hash; 35 | } 36 | } 37 | 38 | testMax("bcrypt.js", bcryptjs); 39 | 40 | console.log("## Comparing bcryptjs with bcrypt\n"); 41 | 42 | function next() { 43 | if (testRounds.length === 0) 44 | return; 45 | (function(rounds) { 46 | var salt = bcryptjs.genSaltSync(rounds); 47 | console.log("#### Using "+rounds+" rounds"); 48 | console.log("Salt: `"+salt+"` "); 49 | testSync("* **bcrypt** sync", salt, bcrypt); 50 | testSync("* **bcrypt.js** sync", salt, bcryptjs); 51 | testAsync("* **bcrypt** async", salt, bcrypt, function() { 52 | testAsync("* **bcrypt.js** async", salt, bcryptjs, function() { 53 | console.log(""); 54 | next(); 55 | }); 56 | }); 57 | })(testRounds.shift()); 58 | } 59 | next(); 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bcryptjs", 3 | "description": "Optimized bcrypt in plain JavaScript with zero dependencies. Compatible to 'bcrypt'.", 4 | "version": "2.1.0", 5 | "author": "Daniel Wirtz ", 6 | "contributors": [ 7 | "Shane Girish (https://github.com/shaneGirish)", 8 | "Alex Murray <> (https://github.com/alexmurray)", 9 | "Nicolas Pelletier <> (https://github.com/NicolasPelletier)", 10 | "Josh Rogers <> (https://github.com/geekymole)", 11 | "Noah Isaacson (https://github.com/nisaacson)" 12 | ], 13 | "repository": { 14 | "type": "url", 15 | "url": "https://github.com/dcodeIO/bcrypt.js.git" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/dcodeIO/bcrypt.js/issues" 19 | }, 20 | "keywords": [ 21 | "bcrypt", 22 | "password", 23 | "auth", 24 | "authentication", 25 | "encryption", 26 | "crypt", 27 | "crypto" 28 | ], 29 | "main": "index.js", 30 | "browser": "dist/bcrypt.js", 31 | "dependencies": {}, 32 | "devDependencies": { 33 | "testjs": "~1", 34 | "closurecompiler": "~1", 35 | "metascript": "~0.18", 36 | "bcrypt": "latest", 37 | "utfx": "~1" 38 | }, 39 | "licenses" : [ 40 | { 41 | "type" : "New-BSD, MIT", 42 | "url" : "https://raw.githubusercontent.com/dcodeIO/bcrypt.js/master/LICENSE" 43 | } 44 | ], 45 | "scripts": { 46 | "test": "node node_modules/testjs/bin/testjs", 47 | "build": "node scripts/build.js", 48 | "compile": "node node_modules/closurecompiler/bin/ccjs dist/bcrypt.js --compilation_level=ADVANCED_OPTIMIZATIONS --create_source_map=dist/bcrypt.min.map --externs=externs/minimal-env.js --output_wrapper=\"(function(){%output%})();\" > dist/bcrypt.min.js", 49 | "compress": "gzip -c -9 dist/bcrypt.min.js > dist/bcrypt.min.js.gz", 50 | "make": "npm run-script build && npm run-script compile && npm test" 51 | } 52 | } -------------------------------------------------------------------------------- /externs/bcrypt.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Closure Compiler Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @fileoverview Definitions for bcrypt.js 2. 19 | * @externs 20 | * @author Daniel Wirtz 21 | */ 22 | 23 | /** 24 | * @type {Object.} 25 | */ 26 | var bcrypt = {}; 27 | 28 | /** 29 | * @param {?function(number):!Array.} random 30 | */ 31 | bcrypt.setRandomFallback = function(random) {}; 32 | 33 | /** 34 | * @param {number=} rounds 35 | * @param {number=} seed_length 36 | * @returns {string} 37 | */ 38 | bcrypt.genSaltSync = function(rounds, seed_length) {}; 39 | 40 | /** 41 | * @param {(number|function(Error, ?string))=} rounds 42 | * @param {(number|function(Error, ?string))=} seed_length 43 | * @param {function(Error, string=)=} callback 44 | */ 45 | bcrypt.genSalt = function(rounds, seed_length, callback) {}; 46 | 47 | /** 48 | * @param {string} s 49 | * @param {(number|string)=} salt 50 | * @returns {?string} 51 | */ 52 | bcrypt.hashSync = function(s, salt) {}; 53 | 54 | /** 55 | * @param {string} s 56 | * @param {number|string} salt 57 | * @param {function(Error, string=)} callback 58 | * @expose 59 | */ 60 | bcrypt.hash = function(s, salt, callback) {}; 61 | 62 | /** 63 | * @param {string} s 64 | * @param {string} hash 65 | * @returns {boolean} 66 | * @throws {Error} 67 | */ 68 | bcrypt.compareSync = function(s, hash) {}; 69 | 70 | /** 71 | * @param {string} s 72 | * @param {string} hash 73 | * @param {function(Error, boolean)} callback 74 | * @throws {Error} 75 | */ 76 | bcrypt.compare = function(s, hash, callback) {}; 77 | 78 | /** 79 | * @param {string} hash 80 | * @returns {number} 81 | * @throws {Error} 82 | */ 83 | bcrypt.getRounds = function(hash) {}; 84 | 85 | /** 86 | * @param {string} hash 87 | * @returns {string} 88 | * @throws {Error} 89 | * @expose 90 | */ 91 | bcrypt.getSalt = function(hash) {}; 92 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | bcrypt.js 2 | --------- 3 | Copyright (c) 2012 Nevins Bartolomeo 4 | Copyright (c) 2012 Shane Girish 5 | Copyright (c) 2014 Daniel Wirtz 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions 9 | are met: 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | isaac.js 30 | -------- 31 | Copyright (c) 2012 Yves-Marie K. Rinquin 32 | 33 | Permission is hereby granted, free of charge, to any person obtaining 34 | a copy of this software and associated documentation files (the 35 | "Software"), to deal in the Software without restriction, including 36 | without limitation the rights to use, copy, modify, merge, publish, 37 | distribute, sublicense, and/or sell copies of the Software, and to 38 | permit persons to whom the Software is furnished to do so, subject to 39 | the following conditions: 40 | 41 | The above copyright notice and this permission notice shall be 42 | included in all copies or substantial portions of the Software. 43 | 44 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 45 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 46 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 47 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 48 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 49 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 50 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 51 | -------------------------------------------------------------------------------- /src/bcrypt/util/base64.js: -------------------------------------------------------------------------------- 1 | // A base64 implementation for the bcrypt algorithm. This is partly non-standard. 2 | 3 | /** 4 | * bcrypt's own non-standard base64 dictionary. 5 | * @type {!Array.} 6 | * @const 7 | * @inner 8 | **/ 9 | var BASE64_CODE = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(''); 10 | 11 | /** 12 | * @type {!Array.} 13 | * @const 14 | * @inner 15 | **/ 16 | var BASE64_INDEX = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 19 | 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, 20 | -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21 | 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30, 22 | 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 23 | 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1]; 24 | 25 | /** 26 | * @type {!function(...number):string} 27 | * @inner 28 | */ 29 | var stringFromCharCode = String.fromCharCode; 30 | 31 | /** 32 | * Encodes a byte array to base64 with up to len bytes of input. 33 | * @param {!Array.} b Byte array 34 | * @param {number} len Maximum input length 35 | * @returns {string} 36 | * @inner 37 | */ 38 | function base64_encode(b, len) { 39 | var off = 0, 40 | rs = [], 41 | c1, c2; 42 | if (len <= 0 || len > b.length) 43 | throw Error("Illegal len: "+len); 44 | while (off < len) { 45 | c1 = b[off++] & 0xff; 46 | rs.push(BASE64_CODE[(c1 >> 2) & 0x3f]); 47 | c1 = (c1 & 0x03) << 4; 48 | if (off >= len) { 49 | rs.push(BASE64_CODE[c1 & 0x3f]); 50 | break; 51 | } 52 | c2 = b[off++] & 0xff; 53 | c1 |= (c2 >> 4) & 0x0f; 54 | rs.push(BASE64_CODE[c1 & 0x3f]); 55 | c1 = (c2 & 0x0f) << 2; 56 | if (off >= len) { 57 | rs.push(BASE64_CODE[c1 & 0x3f]); 58 | break; 59 | } 60 | c2 = b[off++] & 0xff; 61 | c1 |= (c2 >> 6) & 0x03; 62 | rs.push(BASE64_CODE[c1 & 0x3f]); 63 | rs.push(BASE64_CODE[c2 & 0x3f]); 64 | } 65 | return rs.join(''); 66 | } 67 | 68 | /** 69 | * Decodes a base64 encoded string to up to len bytes of output. 70 | * @param {string} s String to decode 71 | * @param {number} len Maximum output length 72 | * @returns {!Array.} 73 | * @inner 74 | */ 75 | function base64_decode(s, len) { 76 | var off = 0, 77 | slen = s.length, 78 | olen = 0, 79 | rs = [], 80 | c1, c2, c3, c4, o, code; 81 | if (len <= 0) 82 | throw Error("Illegal len: "+len); 83 | while (off < slen - 1 && olen < len) { 84 | code = s.charCodeAt(off++); 85 | c1 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 86 | code = s.charCodeAt(off++); 87 | c2 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 88 | if (c1 == -1 || c2 == -1) 89 | break; 90 | o = (c1 << 2) >>> 0; 91 | o |= (c2 & 0x30) >> 4; 92 | rs.push(stringFromCharCode(o)); 93 | if (++olen >= len || off >= slen) 94 | break; 95 | code = s.charCodeAt(off++); 96 | c3 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 97 | if (c3 == -1) 98 | break; 99 | o = ((c2 & 0x0f) << 4) >>> 0; 100 | o |= (c3 & 0x3c) >> 2; 101 | rs.push(stringFromCharCode(o)); 102 | if (++olen >= len || off >= slen) 103 | break; 104 | code = s.charCodeAt(off++); 105 | c4 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 106 | o = ((c3 & 0x03) << 6) >>> 0; 107 | o |= c4; 108 | rs.push(stringFromCharCode(o)); 109 | ++olen; 110 | } 111 | var res = []; 112 | for (off = 0; off -- 2012-04-11 5 | 6 | This is an example of a plain-text file encoded in UTF-8. 7 | 8 | 9 | Danish (da) 10 | --------- 11 | 12 | Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen 13 | Wolther spillede på xylofon. 14 | (= Quiz contestants were eating strawbery with cream while Wolther 15 | the circus clown played on xylophone.) 16 | 17 | German (de) 18 | ----------- 19 | 20 | Falsches Üben von Xylophonmusik quält jeden größeren Zwerg 21 | (= Wrongful practicing of xylophone music tortures every larger dwarf) 22 | 23 | Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich 24 | (= Twelve boxing fighters hunted Eva across the dike of Sylt) 25 | 26 | Heizölrückstoßabdämpfung 27 | (= fuel oil recoil absorber) 28 | (jqvwxy missing, but all non-ASCII letters in one word) 29 | 30 | Greek (el) 31 | ---------- 32 | 33 | Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο 34 | (= No more shall I see acacias or myrtles in the golden clearing) 35 | 36 | Ξεσκεπάζω τὴν ψυχοφθόρα βδελυγμία 37 | (= I uncover the soul-destroying abhorrence) 38 | 39 | English (en) 40 | ------------ 41 | 42 | The quick brown fox jumps over the lazy dog 43 | 44 | Spanish (es) 45 | ------------ 46 | 47 | El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y 48 | frío, añoraba a su querido cachorro. 49 | (Contains every letter and every accent, but not every combination 50 | of vowel + acute.) 51 | 52 | French (fr) 53 | ----------- 54 | 55 | Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à 56 | côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce 57 | qui lui permet de penser à la cænogenèse de l'être dont il est question 58 | dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, 59 | pense-t-il, diminue çà et là la qualité de son œuvre. 60 | 61 | l'île exiguë 62 | Où l'obèse jury mûr 63 | Fête l'haï volapük, 64 | Âne ex aéquo au whist, 65 | Ôtez ce vœu déçu. 66 | 67 | Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en 68 | canoë au delà des îles, près du mälström où brûlent les novæ. 69 | 70 | Irish Gaelic (ga) 71 | ----------------- 72 | 73 | D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh 74 | 75 | Hungarian (hu) 76 | -------------- 77 | 78 | Árvíztűrő tükörfúrógép 79 | (= flood-proof mirror-drilling machine, only all non-ASCII letters) 80 | 81 | Icelandic (is) 82 | -------------- 83 | 84 | Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa 85 | 86 | Sævör grét áðan því úlpan var ónýt 87 | (some ASCII letters missing) 88 | 89 | Japanese (jp) 90 | ------------- 91 | 92 | Hiragana: (Iroha) 93 | 94 | いろはにほへとちりぬるを 95 | わかよたれそつねならむ 96 | うゐのおくやまけふこえて 97 | あさきゆめみしゑひもせす 98 | 99 | Katakana: 100 | 101 | イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム 102 | ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン 103 | 104 | Hebrew (iw) 105 | ----------- 106 | 107 | ? דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה 108 | 109 | Polish (pl) 110 | ----------- 111 | 112 | Pchnąć w tę łódź jeża lub ośm skrzyń fig 113 | (= To push a hedgehog or eight bins of figs in this boat) 114 | 115 | Russian (ru) 116 | ------------ 117 | 118 | В чащах юга жил бы цитрус? Да, но фальшивый экземпляр! 119 | (= Would a citrus live in the bushes of south? Yes, but only a fake one!) 120 | 121 | Съешь же ещё этих мягких французских булок да выпей чаю 122 | (= Eat some more of these fresh French loafs and have some tea) 123 | 124 | Thai (th) 125 | --------- 126 | 127 | [--------------------------|------------------------] 128 | ๏ เป็นมนุษย์สุดประเสริฐเลิศคุณค่า กว่าบรรดาฝูงสัตว์เดรัจฉาน 129 | จงฝ่าฟันพัฒนาวิชาการ อย่าล้างผลาญฤๅเข่นฆ่าบีฑาใคร 130 | ไม่ถือโทษโกรธแช่งซัดฮึดฮัดด่า หัดอภัยเหมือนกีฬาอัชฌาสัย 131 | ปฏิบัติประพฤติกฎกำหนดใจ พูดจาให้จ๊ะๆ จ๋าๆ น่าฟังเอย ฯ 132 | 133 | [The copyright for the Thai example is owned by The Computer 134 | Association of Thailand under the Royal Patronage of His Majesty the 135 | King.] 136 | 137 | Turkish (tr) 138 | ------------ 139 | 140 | Pijamalı hasta, yağız şoföre çabucak güvendi. 141 | (=Patient with pajamas, trusted swarthy driver quickly) 142 | 143 | 144 | Special thanks to the people from all over the world who contributed 145 | these sentences since 1999. 146 | 147 | A much larger collection of such pangrams is now available at 148 | 149 | http://en.wikipedia.org/wiki/List_of_pangrams 150 | 151 | -------------------------------------------------------------------------------- /src/bcrypt/prng/accum.js: -------------------------------------------------------------------------------- 1 | /* basic entropy accumulator */ 2 | var accum = (function() { 3 | 4 | var pool, // randomness pool 5 | time, // start timestamp 6 | last; // last step timestamp 7 | 8 | /* initialize with default pool */ 9 | function init() { 10 | pool = []; 11 | time = new Date().getTime(); 12 | last = time; 13 | // use Math.random 14 | pool.push((Math.random() * 0xffffffff)|0); 15 | // use current time 16 | pool.push(time|0); 17 | } 18 | 19 | /* perform one step */ 20 | function step() { 21 | if (!to) 22 | return; 23 | if (pool.length >= 255) { // stop at 255 values (1 more is added on fetch) 24 | stop(); 25 | return; 26 | } 27 | var now = new Date().getTime(); 28 | // use actual time difference 29 | pool.push(now-last); 30 | // always compute, occasionally use Math.random 31 | var rnd = (Math.random() * 0xffffffff)|0; 32 | if (now % 2) 33 | pool[pool.length-1] += rnd; 34 | last = now; 35 | to = setTimeout(step, 100+Math.random()*512); // use hypothetical time difference 36 | } 37 | 38 | var to = null; 39 | 40 | /* starts accumulating */ 41 | function start() { 42 | if (to) return; 43 | to = setTimeout(step, 100+Math.random()*512); 44 | if (console.log) 45 | console.log("bcrypt-isaac: collecting entropy..."); 46 | // install collectors 47 | if (typeof window !== 'undefined' && window && window.addEventListener) 48 | window.addEventListener("load", loadCollector, false), 49 | window.addEventListener("mousemove", mouseCollector, false), 50 | window.addEventListener("touchmove", touchCollector, false); 51 | else if (typeof document !== 'undefined' && document && document.attachEvent) 52 | document.attachEvent("onload", loadCollector), 53 | document.attachEvent("onmousemove", mouseCollector); 54 | } 55 | 56 | /* stops accumulating */ 57 | function stop() { 58 | if (!to) return; 59 | clearTimeout(to); to = null; 60 | // uninstall collectors 61 | if (typeof window !== 'undefined' && window && window.removeEventListener) 62 | window.removeEventListener("load", loadCollector, false), 63 | window.removeEventListener("mousemove", mouseCollector, false), 64 | window.removeEventListener("touchmove", touchCollector, false); 65 | else if (typeof document !== 'undefined' && document && document.detachEvent) 66 | document.detachEvent("onload", loadCollector), 67 | document.detachEvent("onmousemove", mouseCollector); 68 | } 69 | 70 | /* fetches the randomness pool */ 71 | function fetch() { 72 | // add overall time difference 73 | pool.push((new Date().getTime()-time)|0); 74 | var res = pool; 75 | init(); 76 | if (console.log) 77 | console.log("bcrypt-isaac: using "+res.length+"/256 samples of entropy"); 78 | // console.log(res); 79 | return res; 80 | } 81 | 82 | /* adds the current time to the top of the pool */ 83 | function addTime() { 84 | pool[pool.length-1] += new Date().getTime() - time; 85 | } 86 | 87 | /* page load collector */ 88 | function loadCollector() { 89 | if (!to || pool.length >= 255) 90 | return; 91 | pool.push(0); 92 | addTime(); 93 | } 94 | 95 | /* mouse events collector */ 96 | function mouseCollector(ev) { 97 | if (!to || pool.length >= 255) 98 | return; 99 | try { 100 | var x = ev.x || ev.clientX || ev.offsetX || 0, 101 | y = ev.y || ev.clientY || ev.offsetY || 0; 102 | if (x != 0 || y != 0) 103 | pool[pool.length-1] += ((x-mouseCollector.last[0]) ^ (y-mouseCollector.last[1])), 104 | addTime(), 105 | mouseCollector.last = [x,y]; 106 | } catch (e) {} 107 | } 108 | mouseCollector.last = [0,0]; 109 | 110 | /* touch events collector */ 111 | function touchCollector(ev) { 112 | if (!to || pool.length >= 255) 113 | return; 114 | try { 115 | var touch = ev.touches[0] || ev.changedTouches[0]; 116 | var x = touch.pageX || touch.clientX || 0, 117 | y = touch.pageY || touch.clientY || 0; 118 | if (x != 0 || y != 0) 119 | pool[pool.length-1] += (x-touchCollector.last[0]) ^ (y-touchCollector.last[1]), 120 | addTime(), 121 | touchCollector.last = [x,y]; 122 | } catch (e) {} 123 | } 124 | touchCollector.last = [0,0]; 125 | 126 | init(); 127 | return { 128 | "start": start, 129 | "stop": stop, 130 | "fetch": fetch 131 | } 132 | 133 | })(); 134 | -------------------------------------------------------------------------------- /tests/suite.js: -------------------------------------------------------------------------------- 1 | var path = require("path"), 2 | fs = require("fs"), 3 | binding = require("bcrypt"), 4 | bcrypt = require(path.join(__dirname, '..', 'index.js'))/*, 5 | isaac = eval( 6 | fs.readFileSync(path.join(__dirname, "..", "src", "bcrypt", "prng", "accum.js"))+ 7 | fs.readFileSync(path.join(__dirname, "..", "src", "bcrypt", "prng", "isaac.js"))+ 8 | " accum.start();"+ 9 | " isaac" 10 | )*/; 11 | 12 | module.exports = { 13 | 14 | "genSaltSync": function(test) { 15 | var salt = bcrypt.genSaltSync(10); 16 | test.ok(salt); 17 | test.ok(typeof salt == 'string'); 18 | test.ok(salt.length > 0); 19 | test.done(); 20 | }, 21 | 22 | "genSalt": function(test) { 23 | bcrypt.genSalt(10, function(err, salt) { 24 | test.ok(salt); 25 | test.ok(typeof salt == 'string'); 26 | test.ok(salt.length > 0); 27 | test.done(); 28 | }); 29 | }, 30 | 31 | "hashSync": function(test) { 32 | test.doesNotThrow(function() { 33 | bcrypt.hashSync("hello", 10); 34 | }); 35 | test.notEqual(bcrypt.hashSync("hello", 10), bcrypt.hashSync("hello", 10)); 36 | test.done(); 37 | }, 38 | 39 | "hash": function(test) { 40 | bcrypt.hash("hello", 10, function(err, hash) { 41 | test.notOk(err); 42 | test.ok(hash); 43 | test.done(); 44 | }); 45 | }, 46 | 47 | "compareSync": function(test) { 48 | var salt1 = bcrypt.genSaltSync(), 49 | hash1 = bcrypt.hashSync("hello", salt1); // $2a$ 50 | var salt2 = bcrypt.genSaltSync(); 51 | salt2 = salt2.substring(0,2)+'y'+salt2.substring(3); // $2y$ 52 | var hash2 = bcrypt.hashSync("world", salt2); 53 | test.ok(bcrypt.compareSync("hello", hash1)); 54 | test.notOk(bcrypt.compareSync("hello", hash2)); 55 | test.ok(bcrypt.compareSync("world", hash2)); 56 | test.notOk(bcrypt.compareSync("world", hash1)); 57 | test.done(); 58 | }, 59 | 60 | "compare": function(test) { 61 | var salt1 = bcrypt.genSaltSync(), 62 | hash1 = bcrypt.hashSync("hello", salt1); // $2a$ 63 | var salt2 = bcrypt.genSaltSync(); 64 | salt2 = salt2.substring(0,2)+'y'+salt2.substring(3); // $2y$ 65 | var hash2 = bcrypt.hashSync("world", salt2); 66 | bcrypt.compare("hello", hash1, function(err, same) { 67 | test.notOk(err); 68 | test.ok(same); 69 | bcrypt.compare("hello", hash2, function(err, same) { 70 | test.notOk(err); 71 | test.notOk(same); 72 | bcrypt.compare("world", hash2, function(err, same) { 73 | test.notOk(err); 74 | test.ok(same); 75 | bcrypt.compare("world", hash1, function(err, same) { 76 | test.notOk(err); 77 | test.notOk(same); 78 | test.done(); 79 | }); 80 | }); 81 | }); 82 | }); 83 | }, 84 | 85 | "getSalt": function(test) { 86 | var hash1 = bcrypt.hashSync("hello", bcrypt.genSaltSync()); 87 | test.log("Hash: "+hash1); 88 | var salt = bcrypt.getSalt(hash1); 89 | test.log("Salt: "+salt); 90 | var hash2 = bcrypt.hashSync("hello", salt); 91 | test.equal(hash1, hash2); 92 | test.done(); 93 | }, 94 | 95 | "getRounds": function(test) { 96 | var hash1 = bcrypt.hashSync("hello", bcrypt.genSaltSync()); 97 | test.equal(bcrypt.getRounds(hash1), 10); 98 | test.done(); 99 | }, 100 | 101 | "compat": function(test) { 102 | var pass = fs.readFileSync(path.join(__dirname, "quickbrown.txt"))+"", 103 | salt = bcrypt.genSaltSync(), 104 | hash1 = binding.hashSync(pass, salt), 105 | hash2 = bcrypt.hashSync(pass, salt); 106 | test.equal(hash1, hash2); 107 | test.done(); 108 | }, 109 | 110 | "progress": function(test) { 111 | bcrypt.genSalt(12, function(err, salt) { 112 | test.ok(!err); 113 | var progress = []; 114 | bcrypt.hash("hello world", salt, function(err, hash) { 115 | test.ok(!err); 116 | test.ok(typeof hash === 'string'); 117 | test.ok(progress.length >= 2); 118 | test.strictEqual(progress[0], 0); 119 | test.strictEqual(progress[progress.length-1], 1); 120 | test.done(); 121 | }, function(n) { 122 | progress.push(n); 123 | }); 124 | }); 125 | }/*, 126 | 127 | "isaac": function(test) { 128 | for (var i= 0, n; i<999999; ++i) { 129 | n = ((0.5 + isaac() * 2.3283064365386963e-10) * 256) | 0; 130 | test.ok(n === n && n >= 0 && n < 256 && n % 1 === 0); 131 | } 132 | test.done(); 133 | }*/ 134 | }; 135 | -------------------------------------------------------------------------------- /src/bcrypt/prng/isaac.js: -------------------------------------------------------------------------------- 1 | /* 2 | isaac.js Copyright (c) 2012 Yves-Marie K. Rinquin 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | /* isaac module pattern */ 25 | var isaac = (function(){ 26 | 27 | /* internal states */ 28 | var m = Array(256), // internal memory 29 | acc = 0, // accumulator 30 | brs = 0, // last result 31 | cnt = 0, // counter 32 | r = Array(256), // result array 33 | gnt = 0, // generation counter 34 | isd = false; // initially seeded 35 | 36 | 37 | /* 32-bit integer safe adder */ 38 | function add(x, y) { 39 | var lsb = (x & 0xffff) + (y & 0xffff), 40 | msb = (x >>> 16) + (y >>> 16) + (lsb >>> 16); 41 | return (msb << 16) | (lsb & 0xffff); 42 | } 43 | 44 | /* initialisation */ 45 | function reset() { 46 | acc = brs = cnt = 0; 47 | for (var i = 0; i < 256; ++i) 48 | m[i] = r[i] = 0; 49 | gnt = 0; 50 | } 51 | 52 | /* seeding function */ 53 | function seed(s) { 54 | var a, b, c, d, e, f, g, h, i; 55 | 56 | /* seeding the seeds of love */ 57 | a = b = c = d = e = f = g = h = 0x9e3779b9; /* the golden ratio */ 58 | 59 | if (s && typeof(s) === 'number') 60 | s = [s]; 61 | 62 | if (s instanceof Array) { 63 | reset(); 64 | for (i = 0; i < s.length; ++i) 65 | r[i & 0xff] += typeof(s[i]) === 'number' ? s[i] : 0; 66 | } 67 | 68 | /* private: seed mixer */ 69 | function seed_mix() { 70 | a ^= b << 11; d = add(d, a); b = add(b, c); 71 | b ^= c >>> 2; e = add(e, b); c = add(c, d); 72 | c ^= d << 8; f = add(f, c); d = add(d, e); 73 | d ^= e >>> 16; g = add(g, d); e = add(e, f); 74 | e ^= f << 10; h = add(h, e); f = add(f, g); 75 | f ^= g >>> 4; a = add(a, f); g = add(g, h); 76 | g ^= h << 8; b = add(b, g); h = add(h, a); 77 | h ^= a >>> 9; c = add(c, h); a = add(a, b); 78 | } 79 | 80 | for (i = 0; i < 4; i++) /* scramble it */ 81 | seed_mix(); 82 | 83 | for (i = 0; i < 256; i += 8) { 84 | if (s) /* use all the information in the seed */ 85 | a = add(a, r[i + 0]), b = add(b, r[i + 1]), 86 | c = add(c, r[i + 2]), d = add(d, r[i + 3]), 87 | e = add(e, r[i + 4]), f = add(f, r[i + 5]), 88 | g = add(g, r[i + 6]), h = add(h, r[i + 7]); 89 | seed_mix(); 90 | /* fill in m[] with messy stuff */ 91 | m[i + 0] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d; 92 | m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h; 93 | } 94 | if (s) 95 | /* do a second pass to make all of the seed affect all of m[] */ 96 | for (i = 0; i < 256; i += 8) 97 | a = add(a, m[i + 0]), b = add(b, m[i + 1]), 98 | c = add(c, m[i + 2]), d = add(d, m[i + 3]), 99 | e = add(e, m[i + 4]), f = add(f, m[i + 5]), 100 | g = add(g, m[i + 6]), h = add(h, m[i + 7]), 101 | seed_mix(), 102 | /* fill in m[] with messy stuff (again) */ 103 | m[i + 0] = a, m[i + 1] = b, m[i + 2] = c, m[i + 3] = d, 104 | m[i + 4] = e, m[i + 5] = f, m[i + 6] = g, m[i + 7] = h; 105 | prng(); /* fill in the first set of results */ 106 | gnt = 256; /* prepare to use the first set of results */; 107 | } 108 | 109 | /* isaac generator, n = number of run */ 110 | function prng(n) { 111 | var i, x, y; 112 | n = n && typeof(n) === 'number' ? Math.abs(Math.floor(n)) : 1; 113 | while (n--) { 114 | cnt = add(cnt, 1); 115 | brs = add(brs, cnt); 116 | for(i = 0; i < 256; i++) { 117 | switch(i & 3) { 118 | case 0: acc ^= acc << 13; break; 119 | case 1: acc ^= acc >>> 6; break; 120 | case 2: acc ^= acc << 2; break; 121 | case 3: acc ^= acc >>> 16; break; 122 | } 123 | acc = add(m[(i + 128) & 0xff], acc); x = m[i]; 124 | m[i] = y = add(m[(x >>> 2) & 0xff], add(acc, brs)); 125 | r[i] = brs = add(m[(y >>> 10) & 0xff], x); 126 | } 127 | } 128 | } 129 | 130 | /* return a random number between */ 131 | return function() { 132 | if (!isd) // seed from accumulator 133 | isd = true, 134 | accum.stop(), 135 | seed(accum.fetch()); 136 | if (!gnt--) 137 | prng(), gnt = 255; 138 | return r[gnt]; 139 | }; 140 | })(); 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![bcrypt.js - Optimized bcrypt in JavaScript with zero dependencies](https://raw.github.com/dcodeIO/bcrypt.js/master/bcrypt.png) 2 | =========== 3 | Optimized bcrypt in JavaScript with zero dependencies. Compatible to the C++ [bcrypt](https://npmjs.org/package/bcrypt) 4 | binding on node.js and also working in the browser. 5 | 6 | [![Build Status](https://travis-ci.org/dcodeIO/bcrypt.js.svg?branch=master)](https://travis-ci.org/dcodeIO/bcrypt.js) 7 | [![Donate](https://raw.githubusercontent.com/dcodeIO/bcrypt.js/master/donate.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=info%40code-emitter.com&item_name=Open%20Source%3A%20bcrypt.js) 8 | 9 | Security considerations 10 | ----------------------- 11 | Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the 12 | iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with 13 | increasing computation power. ([see](http://en.wikipedia.org/wiki/Bcrypt)) 14 | 15 | While bcrypt.js is compatible to the C++ bcrypt binding, it is written in pure JavaScript and thus slower ([about 2.7 16 | times](https://github.com/dcodeIO/bcrypt.js/wiki/Benchmark)), effectively reducing the number of iterations that can be 17 | processed in an equal time span. 18 | 19 | The maximum input length is 72 bytes (note that UTF8 encoded characters use up to 4 bytes) and the length of generated 20 | hashes is 60 characters. 21 | 22 | Usage 23 | ----- 24 | The library is compatible with CommonJS and AMD loaders and is exposed globally as `dcodeIO.bcrypt` if neither is 25 | available. 26 | 27 | ### node.js 28 | 29 | On node.js, the inbuilt [crypto module](http://nodejs.org/api/crypto.html)'s randomBytes interface is used to obtain 30 | secure random numbers. 31 | 32 | `npm install bcryptjs` 33 | 34 | ```js 35 | var bcrypt = require('bcryptjs'); 36 | ... 37 | ``` 38 | 39 | ### Browser 40 | 41 | In the browser, bcrypt.js relies on [Web Crypto API](http://www.w3.org/TR/WebCryptoAPI)'s getRandomValues 42 | interface to obtain secure random numbers. If no cryptographically secure source of randomness is available, you may 43 | specify one through [bcrypt.setRandomFallback](https://github.com/dcodeIO/bcrypt.js#setrandomfallbackrandom). 44 | 45 | ```js 46 | var bcrypt = dcodeIO.bcrypt; 47 | ... 48 | ``` 49 | 50 | or 51 | 52 | ```js 53 | require.config({ 54 | paths: { "bcrypt": "/path/to/bcrypt.js" } 55 | }); 56 | require(["bcrypt"], function(bcrypt) { 57 | ... 58 | }); 59 | ``` 60 | 61 | Usage - Sync 62 | ------------ 63 | To hash a password: 64 | 65 | ```javascript 66 | var bcrypt = require('bcryptjs'); 67 | var salt = bcrypt.genSaltSync(10); 68 | var hash = bcrypt.hashSync("B4c0/\/", salt); 69 | // Store hash in your password DB. 70 | ``` 71 | 72 | To check a password: 73 | 74 | ```javascript 75 | // Load hash from your password DB. 76 | bcrypt.compareSync("B4c0/\/", hash); // true 77 | bcrypt.compareSync("not_bacon", hash); // false 78 | ``` 79 | 80 | Auto-gen a salt and hash: 81 | 82 | ```javascript 83 | var hash = bcrypt.hashSync('bacon', 8); 84 | ``` 85 | 86 | Usage - Async 87 | ------------- 88 | To hash a password: 89 | 90 | ```javascript 91 | var bcrypt = require('bcryptjs'); 92 | bcrypt.genSalt(10, function(err, salt) { 93 | bcrypt.hash("B4c0/\/", salt, function(err, hash) { 94 | // Store hash in your password DB. 95 | }); 96 | }); 97 | ``` 98 | 99 | To check a password: 100 | 101 | ```javascript 102 | // Load hash from your password DB. 103 | bcrypt.compare("B4c0/\/", hash, function(err, res) { 104 | // res == true 105 | }); 106 | bcrypt.compare("not_bacon", hash, function(err, res) { 107 | // res = false 108 | }); 109 | ``` 110 | 111 | Auto-gen a salt and hash: 112 | 113 | ```javascript 114 | bcrypt.hash('bacon', 8, function(err, hash) { 115 | }); 116 | ``` 117 | 118 | API 119 | --- 120 | ### setRandomFallback(random) 121 | 122 | Sets the pseudo random number generator to use as a fallback if neither node's `crypto` module nor the Web Crypto 123 | API is available. Please note: It is highly important that the PRNG used is cryptographically secure and that it is 124 | seeded properly! 125 | 126 | | Parameter | Type | Description 127 | |-----------------|-----------------|--------------- 128 | | random | *function(number):!Array.<number>* | Function taking the number of bytes to generate as its sole argument, returning the corresponding array of cryptographically secure random byte values. 129 | | **@see** | | http://nodejs.org/api/crypto.html 130 | | **@see** | | http://www.w3.org/TR/WebCryptoAPI/ 131 | 132 | **Hint:** You might use [isaac.js](https://github.com/rubycon/isaac.js) as a CSPRNG but you still have to make sure to 133 | seed it properly. 134 | 135 | ### genSaltSync(rounds=, seed_length=) 136 | 137 | Synchronously generates a salt. 138 | 139 | | Parameter | Type | Description 140 | |-----------------|-----------------|--------------- 141 | | rounds | *number* | Number of rounds to use, defaults to 10 if omitted 142 | | seed_length | *number* | Not supported. 143 | | **@returns** | *string* | Resulting salt 144 | | **@throws** | *Error* | If a random fallback is required but not set 145 | 146 | ### genSalt(rounds=, seed_length=, callback) 147 | 148 | Asynchronously generates a salt. 149 | 150 | | Parameter | Type | Description 151 | |-----------------|-----------------|--------------- 152 | | rounds | *number | function(Error, string=)* | Number of rounds to use, defaults to 10 if omitted 153 | | seed_length | *number | function(Error, string=)* | Not supported. 154 | | callback | *function(Error, string=)* | Callback receiving the error, if any, and the resulting salt 155 | 156 | ### hashSync(s, salt=) 157 | 158 | Synchronously generates a hash for the given string. 159 | 160 | | Parameter | Type | Description 161 | |-----------------|-----------------|--------------- 162 | | s | *string* | String to hash 163 | | salt | *number | string* | Salt length to generate or salt to use, default to 10 164 | | **@returns** | *string* | Resulting hash 165 | 166 | ### hash(s, salt, callback, progressCallback=) 167 | 168 | Asynchronously generates a hash for the given string. 169 | 170 | | Parameter | Type | Description 171 | |-----------------|-----------------|--------------- 172 | | s | *string* | String to hash 173 | | salt | *number | string* | Salt length to generate or salt to use 174 | | callback | *function(Error, string=)* | Callback receiving the error, if any, and the resulting hash 175 | | progressCallback | *function(number)* | Callback successively called with the percentage of rounds completed (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. 176 | 177 | ### compareSync(s, hash) 178 | 179 | Synchronously tests a string against a hash. 180 | 181 | | Parameter | Type | Description 182 | |-----------------|-----------------|--------------- 183 | | s | *string* | String to compare 184 | | hash | *string* | Hash to test against 185 | | **@returns** | *boolean* | true if matching, otherwise false 186 | | **@throws** | *Error* | If an argument is illegal 187 | 188 | ### compare(s, hash, callback, progressCallback=) 189 | 190 | Asynchronously compares the given data against the given hash. 191 | 192 | | Parameter | Type | Description 193 | |-----------------|-----------------|--------------- 194 | | s | *string* | Data to compare 195 | | hash | *string* | Data to be compared to 196 | | callback | *function(Error, boolean)* | Callback receiving the error, if any, otherwise the result 197 | | progressCallback | *function(number)* | Callback successively called with the percentage of rounds completed (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. 198 | | **@throws** | *Error* | If the callback argument is invalid 199 | 200 | ### getRounds(hash) 201 | 202 | Gets the number of rounds used to encrypt the specified hash. 203 | 204 | | Parameter | Type | Description 205 | |-----------------|-----------------|--------------- 206 | | hash | *string* | Hash to extract the used number of rounds from 207 | | **@returns** | *number* | Number of rounds used 208 | | **@throws** | *Error* | If hash is not a string 209 | 210 | ### getSalt(hash) 211 | 212 | Gets the salt portion from a hash. Does not validate the hash. 213 | 214 | | Parameter | Type | Description 215 | |-----------------|-----------------|--------------- 216 | | hash | *string* | Hash to extract the salt from 217 | | **@returns** | *string* | Extracted salt part 218 | | **@throws** | *Error* | If `hash` is not a string or otherwise invalid 219 | 220 | 221 | Command line 222 | ------------ 223 | `Usage: bcrypt [salt]` 224 | 225 | If the input has spaces inside, simply surround it with quotes. 226 | 227 | Downloads 228 | --------- 229 | * [Distributions](https://github.com/dcodeIO/bcrypt.js/tree/master/dist) 230 | * [ZIP-Archive](https://github.com/dcodeIO/bcrypt.js/archive/master.zip) 231 | * [Tarball](https://github.com/dcodeIO/bcrypt.js/tarball/master) 232 | 233 | Credits 234 | ------- 235 | Based on work started by Shane Girish at [bcrypt-nodejs](https://github.com/shaneGirish/bcrypt-nodejs) (MIT-licensed), 236 | which is itself based on [javascript-bcrypt](http://code.google.com/p/javascript-bcrypt/) (New BSD-licensed). 237 | 238 | License 239 | ------- 240 | New-BSD / MIT ([see](https://github.com/dcodeIO/bcrypt.js/blob/master/LICENSE)) 241 | -------------------------------------------------------------------------------- /src/bcrypt.js: -------------------------------------------------------------------------------- 1 | //? if (typeof ISAAC === 'undefined') ISAAC = false; 2 | /* 3 | Copyright (c) 2012 Nevins Bartolomeo 4 | Copyright (c) 2012 Shane Girish 5 | Copyright (c) 2014 Daniel Wirtz 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions 9 | are met: 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | //? if (ISAAC) 32 | * @license bcrypt-isaac.js (c) 2013 Daniel Wirtz 33 | //? else 34 | * @license bcrypt.js (c) 2013 Daniel Wirtz 35 | * Released under the Apache License, Version 2.0 36 | * see: https://github.com/dcodeIO/bcrypt.js for details 37 | */ 38 | (function(global) { 39 | "use strict"; 40 | 41 | /** 42 | * bcrypt namespace. 43 | * @type {Object.} 44 | */ 45 | var bcrypt = {}; 46 | 47 | /** 48 | * The random implementation to use as a fallback. 49 | * @type {?function(number):!Array.} 50 | * @inner 51 | */ 52 | var randomFallback = null; 53 | 54 | /** 55 | * Generates cryptographically secure random bytes. 56 | * @function 57 | * @param {number} len Bytes length 58 | * @returns {!Array.} Random bytes 59 | * @throws {Error} If no random implementation is available 60 | * @inner 61 | */ 62 | function random(len) { 63 | /* node */ if (typeof module !== 'undefined' && module && module['exports']) 64 | try { 65 | return require("crypto")['randomBytes'](len); 66 | } catch (e) {} 67 | /* WCA */ try { 68 | var a; (global['crypto']||global['msCrypto'])['getRandomValues'](a = new Uint32Array(len)); 69 | return Array.prototype.slice.call(a); 70 | } catch (e) {} 71 | /* fallback */ if (!randomFallback) 72 | throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative"); 73 | return randomFallback(len); 74 | } 75 | 76 | // Test if any secure randomness source is available 77 | var randomAvailable = false; 78 | try { 79 | random(1); 80 | randomAvailable = true; 81 | } catch (e) {} 82 | 83 | // Default fallback, if any 84 | randomFallback = /*? if (ISAAC) { */function(len) { 85 | for (var a=[], i=0; i} random Function taking the number of bytes to generate as its 96 | * sole argument, returning the corresponding array of cryptographically secure random byte values. 97 | * @see http://nodejs.org/api/crypto.html 98 | * @see http://www.w3.org/TR/WebCryptoAPI/ 99 | */ 100 | bcrypt.setRandomFallback = function(random) { 101 | randomFallback = random; 102 | }; 103 | 104 | /** 105 | * Synchronously generates a salt. 106 | * @param {number=} rounds Number of rounds to use, defaults to 10 if omitted 107 | * @param {number=} seed_length Not supported. 108 | * @returns {string} Resulting salt 109 | * @throws {Error} If a random fallback is required but not set 110 | * @expose 111 | */ 112 | bcrypt.genSaltSync = function(rounds, seed_length) { 113 | if (typeof rounds === 'undefined') 114 | rounds = GENSALT_DEFAULT_LOG2_ROUNDS; 115 | else if (typeof rounds !== 'number') 116 | throw Error("Illegal arguments: "+(typeof rounds)+", "+(typeof seed_length)); 117 | if (rounds < 4 || rounds > 31) 118 | throw Error("Illegal number of rounds (4-31): "+rounds); 119 | var salt = []; 120 | salt.push("$2a$"); 121 | if (rounds < 10) 122 | salt.push("0"); 123 | salt.push(rounds.toString()); 124 | salt.push('$'); 125 | salt.push(base64_encode(random(BCRYPT_SALT_LEN), BCRYPT_SALT_LEN)); // May throw 126 | return salt.join(''); 127 | }; 128 | 129 | /** 130 | * Asynchronously generates a salt. 131 | * @param {(number|function(Error, string=))=} rounds Number of rounds to use, defaults to 10 if omitted 132 | * @param {(number|function(Error, string=))=} seed_length Not supported. 133 | * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting salt 134 | * @expose 135 | */ 136 | bcrypt.genSalt = function(rounds, seed_length, callback) { 137 | if (typeof seed_length === 'function') 138 | callback = seed_length, 139 | seed_length = undefined; // Not supported. 140 | if (typeof rounds === 'function') 141 | callback = rounds, 142 | rounds = GENSALT_DEFAULT_LOG2_ROUNDS; 143 | if (typeof callback !== 'function') 144 | throw Error("Illegal callback: "+typeof(callback)); 145 | if (typeof rounds !== 'number') { 146 | nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof rounds)))); 147 | return; 148 | } 149 | nextTick(function() { // Pretty thin, but salting is fast enough 150 | try { 151 | callback(null, bcrypt.genSaltSync(rounds)); 152 | } catch (err) { 153 | callback(err); 154 | } 155 | }); 156 | }; 157 | 158 | /** 159 | * Synchronously generates a hash for the given string. 160 | * @param {string} s String to hash 161 | * @param {(number|string)=} salt Salt length to generate or salt to use, default to 10 162 | * @returns {string} Resulting hash 163 | * @expose 164 | */ 165 | bcrypt.hashSync = function(s, salt) { 166 | if (typeof salt === 'undefined') 167 | salt = GENSALT_DEFAULT_LOG2_ROUNDS; 168 | if (typeof salt === 'number') 169 | salt = bcrypt.genSaltSync(salt); 170 | if (typeof s !== 'string' || typeof salt !== 'string') 171 | throw Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)); 172 | return _hash(s, salt); 173 | }; 174 | 175 | /** 176 | * Asynchronously generates a hash for the given string. 177 | * @param {string} s String to hash 178 | * @param {number|string} salt Salt length to generate or salt to use 179 | * @param {function(Error, string=)} callback Callback receiving the error, if any, and the resulting hash 180 | * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed 181 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. 182 | * @expose 183 | */ 184 | bcrypt.hash = function(s, salt, callback, progressCallback) { 185 | if (typeof callback !== 'function') 186 | throw Error("Illegal callback: "+typeof(callback)); 187 | if (typeof s === 'string' && typeof salt === 'number') 188 | bcrypt.genSalt(salt, function(err, salt) { 189 | _hash(s, salt, callback, progressCallback); 190 | }); 191 | else if (typeof s === 'string' && typeof salt === 'string') 192 | _hash(s, salt, callback, progressCallback); 193 | else 194 | nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)))); 195 | }; 196 | 197 | /** 198 | * Synchronously tests a string against a hash. 199 | * @param {string} s String to compare 200 | * @param {string} hash Hash to test against 201 | * @returns {boolean} true if matching, otherwise false 202 | * @throws {Error} If an argument is illegal 203 | * @expose 204 | */ 205 | bcrypt.compareSync = function(s, hash) { 206 | if (typeof s !== "string" || typeof hash !== "string") 207 | throw Error("Illegal arguments: "+(typeof s)+', '+(typeof hash)); 208 | if (hash.length !== 60) 209 | return false; 210 | var comp = bcrypt.hashSync(s, hash.substr(0, hash.length-31)), 211 | same = comp.length === hash.length, 212 | max_length = (comp.length < hash.length) ? comp.length : hash.length; 213 | // to prevent timing attacks, should check entire string 214 | // don't exit after found to be false 215 | for (var i = 0; i < max_length; ++i) 216 | if (comp.length >= i && hash.length >= i && comp[i] != hash[i]) 217 | same = false; 218 | return same; 219 | }; 220 | 221 | /** 222 | * Asynchronously compares the given data against the given hash. 223 | * @param {string} s Data to compare 224 | * @param {string} hash Data to be compared to 225 | * @param {function(Error, boolean)} callback Callback receiving the error, if any, otherwise the result 226 | * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed 227 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. 228 | * @throws {Error} If the callback argument is invalid 229 | * @expose 230 | */ 231 | bcrypt.compare = function(s, hash, callback, progressCallback) { 232 | if (typeof callback !== 'function') 233 | throw Error("Illegal callback: "+typeof(callback)); 234 | if (typeof s !== "string" || typeof hash !== "string") { 235 | nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof hash)))); 236 | return; 237 | } 238 | bcrypt.hash(s, hash.substr(0, 29), function(err, comp) { 239 | callback(err, hash === comp); 240 | }, progressCallback); 241 | }; 242 | 243 | /** 244 | * Gets the number of rounds used to encrypt the specified hash. 245 | * @param {string} hash Hash to extract the used number of rounds from 246 | * @returns {number} Number of rounds used 247 | * @throws {Error} If hash is not a string 248 | * @expose 249 | */ 250 | bcrypt.getRounds = function(hash) { 251 | if (typeof hash !== "string") 252 | throw Error("Illegal arguments: "+(typeof hash)); 253 | return parseInt(hash.split("$")[2], 10); 254 | }; 255 | 256 | /** 257 | * Gets the salt portion from a hash. Does not validate the hash. 258 | * @param {string} hash Hash to extract the salt from 259 | * @returns {string} Extracted salt part 260 | * @throws {Error} If `hash` is not a string or otherwise invalid 261 | * @expose 262 | */ 263 | bcrypt.getSalt = function(hash) { 264 | if (typeof hash !== 'string') 265 | throw Error("Illegal arguments: "+(typeof hash)); 266 | if (hash.length !== 60) 267 | throw Error("Illegal hash length: "+hash.length+" != 60"); 268 | return hash.substring(0, 29); 269 | }; 270 | 271 | //? include("bcrypt/util.js"); 272 | 273 | //? include("bcrypt/impl.js"); 274 | 275 | //? if (ISAAC) { 276 | //? include("bcrypt/prng/accum.js"); 277 | 278 | // Start accumulating 279 | if (!randomAvailable) 280 | accum.start(); 281 | 282 | //? include("bcrypt/prng/isaac.js"); 283 | //? } 284 | 285 | /* CommonJS */ if (typeof module !== 'undefined' && module["exports"]) 286 | module["exports"] = bcrypt; 287 | /* AMD */ else if (typeof define !== 'undefined' && define["amd"]) 288 | define(function() { return bcrypt; }); 289 | /* Global */ else 290 | (global["dcodeIO"] = global["dcodeIO"] || {})["bcrypt"] = bcrypt; 291 | 292 | })(this); 293 | -------------------------------------------------------------------------------- /dist/bcrypt.min.js: -------------------------------------------------------------------------------- 1 | (function(){/* 2 | bcrypt.js (c) 2013 Daniel Wirtz 3 | Released under the Apache License, Version 2.0 4 | see: https://github.com/dcodeIO/bcrypt.js for details 5 | */ 6 | (function(u){function z(b){if("undefined"!==typeof module&&module&&module.exports)try{return require("crypto").randomBytes(b)}catch(a){}try{var c;(u.crypto||u.msCrypto).getRandomValues(c=new Uint32Array(b));return Array.prototype.slice.call(c)}catch(d){}if(!v)throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative");return v(b)}function D(b){var a=[],c=0;E.f(function(){return c>=b.length?null:b.charCodeAt(c++)},function(c){a.push(c)}); 7 | return a}function w(b,a){var c=0,d=[],f,e;if(0>=a||a>b.length)throw Error("Illegal len: "+a);for(;c>2&63]);f=(f&3)<<4;if(c>=a){d.push(r[f&63]);break}e=b[c++]&255;f|=e>>4&15;d.push(r[f&63]);f=(e&15)<<2;if(c>=a){d.push(r[f&63]);break}e=b[c++]&255;f|=e>>6&3;d.push(r[f&63]);d.push(r[e&63])}return d.join("")}function F(b){for(var a=0,c=b.length,d=0,f=[],e,k,h;ad;){h=b.charCodeAt(a++);e=h>>0;h|=(k&48)>>4;f.push(x(h));if(16<=++d||a>=c)break;h=b.charCodeAt(a++);e=h>>0;h|=(e&60)>>2;f.push(x(h));if(16<=++d||a>=c)break;h=b.charCodeAt(a++);k=h>>0;h|=k;f.push(x(h));++d}b=[];for(a=0;a=h;)f=d[e>>24&255],f+=d[256|e>>16&255],f^=d[512|e>>8&255],f+=d[768|e&255],k=k^f^c[++h],f=d[k>>24&255],f+=d[256|k>>16&255],f^= 9 | d[512|k>>8&255],f+=d[768|k&255],e=e^f^c[++h];b[a]=k^c[17];b[a+1]=e;return b}function s(b,a){for(var c=0,d=0;4>c;++c)d=d<<8|b[a]&255,a=(a+1)%b.length;return{key:d,a:a}}function A(b,a,c){for(var d=0,f=[0,0],e=a.length,k=c.length,h,g=0;gn;n++)for(p=0;p>1;p++)t(k,p<<1,m,l);g=[];for(n=0;n>24&255)>>>0),g.push((k[n]>>16&255)>>>0),g.push((k[n]>>8&255)>>>0),g.push((k[n]&255)>>>0);if(d){d(null, 11 | g);return}return g}d&&q(e)}var k=C.slice(),h=k.length,g;if(4>c||31h&&c.push("0"); 12 | c.push(h.toString());c.push("$");c.push(w(g,g.length));c.push(w(a,4*C.length-1));return c.join("")}if("string"!==typeof b||"string"!==typeof a){d=Error("Invalid string / salt: Not a string");if(c){q(c.bind(this,d));return}throw d;}var e,k;if("$"!==a.charAt(0)||"2"!==a.charAt(1)){d=Error("Invalid salt version: "+a.substring(0,2));if(c){q(c.bind(this,d));return}throw d;}if("$"===a.charAt(2))e=String.fromCharCode(0),k=3;else{e=a.charAt(2);if("a"!==e&&"y"!==e||"$"!==a.charAt(3)){d=Error("Invalid salt revision: "+ 13 | a.substring(2,4));if(c){q(c.bind(this,d));return}throw d;}k=4}if("$"b||31b&&c.push("0");c.push(b.toString());c.push("$");c.push(w(z(16),16));return c.join("")};l.genSalt=function(b,a,c){"function"===typeof a&&(c=a,a=void 0);"function"===typeof b&&(c=b,b=10);if("function"!==typeof c)throw Error("Illegal callback: "+typeof c);"number"!==typeof b?q(c.bind(this,Error("Illegal arguments: "+typeof b))): 15 | q(function(){try{c(null,l.genSaltSync(b))}catch(a){c(a)}})};l.hashSync=function(b,a){"undefined"===typeof a&&(a=10);"number"===typeof a&&(a=l.genSaltSync(a));if("string"!==typeof b||"string"!==typeof a)throw Error("Illegal arguments: "+typeof b+", "+typeof a);return y(b,a)};l.hash=function(b,a,c,d){if("function"!==typeof c)throw Error("Illegal callback: "+typeof c);"string"===typeof b&&"number"===typeof a?l.genSalt(a,function(a,e){y(b,e,c,d)}):"string"===typeof b&&"string"===typeof a?y(b,a,c,d):q(c.bind(this, 16 | Error("Illegal arguments: "+typeof b+", "+typeof a)))};l.compareSync=function(b,a){if("string"!==typeof b||"string"!==typeof a)throw Error("Illegal arguments: "+typeof b+", "+typeof a);if(60!==a.length)return!1;for(var c=l.hashSync(b,a.substr(0,a.length-31)),d=c.length===a.length,f=c.length=e&&a.length>=e&&c[e]!=a[e]&&(d=!1);return d};l.compare=function(b,a,c,d){if("function"!==typeof c)throw Error("Illegal callback: "+typeof c);"string"!==typeof b|| 17 | "string"!==typeof a?q(c.bind(this,Error("Illegal arguments: "+typeof b+", "+typeof a))):l.hash(b,a.substr(0,29),function(d,b){c(d,a===b)},d)};l.getRounds=function(b){if("string"!==typeof b)throw Error("Illegal arguments: "+typeof b);return parseInt(b.split("$")[2],10)};l.getSalt=function(b){if("string"!==typeof b)throw Error("Illegal arguments: "+typeof b);if(60!==b.length)throw Error("Illegal hash length: "+b.length+" != 60");return b.substring(0,29)};var q="undefined"!==typeof process&&process&& 18 | "function"===typeof process.nextTick?"function"===typeof setImmediate?setImmediate:process.nextTick:setTimeout,r="./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(""),p=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,54,55,56,57,58,59,60,61,62,63,-1,-1,-1,-1,-1,-1,-1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,-1,-1,-1,-1,-1,-1,28,29,30,31,32,33,34,35,36, 19 | 37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,-1,-1,-1,-1,-1],x=String.fromCharCode,E=function(){var b={h:1114111,g:function(a,c){var d=null;"number"===typeof a&&(d=a,a=function(){return null});for(;null!==d||null!==(d=a());)128>d?c(d&127):(2048>d?c(d>>6&31|192):(65536>d?c(d>>12&15|224):(c(d>>18&7|240),c(d>>12&63|128)),c(d>>6&63|128)),c(d&63|128)),d=null},e:function(a,c){function d(a){a=a.slice(0,a.indexOf(null));var c=Error(a.toString());c.name="TruncatedError";c.bytes=a;throw c;}for(var b, 20 | e,k,h;null!==(b=a());)if(0===(b&128))c(b);else if(192===(b&224))null===(e=a())&&d([b,e]),c((b&31)<<6|e&63);else if(224===(b&240))null!==(e=a())&&null!==(k=a())||d([b,e,k]),c((b&15)<<12|(e&63)<<6|k&63);else if(240===(b&248))null!==(e=a())&&null!==(k=a())&&null!==(h=a())||d([b,e,k,h]),c((b&7)<<18|(e&63)<<12|(k&63)<<6|h&63);else throw RangeError("Illegal starting byte: "+b);},b:function(a,c){for(var d,b=null;null!==(d=null!==b?b:a());)55296<=d&&57343>=d&&null!==(b=a())&&56320<=b&&57343>=b?(c(1024*(d- 21 | 55296)+b-56320+65536),b=null):c(d);null!==b&&c(b)},d:function(a,c){var b=null;"number"===typeof a&&(b=a,a=function(){return null});for(;null!==b||null!==(b=a());)65535>=b?c(b):(b-=65536,c((b>>10)+55296),c(b%1024+56320)),b=null},f:function(a,c){b.b(a,function(a){b.g(a,c)})},k:function(a,c){b.e(a,function(a){b.d(a,c)})},c:function(a){return 128>a?1:2048>a?2:65536>a?3:4},j:function(a){for(var c,d=0;null!==(c=a());)d+=b.c(c);return d},i:function(a){var c=0,d=0;b.b(a,function(a){++c;d+=b.c(a)});return[c, 22 | d]}};return b}();Date.now=Date.now||function(){return+new Date};var H=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],I=[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109, 23 | 2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993, 24 | 3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498, 25 | 3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101, 26 | 3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981, 27 | 2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946,1266315497, 28 | 3048417604,3681880366,3289982499,290971E4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981, 29 | 3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610, 30 | 322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699, 31 | 720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159, 32 | 885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973, 33 | 2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055,3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326, 34 | 2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912, 35 | 2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472, 36 | 1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100, 37 | 2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164, 38 | 233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504,976866871,3556439503,2881648439,1522871579,1555064734,1336096578, 39 | 3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747, 40 | 3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793, 41 | 3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409E3,2509781533,112762804,3463356488,1866414978,891333506,18488651, 42 | 661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020, 43 | 3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638, 44 | 2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462],C=[1332899944,1700884034,1701343084,1684370003,1668446532,1869963892];"undefined"!==typeof module&&module.exports?module.exports=l:"undefined"!==typeof define&&define.amd?define(function(){return l}):(u.dcodeIO=u.dcodeIO||{}).bcrypt=l})(this);})(); 45 | -------------------------------------------------------------------------------- /src/bcrypt/impl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {number} 3 | * @const 4 | * @inner 5 | */ 6 | var BCRYPT_SALT_LEN = 16; 7 | 8 | /** 9 | * @type {number} 10 | * @const 11 | * @inner 12 | */ 13 | var GENSALT_DEFAULT_LOG2_ROUNDS = 10; 14 | 15 | /** 16 | * @type {number} 17 | * @const 18 | * @inner 19 | */ 20 | var BLOWFISH_NUM_ROUNDS = 16; 21 | 22 | /** 23 | * @type {number} 24 | * @const 25 | * @inner 26 | */ 27 | var MAX_EXECUTION_TIME = 100; 28 | 29 | /** 30 | * @type {Array.} 31 | * @const 32 | * @inner 33 | */ 34 | var P_ORIG = [ 35 | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 36 | 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 37 | 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 38 | 0xb5470917, 0x9216d5d9, 0x8979fb1b 39 | ]; 40 | 41 | /** 42 | * @type {Array.} 43 | * @const 44 | * @inner 45 | */ 46 | var S_ORIG = [ 47 | 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 48 | 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 49 | 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 50 | 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 51 | 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 52 | 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 53 | 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 54 | 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 55 | 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 56 | 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 57 | 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 58 | 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 59 | 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 60 | 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 61 | 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 62 | 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 63 | 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 64 | 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 65 | 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 66 | 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 67 | 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 68 | 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 69 | 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 70 | 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 71 | 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 72 | 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 73 | 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 74 | 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 75 | 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 76 | 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 77 | 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 78 | 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 79 | 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 80 | 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 81 | 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 82 | 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 83 | 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 84 | 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 85 | 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 86 | 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 87 | 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 88 | 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 89 | 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 90 | 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 91 | 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 92 | 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 93 | 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 94 | 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 95 | 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 96 | 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 97 | 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 98 | 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 99 | 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 100 | 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 101 | 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 102 | 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 103 | 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 104 | 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 105 | 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 106 | 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 107 | 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 108 | 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 109 | 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 110 | 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 111 | 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 112 | 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 113 | 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 114 | 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 115 | 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 116 | 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 117 | 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 118 | 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 119 | 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 120 | 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 121 | 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 122 | 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 123 | 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 124 | 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 125 | 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 126 | 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 127 | 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 128 | 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 129 | 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 130 | 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 131 | 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 132 | 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 133 | 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 134 | 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 135 | 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 136 | 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 137 | 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 138 | 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 139 | 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 140 | 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 141 | 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 142 | 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 143 | 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 144 | 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 145 | 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 146 | 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 147 | 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 148 | 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 149 | 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 150 | 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 151 | 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 152 | 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 153 | 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 154 | 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 155 | 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 156 | 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 157 | 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 158 | 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 159 | 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 160 | 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 161 | 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 162 | 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 163 | 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 164 | 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 165 | 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 166 | 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 167 | 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 168 | 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 169 | 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 170 | 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 171 | 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 172 | 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 173 | 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 174 | 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 175 | 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 176 | 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 177 | 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 178 | 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 179 | 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 180 | 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 181 | 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 182 | 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 183 | 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 184 | 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 185 | 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 186 | 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 187 | 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 188 | 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 189 | 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 190 | 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 191 | 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 192 | 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 193 | 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 194 | 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 195 | 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 196 | 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 197 | 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 198 | 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 199 | 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 200 | 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, 201 | 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 202 | 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 203 | 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 204 | 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 205 | 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 206 | 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 207 | 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 208 | 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 209 | 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 210 | 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 211 | 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 212 | 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 213 | 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 214 | 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 215 | 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 216 | 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 217 | 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 218 | 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 219 | 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 220 | 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 221 | 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 222 | 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 223 | 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 224 | 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 225 | 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 226 | 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 227 | 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 228 | 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 229 | 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 230 | 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 231 | 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 232 | 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 233 | 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 234 | 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 235 | 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 236 | 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 237 | 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 238 | 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 239 | 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 240 | 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 241 | 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 242 | 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 243 | 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 244 | 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 245 | 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 246 | 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 247 | 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 248 | 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 249 | 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 250 | 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 251 | 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 252 | ]; 253 | 254 | /** 255 | * @type {Array.} 256 | * @const 257 | * @inner 258 | */ 259 | var C_ORIG = [ 260 | 0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, 261 | 0x6f756274 262 | ]; 263 | 264 | /** 265 | * @param {Array.} lr 266 | * @param {number} off 267 | * @param {Array.} P 268 | * @param {Array.} S 269 | * @returns {Array.} 270 | * @inner 271 | */ 272 | function _encipher(lr, off, P, S) { // This is our bottleneck: 1714/1905 ticks / 90% - see profile.txt 273 | var n, 274 | l = lr[off], 275 | r = lr[off + 1]; 276 | 277 | l ^= P[0]; 278 | for (var i=0, k=BLOWFISH_NUM_ROUNDS-2; i<=k;) 279 | // Feistel substitution on left word 280 | n = S[(l >> 24) & 0xff], 281 | n += S[0x100 | ((l >> 16) & 0xff)], 282 | n ^= S[0x200 | ((l >> 8) & 0xff)], 283 | n += S[0x300 | (l & 0xff)], 284 | r ^= n ^ P[++i], 285 | // Feistel substitution on right word 286 | n = S[(r >> 24) & 0xff], 287 | n += S[0x100 | ((r >> 16) & 0xff)], 288 | n ^= S[0x200 | ((r >> 8) & 0xff)], 289 | n += S[0x300 | (r & 0xff)], 290 | l ^= n ^ P[++i]; 291 | lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; 292 | lr[off + 1] = l; 293 | return lr; 294 | } 295 | 296 | /** 297 | * @param {Array.} data 298 | * @param {number} offp 299 | * @returns {{key: number, offp: number}} 300 | * @inner 301 | */ 302 | function _streamtoword(data, offp) { 303 | for (var i = 0, word = 0; i < 4; ++i) 304 | word = (word << 8) | (data[offp] & 0xff), 305 | offp = (offp + 1) % data.length; 306 | return { key: word, offp: offp }; 307 | } 308 | 309 | /** 310 | * @param {Array.} key 311 | * @param {Array.} P 312 | * @param {Array.} S 313 | * @inner 314 | */ 315 | function _key(key, P, S) { 316 | var offset = 0, 317 | lr = [0, 0], 318 | plen = P.length, 319 | slen = S.length, 320 | sw; 321 | for (var i = 0; i < plen; i++) 322 | sw = _streamtoword(key, offset), 323 | offset = sw.offp, 324 | P[i] = P[i] ^ sw.key; 325 | for (i = 0; i < plen; i += 2) 326 | lr = _encipher(lr, 0, P, S), 327 | P[i] = lr[0], 328 | P[i + 1] = lr[1]; 329 | for (i = 0; i < slen; i += 2) 330 | lr = _encipher(lr, 0, P, S), 331 | S[i] = lr[0], 332 | S[i + 1] = lr[1]; 333 | } 334 | 335 | /** 336 | * Expensive key schedule Blowfish. 337 | * @param {Array.} data 338 | * @param {Array.} key 339 | * @param {Array.} P 340 | * @param {Array.} S 341 | * @inner 342 | */ 343 | function _ekskey(data, key, P, S) { 344 | var offp = 0, 345 | lr = [0, 0], 346 | plen = P.length, 347 | slen = S.length, 348 | sw; 349 | for (var i = 0; i < plen; i++) 350 | sw = _streamtoword(key, offp), 351 | offp = sw.offp, 352 | P[i] = P[i] ^ sw.key; 353 | offp = 0; 354 | for (i = 0; i < plen; i += 2) 355 | sw = _streamtoword(data, offp), 356 | offp = sw.offp, 357 | lr[0] ^= sw.key, 358 | sw = _streamtoword(data, offp), 359 | offp = sw.offp, 360 | lr[1] ^= sw.key, 361 | lr = _encipher(lr, 0, P, S), 362 | P[i] = lr[0], 363 | P[i + 1] = lr[1]; 364 | for (i = 0; i < slen; i += 2) 365 | sw = _streamtoword(data, offp), 366 | offp = sw.offp, 367 | lr[0] ^= sw.key, 368 | sw = _streamtoword(data, offp), 369 | offp = sw.offp, 370 | lr[1] ^= sw.key, 371 | lr = _encipher(lr, 0, P, S), 372 | S[i] = lr[0], 373 | S[i + 1] = lr[1]; 374 | } 375 | 376 | /** 377 | * Internaly crypts a string. 378 | * @param {Array.} b Bytes to crypt 379 | * @param {Array.} salt Salt bytes to use 380 | * @param {number} rounds Number of rounds 381 | * @param {function(Error, Array.=)=} callback Callback receiving the error, if any, and the resulting bytes. If 382 | * omitted, the operation will be performed synchronously. 383 | * @param {function(number)=} progressCallback Callback called with the current progress 384 | * @returns {!Array.|undefined} Resulting bytes if callback has been omitted, otherwise `undefined` 385 | * @inner 386 | */ 387 | function _crypt(b, salt, rounds, callback, progressCallback) { 388 | var cdata = C_ORIG.slice(), 389 | clen = cdata.length, 390 | err; 391 | 392 | // Validate 393 | if (rounds < 4 || rounds > 31) { 394 | err = Error("Illegal number of rounds (4-31): "+rounds); 395 | if (callback) { 396 | nextTick(callback.bind(this, err)); 397 | return; 398 | } else 399 | throw err; 400 | } 401 | if (salt.length !== BCRYPT_SALT_LEN) { 402 | err =Error("Illegal salt length: "+salt.length+" != "+BCRYPT_SALT_LEN); 403 | if (callback) { 404 | nextTick(callback.bind(this, err)); 405 | return; 406 | } else 407 | throw err; 408 | } 409 | rounds = 1 << rounds; 410 | var P = P_ORIG.slice(), 411 | S = S_ORIG.slice(), 412 | i = 0, j; 413 | _ekskey(salt, b, P, S); 414 | 415 | /** 416 | * Calcualtes the next round. 417 | * @returns {Array.|undefined} Resulting array if callback has been omitted, otherwise `undefined` 418 | * @inner 419 | */ 420 | function next() { 421 | if (progressCallback) 422 | progressCallback(i/rounds); 423 | if (i < rounds) { 424 | var start = Date.now(); 425 | for (; i < rounds;) { 426 | i = i + 1; 427 | _key(b, P, S); 428 | _key(salt, P, S); 429 | if (Date.now() - start > MAX_EXECUTION_TIME) 430 | break; 431 | } 432 | } else { 433 | for (i = 0; i < 64; i++) 434 | for (j = 0; j < (clen >> 1); j++) 435 | _encipher(cdata, j << 1, P, S); 436 | var ret = []; 437 | for (i = 0; i < clen; i++) 438 | ret.push(((cdata[i] >> 24) & 0xff) >>> 0), 439 | ret.push(((cdata[i] >> 16) & 0xff) >>> 0), 440 | ret.push(((cdata[i] >> 8) & 0xff) >>> 0), 441 | ret.push((cdata[i] & 0xff) >>> 0); 442 | if (callback) { 443 | callback(null, ret); 444 | return; 445 | } else 446 | return ret; 447 | } 448 | if (callback) 449 | nextTick(next); 450 | } 451 | 452 | // Async 453 | if (typeof callback !== 'undefined') { 454 | next(); 455 | 456 | // Sync 457 | } else { 458 | var res; 459 | while (true) 460 | if (typeof(res = next()) !== 'undefined') 461 | return res || []; 462 | } 463 | } 464 | 465 | /** 466 | * Internally hashes a string. 467 | * @param {string} s String to hash 468 | * @param {?string} salt Salt to use, actually never null 469 | * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash. If omitted, 470 | * hashing is perormed synchronously. 471 | * @param {function(number)=} progressCallback Callback called with the current progress 472 | * @returns {string|undefined} Resulting hash if callback has been omitted, otherwise `undefined` 473 | * @inner 474 | */ 475 | function _hash(s, salt, callback, progressCallback) { 476 | var err; 477 | if (typeof s !== 'string' || typeof salt !== 'string') { 478 | err = Error("Invalid string / salt: Not a string"); 479 | if (callback) { 480 | nextTick(callback.bind(this, err)); 481 | return; 482 | } 483 | else 484 | throw err; 485 | } 486 | 487 | // Validate the salt 488 | var minor, offset; 489 | if (salt.charAt(0) !== '$' || salt.charAt(1) !== '2') { 490 | err = Error("Invalid salt version: "+salt.substring(0,2)); 491 | if (callback) { 492 | nextTick(callback.bind(this, err)); 493 | return; 494 | } 495 | else 496 | throw err; 497 | } 498 | if (salt.charAt(2) === '$') 499 | minor = String.fromCharCode(0), 500 | offset = 3; 501 | else { 502 | minor = salt.charAt(2); 503 | if ((minor !== 'a' && minor !== 'y') || salt.charAt(3) !== '$') { 504 | err = Error("Invalid salt revision: "+salt.substring(2,4)); 505 | if (callback) { 506 | nextTick(callback.bind(this, err)); 507 | return; 508 | } else 509 | throw err; 510 | } 511 | offset = 4; 512 | } 513 | 514 | // Extract number of rounds 515 | if (salt.charAt(offset + 2) > '$') { 516 | err = Error("Missing salt rounds"); 517 | if (callback) { 518 | nextTick(callback.bind(this, err)); 519 | return; 520 | } else 521 | throw err; 522 | } 523 | var r1 = parseInt(salt.substring(offset, offset + 1), 10) * 10, 524 | r2 = parseInt(salt.substring(offset + 1, offset + 2), 10), 525 | rounds = r1 + r2, 526 | real_salt = salt.substring(offset + 3, offset + 25); 527 | s += minor >= 'a' ? "\x00" : ""; 528 | 529 | var passwordb = stringToBytes(s), 530 | saltb = base64_decode(real_salt, BCRYPT_SALT_LEN); 531 | 532 | /** 533 | * Finishes hashing. 534 | * @param {Array.} bytes Byte array 535 | * @returns {string} 536 | * @inner 537 | */ 538 | function finish(bytes) { 539 | var res = []; 540 | res.push("$2"); 541 | if (minor >= 'a') 542 | res.push(minor); 543 | res.push("$"); 544 | if (rounds < 10) 545 | res.push("0"); 546 | res.push(rounds.toString()); 547 | res.push("$"); 548 | res.push(base64_encode(saltb, saltb.length)); 549 | res.push(base64_encode(bytes, C_ORIG.length * 4 - 1)); 550 | return res.join(''); 551 | } 552 | 553 | // Sync 554 | if (typeof callback == 'undefined') 555 | return finish(_crypt(passwordb, saltb, rounds)); 556 | 557 | // Async 558 | else { 559 | _crypt(passwordb, saltb, rounds, function(err, bytes) { 560 | if (err) 561 | callback(err, null); 562 | else 563 | callback(null, finish(bytes)); 564 | }, progressCallback); 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /dist/bcrypt.min.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"", 4 | "lineCount":44, 5 | "mappings":"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", 6 | "sources":["dist/bcrypt.js"], 7 | "names":["global","random","len","module","require","e","a","Uint32Array","Array","prototype","slice","call","randomFallback","Error","stringToBytes","str","out","i","utfx","encodeUTF16toUTF8","length","charCodeAt","b","push","base64_encode","off","rs","c1","c2","BASE64_CODE","join","base64_decode","s","slen","olen","o","BCRYPT_SALT_LEN","code","BASE64_INDEX","stringFromCharCode","c3","c4","res","_encipher","lr","P","S","n","l","r","k","_streamtoword","data","offp","word","key","_key","offset","plen","sw","_ekskey","_crypt","salt","rounds","callback","progressCallback","next","start","Date","now","MAX_EXECUTION_TIME","j","clen","cdata","ret","nextTick","C_ORIG","err","bind","P_ORIG","S_ORIG","_hash","finish","bytes","minor","toString","saltb","charAt","substring","String","fromCharCode","parseInt","r2","real_salt","passwordb","bcrypt","setRandomFallback","bcrypt.setRandomFallback","genSaltSync","bcrypt.genSaltSync","seed_length","GENSALT_DEFAULT_LOG2_ROUNDS","genSalt","bcrypt.genSalt","undefined","hashSync","bcrypt.hashSync","hash","bcrypt.hash","compareSync","bcrypt.compareSync","comp","substr","same","max_length","compare","bcrypt.compare","getRounds","bcrypt.getRounds","split","getSalt","bcrypt.getSalt","process","setImmediate","setTimeout","utfx.encodeUTF8","src","dst","cp","utfx.decodeUTF8","fail","indexOf","name","c","d","RangeError","utfx.UTF16toUTF8","utfx.UTF8toUTF16","utfx.encodeUTF16toUTF8","UTF16toUTF8","encodeUTF8","utfx.decodeUTF8toUTF16","decodeUTF8","UTF8toUTF16","utfx.calculateCodePoint","utfx.calculateUTF8","calculateCodePoint","utfx.calculateUTF16asUTF8","define"] 8 | } 9 | -------------------------------------------------------------------------------- /dist/bcrypt.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Nevins Bartolomeo 3 | Copyright (c) 2012 Shane Girish 4 | Copyright (c) 2014 Daniel Wirtz 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 3. The name of the author may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @license bcrypt.js (c) 2013 Daniel Wirtz 31 | * Released under the Apache License, Version 2.0 32 | * see: https://github.com/dcodeIO/bcrypt.js for details 33 | */ 34 | (function(global) { 35 | "use strict"; 36 | 37 | /** 38 | * bcrypt namespace. 39 | * @type {Object.} 40 | */ 41 | var bcrypt = {}; 42 | 43 | /** 44 | * The random implementation to use as a fallback. 45 | * @type {?function(number):!Array.} 46 | * @inner 47 | */ 48 | var randomFallback = null; 49 | 50 | /** 51 | * Generates cryptographically secure random bytes. 52 | * @function 53 | * @param {number} len Bytes length 54 | * @returns {!Array.} Random bytes 55 | * @throws {Error} If no random implementation is available 56 | * @inner 57 | */ 58 | function random(len) { 59 | /* node */ if (typeof module !== 'undefined' && module && module['exports']) 60 | try { 61 | return require("crypto")['randomBytes'](len); 62 | } catch (e) {} 63 | /* WCA */ try { 64 | var a; (global['crypto']||global['msCrypto'])['getRandomValues'](a = new Uint32Array(len)); 65 | return Array.prototype.slice.call(a); 66 | } catch (e) {} 67 | /* fallback */ if (!randomFallback) 68 | throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative"); 69 | return randomFallback(len); 70 | } 71 | 72 | // Test if any secure randomness source is available 73 | var randomAvailable = false; 74 | try { 75 | random(1); 76 | randomAvailable = true; 77 | } catch (e) {} 78 | 79 | // Default fallback, if any 80 | randomFallback = null; 81 | 82 | /** 83 | * Sets the pseudo random number generator to use as a fallback if neither node's `crypto` module nor the Web Crypto 84 | * API is available. Please note: It is highly important that the PRNG used is cryptographically secure and that it 85 | * is seeded properly! 86 | * @param {?function(number):!Array.} random Function taking the number of bytes to generate as its 87 | * sole argument, returning the corresponding array of cryptographically secure random byte values. 88 | * @see http://nodejs.org/api/crypto.html 89 | * @see http://www.w3.org/TR/WebCryptoAPI/ 90 | */ 91 | bcrypt.setRandomFallback = function(random) { 92 | randomFallback = random; 93 | }; 94 | 95 | /** 96 | * Synchronously generates a salt. 97 | * @param {number=} rounds Number of rounds to use, defaults to 10 if omitted 98 | * @param {number=} seed_length Not supported. 99 | * @returns {string} Resulting salt 100 | * @throws {Error} If a random fallback is required but not set 101 | * @expose 102 | */ 103 | bcrypt.genSaltSync = function(rounds, seed_length) { 104 | if (typeof rounds === 'undefined') 105 | rounds = GENSALT_DEFAULT_LOG2_ROUNDS; 106 | else if (typeof rounds !== 'number') 107 | throw Error("Illegal arguments: "+(typeof rounds)+", "+(typeof seed_length)); 108 | if (rounds < 4 || rounds > 31) 109 | throw Error("Illegal number of rounds (4-31): "+rounds); 110 | var salt = []; 111 | salt.push("$2a$"); 112 | if (rounds < 10) 113 | salt.push("0"); 114 | salt.push(rounds.toString()); 115 | salt.push('$'); 116 | salt.push(base64_encode(random(BCRYPT_SALT_LEN), BCRYPT_SALT_LEN)); // May throw 117 | return salt.join(''); 118 | }; 119 | 120 | /** 121 | * Asynchronously generates a salt. 122 | * @param {(number|function(Error, string=))=} rounds Number of rounds to use, defaults to 10 if omitted 123 | * @param {(number|function(Error, string=))=} seed_length Not supported. 124 | * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting salt 125 | * @expose 126 | */ 127 | bcrypt.genSalt = function(rounds, seed_length, callback) { 128 | if (typeof seed_length === 'function') 129 | callback = seed_length, 130 | seed_length = undefined; // Not supported. 131 | if (typeof rounds === 'function') 132 | callback = rounds, 133 | rounds = GENSALT_DEFAULT_LOG2_ROUNDS; 134 | if (typeof callback !== 'function') 135 | throw Error("Illegal callback: "+typeof(callback)); 136 | if (typeof rounds !== 'number') { 137 | nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof rounds)))); 138 | return; 139 | } 140 | nextTick(function() { // Pretty thin, but salting is fast enough 141 | try { 142 | callback(null, bcrypt.genSaltSync(rounds)); 143 | } catch (err) { 144 | callback(err); 145 | } 146 | }); 147 | }; 148 | 149 | /** 150 | * Synchronously generates a hash for the given string. 151 | * @param {string} s String to hash 152 | * @param {(number|string)=} salt Salt length to generate or salt to use, default to 10 153 | * @returns {string} Resulting hash 154 | * @expose 155 | */ 156 | bcrypt.hashSync = function(s, salt) { 157 | if (typeof salt === 'undefined') 158 | salt = GENSALT_DEFAULT_LOG2_ROUNDS; 159 | if (typeof salt === 'number') 160 | salt = bcrypt.genSaltSync(salt); 161 | if (typeof s !== 'string' || typeof salt !== 'string') 162 | throw Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)); 163 | return _hash(s, salt); 164 | }; 165 | 166 | /** 167 | * Asynchronously generates a hash for the given string. 168 | * @param {string} s String to hash 169 | * @param {number|string} salt Salt length to generate or salt to use 170 | * @param {function(Error, string=)} callback Callback receiving the error, if any, and the resulting hash 171 | * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed 172 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. 173 | * @expose 174 | */ 175 | bcrypt.hash = function(s, salt, callback, progressCallback) { 176 | if (typeof callback !== 'function') 177 | throw Error("Illegal callback: "+typeof(callback)); 178 | if (typeof s === 'string' && typeof salt === 'number') 179 | bcrypt.genSalt(salt, function(err, salt) { 180 | _hash(s, salt, callback, progressCallback); 181 | }); 182 | else if (typeof s === 'string' && typeof salt === 'string') 183 | _hash(s, salt, callback, progressCallback); 184 | else 185 | nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)))); 186 | }; 187 | 188 | /** 189 | * Synchronously tests a string against a hash. 190 | * @param {string} s String to compare 191 | * @param {string} hash Hash to test against 192 | * @returns {boolean} true if matching, otherwise false 193 | * @throws {Error} If an argument is illegal 194 | * @expose 195 | */ 196 | bcrypt.compareSync = function(s, hash) { 197 | if (typeof s !== "string" || typeof hash !== "string") 198 | throw Error("Illegal arguments: "+(typeof s)+', '+(typeof hash)); 199 | if (hash.length !== 60) 200 | return false; 201 | var comp = bcrypt.hashSync(s, hash.substr(0, hash.length-31)), 202 | same = comp.length === hash.length, 203 | max_length = (comp.length < hash.length) ? comp.length : hash.length; 204 | // to prevent timing attacks, should check entire string 205 | // don't exit after found to be false 206 | for (var i = 0; i < max_length; ++i) 207 | if (comp.length >= i && hash.length >= i && comp[i] != hash[i]) 208 | same = false; 209 | return same; 210 | }; 211 | 212 | /** 213 | * Asynchronously compares the given data against the given hash. 214 | * @param {string} s Data to compare 215 | * @param {string} hash Data to be compared to 216 | * @param {function(Error, boolean)} callback Callback receiving the error, if any, otherwise the result 217 | * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed 218 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. 219 | * @throws {Error} If the callback argument is invalid 220 | * @expose 221 | */ 222 | bcrypt.compare = function(s, hash, callback, progressCallback) { 223 | if (typeof callback !== 'function') 224 | throw Error("Illegal callback: "+typeof(callback)); 225 | if (typeof s !== "string" || typeof hash !== "string") { 226 | nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof hash)))); 227 | return; 228 | } 229 | bcrypt.hash(s, hash.substr(0, 29), function(err, comp) { 230 | callback(err, hash === comp); 231 | }, progressCallback); 232 | }; 233 | 234 | /** 235 | * Gets the number of rounds used to encrypt the specified hash. 236 | * @param {string} hash Hash to extract the used number of rounds from 237 | * @returns {number} Number of rounds used 238 | * @throws {Error} If hash is not a string 239 | * @expose 240 | */ 241 | bcrypt.getRounds = function(hash) { 242 | if (typeof hash !== "string") 243 | throw Error("Illegal arguments: "+(typeof hash)); 244 | return parseInt(hash.split("$")[2], 10); 245 | }; 246 | 247 | /** 248 | * Gets the salt portion from a hash. Does not validate the hash. 249 | * @param {string} hash Hash to extract the salt from 250 | * @returns {string} Extracted salt part 251 | * @throws {Error} If `hash` is not a string or otherwise invalid 252 | * @expose 253 | */ 254 | bcrypt.getSalt = function(hash) { 255 | if (typeof hash !== 'string') 256 | throw Error("Illegal arguments: "+(typeof hash)); 257 | if (hash.length !== 60) 258 | throw Error("Illegal hash length: "+hash.length+" != 60"); 259 | return hash.substring(0, 29); 260 | }; 261 | 262 | /** 263 | * Continues with the callback on the next tick. 264 | * @function 265 | * @param {function(...[*])} callback Callback to execute 266 | * @inner 267 | */ 268 | var nextTick = typeof process !== 'undefined' && process && typeof process.nextTick === 'function' 269 | ? (typeof setImmediate === 'function' ? setImmediate : process.nextTick) 270 | : setTimeout; 271 | 272 | /** 273 | * Converts a JavaScript string to UTF8 bytes. 274 | * @param {string} str String 275 | * @returns {!Array.} UTF8 bytes 276 | * @inner 277 | */ 278 | function stringToBytes(str) { 279 | var out = [], 280 | i = 0; 281 | utfx.encodeUTF16toUTF8(function() { 282 | if (i >= str.length) return null; 283 | return str.charCodeAt(i++); 284 | }, function(b) { 285 | out.push(b); 286 | }); 287 | return out; 288 | } 289 | 290 | // A base64 implementation for the bcrypt algorithm. This is partly non-standard. 291 | 292 | /** 293 | * bcrypt's own non-standard base64 dictionary. 294 | * @type {!Array.} 295 | * @const 296 | * @inner 297 | **/ 298 | var BASE64_CODE = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(''); 299 | 300 | /** 301 | * @type {!Array.} 302 | * @const 303 | * @inner 304 | **/ 305 | var BASE64_INDEX = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 306 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 307 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 308 | 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, 309 | -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 310 | 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30, 311 | 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 312 | 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1]; 313 | 314 | /** 315 | * @type {!function(...number):string} 316 | * @inner 317 | */ 318 | var stringFromCharCode = String.fromCharCode; 319 | 320 | /** 321 | * Encodes a byte array to base64 with up to len bytes of input. 322 | * @param {!Array.} b Byte array 323 | * @param {number} len Maximum input length 324 | * @returns {string} 325 | * @inner 326 | */ 327 | function base64_encode(b, len) { 328 | var off = 0, 329 | rs = [], 330 | c1, c2; 331 | if (len <= 0 || len > b.length) 332 | throw Error("Illegal len: "+len); 333 | while (off < len) { 334 | c1 = b[off++] & 0xff; 335 | rs.push(BASE64_CODE[(c1 >> 2) & 0x3f]); 336 | c1 = (c1 & 0x03) << 4; 337 | if (off >= len) { 338 | rs.push(BASE64_CODE[c1 & 0x3f]); 339 | break; 340 | } 341 | c2 = b[off++] & 0xff; 342 | c1 |= (c2 >> 4) & 0x0f; 343 | rs.push(BASE64_CODE[c1 & 0x3f]); 344 | c1 = (c2 & 0x0f) << 2; 345 | if (off >= len) { 346 | rs.push(BASE64_CODE[c1 & 0x3f]); 347 | break; 348 | } 349 | c2 = b[off++] & 0xff; 350 | c1 |= (c2 >> 6) & 0x03; 351 | rs.push(BASE64_CODE[c1 & 0x3f]); 352 | rs.push(BASE64_CODE[c2 & 0x3f]); 353 | } 354 | return rs.join(''); 355 | } 356 | 357 | /** 358 | * Decodes a base64 encoded string to up to len bytes of output. 359 | * @param {string} s String to decode 360 | * @param {number} len Maximum output length 361 | * @returns {!Array.} 362 | * @inner 363 | */ 364 | function base64_decode(s, len) { 365 | var off = 0, 366 | slen = s.length, 367 | olen = 0, 368 | rs = [], 369 | c1, c2, c3, c4, o, code; 370 | if (len <= 0) 371 | throw Error("Illegal len: "+len); 372 | while (off < slen - 1 && olen < len) { 373 | code = s.charCodeAt(off++); 374 | c1 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 375 | code = s.charCodeAt(off++); 376 | c2 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 377 | if (c1 == -1 || c2 == -1) 378 | break; 379 | o = (c1 << 2) >>> 0; 380 | o |= (c2 & 0x30) >> 4; 381 | rs.push(stringFromCharCode(o)); 382 | if (++olen >= len || off >= slen) 383 | break; 384 | code = s.charCodeAt(off++); 385 | c3 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 386 | if (c3 == -1) 387 | break; 388 | o = ((c2 & 0x0f) << 4) >>> 0; 389 | o |= (c3 & 0x3c) >> 2; 390 | rs.push(stringFromCharCode(o)); 391 | if (++olen >= len || off >= slen) 392 | break; 393 | code = s.charCodeAt(off++); 394 | c4 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; 395 | o = ((c3 & 0x03) << 6) >>> 0; 396 | o |= c4; 397 | rs.push(stringFromCharCode(o)); 398 | ++olen; 399 | } 400 | var res = []; 401 | for (off = 0; off 408 | * Released under the Apache License, Version 2.0 409 | * see: https://github.com/dcodeIO/utfx for details 410 | */ 411 | var utfx = function() { 412 | "use strict"; 413 | 414 | /** 415 | * utfx namespace. 416 | * @inner 417 | * @type {!Object.} 418 | */ 419 | var utfx = {}; 420 | 421 | /** 422 | * Maximum valid code point. 423 | * @type {number} 424 | * @const 425 | */ 426 | utfx.MAX_CODEPOINT = 0x10FFFF; 427 | 428 | /** 429 | * Encodes UTF8 code points to UTF8 bytes. 430 | * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point 431 | * respectively `null` if there are no more code points left or a single numeric code point. 432 | * @param {!function(number)} dst Bytes destination as a function successively called with the next byte 433 | */ 434 | utfx.encodeUTF8 = function(src, dst) { 435 | var cp = null; 436 | if (typeof src === 'number') 437 | cp = src, 438 | src = function() { return null; }; 439 | while (cp !== null || (cp = src()) !== null) { 440 | if (cp < 0x80) 441 | dst(cp&0x7F); 442 | else if (cp < 0x800) 443 | dst(((cp>>6)&0x1F)|0xC0), 444 | dst((cp&0x3F)|0x80); 445 | else if (cp < 0x10000) 446 | dst(((cp>>12)&0x0F)|0xE0), 447 | dst(((cp>>6)&0x3F)|0x80), 448 | dst((cp&0x3F)|0x80); 449 | else 450 | dst(((cp>>18)&0x07)|0xF0), 451 | dst(((cp>>12)&0x3F)|0x80), 452 | dst(((cp>>6)&0x3F)|0x80), 453 | dst((cp&0x3F)|0x80); 454 | cp = null; 455 | } 456 | }; 457 | 458 | /** 459 | * Decodes UTF8 bytes to UTF8 code points. 460 | * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there 461 | * are no more bytes left. 462 | * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. 463 | * @throws {RangeError} If a starting byte is invalid in UTF8 464 | * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the 465 | * remaining bytes. 466 | */ 467 | utfx.decodeUTF8 = function(src, dst) { 468 | var a, b, c, d, fail = function(b) { 469 | b = b.slice(0, b.indexOf(null)); 470 | var err = Error(b.toString()); 471 | err.name = "TruncatedError"; 472 | err['bytes'] = b; 473 | throw err; 474 | }; 475 | while ((a = src()) !== null) { 476 | if ((a&0x80) === 0) 477 | dst(a); 478 | else if ((a&0xE0) === 0xC0) 479 | ((b = src()) === null) && fail([a, b]), 480 | dst(((a&0x1F)<<6) | (b&0x3F)); 481 | else if ((a&0xF0) === 0xE0) 482 | ((b=src()) === null || (c=src()) === null) && fail([a, b, c]), 483 | dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F)); 484 | else if ((a&0xF8) === 0xF0) 485 | ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]), 486 | dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F)); 487 | else throw RangeError("Illegal starting byte: "+a); 488 | } 489 | }; 490 | 491 | /** 492 | * Converts UTF16 characters to UTF8 code points. 493 | * @param {!function():number|null} src Characters source as a function returning the next char code respectively 494 | * `null` if there are no more characters left. 495 | * @param {!function(number)} dst Code points destination as a function successively called with each converted code 496 | * point. 497 | */ 498 | utfx.UTF16toUTF8 = function(src, dst) { 499 | var c1, c2 = null; 500 | while (true) { 501 | if ((c1 = c2 !== null ? c2 : src()) === null) 502 | break; 503 | if (c1 >= 0xD800 && c1 <= 0xDFFF) { 504 | if ((c2 = src()) !== null) { 505 | if (c2 >= 0xDC00 && c2 <= 0xDFFF) { 506 | dst((c1-0xD800)*0x400+c2-0xDC00+0x10000); 507 | c2 = null; continue; 508 | } 509 | } 510 | } 511 | dst(c1); 512 | } 513 | if (c2 !== null) dst(c2); 514 | }; 515 | 516 | /** 517 | * Converts UTF8 code points to UTF16 characters. 518 | * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point 519 | * respectively `null` if there are no more code points left or a single numeric code point. 520 | * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. 521 | * @throws {RangeError} If a code point is out of range 522 | */ 523 | utfx.UTF8toUTF16 = function(src, dst) { 524 | var cp = null; 525 | if (typeof src === 'number') 526 | cp = src, src = function() { return null; }; 527 | while (cp !== null || (cp = src()) !== null) { 528 | if (cp <= 0xFFFF) 529 | dst(cp); 530 | else 531 | cp -= 0x10000, 532 | dst((cp>>10)+0xD800), 533 | dst((cp%0x400)+0xDC00); 534 | cp = null; 535 | } 536 | }; 537 | 538 | /** 539 | * Converts and encodes UTF16 characters to UTF8 bytes. 540 | * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` 541 | * if there are no more characters left. 542 | * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. 543 | */ 544 | utfx.encodeUTF16toUTF8 = function(src, dst) { 545 | utfx.UTF16toUTF8(src, function(cp) { 546 | utfx.encodeUTF8(cp, dst); 547 | }); 548 | }; 549 | 550 | /** 551 | * Decodes and converts UTF8 bytes to UTF16 characters. 552 | * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there 553 | * are no more bytes left. 554 | * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. 555 | * @throws {RangeError} If a starting byte is invalid in UTF8 556 | * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. 557 | */ 558 | utfx.decodeUTF8toUTF16 = function(src, dst) { 559 | utfx.decodeUTF8(src, function(cp) { 560 | utfx.UTF8toUTF16(cp, dst); 561 | }); 562 | }; 563 | 564 | /** 565 | * Calculates the byte length of an UTF8 code point. 566 | * @param {number} cp UTF8 code point 567 | * @returns {number} Byte length 568 | */ 569 | utfx.calculateCodePoint = function(cp) { 570 | return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; 571 | }; 572 | 573 | /** 574 | * Calculates the number of UTF8 bytes required to store UTF8 code points. 575 | * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively 576 | * `null` if there are no more code points left. 577 | * @returns {number} The number of UTF8 bytes required 578 | */ 579 | utfx.calculateUTF8 = function(src) { 580 | var cp, l=0; 581 | while ((cp = src()) !== null) 582 | l += utfx.calculateCodePoint(cp); 583 | return l; 584 | }; 585 | 586 | /** 587 | * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. 588 | * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively 589 | * `null` if there are no more characters left. 590 | * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. 591 | */ 592 | utfx.calculateUTF16asUTF8 = function(src) { 593 | var n=0, l=0; 594 | utfx.UTF16toUTF8(src, function(cp) { 595 | ++n; l += utfx.calculateCodePoint(cp); 596 | }); 597 | return [n,l]; 598 | }; 599 | 600 | return utfx; 601 | }(); 602 | 603 | Date.now = Date.now || function() { return +new Date; }; 604 | 605 | /** 606 | * @type {number} 607 | * @const 608 | * @inner 609 | */ 610 | var BCRYPT_SALT_LEN = 16; 611 | 612 | /** 613 | * @type {number} 614 | * @const 615 | * @inner 616 | */ 617 | var GENSALT_DEFAULT_LOG2_ROUNDS = 10; 618 | 619 | /** 620 | * @type {number} 621 | * @const 622 | * @inner 623 | */ 624 | var BLOWFISH_NUM_ROUNDS = 16; 625 | 626 | /** 627 | * @type {number} 628 | * @const 629 | * @inner 630 | */ 631 | var MAX_EXECUTION_TIME = 100; 632 | 633 | /** 634 | * @type {Array.} 635 | * @const 636 | * @inner 637 | */ 638 | var P_ORIG = [ 639 | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 640 | 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 641 | 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 642 | 0xb5470917, 0x9216d5d9, 0x8979fb1b 643 | ]; 644 | 645 | /** 646 | * @type {Array.} 647 | * @const 648 | * @inner 649 | */ 650 | var S_ORIG = [ 651 | 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 652 | 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 653 | 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 654 | 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 655 | 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 656 | 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 657 | 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 658 | 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 659 | 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 660 | 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 661 | 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 662 | 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 663 | 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 664 | 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 665 | 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 666 | 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 667 | 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 668 | 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 669 | 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 670 | 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 671 | 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 672 | 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 673 | 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 674 | 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 675 | 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 676 | 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 677 | 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 678 | 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 679 | 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 680 | 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 681 | 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 682 | 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 683 | 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 684 | 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 685 | 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 686 | 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 687 | 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 688 | 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 689 | 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 690 | 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 691 | 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 692 | 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 693 | 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 694 | 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 695 | 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 696 | 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 697 | 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 698 | 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 699 | 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 700 | 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 701 | 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 702 | 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 703 | 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 704 | 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 705 | 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 706 | 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 707 | 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 708 | 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 709 | 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 710 | 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 711 | 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 712 | 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 713 | 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 714 | 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 715 | 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 716 | 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 717 | 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 718 | 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 719 | 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 720 | 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 721 | 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 722 | 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 723 | 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 724 | 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 725 | 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 726 | 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 727 | 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 728 | 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 729 | 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 730 | 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 731 | 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 732 | 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 733 | 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 734 | 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 735 | 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 736 | 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 737 | 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 738 | 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 739 | 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 740 | 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 741 | 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 742 | 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 743 | 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 744 | 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 745 | 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 746 | 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 747 | 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 748 | 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 749 | 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 750 | 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 751 | 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 752 | 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 753 | 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 754 | 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 755 | 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 756 | 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 757 | 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 758 | 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 759 | 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 760 | 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 761 | 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 762 | 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 763 | 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 764 | 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 765 | 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 766 | 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 767 | 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 768 | 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 769 | 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 770 | 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 771 | 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 772 | 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 773 | 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 774 | 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 775 | 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 776 | 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 777 | 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 778 | 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 779 | 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 780 | 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 781 | 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 782 | 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 783 | 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 784 | 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 785 | 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 786 | 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 787 | 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 788 | 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 789 | 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 790 | 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 791 | 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 792 | 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 793 | 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 794 | 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 795 | 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 796 | 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 797 | 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 798 | 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 799 | 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 800 | 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 801 | 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 802 | 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 803 | 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 804 | 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, 805 | 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 806 | 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 807 | 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 808 | 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 809 | 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 810 | 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 811 | 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 812 | 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 813 | 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 814 | 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 815 | 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 816 | 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 817 | 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 818 | 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 819 | 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 820 | 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 821 | 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 822 | 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 823 | 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 824 | 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 825 | 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 826 | 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 827 | 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 828 | 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 829 | 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 830 | 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 831 | 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 832 | 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 833 | 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 834 | 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 835 | 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 836 | 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 837 | 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 838 | 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 839 | 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 840 | 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 841 | 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 842 | 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 843 | 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 844 | 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 845 | 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 846 | 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 847 | 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 848 | 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 849 | 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 850 | 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 851 | 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 852 | 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 853 | 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 854 | 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 855 | 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 856 | ]; 857 | 858 | /** 859 | * @type {Array.} 860 | * @const 861 | * @inner 862 | */ 863 | var C_ORIG = [ 864 | 0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, 865 | 0x6f756274 866 | ]; 867 | 868 | /** 869 | * @param {Array.} lr 870 | * @param {number} off 871 | * @param {Array.} P 872 | * @param {Array.} S 873 | * @returns {Array.} 874 | * @inner 875 | */ 876 | function _encipher(lr, off, P, S) { // This is our bottleneck: 1714/1905 ticks / 90% - see profile.txt 877 | var n, 878 | l = lr[off], 879 | r = lr[off + 1]; 880 | 881 | l ^= P[0]; 882 | for (var i=0, k=BLOWFISH_NUM_ROUNDS-2; i<=k;) 883 | // Feistel substitution on left word 884 | n = S[(l >> 24) & 0xff], 885 | n += S[0x100 | ((l >> 16) & 0xff)], 886 | n ^= S[0x200 | ((l >> 8) & 0xff)], 887 | n += S[0x300 | (l & 0xff)], 888 | r ^= n ^ P[++i], 889 | // Feistel substitution on right word 890 | n = S[(r >> 24) & 0xff], 891 | n += S[0x100 | ((r >> 16) & 0xff)], 892 | n ^= S[0x200 | ((r >> 8) & 0xff)], 893 | n += S[0x300 | (r & 0xff)], 894 | l ^= n ^ P[++i]; 895 | lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; 896 | lr[off + 1] = l; 897 | return lr; 898 | } 899 | 900 | /** 901 | * @param {Array.} data 902 | * @param {number} offp 903 | * @returns {{key: number, offp: number}} 904 | * @inner 905 | */ 906 | function _streamtoword(data, offp) { 907 | for (var i = 0, word = 0; i < 4; ++i) 908 | word = (word << 8) | (data[offp] & 0xff), 909 | offp = (offp + 1) % data.length; 910 | return { key: word, offp: offp }; 911 | } 912 | 913 | /** 914 | * @param {Array.} key 915 | * @param {Array.} P 916 | * @param {Array.} S 917 | * @inner 918 | */ 919 | function _key(key, P, S) { 920 | var offset = 0, 921 | lr = [0, 0], 922 | plen = P.length, 923 | slen = S.length, 924 | sw; 925 | for (var i = 0; i < plen; i++) 926 | sw = _streamtoword(key, offset), 927 | offset = sw.offp, 928 | P[i] = P[i] ^ sw.key; 929 | for (i = 0; i < plen; i += 2) 930 | lr = _encipher(lr, 0, P, S), 931 | P[i] = lr[0], 932 | P[i + 1] = lr[1]; 933 | for (i = 0; i < slen; i += 2) 934 | lr = _encipher(lr, 0, P, S), 935 | S[i] = lr[0], 936 | S[i + 1] = lr[1]; 937 | } 938 | 939 | /** 940 | * Expensive key schedule Blowfish. 941 | * @param {Array.} data 942 | * @param {Array.} key 943 | * @param {Array.} P 944 | * @param {Array.} S 945 | * @inner 946 | */ 947 | function _ekskey(data, key, P, S) { 948 | var offp = 0, 949 | lr = [0, 0], 950 | plen = P.length, 951 | slen = S.length, 952 | sw; 953 | for (var i = 0; i < plen; i++) 954 | sw = _streamtoword(key, offp), 955 | offp = sw.offp, 956 | P[i] = P[i] ^ sw.key; 957 | offp = 0; 958 | for (i = 0; i < plen; i += 2) 959 | sw = _streamtoword(data, offp), 960 | offp = sw.offp, 961 | lr[0] ^= sw.key, 962 | sw = _streamtoword(data, offp), 963 | offp = sw.offp, 964 | lr[1] ^= sw.key, 965 | lr = _encipher(lr, 0, P, S), 966 | P[i] = lr[0], 967 | P[i + 1] = lr[1]; 968 | for (i = 0; i < slen; i += 2) 969 | sw = _streamtoword(data, offp), 970 | offp = sw.offp, 971 | lr[0] ^= sw.key, 972 | sw = _streamtoword(data, offp), 973 | offp = sw.offp, 974 | lr[1] ^= sw.key, 975 | lr = _encipher(lr, 0, P, S), 976 | S[i] = lr[0], 977 | S[i + 1] = lr[1]; 978 | } 979 | 980 | /** 981 | * Internaly crypts a string. 982 | * @param {Array.} b Bytes to crypt 983 | * @param {Array.} salt Salt bytes to use 984 | * @param {number} rounds Number of rounds 985 | * @param {function(Error, Array.=)=} callback Callback receiving the error, if any, and the resulting bytes. If 986 | * omitted, the operation will be performed synchronously. 987 | * @param {function(number)=} progressCallback Callback called with the current progress 988 | * @returns {!Array.|undefined} Resulting bytes if callback has been omitted, otherwise `undefined` 989 | * @inner 990 | */ 991 | function _crypt(b, salt, rounds, callback, progressCallback) { 992 | var cdata = C_ORIG.slice(), 993 | clen = cdata.length, 994 | err; 995 | 996 | // Validate 997 | if (rounds < 4 || rounds > 31) { 998 | err = Error("Illegal number of rounds (4-31): "+rounds); 999 | if (callback) { 1000 | nextTick(callback.bind(this, err)); 1001 | return; 1002 | } else 1003 | throw err; 1004 | } 1005 | if (salt.length !== BCRYPT_SALT_LEN) { 1006 | err =Error("Illegal salt length: "+salt.length+" != "+BCRYPT_SALT_LEN); 1007 | if (callback) { 1008 | nextTick(callback.bind(this, err)); 1009 | return; 1010 | } else 1011 | throw err; 1012 | } 1013 | rounds = 1 << rounds; 1014 | var P = P_ORIG.slice(), 1015 | S = S_ORIG.slice(), 1016 | i = 0, j; 1017 | _ekskey(salt, b, P, S); 1018 | 1019 | /** 1020 | * Calcualtes the next round. 1021 | * @returns {Array.|undefined} Resulting array if callback has been omitted, otherwise `undefined` 1022 | * @inner 1023 | */ 1024 | function next() { 1025 | if (progressCallback) 1026 | progressCallback(i/rounds); 1027 | if (i < rounds) { 1028 | var start = Date.now(); 1029 | for (; i < rounds;) { 1030 | i = i + 1; 1031 | _key(b, P, S); 1032 | _key(salt, P, S); 1033 | if (Date.now() - start > MAX_EXECUTION_TIME) 1034 | break; 1035 | } 1036 | } else { 1037 | for (i = 0; i < 64; i++) 1038 | for (j = 0; j < (clen >> 1); j++) 1039 | _encipher(cdata, j << 1, P, S); 1040 | var ret = []; 1041 | for (i = 0; i < clen; i++) 1042 | ret.push(((cdata[i] >> 24) & 0xff) >>> 0), 1043 | ret.push(((cdata[i] >> 16) & 0xff) >>> 0), 1044 | ret.push(((cdata[i] >> 8) & 0xff) >>> 0), 1045 | ret.push((cdata[i] & 0xff) >>> 0); 1046 | if (callback) { 1047 | callback(null, ret); 1048 | return; 1049 | } else 1050 | return ret; 1051 | } 1052 | if (callback) 1053 | nextTick(next); 1054 | } 1055 | 1056 | // Async 1057 | if (typeof callback !== 'undefined') { 1058 | next(); 1059 | 1060 | // Sync 1061 | } else { 1062 | var res; 1063 | while (true) 1064 | if (typeof(res = next()) !== 'undefined') 1065 | return res || []; 1066 | } 1067 | } 1068 | 1069 | /** 1070 | * Internally hashes a string. 1071 | * @param {string} s String to hash 1072 | * @param {?string} salt Salt to use, actually never null 1073 | * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash. If omitted, 1074 | * hashing is perormed synchronously. 1075 | * @param {function(number)=} progressCallback Callback called with the current progress 1076 | * @returns {string|undefined} Resulting hash if callback has been omitted, otherwise `undefined` 1077 | * @inner 1078 | */ 1079 | function _hash(s, salt, callback, progressCallback) { 1080 | var err; 1081 | if (typeof s !== 'string' || typeof salt !== 'string') { 1082 | err = Error("Invalid string / salt: Not a string"); 1083 | if (callback) { 1084 | nextTick(callback.bind(this, err)); 1085 | return; 1086 | } 1087 | else 1088 | throw err; 1089 | } 1090 | 1091 | // Validate the salt 1092 | var minor, offset; 1093 | if (salt.charAt(0) !== '$' || salt.charAt(1) !== '2') { 1094 | err = Error("Invalid salt version: "+salt.substring(0,2)); 1095 | if (callback) { 1096 | nextTick(callback.bind(this, err)); 1097 | return; 1098 | } 1099 | else 1100 | throw err; 1101 | } 1102 | if (salt.charAt(2) === '$') 1103 | minor = String.fromCharCode(0), 1104 | offset = 3; 1105 | else { 1106 | minor = salt.charAt(2); 1107 | if ((minor !== 'a' && minor !== 'y') || salt.charAt(3) !== '$') { 1108 | err = Error("Invalid salt revision: "+salt.substring(2,4)); 1109 | if (callback) { 1110 | nextTick(callback.bind(this, err)); 1111 | return; 1112 | } else 1113 | throw err; 1114 | } 1115 | offset = 4; 1116 | } 1117 | 1118 | // Extract number of rounds 1119 | if (salt.charAt(offset + 2) > '$') { 1120 | err = Error("Missing salt rounds"); 1121 | if (callback) { 1122 | nextTick(callback.bind(this, err)); 1123 | return; 1124 | } else 1125 | throw err; 1126 | } 1127 | var r1 = parseInt(salt.substring(offset, offset + 1), 10) * 10, 1128 | r2 = parseInt(salt.substring(offset + 1, offset + 2), 10), 1129 | rounds = r1 + r2, 1130 | real_salt = salt.substring(offset + 3, offset + 25); 1131 | s += minor >= 'a' ? "\x00" : ""; 1132 | 1133 | var passwordb = stringToBytes(s), 1134 | saltb = base64_decode(real_salt, BCRYPT_SALT_LEN); 1135 | 1136 | /** 1137 | * Finishes hashing. 1138 | * @param {Array.} bytes Byte array 1139 | * @returns {string} 1140 | * @inner 1141 | */ 1142 | function finish(bytes) { 1143 | var res = []; 1144 | res.push("$2"); 1145 | if (minor >= 'a') 1146 | res.push(minor); 1147 | res.push("$"); 1148 | if (rounds < 10) 1149 | res.push("0"); 1150 | res.push(rounds.toString()); 1151 | res.push("$"); 1152 | res.push(base64_encode(saltb, saltb.length)); 1153 | res.push(base64_encode(bytes, C_ORIG.length * 4 - 1)); 1154 | return res.join(''); 1155 | } 1156 | 1157 | // Sync 1158 | if (typeof callback == 'undefined') 1159 | return finish(_crypt(passwordb, saltb, rounds)); 1160 | 1161 | // Async 1162 | else { 1163 | _crypt(passwordb, saltb, rounds, function(err, bytes) { 1164 | if (err) 1165 | callback(err, null); 1166 | else 1167 | callback(null, finish(bytes)); 1168 | }, progressCallback); 1169 | } 1170 | } 1171 | 1172 | 1173 | /* CommonJS */ if (typeof module !== 'undefined' && module["exports"]) 1174 | module["exports"] = bcrypt; 1175 | /* AMD */ else if (typeof define !== 'undefined' && define["amd"]) 1176 | define(function() { return bcrypt; }); 1177 | /* Global */ else 1178 | (global["dcodeIO"] = global["dcodeIO"] || {})["bcrypt"] = bcrypt; 1179 | 1180 | })(this); 1181 | --------------------------------------------------------------------------------