diff --git a/firmware/coins.c b/firmware/coins.c index 1600f9acb..1acd8f522 100644 --- a/firmware/coins.c +++ b/firmware/coins.c @@ -58,7 +58,7 @@ bool coinExtractAddressType(const CoinInfo *coin, const char *addr, uint32_t *ad { if (!addr) return false; uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; - int len = base58_decode_check(addr, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + int len = base58_decode_check(addr, coin->curve->hasher_base58, addr_raw, MAX_ADDR_RAW_SIZE); if (len >= 21) { return coinExtractAddressTypeRaw(coin, addr_raw, address_type); } diff --git a/firmware/crypto.c b/firmware/crypto.c index 4ff322c25..2830f7b01 100644 --- a/firmware/crypto.c +++ b/firmware/crypto.c @@ -92,7 +92,7 @@ uint32_t deser_length(const uint8_t *in, uint32_t *out) int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature) { signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes - return hdnode_sign(node, message, message_len, signature + 1, NULL, NULL); + return hdnode_sign(node, message, message_len, HASHER_SHA2, signature + 1, NULL, NULL); } int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature) @@ -101,7 +101,7 @@ int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uin const curve_info *ed25519_curve_info = get_curve_by_name(ED25519_NAME); if (ed25519_curve_info && node->curve == ed25519_curve_info) { // GPG supports variable size digest for Ed25519 signatures - return hdnode_sign(node, message, message_len, signature + 1, NULL, NULL); + return hdnode_sign(node, message, message_len, 0, signature + 1, NULL, NULL); } else { // Ensure 256-bit digest before proceeding if (message_len != 32) { @@ -113,13 +113,13 @@ int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uin static void cryptoMessageHash(const CoinInfo *coin, const uint8_t *message, size_t message_len, uint8_t hash[HASHER_DIGEST_LENGTH]) { Hasher hasher; - hasher_Init(&hasher, coin->curve->hasher_type); + hasher_Init(&hasher, coin->curve->hasher_sign); hasher_Update(&hasher, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header)); uint8_t varint[5]; uint32_t l = ser_length(message_len, varint); hasher_Update(&hasher, varint, l); hasher_Update(&hasher, message, message_len); - hasher_Double(&hasher, hash); + hasher_Final(&hasher, hash); } int cryptoMessageSign(const CoinInfo *coin, HDNode *node, InputScriptType script_type, const uint8_t *message, size_t message_len, uint8_t *signature) @@ -177,8 +177,8 @@ int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t mes // p2pkh if (signature[0] >= 27 && signature[0] <= 34) { - size_t len = base58_decode_check(address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); - ecdsa_get_address_raw(pubkey, coin->address_type, coin->curve->hasher_type, recovered_raw); + size_t len = base58_decode_check(address, coin->curve->hasher_base58, addr_raw, MAX_ADDR_RAW_SIZE); + ecdsa_get_address_raw(pubkey, coin->address_type, coin->curve->hasher_pubkey, recovered_raw); if (memcmp(recovered_raw, addr_raw, len) != 0 || len != address_prefix_bytes_len(coin->address_type) + 20) { return 2; @@ -186,8 +186,8 @@ int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t mes } else // segwit-in-p2sh if (signature[0] >= 35 && signature[0] <= 38) { - size_t len = base58_decode_check(address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); - ecdsa_get_address_segwit_p2sh_raw(pubkey, coin->address_type_p2sh, coin->curve->hasher_type, recovered_raw); + size_t len = base58_decode_check(address, coin->curve->hasher_base58, addr_raw, MAX_ADDR_RAW_SIZE); + ecdsa_get_address_segwit_p2sh_raw(pubkey, coin->address_type_p2sh, coin->curve->hasher_pubkey, recovered_raw); if (memcmp(recovered_raw, addr_raw, len) != 0 || len != address_prefix_bytes_len(coin->address_type_p2sh) + 20) { return 2; @@ -201,7 +201,7 @@ int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t mes || !segwit_addr_decode(&witver, recovered_raw, &len, coin->bech32_prefix, address)) { return 4; } - ecdsa_get_pubkeyhash(pubkey, coin->curve->hasher_type, addr_raw); + ecdsa_get_pubkeyhash(pubkey, coin->curve->hasher_pubkey, addr_raw); if (memcmp(recovered_raw, addr_raw, len) != 0 || witver != 0 || len != 20) { return 2; diff --git a/firmware/signing.c b/firmware/signing.c index bf5d87e0c..8b34e10b8 100644 --- a/firmware/signing.c +++ b/firmware/signing.c @@ -362,8 +362,8 @@ void phase1_request_next_input(void) send_req_1_input(); } else { // compute segwit hashPrevouts & hashSequence - hasher_Double(&hashers[0], hash_prevouts); - hasher_Double(&hashers[1], hash_sequence); + hasher_Final(&hashers[0], hash_prevouts); + hasher_Final(&hashers[1], hash_sequence); hasher_Final(&hashers[2], hash_check); // init hashOutputs hasher_Reset(&hashers[0]); @@ -463,7 +463,7 @@ bool compile_input_script_sig(TxInputType *tinput) tinput->script_sig.size = compile_script_multisig(coin, &(tinput->multisig), tinput->script_sig.bytes); } else { // SPENDADDRESS uint8_t hash[20]; - ecdsa_get_pubkeyhash(node.public_key, coin->curve->hasher_type, hash); + ecdsa_get_pubkeyhash(node.public_key, coin->curve->hasher_pubkey, hash); tinput->script_sig.size = compile_script_sig(coin->address_type, hash, tinput->script_sig.bytes); } return tinput->script_sig.size > 0; @@ -506,23 +506,23 @@ void signing_init(const SignTx *msg, const CoinInfo *_coin, const HDNode *_root) multisig_fp_mismatch = false; next_nonsegwit_input = 0xffffffff; - tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); + tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_sign); if (coin->decred) { to.version |= (DECRED_SERIALIZE_FULL << 16); to.is_decred = true; to.decred_expiry = msg->decred_expiry; - tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); + tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_sign); ti.version |= (DECRED_SERIALIZE_NO_WITNESS << 16); ti.is_decred = true; ti.decred_expiry = msg->decred_expiry; } // segwit hashes for hashPrevouts and hashSequence - hasher_Init(&hashers[0], coin->curve->hasher_type); - hasher_Init(&hashers[1], coin->curve->hasher_type); - hasher_Init(&hashers[2], coin->curve->hasher_type); + hasher_Init(&hashers[0], coin->curve->hasher_sign); + hasher_Init(&hashers[1], coin->curve->hasher_sign); + hasher_Init(&hashers[2], coin->curve->hasher_sign); layoutProgressSwipe(_("Signing transaction"), 0); @@ -718,7 +718,7 @@ static void phase1_request_next_output(void) { // compute Decred hashPrefix tx_hash_final(&ti, hash_prefix, false); } - hasher_Double(&hashers[0], hash_outputs); + hasher_Final(&hashers[0], hash_outputs); if (!signing_check_fee()) { return; } @@ -748,7 +748,7 @@ static void signing_hash_bip143(const TxInputType *txinput, uint8_t *hash) { hasher_Update(&hashers[0], hash_outputs, 32); hasher_Update(&hashers[0], (const uint8_t*) &lock_time, 4); hasher_Update(&hashers[0], (const uint8_t*) &hash_type, 4); - hasher_Double(&hashers[0], hash); + hasher_Final(&hashers[0], hash); } static void signing_hash_decred(const uint8_t *hash_witness, uint8_t *hash) { @@ -797,7 +797,7 @@ static bool signing_sign_hash(TxInputType *txinput, const uint8_t* private_key, static bool signing_sign_input(void) { uint8_t hash[32]; - hasher_Double(&hashers[0], hash); + hasher_Final(&hashers[0], hash); if (memcmp(hash, hash_outputs, 32) != 0) { fsm_sendFailure(FailureType_Failure_DataError, _("Transaction has changed during signing")); signing_abort(); @@ -1000,7 +1000,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, coin->curve->hasher_type); + tx_init(&tp, tx->inputs_cnt, tx->outputs_cnt, tx->version, tx->lock_time, tx->extra_data_len, coin->curve->hasher_sign); if (coin->decred) { tp.version |= (DECRED_SERIALIZE_NO_WITNESS << 16); tp.is_decred = true; @@ -1084,7 +1084,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, coin->curve->hasher_type); + tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_sign); hasher_Reset(&hashers[0]); } // check prevouts and script type @@ -1279,12 +1279,12 @@ void signing_txack(TransactionType *tx) progress = 500 + ((signatures * progress_step + idx2 * progress_meta_step) >> PROGRESS_PRECISION); if (idx1 == 0) { // witness - tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); + tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_sign); to.is_decred = true; } // witness hash - tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); + tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_sign); ti.version |= (DECRED_SERIALIZE_WITNESS_SIGNING << 16); ti.is_decred = true; if (!compile_input_script_sig(&tx->inputs[0])) { diff --git a/firmware/transaction.c b/firmware/transaction.c index 1237da7d0..5a544a927 100644 --- a/firmware/transaction.c +++ b/firmware/transaction.c @@ -131,11 +131,11 @@ bool compute_address(const CoinInfo *coin, raw[0] = 0; // push version raw[1] = 32; // push 32 bytes memcpy(raw+2, digest, 32); // push hash - hasher_Raw(coin->curve->hasher_type, raw, 34, digest); + hasher_Raw(coin->curve->hasher_pubkey, raw, 34, digest); prelen = address_prefix_bytes_len(coin->address_type_p2sh); address_write_prefix_bytes(coin->address_type_p2sh, raw); ripemd160(digest, 32, raw + prelen); - if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) { + if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_base58, address, MAX_ADDR_SIZE)) { return 0; } } else { @@ -143,7 +143,7 @@ bool compute_address(const CoinInfo *coin, prelen = address_prefix_bytes_len(coin->address_type_p2sh); address_write_prefix_bytes(coin->address_type_p2sh, raw); ripemd160(digest, 32, raw + prelen); - if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) { + if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_base58, address, MAX_ADDR_SIZE)) { return 0; } } @@ -152,7 +152,7 @@ bool compute_address(const CoinInfo *coin, if (!coin->has_segwit || !coin->bech32_prefix) { return 0; } - ecdsa_get_pubkeyhash(node->public_key, coin->curve->hasher_type, digest); + ecdsa_get_pubkeyhash(node->public_key, coin->curve->hasher_pubkey, digest); if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_0, digest, 20)) { return 0; } @@ -164,9 +164,9 @@ bool compute_address(const CoinInfo *coin, if (!coin->has_address_type_p2sh) { return 0; } - ecdsa_get_address_segwit_p2sh(node->public_key, coin->address_type_p2sh, coin->curve->hasher_type, address, MAX_ADDR_SIZE); + ecdsa_get_address_segwit_p2sh(node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey, coin->curve->hasher_base58, address, MAX_ADDR_SIZE); } else { - ecdsa_get_address(node->public_key, coin->address_type, coin->curve->hasher_type, address, MAX_ADDR_SIZE); + ecdsa_get_address(node->public_key, coin->address_type, coin->curve->hasher_pubkey, coin->curve->hasher_base58, address, MAX_ADDR_SIZE); } return 1; } @@ -232,7 +232,7 @@ int compile_output(const CoinInfo *coin, const HDNode *root, TxOutputType *in, T return 0; // failed to compile output } - addr_raw_len = base58_decode_check(in->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + addr_raw_len = base58_decode_check(in->address, coin->curve->hasher_base58, addr_raw, MAX_ADDR_RAW_SIZE); size_t prefix_len; if (coin->has_address_type // p2pkh && addr_raw_len == 20 + (prefix_len = address_prefix_bytes_len(coin->address_type)) @@ -327,7 +327,7 @@ uint32_t compile_script_multisig_hash(const CoinInfo *coin, const MultisigRedeem if (n < 1 || n > 15) return 0; Hasher hasher; - hasher_Init(&hasher, coin->curve->hasher_type); + hasher_Init(&hasher, coin->curve->hasher_pubkey); uint8_t d[2]; d[0] = 0x50 + m; hasher_Update(&hasher, d, 1); @@ -650,7 +650,7 @@ 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, HasherType hasher_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, HasherType hasher_sign) { tx->inputs_len = inputs_len; tx->outputs_len = outputs_len; @@ -664,16 +664,12 @@ void tx_init(TxStruct *tx, uint32_t inputs_len, uint32_t outputs_len, uint32_t v tx->is_segwit = false; tx->is_decred = false; tx->decred_expiry = 0; - hasher_Init(&(tx->hasher), hasher_type); + hasher_Init(&(tx->hasher), hasher_sign); } void tx_hash_final(TxStruct *t, uint8_t *hash, bool reverse) { - if (t->is_decred) { - hasher_Final(&(t->hasher), hash); - } else { - hasher_Double(&(t->hasher), hash); - } + hasher_Final(&(t->hasher), hash); if (!reverse) return; for (uint8_t i = 0; i < 16; i++) { uint8_t k = hash[31 - i]; @@ -744,7 +740,7 @@ uint32_t tx_output_weight(const CoinInfo *coin, const TxOutputType *txoutput) { && segwit_addr_decode(&witver, addr_raw, &addr_raw_len, coin->bech32_prefix, txoutput->address)) { output_script_size = 2 + addr_raw_len; } else { - addr_raw_len = base58_decode_check(txoutput->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + addr_raw_len = base58_decode_check(txoutput->address, coin->curve->hasher_base58, addr_raw, MAX_ADDR_RAW_SIZE); if (coin->has_address_type && address_check_prefix(addr_raw, coin->address_type)) { output_script_size = TXSIZE_P2PKHASH; diff --git a/firmware/transaction.h b/firmware/transaction.h index 8177a9655..4363a3b2c 100644 --- a/firmware/transaction.h +++ b/firmware/transaction.h @@ -68,7 +68,7 @@ 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); uint32_t tx_serialize_decred_witness(TxStruct *tx, const TxInputType *input, 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, HasherType hasher_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, HasherType hasher_sign); 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); diff --git a/vendor/trezor-crypto b/vendor/trezor-crypto index bb4c3d052..b9043659c 160000 --- a/vendor/trezor-crypto +++ b/vendor/trezor-crypto @@ -1 +1 @@ -Subproject commit bb4c3d052561bd31856a03d975ca226571f6a893 +Subproject commit b9043659c5c91180c4abfb3ebb603f7b0385f201