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;
|
uint32_t branch_id;
|
||||||
#endif
|
#endif
|
||||||
Hasher hasher_prevouts;
|
Hasher hasher_prevouts;
|
||||||
Hasher hasher_sequence;
|
Hasher hasher_amounts;
|
||||||
|
Hasher hasher_scriptpubkeys;
|
||||||
|
Hasher hasher_sequences;
|
||||||
Hasher hasher_outputs;
|
Hasher hasher_outputs;
|
||||||
uint8_t hash_prevouts[32];
|
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_outputs[32];
|
||||||
|
uint8_t hash_prevouts143[32];
|
||||||
|
uint8_t hash_outputs143[32];
|
||||||
|
uint8_t hash_sequence143[32];
|
||||||
} TxInfo;
|
} TxInfo;
|
||||||
|
|
||||||
static TxInfo info;
|
static TxInfo info;
|
||||||
@ -193,13 +200,13 @@ Phase1 - process inputs
|
|||||||
|
|
||||||
foreach I (idx1):
|
foreach I (idx1):
|
||||||
Request I STAGE_REQUEST_1_INPUT
|
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 Decred decred_hash_prefix
|
||||||
Add I to TransactionChecksum (prevout and type)
|
Add I to TransactionChecksum (prevout and type)
|
||||||
if (I has orig_hash)
|
if (I has orig_hash)
|
||||||
Request input I2 orig_hash, orig_index STAGE_REQUEST_1_ORIG_INPUT
|
Request input I2 orig_hash, orig_index STAGE_REQUEST_1_ORIG_INPUT
|
||||||
Check I matches I2
|
Check I matches I2
|
||||||
Add I2 to orig_hash_prevouts, orig_hash_sequence
|
Add I2 to original segwit sub-hashes
|
||||||
if (Decred)
|
if (Decred)
|
||||||
Return I
|
Return I
|
||||||
|
|
||||||
@ -820,17 +827,19 @@ static bool tx_info_init(TxInfo *tx_info, uint32_t inputs_count,
|
|||||||
// ZIP-243
|
// ZIP-243
|
||||||
hasher_InitParam(&tx_info->hasher_prevouts, HASHER_BLAKE2B_PERSONAL,
|
hasher_InitParam(&tx_info->hasher_prevouts, HASHER_BLAKE2B_PERSONAL,
|
||||||
"ZcashPrevoutHash", 16);
|
"ZcashPrevoutHash", 16);
|
||||||
hasher_InitParam(&tx_info->hasher_sequence, HASHER_BLAKE2B_PERSONAL,
|
hasher_InitParam(&tx_info->hasher_sequences, HASHER_BLAKE2B_PERSONAL,
|
||||||
"ZcashSequencHash", 16);
|
"ZcashSequencHash", 16);
|
||||||
hasher_InitParam(&tx_info->hasher_outputs, HASHER_BLAKE2B_PERSONAL,
|
hasher_InitParam(&tx_info->hasher_outputs, HASHER_BLAKE2B_PERSONAL,
|
||||||
"ZcashOutputsHash", 16);
|
"ZcashOutputsHash", 16);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// BIP-143
|
// BIP-143/BIP-341
|
||||||
hasher_Init(&tx_info->hasher_prevouts, coin->curve->hasher_sign);
|
hasher_Init(&tx_info->hasher_prevouts, HASHER_SHA2);
|
||||||
hasher_Init(&tx_info->hasher_sequence, coin->curve->hasher_sign);
|
hasher_Init(&tx_info->hasher_amounts, HASHER_SHA2);
|
||||||
hasher_Init(&tx_info->hasher_outputs, coin->curve->hasher_sign);
|
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;
|
return true;
|
||||||
@ -901,7 +910,7 @@ void signing_init(const SignTx *msg, const CoinInfo *_coin,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hasher_Init(&hasher_check, coin->curve->hasher_sign);
|
hasher_Init(&hasher_check, HASHER_SHA2);
|
||||||
|
|
||||||
layoutProgressSwipe(_("Signing transaction"), 0);
|
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;
|
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_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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tx_info_add_output(TxInfo *tx_info,
|
static bool tx_info_add_output(TxInfo *tx_info,
|
||||||
const TxOutputBinType *tx_bin_output) {
|
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);
|
tx_output_hash(&tx_info->hasher_outputs, tx_bin_output, coin->decred);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tx_info_finish(TxInfo *tx_info) {
|
static void tx_info_finish(TxInfo *tx_info) {
|
||||||
hasher_Final(&tx_info->hasher_prevouts, tx_info->hash_prevouts);
|
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);
|
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) {
|
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)) {
|
if (!tx_info_add_input(&info, txinput)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1301,7 +1331,7 @@ static bool signing_check_output(TxOutputType *txoutput) {
|
|||||||
tx_serialize_output_hash(&ti, &bin_output);
|
tx_serialize_output_hash(&ti, &bin_output);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Add output to BIP143 computation.
|
// Add output to BIP-143/BIP-341 computation.
|
||||||
return tx_info_add_output(&info, &bin_output);
|
return tx_info_add_output(&info, &bin_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1361,7 +1391,7 @@ static bool signing_check_orig_input(TxInputType *orig_input) {
|
|||||||
return false;
|
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)) {
|
if (!tx_info_add_input(&orig_info, orig_input)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1429,7 +1459,7 @@ static bool signing_check_orig_output(TxOutputType *orig_output) {
|
|||||||
return false;
|
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)) {
|
if (!tx_info_add_output(&orig_info, &orig_bin_output)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1653,9 +1683,9 @@ static void signing_hash_bip143(const TxInfo *tx_info,
|
|||||||
// nVersion
|
// nVersion
|
||||||
hasher_Update(&hasher_preimage, (const uint8_t *)&tx_info->version, 4);
|
hasher_Update(&hasher_preimage, (const uint8_t *)&tx_info->version, 4);
|
||||||
// hashPrevouts
|
// hashPrevouts
|
||||||
hasher_Update(&hasher_preimage, tx_info->hash_prevouts, 32);
|
hasher_Update(&hasher_preimage, tx_info->hash_prevouts143, 32);
|
||||||
// hashSequence
|
// hashSequence
|
||||||
hasher_Update(&hasher_preimage, tx_info->hash_sequence, 32);
|
hasher_Update(&hasher_preimage, tx_info->hash_sequence143, 32);
|
||||||
// outpoint
|
// outpoint
|
||||||
tx_prevout_hash(&hasher_preimage, txinput);
|
tx_prevout_hash(&hasher_preimage, txinput);
|
||||||
// scriptCode
|
// scriptCode
|
||||||
@ -1666,7 +1696,7 @@ static void signing_hash_bip143(const TxInfo *tx_info,
|
|||||||
// nSequence
|
// nSequence
|
||||||
tx_sequence_hash(&hasher_preimage, txinput);
|
tx_sequence_hash(&hasher_preimage, txinput);
|
||||||
// hashOutputs
|
// hashOutputs
|
||||||
hasher_Update(&hasher_preimage, tx_info->hash_outputs, 32);
|
hasher_Update(&hasher_preimage, tx_info->hash_outputs143, 32);
|
||||||
// nLockTime
|
// nLockTime
|
||||||
hasher_Update(&hasher_preimage, (const uint8_t *)&tx_info->lock_time, 4);
|
hasher_Update(&hasher_preimage, (const uint8_t *)&tx_info->lock_time, 4);
|
||||||
// nHashType
|
// nHashType
|
||||||
@ -1675,6 +1705,37 @@ static void signing_hash_bip143(const TxInfo *tx_info,
|
|||||||
hasher_Final(&hasher_preimage, hash);
|
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
|
#if !BITCOIN_ONLY
|
||||||
static void signing_hash_zip243(const TxInfo *tx_info,
|
static void signing_hash_zip243(const TxInfo *tx_info,
|
||||||
const TxInputType *txinput, uint8_t *hash) {
|
const TxInputType *txinput, uint8_t *hash) {
|
||||||
@ -1695,7 +1756,7 @@ static void signing_hash_zip243(const TxInfo *tx_info,
|
|||||||
// 3. hashPrevouts
|
// 3. hashPrevouts
|
||||||
hasher_Update(&hasher_preimage, tx_info->hash_prevouts, 32);
|
hasher_Update(&hasher_preimage, tx_info->hash_prevouts, 32);
|
||||||
// 4. hashSequence
|
// 4. hashSequence
|
||||||
hasher_Update(&hasher_preimage, tx_info->hash_sequence, 32);
|
hasher_Update(&hasher_preimage, tx_info->hash_sequences, 32);
|
||||||
// 5. hashOutputs
|
// 5. hashOutputs
|
||||||
hasher_Update(&hasher_preimage, tx_info->hash_outputs, 32);
|
hasher_Update(&hasher_preimage, tx_info->hash_outputs, 32);
|
||||||
// 6. hashJoinSplits
|
// 6. hashJoinSplits
|
||||||
|
@ -489,6 +489,11 @@ uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input) {
|
|||||||
return 36;
|
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) {
|
uint32_t tx_script_hash(Hasher *hasher, uint32_t size, const uint8_t *data) {
|
||||||
int r = ser_length_hash(hasher, size);
|
int r = ser_length_hash(hasher, size);
|
||||||
hasher_Update(hasher, data, 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);
|
void tx_input_check_hash(Hasher *hasher, const TxInputType *input);
|
||||||
uint32_t tx_prevout_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_script_hash(Hasher *hasher, uint32_t size, const uint8_t *data);
|
||||||
uint32_t tx_sequence_hash(Hasher *hasher, const TxInputType *input);
|
uint32_t tx_sequence_hash(Hasher *hasher, const TxInputType *input);
|
||||||
uint32_t tx_output_hash(Hasher *hasher, const TxOutputBinType *output,
|
uint32_t tx_output_hash(Hasher *hasher, const TxOutputBinType *output,
|
||||||
|
Loading…
Reference in New Issue
Block a user