Repository: bitcoinjs/bitcoinjs-lib
Pull request #455 (2015-09-05 04:30:20)

Cleanup and stop exposing HDNode constants
https://github.com/bitcoinjs/bitcoinjs-lib/commit/4b825bf2a84a7cfad979251c4cf6572e5c6c50b1 is a breaking change,  but,  it had no merits to begin with IMHO.
If it doesn't have consensus, the constants can easily be re-added in `2.x.y`.


Patch:
diff --git a/src/address.js b/src/address.js
index 669b6d57..d6924b32 100644
--- a/src/address.js
+++ b/src/address.js
@@ -9,7 +9,7 @@ function fromBase58Check (address) {
   if (payload.length < 21) throw new TypeError(address + ' is too short')
   if (payload.length > 21) throw new TypeError(address + ' is too long')
 
-  var version = payload.readUInt8(0)
+  var version = payload[0]
   var hash = payload.slice(1)
 
   return { hash: hash, version: version }
@@ -38,15 +38,9 @@ function toBase58Check (hash, version) {
 function toOutputScript (address, network) {
   network = network || networks.bitcoin
 
-  var payload = bs58check.decode(address)
-  if (payload.length < 21) throw new TypeError(address + ' is too short')
-  if (payload.length > 21) throw new TypeError(address + ' is too long')
-
-  var version = payload.readUInt8(0)
-  var hash = payload.slice(1)
-
-  if (version === network.pubKeyHash) return bscript.pubKeyHashOutput(hash)
-  if (version === network.scriptHash) return bscript.scriptHashOutput(hash)
+  var decode = fromBase58Check(address)
+  if (decode.version === network.pubKeyHash) return bscript.pubKeyHashOutput(decode.hash)
+  if (decode.version === network.scriptHash) return bscript.scriptHashOutput(decode.hash)
 
   throw new Error(address + ' has no matching Script')
 }
diff --git a/src/ecdsa.js b/src/ecdsa.js
index a5190b76..103095db 100644
--- a/src/ecdsa.js
+++ b/src/ecdsa.js
@@ -8,16 +8,17 @@ var ECSignature = require('./ecsignature')
 var ZERO = new Buffer([0])
 var ONE = new Buffer([1])
 
+var ecurve = require('ecurve')
+var secp256k1 = ecurve.getCurveByName('secp256k1')
+
 // https://tools.ietf.org/html/rfc6979#section-3.2
-function deterministicGenerateK (curve, hash, d, checkSig) {
+function deterministicGenerateK (hash, x, checkSig) {
   typeforce(types.tuple(
-    types.ECCurve,
     types.Hash256bit,
-    types.BigInt,
+    types.Buffer256bit,
     types.Function
   ), arguments)
 
-  var x = d.toBuffer(32)
   var k = new Buffer(32)
   var v = new Buffer(32)
 
@@ -57,7 +58,7 @@ function deterministicGenerateK (curve, hash, d, checkSig) {
   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(curve.n) >= 0) || !checkSig(T)) {
+  while (T.signum() <= 0 || T.compareTo(secp256k1.n) >= 0 || !checkSig(T)) {
     k = createHmac('sha256', k)
       .update(v)
       .update(ZERO)
@@ -74,18 +75,21 @@ function deterministicGenerateK (curve, hash, d, checkSig) {
   return T
 }
 
-function sign (curve, hash, d) {
-  typeforce(types.tuple(types.ECCurve, types.Hash256bit, types.BigInt), arguments)
+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 = curve.n
-  var G = curve.G
+  var n = secp256k1.n
+  var G = secp256k1.G
 
   var r, s
-  deterministicGenerateK(curve, hash, d, function (k) {
+  deterministicGenerateK(hash, x, function (k) {
     var Q = G.multiply(k)
 
-    if (curve.isInfinity(Q)) return false
+    if (secp256k1.isInfinity(Q)) return false
 
     r = Q.affineX.mod(n)
     if (r.signum() === 0) return false
@@ -96,8 +100,6 @@ function sign (curve, hash, d) {
     return true
   })
 
-  var N_OVER_TWO = n.shiftRight(1)
-
   // enforce low S values, see bip62: 'low s values in signatures'
   if (s.compareTo(N_OVER_TWO) > 0) {
     s = n.subtract(s)
@@ -106,16 +108,15 @@ function sign (curve, hash, d) {
   return new ECSignature(r, s)
 }
 
-function verify (curve, hash, signature, Q) {
+function verify (hash, signature, Q) {
   typeforce(types.tuple(
-    types.ECCurve,
     types.Hash256bit,
     types.ECSignature,
     types.ECPoint
   ), arguments)
 
-  var n = curve.n
-  var G = curve.G
+  var n = secp256k1.n
+  var G = secp256k1.G
 
   var r = signature.r
   var s = signature.s
@@ -141,7 +142,7 @@ function verify (curve, hash, signature, Q) {
   var R = G.multiplyTwo(u1, Q, u2)
 
   // 1.4.5 (cont.) Enforce R is not at infinity
-  if (curve.isInfinity(R)) return false
+  if (secp256k1.isInfinity(R)) return false
 
   // 1.4.6 Convert the field element R.x to an integer
   var xR = R.affineX
@@ -161,16 +162,15 @@ function verify (curve, hash, signature, Q) {
   *
   * http://www.secg.org/download/aid-780/sec1-v2.pdf
   */
-function recoverPubKey (curve, e, signature, i) {
+function recoverPubKey (e, signature, i) {
   typeforce(types.tuple(
-    types.ECCurve,
     types.BigInt,
     types.ECSignature,
     types.UInt2
   ), arguments)
 
-  var n = curve.n
-  var G = curve.G
+  var n = secp256k1.n
+  var G = secp256k1.G
   var r = signature.r
   var s = signature.s
 
@@ -186,11 +186,11 @@ function recoverPubKey (curve, e, signature, i) {
 
   // 1.1 Let x = r + jn
   var x = isSecondKey ? r.add(n) : r
-  var R = curve.pointFromX(isYOdd, x)
+  var R = secp256k1.pointFromX(isYOdd, x)
 
   // 1.4 Check that nR is at infinity
   var nR = R.multiply(n)
-  if (!curve.isInfinity(nR)) throw new Error('nR is not a valid curve point')
+  if (!secp256k1.isInfinity(nR)) throw new Error('nR is not a valid curve point')
 
   // Compute r^-1
   var rInv = r.modInverse(n)
@@ -202,7 +202,7 @@ function recoverPubKey (curve, e, signature, i) {
   //               Q = r^-1 (sR + -eG)
   var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv)
 
-  curve.validate(Q)
+  secp256k1.validate(Q)
 
   return Q
 }
@@ -218,16 +218,15 @@ function recoverPubKey (curve, e, signature, i) {
   * This function simply tries all four cases and returns the value
   * that resulted in a successful pubkey recovery.
   */
-function calcPubKeyRecoveryParam (curve, e, signature, Q) {
+function calcPubKeyRecoveryParam (e, signature, Q) {
   typeforce(types.tuple(
-    types.ECCurve,
     types.BigInt,
     types.ECSignature,
     types.ECPoint
   ), arguments)
 
   for (var i = 0; i < 4; i++) {
-    var Qprime = recoverPubKey(curve, e, signature, i)
+    var Qprime = recoverPubKey(e, signature, i)
 
     // 1.6.2 Verify Q
     if (Qprime.equals(Q)) {
@@ -243,5 +242,8 @@ module.exports = {
   deterministicGenerateK: deterministicGenerateK,
   recoverPubKey: recoverPubKey,
   sign: sign,
-  verify: verify
+  verify: verify,
+
+  // TODO: remove
+  __curve: secp256k1
 }
diff --git a/src/ecpair.js b/src/ecpair.js
index 9e8698be..e469638f 100644
--- a/src/ecpair.js
+++ b/src/ecpair.js
@@ -1,7 +1,6 @@
 var bcrypto = require('./crypto')
 var bs58check = require('bs58check')
 var ecdsa = require('./ecdsa')
-var ecurve = require('ecurve')
 var randomBytes = require('randombytes')
 var typeforce = require('typeforce')
 var types = require('./types')
@@ -10,7 +9,8 @@ var wif = require('wif')
 var NETWORKS = require('./networks')
 var BigInteger = require('bigi')
 
-var secp256k1 = ecurve.getCurveByName('secp256k1')
+var ecurve = require('ecurve')
+var secp256k1 = ecdsa.__curve
 
 function ECPair (d, Q, options) {
   if (options) {
@@ -112,7 +112,7 @@ ECPair.prototype.getPublicKeyBuffer = function () {
 ECPair.prototype.sign = function (hash) {
   if (!this.d) throw new Error('Missing private key')
 
-  return ecdsa.sign(secp256k1, hash, this.d)
+  return ecdsa.sign(hash, this.d)
 }
 
 ECPair.prototype.toWIF = function () {
@@ -122,7 +122,7 @@ ECPair.prototype.toWIF = function () {
 }
 
 ECPair.prototype.verify = function (hash, signature) {
-  return ecdsa.verify(secp256k1, hash, signature, this.Q)
+  return ecdsa.verify(hash, signature, this.Q)
 }
 
 module.exports = ECPair
diff --git a/src/hdnode.js b/src/hdnode.js
index 4cb117f4..22ccecf9 100644
--- a/src/hdnode.js
+++ b/src/hdnode.js
@@ -11,6 +11,9 @@ var ECPair = require('./ecpair')
 var ecurve = require('ecurve')
 var curve = ecurve.getCurveByName('secp256k1')
 
+var MASTER_SECRET = new Buffer('Bitcoin seed')
+var HIGHEST_BIT = 0x80000000
+
 function HDNode (keyPair, chainCode) {
   typeforce(types.tuple('ECPair', types.Buffer256bit), arguments)
 
@@ -23,17 +26,13 @@ function HDNode (keyPair, chainCode) {
   this.parentFingerprint = 0x00000000
 }
 
-HDNode.MASTER_SECRET = new Buffer('Bitcoin seed')
-HDNode.HIGHEST_BIT = 0x80000000
-HDNode.LENGTH = 78
-
 HDNode.fromSeedBuffer = function (seed, network) {
   typeforce(types.tuple(types.Buffer, types.maybe(types.Network)), arguments)
 
   if (seed.length < 16) throw new TypeError('Seed should be at least 128 bits')
   if (seed.length > 64) throw new TypeError('Seed should be at most 512 bits')
 
-  var I = createHmac('sha512', HDNode.MASTER_SECRET).update(seed).digest()
+  var I = createHmac('sha512', MASTER_SECRET).update(seed).digest()
   var IL = I.slice(0, 32)
   var IR = I.slice(32)
 
@@ -53,9 +52,9 @@ HDNode.fromSeedHex = function (hex, network) {
 
 HDNode.fromBase58 = function (string, networks) {
   var buffer = base58check.decode(string)
-  if (buffer.length !== HDNode.LENGTH) throw new Error('Invalid buffer length')
+  if (buffer.length !== 78) throw new Error('Invalid buffer length')
 
-  // 4 byte: version bytes
+  // 4 bytes: version bytes
   var version = buffer.readUInt32BE(0)
   var network
 
@@ -75,7 +74,7 @@ HDNode.fromBase58 = function (string, networks) {
     version !== network.bip32.public) throw new Error('Invalid network')
 
   // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ...
-  var depth = buffer.readUInt8(4)
+  var depth = buffer[4]
 
   // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
   var parentFingerprint = buffer.readUInt32BE(5)
@@ -155,12 +154,11 @@ HDNode.prototype.toBase58 = function (__isPrivate) {
   // Version
   var network = this.keyPair.network
   var version = this.keyPair.d ? network.bip32.private : network.bip32.public
-  var buffer = new Buffer(HDNode.LENGTH)
+  var buffer = new Buffer(78)
 
   // 4 bytes: version bytes
   buffer.writeUInt32BE(version, 0)
 
-  // Depth
   // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ....
   buffer.writeUInt8(this.depth, 4)
 
@@ -191,7 +189,7 @@ HDNode.prototype.toBase58 = function (__isPrivate) {
 
 // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
 HDNode.prototype.derive = function (index) {
-  var isHardened = index >= HDNode.HIGHEST_BIT
+  var isHardened = index >= HIGHEST_BIT
   var data = new Buffer(37)
 
   // Hardened child
@@ -263,7 +261,7 @@ HDNode.prototype.derive = function (index) {
 
 HDNode.prototype.deriveHardened = function (index) {
   // Only derives hardened private keys by default
-  return this.derive(index + HDNode.HIGHEST_BIT)
+  return this.derive(index + HIGHEST_BIT)
 }
 
 HDNode.prototype.toString = HDNode.prototype.toBase58
diff --git a/src/message.js b/src/message.js
index 16fc1fee..29fe7dc8 100644
--- a/src/message.js
+++ b/src/message.js
@@ -7,9 +7,6 @@ var BigInteger = require('bigi')
 var ECPair = require('./ecpair')
 var ECSignature = require('./ecsignature')
 
-var ecurve = require('ecurve')
-var ecparams = ecurve.getCurveByName('secp256k1')
-
 function magicHash (message, network) {
   var messagePrefix = new Buffer(network.messagePrefix)
   var messageBuffer = new Buffer(message)
@@ -25,7 +22,7 @@ function sign (keyPair, message, network) {
   var hash = magicHash(message, network)
   var signature = keyPair.sign(hash)
   var e = BigInteger.fromBuffer(hash)
-  var i = ecdsa.calcPubKeyRecoveryParam(ecparams, e, signature, keyPair.Q)
+  var i = ecdsa.calcPubKeyRecoveryParam(e, signature, keyPair.Q)
 
   return signature.toCompact(i, keyPair.compressed)
 }
@@ -40,7 +37,7 @@ function verify (address, signature, message, network) {
   var hash = magicHash(message, network)
   var parsed = ECSignature.parseCompact(signature)
   var e = BigInteger.fromBuffer(hash)
-  var Q = ecdsa.recoverPubKey(ecparams, e, parsed.signature, parsed.i)
+  var Q = ecdsa.recoverPubKey(e, parsed.signature, parsed.i)
 
   var keyPair = new ECPair(null, Q, {
     compressed: parsed.compressed,
diff --git a/src/script.js b/src/script.js
index b91997f9..56c75e98 100644
--- a/src/script.js
+++ b/src/script.js
@@ -84,7 +84,7 @@ function decompile (buffer) {
   var i = 0
 
   while (i < buffer.length) {
-    var opcode = buffer.readUInt8(i)
+    var opcode = buffer[i]
 
     // data chunk
     if ((opcode > OPS.OP_0) && (opcode <= OPS.OP_PUSHDATA4)) {
diff --git a/src/transaction.js b/src/transaction.js
index d7178423..3ddf84b4 100644
--- a/src/transaction.js
+++ b/src/transaction.js
@@ -52,23 +52,12 @@ Transaction.fromBuffer = function (buffer, __noStrict) {
 
   var vinLen = readVarInt()
   for (var i = 0; i < vinLen; ++i) {
-    var hash = readSlice(32)
-
-    if (Transaction.isCoinbaseHash(hash)) {
-      tx.ins.push({
-        hash: hash,
-        index: readUInt32(),
-        script: readScript(),
-        sequence: readUInt32()
-      })
-    } else {
-      tx.ins.push({
-        hash: hash,
-        index: readUInt32(),
-        script: readScript(),
-        sequence: readUInt32()
-      })
-    }
+    tx.ins.push({
+      hash: readSlice(32),
+      index: readUInt32(),
+      script: readScript(),
+      sequence: readUInt32()
+    })
   }
 
   var voutLen = readVarInt()


Test patch:
diff --git a/test/ecdsa.js b/test/ecdsa.js
index be834553..db7c8b36 100644
--- a/test/ecdsa.js
+++ b/test/ecdsa.js
@@ -10,8 +10,7 @@ var sinon = require('sinon')
 var BigInteger = require('bigi')
 var ECSignature = require('../src/ecsignature')
 
-var ecurve = require('ecurve')
-var curve = ecurve.getCurveByName('secp256k1')
+var curve = ecdsa.__curve
 
 var fixtures = require('./fixtures/ecdsa.json')
 
@@ -23,10 +22,10 @@ describe('ecdsa', function () {
 
     fixtures.valid.ecdsa.forEach(function (f) {
       it('for "' + f.message + '"', function () {
-        var d = BigInteger.fromHex(f.d)
+        var x = BigInteger.fromHex(f.d).toBuffer(32)
         var h1 = bcrypto.sha256(f.message)
 
-        var k = ecdsa.deterministicGenerateK(curve, h1, d, checkSig)
+        var k = ecdsa.deterministicGenerateK(h1, x, checkSig)
         assert.strictEqual(k.toHex(), f.k)
       })
     })
@@ -38,9 +37,9 @@ describe('ecdsa', function () {
         .onCall(1).returns(curve.n) // > n-1
         .onCall(2).returns(new BigInteger('42')) // valid
 
-      var d = new BigInteger('1')
+      var x = new BigInteger('1').toBuffer(32)
       var h1 = new Buffer(32)
-      var k = ecdsa.deterministicGenerateK(curve, h1, d, checkSig)
+      var k = ecdsa.deterministicGenerateK(h1, x, checkSig)
 
       assert.strictEqual(k.toString(), '42')
     }))
@@ -58,20 +57,20 @@ describe('ecdsa', function () {
       checkSig.onCall(0).returns(false) // bad signature
       checkSig.onCall(1).returns(true) // good signature
 
-      var d = new BigInteger('1')
+      var x = new BigInteger('1').toBuffer(32)
       var h1 = new Buffer(32)
-      var k = ecdsa.deterministicGenerateK(curve, h1, d, checkSig)
+      var k = ecdsa.deterministicGenerateK(h1, x, checkSig)
 
       assert.strictEqual(k.toString(), '53')
     }))
 
     fixtures.valid.rfc6979.forEach(function (f) {
       it('produces the expected k values for ' + f.message + " if k wasn't suitable", function () {
-        var d = BigInteger.fromHex(f.d)
+        var x = BigInteger.fromHex(f.d).toBuffer(32)
         var h1 = bcrypto.sha256(f.message)
 
         var results = []
-        ecdsa.deterministicGenerateK(curve, h1, d, function (k) {
+        ecdsa.deterministicGenerateK(h1, x, function (k) {
           results.push(k)
 
           return results.length === 16
@@ -92,7 +91,7 @@ describe('ecdsa', function () {
         var signature = ECSignature.fromDER(new Buffer(f.signature, 'hex'))
         var h1 = bcrypto.sha256(f.message)
         var e = BigInteger.fromBuffer(h1)
-        var Qprime = ecdsa.recoverPubKey(curve, e, signature, f.i)
+        var Qprime = ecdsa.recoverPubKey(e, signature, f.i)
 
         assert(Qprime.equals(Q))
       })
@@ -113,7 +112,7 @@ describe('ecdsa', function () {
 
       points.forEach(function (expectedHex, i) {
         it('recovers an expected point for i of ' + i, function () {
-          var Qprime = ecdsa.recoverPubKey(curve, e, signature, i)
+          var Qprime = ecdsa.recoverPubKey(e, signature, i)
           var QprimeHex = Qprime.getEncoded().toString('hex')
 
           assert.strictEqual(QprimeHex, expectedHex)
@@ -127,7 +126,7 @@ describe('ecdsa', function () {
         var signature = new ECSignature(new BigInteger(f.signatureRaw.r, 16), new BigInteger(f.signatureRaw.s, 16))
 
         assert.throws(function () {
-          ecdsa.recoverPubKey(curve, e, signature, f.i)
+          ecdsa.recoverPubKey(e, signature, f.i)
         }, new RegExp(f.exception))
       })
     })
@@ -138,7 +137,7 @@ describe('ecdsa', function () {
       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(curve, hash, d).toDER()
+        var signature = ecdsa.sign(hash, d).toDER()
 
         assert.strictEqual(signature.toString('hex'), f.signature)
       })
@@ -146,7 +145,7 @@ describe('ecdsa', function () {
 
     it('should sign with low S value', function () {
       var hash = bcrypto.sha256('Vires in numeris')
-      var sig = ecdsa.sign(curve, hash, BigInteger.ONE)
+      var sig = ecdsa.sign(hash, BigInteger.ONE)
 
       // See BIP62 for more information
       var N_OVER_TWO = curve.n.shiftRight(1)
@@ -162,7 +161,7 @@ describe('ecdsa', function () {
         var signature = ECSignature.fromDER(new Buffer(f.signature, 'hex'))
         var Q = curve.G.multiply(d)
 
-        assert(ecdsa.verify(curve, H, signature, Q))
+        assert(ecdsa.verify(H, signature, Q))
       })
     })
 
@@ -180,7 +179,7 @@ describe('ecdsa', function () {
 
         var Q = curve.G.multiply(d)
 
-        assert.strictEqual(ecdsa.verify(curve, H, signature, Q), false)
+        assert.strictEqual(ecdsa.verify(H, signature, Q), false)
       })
     })
   })
diff --git a/test/hdnode.js b/test/hdnode.js
index 3bfed8d2..a14d89fc 100644
--- a/test/hdnode.js
+++ b/test/hdnode.js
@@ -193,7 +193,7 @@ describe('HDNode', function () {
       assert.strictEqual(hd.depth, depth || 0)
 
       if (v.hardened) {
-        assert.strictEqual(hd.index, v.m + HDNode.HIGHEST_BIT)
+        assert.strictEqual(hd.index, v.m + 0x80000000)
       } else {
         assert.strictEqual(hd.index, v.m)
       }