Fix transaction signing

This commit is contained in:
Sky Young 2019-07-19 11:44:37 -06:00
parent 5a300e785f
commit 84aabe20a9
3 changed files with 21 additions and 36 deletions

View File

@ -439,10 +439,11 @@ class TX {
* @param {Amount} value - Previous output value.
* @param {SighashType} type - Sighash type.
* @param {Number} version - Sighash version (0=legacy, 1=segwit).
* @param {Boolean} [includeFloData=true] - Should floData be included in the signature Hash
* @returns {Buffer} Signature hash.
*/
signatureHash(index, prev, value, type, version) {
signatureHash(index, prev, value, type, version, includeFloData = true) {
assert(index >= 0 && index < this.inputs.length);
assert(prev instanceof Script);
assert(typeof value === 'number');
@ -450,11 +451,11 @@ class TX {
// Traditional sighashing
if (version === 0)
return this.signatureHashV0(index, prev, type);
return this.signatureHashV0(index, prev, type, includeFloData);
// Segwit sighashing
if (version === 1)
return this.signatureHashV1(index, prev, value, type);
return this.signatureHashV1(index, prev, value, type, includeFloData);
throw new Error('Unknown sighash version.');
}
@ -465,10 +466,11 @@ class TX {
* @param {Number} index
* @param {Script} prev
* @param {SighashType} type
* @param {Boolean} [includeFloData=true] - Should floData be included in the signature Hash
* @returns {Buffer}
*/
signatureHashV0(index, prev, type) {
signatureHashV0(index, prev, type, includeFloData = true) {
if ((type & 0x1f) === hashType.SINGLE) {
// Bitcoind used to return 1 as an error code:
// it ended up being treated like a hash.
@ -483,7 +485,7 @@ class TX {
prev = prev.removeSeparators();
// Calculate buffer size.
const size = this.hashSize(index, prev, type);
const size = this.hashSize(index, prev, type, includeFloData);
const bw = bio.pool(size);
bw.writeU32(this.version);
@ -574,14 +576,10 @@ class TX {
bw.writeU32(this.locktime);
var fOmitTxComment = !!(type & hashType.OMIT_TX_COMMENT);
if (this.version >= 2 && !fOmitTxComment) {
if (this.version >= 2 && includeFloData) {
bw.writeVarBytes(Buffer.from(this.strFloData));
}
type &= ~hashType.OMIT_TX_COMMENT;
// Append the hash type.
bw.writeU32(type);
@ -597,7 +595,7 @@ class TX {
* @returns {Number}
*/
hashSize(index, prev, type) {
hashSize(index, prev, type, includeFloData = true) {
let size = 0;
size += 4;
@ -631,17 +629,11 @@ class TX {
break;
}
var fOmitTxComment = !!(type & hashType.OMIT_TX_COMMENT);
if (!fOmitTxComment){
if (includeFloData){
let bufferLength = Buffer.from(this.strFloData).length;
if (this.strFloData.length > 0){
size += encoding.sizeVarint(bufferLength);
size += bufferLength
} else {
size += encoding.sizeVarint(0);
}
size += encoding.sizeVarint(bufferLength);
size += bufferLength
}
size += 8;
@ -656,10 +648,11 @@ class TX {
* @param {Script} prev
* @param {Amount} value
* @param {SighashType} type
* @param {Boolean} [includeFloData=true] - Should floData be included in the signature Hash
* @returns {Buffer}
*/
signatureHashV1(index, prev, value, type) {
signatureHashV1(index, prev, value, type, includeFloData = true) {
const input = this.inputs[index];
let prevouts = consensus.ZERO_HASH;
let sequences = consensus.ZERO_HASH;
@ -741,13 +734,10 @@ class TX {
bw.writeU32(this.locktime);
// Add the FloData to the transaction
if (this.version >= 2 && !fOmitTxComment) {
if (this.version >= 2 && includeFloData) {
bw.writeVarBytes(Buffer.from(this.strFloData));
}
// Remove the OMIT_TX_COMMENT flag if included
type &= ~hashType.OMIT_TX_COMMENT;
bw.writeU32(type);
return hash256.digest(bw.render());
@ -770,15 +760,12 @@ class TX {
let type = sig[sig.length - 1];
let signature = sig.slice(0, -1);
let hash = this.signatureHash(index, prev, value, type, version);
let hash = this.signatureHash(index, prev, value, type, version, true);
if (secp256k1.verifyDER(hash, signature, key)){
return true;
} else {
type ^= hashType.OMIT_TX_COMMENT;
hash = this.signatureHash(index, prev, value, type, version);
hash = this.signatureHash(index, prev, value, type, version, false);
return secp256k1.verifyDER(hash, signature, key);
}
}
@ -803,7 +790,7 @@ class TX {
if (version == null)
version = 0;
const hash = this.signatureHash(index, prev, value, type, version);
const hash = this.signatureHash(index, prev, value, type, version, true);
const sig = secp256k1.signDER(hash, key);
const bw = bio.write(sig.length + 1);

View File

@ -1135,19 +1135,17 @@ class Script {
let hash;
try {
hash = tx.signatureHash(index, subscript, value, type, version);
hash = tx.signatureHash(index, subscript, value, type, version, true);
res = checksig(hash, sig, key);
} catch (e) {
// Having issues with signatures? Log this error then!
}
if (!res){
type ^= Script.hashType.OMIT_TX_COMMENT;
try {
hash = tx.signatureHash(index, subscript, value, type, version);
hash = tx.signatureHash(index, subscript, value, type, version, false);
res = checksig(hash, sig, key);
} catch (e) {
// Having issues with signatures? Log this error then!
throw new ScriptError('CHECKSIGVERIFY_ERROR', e)
}
}

View File

@ -68,7 +68,7 @@ const errs = {
WALLET_ALREADY_UNLOCKED: -17
};
const MAGIC_STRING = 'Bitcoin Signed Message:\n';
const MAGIC_STRING = 'Florincoin Signed Message:\n';
/**
* Wallet RPC