ec: start migrating towards secp256k1.
This commit is contained in:
parent
2e1c544679
commit
960d144455
@ -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
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user