From 84aabe20a9e0cb2deff1f6b2a5f90d22f9ff3aa1 Mon Sep 17 00:00:00 2001 From: Sky Young Date: Fri, 19 Jul 2019 11:44:37 -0600 Subject: [PATCH] Fix transaction signing --- lib/primitives/tx.js | 49 ++++++++++++++++---------------------------- lib/script/script.js | 6 ++---- lib/wallet/rpc.js | 2 +- 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index bdf116f5..5882f79e 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -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); diff --git a/lib/script/script.js b/lib/script/script.js index 429351ba..590463c6 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -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) } } diff --git a/lib/wallet/rpc.js b/lib/wallet/rpc.js index a0b8fda7..0b150210 100644 --- a/lib/wallet/rpc.js +++ b/lib/wallet/rpc.js @@ -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