ecdsa: use (r, s) values directly

This commit is contained in:
Daniel Cousens 2014-05-10 22:38:05 +10:00
parent 8d7408202f
commit 2dec1375a1
6 changed files with 26 additions and 41 deletions

View file

@ -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')

View file

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

View file

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

View file

@ -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]
var hash = this.hashForSignature(script, index, type)
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)
}

View file

@ -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)
})
})

View file

@ -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)
})