From a57191c66f836eda7766a5fbeafc4b1b06324bd1 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 12 Jun 2014 10:33:16 -0300 Subject: [PATCH] working on fixing the wierd test --- failsearch.sh | 8 +++ lib/HierarchicalKey.js | 155 +++++++++++++++++++++-------------------- 2 files changed, 89 insertions(+), 74 deletions(-) create mode 100755 failsearch.sh diff --git a/failsearch.sh b/failsearch.sh new file mode 100755 index 0000000..ec89f14 --- /dev/null +++ b/failsearch.sh @@ -0,0 +1,8 @@ +#! /bin/bash + +# run mocha until it fails + +COUNTER=0 +while [ $? -eq 0 ]; do + mocha +done diff --git a/lib/HierarchicalKey.js b/lib/HierarchicalKey.js index 36f47cb..bc4e4d6 100644 --- a/lib/HierarchicalKey.js +++ b/lib/HierarchicalKey.js @@ -6,6 +6,7 @@ var Point = imports.Point || require('./Point'); var SecureRandom = imports.SecureRandom || require('./SecureRandom'); var bignum = imports.bignum || require('bignum'); var networks = require('../networks'); +var BufferPut = require('bufferput'); var secp256k1_n = new bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16); var secp256k1_Gx = new bignum('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16); @@ -19,8 +20,7 @@ var HierarchicalKey = function(bytes) { if (typeof bytes == 'undefined' || bytes == 'mainnet' || bytes == 'livenet') { bytes = 'livenet'; this.version = networks['livenet'].hkeyPrivateVersion; - } - else if (bytes == 'testnet') { + } else if (bytes == 'testnet') { this.version = networks['testnet'].hkeyPrivateVersion; } if (bytes == 'livenet' || bytes == 'testnet') { @@ -35,12 +35,12 @@ var HierarchicalKey = function(bytes) { this.buildExtendedPrivateKey(); return; } - + // decode base58 if (typeof bytes === 'string') { var decoded = base58.decode(bytes); if (decoded.length != 82) - throw new Error('Not enough data, expected 82 and received '+decoded.length); + throw new Error('Not enough data, expected 82 and received ' + decoded.length); var checksum = decoded.slice(78, 82); bytes = decoded.slice(0, 78); @@ -51,7 +51,7 @@ var HierarchicalKey = function(bytes) { } } - if (bytes !== undefined && bytes !== null) + if (bytes !== undefined && bytes !== null) this.initFromBytes(bytes); } @@ -61,9 +61,9 @@ HierarchicalKey.seed = function(bytes, network) { if (!Buffer.isBuffer(bytes)) bytes = new Buffer(bytes, 'hex'); //if not buffer, assume hex - if (bytes.length < 128/8) + if (bytes.length < 128 / 8) return false; //need more entropy - if (bytes.length > 512/8) + if (bytes.length > 512 / 8) return false; var hash = coinUtil.sha512hmac(bytes, new Buffer('Bitcoin seed')); @@ -87,23 +87,23 @@ HierarchicalKey.seed = function(bytes, network) { HierarchicalKey.prototype.initFromBytes = function(bytes) { // Both pub and private extended keys are 78 bytes - if(bytes.length != 78) throw new Error('not enough data'); + if (bytes.length != 78) throw new Error('not enough data'); - this.version = u32(bytes.slice(0, 4)); - this.depth = u8(bytes.slice(4, 5)); + this.version = u32(bytes.slice(0, 4)); + this.depth = u8(bytes.slice(4, 5)); this.parentFingerprint = bytes.slice(5, 9); - this.childIndex = u32(bytes.slice(9, 13)); - this.chainCode = bytes.slice(13, 45); - + this.childIndex = u32(bytes.slice(9, 13)); + this.chainCode = bytes.slice(13, 45); + var keyBytes = bytes.slice(45, 78); - var isPrivate = - (this.version == networks['livenet'].hkeyPrivateVersion || - this.version == networks['testnet'].hkeyPrivateVersion ); + var isPrivate = + (this.version == networks['livenet'].hkeyPrivateVersion || + this.version == networks['testnet'].hkeyPrivateVersion); - var isPublic = - (this.version == networks['livenet'].hkeyPublicVersion || - this.version == networks['testnet'].hkeyPublicVersion ); + var isPublic = + (this.version == networks['livenet'].hkeyPublicVersion || + this.version == networks['testnet'].hkeyPublicVersion); if (isPrivate && keyBytes[0] == 0) { this.eckey = new Key(); @@ -129,33 +129,28 @@ HierarchicalKey.prototype.buildExtendedPublicKey = function() { this.extendedPublicKey = new Buffer([]); var v = null; - switch(this.version) { - case networks['livenet'].hkeyPublicVersion: - case networks['livenet'].hkeyPrivateVersion: - v = networks['livenet'].hkeyPublicVersion; - break; - case networks['testnet'].hkeyPublicVersion: - case networks['testnet'].hkeyPrivateVersion: - v = networks['testnet'].hkeyPublicVersion; - break; - default: - throw new Error('Unknown version'); + switch (this.version) { + case networks['livenet'].hkeyPublicVersion: + case networks['livenet'].hkeyPrivateVersion: + v = networks['livenet'].hkeyPublicVersion; + break; + case networks['testnet'].hkeyPublicVersion: + case networks['testnet'].hkeyPrivateVersion: + v = networks['testnet'].hkeyPublicVersion; + break; + default: + throw new Error('Unknown version'); } - this.extendedPublicKey = Buffer.concat([ - new Buffer([v >> 24]), - new Buffer([(v >> 16) & 0xff]), - new Buffer([(v >> 8) & 0xff]), - new Buffer([v & 0xff]), - new Buffer([this.depth]), - this.parentFingerprint, - new Buffer([this.childIndex >>> 24]), - new Buffer([(this.childIndex >>> 16) & 0xff]), - new Buffer([(this.childIndex >>> 8) & 0xff]), - new Buffer([this.childIndex & 0xff]), - this.chainCode, - this.eckey.public - ]); + var r = new BufferPut(); + r = r.word32be(v); + r = r.word8(this.depth); + r = r.put(this.parentFingerprint); + r = r.word32be(this.childIndex); + r = r.put(this.chainCode); + r = r.put(this.eckey.public); + + this.extendedPublicKey = r.buffer(); console.log('a'); } @@ -178,21 +173,16 @@ HierarchicalKey.prototype.buildExtendedPrivateKey = function() { var v = this.version; - this.extendedPrivateKey = Buffer.concat([ - new Buffer([v >> 24]), - new Buffer([(v >> 16) & 0xff]), - new Buffer([(v >> 8) & 0xff]), - new Buffer([v & 0xff]), - new Buffer([this.depth]), - this.parentFingerprint, - new Buffer([this.childIndex >>> 24]), - new Buffer([(this.childIndex >>> 16) & 0xff]), - new Buffer([(this.childIndex >>> 8) & 0xff]), - new Buffer([this.childIndex & 0xff]), - this.chainCode, - new Buffer([0]), - this.eckey.private - ]); + var r = new BufferPut(); + r = r.word32be(v); + r = r.word8(this.depth); + r = r.put(this.parentFingerprint); + r = r.word32be(this.childIndex); + r = r.put(this.chainCode); + r = r.word8(0); + r = r.put(this.eckey.private); + + this.extendedPrivateKey = r.buffer(); } HierarchicalKey.prototype.extendedPrivateKeyString = function(format) { @@ -220,12 +210,12 @@ HierarchicalKey.prototype.derive = function(path) { for (var i in e) { var c = e[i]; - if (i == 0 ) { + if (i == 0) { if (c != 'm') throw new Error('invalid path'); continue; } - var usePrivate = (c.length > 1) && (c[c.length-1] == '\''); + var usePrivate = (c.length > 1) && (c[c.length - 1] == '\''); var childIndex = parseInt(usePrivate ? c.slice(0, c.length - 1) : c) & 0x7fffffff; if (usePrivate) { @@ -242,15 +232,15 @@ HierarchicalKey.prototype.deriveChild = function(i) { var ib = []; ib.push((i >> 24) & 0xff); ib.push((i >> 16) & 0xff); - ib.push((i >> 8) & 0xff); + ib.push((i >> 8) & 0xff); ib.push(i & 0xff); ib = new Buffer(ib); var usePrivate = (i & 0x80000000) != 0; - var isPrivate = - (this.version == networks['livenet'].hkeyPrivateVersion || - this.version == networks['testnet'].hkeyPrivateVersion ); + var isPrivate = + (this.version == networks['livenet'].hkeyPrivateVersion || + this.version == networks['testnet'].hkeyPrivateVersion); if (usePrivate && (!this.hasPrivateKey || !isPrivate)) throw new Error('Cannot do private key derivation without private key'); @@ -266,18 +256,24 @@ HierarchicalKey.prototype.deriveChild = function(i) { } var hash = coinUtil.sha512hmac(data, this.chainCode); - var il = bignum.fromBuffer(hash.slice(0, 32), {size: 32}); + var il = bignum.fromBuffer(hash.slice(0, 32), { + size: 32 + }); var ir = hash.slice(32, 64); // ki = IL + kpar (mod n). - var priv = bignum.fromBuffer(this.eckey.private, {size: 32}); + var priv = bignum.fromBuffer(this.eckey.private, { + size: 32 + }); var k = il.add(priv).mod(secp256k1_n); ret = new HierarchicalKey(null); ret.chainCode = ir; ret.eckey = new Key(); - ret.eckey.private = k.toBuffer({size: 32}); + ret.eckey.private = k.toBuffer({ + size: 32 + }); ret.eckey.regenerateSync(); ret.hasPrivateKey = true; @@ -303,14 +299,14 @@ HierarchicalKey.prototype.deriveChild = function(i) { ret.chainCode = new Buffer(ir); var eckey = new Key(); - eckey.public = newpub; + eckey.public = newpub; eckey.compressed = true; ret.eckey = eckey; ret.hasPrivateKey = false; } ret.childIndex = i; - ret.parentFingerprint = this.pubKeyHash.slice(0,4); + ret.parentFingerprint = this.pubKeyHash.slice(0, 4); ret.version = this.version; ret.depth = this.depth + 1; @@ -335,9 +331,20 @@ function uint(f, size) { return n; } -function u8(f) {return uint(f,1);} -function u16(f) {return uint(f,2);} -function u32(f) {return uint(f,4);} -function u64(f) {return uint(f,8);} +function u8(f) { + return uint(f, 1); +} + +function u16(f) { + return uint(f, 2); +} + +function u32(f) { + return uint(f, 4); +} + +function u64(f) { + return uint(f, 8); +} module.exports = require('soop')(HierarchicalKey);