From d7c2e4d5a5e75029fc9ff22dc2cb50e08508a3b4 Mon Sep 17 00:00:00 2001 From: "GreenAddress.it" Date: Thu, 17 Apr 2014 06:05:41 +0200 Subject: [PATCH] Uses low 's' values for signatures --- src/ecdsa.js | 5 +++++ test/eckey.js | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/ecdsa.js b/src/ecdsa.js index f46e56d..ebb2216 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -69,6 +69,11 @@ var ecdsa = { var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n) + if (s.compareTo(n.divide(BigInteger.valueOf(2))) > 0) { + // Make 's' value 'low', as per https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures + s = n.subtract(s); + } + return ecdsa.serializeSig(r, s) }, diff --git a/test/eckey.js b/test/eckey.js index 4134333..c492a1d 100644 --- a/test/eckey.js +++ b/test/eckey.js @@ -1,4 +1,8 @@ var assert = require('assert') +var ecdsa = require('../src/ecdsa.js') +var sec = require('../src/jsbn/sec.js') +var BigInteger = require('../src/jsbn/jsbn.js') +var ecparams = sec("secp256k1") var ECKey = require('../src/eckey.js').ECKey var ECPubKey = require('../src/eckey.js').ECPubKey var convert = require('../src/convert.js') @@ -148,6 +152,19 @@ describe('ECKey', function() { assert(priv.verify(message, signature)) }) + it('should sign with low S value', function() { + var priv = new ECKey(hpriv) + var signature = priv.sign(message) + var parsed = ecdsa.parseSig(signature) + + // Check that the 's' value is 'low', to prevent possible transaction malleability as per + // https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures + assert(parsed.s.compareTo(ecparams.getN().divide(BigInteger.valueOf(2))) <= 0) + + assert(priv.verify(message, signature)) + }) + + it('should verify against the public key', function() { var priv = new ECKey(hpriv) var pub = new ECPubKey(hcpub, true)