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": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/44'/1815'/0'/0/1",
|
"path": "m/44'/1815'/0'/0/1",
|
||||||
@ -44,7 +43,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/44'/1815'/0'/0/1",
|
"path": "m/44'/1815'/0'/0/1",
|
||||||
@ -79,7 +77,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -115,7 +112,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/44'/1815'/0'/0/1",
|
"path": "m/44'/1815'/0'/0/1",
|
||||||
@ -160,7 +156,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -197,7 +192,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -234,7 +228,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -270,7 +263,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -306,7 +298,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -344,7 +335,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -384,7 +374,6 @@
|
|||||||
],
|
],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -419,7 +408,6 @@
|
|||||||
],
|
],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -455,7 +443,6 @@
|
|||||||
],
|
],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -487,7 +474,6 @@
|
|||||||
],
|
],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -527,7 +513,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -563,7 +548,6 @@
|
|||||||
],
|
],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -595,7 +579,6 @@
|
|||||||
"auxiliary_data": {
|
"auxiliary_data": {
|
||||||
"blob": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
"blob": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
},
|
},
|
||||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -636,7 +619,6 @@
|
|||||||
"nonce": 22634813
|
"nonce": 22634813
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["SWIPE", "SWIPE", "SWIPE", "SWIPE", "SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -666,7 +648,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/44'/1815'/0'/0/1",
|
"path": "m/44'/1815'/0'/0/1",
|
||||||
@ -706,7 +687,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -754,7 +734,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -813,7 +792,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/1852'/1815'/0'/0/0",
|
"path": "m/1852'/1815'/0'/0/0",
|
||||||
@ -844,7 +822,6 @@
|
|||||||
"certificates": [],
|
"certificates": [],
|
||||||
"withdrawals": [],
|
"withdrawals": [],
|
||||||
"auxiliary_data": null,
|
"auxiliary_data": null,
|
||||||
"input_flow": [["YES"], ["YES"]],
|
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"path": "m/44'/1815'/0'/0/0",
|
"path": "m/44'/1815'/0'/0/0",
|
||||||
|
@ -20,7 +20,7 @@ from pathlib import Path
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import btc, tools
|
from trezorlib import btc, tools
|
||||||
from trezorlib.messages import ButtonRequestType as B
|
from trezorlib.messages import ButtonRequest, ButtonRequestType as B
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
# 1 2 3 4 5 6 7 8 9 10 11 12
|
# 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
|
yield
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
# Input word number
|
# Input word number
|
||||||
code = yield
|
br = yield
|
||||||
assert code == B.MnemonicWordCount
|
assert br.code == B.MnemonicWordCount
|
||||||
debug.input(str(word_count))
|
debug.input(str(word_count))
|
||||||
# Homescreen - proceed to share entry
|
# Homescreen - proceed to share entry
|
||||||
yield
|
yield
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
# Enter shares
|
# Enter shares
|
||||||
for index, share in enumerate(shares):
|
for index, share in enumerate(shares):
|
||||||
code = yield
|
br = yield
|
||||||
assert code == B.MnemonicInput
|
assert br.code == B.MnemonicInput
|
||||||
# Enter mnemonic words
|
# Enter mnemonic words
|
||||||
for word in share.split(" "):
|
for word in share.split(" "):
|
||||||
debug.input(word)
|
debug.input(word)
|
||||||
@ -171,11 +171,11 @@ def click_through(debug, screens, code=None):
|
|||||||
for _ in range(screens):
|
for _ in range(screens):
|
||||||
received = yield
|
received = yield
|
||||||
if code is not None:
|
if code is not None:
|
||||||
assert received == code
|
assert received.code == code
|
||||||
debug.press_yes()
|
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
|
"""Read a given number of mnemonic words from Trezor T screen and correctly
|
||||||
answer confirmation questions. Return the full mnemonic.
|
answer confirmation questions. Return the full mnemonic.
|
||||||
|
|
||||||
@ -185,13 +185,13 @@ def read_and_confirm_mnemonic(debug, words, choose_wrong=False):
|
|||||||
def input_flow():
|
def input_flow():
|
||||||
yield from click_through(client.debug, screens=3)
|
yield from click_through(client.debug, screens=3)
|
||||||
|
|
||||||
yield # confirm mnemonic entry
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
|
|
||||||
"""
|
"""
|
||||||
mnemonic = []
|
mnemonic = []
|
||||||
while True:
|
while True:
|
||||||
|
br = yield
|
||||||
mnemonic.extend(debug.read_reset_word().split())
|
mnemonic.extend(debug.read_reset_word().split())
|
||||||
if len(mnemonic) < words:
|
if br.page_number < br.pages:
|
||||||
debug.swipe_up()
|
debug.swipe_up()
|
||||||
else:
|
else:
|
||||||
# last page is confirmation
|
# last page is confirmation
|
||||||
@ -210,6 +210,15 @@ def read_and_confirm_mnemonic(debug, words, choose_wrong=False):
|
|||||||
return " ".join(mnemonic)
|
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):
|
def get_test_address(client):
|
||||||
"""Fetch a testnet address on a fixed path. Useful to make a pin/passphrase
|
"""Fetch a testnet address on a fixed path. Useful to make a pin/passphrase
|
||||||
protected call, or to identify the root secret (seed+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"]]
|
withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]]
|
||||||
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
|
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
|
||||||
|
|
||||||
input_flow = parameters.get("input_flow", ())
|
|
||||||
|
|
||||||
if parameters.get("security_checks") == "prompt":
|
if parameters.get("security_checks") == "prompt":
|
||||||
device.apply_settings(
|
device.apply_settings(
|
||||||
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
|
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)
|
device.apply_settings(client, safety_checks=messages.SafetyCheckLevel.Strict)
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(_to_device_actions(client, input_flow))
|
|
||||||
|
|
||||||
response = cardano.sign_tx(
|
response = cardano.sign_tx(
|
||||||
client=client,
|
client=client,
|
||||||
inputs=inputs,
|
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"]]
|
withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]]
|
||||||
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
|
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
|
||||||
|
|
||||||
input_flow = parameters.get("input_flow", ())
|
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(_to_device_actions(client, input_flow))
|
|
||||||
|
|
||||||
with pytest.raises(TrezorFailure, match=result["error_message"]):
|
with pytest.raises(TrezorFailure, match=result["error_message"]):
|
||||||
cardano.sign_tx(
|
cardano.sign_tx(
|
||||||
client=client,
|
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"]]
|
withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]]
|
||||||
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
|
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
|
||||||
|
|
||||||
input_flow = parameters.get("input_flow", ())
|
|
||||||
|
|
||||||
expected_responses = [
|
expected_responses = [
|
||||||
messages.PassphraseRequest(),
|
messages.PassphraseRequest(),
|
||||||
messages.ButtonRequest(),
|
# XXX as many ButtonRequests as paginations. We are relying on the fact that
|
||||||
messages.ButtonRequest(),
|
# 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 += [
|
expected_responses += [
|
||||||
messages.CardanoSignedTxChunk(signed_tx_chunk=bytes.fromhex(signed_tx_chunk))
|
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:
|
with client:
|
||||||
client.set_input_flow(_to_device_actions(client, input_flow))
|
|
||||||
client.set_expected_responses(expected_responses)
|
client.set_expected_responses(expected_responses)
|
||||||
|
|
||||||
response = cardano.sign_tx(
|
response = cardano.sign_tx(
|
||||||
client=client,
|
client=client,
|
||||||
inputs=inputs,
|
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.tx_hash.hex() == result["tx_hash"]
|
||||||
assert response.serialized_tx.hex() == result["serialized_tx"]
|
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_ADVANCED_20,
|
||||||
MNEMONIC_SLIP39_BASIC_20_3of6,
|
MNEMONIC_SLIP39_BASIC_20_3of6,
|
||||||
click_through,
|
click_through,
|
||||||
|
paging_responses,
|
||||||
read_and_confirm_mnemonic,
|
read_and_confirm_mnemonic,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,13 +37,15 @@ from ..common import (
|
|||||||
def test_backup_bip39(client):
|
def test_backup_bip39(client):
|
||||||
assert client.features.needs_backup is True
|
assert client.features.needs_backup is True
|
||||||
mnemonic = None
|
mnemonic = None
|
||||||
|
words = 12
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
nonlocal mnemonic
|
nonlocal mnemonic
|
||||||
yield # Confirm Backup
|
yield # Confirm Backup
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
yield # Mnemonic phrases
|
# Mnemonic phrases
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=12)
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
yield # Confirm success
|
yield # Confirm success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
yield # Backup is done
|
yield # Backup is done
|
||||||
@ -53,7 +56,9 @@ def test_backup_bip39(client):
|
|||||||
client.set_expected_responses(
|
client.set_expected_responses(
|
||||||
[
|
[
|
||||||
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.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
@ -76,6 +81,8 @@ def test_backup_bip39(client):
|
|||||||
def test_backup_slip39_basic(client):
|
def test_backup_slip39_basic(client):
|
||||||
assert client.features.needs_backup is True
|
assert client.features.needs_backup is True
|
||||||
mnemonics = []
|
mnemonics = []
|
||||||
|
words = 20
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
# 1. Checklist
|
# 1. Checklist
|
||||||
@ -88,8 +95,8 @@ def test_backup_slip39_basic(client):
|
|||||||
|
|
||||||
# Mnemonic phrases
|
# Mnemonic phrases
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
yield # Phrase screen
|
# Phrase screen
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
mnemonics.append(mnemonic)
|
mnemonics.append(mnemonic)
|
||||||
yield # Confirm continue to next
|
yield # Confirm continue to next
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
@ -101,23 +108,13 @@ def test_backup_slip39_basic(client):
|
|||||||
with client:
|
with client:
|
||||||
client.set_input_flow(input_flow)
|
client.set_input_flow(input_flow)
|
||||||
client.set_expected_responses(
|
client.set_expected_responses(
|
||||||
[
|
[messages.ButtonRequest(code=B.ResetDevice)] * 6 # intro screens
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
+ [
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
*paging_responses(mnemonic_pages, 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.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
|
]
|
||||||
|
* 5 # individual shares
|
||||||
|
+ [
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
messages.Features,
|
messages.Features,
|
||||||
@ -142,6 +139,8 @@ def test_backup_slip39_basic(client):
|
|||||||
def test_backup_slip39_advanced(client):
|
def test_backup_slip39_advanced(client):
|
||||||
assert client.features.needs_backup is True
|
assert client.features.needs_backup is True
|
||||||
mnemonics = []
|
mnemonics = []
|
||||||
|
words = 20
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
# 1. Checklist
|
# 1. Checklist
|
||||||
@ -158,8 +157,8 @@ def test_backup_slip39_advanced(client):
|
|||||||
# Mnemonic phrases
|
# Mnemonic phrases
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
yield # Phrase screen
|
# Phrase screen
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
mnemonics.append(mnemonic)
|
mnemonics.append(mnemonic)
|
||||||
yield # Confirm continue to next
|
yield # Confirm continue to next
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
@ -171,73 +170,18 @@ def test_backup_slip39_advanced(client):
|
|||||||
with client:
|
with client:
|
||||||
client.set_input_flow(input_flow)
|
client.set_input_flow(input_flow)
|
||||||
client.set_expected_responses(
|
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),
|
* 5 # group thresholds
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
+ [
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
*paging_responses(mnemonic_pages, 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
|
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
]
|
||||||
messages.ButtonRequest(code=B.Success),
|
* 25 # individual shares
|
||||||
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
|
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
messages.Features,
|
messages.Features,
|
||||||
|
@ -31,20 +31,6 @@ ADDRESS_N = parse_path("m/44'/194'/0'/0/0")
|
|||||||
@pytest.mark.skip_t1
|
@pytest.mark.skip_t1
|
||||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||||
class TestMsgEosSignTx:
|
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):
|
def test_eos_signtx_transfer_token(self, client):
|
||||||
transaction = {
|
transaction = {
|
||||||
"expiration": "2018-07-14T10:43:28",
|
"expiration": "2018-07-14T10:43:28",
|
||||||
@ -73,7 +59,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=3))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -108,7 +93,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=2))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -143,7 +127,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=2))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -174,7 +157,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=2))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -211,7 +193,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=3))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -247,7 +228,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=2))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -278,7 +258,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=0))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -314,7 +293,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=2))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -349,7 +327,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=2))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -407,7 +384,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=8))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -438,7 +414,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=0))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -503,7 +478,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=6))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -534,7 +508,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=0))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -565,7 +538,6 @@ class TestMsgEosSignTx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, pages=2))
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -646,36 +618,7 @@ class TestMsgEosSignTx:
|
|||||||
"transaction_extensions": [],
|
"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:
|
with client:
|
||||||
client.set_input_flow(input_flow)
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
@ -714,27 +657,7 @@ class TestMsgEosSignTx:
|
|||||||
"context_free_data": [],
|
"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:
|
with client:
|
||||||
client.set_input_flow(input_flow)
|
|
||||||
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
resp = eos.sign_tx(client, ADDRESS_N, transaction, CHAIN_ID)
|
||||||
assert isinstance(resp, EosSignedTx)
|
assert isinstance(resp, EosSignedTx)
|
||||||
assert (
|
assert (
|
||||||
|
@ -177,7 +177,7 @@ def test_show_multisig_xpubs(
|
|||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
yield # show address
|
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 lines[0] == "Multisig 2 of 3"
|
||||||
assert "".join(lines[1:]) == address
|
assert "".join(lines[1:]) == address
|
||||||
|
|
||||||
@ -190,6 +190,7 @@ def test_show_multisig_xpubs(
|
|||||||
lines1 = client.debug.wait_layout().lines
|
lines1 = client.debug.wait_layout().lines
|
||||||
assert lines1[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)")
|
assert lines1[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)")
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
|
yield
|
||||||
lines2 = client.debug.wait_layout().lines
|
lines2 = client.debug.wait_layout().lines
|
||||||
assert lines2[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)")
|
assert lines2[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)")
|
||||||
assert "".join(lines1[1:] + lines2[1:]) == xpubs[0]
|
assert "".join(lines1[1:] + lines2[1:]) == xpubs[0]
|
||||||
@ -199,6 +200,7 @@ def test_show_multisig_xpubs(
|
|||||||
lines1 = client.debug.wait_layout().lines
|
lines1 = client.debug.wait_layout().lines
|
||||||
assert lines1[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)")
|
assert lines1[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)")
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
|
yield
|
||||||
lines2 = client.debug.wait_layout().lines
|
lines2 = client.debug.wait_layout().lines
|
||||||
assert lines2[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)")
|
assert lines2[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)")
|
||||||
assert "".join(lines1[1:] + lines2[1:]) == xpubs[1]
|
assert "".join(lines1[1:] + lines2[1:]) == xpubs[1]
|
||||||
@ -208,6 +210,7 @@ def test_show_multisig_xpubs(
|
|||||||
lines1 = client.debug.wait_layout().lines
|
lines1 = client.debug.wait_layout().lines
|
||||||
assert lines1[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)")
|
assert lines1[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)")
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
|
yield
|
||||||
lines2 = client.debug.wait_layout().lines
|
lines2 = client.debug.wait_layout().lines
|
||||||
assert lines2[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)")
|
assert lines2[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)")
|
||||||
assert "".join(lines1[1:] + lines2[1:]) == xpubs[2]
|
assert "".join(lines1[1:] + lines2[1:]) == xpubs[2]
|
||||||
|
@ -16,48 +16,27 @@
|
|||||||
|
|
||||||
import pytest
|
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.altcoin
|
||||||
@pytest.mark.lisk
|
@pytest.mark.lisk
|
||||||
class TestMsgLiskVerifymessage:
|
@pytest.mark.parametrize("pubkey, signature, message", VECTORS)
|
||||||
def test_verify(self, client):
|
def test_verify(client, pubkey, signature, message):
|
||||||
with client:
|
with client:
|
||||||
client.set_expected_responses(
|
lisk.verify_message(
|
||||||
[
|
client, bytes.fromhex(pubkey), bytes.fromhex(signature), message
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import messages as proto, nem
|
from trezorlib import nem
|
||||||
from trezorlib.messages import ButtonRequestType as B
|
|
||||||
from trezorlib.tools import parse_path
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
from ..common import MNEMONIC12
|
from ..common import MNEMONIC12
|
||||||
|
|
||||||
|
ADDRESS_N = parse_path("m/44'/1'/0'/0'/0'")
|
||||||
|
|
||||||
|
|
||||||
# assertion data from T1
|
# assertion data from T1
|
||||||
@pytest.mark.altcoin
|
@pytest.mark.altcoin
|
||||||
@ -78,7 +79,7 @@ class TestMsgNEMSignTxMosaics:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# not using client.nem_sign_tx() because of swiping
|
# 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 (
|
assert (
|
||||||
tx.data.hex()
|
tx.data.hex()
|
||||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||||
@ -113,7 +114,7 @@ class TestMsgNEMSignTxMosaics:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# not using client.nem_sign_tx() because of swiping
|
# 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 (
|
assert (
|
||||||
tx.data.hex()
|
tx.data.hex()
|
||||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||||
@ -152,7 +153,7 @@ class TestMsgNEMSignTxMosaics:
|
|||||||
"creationFee": 1500,
|
"creationFee": 1500,
|
||||||
}
|
}
|
||||||
|
|
||||||
tx = self._nem_sign(client, 6, test_suite)
|
tx = nem.sign_tx(client, ADDRESS_N, test_suite)
|
||||||
assert (
|
assert (
|
||||||
tx.data.hex()
|
tx.data.hex()
|
||||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||||
@ -161,41 +162,3 @@ class TestMsgNEMSignTxMosaics:
|
|||||||
tx.signature.hex()
|
tx.signature.hex()
|
||||||
== "b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a"
|
== "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"
|
assert layout.text == "Bip39Keyboard"
|
||||||
client.debug.input("stick")
|
client.debug.input("stick")
|
||||||
|
|
||||||
code = yield
|
br = yield
|
||||||
layout = client.debug.wait_layout()
|
layout = client.debug.wait_layout()
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
assert "invalid recovery seed" in layout.text
|
assert "invalid recovery seed" in layout.text
|
||||||
client.debug.click(buttons.OK)
|
client.debug.click(buttons.OK)
|
||||||
|
|
||||||
|
@ -164,8 +164,8 @@ def test_same_share(client):
|
|||||||
for word in second_share:
|
for word in second_share:
|
||||||
debug.input(word)
|
debug.input(word)
|
||||||
|
|
||||||
code = yield
|
br = yield
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
|
|
||||||
client.cancel()
|
client.cancel()
|
||||||
|
|
||||||
@ -204,8 +204,8 @@ def test_group_threshold_reached(client):
|
|||||||
for word in second_share:
|
for word in second_share:
|
||||||
debug.input(word)
|
debug.input(word)
|
||||||
|
|
||||||
code = yield
|
br = yield
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
|
|
||||||
client.cancel()
|
client.cancel()
|
||||||
|
|
||||||
|
@ -154,8 +154,8 @@ def test_ask_word_number(client):
|
|||||||
for _ in range(20):
|
for _ in range(20):
|
||||||
debug.input("slush")
|
debug.input("slush")
|
||||||
|
|
||||||
code = yield # Invalid share
|
br = yield # Invalid share
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
|
|
||||||
yield # Homescreen - start process
|
yield # Homescreen - start process
|
||||||
@ -168,8 +168,8 @@ def test_ask_word_number(client):
|
|||||||
for _ in range(33):
|
for _ in range(33):
|
||||||
debug.input("slush")
|
debug.input("slush")
|
||||||
|
|
||||||
code = yield # Invalid share
|
br = yield # Invalid share
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
|
|
||||||
yield # Homescreen
|
yield # Homescreen
|
||||||
@ -206,8 +206,8 @@ def test_ask_word_number(client):
|
|||||||
for word in share:
|
for word in share:
|
||||||
debug.input(word)
|
debug.input(word)
|
||||||
|
|
||||||
code = yield # Invalid share
|
br = yield # Invalid share
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
debug.press_yes()
|
debug.press_yes()
|
||||||
|
|
||||||
yield # Proceed to next share
|
yield # Proceed to next share
|
||||||
@ -257,8 +257,8 @@ def test_wrong_nth_word(client, nth_word):
|
|||||||
debug.input(share[-1])
|
debug.input(share[-1])
|
||||||
break
|
break
|
||||||
|
|
||||||
code = yield
|
br = yield
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
|
|
||||||
client.cancel()
|
client.cancel()
|
||||||
|
|
||||||
@ -294,8 +294,8 @@ def test_same_share(client):
|
|||||||
for word in second_share:
|
for word in second_share:
|
||||||
debug.input(word)
|
debug.input(word)
|
||||||
|
|
||||||
code = yield
|
br = yield
|
||||||
assert code == messages.ButtonRequestType.Warning
|
assert br.code == messages.ButtonRequestType.Warning
|
||||||
|
|
||||||
client.cancel()
|
client.cancel()
|
||||||
|
|
||||||
|
@ -27,15 +27,16 @@ from ..common import (
|
|||||||
MNEMONIC12,
|
MNEMONIC12,
|
||||||
click_through,
|
click_through,
|
||||||
generate_entropy,
|
generate_entropy,
|
||||||
|
paging_responses,
|
||||||
read_and_confirm_mnemonic,
|
read_and_confirm_mnemonic,
|
||||||
)
|
)
|
||||||
|
|
||||||
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
|
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
|
||||||
STRENGTH_TO_WORDS = {128: 12, 192: 18, 256: 24}
|
|
||||||
|
|
||||||
|
|
||||||
def reset_device(client, strength):
|
def reset_device(client, strength):
|
||||||
words = STRENGTH_TO_WORDS[strength]
|
words = strength // 32 * 3
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
mnemonic = None
|
mnemonic = None
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
@ -46,18 +47,16 @@ def reset_device(client, strength):
|
|||||||
yield from click_through(client.debug, screens=3, code=B.ResetDevice)
|
yield from click_through(client.debug, screens=3, code=B.ResetDevice)
|
||||||
|
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=words)
|
|
||||||
|
|
||||||
# confirm recovery seed check
|
# confirm recovery seed check
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# confirm success
|
# confirm success
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||||
@ -68,7 +67,9 @@ def reset_device(client, strength):
|
|||||||
proto.EntropyRequest(),
|
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.Success),
|
proto.ButtonRequest(code=B.Success),
|
||||||
proto.ButtonRequest(code=B.Success),
|
proto.ButtonRequest(code=B.Success),
|
||||||
proto.Success,
|
proto.Success,
|
||||||
@ -123,13 +124,15 @@ class TestMsgResetDeviceT2:
|
|||||||
def test_reset_device_pin(self, client):
|
def test_reset_device_pin(self, client):
|
||||||
mnemonic = None
|
mnemonic = None
|
||||||
strength = 256 # 24 words
|
strength = 256 # 24 words
|
||||||
|
words = strength // 32 * 3
|
||||||
|
mnemonic_pages = (words // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
nonlocal mnemonic
|
nonlocal mnemonic
|
||||||
|
|
||||||
# Confirm Reset
|
# Confirm Reset
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.ResetDevice
|
assert br.code == B.ResetDevice
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# Enter new PIN
|
# Enter new PIN
|
||||||
@ -141,33 +144,31 @@ class TestMsgResetDeviceT2:
|
|||||||
client.debug.input("654")
|
client.debug.input("654")
|
||||||
|
|
||||||
# Confirm entropy
|
# Confirm entropy
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.ResetDevice
|
assert br.code == B.ResetDevice
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# Backup your seed
|
# Backup your seed
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.ResetDevice
|
assert br.code == B.ResetDevice
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# Confirm warning
|
# Confirm warning
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.ResetDevice
|
assert br.code == B.ResetDevice
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=24)
|
|
||||||
|
|
||||||
# confirm recovery seed check
|
# confirm recovery seed check
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# confirm success
|
# confirm success
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||||
@ -181,7 +182,9 @@ class TestMsgResetDeviceT2:
|
|||||||
proto.EntropyRequest(),
|
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.Success),
|
proto.ButtonRequest(code=B.Success),
|
||||||
proto.ButtonRequest(code=B.Success),
|
proto.ButtonRequest(code=B.Success),
|
||||||
proto.Success,
|
proto.Success,
|
||||||
@ -220,6 +223,8 @@ class TestMsgResetDeviceT2:
|
|||||||
def test_reset_failed_check(self, client):
|
def test_reset_failed_check(self, client):
|
||||||
mnemonic = None
|
mnemonic = None
|
||||||
strength = 256 # 24 words
|
strength = 256 # 24 words
|
||||||
|
words = strength // 32 * 3
|
||||||
|
mnemonic_pages = (words // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
nonlocal mnemonic
|
nonlocal mnemonic
|
||||||
@ -229,30 +234,26 @@ class TestMsgResetDeviceT2:
|
|||||||
yield from click_through(client.debug, screens=3, code=B.ResetDevice)
|
yield from click_through(client.debug, screens=3, code=B.ResetDevice)
|
||||||
|
|
||||||
# mnemonic phrases, wrong answer
|
# mnemonic phrases, wrong answer
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(
|
||||||
assert btn_code == B.ResetDevice
|
client.debug, choose_wrong=True
|
||||||
mnemonic = read_and_confirm_mnemonic(
|
|
||||||
client.debug, words=24, choose_wrong=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# warning screen
|
# warning screen
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.ResetDevice
|
assert br.code == B.ResetDevice
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=24)
|
|
||||||
|
|
||||||
# confirm recovery seed check
|
# confirm recovery seed check
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# confirm success
|
# confirm success
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||||
@ -263,9 +264,11 @@ class TestMsgResetDeviceT2:
|
|||||||
proto.EntropyRequest(),
|
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),
|
]
|
||||||
proto.ButtonRequest(code=B.ResetDevice),
|
+ paging_responses(mnemonic_pages, 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.ButtonRequest(code=B.Success),
|
proto.ButtonRequest(code=B.Success),
|
||||||
proto.Success,
|
proto.Success,
|
||||||
|
@ -23,7 +23,12 @@ from trezorlib import device, messages as proto
|
|||||||
from trezorlib.exceptions import TrezorFailure
|
from trezorlib.exceptions import TrezorFailure
|
||||||
from trezorlib.messages import BackupType, ButtonRequestType as B
|
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
|
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
|
||||||
|
|
||||||
@ -35,6 +40,7 @@ class TestMsgResetDeviceT2:
|
|||||||
def test_reset_device_slip39_advanced(self, client):
|
def test_reset_device_slip39_advanced(self, client):
|
||||||
strength = 128
|
strength = 128
|
||||||
word_count = 20
|
word_count = 20
|
||||||
|
mnemonic_page_count = (word_count // 4) + 1
|
||||||
member_threshold = 3
|
member_threshold = 3
|
||||||
all_mnemonics = []
|
all_mnemonics = []
|
||||||
|
|
||||||
@ -56,19 +62,17 @@ class TestMsgResetDeviceT2:
|
|||||||
for g in range(5):
|
for g in range(5):
|
||||||
for h in range(5):
|
for h in range(5):
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count)
|
|
||||||
all_mnemonics.append(mnemonic)
|
all_mnemonics.append(mnemonic)
|
||||||
|
|
||||||
# Confirm continue to next share
|
# Confirm continue to next share
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# safety warning
|
# safety warning
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||||
@ -94,56 +98,14 @@ class TestMsgResetDeviceT2:
|
|||||||
proto.ButtonRequest(code=B.ResetDevice),
|
proto.ButtonRequest(code=B.ResetDevice),
|
||||||
proto.ButtonRequest(code=B.ResetDevice), # group #5 counts
|
proto.ButtonRequest(code=B.ResetDevice), # group #5 counts
|
||||||
proto.ButtonRequest(code=B.ResetDevice),
|
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.Success),
|
||||||
proto.ButtonRequest(code=B.ResetDevice),
|
]
|
||||||
proto.ButtonRequest(code=B.Success),
|
* (5 * 5) # groups * shares
|
||||||
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
|
|
||||||
proto.ButtonRequest(code=B.Success),
|
proto.ButtonRequest(code=B.Success),
|
||||||
proto.Success,
|
proto.Success,
|
||||||
proto.Features,
|
proto.Features,
|
||||||
|
@ -28,14 +28,16 @@ from ..common import (
|
|||||||
EXTERNAL_ENTROPY,
|
EXTERNAL_ENTROPY,
|
||||||
click_through,
|
click_through,
|
||||||
generate_entropy,
|
generate_entropy,
|
||||||
|
paging_responses,
|
||||||
read_and_confirm_mnemonic,
|
read_and_confirm_mnemonic,
|
||||||
)
|
)
|
||||||
|
|
||||||
STRENGTH_TO_WORDS = {128: 20, 256: 33}
|
|
||||||
|
|
||||||
|
|
||||||
def reset_device(client, strength):
|
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
|
member_threshold = 3
|
||||||
all_mnemonics = []
|
all_mnemonics = []
|
||||||
|
|
||||||
@ -53,19 +55,17 @@ def reset_device(client, strength):
|
|||||||
# show & confirm shares
|
# show & confirm shares
|
||||||
for h in range(5):
|
for h in range(5):
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=words)
|
|
||||||
all_mnemonics.append(mnemonic)
|
all_mnemonics.append(mnemonic)
|
||||||
|
|
||||||
# Confirm continue to next share
|
# Confirm continue to next share
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# safety warning
|
# safety warning
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
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.ResetDevice),
|
proto.ButtonRequest(code=B.ResetDevice),
|
||||||
proto.ButtonRequest(code=B.ResetDevice),
|
]
|
||||||
proto.ButtonRequest(code=B.Success),
|
+ [
|
||||||
proto.ButtonRequest(code=B.ResetDevice),
|
# individual mnemonic
|
||||||
proto.ButtonRequest(code=B.Success),
|
*paging_responses(mnemonic_pages, 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.Success),
|
||||||
|
]
|
||||||
|
* 5 # number of shares
|
||||||
|
+ [
|
||||||
proto.ButtonRequest(code=B.Success),
|
proto.ButtonRequest(code=B.Success),
|
||||||
proto.Success,
|
proto.Success,
|
||||||
proto.Features,
|
proto.Features,
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import btc, messages
|
from trezorlib import btc, messages
|
||||||
|
from trezorlib.debuglink import message_filters
|
||||||
from trezorlib.tools import parse_path
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
S = messages.InputScriptType
|
S = messages.InputScriptType
|
||||||
@ -233,18 +234,20 @@ MESSAGE_LENGTHS = (
|
|||||||
@pytest.mark.parametrize("message", MESSAGE_LENGTHS)
|
@pytest.mark.parametrize("message", MESSAGE_LENGTHS)
|
||||||
def test_signmessage_pagination(client, message):
|
def test_signmessage_pagination(client, message):
|
||||||
message_read = ""
|
message_read = ""
|
||||||
message += "End."
|
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
# collect screen contents into `message_read`.
|
# collect screen contents into `message_read`.
|
||||||
# Join lines that are separated by a single "-" string, space-separate lines otherwise.
|
# Join lines that are separated by a single "-" string, space-separate lines otherwise.
|
||||||
nonlocal message_read
|
nonlocal message_read
|
||||||
|
|
||||||
yield
|
|
||||||
# start assuming there was a word break; this avoids prepending space at start
|
# start assuming there was a word break; this avoids prepending space at start
|
||||||
word_break = True
|
word_break = True
|
||||||
max_attempts = 100
|
page = 0
|
||||||
while max_attempts:
|
while True:
|
||||||
|
br = yield
|
||||||
|
assert br.page_number == page + 1
|
||||||
|
page = br.page_number
|
||||||
|
|
||||||
layout = client.debug.wait_layout()
|
layout = client.debug.wait_layout()
|
||||||
for line in layout.lines[1:]:
|
for line in layout.lines[1:]:
|
||||||
if line == "-":
|
if line == "-":
|
||||||
@ -258,16 +261,12 @@ def test_signmessage_pagination(client, message):
|
|||||||
# attach with space
|
# attach with space
|
||||||
message_read += " " + line
|
message_read += " " + line
|
||||||
|
|
||||||
if not message_read.endswith("End."):
|
if page < br.pages:
|
||||||
client.debug.swipe_up()
|
client.debug.swipe_up()
|
||||||
else:
|
else:
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
break
|
break
|
||||||
|
|
||||||
max_attempts -= 1
|
|
||||||
|
|
||||||
assert max_attempts > 0, "failed to scroll through message"
|
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(input_flow)
|
client.set_input_flow(input_flow)
|
||||||
client.debug.watch_layout(True)
|
client.debug.watch_layout(True)
|
||||||
@ -282,13 +281,20 @@ def test_signmessage_pagination(client, message):
|
|||||||
|
|
||||||
@pytest.mark.skip_t1
|
@pytest.mark.skip_t1
|
||||||
def test_signmessage_pagination_trailing_newline(client):
|
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"
|
message = "THIS\nMUST\nNOT\nBE\nPAGINATED\n"
|
||||||
# The trailing newline must not cause a new paginated screen to appear.
|
# The trailing newline must not cause a new paginated screen to appear.
|
||||||
# The UI must be a single dialog without pagination.
|
# The UI must be a single dialog without pagination.
|
||||||
btc.sign_message(
|
with client:
|
||||||
client,
|
client.set_expected_responses(
|
||||||
coin_name="Bitcoin",
|
[
|
||||||
n=parse_path("m/44h/0h/0h/0/0"),
|
# expect a ButtonRequest that does not have pagination set
|
||||||
message=message,
|
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
|
nonlocal finished
|
||||||
for expected in (B.ConfirmOutput, B.FeeOverThreshold, B.SignTx):
|
for expected in (B.ConfirmOutput, B.FeeOverThreshold, B.SignTx):
|
||||||
br = yield
|
br = yield
|
||||||
assert br == expected
|
assert br.code == expected
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
finished = True
|
finished = True
|
||||||
|
|
||||||
|
@ -517,10 +517,7 @@ def test_p2wpkh_in_p2sh_fee_bump_from_external(client):
|
|||||||
request_output(0),
|
request_output(0),
|
||||||
request_orig_output(0, TXHASH_334cd7),
|
request_orig_output(0, TXHASH_334cd7),
|
||||||
messages.ButtonRequest(code=B.ConfirmOutput),
|
messages.ButtonRequest(code=B.ConfirmOutput),
|
||||||
(
|
messages.ButtonRequest(code=B.ConfirmOutput),
|
||||||
client.features.model == "1",
|
|
||||||
messages.ButtonRequest(code=B.ConfirmOutput),
|
|
||||||
),
|
|
||||||
request_orig_output(1, TXHASH_334cd7),
|
request_orig_output(1, TXHASH_334cd7),
|
||||||
messages.ButtonRequest(code=B.SignTx),
|
messages.ButtonRequest(code=B.SignTx),
|
||||||
request_input(0),
|
request_input(0),
|
||||||
|
@ -29,15 +29,8 @@ TEZOS_PATH_15 = parse_path("m/44'/1729'/15'")
|
|||||||
@pytest.mark.tezos
|
@pytest.mark.tezos
|
||||||
@pytest.mark.skip_t1
|
@pytest.mark.skip_t1
|
||||||
class TestMsgTezosSignTx:
|
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):
|
def test_tezos_sign_tx_proposal(self, client):
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, num_pages=1))
|
|
||||||
resp = tezos.sign_tx(
|
resp = tezos.sign_tx(
|
||||||
client,
|
client,
|
||||||
TEZOS_PATH_10,
|
TEZOS_PATH_10,
|
||||||
@ -70,7 +63,6 @@ class TestMsgTezosSignTx:
|
|||||||
|
|
||||||
def test_tezos_sign_tx_multiple_proposals(self, client):
|
def test_tezos_sign_tx_multiple_proposals(self, client):
|
||||||
with client:
|
with client:
|
||||||
client.set_input_flow(self.input_flow(client.debug, num_pages=2))
|
|
||||||
resp = tezos.sign_tx(
|
resp = tezos.sign_tx(
|
||||||
client,
|
client,
|
||||||
TEZOS_PATH_10,
|
TEZOS_PATH_10,
|
||||||
|
@ -23,11 +23,18 @@ from shamir_mnemonic import shamir
|
|||||||
from trezorlib import device, messages
|
from trezorlib import device, messages
|
||||||
from trezorlib.messages import BackupType, ButtonRequestType as B
|
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):
|
def backup_flow_bip39(client):
|
||||||
mnemonic = None
|
mnemonic = None
|
||||||
|
words = 12
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
nonlocal mnemonic
|
nonlocal mnemonic
|
||||||
@ -36,25 +43,25 @@ def backup_flow_bip39(client):
|
|||||||
yield from click_through(client.debug, screens=1, code=B.ResetDevice)
|
yield from click_through(client.debug, screens=1, code=B.ResetDevice)
|
||||||
|
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=12)
|
|
||||||
|
|
||||||
# confirm recovery seed check
|
# confirm recovery seed check
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# confirm success
|
# confirm success
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
client.set_expected_responses(
|
client.set_expected_responses(
|
||||||
[
|
[
|
||||||
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.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
@ -69,6 +76,8 @@ def backup_flow_bip39(client):
|
|||||||
|
|
||||||
def backup_flow_slip39_basic(client):
|
def backup_flow_slip39_basic(client):
|
||||||
mnemonics = []
|
mnemonics = []
|
||||||
|
words = 20
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
# 1. Checklist
|
# 1. Checklist
|
||||||
@ -81,8 +90,8 @@ def backup_flow_slip39_basic(client):
|
|||||||
|
|
||||||
# Mnemonic phrases
|
# Mnemonic phrases
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
yield # Phrase screen
|
# Phrase screen
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
mnemonics.append(mnemonic)
|
mnemonics.append(mnemonic)
|
||||||
yield # Confirm continue to next
|
yield # Confirm continue to next
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
@ -96,7 +105,7 @@ def backup_flow_slip39_basic(client):
|
|||||||
client.set_expected_responses(
|
client.set_expected_responses(
|
||||||
[messages.ButtonRequest(code=B.ResetDevice)] * 6 # intro screens
|
[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),
|
messages.ButtonRequest(code=B.Success),
|
||||||
]
|
]
|
||||||
* 5 # individual shares
|
* 5 # individual shares
|
||||||
@ -115,6 +124,8 @@ def backup_flow_slip39_basic(client):
|
|||||||
|
|
||||||
def backup_flow_slip39_advanced(client):
|
def backup_flow_slip39_advanced(client):
|
||||||
mnemonics = []
|
mnemonics = []
|
||||||
|
words = 20
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
# 1. Confirm Reset
|
# 1. Confirm Reset
|
||||||
@ -132,19 +143,17 @@ def backup_flow_slip39_advanced(client):
|
|||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
|
|
||||||
mnemonics.append(mnemonic)
|
mnemonics.append(mnemonic)
|
||||||
|
|
||||||
# Confirm continue to next share
|
# Confirm continue to next share
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# safety warning
|
# safety warning
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
@ -157,7 +166,7 @@ def backup_flow_slip39_advanced(client):
|
|||||||
]
|
]
|
||||||
* 5 # group thresholds
|
* 5 # group thresholds
|
||||||
+ [
|
+ [
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
*paging_responses(mnemonic_pages, code=B.ResetDevice),
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
]
|
]
|
||||||
* 25 # individual shares
|
* 25 # individual shares
|
||||||
|
@ -23,7 +23,12 @@ from trezorlib import btc, device, messages
|
|||||||
from trezorlib.messages import BackupType, ButtonRequestType as B
|
from trezorlib.messages import BackupType, ButtonRequestType as B
|
||||||
from trezorlib.tools import parse_path
|
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
|
@pytest.mark.skip_t1
|
||||||
@ -39,8 +44,9 @@ def test_reset_recovery(client):
|
|||||||
|
|
||||||
|
|
||||||
def reset(client, strength=128, skip_backup=False):
|
def reset(client, strength=128, skip_backup=False):
|
||||||
|
words = strength // 32 * 3
|
||||||
|
mnemonic_pages = ((words + 3) // 4) + 1
|
||||||
mnemonic = None
|
mnemonic = None
|
||||||
word_count = strength // 32 * 3
|
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
nonlocal mnemonic
|
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)
|
yield from click_through(client.debug, screens=3, code=B.ResetDevice)
|
||||||
|
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count)
|
|
||||||
|
|
||||||
# confirm recovery seed check
|
# confirm recovery seed check
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# confirm success
|
# confirm success
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
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(
|
client.set_expected_responses(
|
||||||
[
|
[
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
messages.ButtonRequest(code=B.ResetDevice),
|
||||||
messages.EntropyRequest(),
|
messages.EntropyRequest(),
|
||||||
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),
|
]
|
||||||
|
+ paging_responses(mnemonic_pages, code=B.ResetDevice)
|
||||||
|
+ [
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
@ -81,19 +88,17 @@ def reset(client, strength=128, skip_backup=False):
|
|||||||
)
|
)
|
||||||
client.set_input_flow(input_flow)
|
client.set_input_flow(input_flow)
|
||||||
|
|
||||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
# No PIN, no passphrase, don't display random
|
||||||
with mock.patch("os.urandom", os_urandom), client:
|
device.reset(
|
||||||
# No PIN, no passphrase, don't display random
|
client,
|
||||||
device.reset(
|
display_random=False,
|
||||||
client,
|
strength=strength,
|
||||||
display_random=False,
|
passphrase_protection=False,
|
||||||
strength=strength,
|
pin_protection=False,
|
||||||
passphrase_protection=False,
|
label="test",
|
||||||
pin_protection=False,
|
language="en-US",
|
||||||
label="test",
|
backup_type=BackupType.Bip39,
|
||||||
language="en-US",
|
)
|
||||||
backup_type=BackupType.Bip39,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if device is properly initialized
|
# Check if device is properly initialized
|
||||||
assert client.features.initialized is True
|
assert client.features.initialized is True
|
||||||
|
@ -25,6 +25,7 @@ from trezorlib.tools import parse_path
|
|||||||
from ..common import (
|
from ..common import (
|
||||||
EXTERNAL_ENTROPY,
|
EXTERNAL_ENTROPY,
|
||||||
click_through,
|
click_through,
|
||||||
|
paging_responses,
|
||||||
read_and_confirm_mnemonic,
|
read_and_confirm_mnemonic,
|
||||||
recovery_enter_shares,
|
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
|
# per SLIP-39: strength in bits, rounded up to nearest multiple of 10, plus 70 bits
|
||||||
# of metadata, split into 10-bit words
|
# of metadata, split into 10-bit words
|
||||||
word_count = ((strength + 9) // 10) + 7
|
word_count = ((strength + 9) // 10) + 7
|
||||||
|
mnemonic_pages = ((word_count + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
# 1. Confirm Reset
|
# 1. Confirm Reset
|
||||||
@ -81,19 +83,17 @@ def reset(client, strength=128):
|
|||||||
for g in range(5):
|
for g in range(5):
|
||||||
for h in range(5):
|
for h in range(5):
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count)
|
|
||||||
all_mnemonics.append(mnemonic)
|
all_mnemonics.append(mnemonic)
|
||||||
|
|
||||||
# Confirm continue to next share
|
# Confirm continue to next share
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# safety warning
|
# safety warning
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
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),
|
||||||
messages.ButtonRequest(code=B.ResetDevice), # group #5 counts
|
messages.ButtonRequest(code=B.ResetDevice), # group #5 counts
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
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.Success),
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
]
|
||||||
messages.ButtonRequest(code=B.Success),
|
* (5 * 5) # groups * shares
|
||||||
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
|
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
messages.Features,
|
messages.Features,
|
||||||
|
@ -23,7 +23,12 @@ from trezorlib import btc, device, messages
|
|||||||
from trezorlib.messages import BackupType, ButtonRequestType as B
|
from trezorlib.messages import BackupType, ButtonRequestType as B
|
||||||
from trezorlib.tools import parse_path
|
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
|
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
|
||||||
MOCK_OS_URANDOM = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
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
|
# per SLIP-39: strength in bits, rounded up to nearest multiple of 10, plus 70 bits
|
||||||
# of metadata, split into 10-bit words
|
# of metadata, split into 10-bit words
|
||||||
word_count = ((strength + 9) // 10) + 7
|
word_count = ((strength + 9) // 10) + 7
|
||||||
|
mnemonic_pages = ((word_count + 3) // 4) + 1
|
||||||
|
|
||||||
def input_flow():
|
def input_flow():
|
||||||
# 1. Confirm Reset
|
# 1. Confirm Reset
|
||||||
@ -64,19 +70,17 @@ def reset(client, strength=128):
|
|||||||
# show & confirm shares
|
# show & confirm shares
|
||||||
for h in range(5):
|
for h in range(5):
|
||||||
# mnemonic phrases
|
# mnemonic phrases
|
||||||
btn_code = yield
|
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||||
assert btn_code == B.ResetDevice
|
|
||||||
mnemonic = read_and_confirm_mnemonic(client.debug, words=word_count)
|
|
||||||
all_mnemonics.append(mnemonic)
|
all_mnemonics.append(mnemonic)
|
||||||
|
|
||||||
# Confirm continue to next share
|
# Confirm continue to next share
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
# safety warning
|
# safety warning
|
||||||
btn_code = yield
|
br = yield
|
||||||
assert btn_code == B.Success
|
assert br.code == B.Success
|
||||||
client.debug.press_yes()
|
client.debug.press_yes()
|
||||||
|
|
||||||
with client:
|
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.ResetDevice),
|
messages.ButtonRequest(code=B.ResetDevice),
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
]
|
||||||
messages.ButtonRequest(code=B.Success),
|
+ [
|
||||||
messages.ButtonRequest(code=B.ResetDevice),
|
# individual mnemonic
|
||||||
messages.ButtonRequest(code=B.Success),
|
*paging_responses(mnemonic_pages, 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.Success),
|
||||||
|
]
|
||||||
|
* 5 # number of shares
|
||||||
|
+ [
|
||||||
messages.ButtonRequest(code=B.Success),
|
messages.ButtonRequest(code=B.Success),
|
||||||
messages.Success,
|
messages.Success,
|
||||||
messages.Features,
|
messages.Features,
|
||||||
|
Loading…
Reference in New Issue
Block a user