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:
parent
1f4573905f
commit
34e8284331
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user