Browse Source

ecdsa: consistent parameter ordering

hk-custom-address
Daniel Cousens 11 years ago
parent
commit
8d7408202f
  1. 19
      src/ecdsa.js
  2. 7
      src/message.js
  3. 3
      test/ecdsa.js

19
src/ecdsa.js

@ -205,7 +205,7 @@ var ecdsa = {
*
* http://www.secg.org/download/aid-780/sec1-v2.pdf
*/
recoverPubKey: function (r, s, hash, i) {
recoverPubKey: function (e, r, s, i) {
assert.strictEqual(i & 3, i, 'The recovery param is more than two bits')
// A set LSB signifies that the y-coordinate is odd
@ -243,15 +243,16 @@ var ecdsa = {
var R = new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y))
R.validate()
// 1.5 Compute e from M
var e = BigInteger.fromBuffer(hash)
// 1.5 Compute -e from e
var eNeg = e.negate().mod(n)
// 1.6 Compute Q = r^-1 (sR - eG)
// 1.6 Compute Q = r^-1 (sR - eG)
// Q = r^-1 (sR + -eG)
var rInv = r.modInverse(n)
var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv)
var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv)
Q.validate()
if (!ecdsa.verifyRaw(e, r, s, Q)) {
throw new Error("Pubkey recovery unsuccessful")
}
@ -270,16 +271,16 @@ var ecdsa = {
* This function simply tries all four cases and returns the value
* that resulted in a successful pubkey recovery.
*/
calcPubKeyRecoveryParam: function (origPubKey, r, s, hash) {
calcPubKeyRecoveryParam: function (e, r, s, Q) {
for (var i = 0; i < 4; i++) {
var pubKey = ecdsa.recoverPubKey(r, s, hash, i)
var Qprime = ecdsa.recoverPubKey(e, r, s, i)
if (pubKey.equals(origPubKey)) {
if (Qprime.equals(Q)) {
return i
}
}
throw new Error("Unable to find valid recovery factor")
throw new Error('Unable to find valid recovery factor')
}
}

7
src/message.js

@ -1,5 +1,6 @@
/// Implements Bitcoin's feature for signing arbitrary messages.
var Address = require('./address')
var BigInteger = require('bigi')
var bufferutils = require('./bufferutils')
var crypto = require('./crypto')
var ecdsa = require('./ecdsa')
@ -25,7 +26,8 @@ function sign(key, message, network) {
var hash = magicHash(message, network)
var sig = ecdsa.parseSig(key.sign(hash))
var i = ecdsa.calcPubKeyRecoveryParam(key.pub.Q, sig.r, sig.s, hash)
var e = BigInteger.fromBuffer(hash)
var i = ecdsa.calcPubKeyRecoveryParam(e, sig.r, sig.s, key.pub.Q)
return ecdsa.serializeSigCompact(sig.r, sig.s, i, key.pub.compressed)
}
@ -40,7 +42,8 @@ function verify(address, compactSig, message, network) {
var hash = magicHash(message, network)
var sig = ecdsa.parseSigCompact(compactSig)
var Q = ecdsa.recoverPubKey(sig.r, sig.s, hash, sig.i)
var e = BigInteger.fromBuffer(hash)
var Q = ecdsa.recoverPubKey(e, sig.r, sig.s, sig.i)
var pubKey = new ECPubKey(Q, sig.compressed)
return pubKey.getAddress(address.version).toString() === address.toString()

3
test/ecdsa.js

@ -32,8 +32,9 @@ describe('ecdsa', function() {
var obj = ecdsa.parseSigCompact(signature)
var hash = message.magicHash('1111', networks.bitcoin)
var e = BigInteger.fromBuffer(hash)
var pubKey = new ECPubKey(ecdsa.recoverPubKey(obj.r, obj.s, hash, obj.i))
var pubKey = new ECPubKey(ecdsa.recoverPubKey(e, obj.r, obj.s, obj.i))
assert.equal(pubKey.toHex(), '02e8fcf4d749b35879bc1f3b14b49e67ab7301da3558c5a9b74a54f1e6339c334c')
})

Loading…
Cancel
Save