From 64813d3de19c49f6895b4d76b8e863e67e4331c5 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 19 Apr 2016 20:10:22 -0700 Subject: [PATCH] fix ec verification for high s values on non-historical data. --- lib/bcoin/chain.js | 3 ++- lib/bcoin/ec.js | 11 ++++++++--- lib/bcoin/script.js | 9 +++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index d2e6b0d6..a8c8e5e6 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -863,10 +863,11 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac tx.rhash); bcoin.debug('TX:'); bcoin.debug(tx); - bcoin.debug('Input:'); + bcoin.debug('Input (%d):', j); bcoin.debug(tx.inputs[j]); bcoin.debug('TX with coins:'); bcoin.debug(tx.toExtended('hex', true)); + bcoin.debug('Flags: %d', flags); assert(!historical, 'BUG: Invalid inputs in historical data!'); return callback(new VerifyError(block, 'invalid', diff --git a/lib/bcoin/ec.js b/lib/bcoin/ec.js index 2770dc8c..4e2f1b1a 100644 --- a/lib/bcoin/ec.js +++ b/lib/bcoin/ec.js @@ -102,11 +102,12 @@ ec.random = function random(size) { * @param {Buffer} key * @param {Boolean?} - Whether this should be treated as a * "historical" signature. This allows signatures to be of - * odd lengths and high S values. + * odd lengths. + * @param {Boolean?} high - Allow high S value. * @returns {Boolean} */ -ec.verify = function verify(msg, sig, key, historical) { +ec.verify = function verify(msg, sig, key, historical, high) { if (!Buffer.isBuffer(sig)) return false; @@ -130,7 +131,7 @@ ec.verify = function verify(msg, sig, key, historical) { if (secp256k1) { // secp256k1 fails on high s values. This is // bad for verifying historical data. - if (historical) + if (high) sig = ec.toLowS(sig); // Import from DER. @@ -138,6 +139,10 @@ ec.verify = function verify(msg, sig, key, historical) { return secp256k1.verify(msg, sig, key); } + // Make elliptic mimic secp256k1's + // failure with high S values. + if (!high && !ec.isLowS(sig)) + return false; return ec.elliptic.verify(msg, sig, key); } catch (e) { // if (!ec.publicKeyVerify(key)) diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index faa0228e..71e7204b 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -4017,6 +4017,7 @@ Script.concat = function concat(scripts) { Script.checksig = function checksig(msg, sig, key, flags) { var historical = false; + var high = false; if (flags == null) flags = constants.flags.STANDARD_VERIFY_FLAGS; @@ -4024,9 +4025,6 @@ Script.checksig = function checksig(msg, sig, key, flags) { if (!Buffer.isBuffer(sig)) return false; - if (sig.length === 0) - return false; - // Attempt to normalize the signature // length before passing to elliptic. // Note: We only do this for historical data! @@ -4037,7 +4035,10 @@ Script.checksig = function checksig(msg, sig, key, flags) { historical = true; } - return bcoin.ec.verify(msg, sig.slice(0, -1), key, historical); + if (!(flags & constants.flags.VERIFY_LOW_S)) + high = true; + + return bcoin.ec.verify(msg, sig.slice(0, -1), key, historical, high); }; /**