Browse Source

revert behavior of derive

patch-2
Gabe Gattis 8 years ago
parent
commit
1b2c41978f
No known key found for this signature in database GPG Key ID: 441430987182732C
  1. 37
      lib/hdprivatekey.js
  2. 33
      lib/hdpublickey.js
  3. 89
      test/hdkeys.js
  4. 12
      test/hdprivatekey.js
  5. 16
      test/hdpublickey.js

37
lib/hdprivatekey.js

@ -126,12 +126,40 @@ HDPrivateKey._getDerivationIndexes = function(path) {
return _.any(indexes, isNaN) ? null : indexes;
};
HDPrivateKey.prototype.derive = function() {
throw new Error('Method has been deprecated, please use deriveChild or deriveNonCompliantChild' +
'and see documentation for more information');
/**
* WARNING: This method is deprecated. Use deriveChild or deriveNonCompliantChild instead.
*
*
* Get a derived child based on a string or number.
*
* If the first argument is a string, it's parsed as the full path of
* derivation. Valid values for this argument include "m" (which returns the
* same private key), "m/0/1/40/2'/1000", where the ' quote means a hardened
* derivation.
*
* If the first argument is a number, the child with that index will be
* derived. If the second argument is truthy, the hardened version will be
* derived. See the example usage for clarification.
*
* @example
* ```javascript
* var parent = new HDPrivateKey('xprv...');
* var child_0_1_2h = parent.derive(0).derive(1).derive(2, true);
* var copy_of_child_0_1_2h = parent.derive("m/0/1/2'");
* assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h);
* ```
*
* @param {string|number} arg
* @param {boolean?} hardened
*/
HDPrivateKey.prototype.derive = function(arg, hardened) {
return this.deriveNonCompliantChild(arg, hardened);
};
/**
* WARNING: This method will not be officially supported until v1.0.0.
*
*
* Get a derived child based on a string or number.
*
* If the first argument is a string, it's parsed as the full path of
@ -170,6 +198,9 @@ HDPrivateKey.prototype.deriveChild = function(arg, hardened, nonCompliant) {
};
/**
* WARNING: This method will not be officially supported until v1.0.0
*
*
* WARNING: If this is a new implementation you should NOT use this method, you should be using
* `derive` instead.
*

33
lib/hdpublickey.js

@ -85,12 +85,39 @@ HDPublicKey.isValidPath = function(arg) {
return false;
};
HDPublicKey.prototype.derive = function() {
throw new Error('Method has been deprecated, please use deriveChild instead' +
'and see documentation for more information');
/**
* WARNING: This method is deprecated. Use deriveChild instead.
*
*
* Get a derivated child based on a string or number.
*
* If the first argument is a string, it's parsed as the full path of
* derivation. Valid values for this argument include "m" (which returns the
* same public key), "m/0/1/40/2/1000".
*
* Note that hardened keys can't be derived from a public extended key.
*
* If the first argument is a number, the child with that index will be
* derived. See the example usage for clarification.
*
* @example
* ```javascript
* var parent = new HDPublicKey('xpub...');
* var child_0_1_2 = parent.derive(0).derive(1).derive(2);
* var copy_of_child_0_1_2 = parent.derive("m/0/1/2");
* assert(child_0_1_2.xprivkey === copy_of_child_0_1_2);
* ```
*
* @param {string|number} arg
*/
HDPublicKey.prototype.derive = function(arg, hardened) {
return this.deriveChild(arg, hardened);
};
/**
* WARNING: This method will not be officially supported until v1.0.0.
*
*
* Get a derivated child based on a string or number.
*
* If the first argument is a string, it's parsed as the full path of

89
test/hdkeys.js

@ -81,69 +81,69 @@ describe('BIP32 compliance', function() {
});
it("should get m/0' ext. private key from test vector 1", function() {
var privateKey = new HDPrivateKey(vector1_m_private).deriveChild("m/0'");
var privateKey = new HDPrivateKey(vector1_m_private).derive("m/0'");
privateKey.xprivkey.should.equal(vector1_m0h_private);
});
it("should get m/0' ext. public key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'")
HDPrivateKey(vector1_m_private).derive("m/0'")
.xpubkey.should.equal(vector1_m0h_public);
});
it("should get m/0'/1 ext. private key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'/1")
HDPrivateKey(vector1_m_private).derive("m/0'/1")
.xprivkey.should.equal(vector1_m0h1_private);
});
it("should get m/0'/1 ext. public key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'/1")
HDPrivateKey(vector1_m_private).derive("m/0'/1")
.xpubkey.should.equal(vector1_m0h1_public);
});
it("should get m/0'/1 ext. public key from m/0' public key from test vector 1", function() {
var derivedPublic = HDPrivateKey(vector1_m_private).deriveChild("m/0'").hdPublicKey.deriveChild("m/1");
var derivedPublic = HDPrivateKey(vector1_m_private).derive("m/0'").hdPublicKey.derive("m/1");
derivedPublic.xpubkey.should.equal(vector1_m0h1_public);
});
it("should get m/0'/1/2' ext. private key from test vector 1", function() {
var privateKey = new HDPrivateKey(vector1_m_private);
var derived = privateKey.deriveChild("m/0'/1/2'");
var derived = privateKey.derive("m/0'/1/2'");
derived.xprivkey.should.equal(vector1_m0h12h_private);
});
it("should get m/0'/1/2' ext. public key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'/1/2'")
HDPrivateKey(vector1_m_private).derive("m/0'/1/2'")
.xpubkey.should.equal(vector1_m0h12h_public);
});
it("should get m/0'/1/2'/2 ext. private key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'/1/2'/2")
HDPrivateKey(vector1_m_private).derive("m/0'/1/2'/2")
.xprivkey.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() {
var derived = HDPrivateKey(vector1_m_private).deriveChild("m/0'/1/2'").hdPublicKey;
derived.deriveChild("m/2").xpubkey.should.equal(vector1_m0h12h2_public);
var derived = HDPrivateKey(vector1_m_private).derive("m/0'/1/2'").hdPublicKey;
derived.derive("m/2").xpubkey.should.equal(vector1_m0h12h2_public);
});
it("should get m/0'/1/2h/2 ext. public key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'/1/2'/2")
HDPrivateKey(vector1_m_private).derive("m/0'/1/2'/2")
.xpubkey.should.equal(vector1_m0h12h2_public);
});
it("should get m/0'/1/2h/2/1000000000 ext. private key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'/1/2'/2/1000000000")
HDPrivateKey(vector1_m_private).derive("m/0'/1/2'/2/1000000000")
.xprivkey.should.equal(vector1_m0h12h21000000000_private);
});
it("should get m/0'/1/2h/2/1000000000 ext. public key from test vector 1", function() {
HDPrivateKey(vector1_m_private).deriveChild("m/0'/1/2'/2/1000000000")
HDPrivateKey(vector1_m_private).derive("m/0'/1/2'/2/1000000000")
.xpubkey.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() {
var derived = HDPrivateKey(vector1_m_private).deriveChild("m/0'/1/2'/2").hdPublicKey;
derived.deriveChild("m/1000000000").xpubkey.should.equal(vector1_m0h12h21000000000_public);
var derived = HDPrivateKey(vector1_m_private).derive("m/0'/1/2'/2").hdPublicKey;
derived.derive("m/1000000000").xpubkey.should.equal(vector1_m0h12h21000000000_public);
});
it('should initialize test vector 2 from the extended public key', function() {
@ -159,66 +159,66 @@ describe('BIP32 compliance', function() {
});
it("should get m/0 ext. private key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild(0).xprivkey.should.equal(vector2_m0_private);
HDPrivateKey(vector2_m_private).derive(0).xprivkey.should.equal(vector2_m0_private);
});
it("should get m/0 ext. public key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild(0).xpubkey.should.equal(vector2_m0_public);
HDPrivateKey(vector2_m_private).derive(0).xpubkey.should.equal(vector2_m0_public);
});
it("should get m/0 ext. public key from m public key from test vector 2", function() {
HDPrivateKey(vector2_m_private).hdPublicKey.deriveChild(0).xpubkey.should.equal(vector2_m0_public);
HDPrivateKey(vector2_m_private).hdPublicKey.derive(0).xpubkey.should.equal(vector2_m0_public);
});
it("should get m/0/2147483647h ext. private key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'")
.xprivkey.should.equal(vector2_m02147483647h_private);
});
it("should get m/0/2147483647h ext. public key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'")
.xpubkey.should.equal(vector2_m02147483647h_public);
});
it("should get m/0/2147483647h/1 ext. private key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'/1")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'/1")
.xprivkey.should.equal(vector2_m02147483647h1_private);
});
it("should get m/0/2147483647h/1 ext. public key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'/1")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'/1")
.xpubkey.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() {
var derived = HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'").hdPublicKey;
derived.deriveChild(1).xpubkey.should.equal(vector2_m02147483647h1_public);
var derived = HDPrivateKey(vector2_m_private).derive("m/0/2147483647'").hdPublicKey;
derived.derive(1).xpubkey.should.equal(vector2_m02147483647h1_public);
});
it("should get m/0/2147483647h/1/2147483646h ext. private key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'/1/2147483646'")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'/1/2147483646'")
.xprivkey.should.equal(vector2_m02147483647h12147483646h_private);
});
it("should get m/0/2147483647h/1/2147483646h ext. public key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'/1/2147483646'")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'/1/2147483646'")
.xpubkey.should.equal(vector2_m02147483647h12147483646h_public);
});
it("should get m/0/2147483647h/1/2147483646h/2 ext. private key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'/1/2147483646'/2")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'/1/2147483646'/2")
.xprivkey.should.equal(vector2_m02147483647h12147483646h2_private);
});
it("should get m/0/2147483647h/1/2147483646h/2 ext. public key from test vector 2", function() {
HDPrivateKey(vector2_m_private).deriveChild("m/0/2147483647'/1/2147483646'/2")
HDPrivateKey(vector2_m_private).derive("m/0/2147483647'/1/2147483646'/2")
.xpubkey.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() {
var derivedPublic = HDPrivateKey(vector2_m_private)
.deriveChild("m/0/2147483647'/1/2147483646'").hdPublicKey;
derivedPublic.deriveChild("m/2")
.derive("m/0/2147483647'/1/2147483646'").hdPublicKey;
derivedPublic.derive("m/2")
.xpubkey.should.equal(vector2_m02147483647h12147483646h2_public);
});
@ -254,19 +254,20 @@ describe('BIP32 compliance', function() {
derived.privateKey.toString().should.equal('4811a079bab267bfdca855b3bddff20231ff7044e648514fa099158472df2836');
});
it('hdprivatekey will throw deprecation message', function() {
expect(function() {
var key = new HDPrivateKey();
key.derive();
}).to.throw('Method has been deprecated');
it('should NOT use full 32 bytes for private key data that is hashed with the nonCompliant derive method', function() {
// This is to test that the previously implemented non-compliant to BIP32
var privateKeyBuffer = new Buffer('00000055378cf5fafb56c711c674143f9b0ee82ab0ba2924f19b64f5ae7cdbfd', 'hex');
var chainCodeBuffer = new Buffer('9c8a5c863e5941f3d99453e6ba66b328bb17cf0b8dec89ed4fc5ace397a1c089', 'hex');
var key = HDPrivateKey.fromObject({
network: 'testnet',
depth: 0,
parentFingerPrint: 0,
childIndex: 0,
privateKey: privateKeyBuffer,
chainCode: chainCodeBuffer
});
it('hdpublickey will throw deprecation message', function() {
expect(function() {
var key = new HDPrivateKey();
var pubkey = key.hdPublicKey;
pubkey.derive();
}).to.throw('Method has been deprecated');
var derived = key.derive("m/44'/0'/0'/0/0'");
derived.privateKey.toString().should.equal('4811a079bab267bfdca855b3bddff20231ff7044e648514fa099158472df2836');
});
describe('edge cases', function() {
@ -299,7 +300,7 @@ describe('BIP32 compliance', function() {
privateKey: privateKeyBuffer,
chainCode: chainCodeBuffer
});
var derived = key.deriveChild("m/44'");
var derived = key.derive("m/44'");
derived.privateKey.toString().should.equal('b15bce3608d607ee3a49069197732c656bca942ee59f3e29b4d56914c1de6825');
bitcore.PrivateKey.isValid.callCount.should.equal(2);
});
@ -320,7 +321,7 @@ describe('BIP32 compliance', function() {
throw new Error('Point cannot be equal to Infinity');
};
sandbox.spy(key, '_deriveWithNumber');
var derived = key.deriveChild("m/44");
var derived = key.derive("m/44");
key._deriveWithNumber.callCount.should.equal(2);
key.publicKey.toString().should.equal('029e58b241790284ef56502667b15157b3fc58c567f044ddc35653860f9455d099');
});

12
test/hdprivatekey.js

@ -30,7 +30,7 @@ describe('HDPrivate key interface', function() {
var expectDerivationFail = function(argument, error) {
return expectFail(function() {
var privateKey = new HDPrivateKey(xprivkey);
privateKey.deriveChild(argument);
privateKey.derive(argument);
}, error);
};
@ -123,14 +123,14 @@ describe('HDPrivate key interface', function() {
it('allows derivation of hardened keys by passing a very big number', function() {
var privateKey = new HDPrivateKey(xprivkey);
var derivedByNumber = privateKey.deriveChild(0x80000000);
var derivedByArgument = privateKey.deriveChild(0, true);
var derivedByNumber = privateKey.derive(0x80000000);
var derivedByArgument = privateKey.derive(0, true);
derivedByNumber.xprivkey.should.equal(derivedByArgument.xprivkey);
});
it('returns itself with \'m\' parameter', function() {
var privateKey = new HDPrivateKey(xprivkey);
privateKey.should.equal(privateKey.deriveChild('m'));
privateKey.should.equal(privateKey.derive('m'));
});
it('returns InvalidArgument if invalid data is given to getSerializedError', function() {
@ -203,8 +203,8 @@ describe('HDPrivate key interface', function() {
it('shouldn\'t matter if derivations are made with strings or numbers', function() {
var privateKey = new HDPrivateKey(xprivkey);
var derivedByString = privateKey.deriveChild('m/0\'/1/2\'');
var derivedByNumber = privateKey.deriveChild(0, true).deriveChild(1).deriveChild(2, true);
var derivedByString = privateKey.derive('m/0\'/1/2\'');
var derivedByNumber = privateKey.derive(0, true).derive(1).derive(2, true);
derivedByNumber.xprivkey.should.equal(derivedByString.xprivkey);
});

16
test/hdpublickey.js

@ -32,7 +32,7 @@ describe('HDPublicKey interface', function() {
var expectDerivationFail = function(argument, error) {
(function() {
var pubkey = new HDPublicKey(xpubkey);
pubkey.deriveChild(argument);
pubkey.derive(argument);
}).should.throw(error);
};
@ -188,15 +188,15 @@ describe('HDPublicKey interface', function() {
describe('derivation', function() {
it('derivation is the same whether deriving with number or string', function() {
var pubkey = new HDPublicKey(xpubkey);
var derived1 = pubkey.deriveChild(0).deriveChild(1).deriveChild(200000);
var derived2 = pubkey.deriveChild('m/0/1/200000');
var derived1 = pubkey.derive(0).derive(1).derive(200000);
var derived2 = pubkey.derive('m/0/1/200000');
derived1.xpubkey.should.equal(derived_0_1_200000);
derived2.xpubkey.should.equal(derived_0_1_200000);
});
it('allows special parameters m, M', function() {
var expectDerivationSuccess = function(argument) {
new HDPublicKey(xpubkey).deriveChild(argument).xpubkey.should.equal(xpubkey);
new HDPublicKey(xpubkey).derive(argument).xpubkey.should.equal(xpubkey);
};
expectDerivationSuccess('m');
expectDerivationSuccess('M');
@ -204,13 +204,13 @@ describe('HDPublicKey interface', function() {
it('doesn\'t allow object arguments for derivation', function() {
expectFail(function() {
return new HDPublicKey(xpubkey).deriveChild({});
return new HDPublicKey(xpubkey).derive({});
}, hdErrors.InvalidDerivationArgument);
});
it('needs first argument for derivation', function() {
expectFail(function() {
return new HDPublicKey(xpubkey).deriveChild('s');
return new HDPublicKey(xpubkey).derive('s');
}, hdErrors.InvalidPath);
});
@ -224,13 +224,13 @@ describe('HDPublicKey interface', function() {
it('can\'t derive hardened keys', function() {
expectFail(function() {
return new HDPublicKey(xpubkey).deriveChild(HDPublicKey.Hardened);
return new HDPublicKey(xpubkey).derive(HDPublicKey.Hardened);
}, hdErrors.InvalidIndexCantDeriveHardened);
});
it('can\'t derive hardened keys via second argument', function() {
expectFail(function() {
return new HDPublicKey(xpubkey).deriveChild(5, true);
return new HDPublicKey(xpubkey).derive(5, true);
}, hdErrors.InvalidIndexCantDeriveHardened);
});

Loading…
Cancel
Save