From 7cdde940af0893f930b8db4467f1e2063de27518 Mon Sep 17 00:00:00 2001 From: matejcik Date: Thu, 17 Jun 2021 16:31:26 +0200 Subject: [PATCH] chore(tests): adapt device tests to paging information ButtonRequests --- common/tests/fixtures/cardano/sign_tx.json | 23 ---- tests/common.py | 29 +++-- tests/device_tests/cardano/test_sign_tx.py | 37 ++---- tests/device_tests/test_msg_backup_device.py | 118 +++++------------- tests/device_tests/test_msg_eos_signtx.py | 77 ------------ .../device_tests/test_msg_getaddress_show.py | 5 +- .../test_msg_lisk_verifymessage.py | 61 +++------ .../test_msg_nem_signtx_mosaics_t2.py | 49 +------- .../test_msg_recoverydevice_bip39_dryrun.py | 4 +- ...test_msg_recoverydevice_slip39_advanced.py | 8 +- .../test_msg_recoverydevice_slip39_basic.py | 20 +-- .../test_msg_resetdevice_bip39_t2.py | 87 ++++++------- .../test_msg_resetdevice_slip39_advanced.py | 76 +++-------- .../test_msg_resetdevice_slip39_basic.py | 36 +++--- tests/device_tests/test_msg_signmessage.py | 38 +++--- tests/device_tests/test_msg_signtx.py | 2 +- .../test_msg_signtx_replacement.py | 5 +- tests/device_tests/test_msg_tezos_sign_tx.py | 8 -- tests/device_tests/test_reset_backup.py | 49 +++++--- .../device_tests/test_reset_recovery_bip39.py | 53 ++++---- .../test_reset_recovery_slip39_advanced.py | 70 +++-------- .../test_reset_recovery_slip39_basic.py | 36 +++--- 22 files changed, 300 insertions(+), 591 deletions(-) diff --git a/common/tests/fixtures/cardano/sign_tx.json b/common/tests/fixtures/cardano/sign_tx.json index e724650e29..b28677d86d 100644 --- a/common/tests/fixtures/cardano/sign_tx.json +++ b/common/tests/fixtures/cardano/sign_tx.json @@ -14,7 +14,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/44'/1815'/0'/0/1", @@ -44,7 +43,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/44'/1815'/0'/0/1", @@ -79,7 +77,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -115,7 +112,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/44'/1815'/0'/0/1", @@ -160,7 +156,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -197,7 +192,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -234,7 +228,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -270,7 +263,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -306,7 +298,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -344,7 +335,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -384,7 +374,6 @@ ], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -419,7 +408,6 @@ ], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -455,7 +443,6 @@ ], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -487,7 +474,6 @@ ], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -527,7 +513,6 @@ } ], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -563,7 +548,6 @@ ], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -595,7 +579,6 @@ "auxiliary_data": { "blob": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, - "input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -636,7 +619,6 @@ "nonce": 22634813 } }, - "input_flow": [["SWIPE", "SWIPE", "YES"], ["SWIPE", "SWIPE", "SWIPE", "SWIPE", "SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -666,7 +648,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/44'/1815'/0'/0/1", @@ -706,7 +687,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -754,7 +734,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -813,7 +792,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["YES"]], "inputs": [ { "path": "m/1852'/1815'/0'/0/0", @@ -844,7 +822,6 @@ "certificates": [], "withdrawals": [], "auxiliary_data": null, - "input_flow": [["YES"], ["YES"]], "inputs": [ { "path": "m/44'/1815'/0'/0/0", diff --git a/tests/common.py b/tests/common.py index ada85e6f26..368fc8afcc 100644 --- a/tests/common.py +++ b/tests/common.py @@ -20,7 +20,7 @@ from pathlib import Path import pytest from trezorlib import btc, tools -from trezorlib.messages import ButtonRequestType as B +from trezorlib.messages import ButtonRequest, ButtonRequestType as B # fmt: off # 1 2 3 4 5 6 7 8 9 10 11 12 @@ -130,16 +130,16 @@ def recovery_enter_shares(debug, shares, groups=False): yield debug.press_yes() # Input word number - code = yield - assert code == B.MnemonicWordCount + br = yield + assert br.code == B.MnemonicWordCount debug.input(str(word_count)) # Homescreen - proceed to share entry yield debug.press_yes() # Enter shares for index, share in enumerate(shares): - code = yield - assert code == B.MnemonicInput + br = yield + assert br.code == B.MnemonicInput # Enter mnemonic words for word in share.split(" "): debug.input(word) @@ -171,11 +171,11 @@ def click_through(debug, screens, code=None): for _ in range(screens): received = yield if code is not None: - assert received == code + assert received.code == code debug.press_yes() -def read_and_confirm_mnemonic(debug, words, choose_wrong=False): +def read_and_confirm_mnemonic(debug, choose_wrong=False): """Read a given number of mnemonic words from Trezor T screen and correctly answer confirmation questions. Return the full mnemonic. @@ -185,13 +185,13 @@ def read_and_confirm_mnemonic(debug, words, choose_wrong=False): def input_flow(): yield from click_through(client.debug, screens=3) - yield # confirm mnemonic entry - mnemonic = read_and_confirm_mnemonic(client.debug, words=20) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) """ mnemonic = [] while True: + br = yield mnemonic.extend(debug.read_reset_word().split()) - if len(mnemonic) < words: + if br.page_number < br.pages: debug.swipe_up() else: # last page is confirmation @@ -210,6 +210,15 @@ def read_and_confirm_mnemonic(debug, words, choose_wrong=False): return " ".join(mnemonic) +def paging_responses(pages, code=None): + """Generate a sequence of ButtonRequests for paging through a specified number + of screens. + """ + return [ + ButtonRequest(code=code, page_number=i + 1, pages=pages) for i in range(pages) + ] + + def get_test_address(client): """Fetch a testnet address on a fixed path. Useful to make a pin/passphrase protected call, or to identify the root secret (seed+passphrase)""" diff --git a/tests/device_tests/cardano/test_sign_tx.py b/tests/device_tests/cardano/test_sign_tx.py index dbf0633fc3..47dd39d56b 100644 --- a/tests/device_tests/cardano/test_sign_tx.py +++ b/tests/device_tests/cardano/test_sign_tx.py @@ -40,8 +40,6 @@ def test_cardano_sign_tx(client, parameters, result): withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]] auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"]) - input_flow = parameters.get("input_flow", ()) - if parameters.get("security_checks") == "prompt": device.apply_settings( client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily @@ -50,8 +48,6 @@ def test_cardano_sign_tx(client, parameters, result): device.apply_settings(client, safety_checks=messages.SafetyCheckLevel.Strict) with client: - client.set_input_flow(_to_device_actions(client, input_flow)) - response = cardano.sign_tx( client=client, inputs=inputs, @@ -79,11 +75,7 @@ def test_cardano_sign_tx_failed(client, parameters, result): withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]] auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"]) - input_flow = parameters.get("input_flow", ()) - with client: - client.set_input_flow(_to_device_actions(client, input_flow)) - with pytest.raises(TrezorFailure, match=result["error_message"]): cardano.sign_tx( client=client, @@ -108,12 +100,16 @@ def test_cardano_sign_tx_with_multiple_chunks(client, parameters, result): withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]] auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"]) - input_flow = parameters.get("input_flow", ()) - expected_responses = [ messages.PassphraseRequest(), - messages.ButtonRequest(), - messages.ButtonRequest(), + # XXX as many ButtonRequests as paginations. We are relying on the fact that + # there is only one fixture whose pagination is known. + # If that changes, we'll need to figure out something else. + messages.ButtonRequest(page_number=1), + messages.ButtonRequest(page_number=2), + messages.ButtonRequest(page_number=3), + messages.ButtonRequest(page_number=1), + messages.ButtonRequest(page_number=2), ] expected_responses += [ messages.CardanoSignedTxChunk(signed_tx_chunk=bytes.fromhex(signed_tx_chunk)) @@ -124,9 +120,7 @@ def test_cardano_sign_tx_with_multiple_chunks(client, parameters, result): ] with client: - client.set_input_flow(_to_device_actions(client, input_flow)) client.set_expected_responses(expected_responses) - response = cardano.sign_tx( client=client, inputs=inputs, @@ -142,18 +136,3 @@ def test_cardano_sign_tx_with_multiple_chunks(client, parameters, result): ) assert response.tx_hash.hex() == result["tx_hash"] assert response.serialized_tx.hex() == result["serialized_tx"] - - -def _to_device_actions(client, input_flow): - if not input_flow: - yield - - for sequence in input_flow: - yield - for action in sequence: - if action == "SWIPE": - client.debug.swipe_up() - elif action == "YES": - client.debug.press_yes() - else: - raise ValueError("Invalid input action") diff --git a/tests/device_tests/test_msg_backup_device.py b/tests/device_tests/test_msg_backup_device.py index 1d22b2f6cf..4aeb4273f9 100644 --- a/tests/device_tests/test_msg_backup_device.py +++ b/tests/device_tests/test_msg_backup_device.py @@ -27,6 +27,7 @@ from ..common import ( MNEMONIC_SLIP39_ADVANCED_20, MNEMONIC_SLIP39_BASIC_20_3of6, click_through, + paging_responses, read_and_confirm_mnemonic, ) @@ -36,13 +37,15 @@ from ..common import ( def test_backup_bip39(client): assert client.features.needs_backup is True mnemonic = None + words = 12 + mnemonic_pages = ((words + 3) // 4) + 1 def input_flow(): nonlocal mnemonic yield # Confirm Backup client.debug.press_yes() - yield # Mnemonic phrases - mnemonic = read_and_confirm_mnemonic(client.debug, words=12) + # Mnemonic phrases + mnemonic = yield from read_and_confirm_mnemonic(client.debug) yield # Confirm success client.debug.press_yes() yield # Backup is done @@ -53,7 +56,9 @@ def test_backup_bip39(client): client.set_expected_responses( [ messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), + ] + + paging_responses(mnemonic_pages, code=B.ResetDevice) + + [ messages.ButtonRequest(code=B.Success), messages.ButtonRequest(code=B.Success), messages.Success, @@ -76,6 +81,8 @@ def test_backup_bip39(client): def test_backup_slip39_basic(client): assert client.features.needs_backup is True mnemonics = [] + words = 20 + mnemonic_pages = ((words + 3) // 4) + 1 def input_flow(): # 1. Checklist @@ -88,8 +95,8 @@ def test_backup_slip39_basic(client): # Mnemonic phrases for _ in range(5): - yield # Phrase screen - mnemonic = read_and_confirm_mnemonic(client.debug, words=20) + # Phrase screen + mnemonic = yield from read_and_confirm_mnemonic(client.debug) mnemonics.append(mnemonic) yield # Confirm continue to next client.debug.press_yes() @@ -101,23 +108,13 @@ def test_backup_slip39_basic(client): with client: client.set_input_flow(input_flow) client.set_expected_responses( - [ - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), + [messages.ButtonRequest(code=B.ResetDevice)] * 6 # intro screens + + [ + *paging_responses(mnemonic_pages, code=B.ResetDevice), messages.ButtonRequest(code=B.Success), + ] + * 5 # individual shares + + [ messages.ButtonRequest(code=B.Success), messages.Success, messages.Features, @@ -142,6 +139,8 @@ def test_backup_slip39_basic(client): def test_backup_slip39_advanced(client): assert client.features.needs_backup is True mnemonics = [] + words = 20 + mnemonic_pages = ((words + 3) // 4) + 1 def input_flow(): # 1. Checklist @@ -158,8 +157,8 @@ def test_backup_slip39_advanced(client): # Mnemonic phrases for _ in range(5): for _ in range(5): - yield # Phrase screen - mnemonic = read_and_confirm_mnemonic(client.debug, words=20) + # Phrase screen + mnemonic = yield from read_and_confirm_mnemonic(client.debug) mnemonics.append(mnemonic) yield # Confirm continue to next client.debug.press_yes() @@ -171,73 +170,18 @@ def test_backup_slip39_advanced(client): with client: client.set_input_flow(input_flow) client.set_expected_responses( - [ + [messages.ButtonRequest(code=B.ResetDevice)] * 6 # intro screens + + [ messages.ButtonRequest(code=B.ResetDevice), messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), # group #1 counts - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), # group #2 counts - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), # group #3 counts - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), # group #4 counts - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), # group #5 counts - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), # show seeds + ] + * 5 # group thresholds + + [ + *paging_responses(mnemonic_pages, code=B.ResetDevice), messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), # show seeds ends here + ] + * 25 # individual shares + + [ messages.ButtonRequest(code=B.Success), messages.Success, messages.Features, diff --git a/tests/device_tests/test_msg_eos_signtx.py b/tests/device_tests/test_msg_eos_signtx.py index a2c366332a..3ae3bcb5a7 100644 --- a/tests/device_tests/test_msg_eos_signtx.py +++ b/tests/device_tests/test_msg_eos_signtx.py @@ -31,20 +31,6 @@ ADDRESS_N = parse_path("m/44'/194'/0'/0/0") @pytest.mark.skip_t1 @pytest.mark.setup_client(mnemonic=MNEMONIC12) class TestMsgEosSignTx: - @pytest.mark.setup_client(uninitialized=True) - def input_flow(self, debug, pages): - # confirm number of actions - yield - debug.press_yes() - - # swipe through pages - yield - for _ in range(pages - 1): - debug.swipe_up() - - # confirm last page - debug.press_yes() - def test_eos_signtx_transfer_token(self, client): transaction = { "expiration": "2018-07-14T10:43:28", @@ -73,7 +59,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=3)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -108,7 +93,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=2)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -143,7 +127,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=2)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -174,7 +157,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=2)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -211,7 +193,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=3)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -247,7 +228,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=2)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -278,7 +258,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=0)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -314,7 +293,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=2)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -349,7 +327,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=2)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -407,7 +384,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=8)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -438,7 +414,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=0)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -503,7 +478,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=6)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -534,7 +508,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=0)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -565,7 +538,6 @@ class TestMsgEosSignTx: } with client: - client.set_input_flow(self.input_flow(client.debug, pages=2)) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -646,36 +618,7 @@ class TestMsgEosSignTx: "transaction_extensions": [], } - def input_flow(): - # confirm number of actions - yield - client.debug.press_yes() - - # swipe through new account - yield - for _ in range(5): - client.debug.swipe_up() - - # confirm new account - client.debug.press_yes() - - # swipe through buyrambytes - yield - client.debug.swipe_up() - - # confirm buyrambytes - client.debug.press_yes() - - # swipe through delegatebw - yield - for _ in range(2): - client.debug.swipe_up() - - # confirm delegatebw - client.debug.press_yes() - with client: - client.set_input_flow(input_flow) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( @@ -714,27 +657,7 @@ class TestMsgEosSignTx: "context_free_data": [], } - def input_flow(): - # confirm number of actions - yield - client.debug.press_yes() - - # swipe through setcode - yield - client.debug.swipe_up() - - # confirm setcode - client.debug.press_yes() - - # swipe through setabi - yield - client.debug.swipe_up() - - # confirm setabi - client.debug.press_yes() - with client: - client.set_input_flow(input_flow) resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID) assert isinstance(resp, EosSignedTx) assert ( diff --git a/tests/device_tests/test_msg_getaddress_show.py b/tests/device_tests/test_msg_getaddress_show.py index 74dd2574a6..a378622fb8 100644 --- a/tests/device_tests/test_msg_getaddress_show.py +++ b/tests/device_tests/test_msg_getaddress_show.py @@ -177,7 +177,7 @@ def test_show_multisig_xpubs( def input_flow(): yield # show address - lines = client.debug.wait_layout().lines + lines = client.debug.wait_layout().lines # TODO: do not need to *wait* now? assert lines[0] == "Multisig 2 of 3" assert "".join(lines[1:]) == address @@ -190,6 +190,7 @@ def test_show_multisig_xpubs( lines1 = client.debug.wait_layout().lines assert lines1[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)") client.debug.swipe_up() + yield lines2 = client.debug.wait_layout().lines assert lines2[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)") assert "".join(lines1[1:] + lines2[1:]) == xpubs[0] @@ -199,6 +200,7 @@ def test_show_multisig_xpubs( lines1 = client.debug.wait_layout().lines assert lines1[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)") client.debug.swipe_up() + yield lines2 = client.debug.wait_layout().lines assert lines2[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)") assert "".join(lines1[1:] + lines2[1:]) == xpubs[1] @@ -208,6 +210,7 @@ def test_show_multisig_xpubs( lines1 = client.debug.wait_layout().lines assert lines1[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)") client.debug.swipe_up() + yield lines2 = client.debug.wait_layout().lines assert lines2[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)") assert "".join(lines1[1:] + lines2[1:]) == xpubs[2] diff --git a/tests/device_tests/test_msg_lisk_verifymessage.py b/tests/device_tests/test_msg_lisk_verifymessage.py index 995f638710..5e4676135b 100644 --- a/tests/device_tests/test_msg_lisk_verifymessage.py +++ b/tests/device_tests/test_msg_lisk_verifymessage.py @@ -16,48 +16,27 @@ import pytest -from trezorlib import lisk, messages as proto +from trezorlib import lisk + +VECTORS = ( # pubkey, signature, message + ( + "eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294", + "7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05", + "This is an example of a signed message.", + ), + ( + "8bca6b65a1a877767b746ea0b3c4310d404aa113df99c1b554e1802d70185ab5", + "458ca5896d0934866992268f7509b5e954d568b1251e20c19bd3149ee3c86ffb5a44d1c2a0abbb99a3ab4767272dbb0e419b4579e890a24919ebbbe6cc0f970f", + "VeryLongMessage!" * 64, + ), +) @pytest.mark.altcoin @pytest.mark.lisk -class TestMsgLiskVerifymessage: - def test_verify(self, client): - with client: - client.set_expected_responses( - [ - proto.ButtonRequest(code=proto.ButtonRequestType.Other), - proto.ButtonRequest(code=proto.ButtonRequestType.Other), - proto.Success(message="Message verified"), - ] - ) - lisk.verify_message( - client, - bytes.fromhex( - "eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294" - ), - bytes.fromhex( - "7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05" - ), - "This is an example of a signed message.", - ) - - def test_verify_long(self, client): - with client: - client.set_expected_responses( - [ - proto.ButtonRequest(code=proto.ButtonRequestType.Other), - proto.ButtonRequest(code=proto.ButtonRequestType.Other), - proto.Success(message="Message verified"), - ] - ) - lisk.verify_message( - client, - bytes.fromhex( - "8bca6b65a1a877767b746ea0b3c4310d404aa113df99c1b554e1802d70185ab5" - ), - bytes.fromhex( - "458ca5896d0934866992268f7509b5e954d568b1251e20c19bd3149ee3c86ffb5a44d1c2a0abbb99a3ab4767272dbb0e419b4579e890a24919ebbbe6cc0f970f" - ), - "VeryLongMessage!" * 64, - ) +@pytest.mark.parametrize("pubkey, signature, message", VECTORS) +def test_verify(client, pubkey, signature, message): + with client: + lisk.verify_message( + client, bytes.fromhex(pubkey), bytes.fromhex(signature), message + ) diff --git a/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py b/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py index 92b00eab49..6b4d26626f 100644 --- a/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py +++ b/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py @@ -16,12 +16,13 @@ import pytest -from trezorlib import messages as proto, nem -from trezorlib.messages import ButtonRequestType as B +from trezorlib import nem from trezorlib.tools import parse_path from ..common import MNEMONIC12 +ADDRESS_N = parse_path("m/44'/1'/0'/0'/0'") + # assertion data from T1 @pytest.mark.altcoin @@ -78,7 +79,7 @@ class TestMsgNEMSignTxMosaics: } # not using client.nem_sign_tx() because of swiping - tx = self._nem_sign(client, 2, test_suite) + tx = nem.sign_tx(client, ADDRESS_N, test_suite) assert ( tx.data.hex() == "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000" @@ -113,7 +114,7 @@ class TestMsgNEMSignTxMosaics: } # not using client.nem_sign_tx() because of swiping - tx = self._nem_sign(client, 2, test_suite) + tx = nem.sign_tx(client, ADDRESS_N, test_suite) assert ( tx.data.hex() == "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000" @@ -152,7 +153,7 @@ class TestMsgNEMSignTxMosaics: "creationFee": 1500, } - tx = self._nem_sign(client, 6, test_suite) + tx = nem.sign_tx(client, ADDRESS_N, test_suite) assert ( tx.data.hex() == "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000" @@ -161,41 +162,3 @@ class TestMsgNEMSignTxMosaics: tx.signature.hex() == "b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a" ) - - def _nem_sign(self, client, num_of_swipes, test_suite): - n = parse_path("m/44'/1'/0'/0'/0'") - - def input_flow(): - # Confirm Action - btn_code = yield - assert btn_code == B.ConfirmOutput - client.debug.press_yes() - - # Swipe and confirm - yield - for _ in range(num_of_swipes): - client.debug.swipe_up() - client.debug.press_yes() - - # Confirm Action - btn_code = yield - assert btn_code == B.ConfirmOutput - client.debug.press_yes() - - # Sign Tx - btn_code = yield - assert btn_code == B.SignTx - client.debug.press_yes() - - with client: - client.set_expected_responses( - [ - proto.ButtonRequest(code=B.ConfirmOutput), - proto.ButtonRequest(code=B.ConfirmOutput), - proto.ButtonRequest(code=B.ConfirmOutput), - proto.ButtonRequest(code=B.SignTx), - proto.NEMSignedTx, - ] - ) - client.set_input_flow(input_flow) - return nem.sign_tx(client, n, test_suite) diff --git a/tests/device_tests/test_msg_recoverydevice_bip39_dryrun.py b/tests/device_tests/test_msg_recoverydevice_bip39_dryrun.py index 20e51e5470..38ee3d82d7 100644 --- a/tests/device_tests/test_msg_recoverydevice_bip39_dryrun.py +++ b/tests/device_tests/test_msg_recoverydevice_bip39_dryrun.py @@ -143,9 +143,9 @@ def test_invalid_seed_core(client): assert layout.text == "Bip39Keyboard" client.debug.input("stick") - code = yield + br = yield layout = client.debug.wait_layout() - assert code == messages.ButtonRequestType.Warning + assert br.code == messages.ButtonRequestType.Warning assert "invalid recovery seed" in layout.text client.debug.click(buttons.OK) diff --git a/tests/device_tests/test_msg_recoverydevice_slip39_advanced.py b/tests/device_tests/test_msg_recoverydevice_slip39_advanced.py index 4e1d038d8f..a37247e103 100644 --- a/tests/device_tests/test_msg_recoverydevice_slip39_advanced.py +++ b/tests/device_tests/test_msg_recoverydevice_slip39_advanced.py @@ -164,8 +164,8 @@ def test_same_share(client): for word in second_share: debug.input(word) - code = yield - assert code == messages.ButtonRequestType.Warning + br = yield + assert br.code == messages.ButtonRequestType.Warning client.cancel() @@ -204,8 +204,8 @@ def test_group_threshold_reached(client): for word in second_share: debug.input(word) - code = yield - assert code == messages.ButtonRequestType.Warning + br = yield + assert br.code == messages.ButtonRequestType.Warning client.cancel() diff --git a/tests/device_tests/test_msg_recoverydevice_slip39_basic.py b/tests/device_tests/test_msg_recoverydevice_slip39_basic.py index 8c29e8c1d1..5bd0fb1b53 100644 --- a/tests/device_tests/test_msg_recoverydevice_slip39_basic.py +++ b/tests/device_tests/test_msg_recoverydevice_slip39_basic.py @@ -154,8 +154,8 @@ def test_ask_word_number(client): for _ in range(20): debug.input("slush") - code = yield # Invalid share - assert code == messages.ButtonRequestType.Warning + br = yield # Invalid share + assert br.code == messages.ButtonRequestType.Warning debug.press_yes() yield # Homescreen - start process @@ -168,8 +168,8 @@ def test_ask_word_number(client): for _ in range(33): debug.input("slush") - code = yield # Invalid share - assert code == messages.ButtonRequestType.Warning + br = yield # Invalid share + assert br.code == messages.ButtonRequestType.Warning debug.press_yes() yield # Homescreen @@ -206,8 +206,8 @@ def test_ask_word_number(client): for word in share: debug.input(word) - code = yield # Invalid share - assert code == messages.ButtonRequestType.Warning + br = yield # Invalid share + assert br.code == messages.ButtonRequestType.Warning debug.press_yes() yield # Proceed to next share @@ -257,8 +257,8 @@ def test_wrong_nth_word(client, nth_word): debug.input(share[-1]) break - code = yield - assert code == messages.ButtonRequestType.Warning + br = yield + assert br.code == messages.ButtonRequestType.Warning client.cancel() @@ -294,8 +294,8 @@ def test_same_share(client): for word in second_share: debug.input(word) - code = yield - assert code == messages.ButtonRequestType.Warning + br = yield + assert br.code == messages.ButtonRequestType.Warning client.cancel() diff --git a/tests/device_tests/test_msg_resetdevice_bip39_t2.py b/tests/device_tests/test_msg_resetdevice_bip39_t2.py index 12b60f1872..1f033140e2 100644 --- a/tests/device_tests/test_msg_resetdevice_bip39_t2.py +++ b/tests/device_tests/test_msg_resetdevice_bip39_t2.py @@ -27,15 +27,16 @@ from ..common import ( MNEMONIC12, click_through, generate_entropy, + paging_responses, read_and_confirm_mnemonic, ) EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2 -STRENGTH_TO_WORDS = {128: 12, 192: 18, 256: 24} def reset_device(client, strength): - words = STRENGTH_TO_WORDS[strength] + words = strength // 32 * 3 + mnemonic_pages = ((words + 3) // 4) + 1 mnemonic = None def input_flow(): @@ -46,18 +47,16 @@ def reset_device(client, strength): yield from click_through(client.debug, screens=3, code=B.ResetDevice) # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=words) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) # confirm recovery seed check - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # confirm success - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) @@ -68,7 +67,9 @@ def reset_device(client, strength): proto.EntropyRequest(), proto.ButtonRequest(code=B.ResetDevice), proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.ResetDevice), + ] + + paging_responses(mnemonic_pages, code=B.ResetDevice) + + [ proto.ButtonRequest(code=B.Success), proto.ButtonRequest(code=B.Success), proto.Success, @@ -123,13 +124,15 @@ class TestMsgResetDeviceT2: def test_reset_device_pin(self, client): mnemonic = None strength = 256 # 24 words + words = strength // 32 * 3 + mnemonic_pages = (words // 4) + 1 def input_flow(): nonlocal mnemonic # Confirm Reset - btn_code = yield - assert btn_code == B.ResetDevice + br = yield + assert br.code == B.ResetDevice client.debug.press_yes() # Enter new PIN @@ -141,33 +144,31 @@ class TestMsgResetDeviceT2: client.debug.input("654") # Confirm entropy - btn_code = yield - assert btn_code == B.ResetDevice + br = yield + assert br.code == B.ResetDevice client.debug.press_yes() # Backup your seed - btn_code = yield - assert btn_code == B.ResetDevice + br = yield + assert br.code == B.ResetDevice client.debug.press_yes() # Confirm warning - btn_code = yield - assert btn_code == B.ResetDevice + br = yield + assert br.code == B.ResetDevice client.debug.press_yes() # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=24) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) # confirm recovery seed check - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # confirm success - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) @@ -181,7 +182,9 @@ class TestMsgResetDeviceT2: proto.EntropyRequest(), proto.ButtonRequest(code=B.ResetDevice), proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.ResetDevice), + ] + + paging_responses(mnemonic_pages, code=B.ResetDevice) + + [ proto.ButtonRequest(code=B.Success), proto.ButtonRequest(code=B.Success), proto.Success, @@ -220,6 +223,8 @@ class TestMsgResetDeviceT2: def test_reset_failed_check(self, client): mnemonic = None strength = 256 # 24 words + words = strength // 32 * 3 + mnemonic_pages = (words // 4) + 1 def input_flow(): nonlocal mnemonic @@ -229,30 +234,26 @@ class TestMsgResetDeviceT2: yield from click_through(client.debug, screens=3, code=B.ResetDevice) # mnemonic phrases, wrong answer - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic( - client.debug, words=24, choose_wrong=True + mnemonic = yield from read_and_confirm_mnemonic( + client.debug, choose_wrong=True ) # warning screen - btn_code = yield - assert btn_code == B.ResetDevice + br = yield + assert br.code == B.ResetDevice client.debug.press_yes() # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=24) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) # confirm recovery seed check - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # confirm success - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) @@ -263,9 +264,11 @@ class TestMsgResetDeviceT2: proto.EntropyRequest(), proto.ButtonRequest(code=B.ResetDevice), proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.ResetDevice), + ] + + paging_responses(mnemonic_pages, code=B.ResetDevice) + + [proto.ButtonRequest(code=B.ResetDevice)] + + paging_responses(mnemonic_pages, code=B.ResetDevice) + + [ proto.ButtonRequest(code=B.Success), proto.ButtonRequest(code=B.Success), proto.Success, diff --git a/tests/device_tests/test_msg_resetdevice_slip39_advanced.py b/tests/device_tests/test_msg_resetdevice_slip39_advanced.py index d95e70de80..240159038c 100644 --- a/tests/device_tests/test_msg_resetdevice_slip39_advanced.py +++ b/tests/device_tests/test_msg_resetdevice_slip39_advanced.py @@ -23,7 +23,12 @@ from trezorlib import device, messages as proto from trezorlib.exceptions import TrezorFailure from trezorlib.messages import BackupType, ButtonRequestType as B -from ..common import click_through, generate_entropy, read_and_confirm_mnemonic +from ..common import ( + click_through, + generate_entropy, + paging_responses, + read_and_confirm_mnemonic, +) EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2 @@ -35,6 +40,7 @@ class TestMsgResetDeviceT2: def test_reset_device_slip39_advanced(self, client): strength = 128 word_count = 20 + mnemonic_page_count = (word_count // 4) + 1 member_threshold = 3 all_mnemonics = [] @@ -56,19 +62,17 @@ class TestMsgResetDeviceT2: for g in range(5): for h in range(5): # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) all_mnemonics.append(mnemonic) # Confirm continue to next share - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # safety warning - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) @@ -94,56 +98,14 @@ class TestMsgResetDeviceT2: proto.ButtonRequest(code=B.ResetDevice), proto.ButtonRequest(code=B.ResetDevice), # group #5 counts proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.ResetDevice), # show seeds + ] + + [ + # individual mnemonic + *paging_responses(mnemonic_page_count, code=B.ResetDevice), proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), # show seeds ends here + ] + * (5 * 5) # groups * shares + + [ proto.ButtonRequest(code=B.Success), proto.Success, proto.Features, diff --git a/tests/device_tests/test_msg_resetdevice_slip39_basic.py b/tests/device_tests/test_msg_resetdevice_slip39_basic.py index 3fc6944583..00d9760e16 100644 --- a/tests/device_tests/test_msg_resetdevice_slip39_basic.py +++ b/tests/device_tests/test_msg_resetdevice_slip39_basic.py @@ -28,14 +28,16 @@ from ..common import ( EXTERNAL_ENTROPY, click_through, generate_entropy, + paging_responses, read_and_confirm_mnemonic, ) -STRENGTH_TO_WORDS = {128: 20, 256: 33} - def reset_device(client, strength): - words = STRENGTH_TO_WORDS[strength] + # per SLIP-39: strength in bits, rounded up to nearest multiple of 10, plus 70 bits + # of metadata, split into 10-bit words + word_count = ((strength + 9) // 10) + 7 + mnemonic_pages = ((word_count + 3) // 4) + 1 member_threshold = 3 all_mnemonics = [] @@ -53,19 +55,17 @@ def reset_device(client, strength): # show & confirm shares for h in range(5): # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=words) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) all_mnemonics.append(mnemonic) # Confirm continue to next share - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # safety warning - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) @@ -81,16 +81,14 @@ def reset_device(client, strength): proto.ButtonRequest(code=B.ResetDevice), proto.ButtonRequest(code=B.ResetDevice), proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), - proto.ButtonRequest(code=B.Success), - proto.ButtonRequest(code=B.ResetDevice), + ] + + [ + # individual mnemonic + *paging_responses(mnemonic_pages, code=B.ResetDevice), proto.ButtonRequest(code=B.Success), + ] + * 5 # number of shares + + [ proto.ButtonRequest(code=B.Success), proto.Success, proto.Features, diff --git a/tests/device_tests/test_msg_signmessage.py b/tests/device_tests/test_msg_signmessage.py index e2a9a678bb..5483cd77cd 100644 --- a/tests/device_tests/test_msg_signmessage.py +++ b/tests/device_tests/test_msg_signmessage.py @@ -18,6 +18,7 @@ import pytest from trezorlib import btc, messages +from trezorlib.debuglink import message_filters from trezorlib.tools import parse_path S = messages.InputScriptType @@ -233,18 +234,20 @@ MESSAGE_LENGTHS = ( @pytest.mark.parametrize("message", MESSAGE_LENGTHS) def test_signmessage_pagination(client, message): message_read = "" - message += "End." def input_flow(): # collect screen contents into `message_read`. # Join lines that are separated by a single "-" string, space-separate lines otherwise. nonlocal message_read - yield # start assuming there was a word break; this avoids prepending space at start word_break = True - max_attempts = 100 - while max_attempts: + page = 0 + while True: + br = yield + assert br.page_number == page + 1 + page = br.page_number + layout = client.debug.wait_layout() for line in layout.lines[1:]: if line == "-": @@ -258,16 +261,12 @@ def test_signmessage_pagination(client, message): # attach with space message_read += " " + line - if not message_read.endswith("End."): + if page < br.pages: client.debug.swipe_up() else: client.debug.press_yes() break - max_attempts -= 1 - - assert max_attempts > 0, "failed to scroll through message" - with client: client.set_input_flow(input_flow) client.debug.watch_layout(True) @@ -282,13 +281,20 @@ def test_signmessage_pagination(client, message): @pytest.mark.skip_t1 def test_signmessage_pagination_trailing_newline(client): - # This can currently only be tested by a human via the UI test diff: message = "THIS\nMUST\nNOT\nBE\nPAGINATED\n" # The trailing newline must not cause a new paginated screen to appear. # The UI must be a single dialog without pagination. - btc.sign_message( - client, - coin_name="Bitcoin", - n=parse_path("m/44h/0h/0h/0/0"), - message=message, - ) + with client: + client.set_expected_responses( + [ + # expect a ButtonRequest that does not have pagination set + message_filters.ButtonRequest(pages=None), + messages.MessageSignature, + ] + ) + btc.sign_message( + client, + coin_name="Bitcoin", + n=parse_path("m/44h/0h/0h/0/0"), + message=message, + ) diff --git a/tests/device_tests/test_msg_signtx.py b/tests/device_tests/test_msg_signtx.py index 8cd15f95f5..ddd709b4cf 100644 --- a/tests/device_tests/test_msg_signtx.py +++ b/tests/device_tests/test_msg_signtx.py @@ -662,7 +662,7 @@ class TestMsgSigntx: nonlocal finished for expected in (B.ConfirmOutput, B.FeeOverThreshold, B.SignTx): br = yield - assert br == expected + assert br.code == expected client.debug.press_yes() finished = True diff --git a/tests/device_tests/test_msg_signtx_replacement.py b/tests/device_tests/test_msg_signtx_replacement.py index 54c3778a9c..d3a59de4f0 100644 --- a/tests/device_tests/test_msg_signtx_replacement.py +++ b/tests/device_tests/test_msg_signtx_replacement.py @@ -517,10 +517,7 @@ def test_p2wpkh_in_p2sh_fee_bump_from_external(client): request_output(0), request_orig_output(0, TXHASH_334cd7), messages.ButtonRequest(code=B.ConfirmOutput), - ( - client.features.model == "1", - messages.ButtonRequest(code=B.ConfirmOutput), - ), + messages.ButtonRequest(code=B.ConfirmOutput), request_orig_output(1, TXHASH_334cd7), messages.ButtonRequest(code=B.SignTx), request_input(0), diff --git a/tests/device_tests/test_msg_tezos_sign_tx.py b/tests/device_tests/test_msg_tezos_sign_tx.py index da847510da..1cec7f9dc7 100644 --- a/tests/device_tests/test_msg_tezos_sign_tx.py +++ b/tests/device_tests/test_msg_tezos_sign_tx.py @@ -29,15 +29,8 @@ TEZOS_PATH_15 = parse_path("m/44'/1729'/15'") @pytest.mark.tezos @pytest.mark.skip_t1 class TestMsgTezosSignTx: - def input_flow(self, debug, num_pages): - yield - for _ in range(num_pages - 1): - debug.swipe_up() - debug.press_yes() - def test_tezos_sign_tx_proposal(self, client): with client: - client.set_input_flow(self.input_flow(client.debug, num_pages=1)) resp = tezos.sign_tx( client, TEZOS_PATH_10, @@ -70,7 +63,6 @@ class TestMsgTezosSignTx: def test_tezos_sign_tx_multiple_proposals(self, client): with client: - client.set_input_flow(self.input_flow(client.debug, num_pages=2)) resp = tezos.sign_tx( client, TEZOS_PATH_10, diff --git a/tests/device_tests/test_reset_backup.py b/tests/device_tests/test_reset_backup.py index 9d58fe73b8..4e6f082245 100644 --- a/tests/device_tests/test_reset_backup.py +++ b/tests/device_tests/test_reset_backup.py @@ -23,11 +23,18 @@ from shamir_mnemonic import shamir from trezorlib import device, messages from trezorlib.messages import BackupType, ButtonRequestType as B -from ..common import EXTERNAL_ENTROPY, click_through, read_and_confirm_mnemonic +from ..common import ( + EXTERNAL_ENTROPY, + click_through, + paging_responses, + read_and_confirm_mnemonic, +) def backup_flow_bip39(client): mnemonic = None + words = 12 + mnemonic_pages = ((words + 3) // 4) + 1 def input_flow(): nonlocal mnemonic @@ -36,25 +43,25 @@ def backup_flow_bip39(client): yield from click_through(client.debug, screens=1, code=B.ResetDevice) # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=12) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) # confirm recovery seed check - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # confirm success - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() with client: client.set_expected_responses( [ messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), + ] + + paging_responses(mnemonic_pages, code=B.ResetDevice) + + [ messages.ButtonRequest(code=B.Success), messages.ButtonRequest(code=B.Success), messages.Success, @@ -69,6 +76,8 @@ def backup_flow_bip39(client): def backup_flow_slip39_basic(client): mnemonics = [] + words = 20 + mnemonic_pages = ((words + 3) // 4) + 1 def input_flow(): # 1. Checklist @@ -81,8 +90,8 @@ def backup_flow_slip39_basic(client): # Mnemonic phrases for _ in range(5): - yield # Phrase screen - mnemonic = read_and_confirm_mnemonic(client.debug, words=20) + # Phrase screen + mnemonic = yield from read_and_confirm_mnemonic(client.debug) mnemonics.append(mnemonic) yield # Confirm continue to next client.debug.press_yes() @@ -96,7 +105,7 @@ def backup_flow_slip39_basic(client): client.set_expected_responses( [messages.ButtonRequest(code=B.ResetDevice)] * 6 # intro screens + [ - messages.ButtonRequest(code=B.ResetDevice), + *paging_responses(mnemonic_pages, code=B.ResetDevice), messages.ButtonRequest(code=B.Success), ] * 5 # individual shares @@ -115,6 +124,8 @@ def backup_flow_slip39_basic(client): def backup_flow_slip39_advanced(client): mnemonics = [] + words = 20 + mnemonic_pages = ((words + 3) // 4) + 1 def input_flow(): # 1. Confirm Reset @@ -132,19 +143,17 @@ def backup_flow_slip39_advanced(client): for _ in range(5): for _ in range(5): # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=20) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) mnemonics.append(mnemonic) # Confirm continue to next share - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # safety warning - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() with client: @@ -157,7 +166,7 @@ def backup_flow_slip39_advanced(client): ] * 5 # group thresholds + [ - messages.ButtonRequest(code=B.ResetDevice), + *paging_responses(mnemonic_pages, code=B.ResetDevice), messages.ButtonRequest(code=B.Success), ] * 25 # individual shares diff --git a/tests/device_tests/test_reset_recovery_bip39.py b/tests/device_tests/test_reset_recovery_bip39.py index 7fe6dd54ff..2eda9ccb08 100644 --- a/tests/device_tests/test_reset_recovery_bip39.py +++ b/tests/device_tests/test_reset_recovery_bip39.py @@ -23,7 +23,12 @@ from trezorlib import btc, device, messages from trezorlib.messages import BackupType, ButtonRequestType as B from trezorlib.tools import parse_path -from ..common import EXTERNAL_ENTROPY, click_through, read_and_confirm_mnemonic +from ..common import ( + EXTERNAL_ENTROPY, + click_through, + paging_responses, + read_and_confirm_mnemonic, +) @pytest.mark.skip_t1 @@ -39,8 +44,9 @@ def test_reset_recovery(client): def reset(client, strength=128, skip_backup=False): + words = strength // 32 * 3 + mnemonic_pages = ((words + 3) // 4) + 1 mnemonic = None - word_count = strength // 32 * 3 def input_flow(): nonlocal mnemonic @@ -51,28 +57,29 @@ def reset(client, strength=128, skip_backup=False): yield from click_through(client.debug, screens=3, code=B.ResetDevice) # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) # confirm recovery seed check - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # confirm success - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() - with client: + os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) + with mock.patch("os.urandom", os_urandom), client: client.set_expected_responses( [ messages.ButtonRequest(code=B.ResetDevice), messages.EntropyRequest(), messages.ButtonRequest(code=B.ResetDevice), messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), + ] + + paging_responses(mnemonic_pages, code=B.ResetDevice) + + [ messages.ButtonRequest(code=B.Success), messages.ButtonRequest(code=B.Success), messages.Success, @@ -81,19 +88,17 @@ def reset(client, strength=128, skip_backup=False): ) client.set_input_flow(input_flow) - os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) - with mock.patch("os.urandom", os_urandom), client: - # No PIN, no passphrase, don't display random - device.reset( - client, - display_random=False, - strength=strength, - passphrase_protection=False, - pin_protection=False, - label="test", - language="en-US", - backup_type=BackupType.Bip39, - ) + # No PIN, no passphrase, don't display random + device.reset( + client, + display_random=False, + strength=strength, + passphrase_protection=False, + pin_protection=False, + label="test", + language="en-US", + backup_type=BackupType.Bip39, + ) # Check if device is properly initialized assert client.features.initialized is True diff --git a/tests/device_tests/test_reset_recovery_slip39_advanced.py b/tests/device_tests/test_reset_recovery_slip39_advanced.py index 86eed36ea4..02133de6ed 100644 --- a/tests/device_tests/test_reset_recovery_slip39_advanced.py +++ b/tests/device_tests/test_reset_recovery_slip39_advanced.py @@ -25,6 +25,7 @@ from trezorlib.tools import parse_path from ..common import ( EXTERNAL_ENTROPY, click_through, + paging_responses, read_and_confirm_mnemonic, recovery_enter_shares, ) @@ -62,6 +63,7 @@ def reset(client, strength=128): # per SLIP-39: strength in bits, rounded up to nearest multiple of 10, plus 70 bits # of metadata, split into 10-bit words word_count = ((strength + 9) // 10) + 7 + mnemonic_pages = ((word_count + 3) // 4) + 1 def input_flow(): # 1. Confirm Reset @@ -81,19 +83,17 @@ def reset(client, strength=128): for g in range(5): for h in range(5): # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) all_mnemonics.append(mnemonic) # Confirm continue to next share - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # safety warning - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) @@ -119,56 +119,14 @@ def reset(client, strength=128): messages.ButtonRequest(code=B.ResetDevice), messages.ButtonRequest(code=B.ResetDevice), # group #5 counts messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), # show seeds + ] + + [ + # individual mnemonic + *paging_responses(mnemonic_pages, code=B.ResetDevice), messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), # show seeds ends here + ] + * (5 * 5) # groups * shares + + [ messages.ButtonRequest(code=B.Success), messages.Success, messages.Features, diff --git a/tests/device_tests/test_reset_recovery_slip39_basic.py b/tests/device_tests/test_reset_recovery_slip39_basic.py index 43ad63cbad..37b69b614d 100644 --- a/tests/device_tests/test_reset_recovery_slip39_basic.py +++ b/tests/device_tests/test_reset_recovery_slip39_basic.py @@ -23,7 +23,12 @@ from trezorlib import btc, device, messages from trezorlib.messages import BackupType, ButtonRequestType as B from trezorlib.tools import parse_path -from ..common import click_through, read_and_confirm_mnemonic, recovery_enter_shares +from ..common import ( + click_through, + paging_responses, + read_and_confirm_mnemonic, + recovery_enter_shares, +) EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2 MOCK_OS_URANDOM = mock.Mock(return_value=EXTERNAL_ENTROPY) @@ -49,6 +54,7 @@ def reset(client, strength=128): # per SLIP-39: strength in bits, rounded up to nearest multiple of 10, plus 70 bits # of metadata, split into 10-bit words word_count = ((strength + 9) // 10) + 7 + mnemonic_pages = ((word_count + 3) // 4) + 1 def input_flow(): # 1. Confirm Reset @@ -64,19 +70,17 @@ def reset(client, strength=128): # show & confirm shares for h in range(5): # mnemonic phrases - btn_code = yield - assert btn_code == B.ResetDevice - mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count) + mnemonic = yield from read_and_confirm_mnemonic(client.debug) all_mnemonics.append(mnemonic) # Confirm continue to next share - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() # safety warning - btn_code = yield - assert btn_code == B.Success + br = yield + assert br.code == B.Success client.debug.press_yes() with client: @@ -91,16 +95,14 @@ def reset(client, strength=128): messages.ButtonRequest(code=B.ResetDevice), messages.ButtonRequest(code=B.ResetDevice), messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), - messages.ButtonRequest(code=B.Success), - messages.ButtonRequest(code=B.ResetDevice), + ] + + [ + # individual mnemonic + *paging_responses(mnemonic_pages, code=B.ResetDevice), messages.ButtonRequest(code=B.Success), + ] + * 5 # number of shares + + [ messages.ButtonRequest(code=B.Success), messages.Success, messages.Features,