Merge pull request #340 from ryanxcharles/feature/hierarchical-key

Rename BIP32 -> HierarchicalKey, deprecate BIP32
This commit is contained in:
Ryan X. Charles 2014-05-12 11:33:11 -04:00
commit 566f5384db
9 changed files with 235 additions and 231 deletions

View File

@ -35,7 +35,11 @@ requireWhenAccessed('EncodedData', './util/EncodedData');
requireWhenAccessed('VersionedData', './util/VersionedData'); requireWhenAccessed('VersionedData', './util/VersionedData');
requireWhenAccessed('BinaryParser', './util/BinaryParser'); requireWhenAccessed('BinaryParser', './util/BinaryParser');
requireWhenAccessed('Address', './lib/Address'); requireWhenAccessed('Address', './lib/Address');
requireWhenAccessed('BIP32', './lib/BIP32'); requireWhenAccessed('HierarchicalKey', './lib/HierarchicalKey');
Object.defineProperty(module.exports, 'BIP32', {get: function() {
console.log('BIP32 is deprecated. Use bitcore.HierarchicalKey instead.');
return require('./lib/HierarchicalKey');
}});
requireWhenAccessed('Point', './lib/Point'); requireWhenAccessed('Point', './lib/Point');
requireWhenAccessed('Opcode', './lib/Opcode'); requireWhenAccessed('Opcode', './lib/Opcode');
requireWhenAccessed('Script', './lib/Script'); requireWhenAccessed('Script', './lib/Script');

View File

@ -26,7 +26,7 @@ var modules = [
'lib/Address', 'lib/Address',
'lib/Armory', 'lib/Armory',
'lib/Base58', 'lib/Base58',
'lib/BIP32', 'lib/HierarchicalKey',
'lib/Block', 'lib/Block',
'lib/Bloom', 'lib/Bloom',
'lib/Connection', 'lib/Connection',

View File

@ -1,83 +0,0 @@
var run = function() {
bitcore = typeof (bitcore) === 'undefined' ? require('../bitcore') : bitcore;
var BIP32 = bitcore.BIP32;
var Address = bitcore.Address;
var networks = bitcore.networks;
var coinUtil = bitcore.util;
var crypto = require('crypto');
console.log('BIP32: Hierarchical Deterministic Wallets');
console.log('https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\n');
console.log('1) Make new bip32 from randomly generated new seed');
var randomBytes = crypto.randomBytes(256);
var bip32 = BIP32.seed(randomBytes);
console.log('master extended private key: ' + bip32.extendedPrivateKeyString());
console.log('master extended public key: ' + bip32.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: ' + bip32.derive('m/0/3/5').extendedPrivateKeyString());
console.log('m/0/3/5 extended public key: ' + bip32.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('2) Make new bip32 from known seed');
var knownBytes = coinUtil.sha256('do not use this password as a brain wallet');
var bip32 = BIP32.seed(knownBytes);
console.log('master extended private key: ' + bip32.extendedPrivateKeyString());
console.log('master extended public key: ' + bip32.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: ' + bip32.derive('m/0/3/5').extendedPrivateKeyString());
console.log('m/0/3/5 extended public key: ' + bip32.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('3) Make new bip32 from known master private key');
var knownMasterPrivateKey = 'xprv9s21ZrQH143K2LvayFZWVVTomiDKheKWvnupDB8fmjKwxkKG47uvzmFa3vCXoy9fxPJhRYsU19apVfexvMeLpJQuF2XtX1zRF3eao9GqqaQ';
var bip32 = new BIP32(knownMasterPrivateKey);
console.log('master extended private key: ' + bip32.extendedPrivateKeyString());
console.log('master extended public key: ' + bip32.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: ' + bip32.derive('m/0/3/5').extendedPrivateKeyString());
console.log('m/0/3/5 extended public key: ' + bip32.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('4) Make new bip32 from known master public key');
var knownMasterPublicKey = 'xpub661MyMwAqRbcGpiFufipqsKKBG1NHNwfJKishAEFNqJ6ryLcKeKyFNEZces7gMWd4XGg4uUhXy8DS64o1oPGUECVHeLq957Txjwagxt475H';
var bip32 = new BIP32(knownMasterPublicKey);
console.log('master extended private key: cannot derive');
console.log('master extended public key: ' + bip32.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: cannot derive');
console.log('m/0/3/5 extended public key: ' + bip32.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('5) Make new bip32 from known derived public key');
var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3';
var bip32 = new BIP32(knownPublicKey);
console.log('master extended private key: cannot derive');
console.log('master extended public key: ' + bip32.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: cannot derive');
console.log('m/0/3/5 extended public key: ' + bip32.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('6) Make a bunch of new addresses from known public key');
var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3';
var bip32 = new BIP32(knownPublicKey);
console.log('m/0 address: ' + new Address(networks['livenet'].addressVersion, bip32.derive('m/0').eckey.public).toString());
//console.log('m/1 extended public key: ' + bip32.derive('m/1').extendedPublicKeyString());
console.log('m/1 address: ' + new Address(networks['livenet'].addressVersion, bip32.derive('m/1').eckey.public).toString());
//console.log('m/2 extended public key: ' + bip32.derive('m/2').extendedPublicKeyString());
console.log('m/2 address: ' + new Address(networks['livenet'].addressVersion, bip32.derive('m/2').eckey.public).toString());
//console.log('m/3 extended public key: ' + bip32.derive('m/3').extendedPublicKeyString());
console.log('m/3 address: ' + new Address(networks['livenet'].addressVersion, bip32.derive('m/3').eckey.public).toString());
console.log('...');
//console.log('m/100 extended public key: ' + bip32.derive('m/100').extendedPublicKeyString());
console.log('m/100 address: ' + new Address(networks['livenet'].addressVersion, bip32.derive('m/100').eckey.public).toString());
console.log();
};
// This is just for browser & mocha compatibility
if (typeof module !== 'undefined') {
module.exports.run = run;
if (require.main === module) {
run();
}
} else {
run();
}

View File

@ -0,0 +1,83 @@
var run = function() {
bitcore = typeof (bitcore) === 'undefined' ? require('../bitcore') : bitcore;
var HierarchicalKey = bitcore.HierarchicalKey;
var Address = bitcore.Address;
var networks = bitcore.networks;
var coinUtil = bitcore.util;
var crypto = require('crypto');
console.log('HierarchicalKey: Hierarchical Deterministic Wallets (BIP32)');
console.log('https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\n');
console.log('1) Make new hkey from randomly generated new seed');
var randomBytes = crypto.randomBytes(256);
var hkey = HierarchicalKey.seed(randomBytes);
console.log('master extended private key: ' + hkey.extendedPrivateKeyString());
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString());
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('2) Make new hkey from known seed');
var knownBytes = coinUtil.sha256('do not use this password as a brain wallet');
var hkey = HierarchicalKey.seed(knownBytes);
console.log('master extended private key: ' + hkey.extendedPrivateKeyString());
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString());
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('3) Make new hkey from known master private key');
var knownMasterPrivateKey = 'xprv9s21ZrQH143K2LvayFZWVVTomiDKheKWvnupDB8fmjKwxkKG47uvzmFa3vCXoy9fxPJhRYsU19apVfexvMeLpJQuF2XtX1zRF3eao9GqqaQ';
var hkey = new HierarchicalKey(knownMasterPrivateKey);
console.log('master extended private key: ' + hkey.extendedPrivateKeyString());
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString());
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('4) Make new hkey from known master public key');
var knownMasterPublicKey = 'xpub661MyMwAqRbcGpiFufipqsKKBG1NHNwfJKishAEFNqJ6ryLcKeKyFNEZces7gMWd4XGg4uUhXy8DS64o1oPGUECVHeLq957Txjwagxt475H';
var hkey = new HierarchicalKey(knownMasterPublicKey);
console.log('master extended private key: cannot derive');
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: cannot derive');
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('5) Make new hkey from known derived public key');
var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3';
var hkey = new HierarchicalKey(knownPublicKey);
console.log('master extended private key: cannot derive');
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
console.log('m/0/3/5 extended private key: cannot derive');
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
console.log();
console.log('6) Make a bunch of new addresses from known public key');
var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3';
var hkey = new HierarchicalKey(knownPublicKey);
console.log('m/0 address: ' + new Address(networks['livenet'].addressVersion, hkey.derive('m/0').eckey.public).toString());
//console.log('m/1 extended public key: ' + hkey.derive('m/1').extendedPublicKeyString());
console.log('m/1 address: ' + new Address(networks['livenet'].addressVersion, hkey.derive('m/1').eckey.public).toString());
//console.log('m/2 extended public key: ' + hkey.derive('m/2').extendedPublicKeyString());
console.log('m/2 address: ' + new Address(networks['livenet'].addressVersion, hkey.derive('m/2').eckey.public).toString());
//console.log('m/3 extended public key: ' + hkey.derive('m/3').extendedPublicKeyString());
console.log('m/3 address: ' + new Address(networks['livenet'].addressVersion, hkey.derive('m/3').eckey.public).toString());
console.log('...');
//console.log('m/100 extended public key: ' + hkey.derive('m/100').extendedPublicKeyString());
console.log('m/100 address: ' + new Address(networks['livenet'].addressVersion, hkey.derive('m/100').eckey.public).toString());
console.log();
};
// This is just for browser & mocha compatibility
if (typeof module !== 'undefined') {
module.exports.run = run;
if (require.main === module) {
run();
}
} else {
run();
}

View File

@ -11,17 +11,17 @@ var secp256k1_n = new bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBF
var secp256k1_Gx = new bignum('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16); var secp256k1_Gx = new bignum('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16);
/* /*
random new BIP32: new BIP32(); random new HierarchicalKey: new HierarchicalKey();
from extended public or private key: new BIP32(str); from extended public or private key: new HierarchicalKey(str);
new blank BIP32: new BIP32(null); new blank HierarchicalKey: new HierarchicalKey(null);
*/ */
var BIP32 = function(bytes) { var HierarchicalKey = function(bytes) {
if (typeof bytes == 'undefined' || bytes == 'mainnet' || bytes == 'livenet') { if (typeof bytes == 'undefined' || bytes == 'mainnet' || bytes == 'livenet') {
bytes = 'livenet'; bytes = 'livenet';
this.version = networks['livenet'].bip32privateVersion; this.version = networks['livenet'].hkeyPrivateVersion;
} }
else if (bytes == 'testnet') { else if (bytes == 'testnet') {
this.version = networks['testnet'].bip32privateVersion; this.version = networks['testnet'].hkeyPrivateVersion;
} }
if (bytes == 'livenet' || bytes == 'testnet') { if (bytes == 'livenet' || bytes == 'testnet') {
this.depth = 0x00; this.depth = 0x00;
@ -55,7 +55,7 @@ var BIP32 = function(bytes) {
this.initFromBytes(bytes); this.initFromBytes(bytes);
} }
BIP32.seed = function(bytes, network) { HierarchicalKey.seed = function(bytes, network) {
if (!network) if (!network)
network = 'livenet'; network = 'livenet';
@ -65,25 +65,25 @@ BIP32.seed = function(bytes, network) {
return false; //need more entropy return false; //need more entropy
var hash = coinUtil.sha512hmac(bytes, new Buffer('Bitcoin seed')); var hash = coinUtil.sha512hmac(bytes, new Buffer('Bitcoin seed'));
var bip32 = new BIP32(null); var hkey = new HierarchicalKey(null);
bip32.depth = 0x00; hkey.depth = 0x00;
bip32.parentFingerprint = new Buffer([0, 0, 0, 0]); hkey.parentFingerprint = new Buffer([0, 0, 0, 0]);
bip32.childIndex = new Buffer([0, 0, 0, 0]); hkey.childIndex = new Buffer([0, 0, 0, 0]);
bip32.chainCode = hash.slice(32, 64); hkey.chainCode = hash.slice(32, 64);
bip32.version = networks[network].bip32privateVersion; hkey.version = networks[network].hkeyPrivateVersion;
bip32.eckey = new Key(); hkey.eckey = new Key();
bip32.eckey.private = hash.slice(0, 32); hkey.eckey.private = hash.slice(0, 32);
bip32.eckey.regenerateSync(); hkey.eckey.regenerateSync();
bip32.hasPrivateKey = true; hkey.hasPrivateKey = true;
bip32.pubKeyHash = coinUtil.sha256ripe160(bip32.eckey.public); hkey.pubKeyHash = coinUtil.sha256ripe160(hkey.eckey.public);
bip32.buildExtendedPublicKey(); hkey.buildExtendedPublicKey();
bip32.buildExtendedPrivateKey(); hkey.buildExtendedPrivateKey();
return bip32; return hkey;
}; };
BIP32.prototype.initFromBytes = function(bytes) { HierarchicalKey.prototype.initFromBytes = function(bytes) {
// Both pub and private extended keys are 78 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');
@ -96,12 +96,12 @@ BIP32.prototype.initFromBytes = function(bytes) {
var keyBytes = bytes.slice(45, 78); var keyBytes = bytes.slice(45, 78);
var isPrivate = var isPrivate =
(this.version == networks['livenet'].bip32privateVersion || (this.version == networks['livenet'].hkeyPrivateVersion ||
this.version == networks['testnet'].bip32privateVersion ); this.version == networks['testnet'].hkeyPrivateVersion );
var isPublic = var isPublic =
(this.version == networks['livenet'].bip32publicVersion || (this.version == networks['livenet'].hkeyPublicVersion ||
this.version == networks['testnet'].bip32publicVersion ); this.version == networks['testnet'].hkeyPublicVersion );
if (isPrivate && keyBytes[0] == 0) { if (isPrivate && keyBytes[0] == 0) {
this.eckey = new Key(); this.eckey = new Key();
@ -123,18 +123,18 @@ BIP32.prototype.initFromBytes = function(bytes) {
this.buildExtendedPrivateKey(); this.buildExtendedPrivateKey();
} }
BIP32.prototype.buildExtendedPublicKey = function() { HierarchicalKey.prototype.buildExtendedPublicKey = function() {
this.extendedPublicKey = new Buffer([]); this.extendedPublicKey = new Buffer([]);
var v = null; var v = null;
switch(this.version) { switch(this.version) {
case networks['livenet'].bip32publicVersion: case networks['livenet'].hkeyPublicVersion:
case networks['livenet'].bip32privateVersion: case networks['livenet'].hkeyPrivateVersion:
v = networks['livenet'].bip32publicVersion; v = networks['livenet'].hkeyPublicVersion;
break; break;
case networks['testnet'].bip32publicVersion: case networks['testnet'].hkeyPublicVersion:
case networks['testnet'].bip32privateVersion: case networks['testnet'].hkeyPrivateVersion:
v = networks['testnet'].bip32publicVersion; v = networks['testnet'].hkeyPublicVersion;
break; break;
default: default:
throw new Error('Unknown version'); throw new Error('Unknown version');
@ -157,7 +157,7 @@ BIP32.prototype.buildExtendedPublicKey = function() {
]); ]);
} }
BIP32.prototype.extendedPublicKeyString = function(format) { HierarchicalKey.prototype.extendedPublicKeyString = function(format) {
if (format === undefined || format === 'base58') { if (format === undefined || format === 'base58') {
var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPublicKey)); var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPublicKey));
var checksum = hash.slice(0, 4); var checksum = hash.slice(0, 4);
@ -170,7 +170,7 @@ BIP32.prototype.extendedPublicKeyString = function(format) {
} }
} }
BIP32.prototype.buildExtendedPrivateKey = function() { HierarchicalKey.prototype.buildExtendedPrivateKey = function() {
if (!this.hasPrivateKey) return; if (!this.hasPrivateKey) return;
this.extendedPrivateKey = new Buffer([]); this.extendedPrivateKey = new Buffer([]);
@ -193,7 +193,7 @@ BIP32.prototype.buildExtendedPrivateKey = function() {
]); ]);
} }
BIP32.prototype.extendedPrivateKeyString = function(format) { HierarchicalKey.prototype.extendedPrivateKeyString = function(format) {
if (format === undefined || format === 'base58') { if (format === undefined || format === 'base58') {
var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPrivateKey)); var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPrivateKey));
var checksum = hash.slice(0, 4); var checksum = hash.slice(0, 4);
@ -207,14 +207,14 @@ BIP32.prototype.extendedPrivateKeyString = function(format) {
} }
BIP32.prototype.derive = function(path) { HierarchicalKey.prototype.derive = function(path) {
var e = path.split('/'); var e = path.split('/');
// Special cases: // Special cases:
if (path == 'm' || path == 'M' || path == 'm\'' || path == 'M\'') if (path == 'm' || path == 'M' || path == 'm\'' || path == 'M\'')
return this; return this;
var bip32 = this; var hkey = this;
for (var i in e) { for (var i in e) {
var c = e[i]; var c = e[i];
@ -229,13 +229,13 @@ BIP32.prototype.derive = function(path) {
if (usePrivate) if (usePrivate)
childIndex += 0x80000000; childIndex += 0x80000000;
bip32 = bip32.deriveChild(childIndex); hkey = hkey.deriveChild(childIndex);
} }
return bip32; return hkey;
} }
BIP32.prototype.deriveChild = function(i) { HierarchicalKey.prototype.deriveChild = function(i) {
var ib = []; var ib = [];
ib.push((i >> 24) & 0xff); ib.push((i >> 24) & 0xff);
ib.push((i >> 16) & 0xff); ib.push((i >> 16) & 0xff);
@ -246,8 +246,8 @@ BIP32.prototype.deriveChild = function(i) {
var usePrivate = (i & 0x80000000) != 0; var usePrivate = (i & 0x80000000) != 0;
var isPrivate = var isPrivate =
(this.version == networks['livenet'].bip32privateVersion || (this.version == networks['livenet'].hkeyPrivateVersion ||
this.version == networks['testnet'].bip32privateVersion ); this.version == networks['testnet'].hkeyPrivateVersion );
if (usePrivate && (!this.hasPrivateKey || !isPrivate)) if (usePrivate && (!this.hasPrivateKey || !isPrivate))
throw new Error('Cannot do private key derivation without private key'); throw new Error('Cannot do private key derivation without private key');
@ -270,7 +270,7 @@ BIP32.prototype.deriveChild = function(i) {
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); var k = il.add(priv).mod(secp256k1_n);
ret = new BIP32(null); ret = new HierarchicalKey(null);
ret.chainCode = ir; ret.chainCode = ir;
ret.eckey = new Key(); ret.eckey = new Key();
@ -296,7 +296,7 @@ BIP32.prototype.deriveChild = function(i) {
var Kpar = Point.fromUncompressedPubKey(oldkey.public); var Kpar = Point.fromUncompressedPubKey(oldkey.public);
var newpub = Point.add(ilG, Kpar).toUncompressedPubKey(); var newpub = Point.add(ilG, Kpar).toUncompressedPubKey();
ret = new BIP32(null); ret = new HierarchicalKey(null);
ret.chainCode = new Buffer(ir); ret.chainCode = new Buffer(ir);
var eckey = new Key(); var eckey = new Key();
@ -337,4 +337,4 @@ function u16(f) {return uint(f,2);}
function u32(f) {return uint(f,4);} function u32(f) {return uint(f,4);}
function u64(f) {return uint(f,8);} function u64(f) {return uint(f,8);}
module.exports = require('soop')(BIP32); module.exports = require('soop')(HierarchicalKey);

View File

@ -8,8 +8,8 @@ exports.livenet = {
addressVersion: 0x00, addressVersion: 0x00,
privKeyVersion: 128, privKeyVersion: 128,
P2SHVersion: 5, P2SHVersion: 5,
bip32publicVersion: 0x0488b21e, hkeyPublicVersion: 0x0488b21e,
bip32privateVersion: 0x0488ade4, hkeyPrivateVersion: 0x0488ade4,
genesisBlock: { genesisBlock: {
hash: hex('6FE28C0AB6F1B372C1A6A246AE63F74F931E8365E15A089C68D6190000000000'), hash: hex('6FE28C0AB6F1B372C1A6A246AE63F74F931E8365E15A089C68D6190000000000'),
merkle_root: hex('3BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A'), merkle_root: hex('3BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A'),
@ -37,8 +37,8 @@ exports.testnet = {
addressVersion: 0x6f, addressVersion: 0x6f,
privKeyVersion: 239, privKeyVersion: 239,
P2SHVersion: 196, P2SHVersion: 196,
bip32publicVersion: 0x043587cf, hkeyPublicVersion: 0x043587cf,
bip32privateVersion: 0x04358394, hkeyPrivateVersion: 0x04358394,
genesisBlock: { genesisBlock: {
hash: hex('43497FD7F826957108F4A30FD9CEC3AEBA79972084E90EAD01EA330900000000'), hash: hex('43497FD7F826957108F4A30FD9CEC3AEBA79972084E90EAD01EA330900000000'),
merkle_root: hex('3BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A'), merkle_root: hex('3BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A'),

View File

@ -3,9 +3,9 @@
var chai = chai || require('chai'); var chai = chai || require('chai');
var should = chai.should(); var should = chai.should();
var bitcore = bitcore || require('../bitcore'); var bitcore = bitcore || require('../bitcore');
var BIP32 = bitcore.BIP32; var HierarchicalKey = bitcore.HierarchicalKey;
describe('BIP32', function() { describe('HierarchicalKey', function() {
//test vectors: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki //test vectors: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
var vector1_master = '000102030405060708090a0b0c0d0e0f'; var vector1_master = '000102030405060708090a0b0c0d0e0f';
@ -37,238 +37,238 @@ describe('BIP32', function() {
it('should initialize the class', function() { it('should initialize the class', function() {
should.exist(BIP32); should.exist(HierarchicalKey);
}); });
it('should create a mainnet bip32', function() { it('should create a mainnet hkey', function() {
var bip32 = new BIP32('mainnet'); var hkey = new HierarchicalKey('mainnet');
should.exist(bip32); should.exist(hkey);
}); });
it('should create a testnet bip32', function() { it('should create a testnet hkey', function() {
var bip32 = new BIP32('testnet'); var hkey = new HierarchicalKey('testnet');
should.exist(bip32); should.exist(hkey);
}); });
it('should initialize test vector 1 from the extended public key', function() { it('should initialize test vector 1 from the extended public key', function() {
var bip32 = new BIP32(vector1_m_public); var hkey = new HierarchicalKey(vector1_m_public);
should.exist(bip32); should.exist(hkey);
}); });
it('should initialize test vector 1 from the extended private key', function() { it('should initialize test vector 1 from the extended private key', function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
should.exist(bip32); should.exist(hkey);
}); });
it('should get the extended public key from the extended private key for test vector 1', function() { it('should get the extended public key from the extended private key for test vector 1', function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
bip32.extendedPublicKeyString().should.equal(vector1_m_public); hkey.extendedPublicKeyString().should.equal(vector1_m_public);
}); });
it("should get m/0' ext. private key from test vector 1", function() { it("should get m/0' ext. private key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'"); var child = hkey.derive("m/0'");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector1_m0h_private); child.extendedPrivateKeyString().should.equal(vector1_m0h_private);
}); });
it("should get m/0' ext. public key from test vector 1", function() { it("should get m/0' ext. public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'"); var child = hkey.derive("m/0'");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector1_m0h_public); child.extendedPublicKeyString().should.equal(vector1_m0h_public);
}); });
it("should get m/0'/1 ext. private key from test vector 1", function() { it("should get m/0'/1 ext. private key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1"); var child = hkey.derive("m/0'/1");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector1_m0h1_private); child.extendedPrivateKeyString().should.equal(vector1_m0h1_private);
}); });
it("should get m/0'/1 ext. public key from test vector 1", function() { it("should get m/0'/1 ext. public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1"); var child = hkey.derive("m/0'/1");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector1_m0h1_public); child.extendedPublicKeyString().should.equal(vector1_m0h1_public);
}); });
it("should get m/0'/1 ext. public key from m/0' public key from test vector 1", function() { it("should get m/0'/1 ext. public key from m/0' public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'"); var child = hkey.derive("m/0'");
var child_pub = new BIP32(child.extendedPublicKeyString()); var child_pub = new HierarchicalKey(child.extendedPublicKeyString());
var child2 = child_pub.derive("m/1"); var child2 = child_pub.derive("m/1");
should.exist(child2); should.exist(child2);
child2.extendedPublicKeyString().should.equal(vector1_m0h1_public); child2.extendedPublicKeyString().should.equal(vector1_m0h1_public);
}); });
it("should get m/0'/1/2h ext. private key from test vector 1", function() { it("should get m/0'/1/2h ext. private key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'"); var child = hkey.derive("m/0'/1/2'");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector1_m0h12h_private); child.extendedPrivateKeyString().should.equal(vector1_m0h12h_private);
}); });
it("should get m/0'/1/2h ext. public key from test vector 1", function() { it("should get m/0'/1/2h ext. public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'"); var child = hkey.derive("m/0'/1/2'");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector1_m0h12h_public); child.extendedPublicKeyString().should.equal(vector1_m0h12h_public);
}); });
it("should get m/0'/1/2h/2 ext. private key from test vector 1", function() { it("should get m/0'/1/2h/2 ext. private key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'/2"); var child = hkey.derive("m/0'/1/2'/2");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector1_m0h12h2_private); child.extendedPrivateKeyString().should.equal(vector1_m0h12h2_private);
}); });
it("should get m/0'/1/2'/2 ext. public key from m/0'/1/2' public key from test vector 1", function() { it("should get m/0'/1/2'/2 ext. public key from m/0'/1/2' public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'"); var child = hkey.derive("m/0'/1/2'");
var child_pub = new BIP32(child.extendedPublicKeyString()); var child_pub = new HierarchicalKey(child.extendedPublicKeyString());
var child2 = child_pub.derive("m/2"); var child2 = child_pub.derive("m/2");
should.exist(child2); should.exist(child2);
child2.extendedPublicKeyString().should.equal(vector1_m0h12h2_public); child2.extendedPublicKeyString().should.equal(vector1_m0h12h2_public);
}); });
it("should get m/0'/1/2h/2 ext. public key from test vector 1", function() { it("should get m/0'/1/2h/2 ext. public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'/2"); var child = hkey.derive("m/0'/1/2'/2");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector1_m0h12h2_public); child.extendedPublicKeyString().should.equal(vector1_m0h12h2_public);
}); });
it("should get m/0'/1/2h/2/1000000000 ext. private key from test vector 1", function() { it("should get m/0'/1/2h/2/1000000000 ext. private key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'/2/1000000000"); var child = hkey.derive("m/0'/1/2'/2/1000000000");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector1_m0h12h21000000000_private); child.extendedPrivateKeyString().should.equal(vector1_m0h12h21000000000_private);
}); });
it("should get m/0'/1/2h/2/1000000000 ext. public key from test vector 1", function() { it("should get m/0'/1/2h/2/1000000000 ext. public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'/2/1000000000"); var child = hkey.derive("m/0'/1/2'/2/1000000000");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector1_m0h12h21000000000_public); child.extendedPublicKeyString().should.equal(vector1_m0h12h21000000000_public);
}); });
it("should get m/0'/1/2'/2/1000000000 ext. public key from m/0'/1/2'/2 public key from test vector 1", function() { it("should get m/0'/1/2'/2/1000000000 ext. public key from m/0'/1/2'/2 public key from test vector 1", function() {
var bip32 = new BIP32(vector1_m_private); var hkey = new HierarchicalKey(vector1_m_private);
var child = bip32.derive("m/0'/1/2'/2"); var child = hkey.derive("m/0'/1/2'/2");
var child_pub = new BIP32(child.extendedPublicKeyString()); var child_pub = new HierarchicalKey(child.extendedPublicKeyString());
var child2 = child_pub.derive("m/1000000000"); var child2 = child_pub.derive("m/1000000000");
should.exist(child2); should.exist(child2);
child2.extendedPublicKeyString().should.equal(vector1_m0h12h21000000000_public); child2.extendedPublicKeyString().should.equal(vector1_m0h12h21000000000_public);
}); });
it('should initialize test vector 2 from the extended public key', function() { it('should initialize test vector 2 from the extended public key', function() {
var bip32 = new BIP32(vector2_m_public); var hkey = new HierarchicalKey(vector2_m_public);
should.exist(bip32); should.exist(hkey);
}); });
it('should initialize test vector 2 from the extended private key', function() { it('should initialize test vector 2 from the extended private key', function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
should.exist(bip32); should.exist(hkey);
}); });
it('should get the extended public key from the extended private key for test vector 2', function() { it('should get the extended public key from the extended private key for test vector 2', function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
bip32.extendedPublicKeyString().should.equal(vector2_m_public); hkey.extendedPublicKeyString().should.equal(vector2_m_public);
}); });
it("should get m/0 ext. private key from test vector 2", function() { it("should get m/0 ext. private key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0"); var child = hkey.derive("m/0");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector2_m0_private); child.extendedPrivateKeyString().should.equal(vector2_m0_private);
}); });
it("should get m/0 ext. public key from test vector 2", function() { it("should get m/0 ext. public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0"); var child = hkey.derive("m/0");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector2_m0_public); child.extendedPublicKeyString().should.equal(vector2_m0_public);
}); });
it("should get m/0 ext. public key from m public key from test vector 2", function() { it("should get m/0 ext. public key from m public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m"); var child = hkey.derive("m");
var child_pub = new BIP32(child.extendedPublicKeyString()); var child_pub = new HierarchicalKey(child.extendedPublicKeyString());
var child2 = child_pub.derive("m/0"); var child2 = child_pub.derive("m/0");
should.exist(child2); should.exist(child2);
child2.extendedPublicKeyString().should.equal(vector2_m0_public); child2.extendedPublicKeyString().should.equal(vector2_m0_public);
}); });
it("should get m/0/2147483647h ext. private key from test vector 2", function() { it("should get m/0/2147483647h ext. private key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'"); var child = hkey.derive("m/0/2147483647'");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector2_m02147483647h_private); child.extendedPrivateKeyString().should.equal(vector2_m02147483647h_private);
}); });
it("should get m/0/2147483647h ext. public key from test vector 2", function() { it("should get m/0/2147483647h ext. public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'"); var child = hkey.derive("m/0/2147483647'");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector2_m02147483647h_public); child.extendedPublicKeyString().should.equal(vector2_m02147483647h_public);
}); });
it("should get m/0/2147483647h/1 ext. private key from test vector 2", function() { it("should get m/0/2147483647h/1 ext. private key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'/1"); var child = hkey.derive("m/0/2147483647'/1");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector2_m02147483647h1_private); child.extendedPrivateKeyString().should.equal(vector2_m02147483647h1_private);
}); });
it("should get m/0/2147483647h/1 ext. public key from test vector 2", function() { it("should get m/0/2147483647h/1 ext. public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'/1"); var child = hkey.derive("m/0/2147483647'/1");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector2_m02147483647h1_public); child.extendedPublicKeyString().should.equal(vector2_m02147483647h1_public);
}); });
it("should get m/0/2147483647h/1 ext. public key from m/0/2147483647h public key from test vector 2", function() { it("should get m/0/2147483647h/1 ext. public key from m/0/2147483647h public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'"); var child = hkey.derive("m/0/2147483647'");
var child_pub = new BIP32(child.extendedPublicKeyString()); var child_pub = new HierarchicalKey(child.extendedPublicKeyString());
var child2 = child_pub.derive("m/1"); var child2 = child_pub.derive("m/1");
should.exist(child2); should.exist(child2);
child2.extendedPublicKeyString().should.equal(vector2_m02147483647h1_public); child2.extendedPublicKeyString().should.equal(vector2_m02147483647h1_public);
}); });
it("should get m/0/2147483647h/1/2147483646h ext. private key from test vector 2", function() { it("should get m/0/2147483647h/1/2147483646h ext. private key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'/1/2147483646'"); var child = hkey.derive("m/0/2147483647'/1/2147483646'");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector2_m02147483647h12147483646h_private); child.extendedPrivateKeyString().should.equal(vector2_m02147483647h12147483646h_private);
}); });
it("should get m/0/2147483647h/1/2147483646h ext. public key from test vector 2", function() { it("should get m/0/2147483647h/1/2147483646h ext. public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'/1/2147483646'"); var child = hkey.derive("m/0/2147483647'/1/2147483646'");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector2_m02147483647h12147483646h_public); child.extendedPublicKeyString().should.equal(vector2_m02147483647h12147483646h_public);
}); });
it("should get m/0/2147483647h/1/2147483646h/2 ext. private key from test vector 2", function() { it("should get m/0/2147483647h/1/2147483646h/2 ext. private key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'/1/2147483646'/2"); var child = hkey.derive("m/0/2147483647'/1/2147483646'/2");
should.exist(child); should.exist(child);
child.extendedPrivateKeyString().should.equal(vector2_m02147483647h12147483646h2_private); child.extendedPrivateKeyString().should.equal(vector2_m02147483647h12147483646h2_private);
}); });
it("should get m/0/2147483647h/1/2147483646h/2 ext. public key from test vector 2", function() { it("should get m/0/2147483647h/1/2147483646h/2 ext. public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'/1/2147483646'/2"); var child = hkey.derive("m/0/2147483647'/1/2147483646'/2");
should.exist(child); should.exist(child);
child.extendedPublicKeyString().should.equal(vector2_m02147483647h12147483646h2_public); child.extendedPublicKeyString().should.equal(vector2_m02147483647h12147483646h2_public);
}); });
it("should get m/0/2147483647h/1/2147483646h/2 ext. public key from m/0/2147483647h/2147483646h public key from test vector 2", function() { it("should get m/0/2147483647h/1/2147483646h/2 ext. public key from m/0/2147483647h/2147483646h public key from test vector 2", function() {
var bip32 = new BIP32(vector2_m_private); var hkey = new HierarchicalKey(vector2_m_private);
var child = bip32.derive("m/0/2147483647'/1/2147483646'"); var child = hkey.derive("m/0/2147483647'/1/2147483646'");
var child_pub = new BIP32(child.extendedPublicKeyString()); var child_pub = new HierarchicalKey(child.extendedPublicKeyString());
var child2 = child_pub.derive("m/2"); var child2 = child_pub.derive("m/2");
should.exist(child2); should.exist(child2);
child2.extendedPublicKeyString().should.equal(vector2_m02147483647h12147483646h2_public); child2.extendedPublicKeyString().should.equal(vector2_m02147483647h12147483646h2_public);
@ -276,32 +276,32 @@ describe('BIP32', function() {
describe('#seed', function() { describe('#seed', function() {
it('should initialize a new BIP32 correctly from test vector 1 seed', function() { it('should initialize a new HierarchicalKey correctly from test vector 1 seed', function() {
var hex = vector1_master; var hex = vector1_master;
var bip32 = BIP32.seed(hex, 'livenet'); var hkey = HierarchicalKey.seed(hex, 'livenet');
should.exist(bip32); should.exist(hkey);
bip32.extendedPrivateKeyString().should.equal(vector1_m_private); hkey.extendedPrivateKeyString().should.equal(vector1_m_private);
bip32.extendedPublicKeyString().should.equal(vector1_m_public); hkey.extendedPublicKeyString().should.equal(vector1_m_public);
}); });
it('should initialize a new BIP32 correctly from test vector 2 seed', function() { it('should initialize a new HierarchicalKey correctly from test vector 2 seed', function() {
var hex = vector2_master; var hex = vector2_master;
var bip32 = BIP32.seed(hex, 'livenet'); var hkey = HierarchicalKey.seed(hex, 'livenet');
should.exist(bip32); should.exist(hkey);
bip32.extendedPrivateKeyString().should.equal(vector2_m_private); hkey.extendedPrivateKeyString().should.equal(vector2_m_private);
bip32.extendedPublicKeyString().should.equal(vector2_m_public); hkey.extendedPublicKeyString().should.equal(vector2_m_public);
}); });
}); });
describe('testnet', function() { describe('testnet', function() {
it('should initialize a new BIP32 correctly from a random BIP32', function() { it('should initialize a new HierarchicalKey correctly from a random HierarchicalKey', function() {
var b1 = new BIP32('testnet'); var b1 = new HierarchicalKey('testnet');
var b2 = new BIP32(b1.extendedPublicKeyString()); var b2 = new HierarchicalKey(b1.extendedPublicKeyString());
b2.extendedPublicKeyString().should.equal(b1.extendedPublicKeyString()); b2.extendedPublicKeyString().should.equal(b1.extendedPublicKeyString());
}); });
it('should generate valid ext pub key for testnet', function() { it('should generate valid ext pub key for testnet', function() {
var b = new BIP32('testnet'); var b = new HierarchicalKey('testnet');
b.extendedPublicKeyString().substring(0,4).should.equal('tpub'); b.extendedPublicKeyString().substring(0,4).should.equal('tpub');
}); });
}); });

View File

@ -7,7 +7,7 @@ var unmute = require('./mute').unmute;
var examples = [ var examples = [
'Address', 'Address',
'BIP32', 'HierarchicalKey',
'PeerManager', 'PeerManager',
'Rpc', 'Rpc',
'SendTx', 'SendTx',

View File

@ -35,8 +35,8 @@ describe('Miscelaneous stuff', function() {
should.exist(net.addressVersion); should.exist(net.addressVersion);
should.exist(net.privKeyVersion); should.exist(net.privKeyVersion);
should.exist(net.P2SHVersion); should.exist(net.P2SHVersion);
should.exist(net.bip32publicVersion); should.exist(net.hkeyPublicVersion);
should.exist(net.bip32privateVersion); should.exist(net.hkeyPrivateVersion);
} }
}); });
it('should initialze the const object', function() { it('should initialze the const object', function() {