Skip to content

Commit

Permalink
Merge pull request #455 from bitcoinjs/clean
Browse files Browse the repository at this point in the history
Cleanup and stop exposing HDNode constants
  • Loading branch information
dcousens committed Sep 5, 2015
2 parents 4ec7c40 + e8cb7c1 commit 4c92de7
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 96 deletions.
14 changes: 4 additions & 10 deletions src/address.js
Expand Up @@ -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 }
Expand Down Expand Up @@ -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')
}
Expand Down
60 changes: 31 additions & 29 deletions src/ecdsa.js
Expand Up @@ -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)

Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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)
Expand All @@ -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
}
Expand All @@ -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)) {
Expand All @@ -243,5 +242,8 @@ module.exports = {
deterministicGenerateK: deterministicGenerateK,
recoverPubKey: recoverPubKey,
sign: sign,
verify: verify
verify: verify,

// TODO: remove
__curve: secp256k1
}
8 changes: 4 additions & 4 deletions 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')
Expand All @@ -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) {
Expand Down Expand Up @@ -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 () {
Expand All @@ -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
22 changes: 10 additions & 12 deletions src/hdnode.js
Expand Up @@ -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)

Expand All @@ -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)

Expand All @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 2 additions & 5 deletions src/message.js
Expand Up @@ -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)
Expand All @@ -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)
}
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/script.js
Expand Up @@ -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)) {
Expand Down
23 changes: 6 additions & 17 deletions src/transaction.js
Expand Up @@ -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()
Expand Down

0 comments on commit 4c92de7

Please sign in to comment.