crypto: expose scrypt.
This commit is contained in:
parent
a52f239f3c
commit
2dba490d02
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var random = require('./random');
|
var random = require('./random');
|
||||||
|
var scrypt = require('./scrypt');
|
||||||
|
var scryptAsync = require('./scrypt-async');
|
||||||
var native = require('../utils/native');
|
var native = require('../utils/native');
|
||||||
var nativeCrypto, supersha, hash, aes;
|
var nativeCrypto, supersha, hash, aes;
|
||||||
|
|
||||||
@ -139,7 +141,7 @@ if (native)
|
|||||||
crypto.hmac = native.hmac;
|
crypto.hmac = native.hmac;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform key stretching using PBKDF2.
|
* Perform key derivation using PBKDF2.
|
||||||
* @param {Buffer} key
|
* @param {Buffer} key
|
||||||
* @param {Buffer} salt
|
* @param {Buffer} salt
|
||||||
* @param {Number} iter
|
* @param {Number} iter
|
||||||
@ -148,7 +150,7 @@ if (native)
|
|||||||
* @returns {Buffer}
|
* @returns {Buffer}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
crypto.pbkdf2Sync = function pbkdf2Sync(key, salt, iter, len, alg) {
|
crypto.pbkdf2 = function pbkdf2(key, salt, iter, len, alg) {
|
||||||
if (typeof key === 'string')
|
if (typeof key === 'string')
|
||||||
key = new Buffer(key, 'utf8');
|
key = new Buffer(key, 'utf8');
|
||||||
|
|
||||||
@ -171,7 +173,7 @@ crypto.pbkdf2Sync = function pbkdf2Sync(key, salt, iter, len, alg) {
|
|||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
|
|
||||||
crypto.pbkdf2 = function pbkdf2(key, salt, iter, len, alg, callback) {
|
crypto.pbkdf2Async = function pbkdf2Async(key, salt, iter, len, alg, callback) {
|
||||||
var result;
|
var result;
|
||||||
|
|
||||||
if (typeof key === 'string')
|
if (typeof key === 'string')
|
||||||
@ -192,6 +194,48 @@ crypto.pbkdf2 = function pbkdf2(key, salt, iter, len, alg, callback) {
|
|||||||
return callback(null, result);
|
return callback(null, result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform key derivation using scrypt.
|
||||||
|
* @param {Buffer} passwd
|
||||||
|
* @param {Buffer} salt
|
||||||
|
* @param {Number} N
|
||||||
|
* @param {Number} r
|
||||||
|
* @param {Number} p
|
||||||
|
* @param {Number} len
|
||||||
|
* @returns {Buffer}
|
||||||
|
*/
|
||||||
|
|
||||||
|
crypto.scrypt = function _scrypt(passwd, salt, N, r, p, len) {
|
||||||
|
if (typeof passwd === 'string')
|
||||||
|
passwd = new Buffer(passwd, 'utf8');
|
||||||
|
|
||||||
|
if (typeof salt === 'string')
|
||||||
|
salt = new Buffer(salt, 'utf8');
|
||||||
|
|
||||||
|
return scrypt(passwd, salt, N, r, p, len);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute scrypt asynchronously.
|
||||||
|
* @param {Buffer} passwd
|
||||||
|
* @param {Buffer} salt
|
||||||
|
* @param {Number} N
|
||||||
|
* @param {Number} r
|
||||||
|
* @param {Number} p
|
||||||
|
* @param {Number} len
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
crypto.scryptAsync = function _scryptAsync(passwd, salt, N, r, p, len, callback) {
|
||||||
|
if (typeof passwd === 'string')
|
||||||
|
passwd = new Buffer(passwd, 'utf8');
|
||||||
|
|
||||||
|
if (typeof salt === 'string')
|
||||||
|
salt = new Buffer(salt, 'utf8');
|
||||||
|
|
||||||
|
return scryptAsync(passwd, salt, N, r, p, len, callback);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derive a key using pbkdf2 with 50,000 iterations.
|
* Derive a key using pbkdf2 with 50,000 iterations.
|
||||||
* @param {Buffer|String} passphrase
|
* @param {Buffer|String} passphrase
|
||||||
@ -199,7 +243,7 @@ crypto.pbkdf2 = function pbkdf2(key, salt, iter, len, alg, callback) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
crypto.derive = function derive(passphrase, callback) {
|
crypto.derive = function derive(passphrase, callback) {
|
||||||
crypto.pbkdf2(passphrase, 'bcoin', 50000, 32, 'sha256', callback);
|
crypto.pbkdf2Async(passphrase, 'bcoin', 50000, 32, 'sha256', callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -304,7 +348,7 @@ crypto.decipher = function decipher(data, key, iv) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform key stretching using PBKDF2.
|
* Perform key derivation using PBKDF2.
|
||||||
* @private
|
* @private
|
||||||
* @param {Buffer} key
|
* @param {Buffer} key
|
||||||
* @param {Buffer} salt
|
* @param {Buffer} salt
|
||||||
|
|||||||
@ -51,18 +51,9 @@ var U32Array = typeof Uint32Array === 'function' ? Uint32Array : Array;
|
|||||||
* @returns {Buffer}
|
* @returns {Buffer}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function scrypt(passwd, salt, N, r, p, len, callback) {
|
function scryptAsync(passwd, salt, N, r, p, len, callback) {
|
||||||
var V, XY;
|
var V, XY;
|
||||||
|
|
||||||
if (typeof passwd === 'string')
|
|
||||||
passwd = new Buffer(passwd, 'utf8');
|
|
||||||
|
|
||||||
if (typeof salt === 'string')
|
|
||||||
salt = new Buffer(salt, 'utf8');
|
|
||||||
|
|
||||||
if (native)
|
|
||||||
return native.scryptAsync(passwd, salt, N, r, p, len, callback);
|
|
||||||
|
|
||||||
if (r * p >= (1 << 30))
|
if (r * p >= (1 << 30))
|
||||||
return callback(new Error('EFBIG'));
|
return callback(new Error('EFBIG'));
|
||||||
|
|
||||||
@ -75,7 +66,7 @@ function scrypt(passwd, salt, N, r, p, len, callback) {
|
|||||||
XY = new Buffer(256 * r);
|
XY = new Buffer(256 * r);
|
||||||
V = new Buffer(128 * r * N);
|
V = new Buffer(128 * r * N);
|
||||||
|
|
||||||
crypto.pbkdf2(passwd, salt, 1, p * 128 * r, 'sha256', function(err, B) {
|
crypto.pbkdf2Async(passwd, salt, 1, p * 128 * r, 'sha256', function(err, B) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
@ -85,11 +76,14 @@ function scrypt(passwd, salt, N, r, p, len, callback) {
|
|||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
crypto.pbkdf2(passwd, B, 1, len, 'sha256', callback);
|
crypto.pbkdf2Async(passwd, B, 1, len, 'sha256', callback);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (native)
|
||||||
|
scryptAsync = native.scryptAsync;
|
||||||
|
|
||||||
function salsa20_8(B) {
|
function salsa20_8(B) {
|
||||||
var B32 = new U32Array(16);
|
var B32 = new U32Array(16);
|
||||||
var x = new U32Array(16);
|
var x = new U32Array(16);
|
||||||
@ -232,4 +226,4 @@ function forRangeSerial(from, to, iter, callback) {
|
|||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = scrypt;
|
module.exports = scryptAsync;
|
||||||
|
|||||||
@ -53,15 +53,6 @@ var U32Array = typeof Uint32Array === 'function' ? Uint32Array : Array;
|
|||||||
function scrypt(passwd, salt, N, r, p, len) {
|
function scrypt(passwd, salt, N, r, p, len) {
|
||||||
var i, B, V, XY;
|
var i, B, V, XY;
|
||||||
|
|
||||||
if (typeof passwd === 'string')
|
|
||||||
passwd = new Buffer(passwd, 'utf8');
|
|
||||||
|
|
||||||
if (typeof salt === 'string')
|
|
||||||
salt = new Buffer(salt, 'utf8');
|
|
||||||
|
|
||||||
if (native)
|
|
||||||
return native.scrypt(passwd, salt, N, r, p, len);
|
|
||||||
|
|
||||||
if (r * p >= (1 << 30))
|
if (r * p >= (1 << 30))
|
||||||
throw new Error('EFBIG');
|
throw new Error('EFBIG');
|
||||||
|
|
||||||
@ -74,14 +65,17 @@ function scrypt(passwd, salt, N, r, p, len) {
|
|||||||
XY = new Buffer(256 * r);
|
XY = new Buffer(256 * r);
|
||||||
V = new Buffer(128 * r * N);
|
V = new Buffer(128 * r * N);
|
||||||
|
|
||||||
B = crypto.pbkdf2Sync(passwd, salt, 1, p * 128 * r, 'sha256');
|
B = crypto.pbkdf2(passwd, salt, 1, p * 128 * r, 'sha256');
|
||||||
|
|
||||||
for (i = 0; i < p; i++)
|
for (i = 0; i < p; i++)
|
||||||
smix(B, i * 128 * r, r, N, V, XY);
|
smix(B, i * 128 * r, r, N, V, XY);
|
||||||
|
|
||||||
return crypto.pbkdf2Sync(passwd, B, 1, len, 'sha256');
|
return crypto.pbkdf2(passwd, B, 1, len, 'sha256');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (native)
|
||||||
|
scrypt = native.scrypt;
|
||||||
|
|
||||||
function salsa20_8(B) {
|
function salsa20_8(B) {
|
||||||
var B32 = new U32Array(16);
|
var B32 = new U32Array(16);
|
||||||
var x = new U32Array(16);
|
var x = new U32Array(16);
|
||||||
|
|||||||
@ -142,7 +142,7 @@ Mnemonic.prototype.toSeed = function toSeed(passphrase) {
|
|||||||
|
|
||||||
this.passphrase = passphrase;
|
this.passphrase = passphrase;
|
||||||
|
|
||||||
return crypto.pbkdf2Sync(
|
return crypto.pbkdf2(
|
||||||
nfkd(this.getPhrase()),
|
nfkd(this.getPhrase()),
|
||||||
nfkd('mnemonic' + passphrase),
|
nfkd('mnemonic' + passphrase),
|
||||||
2048, 64, 'sha512');
|
2048, 64, 'sha512');
|
||||||
|
|||||||
@ -9,7 +9,7 @@ var nativeCrypto = require('crypto');
|
|||||||
|
|
||||||
describe('AES', function() {
|
describe('AES', function() {
|
||||||
function pbkdf2key(passphrase, iterations, dkLen, ivLen, alg) {
|
function pbkdf2key(passphrase, iterations, dkLen, ivLen, alg) {
|
||||||
var key = crypto.pbkdf2Sync(passphrase, '', iterations, dkLen + ivLen, 'sha512');
|
var key = crypto.pbkdf2(passphrase, '', iterations, dkLen + ivLen, 'sha512');
|
||||||
return {
|
return {
|
||||||
key: key.slice(0, dkLen),
|
key: key.slice(0, dkLen),
|
||||||
iv: key.slice(dkLen, dkLen + ivLen)
|
iv: key.slice(dkLen, dkLen + ivLen)
|
||||||
|
|||||||
@ -91,7 +91,7 @@ describe('HD', function() {
|
|||||||
var master, child1, child2, child3, child4, child5, child6;
|
var master, child1, child2, child3, child4, child5, child6;
|
||||||
|
|
||||||
it('should create a pbkdf2 seed', function() {
|
it('should create a pbkdf2 seed', function() {
|
||||||
var checkSeed = crypto.pbkdf2Sync(
|
var checkSeed = crypto.pbkdf2(
|
||||||
phrase, 'mnemonic' + 'foo', 2048, 64, 'sha512').toString('hex');
|
phrase, 'mnemonic' + 'foo', 2048, 64, 'sha512').toString('hex');
|
||||||
assert.equal(checkSeed, seed);
|
assert.equal(checkSeed, seed);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var scrypt = require('../lib/crypto/scrypt');
|
var scrypt = require('../lib/crypto/crypto').scrypt;
|
||||||
|
|
||||||
describe('Scrypt', function() {
|
describe('Scrypt', function() {
|
||||||
it('should perform scrypt with N=16', function() {
|
it('should perform scrypt with N=16', function() {
|
||||||
@ -13,7 +13,7 @@ describe('Scrypt', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should perform scrypt with N=1024', function() {
|
it('should perform scrypt with N=1024', function() {
|
||||||
var result = scrypt('password', 'NaCl', 1024, 8, 16, 64)
|
var result = scrypt('password', 'NaCl', 1024, 8, 16, 64);
|
||||||
assert.equal(result.toString('hex'), ''
|
assert.equal(result.toString('hex'), ''
|
||||||
+ 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773'
|
+ 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773'
|
||||||
+ '76634b3731622eaf30d92e22a3886ff109279d9830dac727afb9'
|
+ '76634b3731622eaf30d92e22a3886ff109279d9830dac727afb9'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user