ec: start migrating towards secp256k1.

This commit is contained in:
Christopher Jeffrey 2016-09-24 19:28:59 -07:00
parent 2e1c544679
commit 960d144455
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -21,6 +21,19 @@ try {
;
}
/*
* Constants
*/
var ZERO_S = new Buffer(
'0000000000000000000000000000000000000000000000000000000000000000',
'hex'
);
var HALF_ORDER = new Buffer(
'7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0',
'hex');
/**
* @exports ec
*/
@ -173,8 +186,7 @@ ec.ecdh = function ecdh(pub, priv) {
if (secp256k1) {
point = secp256k1.ecdhUnsafe(pub, priv, true);
point = ec.curve.decodePoint(point);
return point.getX().toArrayLike(Buffer, 'be', 32);
return point.slice(1, 33);
}
priv = ec.elliptic.keyPair({ priv: priv });
@ -204,11 +216,13 @@ ec.recover = function recover(msg, sig, j, compressed) {
} catch (e) {
return;
}
try {
key = secp256k1.recover(msg, sig, j, compressed);
} catch (e) {
return;
}
return key;
}
@ -248,22 +262,16 @@ ec.verify = function verify(msg, sig, key, historical, high) {
if (key.length === 0)
return false;
// Attempt to normalize the signature
// length before passing to elliptic.
// Note: We only do this for historical data!
// https://github.com/indutny/elliptic/issues/78
if (historical)
sig = ec.normalizeLength(sig);
if (secp256k1) {
// secp256k1 fails on high s values. This is
// bad for verifying historical data.
if (high)
sig = ec.toLowS(sig);
try {
// Import from DER.
sig = secp256k1.signatureImport(sig);
if (historical)
sig = secp256k1.signatureImportLax(sig);
else
sig = secp256k1.signatureImport(sig);
if (high)
sig = secp256k1.signatureNormalize(sig);
result = secp256k1.verify(msg, sig, key);
} catch (e) {
result = false;
@ -272,6 +280,13 @@ ec.verify = function verify(msg, sig, key, historical, high) {
return result;
}
// Attempt to normalize the signature
// length before passing to elliptic.
// Note: We only do this for historical data!
// https://github.com/indutny/elliptic/issues/78
if (historical)
sig = ec.normalizeLength(sig);
// Make elliptic mimic secp256k1's
// failure with high S values.
if (!high && !ec.isLowS(sig))
@ -446,14 +461,36 @@ ec.normalizeLength = function normalizeLength(sig) {
*/
ec.isLowS = function isLowS(sig) {
if (Buffer.isBuffer(sig)) {
var rs, s;
if (secp256k1) {
try {
sig = new ec.signature(sig);
rs = secp256k1.signatureImport(sig);
s = rs.slice(32, 64);
} catch (e) {
return false;
}
if (utils.equal(s, ZERO_S))
return false;
// If S is greater than half the order,
// it's too high.
if (utils.cmp(s, HALF_ORDER) > 0)
return false;
return true;
}
try {
sig = new ec.signature(sig);
} catch (e) {
return false;
}
if (sig.s.cmpn(0) === 0)
return false;
// If S is greater than half the order,
// it's too high.
if (sig.s.cmp(ec.elliptic.nh) > 0)
@ -462,30 +499,6 @@ ec.isLowS = function isLowS(sig) {
return true;
};
/**
* Lower the S value of a signature (used
* for verifying historical data).
* @param {Buffer} sig - DER formatted.
* @returns {Buffer}
*/
ec.toLowS = function toLowS(sig) {
if (Buffer.isBuffer(sig)) {
try {
sig = new ec.signature(sig);
} catch (e) {
return sig;
}
}
// If S is greater than half the order,
// it's too high.
if (sig.s.cmp(ec.elliptic.nh) > 0)
sig.s = ec.curve.n.sub(sig.s);
return new Buffer(sig.toDER());
};
/*
* Helpers
*/