mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-24 15:28:10 +00:00
chore(tests): adapt device tests to paging information ButtonRequests
This commit is contained in:
parent
d047c98cb2
commit
7cdde940af
23
common/tests/fixtures/cardano/sign_tx.json
vendored
23
common/tests/fixtures/cardano/sign_tx.json
vendored
@ -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",
|
||||
|
@ -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)"""
|
||||
|
@ -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")
|
||||
|
@ -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,
|
||||
|
@ -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 (
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user