diff --git a/package.json b/package.json index f5cceb8..cf3db97 100644 --- a/package.json +++ b/package.json @@ -31,14 +31,12 @@ ], "dependencies": { "bech32": "^1.1.2", - "bigi": "^1.4.0", "bip32": "^0.1.0", "bip66": "^1.1.0", "bitcoin-ops": "^1.4.0", "bs58check": "^2.0.0", "create-hash": "^1.1.0", "create-hmac": "^1.1.3", - "ecurve": "^1.0.0", "merkle-lib": "^2.0.10", "pushdata-bitcoin": "^1.0.1", "randombytes": "^2.0.1", diff --git a/src/ecdsa.js b/src/ecdsa.js deleted file mode 100644 index 403ffd5..0000000 --- a/src/ecdsa.js +++ /dev/null @@ -1,163 +0,0 @@ -var Buffer = require('safe-buffer').Buffer -var createHmac = require('create-hmac') -var typeforce = require('typeforce') -var types = require('./types') - -var BigInteger = require('bigi') - -var ZERO = Buffer.alloc(1, 0) -var ONE = Buffer.alloc(1, 1) - -var ecurve = require('ecurve') -var secp256k1 = ecurve.getCurveByName('secp256k1') - -// https://tools.ietf.org/html/rfc6979#section-3.2 -function deterministicGenerateK (hash, x, checkSig) { - typeforce(types.tuple( - types.Hash256bit, - types.Buffer256bit, - types.Function - ), arguments) - - // Step A, ignored as hash already provided - // Step B - // Step C - var k = Buffer.alloc(32, 0) - var v = Buffer.alloc(32, 1) - - // Step D - k = createHmac('sha256', k) - .update(v) - .update(ZERO) - .update(x) - .update(hash) - .digest() - - // Step E - v = createHmac('sha256', k).update(v).digest() - - // Step F - k = createHmac('sha256', k) - .update(v) - .update(ONE) - .update(x) - .update(hash) - .digest() - - // Step G - v = createHmac('sha256', k).update(v).digest() - - // Step H1/H2a, ignored as tlen === qlen (256 bit) - // Step H2b - v = createHmac('sha256', k).update(v).digest() - - var T = BigInteger.fromBuffer(v) - - // Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA - while (T.signum() <= 0 || T.compareTo(secp256k1.n) >= 0 || !checkSig(T)) { - k = createHmac('sha256', k) - .update(v) - .update(ZERO) - .digest() - - v = createHmac('sha256', k).update(v).digest() - - // Step H1/H2a, again, ignored as tlen === qlen (256 bit) - // Step H2b again - v = createHmac('sha256', k).update(v).digest() - T = BigInteger.fromBuffer(v) - } - - return T -} - -var N_OVER_TWO = secp256k1.n.shiftRight(1) - -function sign (hash, d) { - typeforce(types.tuple(types.Hash256bit, types.BigInt), arguments) - - var x = d.toBuffer(32) - var e = BigInteger.fromBuffer(hash) - var n = secp256k1.n - var G = secp256k1.G - - var r, s - deterministicGenerateK(hash, x, function (k) { - var Q = G.multiply(k) - - if (secp256k1.isInfinity(Q)) return false - - r = Q.affineX.mod(n) - if (r.signum() === 0) return false - - s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n) - if (s.signum() === 0) return false - - return true - }) - - // enforce low S values, see bip62: 'low s values in signatures' - if (s.compareTo(N_OVER_TWO) > 0) { - s = n.subtract(s) - } - - return { - r: r, - s: s - } -} - -function verify (hash, signature, Q) { - typeforce(types.tuple( - types.Hash256bit, - types.ECSignature, - types.ECPoint - ), arguments) - - var n = secp256k1.n - var G = secp256k1.G - - var r = signature.r - var s = signature.s - - // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] - if (r.signum() <= 0 || r.compareTo(n) >= 0) return false - if (s.signum() <= 0 || s.compareTo(n) >= 0) return false - - // 1.4.2 H = Hash(M), already done by the user - // 1.4.3 e = H - var e = BigInteger.fromBuffer(hash) - - // Compute s^-1 - var sInv = s.modInverse(n) - - // 1.4.4 Compute u1 = es^−1 mod n - // u2 = rs^−1 mod n - var u1 = e.multiply(sInv).mod(n) - var u2 = r.multiply(sInv).mod(n) - - // 1.4.5 Compute R = (xR, yR) - // R = u1G + u2Q - var R = G.multiplyTwo(u1, Q, u2) - - // 1.4.5 (cont.) Enforce R is not at infinity - if (secp256k1.isInfinity(R)) return false - - // 1.4.6 Convert the field element R.x to an integer - var xR = R.affineX - - // 1.4.7 Set v = xR mod n - var v = xR.mod(n) - - // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" - return v.equals(r) -} - -module.exports = { - deterministicGenerateK: deterministicGenerateK, - sign: sign, - verify: verify, - - // TODO: remove - __curve: secp256k1 -} diff --git a/src/ecpair.js b/src/ecpair.js index b491f53..9467b1b 100644 --- a/src/ecpair.js +++ b/src/ecpair.js @@ -1,63 +1,73 @@ -let ecdsa = require('./ecdsa') +let ecc = require('tiny-secp256k1') let randomBytes = require('randombytes') let typeforce = require('typeforce') let types = require('./types') let wif = require('wif') let NETWORKS = require('./networks') -let BigInteger = require('bigi') -let ecurve = require('ecurve') -let secp256k1 = ecdsa.__curve +// TODO: why is the function name toJSON weird? +function isPoint (x) { return ecc.isPoint(x) } +let isOptions = typeforce.maybe(typeforce.compile({ + compressed: types.maybe(types.Boolean), + network: types.maybe(types.Network) +})) function ECPair (d, Q, options) { - if (options) { - typeforce({ - compressed: types.maybe(types.Boolean), - network: types.maybe(types.Network) - }, options) - } - options = options || {} - if (d) { - if (d.signum() <= 0) throw new Error('Private key must be greater than 0') - if (d.compareTo(secp256k1.n) >= 0) throw new Error('Private key must be less than the curve order') - if (Q) throw new TypeError('Unexpected publicKey parameter') - - this.d = d - } else { - typeforce(types.ECPoint, Q) - - this.__Q = Q - } - this.compressed = options.compressed === undefined ? true : options.compressed this.network = options.network || NETWORKS.bitcoin + + this.__d = d || null + this.__Q = null + if (Q) this.__Q = ecc.pointCompress(Q, this.compressed) } -Object.defineProperty(ECPair.prototype, 'Q', { - get: function () { - if (!this.__Q && this.d) { - this.__Q = secp256k1.G.multiply(this.d) - } - - return this.__Q - } -}) - -ECPair.fromPublicKeyBuffer = function (buffer, network) { - var Q = ecurve.Point.decodeFrom(secp256k1, buffer) - - return new ECPair(null, Q, { - compressed: Q.compressed, - network: network - }) +ECPair.prototype.getNetwork = function () { + return this.network } -ECPair.fromWIF = function (string, network) { - var decoded = wif.decode(string) - var version = decoded.version +ECPair.prototype.getPrivateKey = function () { + return this.__d +} + +ECPair.prototype.getPublicKey = function () { + if (!this.__Q) this.__Q = ecc.pointFromScalar(this.__d, this.compressed) + return this.__Q +} + +ECPair.prototype.toWIF = function () { + if (!this.__d) throw new Error('Missing private key') + return wif.encode(this.network.wif, this.__d, this.compressed) +} + +ECPair.prototype.sign = function (hash) { + if (!this.__d) throw new Error('Missing private key') + return ecc.sign(hash, this.__d) +} + +ECPair.prototype.verify = function (hash, signature) { + return ecc.verify(hash, this.getPublicKey(), signature) +} + +function fromPrivateKey (buffer, options) { + typeforce(types.Buffer256bit, buffer) + if (!ecc.isPrivate(buffer)) throw new TypeError('Private key not in range [1, n)') + typeforce(isOptions, options) + + return new ECPair(buffer, null, options) +} + +function fromPublicKey (buffer, options) { + typeforce(isPoint, buffer) + typeforce(isOptions, options) + return new ECPair(null, buffer, options) +} + +function fromWIF (string, network) { + let decoded = wif.decode(string) + let version = decoded.version // list of networks? if (types.Array(network)) { @@ -74,58 +84,29 @@ ECPair.fromWIF = function (string, network) { if (version !== network.wif) throw new Error('Invalid network version') } - var d = BigInteger.fromBuffer(decoded.privateKey) - - return new ECPair(d, null, { + return fromPrivateKey(decoded.privateKey, { compressed: decoded.compressed, network: network }) } -ECPair.makeRandom = function (options) { +function makeRandom (options) { + typeforce(isOptions, options) options = options || {} + let rng = options.rng || randomBytes - var rng = options.rng || randomBytes - - var d + let d do { - var buffer = rng(32) - typeforce(types.Buffer256bit, buffer) + d = rng(32) + typeforce(types.Buffer256bit, d) + } while (!ecc.isPrivate(d)) - d = BigInteger.fromBuffer(buffer) - } while (d.signum() <= 0 || d.compareTo(secp256k1.n) >= 0) - - return new ECPair(d, null, options) + return fromPrivateKey(d, options) } -ECPair.prototype.getNetwork = function () { - return this.network +module.exports = { + makeRandom, + fromPrivateKey, + fromPublicKey, + fromWIF } - -ECPair.prototype.getPublicKeyBuffer = function () { - return this.Q.getEncoded(this.compressed) -} - -ECPair.prototype.sign = function (hash) { - if (!this.d) throw new Error('Missing private key') - - let signature = ecdsa.sign(hash, this.d) - return Buffer.concat([signature.r.toBuffer(32), signature.s.toBuffer(32)], 64) -} - -ECPair.prototype.toWIF = function () { - if (!this.d) throw new Error('Missing private key') - - return wif.encode(this.network.wif, this.d.toBuffer(32), this.compressed) -} - -ECPair.prototype.verify = function (hash, signature) { - signature = { - r: BigInteger.fromBuffer(signature.slice(0, 32)), - s: BigInteger.fromBuffer(signature.slice(32, 64)) - } - - return ecdsa.verify(hash, signature, this.Q) -} - -module.exports = ECPair diff --git a/src/transaction_builder.js b/src/transaction_builder.js index 3a1310b..4f731dc 100644 --- a/src/transaction_builder.js +++ b/src/transaction_builder.js @@ -180,7 +180,7 @@ function fixMultisigOrder (input, transaction, vin) { var unmatched = input.signatures.concat() input.signatures = input.pubKeys.map(function (pubKey) { - var keyPair = ECPair.fromPublicKeyBuffer(pubKey) + var keyPair = ECPair.fromPublicKey(pubKey) var match // check for a signature @@ -686,7 +686,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy throw new Error('Inconsistent redeemScript') } - var kpPubKey = keyPair.publicKey || keyPair.getPublicKeyBuffer() + var kpPubKey = keyPair.publicKey || keyPair.getPublicKey() if (!canSign(input)) { if (witnessValue !== undefined) { if (input.value !== undefined && input.value !== witnessValue) throw new Error('Input didn\'t match witnessValue') diff --git a/src/types.js b/src/types.js index c1e5fb1..302043f 100644 --- a/src/types.js +++ b/src/types.js @@ -16,11 +16,9 @@ function Satoshi (value) { } // external dependent types -var BigInt = typeforce.quacksLike('BigInteger') var ECPoint = typeforce.quacksLike('Point') // exposed, external API -var ECSignature = typeforce.compile({ r: BigInt, s: BigInt }) var Network = typeforce.compile({ messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String), bip32: { @@ -34,11 +32,9 @@ var Network = typeforce.compile({ // extend typeforce types with ours var types = { - BigInt: BigInt, BIP32Path: BIP32Path, Buffer256bit: typeforce.BufferN(32), ECPoint: ECPoint, - ECSignature: ECSignature, Hash160bit: typeforce.BufferN(20), Hash256bit: typeforce.BufferN(32), Network: Network, diff --git a/test/bitcoin.core.js b/test/bitcoin.core.js index b042ae1..4bf6785 100644 --- a/test/bitcoin.core.js +++ b/test/bitcoin.core.js @@ -94,7 +94,7 @@ describe('Bitcoin-core', function () { var keyPair = bitcoin.ECPair.fromWIF(string, network) it('fromWIF imports ' + string, function () { - assert.strictEqual(keyPair.d.toHex(), hex) + assert.strictEqual(keyPair.getPrivateKey().toString('hex'), hex) assert.strictEqual(keyPair.compressed, params.isCompressed) }) diff --git a/test/ecdsa.js b/test/ecdsa.js deleted file mode 100644 index 1f20a41..0000000 --- a/test/ecdsa.js +++ /dev/null @@ -1,135 +0,0 @@ -/* global describe, it */ - -var assert = require('assert') -var bcrypto = require('../src/crypto') -var ecdsa = require('../src/ecdsa') -var hoodwink = require('hoodwink') - -var BigInteger = require('bigi') - -var curve = ecdsa.__curve - -var fixtures = require('./fixtures/ecdsa.json') - -describe('ecdsa', function () { - function fromRaw (signature) { - return { - r: new BigInteger(signature.r, 16), - s: new BigInteger(signature.s, 16) - } - } - - function toRaw (signature) { - return { - r: signature.r.toHex(), - s: signature.s.toHex() - } - } - - describe('deterministicGenerateK', function () { - function checkSig () { - return true - } - - fixtures.valid.ecdsa.forEach(function (f) { - it('for "' + f.message + '"', function () { - var x = BigInteger.fromHex(f.d).toBuffer(32) - var h1 = bcrypto.sha256(f.message) - - var k = ecdsa.deterministicGenerateK(h1, x, checkSig) - assert.strictEqual(k.toHex(), f.k) - }) - }) - - it('loops until an appropriate k value is found', hoodwink(function () { - this.mock(BigInteger, 'fromBuffer', function f (b) { - assert.strictEqual(b.length, 32) - if (f.calls === 0) return BigInteger.ZERO // < 1 - if (f.calls === 1) return curve.n // > n - 1 - if (f.calls === 2) return new BigInteger('42') // valid - }, 3) - - var x = new BigInteger('1').toBuffer(32) - var h1 = Buffer.alloc(32) - var k = ecdsa.deterministicGenerateK(h1, x, checkSig) - - assert.strictEqual(k.toString(), '42') - })) - - it('loops until a suitable signature is found', hoodwink(function () { - var checkSigStub = this.stub(function f () { - if (f.calls === 0) return false // bad signature - if (f.calls === 1) return true // good signature - }, 2) - - var x = BigInteger.ONE.toBuffer(32) - var h1 = Buffer.alloc(32) - var k = ecdsa.deterministicGenerateK(h1, x, checkSigStub) - - assert.strictEqual(k.toHex(), 'a9b1a1a84a4c2f96b6158ed7a81404c50cb74373c22e8d9e02d0411d719acae2') - })) - - fixtures.valid.rfc6979.forEach(function (f) { - it('produces the expected k values for ' + f.message + " if k wasn't suitable", function () { - var x = BigInteger.fromHex(f.d).toBuffer(32) - var h1 = bcrypto.sha256(f.message) - - var results = [] - ecdsa.deterministicGenerateK(h1, x, function (k) { - results.push(k) - - return results.length === 16 - }) - - assert.strictEqual(results[0].toHex(), f.k0) - assert.strictEqual(results[1].toHex(), f.k1) - assert.strictEqual(results[15].toHex(), f.k15) - }) - }) - }) - - describe('sign', function () { - fixtures.valid.ecdsa.forEach(function (f) { - it('produces a deterministic signature for "' + f.message + '"', function () { - var d = BigInteger.fromHex(f.d) - var hash = bcrypto.sha256(f.message) - var signature = ecdsa.sign(hash, d) - - assert.deepEqual(toRaw(signature), f.signature) - }) - }) - - it('should sign with low S value', function () { - var hash = bcrypto.sha256('Vires in numeris') - var sig = ecdsa.sign(hash, BigInteger.ONE) - - // See BIP62 for more information - var N_OVER_TWO = curve.n.shiftRight(1) - assert(sig.s.compareTo(N_OVER_TWO) <= 0) - }) - }) - - describe('verify', function () { - fixtures.valid.ecdsa.forEach(function (f) { - it('verifies a valid signature for "' + f.message + '"', function () { - var d = BigInteger.fromHex(f.d) - var H = bcrypto.sha256(f.message) - var signature = fromRaw(f.signature) - var Q = curve.G.multiply(d) - - assert(ecdsa.verify(H, signature, Q)) - }) - }) - - fixtures.invalid.verify.forEach(function (f) { - it('fails to verify with ' + f.description, function () { - var H = bcrypto.sha256(f.message) - var d = BigInteger.fromHex(f.d) - var signature = fromRaw(f.signature) - var Q = curve.G.multiply(d) - - assert.strictEqual(ecdsa.verify(H, signature, Q), false) - }) - }) - }) -}) diff --git a/test/ecpair.js b/test/ecpair.js index 52e5499..89deae2 100644 --- a/test/ecpair.js +++ b/test/ecpair.js @@ -1,34 +1,36 @@ /* global describe, it, beforeEach */ /* eslint-disable no-new */ -var assert = require('assert') -var ecdsa = require('../src/ecdsa') -var ecurve = require('ecurve') -var proxyquire = require('proxyquire') -var hoodwink = require('hoodwink') +let assert = require('assert') +let proxyquire = require('proxyquire') +let hoodwink = require('hoodwink') -var BigInteger = require('bigi') -var ECPair = require('../src/ecpair') +let ECPair = require('../src/ecpair') +let tinysecp = require('tiny-secp256k1') -var fixtures = require('./fixtures/ecpair.json') -var curve = ecdsa.__curve +let fixtures = require('./fixtures/ecpair.json') -var NETWORKS = require('../src/networks') -var NETWORKS_LIST = [] // Object.values(NETWORKS) -for (var networkName in NETWORKS) { +let NETWORKS = require('../src/networks') +let NETWORKS_LIST = [] // Object.values(NETWORKS) +for (let networkName in NETWORKS) { NETWORKS_LIST.push(NETWORKS[networkName]) } +let ZERO = Buffer.alloc(32, 0) +let ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex') +let GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex') +let GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex') + describe('ECPair', function () { describe('constructor', function () { it('defaults to compressed', function () { - var keyPair = new ECPair(BigInteger.ONE) + let keyPair = ECPair.fromPrivateKey(ONE) assert.strictEqual(keyPair.compressed, true) }) it('supports the uncompressed option', function () { - var keyPair = new ECPair(BigInteger.ONE, null, { + let keyPair = ECPair.fromPrivateKey(ONE, { compressed: false }) @@ -36,7 +38,7 @@ describe('ECPair', function () { }) it('supports the network option', function () { - var keyPair = new ECPair(BigInteger.ONE, null, { + let keyPair = ECPair.fromPrivateKey(ONE, { compressed: false, network: NETWORKS.testnet }) @@ -45,51 +47,56 @@ describe('ECPair', function () { }) fixtures.valid.forEach(function (f) { - it('calculates the public point for ' + f.WIF, function () { - var d = new BigInteger(f.d) - var keyPair = new ECPair(d, null, { + it('derives public key for ' + f.WIF, function () { + let d = Buffer.from(f.d, 'hex') + console.log(d) + + let keyPair = ECPair.fromPrivateKey(d, { compressed: f.compressed }) - assert.strictEqual(keyPair.getPublicKeyBuffer().toString('hex'), f.Q) + assert.strictEqual(keyPair.getPublicKey().toString('hex'), f.Q) }) }) fixtures.invalid.constructor.forEach(function (f) { it('throws ' + f.exception, function () { - var d = f.d && new BigInteger(f.d) - var Q = f.Q && ecurve.Point.decodeFrom(curve, Buffer.from(f.Q, 'hex')) - - assert.throws(function () { - new ECPair(d, Q, f.options) - }, new RegExp(f.exception)) + if (f.d) { + let d = Buffer.from(f.d, 'hex') + assert.throws(function () { + ECPair.fromPrivateKey(d, f.options) + }, new RegExp(f.exception)) + } else { + let Q = Buffer.from(f.Q, 'hex') + assert.throws(function () { + ECPair.fromPublicKey(Q, f.options) + }, new RegExp(f.exception)) + } }) }) }) - describe('getPublicKeyBuffer', function () { - var keyPair + describe('getPublicKey', function () { + let keyPair beforeEach(function () { - keyPair = new ECPair(BigInteger.ONE) + keyPair = ECPair.fromPrivateKey(ONE) }) - it('wraps Q.getEncoded', hoodwink(function () { - this.mock(keyPair.Q, 'getEncoded', function (compressed) { - assert.strictEqual(compressed, keyPair.compressed) - }, 1) - - keyPair.getPublicKeyBuffer() + it('calls pointFromScalar lazily', hoodwink(function () { + assert.strictEqual(keyPair.__Q, null) + keyPair.getPublicKey() + assert.strictEqual(keyPair.__Q.toString('hex'), '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798') })) }) describe('fromWIF', function () { fixtures.valid.forEach(function (f) { it('imports ' + f.WIF + ' (' + f.network + ')', function () { - var network = NETWORKS[f.network] - var keyPair = ECPair.fromWIF(f.WIF, network) + let network = NETWORKS[f.network] + let keyPair = ECPair.fromWIF(f.WIF, network) - assert.strictEqual(keyPair.d.toString(), f.d) + assert.strictEqual(keyPair.getPrivateKey().toString('hex'), f.d) assert.strictEqual(keyPair.compressed, f.compressed) assert.strictEqual(keyPair.network, network) }) @@ -97,9 +104,9 @@ describe('ECPair', function () { fixtures.valid.forEach(function (f) { it('imports ' + f.WIF + ' (via list of networks)', function () { - var keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) + let keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) - assert.strictEqual(keyPair.d.toString(), f.d) + assert.strictEqual(keyPair.getPrivateKey().toString('hex'), f.d) assert.strictEqual(keyPair.compressed, f.compressed) assert.strictEqual(keyPair.network, NETWORKS[f.network]) }) @@ -108,7 +115,7 @@ describe('ECPair', function () { fixtures.invalid.fromWIF.forEach(function (f) { it('throws on ' + f.WIF, function () { assert.throws(function () { - var networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST + let networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST ECPair.fromWIF(f.WIF, networks) }, new RegExp(f.exception)) @@ -119,30 +126,29 @@ describe('ECPair', function () { describe('toWIF', function () { fixtures.valid.forEach(function (f) { it('exports ' + f.WIF, function () { - var keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) - var result = keyPair.toWIF() - + let keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) + let result = keyPair.toWIF() assert.strictEqual(result, f.WIF) }) }) }) describe('makeRandom', function () { - var d = Buffer.from('0404040404040404040404040404040404040404040404040404040404040404', 'hex') - var exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv' + let d = Buffer.alloc(32, 4) + let exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv' describe('uses randombytes RNG', function () { it('generates a ECPair', function () { - var stub = { randombytes: function () { return d } } - var ProxiedECPair = proxyquire('../src/ecpair', stub) + let stub = { randombytes: function () { return d } } + let ProxiedECPair = proxyquire('../src/ecpair', stub) - var keyPair = ProxiedECPair.makeRandom() + let keyPair = ProxiedECPair.makeRandom() assert.strictEqual(keyPair.toWIF(), exWIF) }) }) it('allows a custom RNG to be used', function () { - var keyPair = ECPair.makeRandom({ + let keyPair = ECPair.makeRandom({ rng: function (size) { return d.slice(0, size) } }) @@ -150,14 +156,14 @@ describe('ECPair', function () { }) it('retains the same defaults as ECPair constructor', function () { - var keyPair = ECPair.makeRandom() + let keyPair = ECPair.makeRandom() assert.strictEqual(keyPair.compressed, true) assert.strictEqual(keyPair.network, NETWORKS.bitcoin) }) it('supports the options parameter', function () { - var keyPair = ECPair.makeRandom({ + let keyPair = ECPair.makeRandom({ compressed: false, network: NETWORKS.testnet }) @@ -168,7 +174,7 @@ describe('ECPair', function () { it('throws if d is bad length', function () { function rng () { - return BigInteger.ZERO.toBuffer(28) + return Buffer.alloc(28) } assert.throws(function () { @@ -176,20 +182,20 @@ describe('ECPair', function () { }, /Expected Buffer\(Length: 32\), got Buffer\(Length: 28\)/) }) - it('loops until d is within interval [1, n - 1] : 1', hoodwink(function () { - var rng = this.stub(function f () { - if (f.calls === 0) return BigInteger.ZERO.toBuffer(32) // 0 - return BigInteger.ONE.toBuffer(32) // >0 + it('loops until d is within interval [1, n) : 1', hoodwink(function () { + let rng = this.stub(function f () { + if (f.calls === 0) return ZERO // 0 + return ONE // >0 }, 2) ECPair.makeRandom({ rng: rng }) })) - it('loops until d is within interval [1, n - 1] : n - 1', hoodwink(function () { - var rng = this.stub(function f () { - if (f.calls === 0) return BigInteger.ZERO.toBuffer(32) // <1 - if (f.calls === 1) return curve.n.toBuffer(32) // >n-1 - return curve.n.subtract(BigInteger.ONE).toBuffer(32) // n-1 + it('loops until d is within interval [1, n) : n - 1', hoodwink(function () { + let rng = this.stub(function f () { + if (f.calls === 0) return ZERO // <1 + if (f.calls === 1) return GROUP_ORDER // >n-1 + return GROUP_ORDER_LESS_1 // n-1 }, 3) ECPair.makeRandom({ rng: rng }) @@ -199,35 +205,36 @@ describe('ECPair', function () { describe('getNetwork', function () { fixtures.valid.forEach(function (f) { it('returns ' + f.network + ' for ' + f.WIF, function () { - var network = NETWORKS[f.network] - var keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) + let network = NETWORKS[f.network] + let keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) assert.strictEqual(keyPair.getNetwork(), network) }) }) }) - describe('ecdsa wrappers', function () { - var keyPair, hash + describe('tinysecp wrappers', function () { + let keyPair, hash, signature beforeEach(function () { keyPair = ECPair.makeRandom() - hash = Buffer.alloc(32) + hash = ZERO + signature = Buffer.alloc(64, 1) }) describe('signing', function () { - it('wraps ecdsa.sign', hoodwink(function () { - this.mock(ecdsa, 'sign', function (h, d) { + it('wraps tinysecp.sign', hoodwink(function () { + this.mock(tinysecp, 'sign', function (h, d) { assert.strictEqual(h, hash) - assert.strictEqual(d, keyPair.d) - return { r: BigInteger.ONE, s: BigInteger.ONE } + assert.strictEqual(d, keyPair.getPrivateKey()) + return signature }, 1) - keyPair.sign(hash) + assert.strictEqual(keyPair.sign(hash), signature) })) it('throws if no private key is found', function () { - keyPair.d = null + delete keyPair.__d assert.throws(function () { keyPair.sign(hash) @@ -236,24 +243,15 @@ describe('ECPair', function () { }) describe('verify', function () { - var signature - - beforeEach(function () { - signature = keyPair.sign(hash) - }) - - it('wraps ecdsa.verify', hoodwink(function () { - this.mock(ecdsa, 'verify', function (h, s, q) { + it('wraps tinysecp.verify', hoodwink(function () { + this.mock(tinysecp, 'verify', function (h, q, s) { assert.strictEqual(h, hash) - // assert.strictEqual(s, signature) - assert.deepEqual(s, { - r: BigInteger.fromBuffer(signature.slice(0, 32)), - s: BigInteger.fromBuffer(signature.slice(32, 64)) - }) - assert.strictEqual(q, keyPair.Q) + assert.strictEqual(q, keyPair.getPublicKey()) + assert.strictEqual(s, signature) + return true }, 1) - keyPair.verify(hash, signature) + assert.strictEqual(keyPair.verify(hash, signature), true) })) }) }) diff --git a/test/fixtures/ecpair.json b/test/fixtures/ecpair.json index 6f0a1a2..77eee08 100644 --- a/test/fixtures/ecpair.json +++ b/test/fixtures/ecpair.json @@ -1,7 +1,7 @@ { "valid": [ { - "d": "1", + "d": "0000000000000000000000000000000000000000000000000000000000000001", "Q": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "compressed": true, "network": "bitcoin", @@ -9,7 +9,7 @@ "WIF": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn" }, { - "d": "1", + "d": "0000000000000000000000000000000000000000000000000000000000000001", "Q": "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", "compressed": false, "network": "bitcoin", @@ -17,7 +17,7 @@ "WIF": "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf" }, { - "d": "19898843618908353587043383062236220484949425084007183071220218307100305431102", + "d": "2bfe58ab6d9fd575bdc3a624e4825dd2b375d64ac033fbc46ea79dbab4f69a3e", "Q": "02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340", "compressed": true, "network": "bitcoin", @@ -25,7 +25,7 @@ "WIF": "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9o" }, { - "d": "48968302285117906840285529799176770990048954789747953886390402978935544927851", + "d": "6c4313b03f2e7324d75e642f0ab81b734b724e13fec930f309e222470236d66b", "Q": "024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34", "compressed": true, "network": "bitcoin", @@ -33,7 +33,7 @@ "WIF": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx" }, { - "d": "48968302285117906840285529799176770990048954789747953886390402978935544927851", + "d": "6c4313b03f2e7324d75e642f0ab81b734b724e13fec930f309e222470236d66b", "Q": "044289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34cec320a0565fb7caf11b1ca2f445f9b7b012dda5718b3cface369ee3a034ded6", "compressed": false, "network": "bitcoin", @@ -41,7 +41,7 @@ "WIF": "5JdxzLtFPHNe7CAL8EBC6krdFv9pwPoRo4e3syMZEQT9srmK8hh" }, { - "d": "48968302285117906840285529799176770990048954789747953886390402978935544927851", + "d": "6c4313b03f2e7324d75e642f0ab81b734b724e13fec930f309e222470236d66b", "Q": "024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34", "compressed": true, "network": "testnet", @@ -49,7 +49,7 @@ "WIF": "cRD9b1m3vQxmwmjSoJy7Mj56f4uNFXjcWMCzpQCEmHASS4edEwXv" }, { - "d": "48968302285117906840285529799176770990048954789747953886390402978935544927851", + "d": "6c4313b03f2e7324d75e642f0ab81b734b724e13fec930f309e222470236d66b", "Q": "044289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34cec320a0565fb7caf11b1ca2f445f9b7b012dda5718b3cface369ee3a034ded6", "compressed": false, "network": "testnet", @@ -57,7 +57,7 @@ "WIF": "92Qba5hnyWSn5Ffcka56yMQauaWY6ZLd91Vzxbi4a9CCetaHtYj" }, { - "d": "115792089237316195423570985008687907852837564279074904382605163141518161494336", + "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "Q": "0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "compressed": true, "network": "bitcoin", @@ -68,36 +68,27 @@ "invalid": { "constructor": [ { - "exception": "Private key must be greater than 0", - "d": "-1" + "exception": "Private key not in range \\[1, n\\)", + "d": "0000000000000000000000000000000000000000000000000000000000000000" }, { - "exception": "Private key must be greater than 0", - "d": "0" + "exception": "Private key not in range \\[1, n\\)", + "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" }, { - "exception": "Private key must be less than the curve order", - "d": "115792089237316195423570985008687907852837564279074904382605163141518161494337" - }, - { - "exception": "Private key must be less than the curve order", - "d": "115792089237316195423570985008687907853269984665640564039457584007913129639935" + "exception": "Private key not in range \\[1, n\\)", + "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142" }, { "exception": "Expected property \"compressed\" of type \\?Boolean, got Number 2", - "d": "1", + "d": "0000000000000000000000000000000000000000000000000000000000000001", "options": { "compressed": 2 } }, - { - "exception": "Unexpected publicKey parameter", - "d": "1", - "Q": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" - }, { "exception": "Expected property \"network.messagePrefix\" of type Buffer|String, got undefined", - "d": "1", + "d": "0000000000000000000000000000000000000000000000000000000000000001", "options": { "network": {} } diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js index 0baaffa..46a0393 100644 --- a/test/integration/_regtest.js +++ b/test/integration/_regtest.js @@ -72,7 +72,7 @@ let baddress = bitcoin.address let bcrypto = bitcoin.crypto function getAddress (node, network) { network = network || bitcoin.networks.bitcoin - return baddress.toBase58Check(bcrypto.hash160(node.getPublicKeyBuffer()), network.pubKeyHash) + return baddress.toBase58Check(bcrypto.hash160(node.getPublicKey()), network.pubKeyHash) } function randomAddress () { diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 0f8ae52..5cd6a46 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -12,7 +12,7 @@ let baddress = bitcoin.address let bcrypto = bitcoin.crypto function getAddress (node, network) { network = network || bitcoin.networks.bitcoin - return baddress.toBase58Check(bcrypto.hash160(node.getPublicKeyBuffer()), network.pubKeyHash) + return baddress.toBase58Check(bcrypto.hash160(node.getPublicKey()), network.pubKeyHash) } describe('bitcoinjs-lib (addresses)', function () { @@ -26,7 +26,7 @@ describe('bitcoinjs-lib (addresses)', function () { it('can generate an address from a SHA256 hash', function () { var hash = bitcoin.crypto.sha256(Buffer.from('correct horse battery staple')) - var keyPair = bitcoin.ECPair.makeRandom({ rng: () => hash }) + var keyPair = bitcoin.ECPair.fromPrivateKey(hash) var address = getAddress(keyPair) // Generating addresses from SHA256 hashes is not secure if the input to the hash function is predictable @@ -57,7 +57,7 @@ describe('bitcoinjs-lib (addresses)', function () { it('can generate a SegWit address', function () { var keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') - var pubKey = keyPair.getPublicKeyBuffer() + var pubKey = keyPair.getPublicKey() var scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey)) var address = bitcoin.address.fromOutputScript(scriptPubKey) @@ -67,7 +67,7 @@ describe('bitcoinjs-lib (addresses)', function () { it('can generate a SegWit address (via P2SH)', function () { var keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') - var pubKey = keyPair.getPublicKeyBuffer() + var pubKey = keyPair.getPublicKey() var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey)) var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript)) diff --git a/test/integration/cltv.js b/test/integration/cltv.js index 2b51ed7..52b9f00 100644 --- a/test/integration/cltv.js +++ b/test/integration/cltv.js @@ -25,11 +25,11 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () { bitcoin.opcodes.OP_DROP, bitcoin.opcodes.OP_ELSE, - bQ.getPublicKeyBuffer(), + bQ.getPublicKey(), bitcoin.opcodes.OP_CHECKSIGVERIFY, bitcoin.opcodes.OP_ENDIF, - aQ.getPublicKeyBuffer(), + aQ.getPublicKey(), bitcoin.opcodes.OP_CHECKSIG ]) } diff --git a/test/integration/crypto.js b/test/integration/crypto.js index 8566628..58ae431 100644 --- a/test/integration/crypto.js +++ b/test/integration/crypto.js @@ -24,7 +24,7 @@ describe('bitcoinjs-lib (crypto)', function () { assert(bitcoin.script.pubKeyHash.input.check(scriptChunks), 'Expected pubKeyHash script') var prevOutScript = bitcoin.address.toOutputScript('1ArJ9vRaQcoQ29mTWZH768AmRwzb6Zif1z') var scriptSignature = bitcoin.script.signature.decode(scriptChunks[0]) - var publicKey = bitcoin.ECPair.fromPublicKeyBuffer(scriptChunks[1]) + var publicKey = bitcoin.ECPair.fromPublicKey(scriptChunks[1]) var m = tx.hashForSignature(vin, prevOutScript, scriptSignature.hashType) assert(publicKey.verify(m, scriptSignature.signature), 'Invalid m') diff --git a/test/integration/csv.js b/test/integration/csv.js index ef9c30f..6aa3087 100644 --- a/test/integration/csv.js +++ b/test/integration/csv.js @@ -26,11 +26,11 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () { bitcoin.opcodes.OP_DROP, bitcoin.opcodes.OP_ELSE, - bQ.getPublicKeyBuffer(), + bQ.getPublicKey(), bitcoin.opcodes.OP_CHECKSIGVERIFY, bitcoin.opcodes.OP_ENDIF, - aQ.getPublicKeyBuffer(), + aQ.getPublicKey(), bitcoin.opcodes.OP_CHECKSIG ]) } diff --git a/test/integration/stealth.js b/test/integration/stealth.js index b3cea41..91508e2 100644 --- a/test/integration/stealth.js +++ b/test/integration/stealth.js @@ -1,74 +1,72 @@ /* global describe, it */ let assert = require('assert') -let bigi = require('bigi') let bitcoin = require('../../') - -let ecurve = require('ecurve') -let secp256k1 = ecurve.getCurveByName('secp256k1') -let G = secp256k1.G -let n = secp256k1.n +let ecc = require('tiny-secp256k1') // TODO: remove let baddress = bitcoin.address let bcrypto = bitcoin.crypto function getAddress (node) { - return baddress.toBase58Check(bcrypto.hash160(node.getPublicKeyBuffer()), bitcoin.networks.bitcoin.pubKeyHash) + return baddress.toBase58Check(bcrypto.hash160(node.getPublicKey()), bitcoin.networks.bitcoin.pubKeyHash) } // vG = (dG \+ sha256(e * dG)G) function stealthSend (e, Q) { - var eQ = Q.multiply(e) // shared secret - var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded())) - var cG = G.multiply(c) - var vG = new bitcoin.ECPair(null, Q.add(cG)) + var eQ = ecc.pointMultiply(Q, e, true) // shared secret + var c = bitcoin.crypto.sha256(eQ) + var Qc = ecc.pointAddScalar(Q, c) + var vG = bitcoin.ECPair.fromPublicKey(Qc) return vG } // v = (d + sha256(eG * d)) function stealthReceive (d, eG) { - var eQ = eG.multiply(d) // shared secret - var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded())) - var v = new bitcoin.ECPair(d.add(c).mod(n)) + var eQ = ecc.pointMultiply(eG, d) // shared secret + var c = bitcoin.crypto.sha256(eQ) + var dc = ecc.privateAdd(d, c) + var v = bitcoin.ECPair.fromPrivateKey(dc) return v } // d = (v - sha256(e * dG)) function stealthRecoverLeaked (v, e, Q) { - var eQ = Q.multiply(e) // shared secret - var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded())) - var d = new bitcoin.ECPair(v.subtract(c).mod(n)) + var eQ = ecc.pointMultiply(Q, e) // shared secret + var c = bitcoin.crypto.sha256(eQ) + var vc = ecc.privateSub(v, c) + var d = bitcoin.ECPair.fromPrivateKey(vc) return d } // vG = (rG \+ sha256(e * dG)G) function stealthDualSend (e, R, Q) { - var eQ = Q.multiply(e) // shared secret - var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded())) - var cG = G.multiply(c) - var vG = new bitcoin.ECPair(null, R.add(cG)) + var eQ = ecc.pointMultiply(Q, e) // shared secret + var c = bitcoin.crypto.sha256(eQ) + var Rc = ecc.pointAddScalar(R, c) + var vG = bitcoin.ECPair.fromPublicKey(Rc) return vG } // vG = (rG \+ sha256(eG * d)G) function stealthDualScan (d, R, eG) { - var eQ = eG.multiply(d) // shared secret - var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded())) - var cG = G.multiply(c) - var vG = new bitcoin.ECPair(null, R.add(cG)) + var eQ = ecc.pointMultiply(eG, d) // shared secret + var c = bitcoin.crypto.sha256(eQ) + var Rc = ecc.pointAddScalar(R, c) + var vG = bitcoin.ECPair.fromPublicKey(Rc) return vG } // v = (r + sha256(eG * d)) function stealthDualReceive (d, r, eG) { - var eQ = eG.multiply(d) // shared secret - var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded())) - var v = new bitcoin.ECPair(r.add(c).mod(n)) + var eQ = ecc.pointMultiply(eG, d) // shared secret + var c = bitcoin.crypto.sha256(eQ) + var rc = ecc.privateAdd(r, c) + var v = bitcoin.ECPair.fromPrivateKey(rc) return v } @@ -80,12 +78,12 @@ describe('bitcoinjs-lib (crypto)', function () { var nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender // ... recipient reveals public key (recipient.Q) to sender - var forSender = stealthSend(nonce.d, recipient.Q) + var forSender = stealthSend(nonce.getPrivateKey(), recipient.getPublicKey()) assert.equal(getAddress(forSender), '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE') assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/) // ... sender reveals nonce public key (nonce.Q) to recipient - var forRecipient = stealthReceive(recipient.d, nonce.Q) + var forRecipient = stealthReceive(recipient.getPrivateKey(), nonce.getPublicKey()) assert.equal(getAddress(forRecipient), '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE') assert.equal(forRecipient.toWIF(), 'L1yjUN3oYyCXV3LcsBrmxCNTa62bZKWCybxVJMvqjMmmfDE8yk7n') @@ -98,11 +96,11 @@ describe('bitcoinjs-lib (crypto)', function () { var nonce = bitcoin.ECPair.makeRandom() // private to sender // ... recipient reveals public key (recipient.Q) to sender - var forSender = stealthSend(nonce.d, recipient.Q) + var forSender = stealthSend(nonce.getPrivateKey(), recipient.getPublicKey()) assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/) // ... sender reveals nonce public key (nonce.Q) to recipient - var forRecipient = stealthReceive(recipient.d, nonce.Q) + var forRecipient = stealthReceive(recipient.getPrivateKey(), nonce.getPublicKey()) assert.doesNotThrow(function () { forRecipient.toWIF() }) // sender and recipient, both derived same address @@ -114,15 +112,15 @@ describe('bitcoinjs-lib (crypto)', function () { var nonce = bitcoin.ECPair.makeRandom() // private to sender // ... recipient reveals public key (recipient.Q) to sender - var forSender = stealthSend(nonce.d, recipient.Q) + var forSender = stealthSend(nonce.getPrivateKey(), recipient.getPublicKey()) assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/) // ... sender reveals nonce public key (nonce.Q) to recipient - var forRecipient = stealthReceive(recipient.d, nonce.Q) + var forRecipient = stealthReceive(recipient.getPrivateKey(), nonce.getPublicKey()) assert.doesNotThrow(function () { forRecipient.toWIF() }) // ... recipient accidentally leaks forRecipient.d on the blockchain - var leaked = stealthRecoverLeaked(forRecipient.d, nonce.d, recipient.Q) + var leaked = stealthRecoverLeaked(forRecipient.getPrivateKey(), nonce.getPrivateKey(), recipient.getPublicKey()) assert.equal(leaked.toWIF(), recipient.toWIF()) }) @@ -133,15 +131,15 @@ describe('bitcoinjs-lib (crypto)', function () { var nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender // ... recipient reveals public key(s) (recipient.Q, scan.Q) to sender - var forSender = stealthDualSend(nonce.d, recipient.Q, scan.Q) + var forSender = stealthDualSend(nonce.getPrivateKey(), recipient.getPublicKey(), scan.getPublicKey()) assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/) // ... sender reveals nonce public key (nonce.Q) to scanner - var forScanner = stealthDualScan(scan.d, recipient.Q, nonce.Q) + var forScanner = stealthDualScan(scan.getPrivateKey(), recipient.getPublicKey(), nonce.getPublicKey()) assert.throws(function () { forScanner.toWIF() }, /Error: Missing private key/) // ... scanner reveals relevant transaction + nonce public key (nonce.Q) to recipient - var forRecipient = stealthDualReceive(scan.d, recipient.d, nonce.Q) + var forRecipient = stealthDualReceive(scan.getPrivateKey(), recipient.getPrivateKey(), nonce.getPublicKey()) assert.doesNotThrow(function () { forRecipient.toWIF() }) // scanner, sender and recipient, all derived same address @@ -155,15 +153,15 @@ describe('bitcoinjs-lib (crypto)', function () { var nonce = bitcoin.ECPair.makeRandom() // private to sender // ... recipient reveals public key(s) (recipient.Q, scan.Q) to sender - var forSender = stealthDualSend(nonce.d, recipient.Q, scan.Q) + var forSender = stealthDualSend(nonce.getPrivateKey(), recipient.getPublicKey(), scan.getPublicKey()) assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/) // ... sender reveals nonce public key (nonce.Q) to scanner - var forScanner = stealthDualScan(scan.d, recipient.Q, nonce.Q) + var forScanner = stealthDualScan(scan.getPrivateKey(), recipient.getPublicKey(), nonce.getPublicKey()) assert.throws(function () { forScanner.toWIF() }, /Error: Missing private key/) // ... scanner reveals relevant transaction + nonce public key (nonce.Q) to recipient - var forRecipient = stealthDualReceive(scan.d, recipient.d, nonce.Q) + var forRecipient = stealthDualReceive(scan.getPrivateKey(), recipient.getPrivateKey(), nonce.getPublicKey()) assert.doesNotThrow(function () { forRecipient.toWIF() }) // scanner, sender and recipient, all derived same address diff --git a/test/integration/transactions.js b/test/integration/transactions.js index c1e4862..70d68a6 100644 --- a/test/integration/transactions.js +++ b/test/integration/transactions.js @@ -10,7 +10,7 @@ let baddress = bitcoin.address let bcrypto = bitcoin.crypto function getAddress (node, network) { network = network || bitcoin.networks.bitcoin - return baddress.toBase58Check(bcrypto.hash160(node.getPublicKeyBuffer()), network.pubKeyHash) + return baddress.toBase58Check(bcrypto.hash160(node.getPublicKey()), network.pubKeyHash) } function rng () { @@ -115,7 +115,7 @@ describe('bitcoinjs-lib (transactions)', function () { '91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe', '91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx9rcrL7' ].map(function (wif) { return bitcoin.ECPair.fromWIF(wif, regtest) }) - var pubKeys = keyPairs.map(function (x) { return x.getPublicKeyBuffer() }) + var pubKeys = keyPairs.map(function (x) { return x.getPublicKey() }) var redeemScript = bitcoin.script.multisig.output.encode(2, pubKeys) var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript)) @@ -150,7 +150,7 @@ describe('bitcoinjs-lib (transactions)', function () { this.timeout(30000) var keyPair = bitcoin.ECPair.fromWIF('cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA', regtest) - var pubKey = keyPair.getPublicKeyBuffer() + var pubKey = keyPair.getPublicKey() var pubKeyHash = bitcoin.crypto.hash160(pubKey) var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash) @@ -191,7 +191,7 @@ describe('bitcoinjs-lib (transactions)', function () { 'cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87KcLPVfXz', 'cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87L7FgDCKE' ].map(function (wif) { return bitcoin.ECPair.fromWIF(wif, regtest) }) - var pubKeys = keyPairs.map(function (x) { return x.getPublicKeyBuffer() }) + var pubKeys = keyPairs.map(function (x) { return x.getPublicKey() }) var witnessScript = bitcoin.script.multisig.output.encode(3, pubKeys) var redeemScript = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript)) @@ -241,7 +241,7 @@ describe('bitcoinjs-lib (transactions)', function () { var ss = bitcoin.script.signature.decode(scriptSig.signature) var hash = tx.hashForSignature(i, prevOutScript, ss.hashType) - assert.strictEqual(scriptSig.pubKey.toString('hex'), keyPair.getPublicKeyBuffer().toString('hex')) + assert.strictEqual(scriptSig.pubKey.toString('hex'), keyPair.getPublicKey().toString('hex')) assert.strictEqual(keyPair.verify(hash, ss.signature), true) }) }) diff --git a/test/transaction_builder.js b/test/transaction_builder.js index 86f7eca..9c9cc47 100644 --- a/test/transaction_builder.js +++ b/test/transaction_builder.js @@ -7,7 +7,6 @@ let bscript = require('../src/script') let btemplates = require('../src/templates') let ops = require('bitcoin-ops') -let BigInteger = require('bigi') let ECPair = require('../src/ecpair') let Transaction = require('../src/transaction') let TransactionBuilder = require('../src/transaction_builder') @@ -17,7 +16,7 @@ let fixtures = require('./fixtures/transaction_builder') // TODO: remove function getAddress (node) { - return baddress.toBase58Check(bcrypto.hash160(node.getPublicKeyBuffer()), NETWORKS.bitcoin.pubKeyHash) + return baddress.toBase58Check(bcrypto.hash160(node.getPublicKey()), NETWORKS.bitcoin.pubKeyHash) } function construct (f, dontSign) { @@ -89,7 +88,7 @@ function construct (f, dontSign) { describe('TransactionBuilder', function () { // constants - var keyPair = new ECPair(BigInteger.ONE) + var keyPair = ECPair.fromPrivateKey(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')) var scripts = [ '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH', '1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP' diff --git a/test/types.js b/test/types.js index 832b32d..2dbc554 100644 --- a/test/types.js +++ b/test/types.js @@ -5,18 +5,6 @@ var types = require('../src/types') var typeforce = require('typeforce') describe('types', function () { - describe('BigInt/ECPoint', function () { - it('return true for duck types', function () { - assert(types.BigInt(new function BigInteger () {}())) - assert(types.ECPoint(new function Point () {}())) - }) - - it('return false for bad types', function () { - assert(!types.BigInt(new function NotABigInteger () {}())) - assert(!types.ECPoint(new function NotAPoint () {}())) - }) - }) - describe('Buffer Hash160/Hash256', function () { var buffer20byte = Buffer.alloc(20) var buffer32byte = Buffer.alloc(32)