From 6e25e0b3634a7eda6f930cefbae2ddd142dfbd06 Mon Sep 17 00:00:00 2001 From: Saleem Rashid Date: Sat, 9 Dec 2017 18:28:53 +0000 Subject: [PATCH] coins: Use curve_info instead of HasherType --- firmware/coins-gen.py | 2 +- firmware/coins.c | 3 ++- firmware/coins.h | 3 ++- firmware/crypto.c | 12 ++++++------ firmware/signing.c | 16 ++++++++-------- firmware/transaction.c | 18 +++++++++--------- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/firmware/coins-gen.py b/firmware/coins-gen.py index c35e7f4..b4ccf5f 100755 --- a/firmware/coins-gen.py +++ b/firmware/coins-gen.py @@ -29,7 +29,7 @@ def get_fields(coin): '%d' % coin['forkid'] if coin['forkid'] else '0', '"%s"' % coin['bech32_prefix'] if coin.get('bech32_prefix') is not None else 'NULL', '0x%08x' % (0x80000000 + coin['bip44']), - 'HASHER_SHA2', + '&%s_info' % 'secp256k1', ] diff --git a/firmware/coins.c b/firmware/coins.c index ae057cf..94766a1 100644 --- a/firmware/coins.c +++ b/firmware/coins.c @@ -22,6 +22,7 @@ #include "address.h" #include "ecdsa.h" #include "base58.h" +#include "secp256k1.h" // filled CoinInfo structure defined in coins.h const CoinInfo coins[COINS_COUNT] = { @@ -63,7 +64,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->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + int len = base58_decode_check(addr, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); if (len >= 21) { return coinExtractAddressTypeRaw(coin, addr_raw, address_type); } diff --git a/firmware/coins.h b/firmware/coins.h index a9eb89f..9ee822a 100644 --- a/firmware/coins.h +++ b/firmware/coins.h @@ -23,6 +23,7 @@ #include #include +#include "bip32.h" #include "coins_count.h" #include "hasher.h" @@ -44,7 +45,7 @@ typedef struct _CoinInfo { uint32_t forkid; const char *bech32_prefix; uint32_t coin_type; - HasherType hasher_type; + const curve_info *curve; } CoinInfo; extern const CoinInfo coins[COINS_COUNT]; diff --git a/firmware/crypto.c b/firmware/crypto.c index 3eeba4a..2d12d9b 100644 --- a/firmware/crypto.c +++ b/firmware/crypto.c @@ -114,7 +114,7 @@ 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->hasher_type); + hasher_Init(&hasher, coin->curve->hasher_type); 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); @@ -178,8 +178,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->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); - ecdsa_get_address_raw(pubkey, coin->address_type, coin->hasher_type, recovered_raw); + 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); if (memcmp(recovered_raw, addr_raw, len) != 0 || len != address_prefix_bytes_len(coin->address_type) + 20) { return 2; @@ -187,8 +187,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->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); - ecdsa_get_address_segwit_p2sh_raw(pubkey, coin->address_type_p2sh, coin->hasher_type, recovered_raw); + 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); if (memcmp(recovered_raw, addr_raw, len) != 0 || len != address_prefix_bytes_len(coin->address_type_p2sh) + 20) { return 2; @@ -202,7 +202,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->hasher_type, addr_raw); + ecdsa_get_pubkeyhash(pubkey, coin->curve->hasher_type, 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 38f87eb..e31078b 100644 --- a/firmware/signing.c +++ b/firmware/signing.c @@ -424,7 +424,7 @@ bool compile_input_script_sig(TxInputType *tinput) tinput->script_sig.size = compile_script_multisig(&(tinput->multisig), tinput->script_sig.bytes); } else { // SPENDADDRESS uint8_t hash[20]; - ecdsa_get_pubkeyhash(node.public_key, coin->hasher_type, hash); + ecdsa_get_pubkeyhash(node.public_key, coin->curve->hasher_type, hash); tinput->script_sig.size = compile_script_sig(coin->address_type, hash, tinput->script_sig.bytes); } return tinput->script_sig.size > 0; @@ -463,11 +463,11 @@ 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, coin->hasher_type); + tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); // segwit hashes for hashPrevouts and hashSequence - hasher_Init(&hashers[0], coin->hasher_type); - hasher_Init(&hashers[1], coin->hasher_type); - hasher_Init(&hashers[2], coin->hasher_type); + hasher_Init(&hashers[0], coin->curve->hasher_type); + hasher_Init(&hashers[1], coin->curve->hasher_type); + hasher_Init(&hashers[2], coin->curve->hasher_type); layoutProgressSwipe(_("Signing transaction"), 0); @@ -883,7 +883,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->hasher_type); + tx_init(&tp, tx->inputs_cnt, tx->outputs_cnt, tx->version, tx->lock_time, tx->extra_data_len, coin->curve->hasher_type); progress_meta_step = progress_step / (tp.inputs_len + tp.outputs_len); idx2 = 0; if (tp.inputs_len > 0) { @@ -957,7 +957,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->hasher_type); + tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); hasher_Reset(&hashers[0]); } // check prevouts and script type @@ -1091,7 +1091,7 @@ void signing_txack(TransactionType *tx) tx->inputs[0].script_sig.bytes[1] = 0x00; // witness 0 script tx->inputs[0].script_sig.bytes[2] = 0x20; // push 32 bytes (digest) // compute digest of multisig script - if (!compile_script_multisig_hash(&tx->inputs[0].multisig, coin->hasher_type, tx->inputs[0].script_sig.bytes + 3)) { + if (!compile_script_multisig_hash(&tx->inputs[0].multisig, coin->curve->hasher_type, tx->inputs[0].script_sig.bytes + 3)) { fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input")); signing_abort(); return; diff --git a/firmware/transaction.c b/firmware/transaction.c index 9067bb9..2e8f246 100644 --- a/firmware/transaction.c +++ b/firmware/transaction.c @@ -97,7 +97,7 @@ bool compute_address(const CoinInfo *coin, if (cryptoMultisigPubkeyIndex(multisig, node->public_key) < 0) { return 0; } - if (compile_script_multisig_hash(multisig, coin->hasher_type, digest) == 0) { + if (compile_script_multisig_hash(multisig, coin->curve->hasher_type, digest) == 0) { return 0; } if (script_type == InputScriptType_SPENDWITNESS) { @@ -119,11 +119,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->hasher_type, raw, 34, digest); + hasher_Raw(coin->curve->hasher_type, 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->hasher_type, address, MAX_ADDR_SIZE)) { + if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) { return 0; } } else { @@ -131,7 +131,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->hasher_type, address, MAX_ADDR_SIZE)) { + if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) { return 0; } } @@ -140,7 +140,7 @@ bool compute_address(const CoinInfo *coin, if (!coin->has_segwit || !coin->bech32_prefix) { return 0; } - ecdsa_get_pubkeyhash(node->public_key, coin->hasher_type, digest); + ecdsa_get_pubkeyhash(node->public_key, coin->curve->hasher_type, digest); if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_0, digest, 20)) { return 0; } @@ -152,9 +152,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->hasher_type, address, MAX_ADDR_SIZE); + ecdsa_get_address_segwit_p2sh(node->public_key, coin->address_type_p2sh, coin->curve->hasher_type, address, MAX_ADDR_SIZE); } else { - ecdsa_get_address(node->public_key, coin->address_type, coin->hasher_type, address, MAX_ADDR_SIZE); + ecdsa_get_address(node->public_key, coin->address_type, coin->curve->hasher_type, address, MAX_ADDR_SIZE); } return 1; } @@ -219,7 +219,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->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + addr_raw_len = base58_decode_check(in->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); size_t prefix_len; if (coin->has_address_type // p2pkh && address_check_prefix(addr_raw, coin->address_type) @@ -639,7 +639,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->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + addr_raw_len = base58_decode_check(txoutput->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); if (coin->has_address_type && address_check_prefix(addr_raw, coin->address_type)) { output_script_size = TXSIZE_P2PKHASH;