handle low S values in signatures.
This commit is contained in:
parent
de455fa3e9
commit
a71da261ad
@ -31,5 +31,6 @@ bcoin.protocol.network.set(process.env.BCOIN_NETWORK || 'main');
|
|||||||
|
|
||||||
bcoin.bn = bn;
|
bcoin.bn = bn;
|
||||||
bcoin.elliptic = elliptic;
|
bcoin.elliptic = elliptic;
|
||||||
|
bcoin.signature = require('elliptic/lib/elliptic/ec/signature');
|
||||||
bcoin.hash = hash;
|
bcoin.hash = hash;
|
||||||
bcoin.async = async;
|
bcoin.async = async;
|
||||||
|
|||||||
@ -237,9 +237,12 @@ script.subscript = function subscript(s, lastSep) {
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
script.checksig = function checksig(hash, sig, pub) {
|
script.checksig = function checksig(msg, sig, pub) {
|
||||||
var k;
|
var k;
|
||||||
|
|
||||||
|
if (pub.getPublic)
|
||||||
|
pub = pub.getPublic();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
k = bcoin.ecdsa.keyPair({ pub: pub });
|
k = bcoin.ecdsa.keyPair({ pub: pub });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -255,7 +258,7 @@ script.checksig = function checksig(hash, sig, pub) {
|
|||||||
// Use a try catch in case there are
|
// Use a try catch in case there are
|
||||||
// any uncaught errors for bad inputs in verify().
|
// any uncaught errors for bad inputs in verify().
|
||||||
try {
|
try {
|
||||||
return bcoin.ecdsa.verify(hash, sig, pub);
|
return bcoin.ecdsa.verify(msg, sig, pub);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1542,6 +1545,54 @@ script.isValidSignature = function isValidSignature(sig, allowZero) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script.isLowDER = function isLowDER(sig, type) {
|
||||||
|
var half = bcoin.ecdsa.n.ushrn(1);
|
||||||
|
|
||||||
|
if (!sig.s) {
|
||||||
|
assert(utils.isBuffer(sig));
|
||||||
|
|
||||||
|
if (sig[sig.length - 1] === type)
|
||||||
|
sig = sig.slice(0, -1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
sig = new bcoin.signature(sig);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Technically a negative S value is low,
|
||||||
|
// but we don't want to ever use negative
|
||||||
|
// S values in bitcoin.
|
||||||
|
if (sig.s.cmpn(0) <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If S is greater than half the order,
|
||||||
|
// it's too high.
|
||||||
|
if (sig.s.cmp(half) > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
script.sign = function sign(msg, key) {
|
||||||
|
var half = bcoin.ecdsa.n.ushrn(1);
|
||||||
|
var sig = bcoin.ecdsa.sign(msg, key.priv);
|
||||||
|
|
||||||
|
// Elliptic shouldn't be generating
|
||||||
|
// negative S values.
|
||||||
|
assert(sig.s.cmpn(0) > 0);
|
||||||
|
|
||||||
|
// S value is already low.
|
||||||
|
if (sig.s.cmp(half) <= 0)
|
||||||
|
return sig.toDER();
|
||||||
|
|
||||||
|
// Subtract from the `n` order to make it smaller.
|
||||||
|
sig.s = bcoin.ecdsa.n.sub(sig.s);
|
||||||
|
|
||||||
|
return sig.toDER();
|
||||||
|
};
|
||||||
|
|
||||||
script.format = function format(input, output) {
|
script.format = function format(input, output) {
|
||||||
var scripts = [];
|
var scripts = [];
|
||||||
var prev, redeem;
|
var prev, redeem;
|
||||||
|
|||||||
@ -251,7 +251,10 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
hash = this.signatureHash(index, redeem, type);
|
hash = this.signatureHash(index, redeem, type);
|
||||||
|
|
||||||
// Sign the transaction with our one input
|
// Sign the transaction with our one input
|
||||||
signature = bcoin.ecdsa.sign(hash, key.priv).toDER();
|
signature = bcoin.script.sign(hash, key);
|
||||||
|
|
||||||
|
// Something is broken if this doesn't work:
|
||||||
|
assert(bcoin.script.checksig(hash, signature, key));
|
||||||
|
|
||||||
// Add the sighash as a single byte to the signature
|
// Add the sighash as a single byte to the signature
|
||||||
signature = signature.concat(type);
|
signature = signature.concat(type);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user