From e073ee3d46dc49b3a5c1b8b17a500b3596eb21fa Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 10 Apr 2015 11:07:08 +1000 Subject: [PATCH 1/4] ecdsa: avoid 2-line if statements --- src/ecdsa.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ecdsa.js b/src/ecdsa.js index c88add3..89d4d0d 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 }) From 4f8c7f434842fdc0d29beb47f9c98989794afe15 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 10 Apr 2015 11:07:30 +1000 Subject: [PATCH 2/4] ecdsa: 1.6.1 moved to relevant section --- src/ecdsa.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ecdsa.js b/src/ecdsa.js index 89d4d0d..56f35f4 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -177,14 +177,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 From a221bd142ce1c279f8b4994c3e32bf2c2f0c6dc5 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 10 Apr 2015 17:20:22 +1000 Subject: [PATCH 3/4] ecdsa: split steps up further as per sec1-v2.pdf --- src/ecdsa.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ecdsa.js b/src/ecdsa.js index 56f35f4..71f0bbd 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -115,21 +115,27 @@ 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) + // 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.6 Convert the field element R.x to an integer + var xR = R.affineX + + // 1.4.7 Set v = xR mod n + var v = xR.mod(n) + // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" return v.equals(r) } From 4c030be343b2176d2765ba7a3e2b8966e7964f22 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 10 Apr 2015 17:22:00 +1000 Subject: [PATCH 4/4] ecdsa: remove unused verifyRaw --- src/ecdsa.js | 17 ++++++----------- test/ecdsa.js | 8 ++------ test/fixtures/ecdsa.json | 2 +- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/ecdsa.js b/src/ecdsa.js index 71f0bbd..549eedb 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -104,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 @@ -115,6 +115,10 @@ 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 + // 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) @@ -140,14 +144,6 @@ function verifyRaw (curve, e, signature, Q) { return v.equals(r) } -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) - - return verifyRaw(curve, e, signature, Q) -} - /** * Recover a public key from a signature. * @@ -227,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",