diff --git a/legacy/firmware/signing.c b/legacy/firmware/signing.c index 13ad7b858..8700360c7 100644 --- a/legacy/firmware/signing.c +++ b/legacy/firmware/signing.c @@ -115,11 +115,18 @@ typedef struct { uint32_t branch_id; #endif Hasher hasher_prevouts; - Hasher hasher_sequence; + Hasher hasher_amounts; + Hasher hasher_scriptpubkeys; + Hasher hasher_sequences; Hasher hasher_outputs; uint8_t hash_prevouts[32]; - uint8_t hash_sequence[32]; + uint8_t hash_amounts[32]; + uint8_t hash_scriptpubkeys[32]; + uint8_t hash_sequences[32]; uint8_t hash_outputs[32]; + uint8_t hash_prevouts143[32]; + uint8_t hash_outputs143[32]; + uint8_t hash_sequence143[32]; } TxInfo; static TxInfo info; @@ -193,13 +200,13 @@ Phase1 - process inputs foreach I (idx1): Request I STAGE_REQUEST_1_INPUT - Add I to segwit hash_prevouts, hash_sequence + Add I to segwit sub-hashes Add I to Decred decred_hash_prefix Add I to TransactionChecksum (prevout and type) if (I has orig_hash) Request input I2 orig_hash, orig_index STAGE_REQUEST_1_ORIG_INPUT Check I matches I2 - Add I2 to orig_hash_prevouts, orig_hash_sequence + Add I2 to original segwit sub-hashes if (Decred) Return I @@ -820,17 +827,19 @@ static bool tx_info_init(TxInfo *tx_info, uint32_t inputs_count, // ZIP-243 hasher_InitParam(&tx_info->hasher_prevouts, HASHER_BLAKE2B_PERSONAL, "ZcashPrevoutHash", 16); - hasher_InitParam(&tx_info->hasher_sequence, HASHER_BLAKE2B_PERSONAL, + hasher_InitParam(&tx_info->hasher_sequences, HASHER_BLAKE2B_PERSONAL, "ZcashSequencHash", 16); hasher_InitParam(&tx_info->hasher_outputs, HASHER_BLAKE2B_PERSONAL, "ZcashOutputsHash", 16); } else #endif { - // BIP-143 - hasher_Init(&tx_info->hasher_prevouts, coin->curve->hasher_sign); - hasher_Init(&tx_info->hasher_sequence, coin->curve->hasher_sign); - hasher_Init(&tx_info->hasher_outputs, coin->curve->hasher_sign); + // BIP-143/BIP-341 + hasher_Init(&tx_info->hasher_prevouts, HASHER_SHA2); + hasher_Init(&tx_info->hasher_amounts, HASHER_SHA2); + hasher_Init(&tx_info->hasher_scriptpubkeys, HASHER_SHA2); + hasher_Init(&tx_info->hasher_sequences, HASHER_SHA2); + hasher_Init(&tx_info->hasher_outputs, HASHER_SHA2); } return true; @@ -901,7 +910,7 @@ void signing_init(const SignTx *msg, const CoinInfo *_coin, } #endif - hasher_Init(&hasher_check, coin->curve->hasher_sign); + hasher_Init(&hasher_check, HASHER_SHA2); layoutProgressSwipe(_("Signing transaction"), 0); @@ -1123,28 +1132,49 @@ static bool tx_info_add_input(TxInfo *tx_info, const TxInputType *txinput) { tx_info->min_sequence = txinput->sequence; } - // Add input to BIP-143 hashPrevouts and hashSequence. + // Add input to BIP-143 and BIP-341 running sub-hashes. tx_prevout_hash(&tx_info->hasher_prevouts, txinput); - tx_sequence_hash(&tx_info->hasher_sequence, txinput); + tx_amount_hash(&tx_info->hasher_amounts, txinput); + tx_script_hash(&tx_info->hasher_scriptpubkeys, txinput->script_pubkey.size, + txinput->script_pubkey.bytes); + tx_sequence_hash(&tx_info->hasher_sequences, txinput); return true; } static bool tx_info_add_output(TxInfo *tx_info, const TxOutputBinType *tx_bin_output) { - // Add output to BIP-143 hashOutputs. + // Add output to BIP-143/BIP-341 hashOutputs. tx_output_hash(&tx_info->hasher_outputs, tx_bin_output, coin->decred); return true; } static void tx_info_finish(TxInfo *tx_info) { hasher_Final(&tx_info->hasher_prevouts, tx_info->hash_prevouts); - hasher_Final(&tx_info->hasher_sequence, tx_info->hash_sequence); + hasher_Final(&tx_info->hasher_amounts, tx_info->hash_amounts); + hasher_Final(&tx_info->hasher_scriptpubkeys, tx_info->hash_scriptpubkeys); + hasher_Final(&tx_info->hasher_sequences, tx_info->hash_sequences); hasher_Final(&tx_info->hasher_outputs, tx_info->hash_outputs); + + if (coin->curve->hasher_sign == HASHER_SHA2D) { + hasher_Raw(HASHER_SHA2, tx_info->hash_prevouts, + sizeof(tx_info->hash_prevouts), tx_info->hash_prevouts143); + hasher_Raw(HASHER_SHA2, tx_info->hash_sequences, + sizeof(tx_info->hash_sequences), tx_info->hash_sequence143); + hasher_Raw(HASHER_SHA2, tx_info->hash_outputs, + sizeof(tx_info->hash_outputs), tx_info->hash_outputs143); + } else { + memcpy(tx_info->hash_prevouts143, tx_info->hash_prevouts, + sizeof(tx_info->hash_prevouts)); + memcpy(tx_info->hash_sequence143, tx_info->hash_sequences, + sizeof(tx_info->hash_sequences)); + memcpy(tx_info->hash_outputs143, tx_info->hash_outputs, + sizeof(tx_info->hash_outputs)); + } } static bool signing_check_input(const TxInputType *txinput) { - // Add input to BIP143 computation. + // Add input to BIP-143/BIP-341 computation. if (!tx_info_add_input(&info, txinput)) { return false; } @@ -1301,7 +1331,7 @@ static bool signing_check_output(TxOutputType *txoutput) { tx_serialize_output_hash(&ti, &bin_output); } #endif - // Add output to BIP143 computation. + // Add output to BIP-143/BIP-341 computation. return tx_info_add_output(&info, &bin_output); } @@ -1361,7 +1391,7 @@ static bool signing_check_orig_input(TxInputType *orig_input) { return false; } - // Add input to original BIP143 computation. + // Add input to original BIP-143/BIP-341 computation. if (!tx_info_add_input(&orig_info, orig_input)) { return false; } @@ -1429,7 +1459,7 @@ static bool signing_check_orig_output(TxOutputType *orig_output) { return false; } - // Add output to original BIP143 computation. + // Add output to original BIP-143/BIP-341 computation. if (!tx_info_add_output(&orig_info, &orig_bin_output)) { return false; } @@ -1653,9 +1683,9 @@ static void signing_hash_bip143(const TxInfo *tx_info, // nVersion hasher_Update(&hasher_preimage, (const uint8_t *)&tx_info->version, 4); // hashPrevouts - hasher_Update(&hasher_preimage, tx_info->hash_prevouts, 32); + hasher_Update(&hasher_preimage, tx_info->hash_prevouts143, 32); // hashSequence - hasher_Update(&hasher_preimage, tx_info->hash_sequence, 32); + hasher_Update(&hasher_preimage, tx_info->hash_sequence143, 32); // outpoint tx_prevout_hash(&hasher_preimage, txinput); // scriptCode @@ -1666,7 +1696,7 @@ static void signing_hash_bip143(const TxInfo *tx_info, // nSequence tx_sequence_hash(&hasher_preimage, txinput); // hashOutputs - hasher_Update(&hasher_preimage, tx_info->hash_outputs, 32); + hasher_Update(&hasher_preimage, tx_info->hash_outputs143, 32); // nLockTime hasher_Update(&hasher_preimage, (const uint8_t *)&tx_info->lock_time, 4); // nHashType @@ -1675,6 +1705,37 @@ static void signing_hash_bip143(const TxInfo *tx_info, hasher_Final(&hasher_preimage, hash); } +static void signing_hash_bip341(const TxInfo *tx_info, uint32_t i, + uint8_t sighash_type, uint8_t *hash) { + const uint8_t zero = 0; + Hasher sigmsg_hasher = {0}; + hasher_Init(&sigmsg_hasher, HASHER_SHA2_TAPSIGHASH); + // sighash epoch 0 + hasher_Update(&sigmsg_hasher, &zero, 1); + // nHashType + hasher_Update(&sigmsg_hasher, &sighash_type, 1); + // nVersion + hasher_Update(&sigmsg_hasher, (const uint8_t *)&tx_info->version, 4); + // nLockTime + hasher_Update(&sigmsg_hasher, (const uint8_t *)&tx_info->lock_time, 4); + // sha_prevouts + hasher_Update(&sigmsg_hasher, tx_info->hash_prevouts, 32); + // sha_amounts + hasher_Update(&sigmsg_hasher, tx_info->hash_amounts, 32); + // sha_scriptpubkeys + hasher_Update(&sigmsg_hasher, tx_info->hash_scriptpubkeys, 32); + // sha_sequences + hasher_Update(&sigmsg_hasher, tx_info->hash_sequences, 32); + // sha_outputs + hasher_Update(&sigmsg_hasher, tx_info->hash_outputs, 32); + // spend_type 0 (no tapscript message extension, no annex) + hasher_Update(&sigmsg_hasher, &zero, 1); + // input_index + hasher_Update(&sigmsg_hasher, (const uint8_t *)&i, 4); + + hasher_Final(&sigmsg_hasher, hash); +} + #if !BITCOIN_ONLY static void signing_hash_zip243(const TxInfo *tx_info, const TxInputType *txinput, uint8_t *hash) { @@ -1695,7 +1756,7 @@ static void signing_hash_zip243(const TxInfo *tx_info, // 3. hashPrevouts hasher_Update(&hasher_preimage, tx_info->hash_prevouts, 32); // 4. hashSequence - hasher_Update(&hasher_preimage, tx_info->hash_sequence, 32); + hasher_Update(&hasher_preimage, tx_info->hash_sequences, 32); // 5. hashOutputs hasher_Update(&hasher_preimage, tx_info->hash_outputs, 32); // 6. hashJoinSplits diff --git a/legacy/firmware/transaction.c b/legacy/firmware/transaction.c index b004c1aee..67a43c076 100644 --- a/legacy/firmware/transaction.c +++ b/legacy/firmware/transaction.c @@ -489,6 +489,11 @@ uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input) { return 36; } +uint32_t tx_amount_hash(Hasher *hasher, const TxInputType *input) { + hasher_Update(hasher, (const uint8_t *)&input->amount, 8); + return 8; +} + uint32_t tx_script_hash(Hasher *hasher, uint32_t size, const uint8_t *data) { int r = ser_length_hash(hasher, size); hasher_Update(hasher, data, size); diff --git a/legacy/firmware/transaction.h b/legacy/firmware/transaction.h index 493f51568..1f9953607 100644 --- a/legacy/firmware/transaction.h +++ b/legacy/firmware/transaction.h @@ -78,6 +78,7 @@ int compile_output(const CoinInfo *coin, AmountUnit amount_unit, void tx_input_check_hash(Hasher *hasher, const TxInputType *input); uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input); +uint32_t tx_amount_hash(Hasher *hasher, const TxInputType *input); uint32_t tx_script_hash(Hasher *hasher, uint32_t size, const uint8_t *data); uint32_t tx_sequence_hash(Hasher *hasher, const TxInputType *input); uint32_t tx_output_hash(Hasher *hasher, const TxOutputBinType *output,