refactor utils.

This commit is contained in:
Christopher Jeffrey 2016-04-30 19:43:00 -07:00
parent 22680ff235
commit 74a5a39bf7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 79 additions and 62 deletions

View File

@ -455,7 +455,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
data = p.render();
hash = utils.sha512hmac(data, this.chainCode);
hash = utils.hmac('sha512', data, this.chainCode);
leftPart = new bn(hash.slice(0, 32));
chainCode = hash.slice(32, 64);
@ -699,7 +699,7 @@ HDPrivateKey.parseSeed = function parseSeed(seed, networkType) {
throw new Error('Entropy not in range.');
}
hash = utils.sha512hmac(data, 'Bitcoin seed');
hash = utils.hmac('sha512', data, 'Bitcoin seed');
return {
version: networkType
@ -1045,7 +1045,7 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
p.writeU32BE(index);
data = p.render();
hash = utils.sha512hmac(data, this.chainCode);
hash = utils.hmac('sha512', data, this.chainCode);
leftPart = new bn(hash.slice(0, 32));
chainCode = hash.slice(32, 64);

View File

@ -197,6 +197,21 @@ utils.isBase58 = function isBase58(msg) {
return typeof msg === 'string' && /^[1-9a-zA-Z]+$/.test(msg);
};
/**
* Hash with chosen algorithm.
* @param {String} alg
* @param {Buffer|String} data
* @param {String?} enc - Any buffer-supported encoding.
* @returns {Buffer}
*/
utils.hash = function _hash(alg, data, enc) {
if (!crypto)
return new Buffer(hash[alg]().update(data, enc).digest());
return crypto.createHash(alg).update(data, enc).digest();
};
/**
* Hash with ripemd160.
* @param {Buffer|String} data
@ -205,10 +220,7 @@ utils.isBase58 = function isBase58(msg) {
*/
utils.ripemd160 = function ripemd160(data, enc) {
if (!crypto)
return new Buffer(hash.ripemd160().update(data, enc).digest());
return crypto.createHash('ripemd160').update(data, enc).digest();
return utils.hash('ripemd160', data, enc);
};
/**
@ -219,10 +231,18 @@ utils.ripemd160 = function ripemd160(data, enc) {
*/
utils.sha1 = function sha1(data, enc) {
if (!crypto)
return new Buffer(hash.sha1().update(data, enc).digest());
return utils.hash('sha1', data, enc);
};
return crypto.createHash('sha1').update(data, enc).digest();
/**
* Hash with sha256.
* @param {Buffer|String} data
* @param {String?} enc - Any buffer-supported encoding.
* @returns {Buffer}
*/
utils.sha256 = function sha256(data, enc) {
return utils.hash('sha256', data, enc);
};
/**
@ -236,31 +256,6 @@ utils.ripesha = function ripesha(data, enc) {
return utils.ripemd160(utils.sha256(data, enc));
};
/**
* Create a sha256 checksum (common in bitcoin).
* @param {Buffer|String} data
* @param {String?} enc - Any buffer-supported encoding.
* @returns {Buffer}
*/
utils.checksum = function checksum(data, enc) {
return utils.dsha256(data, enc).slice(0, 4);
};
/**
* Hash with sha256.
* @param {Buffer|String} data
* @param {String?} enc - Any buffer-supported encoding.
* @returns {Buffer}
*/
utils.sha256 = function sha256(data, enc) {
if (!crypto)
return new Buffer(hash.sha256().update(data, enc).digest());
return crypto.createHash('sha256').update(data, enc).digest();
};
/**
* Hash with sha256 twice (OP_HASH256).
* @param {Buffer|String} data
@ -273,24 +268,34 @@ utils.dsha256 = function dsha256(data, enc) {
};
/**
* Create a sha512 HMAC.
* Create a sha256 checksum (common in bitcoin).
* @param {Buffer|String} data
* @param {String?} enc - Any buffer-supported encoding.
* @returns {Buffer}
*/
utils.checksum = function checksum(data, enc) {
return utils.dsha256(data, enc).slice(0, 4);
};
/**
* Create an HMAC.
* @param {String} alg
* @param {Buffer} data
* @param {Buffer} salt
* @returns {Buffer} HMAC
*/
utils.sha512hmac = function sha512hmac(data, salt) {
var hmac, result;
utils.hmac = function hmac(alg, data, salt) {
var hmac;
if (!crypto) {
hmac = hash.hmac(hash.sha512, salt);
hmac = hash.hmac(hash[alg], salt);
return new Buffer(hmac.update(data).digest());
}
hmac = crypto.createHmac('sha512', salt);
result = hmac.update(data).digest();
return result;
hmac = crypto.createHmac(alg, salt);
return hmac.update(data).digest();
};
/**
@ -299,6 +304,7 @@ utils.sha512hmac = function sha512hmac(data, salt) {
* @param {Buffer} salt
* @param {Number} iterations
* @param {Number} dkLen - Output size.
* @param {String?} alg
*/
/*!
@ -308,9 +314,8 @@ utils.sha512hmac = function sha512hmac(data, salt) {
* Copyright (c) 2014, JP Richardson
*/
utils.pbkdf2 = function pbkdf2(key, salt, iterations, dkLen) {
var hLen = 64;
var DK, U, T, block1, l, r;
utils.pbkdf2 = function pbkdf2(key, salt, iterations, dkLen, alg) {
var hLen, DK, U, T, block, l, r;
var i, j, k, destPos, len;
if (typeof key === 'string')
@ -319,33 +324,44 @@ utils.pbkdf2 = function pbkdf2(key, salt, iterations, dkLen) {
if (typeof salt === 'string')
salt = new Buffer(salt, 'utf8');
if (!alg)
alg = 'sha512';
if (crypto && crypto.pbkdf2Sync)
return crypto.pbkdf2Sync(key, salt, iterations, dkLen, 'sha512');
return crypto.pbkdf2Sync(key, salt, iterations, dkLen, alg);
if (alg === 'sha512')
hLen = 64;
else if (alg === 'sha256')
hLen = 32;
else if (alg === 'sha1' || alg === 'ripemd160')
hLen = 20;
else if (alg === 'md5')
hLen = 16;
assert(dkLen <= 0xffffffff * hLen, 'Requested key length too long');
DK = new Buffer(dkLen);
U = new Buffer(hLen);
T = new Buffer(hLen);
block1 = new Buffer(salt.length + 4);
block = new Buffer(salt.length + 4);
l = Math.ceil(dkLen / hLen);
r = dkLen - (l - 1) * hLen;
salt.copy(block1, 0, 0, salt.length);
salt.copy(block, 0, 0, salt.length);
for (i = 1; i <= l; i++) {
block1[salt.length + 0] = i >> 24 & 0xff;
block1[salt.length + 1] = i >> 16 & 0xff;
block1[salt.length + 2] = i >> 8 & 0xff;
block1[salt.length + 3] = i >> 0 & 0xff;
block[salt.length + 0] = (i >>> 24) & 0xff;
block[salt.length + 1] = (i >>> 16) & 0xff;
block[salt.length + 2] = (i >>> 8) & 0xff;
block[salt.length + 3] = (i >>> 0) & 0xff;
U = utils.sha512hmac(block1, key);
U = utils.hmac(alg, block, key);
U.copy(T, 0, 0, hLen);
for (j = 1; j < iterations; j++) {
U = utils.sha512hmac(U, key);
U = utils.hmac(alg, U, key);
for (k = 0; k < hLen; k++)
T[k] ^= U[k];
@ -428,16 +444,17 @@ utils.decrypt = function decrypt(data, passphrase) {
* @param {Buffer|String} passphrase
* @param {(Buffer|String)?} salt
* @param {Number} iterations
* @param {Number} keySize - Key size in bits.
* @param {Number} ivSize - IV size in bytes.
* @param {Number} dkLen
* @param {Number} ivLen
* @param {String?} alg
* @returns {Buffer}
*/
utils.pbkdf2key = function pbkdf2key(passphrase, salt, iterations, keySize, ivSize) {
var key = utils.pbkdf2(passphrase, salt || '', iterations, keySize + ivSize);
utils.pbkdf2key = function pbkdf2key(passphrase, salt, iterations, dkLen, ivLen, alg) {
var key = utils.pbkdf2(passphrase, salt || '', iterations, dkLen + ivLen, alg);
return {
key: key.slice(0, keySize),
iv: key.slice(keySize)
key: key.slice(0, dkLen),
iv: key.slice(dkLen)
};
};