diff --git a/src/ecdsa.js b/src/ecdsa.js index c88add3..549eedb 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -75,25 +75,21 @@ function deterministicGenerateK (curve, hash, d, checkSig) { } function sign (curve, hash, d) { - var r, s - var e = BigInteger.fromBuffer(hash) var n = curve.n var G = curve.G + var r, s deterministicGenerateK(curve, hash, d, function (k) { var Q = G.multiply(k) - if (curve.isInfinity(Q)) - return false + if (curve.isInfinity(Q)) return false r = Q.affineX.mod(n) - if (r.signum() === 0) - return false + if (r.signum() === 0) return false s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n) - if (s.signum() === 0) - return false + if (s.signum() === 0) return false return true }) @@ -108,7 +104,7 @@ function sign (curve, hash, d) { return new ECSignature(r, s) } -function verifyRaw (curve, e, signature, Q) { +function verify (curve, hash, signature, Q) { var n = curve.n var G = curve.G @@ -119,31 +115,33 @@ function verifyRaw (curve, e, signature, Q) { if (r.signum() <= 0 || r.compareTo(n) >= 0) return false if (s.signum() <= 0 || s.compareTo(n) >= 0) return false - // c = s^-1 mod n - var c = s.modInverse(n) + // 1.4.2 H = Hash(M), already done by the user + // 1.4.3 e = H + var e = BigInteger.fromBuffer(hash) + + // Compute s^-1 + var sInv = s.modInverse(n) // 1.4.4 Compute u1 = es^−1 mod n // u2 = rs^−1 mod n - var u1 = e.multiply(c).mod(n) - var u2 = r.multiply(c).mod(n) + var u1 = e.multiply(sInv).mod(n) + var u2 = r.multiply(sInv).mod(n) - // 1.4.5 Compute R = (xR, yR) = u1G + u2Q + // 1.4.5 Compute R = (xR, yR) + // R = u1G + u2Q var R = G.multiplyTwo(u1, Q, u2) - var v = R.affineX.mod(n) // 1.4.5 (cont.) Enforce R is not at infinity if (curve.isInfinity(R)) return false - // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" - return v.equals(r) -} + // 1.4.6 Convert the field element R.x to an integer + var xR = R.affineX -function verify (curve, hash, signature, Q) { - // 1.4.2 H = Hash(M), already done by the user - // 1.4.3 e = H - var e = BigInteger.fromBuffer(hash) + // 1.4.7 Set v = xR mod n + var v = xR.mod(n) - return verifyRaw(curve, e, signature, Q) + // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" + return v.equals(r) } /** @@ -181,14 +179,16 @@ function recoverPubKey (curve, e, signature, i) { var nR = R.multiply(n) assert(curve.isInfinity(nR), 'nR is not a valid curve point') + // Compute r^-1 + var rInv = r.modInverse(n) + // Compute -e from e var eNeg = e.negate().mod(n) // 1.6.1 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) + curve.validate(Q) return Q @@ -223,6 +223,5 @@ module.exports = { deterministicGenerateK: deterministicGenerateK, recoverPubKey: recoverPubKey, sign: sign, - verify: verify, - verifyRaw: verifyRaw + verify: verify } diff --git a/test/ecdsa.js b/test/ecdsa.js index a5ff8a5..94f0f40 100644 --- a/test/ecdsa.js +++ b/test/ecdsa.js @@ -158,30 +158,26 @@ describe('ecdsa', function () { }) }) - describe('verify/verifyRaw', function () { + describe('verify', function () { fixtures.valid.ecdsa.forEach(function (f) { it('verifies a valid signature for "' + f.message + '"', function () { var d = BigInteger.fromHex(f.d) var H = crypto.sha256(f.message) - var e = BigInteger.fromBuffer(H) var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s)) var Q = curve.G.multiply(d) assert(ecdsa.verify(curve, H, signature, Q)) - assert(ecdsa.verifyRaw(curve, e, signature, Q)) }) }) - fixtures.invalid.verifyRaw.forEach(function (f) { + fixtures.invalid.verify.forEach(function (f) { it('fails to verify with ' + f.description, function () { var H = crypto.sha256(f.message) - var e = BigInteger.fromBuffer(H) var d = BigInteger.fromHex(f.d) var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s)) var Q = curve.G.multiply(d) assert.equal(ecdsa.verify(curve, H, signature, Q), false) - assert.equal(ecdsa.verifyRaw(curve, e, signature, Q), false) }) }) }) diff --git a/test/fixtures/ecdsa.json b/test/fixtures/ecdsa.json index 57814c2..7bbcc85 100644 --- a/test/fixtures/ecdsa.json +++ b/test/fixtures/ecdsa.json @@ -218,7 +218,7 @@ "i": 4 } ], - "verifyRaw": [ + "verify": [ { "description": "The wrong signature", "d": "01",