From a8bc3cb6bd15a137c09fefcf56a94619e6d1d4ba Mon Sep 17 00:00:00 2001 From: Jochen Hoenicke Date: Tue, 31 Oct 2017 22:21:51 +0100 Subject: [PATCH] Remove add_hash_type fields. The 4 byte hash_type/forkid is part of the signed message, but not part of the transaction. Instead of hacking it into the transaction, add it after the transaction when computing the signature. --- firmware/signing.c | 8 +++++--- firmware/transaction.c | 19 +++---------------- firmware/transaction.h | 4 ++-- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/firmware/signing.c b/firmware/signing.c index b1077657ab..8f940df657 100644 --- a/firmware/signing.c +++ b/firmware/signing.c @@ -453,7 +453,7 @@ void signing_init(uint32_t _inputs_count, uint32_t _outputs_count, const CoinInf multisig_fp_mismatch = false; next_nonsegwit_input = 0xffffffff; - tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, false); + tx_init(&to, inputs_count, outputs_count, version, lock_time, 0); // segwit hashes for hashPrevouts and hashSequence sha256_Init(&hashers[0]); sha256_Init(&hashers[1]); @@ -700,6 +700,8 @@ static bool signing_sign_input(void) { return false; } + uint32_t hash_type = signing_hash_type(); + sha256_Update(&ti.ctx, (const uint8_t *)&hash_type, 4); tx_hash_final(&ti, hash, false); resp.has_serialized = true; if (!signing_sign_hash(&input, privkey, pubkey, hash)) @@ -867,7 +869,7 @@ void signing_txack(TransactionType *tx) } return; case STAGE_REQUEST_2_PREV_META: - tx_init(&tp, tx->inputs_cnt, tx->outputs_cnt, tx->version, tx->lock_time, tx->extra_data_len, false); + tx_init(&tp, tx->inputs_cnt, tx->outputs_cnt, tx->version, tx->lock_time, tx->extra_data_len); progress_meta_step = progress_step / (tp.inputs_len + tp.outputs_len); idx2 = 0; if (tp.inputs_len > 0) { @@ -940,7 +942,7 @@ void signing_txack(TransactionType *tx) case STAGE_REQUEST_4_INPUT: progress = 500 + ((signatures * progress_step + idx2 * progress_meta_step) >> PROGRESS_PRECISION); if (idx2 == 0) { - tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, true); + tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0); sha256_Init(&hashers[0]); } // check prevouts and script type diff --git a/firmware/transaction.c b/firmware/transaction.c index 39ada73bc8..965e9cffbf 100644 --- a/firmware/transaction.c +++ b/firmware/transaction.c @@ -455,25 +455,13 @@ uint32_t tx_serialize_middle_hash(TxStruct *tx) uint32_t tx_serialize_footer(TxStruct *tx, uint8_t *out) { memcpy(out, &(tx->lock_time), 4); - if (tx->add_hash_type) { - uint32_t ht = 1; - memcpy(out + 4, &ht, 4); - return 8; - } else { - return 4; - } + return 4; } uint32_t tx_serialize_footer_hash(TxStruct *tx) { sha256_Update(&(tx->ctx), (const uint8_t *)&(tx->lock_time), 4); - if (tx->add_hash_type) { - uint32_t ht = 1; - sha256_Update(&(tx->ctx), (const uint8_t *)&ht, 4); - return 8; - } else { - return 4; - } + return 4; } uint32_t tx_serialize_output(TxStruct *tx, const TxOutputBinType *output, uint8_t *out) @@ -545,13 +533,12 @@ uint32_t tx_serialize_extra_data_hash(TxStruct *tx, const uint8_t *data, uint32_ return datalen; } -void tx_init(TxStruct *tx, uint32_t inputs_len, uint32_t outputs_len, uint32_t version, uint32_t lock_time, uint32_t extra_data_len, bool add_hash_type) +void tx_init(TxStruct *tx, uint32_t inputs_len, uint32_t outputs_len, uint32_t version, uint32_t lock_time, uint32_t extra_data_len) { tx->inputs_len = inputs_len; tx->outputs_len = outputs_len; tx->version = version; tx->lock_time = lock_time; - tx->add_hash_type = add_hash_type; tx->have_inputs = 0; tx->have_outputs = 0; tx->extra_data_len = extra_data_len; diff --git a/firmware/transaction.h b/firmware/transaction.h index 34654e1516..f5e4ee30d4 100644 --- a/firmware/transaction.h +++ b/firmware/transaction.h @@ -33,7 +33,7 @@ typedef struct { uint32_t version; uint32_t lock_time; - bool add_hash_type, is_segwit; + bool is_segwit; uint32_t have_inputs; uint32_t have_outputs; @@ -64,7 +64,7 @@ uint32_t tx_serialize_footer(TxStruct *tx, uint8_t *out); uint32_t tx_serialize_input(TxStruct *tx, const TxInputType *input, uint8_t *out); uint32_t tx_serialize_output(TxStruct *tx, const TxOutputBinType *output, uint8_t *out); -void tx_init(TxStruct *tx, uint32_t inputs_len, uint32_t outputs_len, uint32_t version, uint32_t lock_time, uint32_t extra_data_len, bool add_hash_type); +void tx_init(TxStruct *tx, uint32_t inputs_len, uint32_t outputs_len, uint32_t version, uint32_t lock_time, uint32_t extra_data_len); uint32_t tx_serialize_header_hash(TxStruct *tx); uint32_t tx_serialize_input_hash(TxStruct *tx, const TxInputType *input); uint32_t tx_serialize_output_hash(TxStruct *tx, const TxOutputBinType *output);