verify sighash types other than all.

This commit is contained in:
Christopher Jeffrey 2015-12-07 14:12:42 -08:00
parent 1804acc77c
commit cf20326e98
2 changed files with 30 additions and 23 deletions

View File

@ -128,7 +128,7 @@ script.verify = function verify(hash, sig, pub) {
}
};
script.execute = function execute(s, stack, tx) {
script.execute = function execute(s, stack, hasher) {
if (s.length > 10000) {
return false;
}
@ -160,20 +160,20 @@ script.execute = function execute(s, stack, tx) {
}
} else if (o === 'checksigverify' || o === 'checksig') {
if (!tx || stack.length < 2)
if (!hasher || stack.length < 2)
return false;
var pub = stack.pop();
var sig = stack.pop();
var type = sig[sig.length - 1];
if (type !== 1)
if (!constants.rhashType[type & 0x7f])
return false;
// XXX Deal with different hashTypes besides `all`
// if (typeof tx === 'function')
// tx = tx(constants.rhashType[type]);
var hash = hasher;
if (typeof hash === 'function')
hash = hash(type);
var res = script.verify(tx, sig.slice(0, -1), pub);
var res = script.verify(hash, sig.slice(0, -1), pub);
if (o === 'checksigverify') {
if (!res)
return false;
@ -181,7 +181,7 @@ script.execute = function execute(s, stack, tx) {
stack.push(res ? [ 1 ] : []);
}
} else if (o === 'checkmultisigverify' || o === 'checkmultisig') {
if (!tx || stack.length < 3)
if (!hasher || stack.length < 3)
return false;
var n = stack.pop();
@ -214,16 +214,16 @@ script.execute = function execute(s, stack, tx) {
for (var i = 0, j = 0; i < m && j < n; i++) {
var sig = stack.pop();
var type = sig[sig.length - 1];
if (type !== 1)
if (!constants.rhashType[type & 0x7f])
return false;
// XXX Deal with different hashTypes besides `all`
// if (typeof tx === 'function')
// tx = tx(constants.rhashType[type]);
var hash = hasher;
if (typeof hash === 'function')
hash = hash(type);
var res = false;
for (; !res && j < n; j++)
res = script.verify(tx, sig.slice(0, -1), keys[j]);
res = script.verify(hash, sig.slice(0, -1), keys[j]);
if (res)
succ++;
}

View File

@ -124,6 +124,12 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) {
};
TX.prototype.signature = function(input, key, type) {
if (!type)
type = 'all';
if (typeof type === 'string')
type = bcoin.protocol.constants.hashType[type];
// Get the previous output's subscript
var s = input.out.tx.getSubscript(input.out.index);
@ -134,7 +140,7 @@ TX.prototype.signature = function(input, key, type) {
var signature = bcoin.ecdsa.sign(hash, key).toDER();
// Add the sighash as a single byte to the signature
signature = signature.concat(constants.hashType[type]);
signature = signature.concat(type);
return signature;
};
@ -187,6 +193,9 @@ TX.prototype.signInput = function(input, key, type) {
if (!type)
type = 'all';
if (typeof type === 'string')
type = bcoin.protocol.constants.hashType[type];
// Get the previous output's subscript
var s = input.out.tx.getSubscript(input.out.index);
@ -197,7 +206,7 @@ TX.prototype.signInput = function(input, key, type) {
var signature = bcoin.ecdsa.sign(hash, key).toDER();
// Add the sighash as a single byte to the signature
signature = signature.concat(constants.hashType[type]);
signature = signature.concat(type);
// P2PKH and simple tx
if (bcoin.script.isPubkeyhash(s) || bcoin.script.isSimplePubkeyhash(s)) {
@ -329,13 +338,14 @@ TX.prototype.getSubscript = function getSubscript(index) {
TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
var copy = this.clone();
if (typeof type === 'string')
type = bcoin.protocol.constants.hashType[type];
copy.inputs.forEach(function(input, i) {
input.script = index === i ? s : [];
});
var verifyStr = copy.render();
verifyStr = verifyStr.concat(
bcoin.protocol.constants.hashType[type], 0, 0, 0
);
utils.writeU32(verifyStr, type, verifyStr.length);
var hash = utils.dsha256(verifyStr);
return hash;
@ -356,15 +366,12 @@ TX.prototype.verify = function verify(index, force) {
assert(input.out.tx.outputs.length > input.out.index);
var subscript = input.out.tx.getSubscript(input.out.index);
var hash = this.subscriptHash(i, subscript, 'all');
// XXX Deal with different hashTypes besides `all`
// var hash = this.subscriptHash.bind(this, i, subscript);
var hasher = this.subscriptHash.bind(this, i, subscript);
var stack = [];
bcoin.script.execute(input.script, stack);
var prev = input.out.tx.outputs[input.out.index].script;
var res = bcoin.script.execute(prev, stack, hash);
var res = bcoin.script.execute(prev, stack, hasher);
if (!res)
return false;