From d14b08efd1bf95749cbc32b29fb0f69f67a35b42 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Thu, 22 May 2014 12:28:14 +1000 Subject: [PATCH] ec/dsa: recovery param now used consistently Also added an assertion rather than massaging the input. --- src/ec.js | 6 ++++-- src/ecdsa.js | 14 ++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ec.js b/src/ec.js index 22705e9..854532a 100644 --- a/src/ec.js +++ b/src/ec.js @@ -339,7 +339,7 @@ ECPointFp.decodeFrom = function (curve, buffer) { assert.equal(buffer.length, 33, 'Invalid sequence length') assert(type === 0x02 || type === 0x03, 'Invalid sequence tag') - var isYEven = type === 0x03 + var isYEven = (type === 0x02) var p = curve.getQ() // We precalculate (p + 1) / 4 where p is the field order @@ -349,7 +349,9 @@ ECPointFp.decodeFrom = function (curve, buffer) { var alpha = x.square().multiply(x).add(SEVEN).mod(p) var beta = alpha.modPow(P_OVER_FOUR, p) - y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta) + // If beta is even, but y isn't, or vice versa, then convert it, + // otherwise we're done and y == beta. + y = (beta.isEven() ^ isYEven) ? p.subtract(beta) : beta } else { assert.equal(buffer.length, 65, 'Invalid sequence length') diff --git a/src/ecdsa.js b/src/ecdsa.js index 6a7fd72..9993af0 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -240,12 +240,11 @@ var ecdsa = { * http://www.secg.org/download/aid-780/sec1-v2.pdf */ recoverPubKey: function (r, s, hash, i) { - // The recovery parameter i has two bits. - i = i & 3 + assert.strictEqual(i & 3, i, 'The recovery param is more than two bits') - // The less significant bit specifies whether the y coordinate - // of the compressed point is even or not. - var isYEven = i & 1 + // A set LSB signifies that the y-coordinate is odd + // By reduction, the y-coordinate is even if it is clear + var isYEven = !(i & 1) // The more significant bit specifies whether we should use the // first or second candidate key. @@ -270,10 +269,9 @@ var ecdsa = { var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p) var beta = alpha.modPow(P_OVER_FOUR, p) - // var xorOdd = beta.isEven() ? (i % 2) : ((i+1) % 2) - // If beta is even, but y isn't or vice versa, then convert it, + // If beta is even, but y isn't, or vice versa, then convert it, // otherwise we're done and y == beta. - var y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta) + var y = (beta.isEven() ^ isYEven) ? p.subtract(beta) : beta // 1.4 Check that nR is at infinity var R = new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y))