diff --git a/lib/bcoin/ec.js b/lib/bcoin/ec.js index 00d7613f..6c9bbddc 100644 --- a/lib/bcoin/ec.js +++ b/lib/bcoin/ec.js @@ -17,7 +17,8 @@ if (!utils.isBrowser) crypto = require('cry' + 'pto'); try { - secp256k1 = require('secp' + '256k1'); + if (+process.env.BCOIN_USE_ELLIPTIC !== 1) + secp256k1 = require('secp' + '256k1'); } catch (e) { ; } @@ -95,28 +96,6 @@ ec.publicKeyCreate = function publicKeyCreate(priv, compressed) { return new Buffer(priv); }; -/** - * Decode a point. - * @param {Buffer} key - * @returns {elliptic.Point} - */ - -ec.decodePoint = function decodePoint(key) { - var hybrid, point; - - if (key[0] === 0x06 || key[0] === 0x07) { - hybrid = key[0]; - key[0] = 0x04; - } - - point = ec.elliptic.curve.decodePoint(key); - - if (hybrid != null) - key[0] = hybrid; - - return point; -}; - /** * Compress or decompress public key. * @param {Buffer} pub @@ -129,7 +108,7 @@ ec.publicKeyConvert = function publicKeyConvert(key, compressed) { if (secp256k1) return secp256k1.publicKeyConvert(key, compressed); - point = ec.decodePoint(key); + point = ec.elliptic.curve.decodePoint(key); return new Buffer(point.encode('array', compressed)); }; @@ -142,19 +121,21 @@ ec.publicKeyConvert = function publicKeyConvert(key, compressed) { */ ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) { + var key; + if (secp256k1) return secp256k1.privateKeyTweakAdd(privateKey, tweak); - privateKey = new bn(tweak) + key = new bn(tweak) .add(new bn(privateKey)) .mod(ec.curve.n) .toArrayLike(Buffer, 'be', 32); // Only a 1 in 2^127 chance of happening. - if (!ec.privateKeyVerify(privateKey)) + if (!ec.privateKeyVerify(key)) throw new Error('Private key is invalid.'); - return privateKey; + return key; }; /** @@ -165,19 +146,19 @@ ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) { */ ec.publicKeyTweakAdd = function publicKeyTweakAdd(publicKey, tweak, compressed) { - var point; + var point, key; if (secp256k1) return secp256k1.publicKeyTweakAdd(publicKey, tweak, compressed); - point = ec.decodePoint(publicKey); + point = ec.curve.decodePoint(publicKey); point = ec.curve.g.mul(new bn(tweak)).add(point); - publicKey = new Buffer(point.encode('array', compressed)); + key = new Buffer(point.encode('array', compressed)); - if (!ec.publicKeyVerify(publicKey)) + if (!ec.publicKeyVerify(key)) throw new Error('Public key is invalid.'); - return publicKey; + return key; }; /** @@ -236,7 +217,7 @@ ec.rand = function rand(min, max) { */ ec.verify = function verify(msg, sig, key, historical, high) { - var hybrid, result; + var result; if (key.getPublicKey) key = key.getPublicKey(); @@ -280,23 +261,12 @@ ec.verify = function verify(msg, sig, key, historical, high) { if (!high && !ec.isLowS(sig)) return false; - // Elliptic does not support - // openssl's "hybrid" keys yet. - if (key[0] === 0x06 || key[0] === 0x07) { - hybrid = key[0]; - key[0] = 0x04; - } - try { result = ec.elliptic.verify(msg, sig, key); } catch (e) { result = false; } - // Reset the byte if we need to. - if (hybrid != null) - key[0] = hybrid; - return result; }; @@ -307,25 +277,17 @@ ec.verify = function verify(msg, sig, key, historical, high) { */ ec.publicKeyVerify = function publicKeyVerify(key) { - var result, hybrid; + var result; if (secp256k1) return secp256k1.publicKeyVerify(key); - if (key[0] === 0x06 || key[0] === 0x07) { - hybrid = key[0]; - key[0] = 0x04; - } - try { result = ec.elliptic.keyPair({ pub: key }).validate(); } catch (e) { result = false; } - if (hybrid != null) - key[0] = hybrid; - return result; }; @@ -413,26 +375,6 @@ ec.normalizeLength = function normalizeLength(sig) { return data; }; -function getLength(buf, p) { - var initial = buf[p.place++]; - var octetLen, val, i, off; - - if (!(initial & 0x80)) - return initial; - - octetLen = initial & 0xf; - val = 0; - - for (i = 0, off = p.place; i < octetLen; i++, off++) { - val <<= 8; - val |= buf[off]; - } - - p.place = off; - - return val; -} - /** * Test whether a signature has a low S value. * @param {Buffer} sig @@ -479,3 +421,27 @@ ec.toLowS = function toLowS(sig) { return new Buffer(sig.toDER()); }; + +/* + * Helpers + */ + +function getLength(buf, p) { + var initial = buf[p.place++]; + var octetLen, val, i, off; + + if (!(initial & 0x80)) + return initial; + + octetLen = initial & 0xf; + val = 0; + + for (i = 0, off = p.place; i < octetLen; i++, off++) { + val <<= 8; + val |= buf[off]; + } + + p.place = off; + + return val; +}