From f34fba7020e883dbc0cb0cc5764c5a677c4e5441 Mon Sep 17 00:00:00 2001 From: Struan Clark Date: Sat, 4 Mar 2023 00:51:51 -0700 Subject: [PATCH 1/5] adding magic number comments --- views/flipbip_scene_1.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/views/flipbip_scene_1.c b/views/flipbip_scene_1.c index 44bfdd8515e..c2d59734cab 100644 --- a/views/flipbip_scene_1.c +++ b/views/flipbip_scene_1.c @@ -264,6 +264,12 @@ static void flipbip_scene_1_model_init(FlipBipScene1Model* const model, const in // constants for Bitcoin const uint32_t version_public = 0x0488b21e; const uint32_t version_private = 0x0488ade4; + // "xprv_magic": 76066276, + // "xpub_magic": 76067358, + // "xpub_magic_segwit_p2sh": 77429938, + // "xpub_magic_segwit_native": 78792518, + // "xpub_magic_multisig_segwit_p2sh": 43365439, + // "xpub_magic_multisig_segwit_native": 44728019, // buffer for key serialization const size_t buflen = 128; From a978a3761dafd7a7d13067f85c2938ad01fc0c65 Mon Sep 17 00:00:00 2001 From: xtruan Date: Sat, 4 Mar 2023 10:00:02 -0800 Subject: [PATCH 2/5] move eth address hashing to heap --- crypto/bip32.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crypto/bip32.c b/crypto/bip32.c index 09723d9fd5e..b8a787e2378 100644 --- a/crypto/bip32.c +++ b/crypto/bip32.c @@ -507,7 +507,9 @@ int hdnode_fill_public_key(HDNode *node) { #if USE_ETHEREUM int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) { uint8_t buf[65] = {0}; - SHA3_CTX ctx = {0}; + //SHA3_CTX ctx = {0}; + SHA3_CTX *ctx = malloc(sizeof(SHA3_CTX)); + memzero(ctx, sizeof(SHA3_CTX)); /* get uncompressed public key */ if (ecdsa_get_public_key65(node->curve->params, node->private_key, buf) != @@ -516,9 +518,12 @@ int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) { } /* compute sha3 of x and y coordinate without 04 prefix */ - sha3_256_Init(&ctx); - sha3_Update(&ctx, buf + 1, 64); - keccak_Final(&ctx, buf); + sha3_256_Init(ctx); + sha3_Update(ctx, buf + 1, 64); + keccak_Final(ctx, buf); + + memzero(ctx, sizeof(SHA3_CTX)); + free(ctx); /* result are the least significant 160 bits */ memcpy(pubkeyhash, buf + 12, 20); From 95455c3ae1b152b99925f0fd57c610ef880d3a18 Mon Sep 17 00:00:00 2001 From: xtruan Date: Sat, 4 Mar 2023 10:58:30 -0800 Subject: [PATCH 3/5] eth compatibility! --- crypto/options.h | 4 +- flipbip.c | 3 +- flipbip.h | 12 ++-- scenes/flipbip_scene_menu.c | 7 +- scenes/flipbip_scene_settings.c | 56 +++++++-------- views/flipbip_scene_1.c | 117 +++++++++++++++++--------------- 6 files changed, 108 insertions(+), 91 deletions(-) diff --git a/crypto/options.h b/crypto/options.h index 1fa49c94381..f0edcc60f2a 100644 --- a/crypto/options.h +++ b/crypto/options.h @@ -63,7 +63,7 @@ // support Ethereum operations #ifndef USE_ETHEREUM -#define USE_ETHEREUM 0 +#define USE_ETHEREUM 1 #endif // support NEM operations @@ -83,7 +83,7 @@ // support Keccak hashing #ifndef USE_KECCAK -#define USE_KECCAK 0 +#define USE_KECCAK 1 #endif // add way how to mark confidential data diff --git a/flipbip.c b/flipbip.c index 888d1060dbf..43447de1042 100644 --- a/flipbip.c +++ b/flipbip.c @@ -38,10 +38,11 @@ FlipBip* flipbip_app_alloc() { view_dispatcher_set_custom_event_callback(app->view_dispatcher, flipbip_custom_event_callback); app->submenu = submenu_alloc(); + // Settings app->haptic = 1; - //app->speaker = 1; app->led = 1; app->bip39_strength = 2; // 256 bits (24 words) + app->bip44_coin = 0; // 0 (BTC) view_dispatcher_add_view(app->view_dispatcher, FlipBipViewIdMenu, submenu_get_view(app->submenu)); app->flipbip_startscreen = flipbip_startscreen_alloc(); diff --git a/flipbip.h b/flipbip.h index 805270d4895..42a49d8fa12 100644 --- a/flipbip.h +++ b/flipbip.h @@ -26,9 +26,9 @@ typedef struct { FlipBipScene1* flipbip_scene_1; // FlipBipScene2* flipbip_scene_2; int haptic; - // int speaker; int led; int bip39_strength; + int bip44_coin; } FlipBip; typedef enum { @@ -44,11 +44,6 @@ typedef enum { FlipBipHapticOn, } FlipBipHapticState; -// typedef enum { -// FlipBipSpeakerOff, -// FlipBipSpeakerOn, -// } FlipBipSpeakerState; - typedef enum { FlipBipLedOff, FlipBipLedOn, @@ -59,3 +54,8 @@ typedef enum { FlipBipStrength192, FlipBipStrength256, } FlipBipStrengthState; + +typedef enum { + FlipBipCoinBTC0, + FlipBipCoinETH60, +} FlipBipCoinState; diff --git a/scenes/flipbip_scene_menu.c b/scenes/flipbip_scene_menu.c index 25b6fa28dbd..98d073bad8a 100644 --- a/scenes/flipbip_scene_menu.c +++ b/scenes/flipbip_scene_menu.c @@ -14,7 +14,12 @@ void flipbip_scene_menu_submenu_callback(void* context, uint32_t index) { void flipbip_scene_menu_on_enter(void* context) { FlipBip* app = context; - submenu_add_item(app->submenu, "Generate wallet", SubmenuIndexScene1, flipbip_scene_menu_submenu_callback, app); + if (app->bip44_coin == FlipBipCoinBTC0) { // BTC + submenu_add_item(app->submenu, "Generate BTC wallet", SubmenuIndexScene1, flipbip_scene_menu_submenu_callback, app); + } + if (app->bip44_coin == FlipBipCoinETH60) { // ETH + submenu_add_item(app->submenu, "Generate ETH wallet", SubmenuIndexScene1, flipbip_scene_menu_submenu_callback, app); + } //submenu_add_item(app->submenu, "Scene 2", SubmenuIndexScene2, flipbip_scene_menu_submenu_callback, app); submenu_add_item(app->submenu, "Settings", SubmenuIndexSettings, flipbip_scene_menu_submenu_callback, app); diff --git a/scenes/flipbip_scene_settings.c b/scenes/flipbip_scene_settings.c index fa774046698..d65cf5f48d0 100644 --- a/scenes/flipbip_scene_settings.c +++ b/scenes/flipbip_scene_settings.c @@ -3,9 +3,9 @@ // enum SettingsIndex { // SettingsIndexBip39Strength = 10, +// SettingsIndexBip44Coin, // SettingsIndexHaptic, // SettingsIndexValue1, -// SettingsIndexValue2, // }; const char* const haptic_text[2] = { @@ -17,15 +17,6 @@ const uint32_t haptic_value[2] = { FlipBipHapticOn, }; -// const char* const speaker_text[2] = { -// "OFF", -// "ON", -// }; -// const uint32_t speaker_value[2] = { -// FlipBipSpeakerOff, -// FlipBipSpeakerOn, -// }; - const char* const led_text[2] = { "OFF", "ON", @@ -46,6 +37,15 @@ const uint32_t bip39_strength_value[3] = { FlipBipStrength256, }; +const char* const bip44_coin_text[2] = { + "BTC", + "ETH", +}; +const uint32_t bip44_coin_value[2] = { + FlipBipCoinBTC0, + FlipBipCoinETH60, +}; + static void flipbip_scene_settings_set_haptic(VariableItem* item) { FlipBip* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); @@ -53,13 +53,6 @@ static void flipbip_scene_settings_set_haptic(VariableItem* item) { app->haptic = haptic_value[index]; } -// static void flipbip_scene_settings_set_speaker(VariableItem* item) { -// FlipBip* app = variable_item_get_context(item); -// uint8_t index = variable_item_get_current_value_index(item); -// variable_item_set_current_value_text(item, speaker_text[index]); -// app->speaker = speaker_value[index]; -// } - static void flipbip_scene_settings_set_led(VariableItem* item) { FlipBip* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); @@ -74,6 +67,13 @@ static void flipbip_scene_settings_set_bip39_strength(VariableItem* item) { app->bip39_strength = bip39_strength_value[index]; } +static void flipbip_scene_settings_set_bip44_coin(VariableItem* item) { + FlipBip* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, bip44_coin_text[index]); + app->bip44_coin = bip44_coin_value[index]; +} + void flipbip_scene_settings_submenu_callback(void* context, uint32_t index) { FlipBip* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, index); @@ -95,6 +95,17 @@ void flipbip_scene_settings_on_enter(void* context) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, bip39_strength_text[value_index]); + // BIP44 Coin + item = variable_item_list_add( + app->variable_item_list, + "BIP44 Coin:", + 2, + flipbip_scene_settings_set_bip44_coin, + app); + value_index = value_index_uint32(app->bip44_coin, bip44_coin_value, 2); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, bip44_coin_text[value_index]); + // Vibro on/off item = variable_item_list_add( app->variable_item_list, @@ -106,17 +117,6 @@ void flipbip_scene_settings_on_enter(void* context) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, haptic_text[value_index]); - // // Sound on/off - // item = variable_item_list_add( - // app->variable_item_list, - // "Sound:", - // 2, - // flipbip_scene_settings_set_speaker, - // app); - // value_index = value_index_uint32(app->speaker, speaker_value, 2); - // variable_item_set_current_value_index(item, value_index); - // variable_item_set_current_value_text(item, speaker_text[value_index]); - // LED Effects on/off item = variable_item_list_add( app->variable_item_list, diff --git a/views/flipbip_scene_1.c b/views/flipbip_scene_1.c index c2d59734cab..159761ff99e 100644 --- a/views/flipbip_scene_1.c +++ b/views/flipbip_scene_1.c @@ -26,6 +26,7 @@ struct FlipBipScene1 { typedef struct { int page; int strength; + uint32_t coin; CONFIDENTIAL const char* mnemonic; CONFIDENTIAL uint8_t seed[64]; CONFIDENTIAL const HDNode* node; @@ -133,11 +134,7 @@ static void flipbip_scene_1_draw_seed(FlipBipScene1Model* const model) { free(seed_working); } -static void flipbip_scene_1_draw_address(const HDNode* node, uint32_t addr_index) { - // Constants for Bitcoin address generation - const char addr_version = 0x00; - //const char wif_version = 0x80; - +static void flipbip_scene_1_draw_address(const HDNode* node, uint32_t addr_type, uint32_t addr_index) { // buffer for key serialization const size_t buflen = 128; char buf[128 + 1]; @@ -147,17 +144,36 @@ static void flipbip_scene_1_draw_address(const HDNode* node, uint32_t addr_index hdnode_private_ckd(addr_node, addr_index); hdnode_fill_public_key(addr_node); - ecdsa_get_address(addr_node->public_key, addr_version, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen); - - char *address = malloc(buflen + 1); - strncpy(address, buf, buflen); - flipbip_scene_1_draw_generic(address, 12); - memzero(address, buflen + 1); - free(address); - //ecdsa_get_wif(addr_node->private_key, wif_version, HASHER_SHA2D, buf, buflen); - //char *wif = malloc(buflen + 1); - //strncpy(wif, buf, buflen); + if (addr_type == 0) { // BTC + // BTC style address + const char addr_version = 0x00; + //const char wif_version = 0x80; + ecdsa_get_address(addr_node->public_key, addr_version, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen); + + char *address = malloc(buflen + 1); + strncpy(address, buf, buflen); + flipbip_scene_1_draw_generic(address, 12); + memzero(address, buflen + 1); + free(address); + + //ecdsa_get_wif(addr_node->private_key, wif_version, HASHER_SHA2D, buf, buflen); + //char *wif = malloc(buflen + 1); + //strncpy(wif, buf, buflen); + } else if (addr_type == 60) { // ETH + // ETH style address + hdnode_get_ethereum_pubkeyhash(addr_node, (uint8_t *)buf); + char *address = malloc(42 + 1); + memcpy(address, "0x", 2); + // Convert the hash to a hex string + for (size_t i = 0; i < 20; i++) { + //flipbip_itoa(buf[i], address + 2 + (i * 2), 42 + 1, 16); + sprintf(address + 2 + (i * 2), "%02x", buf[i]); + } + flipbip_scene_1_draw_generic(address, 12); + memzero(address, 42 + 1); + free(address); + } memzero(addr_node, sizeof(HDNode)); free(addr_node); @@ -209,20 +225,21 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { flipbip_scene_1_draw_generic(model->xpub_extended, 20); } else if (model->page >= 9 && model->page <= 13) { - flipbip_scene_1_draw_address(model->node, model->page - 9); + flipbip_scene_1_draw_address(model->node, model->coin, model->page - 9); } if (model->page == 0) { canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 1, 10, "Generating..."); - canvas_draw_str(canvas, 6, 30, "m/44'/0'/0'/0"); + canvas_draw_str(canvas, 6, 30, "m/44'/C'/0'/0"); } else if (model->page >= 9 && model->page <= 13) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 1, 2, AlignLeft, AlignTop, "Receive address:"); canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 1, 10, "Receive address:"); - - canvas_draw_str(canvas, 6, 30, s_disp_text1); - canvas_draw_str(canvas, 6, 42, s_disp_text2); - canvas_draw_str(canvas, 6, 54, s_disp_text3); + canvas_draw_str(canvas, 6, 22, s_disp_text1); + canvas_draw_str(canvas, 6, 34, s_disp_text2); + canvas_draw_str(canvas, 6, 46, s_disp_text3); + canvas_draw_str(canvas, 6, 58, s_disp_text4); } else { canvas_set_font(canvas, FontSecondary); @@ -233,13 +250,13 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { canvas_draw_str_aligned(canvas, 1, 42, AlignLeft, AlignTop, s_disp_text5); canvas_draw_str_aligned(canvas, 1, 52, AlignLeft, AlignTop, s_disp_text6); } - } -static void flipbip_scene_1_model_init(FlipBipScene1Model* const model, const int strength) { +static void flipbip_scene_1_model_init(FlipBipScene1Model* const model, const int strength, const uint32_t coin) { model->page = 0; + model->coin = coin; // Generate a random mnemonic using trezor-crypto model->strength = strength; @@ -255,13 +272,14 @@ static void flipbip_scene_1_model_init(FlipBipScene1Model* const model, const in HDNode *root = malloc(sizeof(HDNode)); hdnode_from_seed(model->seed, 64, SECP256K1_NAME, root); - // m/44'/0'/0'/0 - uint32_t purpose = 44; - uint32_t coin = 0; // Bitcoin - uint32_t account = 0; - uint32_t change = 0; + // m/44'/0'/0'/0 or m/44'/60'/0'/0 + const uint32_t purpose = 44; + //const uint32_t coin = 0; // BTC + //const uint32_t coin = 60; // ETH + const uint32_t account = 0; + const uint32_t change = 0; - // constants for Bitcoin + // constants for BTC / ETH const uint32_t version_public = 0x0488b21e; const uint32_t version_private = 0x0488ade4; // "xprv_magic": 76066276, @@ -288,11 +306,11 @@ static void flipbip_scene_1_model_init(FlipBipScene1Model* const model, const in fingerprint = hdnode_fingerprint(node); hdnode_private_ckd_prime(node, purpose); // purpose - // coin m/44'/0' + // coin m/44'/0' or m/44'/60' fingerprint = hdnode_fingerprint(node); - hdnode_private_ckd_prime(node, coin); // coin + hdnode_private_ckd_prime(node, model->coin); // coin - // account m/44'/0'/0' + // account m/44'/0'/0' or m/44'/60'/0' fingerprint = hdnode_fingerprint(node); hdnode_private_ckd_prime(node, account); // account @@ -306,7 +324,7 @@ static void flipbip_scene_1_model_init(FlipBipScene1Model* const model, const in strncpy(xpub_acc, buf, buflen); model->xpub_account = xpub_acc; - // external/internal (change) m/44'/0'/0'/0 + // external/internal (change) m/44'/0'/0'/0 or m/44'/60'/0'/0 fingerprint = hdnode_fingerprint(node); hdnode_private_ckd(node, change); // external/internal (change) @@ -391,6 +409,7 @@ void flipbip_scene_1_exit(void* context) { { model->page = 0; model->strength = 0; + model->coin = 0; for (int i = 0; i < 64; i++) { model->seed[i] = 0; } @@ -419,10 +438,17 @@ void flipbip_scene_1_enter(void* context) { FlipBipScene1* instance = (FlipBipScene1*)context; FlipBip* app = instance->context; + + // BIP39 Strength setting int strength_setting = app->bip39_strength; - int strength = 256; - if (strength_setting == 0) strength = 128; - else if (strength_setting == 1) strength = 192; + int strength = 256; // FlipBipStrength256 // 24 words (256 bit) + if (strength_setting == FlipBipStrength128) strength = 128; // 12 words (128 bit) + else if (strength_setting == FlipBipStrength192) strength = 192; // 18 words (192 bit) + + // BIP44 Coin setting + int coin_setting = app->bip44_coin; + uint32_t coin = 0; //FlipBipCoinBTC0 // BTC (0) + if (coin_setting == FlipBipCoinETH60) coin = 60; // ETH (60) flipbip_play_happy_bump(app); flipbip_led_set_rgb(app, 255, 0, 0); @@ -431,7 +457,7 @@ void flipbip_scene_1_enter(void* context) { instance->view, FlipBipScene1Model * model, { - flipbip_scene_1_model_init(model, strength); + flipbip_scene_1_model_init(model, strength, coin); }, true ); @@ -446,21 +472,6 @@ FlipBipScene1* flipbip_scene_1_alloc() { view_set_input_callback(instance->view, flipbip_scene_1_input); view_set_enter_callback(instance->view, flipbip_scene_1_enter); view_set_exit_callback(instance->view, flipbip_scene_1_exit); - - // FlipBip* app = instance->context; - // int strength_setting = app->bip39_strength; - // int strength = 256; - // if (strength_setting == 0) strength = 128; - // else if (strength_setting == 1) strength = 192; - - // with_view_model( - // instance->view, - // FlipBipScene1Model * model, - // { - // flipbip_scene_1_model_init(model, strength); - // }, - // true - // ); return instance; } From 553b8f376de668c7edfc2efa34e8fc0eb7ab8735 Mon Sep 17 00:00:00 2001 From: xtruan Date: Sat, 4 Mar 2023 11:05:32 -0800 Subject: [PATCH 4/5] message cleanup --- views/flipbip_scene_1.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/views/flipbip_scene_1.c b/views/flipbip_scene_1.c index 159761ff99e..a53ceb40393 100644 --- a/views/flipbip_scene_1.c +++ b/views/flipbip_scene_1.c @@ -234,7 +234,17 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { canvas_draw_str(canvas, 6, 30, "m/44'/C'/0'/0"); } else if (model->page >= 9 && model->page <= 13) { canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 1, 2, AlignLeft, AlignTop, "Receive address:"); + const char * receive_text; + if (model->coin == 0) { // BTC + receive_text = "BTC receive address:"; + } + else if (model->coin == 60) { // ETH + receive_text = "ETH receive address:"; + } + else { + receive_text = "Receive address:"; + } + canvas_draw_str_aligned(canvas, 1, 2, AlignLeft, AlignTop, receive_text); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 6, 22, s_disp_text1); canvas_draw_str(canvas, 6, 34, s_disp_text2); From 4ea47f6e093bf7bffccaa122864e7eb04cfdc639 Mon Sep 17 00:00:00 2001 From: xtruan Date: Sat, 4 Mar 2023 11:08:09 -0800 Subject: [PATCH 5/5] update readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ec5e33ecae..cb5fd88cfff 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,14 @@ The application will be compiled and copied onto your device - BIP39 mnemonic to BIP39 seed generation - Hierarchical Deterministic (HD) wallet generation from seed - Generation of offline `m/44'/0'/0'/0` BTC wallet + - Generation of offline `m/44'/60'/0'/0` ETH wallet (coded from the $SPORK Castle of ETHDenver 2023!) - Similar features to: https://iancoleman.io/bip39/ ### Work in Progress - Support for BIP39 passphrase - Currently blank -- Support for custom BIP32 wallet paths +- Support for more custom BIP32 wallet paths - Currently hardcoded to `m/44'/0'/0'/0` ### (FAR) Future