formatting changes.

This commit is contained in:
Christopher Jeffrey 2015-12-07 15:51:15 -08:00
parent b1e7cde3dd
commit 37e1c8a2ef
2 changed files with 83 additions and 87 deletions

View File

@ -68,9 +68,9 @@ var ec = elliptic.curves.secp256k1;
*/ */
function HDSeed(options) { function HDSeed(options) {
if (!(this instanceof HDSeed)) { if (!(this instanceof HDSeed))
return new HDSeed(options); return new HDSeed(options);
}
this.bits = options.bits || 128; this.bits = options.bits || 128;
this.entropy = options.entropy || HDSeed._entropy(this.bits / 8); this.entropy = options.entropy || HDSeed._entropy(this.bits / 8);
this.mnemonic = options.mnemonic || HDSeed._mnemonic(this.entropy); this.mnemonic = options.mnemonic || HDSeed._mnemonic(this.entropy);
@ -131,21 +131,17 @@ var PATH_ROOTS = ['m', 'M', 'm\'', 'M\''];
function HDPriv(options) { function HDPriv(options) {
var data; var data;
if (!(this instanceof HDPriv)) { if (!(this instanceof HDPriv))
return new HDPriv(options); return new HDPriv(options);
}
if (!options) { if (!options)
options = { seed: new HDSeed({ passphrase: '' }) }; options = { seed: new HDSeed({ passphrase: '' }) };
}
if (typeof options === 'string' && options.indexOf('xprv') === 0) { if (typeof options === 'string' && options.indexOf('xprv') === 0)
options = { xkey: options }; options = { xkey: options };
}
if (options.passphrase) { if (options.passphrase)
options.seed = new HDSeed({ passphrase: options.passphrase }); options.seed = new HDSeed({ passphrase: options.passphrase });
}
if (options.seed) { if (options.seed) {
if (typeof options.seed === 'object' && !(options.seed instanceof HDSeed)) { if (typeof options.seed === 'object' && !(options.seed instanceof HDSeed)) {
@ -168,53 +164,60 @@ function HDPriv(options) {
HDPriv.prototype._normalize = function(data, version) { HDPriv.prototype._normalize = function(data, version) {
var b; var b;
data.version = version || VERSION.xprivkey; data.version = version || VERSION.xprivkey;
data.version = +data.version; data.version = +data.version;
data.depth = +data.depth; data.depth = +data.depth;
if (typeof data.parentFingerPrint === 'number') { if (typeof data.parentFingerPrint === 'number') {
b = []; b = [];
utils.writeU32BE(b, data.parentFingerPrint, 0); utils.writeU32BE(b, data.parentFingerPrint, 0);
data.parentFingerPrint = b; data.parentFingerPrint = b;
} }
data.childIndex = +data.childIndex; data.childIndex = +data.childIndex;
if (typeof data.chainCode === 'string') {
if (typeof data.chainCode === 'string')
data.chainCode = utils.toArray(data.chainCode, 'hex'); data.chainCode = utils.toArray(data.chainCode, 'hex');
}
data.privateKey = data.privateKey || data.priv; data.privateKey = data.privateKey || data.priv;
if (data.privateKey) { if (data.privateKey) {
if (data.privateKey.getPrivate) { if (data.privateKey.getPrivate)
data.privateKey = data.privateKey.getPrivate().toArray(); data.privateKey = data.privateKey.getPrivate().toArray();
} else if (typeof data.privateKey === 'string') { else if (typeof data.privateKey === 'string')
data.privateKey = utils.toArray(data.privateKey, 'hex'); data.privateKey = utils.toArray(data.privateKey, 'hex');
}
} }
data.publicKey = data.publicKey || data.pub; data.publicKey = data.publicKey || data.pub;
if (data.publicKey) { if (data.publicKey) {
if (data.publicKey.getPublic) { if (data.publicKey.getPublic)
data.publicKey = data.privateKey.getPublic(true, 'array'); data.publicKey = data.privateKey.getPublic(true, 'array');
} else if (typeof data.publicKey === 'string') { else if (typeof data.publicKey === 'string')
data.publicKey = utils.toArray(data.publicKey, 'hex'); data.publicKey = utils.toArray(data.publicKey, 'hex');
}
} }
if (typeof data.checksum === 'number') { if (typeof data.checksum === 'number') {
b = []; b = [];
utils.writeU32BE(b, data.checksum, 0); utils.writeU32BE(b, data.checksum, 0);
data.checksum = b; data.checksum = b;
} }
return data; return data;
}; };
HDPriv.prototype._seed = function(seed) { HDPriv.prototype._seed = function(seed) {
if (seed instanceof HDSeed) { if (seed instanceof HDSeed)
seed = seed.seed; seed = seed.seed;
}
if (typeof seed === 'string' && /^[0-9a-f]+$/i.test(seed)) { if (typeof seed === 'string' && /^[0-9a-f]+$/i.test(seed))
seed = utils.toArray(seed, 'hex'); seed = utils.toArray(seed, 'hex');
}
if (seed.length < MIN_ENTROPY || seed.length > MAX_ENTROPY) { if (seed.length < MIN_ENTROPY || seed.length > MAX_ENTROPY)
throw new Error; throw new Error('entropy not in range');
}
var hash = sha512hmac(seed, 'Bitcoin seed'); var hash = sha512hmac(seed, 'Bitcoin seed');
return { return {
// version: VERSION.xprivkey, // version: VERSION.xprivkey,
depth: 0, depth: 0,
@ -230,6 +233,7 @@ HDPriv.prototype._unbuild = function(xkey) {
var raw = utils.fromBase58(xkey); var raw = utils.fromBase58(xkey);
var data = {}; var data = {};
var off = 0; var off = 0;
data.version = utils.readU32BE(raw, off); data.version = utils.readU32BE(raw, off);
off += 4; off += 4;
data.depth = raw[off]; data.depth = raw[off];
@ -245,16 +249,18 @@ HDPriv.prototype._unbuild = function(xkey) {
off += data.privateKey.length; off += data.privateKey.length;
data.checksum = utils.readU32BE(raw, off); data.checksum = utils.readU32BE(raw, off);
off += 4; off += 4;
var hash = utils.dsha256(raw.slice(0, -4)); var hash = utils.dsha256(raw.slice(0, -4));
if (data.checksum !== utils.readU32BE(hash, 0)) { if (data.checksum !== utils.readU32BE(hash, 0))
throw new Error('checksum mismatch'); throw new Error('checksum mismatch');
}
return data; return data;
}; };
HDPriv.prototype._build = function(data) { HDPriv.prototype._build = function(data) {
var sequence = []; var sequence = [];
var off = 0; var off = 0;
utils.writeU32BE(sequence, data.version, off); utils.writeU32BE(sequence, data.version, off);
off += 4; off += 4;
sequence[off] = data.depth; sequence[off] = data.depth;
@ -300,24 +306,22 @@ HDPriv.prototype._build = function(data) {
}; };
HDPriv.prototype.derive = function(index, hard) { HDPriv.prototype.derive = function(index, hard) {
if (typeof index === 'string') { if (typeof index === 'string')
return this.deriveString(index); return this.deriveString(index);
}
hard = index >= HARDENED ? true : hard; hard = index >= HARDENED ? true : hard;
if (index < HARDENED && hard === true) { if (index < HARDENED && hard === true)
index += HARDENED; index += HARDENED;
}
var index_ = []; var index_ = [];
utils.writeU32BE(index_, index, 0); utils.writeU32BE(index_, index, 0);
var data; var data;
if (hard) { if (hard)
data = [0].concat(this.privateKey).concat(index_); data = [0].concat(this.privateKey).concat(index_);
} else { else
data = [].concat(this.publicKey).concat(index_); data = [].concat(this.publicKey).concat(index_);
}
var hash = sha512hmac(data, this.chainCode); var hash = sha512hmac(data, this.chainCode);
var leftPart = new bn(hash.slice(0, 32)); var leftPart = new bn(hash.slice(0, 32));
var chainCode = hash.slice(32, 64); var chainCode = hash.slice(32, 64);
@ -327,7 +331,10 @@ HDPriv.prototype.derive = function(index, hard) {
//var privateKey = leftPart.add(new bn(this.privateKey)).mod(ec.curve.n).toArray(); //var privateKey = leftPart.add(new bn(this.privateKey)).mod(ec.curve.n).toArray();
// Use this as a workaround: // Use this as a workaround:
var n = new bn('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex'); var n = new bn(
'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141',
'hex'
);
var privateKey = leftPart.add(new bn(this.privateKey)).mod(n).toArray(); var privateKey = leftPart.add(new bn(this.privateKey)).mod(n).toArray();
return new HDPriv({ return new HDPriv({
@ -346,27 +353,26 @@ HDPriv._getIndexes = function(path) {
var root = steps.shift(); var root = steps.shift();
var indexes = []; var indexes = [];
if (~PATH_ROOTS.indexOf(path)) { if (~PATH_ROOTS.indexOf(path))
return indexes; return indexes;
}
if (!~PATH_ROOTS.indexOf(root)) { if (!~PATH_ROOTS.indexOf(root))
return null; return null;
}
for (var i = 0; i < steps.length; i++) { for (var i = 0; i < steps.length; i++) {
var step = steps[i]; var step = steps[i];
var hard = step[step.length - 1] === '\''; var hard = step[step.length - 1] === '\'';
if (hard) {
if (hard)
step = step.slice(0, -1); step = step.slice(0, -1);
}
if (!step || step[0] === '-') { if (!step || step[0] === '-')
return null; return null;
}
var index = +step; var index = +step;
if (hard) { if (hard)
index += HARDENED; index += HARDENED;
}
indexes.push(index); indexes.push(index);
} }
@ -390,9 +396,8 @@ HDPriv.isValidPath = function(path, hard) {
}; };
HDPriv.prototype.deriveString = function(path) { HDPriv.prototype.deriveString = function(path) {
if (!HDPriv.isValidPath(path)) { if (!HDPriv.isValidPath(path))
throw new Error('invalid path'); throw new Error('invalid path');
}
var indexes = HDPriv._getIndexes(path); var indexes = HDPriv._getIndexes(path);
@ -406,21 +411,18 @@ HDPriv.prototype.deriveString = function(path) {
*/ */
function HDPub(options) { function HDPub(options) {
if (!(this instanceof HDPub)) { if (!(this instanceof HDPub))
return new HDPriv(options); return new HDPriv(options);
}
var data; var data;
if (typeof options === 'string' && options.indexOf('xpub') === 0) { if (typeof options === 'string' && options.indexOf('xpub') === 0)
options = { xkey: options }; options = { xkey: options };
}
if (options.xkey) { if (options.xkey)
data = this._unbuild(options.xkey); data = this._unbuild(options.xkey);
} else { else
data = options; data = options;
}
data = this._normalize(data, VERSION.xpubkey); data = this._normalize(data, VERSION.xpubkey);
@ -435,6 +437,7 @@ HDPub.prototype._unbuild = function(xkey) {
var raw = utils.fromBase58(xkey); var raw = utils.fromBase58(xkey);
var data = {}; var data = {};
var off = 0; var off = 0;
data.version = utils.readU32BE(raw, off); data.version = utils.readU32BE(raw, off);
off += 4; off += 4;
data.depth = raw[off]; data.depth = raw[off];
@ -449,16 +452,18 @@ HDPub.prototype._unbuild = function(xkey) {
off += data.publicKey.length; off += data.publicKey.length;
data.checksum = utils.readU32BE(raw, off); data.checksum = utils.readU32BE(raw, off);
off += 4; off += 4;
var hash = utils.dsha256(raw.slice(0, -4)); var hash = utils.dsha256(raw.slice(0, -4));
if (data.checksum !== utils.readU32BE(hash, 0)) { if (data.checksum !== utils.readU32BE(hash, 0))
throw new Error('checksum mismatch'); throw new Error('checksum mismatch');
}
return data; return data;
}; };
HDPub.prototype._build = function(data) { HDPub.prototype._build = function(data) {
var sequence = []; var sequence = [];
var off = 0; var off = 0;
utils.writeU32BE(sequence, data.version, off); utils.writeU32BE(sequence, data.version, off);
off += 4; off += 4;
sequence[off] = data.depth; sequence[off] = data.depth;
@ -475,11 +480,10 @@ HDPub.prototype._build = function(data) {
utils.copy(checksum, sequence, off, true); utils.copy(checksum, sequence, off, true);
off += 4; off += 4;
if (!data.checksum || !data.checksum.length) { if (!data.checksum || !data.checksum.length)
data.checksum = checksum; data.checksum = checksum;
} else if (utils.toHex(checksum) !== utils.toHex(data.checksum)) { else if (utils.toHex(checksum) !== utils.toHex(data.checksum))
throw new Error; throw new Error('checksum mismatch');
}
var xpubkey = utils.toBase58(sequence); var xpubkey = utils.toBase58(sequence);
@ -503,16 +507,14 @@ HDPub.prototype._build = function(data) {
}; };
HDPub.prototype.derive = function(index, hard) { HDPub.prototype.derive = function(index, hard) {
if (typeof index === 'string') { if (typeof index === 'string')
return this.deriveString(index); return this.deriveString(index);
}
if (index >= HARDENED || hard) { if (index >= HARDENED || hard)
throw new Error; throw new Error('invalid index');
}
if (index < 0) { if (index < 0)
throw new Error; throw new Error('invalid path');
}
var index_ = []; var index_ = [];
utils.writeU32BE(index_, index, 0); utils.writeU32BE(index_, index, 0);
@ -541,18 +543,18 @@ HDPub.isValidPath = function(arg) {
var indexes = HDPriv._getIndexes(arg); var indexes = HDPriv._getIndexes(arg);
return indexes !== null && indexes.every(HDPub.isValidPath); return indexes !== null && indexes.every(HDPub.isValidPath);
} }
if (typeof arg === 'number') {
if (typeof arg === 'number')
return arg >= 0 && arg < HARDENED; return arg >= 0 && arg < HARDENED;
}
return false; return false;
}; };
HDPub.prototype.deriveString = function(path) { HDPub.prototype.deriveString = function(path) {
if (~path.indexOf('\'')) { if (~path.indexOf('\''))
throw new Error('cannot derive hardened'); throw new Error('cannot derive hardened');
} else if (!HDPub.isValidPath(path)) { else if (!HDPub.isValidPath(path))
throw new Error('invalid path'); throw new Error('invalid path');
}
var indexes = HDPriv._getIndexes(path); var indexes = HDPriv._getIndexes(path);
@ -601,25 +603,20 @@ function pbkdf2(key, salt, iterations, dkLen) {
'use strict'; 'use strict';
var hLen = 64; var hLen = 64;
if (dkLen > (Math.pow(2, 32) - 1) * hLen) { if (dkLen > (Math.pow(2, 32) - 1) * hLen)
throw Error('Requested key length too long'); throw Error('Requested key length too long');
}
if (typeof key !== 'string' && typeof key.length !== 'number') { if (typeof key !== 'string' && typeof key.length !== 'number')
throw new TypeError('key must a string or array'); throw new TypeError('key must a string or array');
}
if (typeof salt !== 'string' && typeof salt.length !== 'number') { if (typeof salt !== 'string' && typeof salt.length !== 'number')
throw new TypeError('salt must a string or array'); throw new TypeError('salt must a string or array');
}
if (typeof key === 'string') { if (typeof key === 'string')
key = utils.toArray(key, null); key = utils.toArray(key, null);
}
if (typeof salt === 'string') { if (typeof salt === 'string')
salt = utils.toArray(salt, null); salt = utils.toArray(salt, null);
}
var DK = new Array(dkLen); var DK = new Array(dkLen);
var U = new Array(hLen); var U = new Array(hLen);
@ -630,6 +627,7 @@ function pbkdf2(key, salt, iterations, dkLen) {
var r = dkLen - (l - 1) * hLen; var r = dkLen - (l - 1) * hLen;
utils.copy(salt.slice(0, salt.length), block1, 0); utils.copy(salt.slice(0, salt.length), block1, 0);
for (var i = 1; i <= l; i++) { for (var i = 1; i <= l; i++) {
block1[salt.length + 0] = (i >> 24 & 0xff); block1[salt.length + 0] = (i >> 24 & 0xff);
block1[salt.length + 1] = (i >> 16 & 0xff); block1[salt.length + 1] = (i >> 16 & 0xff);
@ -643,9 +641,8 @@ function pbkdf2(key, salt, iterations, dkLen) {
for (var j = 1; j < iterations; j++) { for (var j = 1; j < iterations; j++) {
U = sha512hmac(U, key); U = sha512hmac(U, key);
for (var k = 0; k < hLen; k++) { for (var k = 0; k < hLen; k++)
T[k] ^= U[k]; T[k] ^= U[k];
}
} }
var destPos = (i - 1) * hLen; var destPos = (i - 1) * hLen;

View File

@ -284,9 +284,8 @@ TX.prototype.scriptOutput = function(options) {
} }
keys = keys.map(function(key) { keys = keys.map(function(key) {
if (typeof key === 'string') { if (typeof key === 'string')
return utils.toKeyArray(key); return utils.toKeyArray(key);
}
return key; return key;
}); });