diff --git a/src/ecdsa.js b/src/ecdsa.js index 5303c0b..bb70c56 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -54,30 +54,10 @@ var ecdsa = { s = n.subtract(s) } - return ecdsa.serializeSig(r, s) + return {r: r, s: s} }, - verify: function (hash, sig, pubkey) { - var r,s - if (Array.isArray(sig) || Buffer.isBuffer(sig)) { - var obj = ecdsa.parseSig(sig) - r = obj.r - s = obj.s - } else if ("object" === typeof sig && sig.r && sig.s) { - r = sig.r - s = sig.s - } else { - throw new Error("Invalid value for signature") - } - - var Q - if (pubkey instanceof ECPointFp) { - Q = pubkey - } else if (Array.isArray(pubkey) || Buffer.isBuffer(pubkey)) { - Q = ECPointFp.decodeFrom(ecparams.getCurve(), pubkey) - } else { - throw new Error("Invalid format for pubkey value, must be byte array or ECPointFp") - } + verify: function (hash, r, s, Q) { var e = BigInteger.fromBuffer(hash) return ecdsa.verifyRaw(e, r, s, Q) @@ -140,8 +120,6 @@ var ecdsa = { * } */ parseSig: function (buffer) { - if (Array.isArray(buffer)) buffer = new Buffer(buffer) // FIXME: transitionary - assert.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence') assert.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length') diff --git a/src/ecpubkey.js b/src/ecpubkey.js index bd2e7e8..a5b86bd 100644 --- a/src/ecpubkey.js +++ b/src/ecpubkey.js @@ -36,8 +36,8 @@ ECPubKey.prototype.getAddress = function(version) { return new Address(crypto.hash160(this.toBuffer()), version) } -ECPubKey.prototype.verify = function(hash, sig) { - return ecdsa.verify(hash, sig, this.Q) +ECPubKey.prototype.verify = function(hash, signature) { + return ecdsa.verify(hash, signature.r, signature.s, this.Q) } // Export functions diff --git a/src/message.js b/src/message.js index 1feaa31..2a72f83 100644 --- a/src/message.js +++ b/src/message.js @@ -25,7 +25,7 @@ function sign(key, message, network) { network = network || networks.bitcoin var hash = magicHash(message, network) - var sig = ecdsa.parseSig(key.sign(hash)) + var sig = key.sign(hash) var e = BigInteger.fromBuffer(hash) var i = ecdsa.calcPubKeyRecoveryParam(e, sig.r, sig.s, key.pub.Q) diff --git a/src/transaction.js b/src/transaction.js index bfbbe0e..09db26d 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -364,27 +364,35 @@ Transaction.prototype.sign = function(index, key, type) { this.setScriptSig(index, scriptSig) } -Transaction.prototype.signScriptSig = function(index, script, key, type) { +Transaction.prototype.signScriptSig = function(index, scriptPubKey, key, type) { type = type || SIGHASH_ALL assert((index >= 0), 'Invalid vin index') - assert(script instanceof Script, 'Invalid Script object') + assert(scriptPubKey instanceof Script, 'Invalid Script object') assert(key instanceof ECKey, 'Invalid private key') // assert.equal(type & 0x7F, type, 'Invalid type') // TODO - var hash = this.hashForSignature(script, index, type) - return key.sign(hash).concat([type]) + var hash = this.hashForSignature(scriptPubKey, index, type) + var sig = key.sign(hash) + var DERsig = ecdsa.serializeSig(sig.r, sig.s) + + return Buffer.concat([ + new Buffer(DERsig), + new Buffer([type]) + ]) } Transaction.prototype.setScriptSig = function(index, script) { this.ins[index].script = script } -Transaction.prototype.validateSig = function(index, script, pub, sig) { - var type = sig[sig.length - 1] +Transaction.prototype.validateSig = function(index, script, pub, DERsig) { + var type = DERsig.readUInt8(DERsig.length - 1) + DERsig = DERsig.slice(0, -1) + var hash = this.hashForSignature(script, index, type) + var sig = ecdsa.parseSig(DERsig) - sig = sig.slice(0, -1) return pub.verify(hash, sig) } diff --git a/test/ecdsa.js b/test/ecdsa.js index ad9806d..bc9e49d 100644 --- a/test/ecdsa.js +++ b/test/ecdsa.js @@ -46,7 +46,7 @@ describe('ecdsa', function() { var D = BigInteger.fromHex(f.D) var priv = new ECKey(D) var hash = crypto.sha256(f.message) - var sig = ecdsa.parseSig(priv.sign(hash)) + var sig = priv.sign(hash) assert.equal(sig.r.toString(), f.signature.r) assert.equal(sig.s.toString(), f.signature.s) @@ -56,12 +56,11 @@ describe('ecdsa', function() { it('should sign with low S value', function() { var priv = ECKey.makeRandom() var hash = crypto.sha256('Vires in numeris') - var signature = priv.sign(hash) - var psig = ecdsa.parseSig(signature) + var sig = priv.sign(hash) // See BIP62 for more information var N_OVER_TWO = ecparams.getN().shiftRight(1) - assert(psig.s.compareTo(N_OVER_TWO) <= 0) + assert(sig.s.compareTo(N_OVER_TWO) <= 0) }) }) diff --git a/test/transaction.js b/test/transaction.js index 9f33cc4..e22f7f8 100644 --- a/test/transaction.js +++ b/test/transaction.js @@ -197,7 +197,7 @@ describe('Transaction', function() { tx.sign(0, key) var script = prevTx.outs[0].script - var sig = tx.ins[0].script.chunks[0] + var sig = new Buffer(tx.ins[0].script.chunks[0]) assert.equal(tx.validateSig(0, script, key.pub, sig), true) }) @@ -213,7 +213,7 @@ describe('Transaction', function() { it('returns true for valid signature', function(){ var key = ECKey.fromWIF('L44f7zxJ5Zw4EK9HZtyAnzCYz2vcZ5wiJf9AuwhJakiV4xVkxBeb') var script = prevTx.outs[0].script - var sig = validTx.ins[0].script.chunks[0] + var sig = new Buffer(validTx.ins[0].script.chunks[0]) assert.equal(validTx.validateSig(0, script, key.pub, sig), true) })