diff --git a/CHANGELOG.md b/CHANGELOG.md index dfd6f925..7f93616d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change log +## [1.2.0] - 2023-04-21 +### Added +- + +### Changed +- Simplified flow code + +### Fixed +- + ## [1.2.0] - 2023-04-21 ### Added - Added automated tests diff --git a/Makefile b/Makefile index 2dc8bfc1..1d791c1a 100755 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ all: default APPNAME = "SSKR Check" APPVERSION_M = 1 -APPVERSION_N = 2 +APPVERSION_N = 3 APPVERSION_P = 0 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" diff --git a/README.md b/README.md index 431ae312..f709908e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This application invites the user to type a BIP-39 seed on their Ledger device, The app also provides an option to confirm the onboarded seed against SSKR shares. -SSKR is [Sharded Secret Key Reconstruction](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-011-sskr.md). It is a way that you can divide ("shard") the master seed underlying a Bitcoin HD wallet into "shares", which you can then distribute to friends, family, or fiduciaries. If you ever lose your seed, you can then "reconstruct" it by collecting a sufficient number of your shares (the "threshold"). Knowledge of fewer than the required number of parts does not leak information about the master secret. +SSKR is [Sharded Secret Key Reconstruction](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-011-sskr.md), am i nteroperable implementation of [Shamir's Secret Sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing). It is a way that you can divide ("shard") the master seed underlying a Bitcoin HD wallet into "shares", which you can then distribute to friends, family, or fiduciaries. If you ever lose your seed, you can then "reconstruct" it by collecting a sufficient number of your shares (the "threshold"). Knowledge of fewer than the required number of parts does not leak information about the master secret. Further explanation of SSKR may be found [here](https://github.com/BlockchainCommons/crypto-commons/blob/master/Docs/sskr-users.md). diff --git a/TODO.md b/TODO.md index dafe0968..0468cf60 100755 --- a/TODO.md +++ b/TODO.md @@ -12,6 +12,7 @@ ### Done ✓ +- [x] Simplified flow code - [x] Add flow to set SSKR threshold values - [x] Add automated tests - [x] Fix issue with using 'cx_crc32_hw()' function in 'onboarding_seed_sskr.c' when testing with Speculos diff --git a/glyphs/bip39_nanos.gif b/glyphs/bip39_nanos.gif new file mode 100755 index 00000000..ec8af4bf Binary files /dev/null and b/glyphs/bip39_nanos.gif differ diff --git a/glyphs/bip39_nanox.gif b/glyphs/bip39_nanox.gif new file mode 100755 index 00000000..1b9ce0f0 Binary files /dev/null and b/glyphs/bip39_nanox.gif differ diff --git a/glyphs/nanos_app_sskr_check.gif b/glyphs/sskr_nanos.gif similarity index 100% rename from glyphs/nanos_app_sskr_check.gif rename to glyphs/sskr_nanos.gif diff --git a/glyphs/nanox_app_sskr_check.gif b/glyphs/sskr_nanox.gif similarity index 100% rename from glyphs/nanox_app_sskr_check.gif rename to glyphs/sskr_nanox.gif diff --git a/src/nanos_enter_phrase.c b/src/nanos_enter_phrase.c index 446b9c65..debd29dc 100644 --- a/src/nanos_enter_phrase.c +++ b/src/nanos_enter_phrase.c @@ -31,7 +31,7 @@ UX_STEP_CB(restore_1_intro_1, nn, screen_onboarding_restore_word_display_auto_co UX_FLOW(restore_1_intro, &restore_1_intro_1); -UX_STEP_CB(restore_1_bip39_invalid_step_1, pbb, screen_onboarding_1_restore_init(); +UX_STEP_CB(restore_1_bip39_invalid_step_1, pbb, screen_onboarding_bip39_restore_init(); , {&C_icon_warning, "BIP39 Recovery", "phrase invalid"}); UX_FLOW(restore_1_bip39_invalid, &restore_1_bip39_invalid_step_1); @@ -58,14 +58,14 @@ UX_STEP_CB(ux_bip39_match_step_1, pbb, os_sched_exit(0);, }); UX_STEP_CB(ux_bip39_match_step_2, pb, os_sched_exit(0), {&C_icon_dashboard_x, "Quit"}); UX_STEP_CB(ux_bip39_match_step_3, pbb, set_sskr_descriptor_values(); - , {&C_nanos_app_sskr_check, "Generate", "SSKR phrases"}); + , {&SSKR_ICON, "Generate", "SSKR phrases"}); UX_FLOW(flow_final_bip39_match, &ux_bip39_match_step_1, &ux_bip39_match_step_2, &ux_bip39_match_step_3); -UX_STEP_CB(restore_1_sskr_invalid_step_1, pbb, screen_onboarding_2_restore_init(); +UX_STEP_CB(restore_1_sskr_invalid_step_1, pbb, screen_onboarding_sskr_restore_init(); , {&C_icon_warning, "SSKR Recovery", "phrase invalid"}); UX_FLOW(restore_1_sskr_invalid, &restore_1_sskr_invalid_step_1); @@ -91,7 +91,7 @@ UX_STEP_CB(ux_sskr_match_step_1, pbb, os_sched_exit(0);, "is correct", }); UX_STEP_CB(ux_sskr_match_step_2, pb, os_sched_exit(0), {&C_icon_dashboard_x, "Quit"}); -UX_STEP_CB(ux_sskr_match_step_3, pbb, generate_bip39();, {&C_badge, "Generate", "BIP39 phrase"}); +UX_STEP_CB(ux_sskr_match_step_3, pbb, generate_bip39();, {&BIP39_ICON, "Generate", "BIP39 phrase"}); UX_FLOW(flow_final_sskr_match, &ux_sskr_match_step_1, &ux_sskr_match_step_2, &ux_sskr_match_step_3); diff --git a/src/nanox_enter_phrase.c b/src/nanox_enter_phrase.c index e7255ca3..cedf6271 100644 --- a/src/nanox_enter_phrase.c +++ b/src/nanox_enter_phrase.c @@ -173,7 +173,7 @@ UX_STEP_VALID(ux_bip39_success_step_1, {&C_icon_validate_14, "BIP39 Phrase", "is correct"}); UX_STEP_CB(ux_bip39_success_step_2, pb, os_sched_exit(0), {&C_icon_dashboard_x, "Quit"}); UX_STEP_CB(ux_bip39_success_step_3, pbb, set_sskr_descriptor_values(); - , {&C_nanox_app_sskr_check, "Generate", "SSKR phrases"}); + , {&SSKR_ICON, "Generate", "SSKR phrases"}); UX_FLOW(ux_bip39_succesful_check_flow, &ux_bip39_success_step_1, @@ -198,7 +198,7 @@ UX_STEP_VALID(ux_sskr_success_step_1, os_sched_exit(-1), {&C_icon_validate_14, "SSKR Phrase", "is correct"}); UX_STEP_CB(ux_sskr_success_step_2, pb, os_sched_exit(0), {&C_icon_dashboard_x, "Quit"}); -UX_STEP_CB(ux_sskr_success_step_3, pbb, generate_bip39();, {&C_badge, "Generate", "BIP39 phrases"}); +UX_STEP_CB(ux_sskr_success_step_3, pbb, generate_bip39();, {&BIP39_ICON, "Generate", "BIP39 phrases"}); UX_FLOW(ux_sskr_succesful_check_flow, &ux_sskr_success_step_1, diff --git a/src/ui.c b/src/ui.c index 8cd10b78..d06f0b04 100644 --- a/src/ui.c +++ b/src/ui.c @@ -8,63 +8,13 @@ enum UI_STATE uiState; ux_state_t G_ux; bolos_ux_params_t G_ux_params; -#if defined(TARGET_NANOS) - -UX_STEP_CB(restore_1_1_1, bb, G_bolos_ux_context.onboarding_kind = BOLOS_UX_ONBOARDING_NEW_24; - screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); - , - { - "Recovery phrase", - "with 24 words", - }); - -UX_STEP_CB(restore_1_1_2, bb, G_bolos_ux_context.onboarding_kind = BOLOS_UX_ONBOARDING_NEW_18; - screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); - , - { - "Recovery phrase", - "with 18 words", - }); - -UX_STEP_CB(restore_1_1_3, bb, G_bolos_ux_context.onboarding_kind = BOLOS_UX_ONBOARDING_NEW_12; - screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); - , - { - "Recovery phrase", - "with 12 words", - }); - -UX_FLOW(restore_1_1, &restore_1_1_1, &restore_1_1_2, &restore_1_1_3); +////////////////////////////////////////////////////////////////////// -void screen_onboarding_1_restore_init(void) { +void screen_onboarding_bip39_restore_init(void) { G_bolos_ux_context.onboarding_type = BOLOS_UX_ONBOARDING_BIP39; - ux_flow_init(0, restore_1_1, NULL); -} - -void screen_onboarding_2_restore_init(void) { - G_bolos_ux_context.onboarding_type = BOLOS_UX_ONBOARDING_SSKR; screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); } -UX_STEP_VALID(ux_idle_flow_1_step, pbb, screen_onboarding_1_restore_init();, - { - &C_badge, - "Check BIP39", - "recovery phrase", - }); - -UX_STEP_VALID(ux_idle_flow_2_step, pbb, screen_onboarding_2_restore_init(); - , - { - &C_nanos_app_sskr_check, - "Check SSKR", - "recovery phrase", - }); - -#elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) - -////////////////////////////////////////////////////////////////////// - const char* const number_of_bip39_words_values[] = { "12 words", "18 words", @@ -72,7 +22,7 @@ const char* const number_of_bip39_words_values[] = { "Back", }; -const char* number_of_bip39_words_get(unsigned int idx) { +const char* number_of_bip39_words_getter(unsigned int idx) { if (idx < ARRAYLEN(number_of_bip39_words_values)) { return number_of_bip39_words_values[idx]; } @@ -91,66 +41,77 @@ void number_of_bip39_words_selector(unsigned int idx) { G_bolos_ux_context.onboarding_kind = BOLOS_UX_ONBOARDING_NEW_24; goto word_init; word_init: - screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); + screen_onboarding_bip39_restore_init(); break; default: ui_idle_init(); } } -void screen_onboarding_1_restore_init(void) { - G_bolos_ux_context.onboarding_type = BOLOS_UX_ONBOARDING_BIP39; - ux_menulist_init(0, number_of_bip39_words_get, number_of_bip39_words_selector); -} +#if defined(TARGET_NANOS) +UX_STEP_NOCB(ux_bip39_instruction_step, nn, {"Enter number", "of BIP39 words"}); +#elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) +UX_STEP_NOCB(ux_bip39_instruction_step, + nnn, + { + "Select the number of", + "words written on", + "your Recovery Sheet", + }); +#endif -void screen_onboarding_2_restore_init(void) { - G_bolos_ux_context.onboarding_type = BOLOS_UX_ONBOARDING_SSKR; - screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); -} +UX_STEP_MENULIST(ux_bip39_menu_step, number_of_bip39_words_getter, number_of_bip39_words_selector); -////////////////////////////////////////////////////////////////////// +UX_FLOW(ux_bip39_flow, &ux_bip39_instruction_step, &ux_bip39_menu_step); -UX_STEP_VALID(ux_instruction_1_1_step, - nnn, - screen_onboarding_1_restore_init(), - { - "Select the number of", - "words written on", - "your Recovery Sheet", - }); +////////////////////////////////////////////////////////////////////// -UX_FLOW(ux_instruction_1_flow, &ux_instruction_1_1_step); +void screen_onboarding_sskr_restore_init(void) { + G_bolos_ux_context.onboarding_type = BOLOS_UX_ONBOARDING_SSKR; + screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); +} -UX_STEP_VALID(ux_instruction_2_1_step, - nnn, - screen_onboarding_2_restore_init(), - { - "Enter first word of", - "first share of SSKR", - "recovery phrase", - }); +#if defined(TARGET_NANOS) +UX_STEP_CB(ux_sskr_instruction_step, + nn, + screen_onboarding_sskr_restore_init(), + { + "Enter SSKR", + "recovery phrase", + }); +#elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) +UX_STEP_CB(ux_sskr_instruction_step, + nnn, + G_bolos_ux_context.onboarding_type = BOLOS_UX_ONBOARDING_SSKR; + screen_onboarding_restore_word_init(RESTORE_WORD_ACTION_FIRST_WORD); + , + { + "Enter first word of", + "first share of SSKR", + "recovery phrase", + }); +#endif -UX_FLOW(ux_instruction_2_flow, &ux_instruction_2_1_step); +UX_FLOW(ux_sskr_flow, &ux_sskr_instruction_step); ////////////////////////////////////////////////////////////////////// UX_STEP_VALID(ux_idle_flow_1_step, pbb, - ux_flow_init(0, ux_instruction_1_flow, NULL), + ux_flow_init(0, ux_bip39_flow, NULL), { - &C_badge, + &BIP39_ICON, "Check BIP39", "recovery phrase", }); UX_STEP_VALID(ux_idle_flow_2_step, pbb, - ux_flow_init(0, ux_instruction_2_flow, NULL), + ux_flow_init(0, ux_sskr_flow, NULL), { - &C_nanox_app_sskr_check, + &SSKR_ICON, "Check SSKR", "recovery phrase", }); -#endif UX_STEP_NOCB(ux_idle_flow_3_step, bn, diff --git a/src/ui.h b/src/ui.h index b48991ca..cf807efa 100644 --- a/src/ui.h +++ b/src/ui.h @@ -26,8 +26,12 @@ #if defined(TARGET_NANOS) #include "ux_nanos.h" #define ARRAYLEN(array) (sizeof(array) / sizeof(array[0])) +#define BIP39_ICON C_bip39_nanos +#define SSKR_ICON C_sskr_nanos #elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) #include "ux_nanox.h" +#define BIP39_ICON C_bip39_nanox +#define SSKR_ICON C_sskr_nanox #endif void ui_idle_init(void); diff --git a/src/ux_common/common.h b/src/ux_common/common.h index f74af823..86337f58 100644 --- a/src/ux_common/common.h +++ b/src/ux_common/common.h @@ -52,8 +52,8 @@ void bolos_ux_hslider3_next(void); void bolos_ux_hslider3_previous(void); // all screens -void screen_onboarding_1_restore_init(void); -void screen_onboarding_2_restore_init(void); +void screen_onboarding_bip39_restore_init(void); +void screen_onboarding_sskr_restore_init(void); #define RESTORE_WORD_ACTION_REENTER_WORD 0 #define RESTORE_WORD_ACTION_FIRST_WORD 1 void screen_onboarding_restore_word_init(unsigned int action); diff --git a/tests/deprecated/nanos-bip39-12-word.json b/tests/deprecated/nanos-bip39-12-word.json index c7085217..968ac6ba 100755 --- a/tests/deprecated/nanos-bip39-12-word.json +++ b/tests/deprecated/nanos-bip39-12-word.json @@ -42,16 +42,6 @@ 2, false ], - [ - "button", - 2, - true - ], - [ - "button", - 2, - false - ], [ "button", 1, diff --git a/tests/deprecated/nanos-bip39-12-word.test b/tests/deprecated/nanos-bip39-12-word.test index 5c838ecc..ec27c4fa 100644 --- a/tests/deprecated/nanos-bip39-12-word.test +++ b/tests/deprecated/nanos-bip39-12-word.test @@ -1,6 +1,5 @@ POST /button/both POST /button/right -POST /button/right POST /button/both POST /button/both POST /button/right diff --git a/tests/deprecated/nanos-bip39-18-word.json b/tests/deprecated/nanos-bip39-18-word.json index d3f80136..576f3ff8 100755 --- a/tests/deprecated/nanos-bip39-18-word.json +++ b/tests/deprecated/nanos-bip39-18-word.json @@ -42,6 +42,16 @@ 2, false ], + [ + "button", + 2, + true + ], + [ + "button", + 2, + false + ], [ "button", 1, diff --git a/tests/deprecated/nanos-bip39-18-word.test b/tests/deprecated/nanos-bip39-18-word.test index 00e35613..fe0a3437 100644 --- a/tests/deprecated/nanos-bip39-18-word.test +++ b/tests/deprecated/nanos-bip39-18-word.test @@ -1,5 +1,6 @@ POST /button/both POST /button/right +POST /button/right POST /button/both POST /button/both POST /button/left diff --git a/tests/deprecated/nanos-bip39-24-word.json b/tests/deprecated/nanos-bip39-24-word.json index 9773f13b..bad9142e 100755 --- a/tests/deprecated/nanos-bip39-24-word.json +++ b/tests/deprecated/nanos-bip39-24-word.json @@ -52,6 +52,36 @@ 2, false ], + [ + "button", + 2, + true + ], + [ + "button", + 2, + false + ], + [ + "button", + 2, + true + ], + [ + "button", + 2, + false + ], + [ + "button", + 2, + true + ], + [ + "button", + 2, + false + ], [ "button", 1, diff --git a/tests/deprecated/nanos-bip39-24-word.test b/tests/deprecated/nanos-bip39-24-word.test index ba2ce134..acbf9fb9 100644 --- a/tests/deprecated/nanos-bip39-24-word.test +++ b/tests/deprecated/nanos-bip39-24-word.test @@ -1,4 +1,7 @@ POST /button/both +POST /button/right +POST /button/right +POST /button/right POST /button/both POST /button/both POST /button/left diff --git a/tests/deprecated/nanos-sskr-128bit.json b/tests/deprecated/nanos-sskr-128bit.json index 3c29a8c8..d0d99e83 100755 --- a/tests/deprecated/nanos-sskr-128bit.json +++ b/tests/deprecated/nanos-sskr-128bit.json @@ -80,6 +80,26 @@ 1, true ], + [ + "button", + 2, + true + ], + [ + "button", + 1, + false + ], + [ + "button", + 2, + false + ], + [ + "button", + 1, + true + ], [ "button", 1, diff --git a/tests/deprecated/nanos-sskr-128bit.test b/tests/deprecated/nanos-sskr-128bit.test index ff126825..86acf2bb 100644 --- a/tests/deprecated/nanos-sskr-128bit.test +++ b/tests/deprecated/nanos-sskr-128bit.test @@ -1,6 +1,7 @@ POST /button/right POST /button/both POST /button/both +POST /button/both POST /button/left POST /button/left POST /button/left diff --git a/tests/deprecated/nanos-sskr-256bit.json b/tests/deprecated/nanos-sskr-256bit.json index 8aa59031..d1e6bd15 100755 --- a/tests/deprecated/nanos-sskr-256bit.json +++ b/tests/deprecated/nanos-sskr-256bit.json @@ -56,6 +56,26 @@ false ], [ + [ + "button", + 1, + true + ], + [ + "button", + 2, + true + ], + [ + "button", + 1, + false + ], + [ + "button", + 2, + false + ], "button", 1, true diff --git a/tests/deprecated/nanos-sskr-256bit.test b/tests/deprecated/nanos-sskr-256bit.test index aff02e02..af06effa 100644 --- a/tests/deprecated/nanos-sskr-256bit.test +++ b/tests/deprecated/nanos-sskr-256bit.test @@ -1,6 +1,7 @@ POST /button/right POST /button/both POST /button/both +POST /button/both POST /button/left POST /button/left POST /button/left diff --git a/tests/functional/test_bip39_12word.py b/tests/functional/test_bip39_12word.py index 582e2ef4..21adfad1 100755 --- a/tests/functional/test_bip39_12word.py +++ b/tests/functional/test_bip39_12word.py @@ -17,7 +17,6 @@ def test_bip39_12word(firmware, backend, navigator): instructions = [ NavInsID.BOTH_CLICK, NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK, NavInsID.BOTH_CLICK, NavInsID.BOTH_CLICK, NavInsID.RIGHT_CLICK, diff --git a/tests/functional/test_bip39_18word.py b/tests/functional/test_bip39_18word.py index 6e8af0c0..6a65f3f4 100755 --- a/tests/functional/test_bip39_18word.py +++ b/tests/functional/test_bip39_18word.py @@ -16,6 +16,7 @@ def test_bip39_18word(firmware, backend, navigator): instructions = [ NavInsID.BOTH_CLICK, NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, NavInsID.BOTH_CLICK, NavInsID.BOTH_CLICK, NavInsID.LEFT_CLICK, diff --git a/tests/functional/test_bip39_24word.py b/tests/functional/test_bip39_24word.py index 0f21ad9d..69004b9a 100755 --- a/tests/functional/test_bip39_24word.py +++ b/tests/functional/test_bip39_24word.py @@ -16,6 +16,9 @@ def test_bip39_24word(firmware, backend, navigator): backend.wait_for_text_on_screen("recovery phras", 1) instructions = [ NavInsID.BOTH_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, NavInsID.BOTH_CLICK, NavInsID.BOTH_CLICK, NavInsID.LEFT_CLICK, diff --git a/tests/functional/test_sskr_128bit.py b/tests/functional/test_sskr_128bit.py index 24baf90c..de78e9af 100755 --- a/tests/functional/test_sskr_128bit.py +++ b/tests/functional/test_sskr_128bit.py @@ -18,6 +18,7 @@ def test_sskr_128bit(firmware, backend, navigator): backend.wait_for_text_on_screen("Check SSKR", 5) backend.wait_for_text_on_screen("recovery phras", 1) instructions = [ + NavInsID.BOTH_CLICK, NavInsID.BOTH_CLICK, NavInsID.BOTH_CLICK, NavInsID.LEFT_CLICK, diff --git a/tests/functional/test_sskr_256bit.py b/tests/functional/test_sskr_256bit.py index 6bd14264..38e83d47 100755 --- a/tests/functional/test_sskr_256bit.py +++ b/tests/functional/test_sskr_256bit.py @@ -19,6 +19,7 @@ def test_sskr_256bit(firmware, backend, navigator): backend.wait_for_text_on_screen("Check SSKR", 5) backend.wait_for_text_on_screen("recovery phras", 1) instructions = [ + NavInsID.BOTH_CLICK, NavInsID.BOTH_CLICK, NavInsID.BOTH_CLICK, NavInsID.LEFT_CLICK,