hd: use a u32 for fingerprints.

This commit is contained in:
Christopher Jeffrey 2017-08-11 05:19:46 -07:00
parent aa327131e8
commit b8f57df90c
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 35 additions and 36 deletions

View File

@ -109,7 +109,7 @@ common.parsePath = function parsePath(path, hard) {
common.isMaster = function isMaster(key) {
return key.depth === 0
&& key.childIndex === 0
&& key.parentFingerPrint.readUInt32LE(0, true) === 0;
&& key.parentFingerPrint === 0;
};
/**
@ -135,5 +135,6 @@ common.isBIP44 = function isBIP44(key, account) {
*/
common.isBIP45 = function isBIP45(key) {
return key.depth === 1 && (key.childIndex & ~common.HARDENED) === 45;
const index = (common.HARDENED | 45) >>> 0;
return key.depth === 1 && key.childIndex === index;
};

View File

@ -34,13 +34,13 @@ const SEED_SALT = Buffer.from('Bitcoin seed', 'ascii');
* @param {Object|Base58String} options
* @param {Base58String?} options.xkey - Serialized base58 key.
* @param {Number?} options.depth
* @param {Buffer?} options.parentFingerPrint
* @param {Number?} options.parentFingerPrint
* @param {Number?} options.childIndex
* @param {Buffer?} options.chainCode
* @param {Buffer?} options.privateKey
* @property {Network} network
* @property {Number} depth
* @property {Buffer} parentFingerPrint
* @property {Number} parentFingerPrint
* @property {Number} childIndex
* @property {Buffer} chainCode
* @property {Buffer} privateKey
@ -52,13 +52,13 @@ function HDPrivateKey(options) {
this.network = Network.primary;
this.depth = 0;
this.parentFingerPrint = encoding.ZERO_U32;
this.parentFingerPrint = 0;
this.childIndex = 0;
this.chainCode = encoding.ZERO_HASH;
this.privateKey = encoding.ZERO_HASH;
this.publicKey = encoding.ZERO_KEY;
this.fingerPrint = null;
this.fingerPrint = -1;
this._xprivkey = null;
@ -77,7 +77,7 @@ function HDPrivateKey(options) {
HDPrivateKey.prototype.fromOptions = function fromOptions(options) {
assert(options, 'No options for HD private key.');
assert(util.isU8(options.depth));
assert(Buffer.isBuffer(options.parentFingerPrint));
assert(util.isU32(options.parentFingerPrint));
assert(util.isU32(options.childIndex));
assert(Buffer.isBuffer(options.chainCode));
assert(Buffer.isBuffer(options.privateKey));
@ -155,16 +155,13 @@ HDPrivateKey.prototype.xpubkey = function xpubkey() {
HDPrivateKey.prototype.destroy = function destroy(pub) {
this.depth = 0;
this.childIndex = 0;
this.parentFingerPrint = 0;
cleanse(this.parentFingerPrint);
cleanse(this.chainCode);
cleanse(this.privateKey);
cleanse(this.publicKey);
if (this.fingerPrint) {
cleanse(this.fingerPrint);
this.fingerPrint = null;
}
this.fingerPrint = -1;
if (this._hdPublicKey) {
if (pub)
@ -226,8 +223,10 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
return this.derive(index + 1);
}
if (!this.fingerPrint)
this.fingerPrint = digest.hash160(this.publicKey).slice(0, 4);
if (this.fingerPrint === -1) {
const fp = digest.hash160(this.publicKey);
this.fingerPrint = fp.readUInt32BE(0, true);
}
const child = new HDPrivateKey();
child.network = this.network;
@ -403,7 +402,7 @@ HDPrivateKey.prototype.equals = function equals(obj) {
return this.network === obj.network
&& this.depth === obj.depth
&& this.parentFingerPrint.equals(obj.parentFingerPrint)
&& this.parentFingerPrint === obj.parentFingerPrint
&& this.childIndex === obj.childIndex
&& this.chainCode.equals(obj.chainCode)
&& this.privateKey.equals(obj.privateKey);
@ -423,7 +422,7 @@ HDPrivateKey.prototype.compare = function compare(key) {
if (cmp !== 0)
return cmp;
cmp = this.parentFingerPrint.compare(key.parentFingerPrint);
cmp = this.parentFingerPrint - key.parentFingerPrint;
if (cmp !== 0)
return cmp;
@ -471,7 +470,7 @@ HDPrivateKey.prototype.fromSeed = function fromSeed(seed, network) {
this.network = Network.get(network);
this.depth = 0;
this.parentFingerPrint = Buffer.from([0, 0, 0, 0]);
this.parentFingerPrint = 0;
this.childIndex = 0;
this.chainCode = right;
this.privateKey = left;
@ -551,7 +550,7 @@ HDPrivateKey.prototype.fromKey = function fromKey(key, entropy, network) {
assert(Buffer.isBuffer(entropy) && entropy.length === 32);
this.network = Network.get(network);
this.depth = 0;
this.parentFingerPrint = Buffer.from([0, 0, 0, 0]);
this.parentFingerPrint = 0;
this.childIndex = 0;
this.chainCode = entropy;
this.privateKey = key;
@ -608,7 +607,7 @@ HDPrivateKey.prototype.fromReader = function fromReader(br, network) {
this.network = Network.fromPrivate(version, network);
this.depth = br.readU8();
this.parentFingerPrint = br.readBytes(4);
this.parentFingerPrint = br.readU32BE();
this.childIndex = br.readU32BE();
this.chainCode = br.readBytes(32);
assert(br.readU8() === 0);
@ -664,7 +663,7 @@ HDPrivateKey.prototype.toWriter = function toWriter(bw, network) {
bw.writeU32BE(network.keyPrefix.xprivkey);
bw.writeU8(this.depth);
bw.writeBytes(this.parentFingerPrint);
bw.writeU32BE(this.parentFingerPrint);
bw.writeU32BE(this.childIndex);
bw.writeBytes(this.chainCode);
bw.writeU8(0);

View File

@ -25,13 +25,13 @@ const common = require('./common');
* @param {Object|Base58String} options
* @param {Base58String?} options.xkey - Serialized base58 key.
* @param {Number?} options.depth
* @param {Buffer?} options.parentFingerPrint
* @param {Number?} options.parentFingerPrint
* @param {Number?} options.childIndex
* @param {Buffer?} options.chainCode
* @param {Buffer?} options.publicKey
* @property {Network} network
* @property {Number} depth
* @property {Buffer} parentFingerPrint
* @property {Number} parentFingerPrint
* @property {Number} childIndex
* @property {Buffer} chainCode
* @property {Buffer} publicKey
@ -43,12 +43,12 @@ function HDPublicKey(options) {
this.network = Network.primary;
this.depth = 0;
this.parentFingerPrint = encoding.ZERO_U32;
this.parentFingerPrint = 0;
this.childIndex = 0;
this.chainCode = encoding.ZERO_HASH;
this.publicKey = encoding.ZERO_KEY;
this.fingerPrint = null;
this.fingerPrint = -1;
this._xpubkey = null;
@ -65,7 +65,7 @@ function HDPublicKey(options) {
HDPublicKey.prototype.fromOptions = function fromOptions(options) {
assert(options, 'No options for HDPublicKey');
assert(util.isU8(options.depth));
assert(Buffer.isBuffer(options.parentFingerPrint));
assert(util.isU32(options.parentFingerPrint));
assert(util.isU32(options.childIndex));
assert(Buffer.isBuffer(options.chainCode));
assert(Buffer.isBuffer(options.publicKey));
@ -128,15 +128,12 @@ HDPublicKey.prototype.xpubkey = function xpubkey() {
HDPublicKey.prototype.destroy = function destroy() {
this.depth = 0;
this.childIndex = 0;
this.parentFingerPrint = 0;
cleanse(this.parentFingerPrint);
cleanse(this.chainCode);
cleanse(this.publicKey);
if (this.fingerPrint) {
cleanse(this.fingerPrint);
this.fingerPrint = null;
}
this.fingerPrint = -1;
this._xpubkey = null;
};
@ -186,8 +183,10 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
return this.derive(index + 1);
}
if (!this.fingerPrint)
this.fingerPrint = digest.hash160(this.publicKey).slice(0, 4);
if (this.fingerPrint === -1) {
const fp = digest.hash160(this.publicKey);
this.fingerPrint = fp.readUInt32BE(0, true);
}
const child = new HDPublicKey();
child.network = this.network;
@ -318,7 +317,7 @@ HDPublicKey.prototype.equals = function equals(obj) {
return this.network === obj.network
&& this.depth === obj.depth
&& this.parentFingerPrint.equals(obj.parentFingerPrint)
&& this.parentFingerPrint === obj.parentFingerPrint
&& this.childIndex === obj.childIndex
&& this.chainCode.equals(obj.chainCode)
&& this.publicKey.equals(obj.publicKey);
@ -338,7 +337,7 @@ HDPublicKey.prototype.compare = function compare(key) {
if (cmp !== 0)
return cmp;
cmp = this.parentFingerPrint.compare(key.parentFingerPrint);
cmp = this.parentFingerPrint - key.parentFingerPrint;
if (cmp !== 0)
return cmp;
@ -469,7 +468,7 @@ HDPublicKey.prototype.fromReader = function fromReader(br, network) {
this.network = Network.fromPublic(version, network);
this.depth = br.readU8();
this.parentFingerPrint = br.readBytes(4);
this.parentFingerPrint = br.readU32BE();
this.childIndex = br.readU32BE();
this.chainCode = br.readBytes(32);
this.publicKey = br.readBytes(33);
@ -514,7 +513,7 @@ HDPublicKey.prototype.toWriter = function toWriter(bw, network) {
bw.writeU32BE(network.keyPrefix.xpubkey);
bw.writeU8(this.depth);
bw.writeBytes(this.parentFingerPrint);
bw.writeU32BE(this.parentFingerPrint);
bw.writeU32BE(this.childIndex);
bw.writeBytes(this.chainCode);
bw.writeBytes(this.publicKey);