From d4cc4a48b87224ce5a0e9d4897ea722a9173af4d Mon Sep 17 00:00:00 2001 From: Peter Banik Date: Fri, 21 Apr 2017 12:51:13 +0200 Subject: [PATCH] Added altcoin support to GetPublicKey (#161) --- firmware/coins-gen.py | 6 ++++++ firmware/coins.c | 16 ++++++++-------- firmware/fsm.c | 5 ++++- firmware/protob/messages.options | 1 + firmware/protob/messages.pb.c | 4 +++- firmware/protob/messages.pb.h | 12 ++++++++---- 6 files changed, 30 insertions(+), 14 deletions(-) diff --git a/firmware/coins-gen.py b/firmware/coins-gen.py index d3109ec8d1..c7181d942e 100755 --- a/firmware/coins-gen.py +++ b/firmware/coins-gen.py @@ -30,6 +30,12 @@ for c in coins: 'true' if c['signed_message_header'] is not None else 'false', '"\\x%02x" "%s"' % (len(c['signed_message_header']), c['signed_message_header'].replace('\n', '\\n')) if c['signed_message_header'] is not None else 'NULL', + + 'true' if c['xpub_magic'] is not None else 'false', + '0x%s' % c['xpub_magic'] if c['xpub_magic'] is not None else '00000000', + + 'true' if c['xprv_magic'] is not None else 'false', + '0x%s' % c['xprv_magic'] if c['xprv_magic'] is not None else '00000000' ]) for j in range(len(fields[0])): diff --git a/firmware/coins.c b/firmware/coins.c index 094f2d5ed9..f26808e2bf 100644 --- a/firmware/coins.c +++ b/firmware/coins.c @@ -26,14 +26,14 @@ // filled CoinType Protobuf structure defined in https://github.com/trezor/trezor-common/blob/master/protob/types.proto#L133 // address types > 0xFF represent a two-byte prefix in big-endian order const CoinType coins[COINS_COUNT] = { - {true, "Bitcoin", true, "BTC", true, 0, true, 300000, true, 5, true, 6, true, 10, true, "\x18" "Bitcoin Signed Message:\n", }, - {true, "Testnet", true, "TEST", true, 111, true, 10000000, true, 196, true, 3, true, 40, true, "\x18" "Bitcoin Signed Message:\n", }, - {true, "Namecoin", true, "NMC", true, 52, true, 10000000, true, 5, false, 0, false, 0, true, "\x19" "Namecoin Signed Message:\n", }, - {true, "Litecoin", true, "LTC", true, 48, true, 1000000, true, 5, false, 0, false, 0, true, "\x19" "Litecoin Signed Message:\n", }, - {true, "Dogecoin", true, "DOGE", true, 30, true, 1000000000, true, 22, false, 0, false, 0, true, "\x19" "Dogecoin Signed Message:\n", }, - {true, "Dash", true, "DASH", true, 76, true, 100000, true, 16, false, 0, false, 0, true, "\x19" "DarkCoin Signed Message:\n", }, - {true, "Zcash", true, "ZEC", true, 7352, true, 1000000, true, 7357, false, 0, false, 0, true, "\x16" "Zcash Signed Message:\n", }, - {true, "Zcash Testnet", true, "TAZ", true, 7461, true, 10000000, true, 7354, false, 0, false, 0, true, "\x16" "Zcash Signed Message:\n", }, + {true, "Bitcoin", true, "BTC", true, 0, true, 300000, true, 5, true, 6, true, 10, true, "\x18" "Bitcoin Signed Message:\n", true, 0x0488b21e, true, 0x0488ade4, }, + {true, "Testnet", true, "TEST", true, 111, true, 10000000, true, 196, true, 3, true, 40, true, "\x18" "Bitcoin Signed Message:\n", true, 0x043587cf, true, 0x04358394, }, + {true, "Namecoin", true, "NMC", true, 52, true, 10000000, true, 5, false, 0, false, 0, true, "\x19" "Namecoin Signed Message:\n", true, 0x019da462, true, 0x019d9cfe, }, + {true, "Litecoin", true, "LTC", true, 48, true, 1000000, true, 5, false, 0, false, 0, true, "\x19" "Litecoin Signed Message:\n", true, 0x019da462, true, 0x019d9cfe, }, + {true, "Dogecoin", true, "DOGE", true, 30, true, 1000000000, true, 22, false, 0, false, 0, true, "\x19" "Dogecoin Signed Message:\n", true, 0x02facafd, true, 0x02fac398, }, + {true, "Dash", true, "DASH", true, 76, true, 100000, true, 16, false, 0, false, 0, true, "\x19" "DarkCoin Signed Message:\n", true, 0x02fe52cc, true, 0x02fe52f8, }, + {true, "Zcash", true, "ZEC", true, 7352, true, 1000000, true, 7357, false, 0, false, 0, true, "\x16" "Zcash Signed Message:\n", true, 0x0488b21e, true, 0x0488ade4, }, + {true, "Zcash Testnet", true, "TAZ", true, 7461, true, 10000000, true, 7354, false, 0, false, 0, true, "\x16" "Zcash Signed Message:\n", true, 0x043587cf, true, 0x04358394, }, }; const CoinType *coinByShortcut(const char *shortcut) diff --git a/firmware/fsm.c b/firmware/fsm.c index 3cea7f2331..0893d3f5bd 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -317,6 +317,9 @@ void fsm_msgGetPublicKey(GetPublicKey *msg) CHECK_PIN + const CoinType *coin = fsm_getCoin(msg->coin_name); + if (!coin) return; + const char *curve = SECP256K1_NAME; if (msg->has_ecdsa_curve_name) { curve = msg->ecdsa_curve_name; @@ -360,7 +363,7 @@ void fsm_msgGetPublicKey(GetPublicKey *msg) resp->node.public_key.bytes[0] = 0; } resp->has_xpub = true; - hdnode_serialize_public(node, fingerprint, resp->xpub, sizeof(resp->xpub)); + hdnode_serialize_public(node, fingerprint, resp->xpub, sizeof(resp->xpub), coin->xpub_magic); msg_write(MessageType_MessageType_PublicKey, resp); layoutHome(); } diff --git a/firmware/protob/messages.options b/firmware/protob/messages.options index 9164ce6dba..c0f88fc3ff 100644 --- a/firmware/protob/messages.options +++ b/firmware/protob/messages.options @@ -26,6 +26,7 @@ Entropy.entropy max_size:1024 GetPublicKey.address_n max_count:8 GetPublicKey.ecdsa_curve_name max_size:32 +GetPublicKey.coin_name max_size:17 PublicKey.xpub max_size:113 diff --git a/firmware/protob/messages.pb.c b/firmware/protob/messages.pb.c index 7011ece5d2..8e85255962 100644 --- a/firmware/protob/messages.pb.c +++ b/firmware/protob/messages.pb.c @@ -3,6 +3,7 @@ #include "messages.pb.h" +const char GetPublicKey_coin_name_default[17] = "Bitcoin"; const char GetAddress_coin_name_default[17] = "Bitcoin"; const InputScriptType GetAddress_script_type_default = InputScriptType_SPENDADDRESS; const char LoadDevice_language_default[17] = "english"; @@ -130,10 +131,11 @@ const pb_field_t Entropy_fields[2] = { PB_LAST_FIELD }; -const pb_field_t GetPublicKey_fields[4] = { +const pb_field_t GetPublicKey_fields[5] = { PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, GetPublicKey, address_n, address_n, 0), PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, GetPublicKey, ecdsa_curve_name, address_n, 0), PB_FIELD2( 3, BOOL , OPTIONAL, STATIC , OTHER, GetPublicKey, show_display, ecdsa_curve_name, 0), + PB_FIELD2( 4, STRING , OPTIONAL, STATIC , OTHER, GetPublicKey, coin_name, show_display, &GetPublicKey_coin_name_default), PB_LAST_FIELD }; diff --git a/firmware/protob/messages.pb.h b/firmware/protob/messages.pb.h index f5b5893b61..ced5e9b6e1 100644 --- a/firmware/protob/messages.pb.h +++ b/firmware/protob/messages.pb.h @@ -598,6 +598,8 @@ typedef struct _GetPublicKey { char ecdsa_curve_name[32]; bool has_show_display; bool show_display; + bool has_coin_name; + char coin_name[17]; } GetPublicKey; typedef struct _LoadDevice { @@ -831,6 +833,7 @@ typedef struct _WordRequest { } WordRequest; /* Default values for struct fields */ +extern const char GetPublicKey_coin_name_default[17]; extern const char GetAddress_coin_name_default[17]; extern const InputScriptType GetAddress_script_type_default; extern const char LoadDevice_language_default[17]; @@ -867,7 +870,7 @@ extern const uint32_t SimpleSignTx_lock_time_default; #define PassphraseAck_init_default {""} #define GetEntropy_init_default {0} #define Entropy_init_default {{0, {0}}} -#define GetPublicKey_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, 0} +#define GetPublicKey_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, 0, false, "Bitcoin"} #define PublicKey_init_default {HDNodeType_init_default, false, ""} #define GetAddress_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "Bitcoin", false, 0, false, MultisigRedeemScriptType_init_default, false, InputScriptType_SPENDADDRESS} #define EthereumGetAddress_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, 0} @@ -933,7 +936,7 @@ extern const uint32_t SimpleSignTx_lock_time_default; #define PassphraseAck_init_zero {""} #define GetEntropy_init_zero {0} #define Entropy_init_zero {{0, {0}}} -#define GetPublicKey_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, 0} +#define GetPublicKey_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, 0, false, ""} #define PublicKey_init_zero {HDNodeType_init_zero, false, ""} #define GetAddress_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, 0, false, MultisigRedeemScriptType_init_zero, false, (InputScriptType)0} #define EthereumGetAddress_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, 0} @@ -1090,6 +1093,7 @@ extern const uint32_t SimpleSignTx_lock_time_default; #define GetPublicKey_address_n_tag 1 #define GetPublicKey_ecdsa_curve_name_tag 2 #define GetPublicKey_show_display_tag 3 +#define GetPublicKey_coin_name_tag 4 #define LoadDevice_mnemonic_tag 1 #define LoadDevice_node_tag 2 #define LoadDevice_pin_tag 3 @@ -1178,7 +1182,7 @@ extern const pb_field_t PassphraseRequest_fields[1]; extern const pb_field_t PassphraseAck_fields[2]; extern const pb_field_t GetEntropy_fields[2]; extern const pb_field_t Entropy_fields[2]; -extern const pb_field_t GetPublicKey_fields[4]; +extern const pb_field_t GetPublicKey_fields[5]; extern const pb_field_t PublicKey_fields[3]; extern const pb_field_t GetAddress_fields[6]; extern const pb_field_t EthereumGetAddress_fields[3]; @@ -1246,7 +1250,7 @@ extern const pb_field_t DebugLinkFlashErase_fields[2]; #define PassphraseAck_size 53 #define GetEntropy_size 6 #define Entropy_size 1027 -#define GetPublicKey_size 84 +#define GetPublicKey_size 103 #define PublicKey_size (121 + HDNodeType_size) #define GetAddress_size (81 + MultisigRedeemScriptType_size) #define EthereumGetAddress_size 50