crypto: expose scrypt.

This commit is contained in:
Christopher Jeffrey 2016-09-12 22:55:47 -07:00
parent a52f239f3c
commit 2dba490d02
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
7 changed files with 66 additions and 34 deletions

View File

@ -9,6 +9,8 @@
var assert = require('assert');
var random = require('./random');
var scrypt = require('./scrypt');
var scryptAsync = require('./scrypt-async');
var native = require('../utils/native');
var nativeCrypto, supersha, hash, aes;
@ -139,7 +141,7 @@ if (native)
crypto.hmac = native.hmac;
/**
* Perform key stretching using PBKDF2.
* Perform key derivation using PBKDF2.
* @param {Buffer} key
* @param {Buffer} salt
* @param {Number} iter
@ -148,7 +150,7 @@ if (native)
* @returns {Buffer}
*/
crypto.pbkdf2Sync = function pbkdf2Sync(key, salt, iter, len, alg) {
crypto.pbkdf2 = function pbkdf2(key, salt, iter, len, alg) {
if (typeof key === 'string')
key = new Buffer(key, 'utf8');
@ -171,7 +173,7 @@ crypto.pbkdf2Sync = function pbkdf2Sync(key, salt, iter, len, alg) {
* @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;
if (typeof key === 'string')
@ -192,6 +194,48 @@ crypto.pbkdf2 = function pbkdf2(key, salt, iter, len, alg, callback) {
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.
* @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.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
* @param {Buffer} key
* @param {Buffer} salt

View File

@ -51,18 +51,9 @@ var U32Array = typeof Uint32Array === 'function' ? Uint32Array : Array;
* @returns {Buffer}
*/
function scrypt(passwd, salt, N, r, p, len, callback) {
function scryptAsync(passwd, salt, N, r, p, len, callback) {
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))
return callback(new Error('EFBIG'));
@ -75,7 +66,7 @@ function scrypt(passwd, salt, N, r, p, len, callback) {
XY = new Buffer(256 * r);
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)
return callback(err);
@ -85,11 +76,14 @@ function scrypt(passwd, salt, N, r, p, len, callback) {
if (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) {
var B32 = new U32Array(16);
var x = new U32Array(16);
@ -232,4 +226,4 @@ function forRangeSerial(from, to, iter, callback) {
* Expose
*/
module.exports = scrypt;
module.exports = scryptAsync;

View File

@ -53,15 +53,6 @@ var U32Array = typeof Uint32Array === 'function' ? Uint32Array : Array;
function scrypt(passwd, salt, N, r, p, len) {
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))
throw new Error('EFBIG');
@ -74,14 +65,17 @@ function scrypt(passwd, salt, N, r, p, len) {
XY = new Buffer(256 * r);
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++)
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) {
var B32 = new U32Array(16);
var x = new U32Array(16);

View File

@ -142,7 +142,7 @@ Mnemonic.prototype.toSeed = function toSeed(passphrase) {
this.passphrase = passphrase;
return crypto.pbkdf2Sync(
return crypto.pbkdf2(
nfkd(this.getPhrase()),
nfkd('mnemonic' + passphrase),
2048, 64, 'sha512');

View File

@ -9,7 +9,7 @@ var nativeCrypto = require('crypto');
describe('AES', function() {
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 {
key: key.slice(0, dkLen),
iv: key.slice(dkLen, dkLen + ivLen)

View File

@ -91,7 +91,7 @@ describe('HD', function() {
var master, child1, child2, child3, child4, child5, child6;
it('should create a pbkdf2 seed', function() {
var checkSeed = crypto.pbkdf2Sync(
var checkSeed = crypto.pbkdf2(
phrase, 'mnemonic' + 'foo', 2048, 64, 'sha512').toString('hex');
assert.equal(checkSeed, seed);
});

View File

@ -1,7 +1,7 @@
'use strict';
var assert = require('assert');
var scrypt = require('../lib/crypto/scrypt');
var scrypt = require('../lib/crypto/crypto').scrypt;
describe('Scrypt', function() {
it('should perform scrypt with N=16', function() {
@ -13,7 +13,7 @@ describe('Scrypt', 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'), ''
+ 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773'
+ '76634b3731622eaf30d92e22a3886ff109279d9830dac727afb9'