more accurate sighashing.

This commit is contained in:
Christopher Jeffrey 2016-04-27 20:06:55 -07:00
parent e258755671
commit fbeefe03c7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 34 additions and 10 deletions

View File

@ -927,9 +927,6 @@ Script.prototype.toRaw = function toRaw(enc) {
/** /**
* Get the script's "subscript" starting at a separator. * Get the script's "subscript" starting at a separator.
* Remove all OP_CODESEPARATORs if present. This bizarre
* behavior is necessary for signing and verification when
* code separators are present.
* @param {Number?} lastSep - The last separator to sign/verify beyond. * @param {Number?} lastSep - The last separator to sign/verify beyond.
* @returns {Script} Subscript. * @returns {Script} Subscript.
*/ */
@ -938,14 +935,38 @@ Script.prototype.getSubscript = function getSubscript(lastSep) {
var code = []; var code = [];
var i; var i;
if (lastSep == null) // Optimization: avoid re-rendering
lastSep = -1; // of the script in 99.9% of cases.
if (lastSep === 0) {
code = this.clone();
code.raw = this.raw;
return code;
}
assert(lastSep <= 0 || this.code[lastSep] === opcodes.OP_CODESEPARATOR); for (i = lastSep; i < this.code.length; i++) {
for (i = lastSep + 1; i < this.code.length; i++) {
if (Script.isBadPush(this.code[i])) if (Script.isBadPush(this.code[i]))
break; break;
code.push(this.code[i]);
}
return new Script(code);
};
/**
* Get the script's "subscript" starting at a separator.
* Remove all OP_CODESEPARATORs if present. This bizarre
* behavior is necessary for signing and verification when
* code separators are present.
* @returns {Script} Subscript.
*/
Script.prototype.removeSeparators = function removeSeparators() {
var code = [];
var i;
for (i = 0; i < this.code.length; i++) {
// NOTE: We do not check for bad pushes here. Bad
// pushes may have been created by FindAndDelete().
if (this.code[i] !== opcodes.OP_CODESEPARATOR) if (this.code[i] !== opcodes.OP_CODESEPARATOR)
code.push(this.code[i]); code.push(this.code[i]);
} }
@ -974,7 +995,7 @@ Script.prototype.getSubscript = function getSubscript(lastSep) {
Script.prototype.execute = function execute(stack, flags, tx, index, version) { Script.prototype.execute = function execute(stack, flags, tx, index, version) {
var ip = 0; var ip = 0;
var lastSep = -1; var lastSep = 0;
var opCount = 0; var opCount = 0;
var op, val, v1, v2, v3; var op, val, v1, v2, v3;
var n, n1, n2, n3; var n, n1, n2, n3;

View File

@ -402,6 +402,9 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) {
for (i = 0; i < copy.inputs.length; i++) for (i = 0; i < copy.inputs.length; i++)
copy.inputs[i].script = new Script([]); copy.inputs[i].script = new Script([]);
// Remove all code separators.
prev = prev.removeSeparators();
// Set our input to previous output's script // Set our input to previous output's script
copy.inputs[index].script = prev; copy.inputs[index].script = prev;

View File

@ -263,7 +263,7 @@ describe('TX', function() {
if (hexType.length % 2 !== 0) if (hexType.length % 2 !== 0)
hexType = '0' + hexType; hexType = '0' + hexType;
it('should get signature hash of ' + data[4] + ' (' + hexType + ')' + suffix, function () { it('should get signature hash of ' + data[4] + ' (' + hexType + ')' + suffix, function () {
var subscript = script.getSubscript(); var subscript = script.getSubscript(0).removeSeparators();
var hash = tx.signatureHash(index, subscript, type, 0).toString('hex'); var hash = tx.signatureHash(index, subscript, type, 0).toString('hex');
assert.equal(hash, expected); assert.equal(hash, expected);
}); });