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
|
* @exports ec
|
||||||
*/
|
*/
|
||||||
@ -173,8 +186,7 @@ ec.ecdh = function ecdh(pub, priv) {
|
|||||||
|
|
||||||
if (secp256k1) {
|
if (secp256k1) {
|
||||||
point = secp256k1.ecdhUnsafe(pub, priv, true);
|
point = secp256k1.ecdhUnsafe(pub, priv, true);
|
||||||
point = ec.curve.decodePoint(point);
|
return point.slice(1, 33);
|
||||||
return point.getX().toArrayLike(Buffer, 'be', 32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = ec.elliptic.keyPair({ priv: priv });
|
priv = ec.elliptic.keyPair({ priv: priv });
|
||||||
@ -204,11 +216,13 @@ ec.recover = function recover(msg, sig, j, compressed) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
key = secp256k1.recover(msg, sig, j, compressed);
|
key = secp256k1.recover(msg, sig, j, compressed);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,22 +262,16 @@ ec.verify = function verify(msg, sig, key, historical, high) {
|
|||||||
if (key.length === 0)
|
if (key.length === 0)
|
||||||
return false;
|
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) {
|
if (secp256k1) {
|
||||||
// secp256k1 fails on high s values. This is
|
|
||||||
// bad for verifying historical data.
|
|
||||||
if (high)
|
|
||||||
sig = ec.toLowS(sig);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Import from DER.
|
if (historical)
|
||||||
sig = secp256k1.signatureImport(sig);
|
sig = secp256k1.signatureImportLax(sig);
|
||||||
|
else
|
||||||
|
sig = secp256k1.signatureImport(sig);
|
||||||
|
|
||||||
|
if (high)
|
||||||
|
sig = secp256k1.signatureNormalize(sig);
|
||||||
|
|
||||||
result = secp256k1.verify(msg, sig, key);
|
result = secp256k1.verify(msg, sig, key);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
result = false;
|
result = false;
|
||||||
@ -272,6 +280,13 @@ ec.verify = function verify(msg, sig, key, historical, high) {
|
|||||||
return result;
|
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
|
// Make elliptic mimic secp256k1's
|
||||||
// failure with high S values.
|
// failure with high S values.
|
||||||
if (!high && !ec.isLowS(sig))
|
if (!high && !ec.isLowS(sig))
|
||||||
@ -446,14 +461,36 @@ ec.normalizeLength = function normalizeLength(sig) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ec.isLowS = function isLowS(sig) {
|
ec.isLowS = function isLowS(sig) {
|
||||||
if (Buffer.isBuffer(sig)) {
|
var rs, s;
|
||||||
|
|
||||||
|
if (secp256k1) {
|
||||||
try {
|
try {
|
||||||
sig = new ec.signature(sig);
|
rs = secp256k1.signatureImport(sig);
|
||||||
|
s = rs.slice(32, 64);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
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,
|
// If S is greater than half the order,
|
||||||
// it's too high.
|
// it's too high.
|
||||||
if (sig.s.cmp(ec.elliptic.nh) > 0)
|
if (sig.s.cmp(ec.elliptic.nh) > 0)
|
||||||
@ -462,30 +499,6 @@ ec.isLowS = function isLowS(sig) {
|
|||||||
return true;
|
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
|
* Helpers
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user