1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 04:18:10 +00:00

feat(legacy): Implement the BIP-341 common signature message computation.

This commit is contained in:
Andrew Kozlik 2021-11-10 12:43:03 +01:00 committed by Andrew Kozlik
parent 1f4573905f
commit 34e8284331
3 changed files with 89 additions and 22 deletions

View File

@ -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

View File

@ -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);

View File

@ -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,