bitcore-lib
Advanced tools
Comparing version 0.13.19 to 0.14.0
@@ -8,11 +8,11 @@ # Bitcoin Crypto | ||
## BN | ||
The `bitcore.Crypto.BN` class contains a wrapper around [bn.js](https://github.com/indutny/bn.js), the bignum library used internally in bitcore. | ||
The `bitcore.crypto.BN` class contains a wrapper around [bn.js](https://github.com/indutny/bn.js), the bignum library used internally in bitcore. | ||
## Point | ||
The `bitcore.Crypto.Point` class contains a wrapper around the class Point of [elliptic.js](https://github.com/indutny/elliptic), the elliptic curve library used internally in bitcore. | ||
The `bitcore.crypto.Point` class contains a wrapper around the class Point of [elliptic.js](https://github.com/indutny/elliptic), the elliptic curve library used internally in bitcore. | ||
## Hash | ||
The `bitcore.Crypto.Hash` namespace contains a set of hashes and utilities. These are either the native `crypto` hash functions from `node.js` or their respective browser shims as provided by the `browserify` library. | ||
The `bitcore.crypto.Hash` namespace contains a set of hashes and utilities. These are either the native `crypto` hash functions from `node.js` or their respective browser shims as provided by the `browserify` library. | ||
## ECDSA | ||
`bitcore.Crypto.ECDSA` contains a pure JavaScript implementation of the elliptic curve DSA signature scheme based on [elliptic.js](https://github.com/indutny/elliptic). | ||
`bitcore.crypto.ECDSA` contains a pure JavaScript implementation of the elliptic curve DSA signature scheme based on [elliptic.js](https://github.com/indutny/elliptic). |
@@ -18,3 +18,3 @@ # HDKeys | ||
var retrieved = new HDPrivateKey('xpriv...'); | ||
var derived = hdPrivateKey.derive("m/0'"); | ||
var derived = hdPrivateKey.derive("m/0'"); // see deprecation warning for derive | ||
var derivedByNumber = hdPrivateKey.derive(1).derive(2, true); | ||
@@ -43,3 +43,12 @@ var derivedByArgument = hdPrivateKey.derive("m/1/2'"); | ||
var address = new Address(hdPublicKey.publicKey, Networks.livenet); | ||
var derivedAddress = new Address(hdPublicKey.derive(100).publicKey, Networks.testnet); | ||
var derivedAddress = new Address(hdPublicKey.derive(100).publicKey, Networks.testnet); // see deprecation warning for derive | ||
``` | ||
## Deprecation Warning for `HDPublicKey.derive()` and `HDPrivateKey.derive()` | ||
There was a bug that was discovered with derivation that would incorrectly calculate the child key against the [BIP32 specification](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). | ||
The bug only affected hardened derivations using an extended private key, and did not affect public key derivation. It also did not affect every derivation and would happen 1 in 256 times where where the private key for the extended private key had a leading zero *(e.g. any private key less than or equal to '0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')*. The leading zero was not included in serialization before hashing to derive a child key, as it should have been. | ||
As a result, `HDPublicKey.derive()` and `HDPrivateKey.derive()` are now deprecated. These methods will throw an error in the next major release. | ||
`HDPublicKey.deriveChild()`, `HDPrivateKey.deriveChild()`, and `HDPrivateKey.deriveNonCompliantChild()` have been implemented as alternatives. Note that these new methods will not be officially supported until v1.0.0. `deriveNonCompliantChild` will derive using the non-BIP32 derivation and is equivalent to the buggy version, `derive`. The `deriveNonCompliantChild` method should not be used unless you're upgrading and need to maintain compatibility with the old derivation. |
@@ -9,3 +9,3 @@ 'use strict'; | ||
if (version !== undefined) { | ||
var message = 'More than one instance of bitcore-lib found. ' + | ||
var message = 'More than one instance of bitcore-lib found. ' + | ||
'Please make sure to require bitcore-lib and check that submodules do' + | ||
@@ -70,3 +70,2 @@ ' not also include their own bitcore-lib dependency.'; | ||
// Internal usage, exposed for testing/advanced tweaking | ||
bitcore._HDKeyCache = require('./lib/hdkeycache'); | ||
bitcore.Transaction.sighash = require('./lib/transaction/sighash'); |
@@ -139,3 +139,3 @@ 'use strict'; | ||
var info = {}; | ||
info.version = br.readUInt32LE(); | ||
info.version = br.readInt32LE(); | ||
info.prevHash = br.read(32); | ||
@@ -195,3 +195,3 @@ info.merkleRoot = br.read(32); | ||
} | ||
bw.writeUInt32LE(this.version); | ||
bw.writeInt32LE(this.version); | ||
bw.write(this.prevHash); | ||
@@ -198,0 +198,0 @@ bw.write(this.merkleRoot); |
@@ -86,2 +86,8 @@ 'use strict'; | ||
BufferReader.prototype.readInt32LE = function() { | ||
var val = this.buf.readInt32LE(this.pos); | ||
this.pos = this.pos + 4; | ||
return val; | ||
}; | ||
BufferReader.prototype.readUInt64BEBN = function() { | ||
@@ -88,0 +94,0 @@ var buf = this.buf.slice(this.pos, this.pos + 8); |
@@ -14,3 +14,2 @@ 'use strict'; | ||
var Network = require('./networks'); | ||
var HDKeyCache = require('./hdkeycache'); | ||
var Point = require('./crypto/point'); | ||
@@ -132,2 +131,5 @@ var PrivateKey = require('./privatekey'); | ||
/** | ||
* WARNING: This method is deprecated. Use deriveChild or deriveNonCompliantChild instead. This is not BIP32 compliant | ||
* | ||
* | ||
* Get a derived child based on a string or number. | ||
@@ -156,2 +158,35 @@ * | ||
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 | ||
* 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. | ||
* | ||
* WARNING: The `nonCompliant` option should NOT be used, except for older implementation | ||
* that used a derivation strategy that used a non-zero padded private key. | ||
* | ||
* @example | ||
* ```javascript | ||
* var parent = new HDPrivateKey('xprv...'); | ||
* var child_0_1_2h = parent.deriveChild(0).deriveChild(1).deriveChild(2, true); | ||
* var copy_of_child_0_1_2h = parent.deriveChild("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.deriveChild = function(arg, hardened) { | ||
if (_.isNumber(arg)) { | ||
@@ -166,3 +201,29 @@ return this._deriveWithNumber(arg, hardened); | ||
HDPrivateKey.prototype._deriveWithNumber = function(index, hardened) { | ||
/** | ||
* 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. | ||
* | ||
* This method is explicitly for use and compatibility with an implementation that | ||
* was not compliant with BIP32 regarding the derivation algorithm. The private key | ||
* must be 32 bytes hashing, and this implementation will use the non-zero padded | ||
* serialization of a private key, such that it's still possible to derive the privateKey | ||
* to recover those funds. | ||
* | ||
* @param {string|number} arg | ||
* @param {boolean?} hardened | ||
*/ | ||
HDPrivateKey.prototype.deriveNonCompliantChild = function(arg, hardened) { | ||
if (_.isNumber(arg)) { | ||
return this._deriveWithNumber(arg, hardened, true); | ||
} else if (_.isString(arg)) { | ||
return this._deriveFromString(arg, true); | ||
} else { | ||
throw new hdErrors.InvalidDerivationArgument(arg); | ||
} | ||
}; | ||
HDPrivateKey.prototype._deriveWithNumber = function(index, hardened, nonCompliant) { | ||
/* jshint maxstatements: 20 */ | ||
@@ -179,11 +240,14 @@ /* jshint maxcomplexity: 10 */ | ||
var cached = HDKeyCache.get(this.xprivkey, index, hardened); | ||
if (cached) { | ||
return cached; | ||
} | ||
var indexBuffer = BufferUtil.integerAsBuffer(index); | ||
var data; | ||
if (hardened) { | ||
data = BufferUtil.concat([new buffer.Buffer([0]), this.privateKey.toBuffer(), indexBuffer]); | ||
if (hardened && nonCompliant) { | ||
// The private key serialization in this case will not be exactly 32 bytes and can be | ||
// any value less, and the value is not zero-padded. | ||
var nonZeroPadded = this.privateKey.bn.toBuffer(); | ||
data = BufferUtil.concat([new buffer.Buffer([0]), nonZeroPadded, indexBuffer]); | ||
} else if (hardened) { | ||
// This will use a 32 byte zero padded serialization of the private key | ||
var privateKeyBuffer = this.privateKey.bn.toBuffer({size: 32}); | ||
assert(privateKeyBuffer.length === 32, 'length of private key buffer is expected to be 32 bytes'); | ||
data = BufferUtil.concat([new buffer.Buffer([0]), privateKeyBuffer, indexBuffer]); | ||
} else { | ||
@@ -202,2 +266,7 @@ data = BufferUtil.concat([this.publicKey.toBuffer(), indexBuffer]); | ||
if (!PrivateKey.isValid(privateKey)) { | ||
// Index at this point is already hardened, we can pass null as the hardened arg | ||
return this._deriveWithNumber(index + 1, null, nonCompliant); | ||
} | ||
var derived = new HDPrivateKey({ | ||
@@ -211,7 +280,7 @@ network: this.network, | ||
}); | ||
HDKeyCache.set(this.xprivkey, index, hardened, derived); | ||
return derived; | ||
}; | ||
HDPrivateKey.prototype._deriveFromString = function(path) { | ||
HDPrivateKey.prototype._deriveFromString = function(path, nonCompliant) { | ||
if (!HDPrivateKey.isValidPath(path)) { | ||
@@ -223,3 +292,3 @@ throw new hdErrors.InvalidPath(path); | ||
var derived = indexes.reduce(function(prev, index) { | ||
return prev._deriveWithNumber(index); | ||
return prev._deriveWithNumber(index, null, nonCompliant); | ||
}, this); | ||
@@ -226,0 +295,0 @@ |
@@ -11,3 +11,2 @@ 'use strict'; | ||
var HDPrivateKey = require('./hdprivatekey'); | ||
var HDKeyCache = require('./hdkeycache'); | ||
var Network = require('./networks'); | ||
@@ -91,2 +90,5 @@ var Point = require('./crypto/point'); | ||
/** | ||
* WARNING: This method is deprecated. Use deriveChild instead. | ||
* | ||
* | ||
* Get a derivated child based on a string or number. | ||
@@ -114,2 +116,31 @@ * | ||
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 | ||
* 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.deriveChild(0).deriveChild(1).deriveChild(2); | ||
* var copy_of_child_0_1_2 = parent.deriveChild("m/0/1/2"); | ||
* assert(child_0_1_2.xprivkey === copy_of_child_0_1_2); | ||
* ``` | ||
* | ||
* @param {string|number} arg | ||
*/ | ||
HDPublicKey.prototype.deriveChild = function(arg, hardened) { | ||
if (_.isNumber(arg)) { | ||
@@ -131,6 +162,2 @@ return this._deriveWithNumber(arg, hardened); | ||
} | ||
var cached = HDKeyCache.get(this.xpubkey, index, false); | ||
if (cached) { | ||
return cached; | ||
} | ||
@@ -143,3 +170,8 @@ var indexBuffer = BufferUtil.integerAsBuffer(index); | ||
var publicKey = PublicKey.fromPoint(Point.getG().mul(leftPart).add(this.publicKey.point)); | ||
var publicKey; | ||
try { | ||
publicKey = PublicKey.fromPoint(Point.getG().mul(leftPart).add(this.publicKey.point)); | ||
} catch (e) { | ||
return this._deriveWithNumber(index + 1); | ||
} | ||
@@ -154,3 +186,3 @@ var derived = new HDPublicKey({ | ||
}); | ||
HDKeyCache.set(this.xpubkey, index, false, derived); | ||
return derived; | ||
@@ -157,0 +189,0 @@ }; |
@@ -339,2 +339,3 @@ 'use strict'; | ||
PrivateKey.prototype.toBuffer = function(){ | ||
// TODO: use `return this.bn.toBuffer({ size: 32 })` in v1.0.0 | ||
return this.bn.toBuffer(); | ||
@@ -344,2 +345,14 @@ }; | ||
/** | ||
* WARNING: This method will not be officially supported until v1.0.0. | ||
* | ||
* | ||
* Will return the private key as a BN buffer without leading zero padding | ||
* | ||
* @returns {Buffer} A buffer of the private key | ||
*/ | ||
PrivateKey.prototype.toBufferNoPadding = function() { | ||
return this.bn.toBuffer(); | ||
}; | ||
/** | ||
* Will return the corresponding public key | ||
@@ -346,0 +359,0 @@ * |
@@ -331,3 +331,3 @@ 'use strict'; | ||
Script.prototype.getPublicKey = function() { | ||
$.checkState(this.isPublicKeyOut(), 'Can\'t retreive PublicKey from a non-PK output'); | ||
$.checkState(this.isPublicKeyOut(), 'Can\'t retrieve PublicKey from a non-PK output'); | ||
return this.chunks[0].buf; | ||
@@ -334,0 +334,0 @@ }; |
@@ -69,3 +69,3 @@ 'use strict'; | ||
// Margin of error to allow fees in the vecinity of the expected value but doesn't allow a big difference | ||
Transaction.FEE_SECURITY_MARGIN = 15; | ||
Transaction.FEE_SECURITY_MARGIN = 150; | ||
@@ -82,3 +82,3 @@ // max amount of satoshis in circulation | ||
// Value used for fee estimation (satoshis per kilobyte) | ||
Transaction.FEE_PER_KB = 10000; | ||
Transaction.FEE_PER_KB = 100000; | ||
@@ -284,3 +284,3 @@ // Safe upper bound for change address script size in bytes | ||
Transaction.prototype.toBufferWriter = function(writer) { | ||
writer.writeUInt32LE(this.version); | ||
writer.writeInt32LE(this.version); | ||
writer.writeVarintNum(this.inputs.length); | ||
@@ -307,3 +307,3 @@ _.each(this.inputs, function(input) { | ||
this.version = reader.readUInt32LE(); | ||
this.version = reader.readInt32LE(); | ||
sizeTxIns = reader.readVarintNum(); | ||
@@ -310,0 +310,0 @@ for (i = 0; i < sizeTxIns; i++) { |
{ | ||
"name": "bitcore", | ||
"version": "0.13.18", | ||
"version": "0.13.19", | ||
"dependencies": { | ||
@@ -5,0 +5,0 @@ "bn.js": { |
{ | ||
"name": "bitcore-lib", | ||
"version": "0.13.19", | ||
"version": "0.14.0", | ||
"description": "A pure and powerful JavaScript Bitcoin library.", | ||
@@ -5,0 +5,0 @@ "author": "BitPay <dev@bitpay.com>", |
@@ -69,5 +69,8 @@ Bitcore Library | ||
To verify signatures, use the following PGP keys: | ||
- @braydonf: https://pgp.mit.edu/pks/lookup?op=get&search=0x9BBF07CAC07A276D | ||
- @pnagurny: https://pgp.mit.edu/pks/lookup?op=get&search=0x0909B33F0AA53013 | ||
- @braydonf: https://pgp.mit.edu/pks/lookup?op=get&search=0x9BBF07CAC07A276D `D909 EFE6 70B5 F6CC 89A3 607A 9BBF 07CA C07A 276D` | ||
- @gabegattis: https://pgp.mit.edu/pks/lookup?op=get&search=0x441430987182732C `F3EA 8E28 29B4 EC93 88CB B0AA 4414 3098 7182 732C` | ||
- @kleetus: https://pgp.mit.edu/pks/lookup?op=get&search=0x33195D27EF6BDB7F `F8B0 891C C459 C197 65C2 5043 3319 5D27 EF6B DB7F` | ||
- @matiu: https://pgp.mit.edu/pks/lookup?op=get&search=0x9EDE6DE4DE531FAC `25CE ED88 A1B1 0CD1 12CD 4121 9EDE 6DE4 DE53 1FAC` | ||
## Development & Tests | ||
@@ -94,2 +97,2 @@ | ||
Copyright 2013-2015 BitPay, Inc. Bitcore is a trademark maintained by BitPay, Inc. | ||
Copyright 2013-2017 BitPay, Inc. Bitcore is a trademark maintained by BitPay, Inc. |
@@ -82,2 +82,12 @@ 'use strict'; | ||
describe('version', function() { | ||
it('is interpreted as an int32le', function() { | ||
var hex = 'ffffffff00000000000000000000000000000000000000000000000000000000000000004141414141414141414141414141414141414141414141414141414141414141010000000200000003000000'; | ||
var header = BlockHeader.fromBuffer(new Buffer(hex, 'hex')); | ||
header.version.should.equal(-1); | ||
header.timestamp.should.equal(1); | ||
}); | ||
}); | ||
describe('#fromObject', function() { | ||
@@ -84,0 +94,0 @@ |
@@ -83,4 +83,4 @@ [ | ||
"sign", ["L4jFVcDaqZCkknP5KQWjCBgiLFxKxRxywNGTucm3jC3ozByZcbZv"], | ||
"serialize", "010000000220c24f763536edb05ce8df2a4816d971be4f20b58451d71589db434aca98bfaf00000000fc00473044022077fca9eb2544894068c47028855b0cf147526e9a54d993b7aa028908526944ea02203223ca379fa06b5544c02ed74b3ebb9734e2a9e09bca9b572aa56443a3be4d8d0147304402205caaf5666489ab005f280d30afbcda4d8f6f7195b0a13de89bc1e80f58219f5e02205414938c9d0496f5b45c1f45c028c019b3a956549938c09d983a3cc03e819f05014c695221020483ebb834d91d494a3b649cf0e8f5c9c4fcec5f194ab94341cc99bb440007f2210271ebaeef1c2bf0c1a4772d1391eab03e4d96a6e9b48551ab4e4b0d2983eb452b2103a659828aabe443e2dedabb1db5a22335c5ace5b5b7126998a288d63c99516dd853aeffffffffa0644cd1606e081c59eb65fe69d4a83a3a822da423bc392c91712fb77a192edc00000000fdfd0000483045022100c4c98f6cc0a313aee264ab8171927de590ab495b78f26159e56ba49fc26b1e3802206a12c4d41863756e35f72bd365d862da907272bcb2a949d1d2f64c1867d88ce90147304402207035e6083876dcd5512b40bb3d81e2b38393a62f962f8b701efc066db446ae500220121d38105bb58d8b8ad78bbef212c1f958124d47186bcc1ddcccfc0480eb7eb8014c695221020483ebb834d91d494a3b649cf0e8f5c9c4fcec5f194ab94341cc99bb440007f2210271ebaeef1c2bf0c1a4772d1391eab03e4d96a6e9b48551ab4e4b0d2983eb452b2103a659828aabe443e2dedabb1db5a22335c5ace5b5b7126998a288d63c99516dd853aeffffffff03f04902000000000017a9144de752833233fe69a20064f29b2ca0f6399c8af387007102000000000017a9144de752833233fe69a20064f29b2ca0f6399c8af3873b8f04000000000017a9146c8d8b04c6a1e664b1ec20ec932760760c97688e8700000000" | ||
"serialize", "010000000220c24f763536edb05ce8df2a4816d971be4f20b58451d71589db434aca98bfaf00000000fdfd0000473044022024b955f8bf6aaf0741da011e3214eaec7040cd12694303471cefc6ba0cc4ec290220124738015033a465636dec1524a6f956a229e69d31aef6c7a98b2a291f3cfc6701483045022100e6ae6c43240e8a11a6de2d034501c2a366c0ccdf069c7828de0791f05e68e787022028b80bd36c2b2ae63fe7afb491da6c0ce23fbbb982450962c817b20f0bb24075014c695221020483ebb834d91d494a3b649cf0e8f5c9c4fcec5f194ab94341cc99bb440007f2210271ebaeef1c2bf0c1a4772d1391eab03e4d96a6e9b48551ab4e4b0d2983eb452b2103a659828aabe443e2dedabb1db5a22335c5ace5b5b7126998a288d63c99516dd853aeffffffffa0644cd1606e081c59eb65fe69d4a83a3a822da423bc392c91712fb77a192edc00000000fc00483045022100ae7f136cf906dc37d34d5035b8d2001c6a783773b74507ba83080e73e903623f0220023baf7738395268f7097e5586130f682b911fd49b83b265f8fa481f2a6b1ee90146304302201d60f512a8b37663d85c123933053e0354f13d89daf699ca600defa03d4a1dab021f41042b6e4ba30311fc3a68c228c3725f3b0f05a4453ef19408e6a4ae30a2b0014c695221020483ebb834d91d494a3b649cf0e8f5c9c4fcec5f194ab94341cc99bb440007f2210271ebaeef1c2bf0c1a4772d1391eab03e4d96a6e9b48551ab4e4b0d2983eb452b2103a659828aabe443e2dedabb1db5a22335c5ace5b5b7126998a288d63c99516dd853aeffffffff03f04902000000000017a9144de752833233fe69a20064f29b2ca0f6399c8af387007102000000000017a9144de752833233fe69a20064f29b2ca0f6399c8af387ab2f03000000000017a9146c8d8b04c6a1e664b1ec20ec932760760c97688e8700000000" | ||
] | ||
] |
@@ -16,2 +16,3 @@ 'use strict'; | ||
var expect = require('chai').expect; | ||
var sinon = require('sinon'); | ||
var bitcore = require('..'); | ||
@@ -225,2 +226,107 @@ var Networks = bitcore.Networks; | ||
it('should use full 32 bytes for private key data that is hashed (as per bip32)', function() { | ||
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki | ||
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 | ||
}); | ||
var derived = key.deriveChild("m/44'/0'/0'/0/0'"); | ||
derived.privateKey.toString().should.equal('3348069561d2a0fb925e74bf198762acc47dce7db27372257d2d959a9e6f8aeb'); | ||
}); | ||
it('should NOT use full 32 bytes for private key data that is hashed with nonCompliant flag', 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 | ||
}); | ||
var derived = key.deriveNonCompliantChild("m/44'/0'/0'/0/0'"); | ||
derived.privateKey.toString().should.equal('4811a079bab267bfdca855b3bddff20231ff7044e648514fa099158472df2836'); | ||
}); | ||
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 | ||
}); | ||
var derived = key.derive("m/44'/0'/0'/0/0'"); | ||
derived.privateKey.toString().should.equal('4811a079bab267bfdca855b3bddff20231ff7044e648514fa099158472df2836'); | ||
}); | ||
describe('edge cases', function() { | ||
var sandbox = sinon.sandbox.create(); | ||
afterEach(function() { | ||
sandbox.restore(); | ||
}); | ||
it('will handle edge case that derived private key is invalid', function() { | ||
var invalid = new Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex'); | ||
var privateKeyBuffer = new Buffer('5f72914c48581fc7ddeb944a9616389200a9560177d24f458258e5b04527bcd1', 'hex'); | ||
var chainCodeBuffer = new Buffer('39816057bba9d952fe87fe998b7fd4d690a1bb58c2ff69141469e4d1dffb4b91', 'hex'); | ||
var unstubbed = bitcore.crypto.BN.prototype.toBuffer; | ||
var count = 0; | ||
var stub = sandbox.stub(bitcore.crypto.BN.prototype, 'toBuffer', function(args) { | ||
// On the fourth call to the function give back an invalid private key | ||
// otherwise use the normal behavior. | ||
count++; | ||
if (count === 4) { | ||
return invalid; | ||
} | ||
var ret = unstubbed.apply(this, arguments); | ||
return ret; | ||
}); | ||
sandbox.spy(bitcore.PrivateKey, 'isValid'); | ||
var key = HDPrivateKey.fromObject({ | ||
network: 'testnet', | ||
depth: 0, | ||
parentFingerPrint: 0, | ||
childIndex: 0, | ||
privateKey: privateKeyBuffer, | ||
chainCode: chainCodeBuffer | ||
}); | ||
var derived = key.derive("m/44'"); | ||
derived.privateKey.toString().should.equal('b15bce3608d607ee3a49069197732c656bca942ee59f3e29b4d56914c1de6825'); | ||
bitcore.PrivateKey.isValid.callCount.should.equal(2); | ||
}); | ||
it('will handle edge case that a derive public key is invalid', function() { | ||
var publicKeyBuffer = new Buffer('029e58b241790284ef56502667b15157b3fc58c567f044ddc35653860f9455d099', 'hex'); | ||
var chainCodeBuffer = new Buffer('39816057bba9d952fe87fe998b7fd4d690a1bb58c2ff69141469e4d1dffb4b91', 'hex'); | ||
var key = new HDPublicKey({ | ||
network: 'testnet', | ||
depth: 0, | ||
parentFingerPrint: 0, | ||
childIndex: 0, | ||
chainCode: chainCodeBuffer, | ||
publicKey: publicKeyBuffer | ||
}); | ||
var unstubbed = bitcore.PublicKey.fromPoint; | ||
bitcore.PublicKey.fromPoint = function() { | ||
bitcore.PublicKey.fromPoint = unstubbed; | ||
throw new Error('Point cannot be equal to Infinity'); | ||
}; | ||
sandbox.spy(key, '_deriveWithNumber'); | ||
var derived = key.derive("m/44"); | ||
key._deriveWithNumber.callCount.should.equal(2); | ||
key.publicKey.toString().should.equal('029e58b241790284ef56502667b15157b3fc58c567f044ddc35653860f9455d099'); | ||
}); | ||
}); | ||
describe('seed', function() { | ||
@@ -227,0 +333,0 @@ |
@@ -274,10 +274,3 @@ 'use strict'; | ||
}); | ||
it('should use the cache', function() { | ||
var pubkey = new HDPublicKey(xpubkey); | ||
var derived1 = pubkey.derive(0); | ||
var derived2 = pubkey.derive(0); | ||
derived1.should.equal(derived2); | ||
}); | ||
}); | ||
}); |
@@ -333,2 +333,25 @@ 'use strict'; | ||
}); | ||
it('will output a 31 byte buffer', function() { | ||
var bn = BN.fromBuffer(new Buffer('9b5a0e8fee1835e21170ce1431f9b6f19b487e67748ed70d8a4462bc031915', 'hex')); | ||
var privkey = new PrivateKey(bn); | ||
var buffer = privkey.toBufferNoPadding(); | ||
buffer.length.should.equal(31); | ||
}); | ||
// TODO: enable for v1.0.0 when toBuffer is changed to always be 32 bytes long | ||
// it('will output a 32 byte buffer', function() { | ||
// var bn = BN.fromBuffer(new Buffer('9b5a0e8fee1835e21170ce1431f9b6f19b487e67748ed70d8a4462bc031915', 'hex')); | ||
// var privkey = new PrivateKey(bn); | ||
// var buffer = privkey.toBuffer(); | ||
// buffer.length.should.equal(32); | ||
// }); | ||
// TODO: enable for v1.0.0 when toBuffer is changed to always be 32 bytes long | ||
// it('should return buffer with length equal 32', function() { | ||
// var bn = BN.fromBuffer(buf.slice(0, 31)); | ||
// var privkey = new PrivateKey(bn, 'livenet'); | ||
// var expected = Buffer.concat([ new Buffer([0]), buf.slice(0, 31) ]); | ||
// privkey.toBuffer().toString('hex').should.equal(expected.toString('hex')); | ||
// }); | ||
}); | ||
@@ -335,0 +358,0 @@ |
@@ -31,2 +31,8 @@ 'use strict'; | ||
it('should parse the version as a signed integer', function () { | ||
var transaction = Transaction('ffffffff0000ffffffff') | ||
transaction.version.should.equal(-1); | ||
transaction.nLockTime.should.equal(0xffffffff); | ||
}); | ||
it('fails if an invalid parameter is passed to constructor', function() { | ||
@@ -204,2 +210,10 @@ expect(function() { | ||
}; | ||
var simpleUtxoWith1000000Satoshis = { | ||
address: fromAddress, | ||
txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458', | ||
outputIndex: 0, | ||
script: Script.buildPublicKeyHashOut(fromAddress).toString(), | ||
satoshis: 1000000 | ||
}; | ||
var anyoneCanSpendUTXO = JSON.parse(JSON.stringify(simpleUtxoWith100000Satoshis)); | ||
@@ -223,2 +237,3 @@ anyoneCanSpendUTXO.script = new Script().add('OP_TRUE'); | ||
}; | ||
var tenth = 1e7; | ||
@@ -295,8 +310,8 @@ var fourth = 25e6; | ||
var transaction = new Transaction() | ||
.from(simpleUtxoWith100000Satoshis) | ||
.to(toAddress, 50000) | ||
.from(simpleUtxoWith1000000Satoshis) | ||
.to(toAddress, 500000) | ||
.change(changeAddress) | ||
.sign(privateKey); | ||
transaction.outputs.length.should.equal(2); | ||
transaction.outputs[1].satoshis.should.equal(40000); | ||
transaction.outputs[1].satoshis.should.equal(400000); | ||
transaction.outputs[1].script.toString() | ||
@@ -310,4 +325,4 @@ .should.equal(Script.fromAddress(changeAddress).toString()); | ||
var transaction = new Transaction() | ||
.from(simpleUtxoWith100000Satoshis) | ||
.to(toAddress, 50000) | ||
.from(simpleUtxoWith1000000Satoshis) | ||
.to(toAddress, 500000) | ||
.change(changeAddressP2SH) | ||
@@ -522,5 +537,5 @@ .sign(privateKey); | ||
transaction | ||
.to(toAddress, 90000000) | ||
.to(toAddress, 84000000) | ||
.change(changeAddress) | ||
.fee(10000000); | ||
.fee(16000000); | ||
@@ -928,3 +943,3 @@ expect(function() { | ||
transaction.inputAmount.should.equal(100000000); | ||
transaction.outputAmount.should.equal(99990000); | ||
transaction.outputAmount.should.equal(99900000); | ||
}); | ||
@@ -1021,3 +1036,3 @@ it('returns correct values for coinjoin transaction', function() { | ||
tx.outputs[0].script.toAddress().toString().should.equal(toAddress); | ||
tx.outputs[1].satoshis.should.equal(89990000); | ||
tx.outputs[1].satoshis.should.equal(89900000); | ||
tx.outputs[1].script.toAddress().toString().should.equal(changeAddress); | ||
@@ -1024,0 +1039,0 @@ }); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
2
97
5
1
3617190
142
73736