diff --git a/tests/speculos/boilerplate_client/boilerplate_cmd.py b/tests/speculos/boilerplate_client/boilerplate_cmd.py index 4e98c46..0f86c96 100644 --- a/tests/speculos/boilerplate_client/boilerplate_cmd.py +++ b/tests/speculos/boilerplate_client/boilerplate_cmd.py @@ -15,10 +15,12 @@ from boilerplate_client.transaction import Transaction class BoilerplateCommand: def __init__(self, client: SpeculosClient, - debug: bool = False) -> None: + debug: bool = False, + model: str = "nanos") -> None: self.client = client self.builder = BoilerplateCommandBuilder(debug=debug) self.debug = debug + self.model = model def get_configuration(self) -> Tuple[int, int, int, int]: try: diff --git a/tests/speculos/boilerplate_client/utils.py b/tests/speculos/boilerplate_client/utils.py index c2fe9d3..4a31eb7 100644 --- a/tests/speculos/boilerplate_client/utils.py +++ b/tests/speculos/boilerplate_client/utils.py @@ -1,11 +1,24 @@ from io import BytesIO from typing import List, Optional, Literal +import speculos.client + +import PIL.Image as Image +import io UINT64_MAX: int = 18446744073709551615 UINT32_MAX: int = 4294967295 UINT16_MAX: int = 65535 +def save_screenshot(cmd, path: str): + screenshot = cmd.client.get_screenshot() + img = Image.open(io.BytesIO(screenshot)) + img.save(path) + + +def compare_screenshot(cmd, path: str): + screenshot = cmd.client.get_screenshot() + assert speculos.client.screenshot_equal(path, io.BytesIO(screenshot)) def bip32_path_from_string(path: str) -> List[bytes]: splitted_path: List[str] = path.split("/") diff --git a/tests/speculos/conftest.py b/tests/speculos/conftest.py index 8c3999e..f370ec7 100644 --- a/tests/speculos/conftest.py +++ b/tests/speculos/conftest.py @@ -1,5 +1,6 @@ from collections import namedtuple from pathlib import Path +from pyexpat import model import pytest @@ -11,17 +12,31 @@ from boilerplate_client.boilerplate_cmd import BoilerplateCommand SCRIPT_DIR = Path(__file__).absolute().parent API_URL = "http://127.0.0.1:5000" -@pytest.fixture(scope="session") -def client(): +def pytest_addoption(parser): + # nanos or nanox + parser.addoption("--model", action="store", default="nanos") + # qt: default, requires a X server + # headless: nothing is displayed + parser.addoption("--display", action="store", default="qt") + +@pytest.fixture() +def client(pytestconfig): file_path = SCRIPT_DIR.parent.parent / "bin" / "app.elf" - args = ['--model', 'nanos', '--display', 'qt', '--sdk', '2.1'] + model = pytestconfig.getoption("model") + version = '2.1' # latest version of nanos_sdk + + if model == "nanox": + version = '2.0.2' # latest version of nanox_sdk + + args = ['--model', model, '--display', pytestconfig.getoption("display"), '--sdk', version] with SpeculosClient(app=str(file_path), args=args) as client: yield client -@pytest.fixture(scope="session") -def cmd(client): +@pytest.fixture() +def cmd(client, pytestconfig): yield BoilerplateCommand( client=client, - debug=True + debug=True, + model=pytestconfig.getoption("model"), ) diff --git a/tests/speculos/test_configuration_cmd.py b/tests/speculos/test_configuration_cmd.py index 9694737..52c6601 100644 --- a/tests/speculos/test_configuration_cmd.py +++ b/tests/speculos/test_configuration_cmd.py @@ -1,3 +1,7 @@ def test_configuration(cmd): - assert cmd.get_configuration() == (14, 1, 9, 17) \ No newline at end of file + if cmd.model == "nanos": + assert cmd.get_configuration() == (14, 1, 9, 17) + + if cmd.model == "nanox": + assert cmd.get_configuration() == (14, 1, 9, 17) \ No newline at end of file diff --git a/tests/speculos/test_pubkey_cmd.py b/tests/speculos/test_pubkey_cmd.py index 9a79429..7d3d90e 100644 --- a/tests/speculos/test_pubkey_cmd.py +++ b/tests/speculos/test_pubkey_cmd.py @@ -3,7 +3,10 @@ from cgitb import reset from pickle import TRUE from typing import Tuple +from time import sleep + import boilerplate_client +from boilerplate_client.utils import UINT64_MAX, compare_screenshot, save_screenshot def test_get_public_key(cmd): @@ -25,15 +28,37 @@ def test_get_public_key(cmd): # DAI COIN with display result: list = [] with cmd.get_public_key(bip32_path="44'/700'/1'/0/0", display=True, result=result) as exchange: - cmd.client.press_and_release('right') - # Verify address - cmd.client.press_and_release('right') - # Address 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Approved - cmd.client.press_and_release('both') + sleep(0.5) + + if cmd.model == "nanos": + # Verify address + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00000.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00003.png") + cmd.client.press_and_release('right') + + # Approved + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00004.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Verify address + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00000.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00001.png") + cmd.client.press_and_release('right') + + # Approve + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/get_public_key/00002.png") + cmd.client.press_and_release('both') uncompressed_addr_len, eth_addr, chain_code = result assert len(uncompressed_addr_len) == 65 @@ -50,16 +75,45 @@ def test_reject_get_public_key(cmd): # DAI COIN with display result: list = [] with cmd.get_public_key(bip32_path="44'/700'/1'/0/0", display=True, result=result) as exchange: - cmd.client.press_and_release('right') - # Verify address - cmd.client.press_and_release('right') - # Address 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Reject - cmd.client.press_and_release('right') - cmd.client.press_and_release('both') + sleep(0.5) + + if cmd.model == "nanos": + # Verify address + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00000.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00003.png") + cmd.client.press_and_release('right') + + # Approve + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00004.png") + cmd.client.press_and_release('right') + + # Reject + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00005.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Verify address + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00000.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00001.png") + cmd.client.press_and_release('right') + + # Approve + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00002.png") + cmd.client.press_and_release('right') + + # Reject + compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00003.png") + cmd.client.press_and_release('both') except boilerplate_client.exception.errors.DenyError as error: assert error.args[0] == '0x6985' diff --git a/tests/speculos/test_sign_cmd.py b/tests/speculos/test_sign_cmd.py index 0983325..a2f286c 100644 --- a/tests/speculos/test_sign_cmd.py +++ b/tests/speculos/test_sign_cmd.py @@ -1,14 +1,14 @@ -from urllib import response +from time import sleep import boilerplate_client -import struct -from boilerplate_client.utils import UINT64_MAX + +from boilerplate_client.utils import UINT64_MAX, compare_screenshot, compare_screenshot, save_screenshot from boilerplate_client.transaction import Transaction # https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md -def test_simple_sign(cmd): +def test_sign_simple(cmd): result: list = [] # Ether coin type @@ -25,20 +25,57 @@ def test_simple_sign(cmd): ) with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: - # Review transaction - cmd.client.press_and_release('right') - # Amount 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Address 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Max Fees - cmd.client.press_and_release('right') - #Accept and send - cmd.client.press_and_release('both') + sleep(0.5) + + if cmd.model == "nanos": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00000.png") + cmd.client.press_and_release('right') + + # Amount 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00003.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00004.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00005.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00006.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00007.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00008.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00000.png") + cmd.client.press_and_release('right') + + # Amount + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00001.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00002.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00003.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/simple/00004.png") + cmd.client.press_and_release('both') v, r, s = result @@ -64,22 +101,65 @@ def test_sign_dai_coin_type_on_network_5234(cmd): ) with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: - # Review transaction - cmd.client.press_and_release('right') - # Amount 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Address 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Network 5243 - cmd.client.press_and_release('right') - # Max Fees - cmd.client.press_and_release('right') - #Accept and send - cmd.client.press_and_release('both') + sleep(0.5) + + if cmd.model == "nanos": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00000.png") + cmd.client.press_and_release('right') + + # Amount 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00003.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00004.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00005.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00006.png") + cmd.client.press_and_release('right') + + # Network 5243 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00007.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00008.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00009.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00000.png") + cmd.client.press_and_release('right') + + # Amount + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00001.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00002.png") + cmd.client.press_and_release('right') + + # Network 5243 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00003.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00004.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/dai_coin_type_on_network_5234/00005.png") + cmd.client.press_and_release('both') v, r, s = result @@ -103,28 +183,150 @@ def test_sign_reject(cmd): value=0x6f9c9e7bf61818, chainID=1, ) + try: with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: - # Review transaction - cmd.client.press_and_release('right') - # Amount 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Address 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Max Fees - cmd.client.press_and_release('right') - # Accept and send - cmd.client.press_and_release('right') - # Reject - cmd.client.press_and_release('both') + sleep(0.5) + + if cmd.model == "nanos": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00000.png") + cmd.client.press_and_release('right') + + # Amount 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00003.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00004.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00005.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00006.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00007.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00008.png") + cmd.client.press_and_release('right') + + # Reject + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00009.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00000.png") + cmd.client.press_and_release('right') + + # Amount + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00001.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00002.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00003.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00004.png") + cmd.client.press_and_release('right') + + # Reject + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00005.png") + cmd.client.press_and_release('both') + except boilerplate_client.exception.errors.DenyError as error: assert error.args[0] == '0x6985' +def test_sign_limit_nonce(cmd): + result: list = [] + + # Ether coin type + bip32_path="44'/60'/1'/0/0" + + # EIP-2681: Limit account nonce to 2^64-1 + transaction = Transaction( + txType=0xEB, + nonce=2**64-1, + gasPrice=10, + gasLimit=50000, + to="0x5a321744667052affa8386ed49e00ef223cbffc3", + value=0x08762, + chainID=1, + ) + + with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00000.png") + cmd.client.press_and_release('right') + + # Amount 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00003.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00004.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00005.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00006.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00007.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00008.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00000.png") + cmd.client.press_and_release('right') + + # Amount + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00001.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00002.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00003.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/limit_nonce/00004.png") + cmd.client.press_and_release('both') + + v, r, s = result + + assert v == 0x26 # 38 + assert r.hex() == "7f17f9efa5a6065f885a44a5f5d68a62381c6b2b23047817b4569c61ccf571c6" + assert s.hex() == "4b67d37cfe473e0b2daf246fa82c7595bcff0c1515d69089037d0c061f14b3b3" + + def test_sign_error_transaction_type(cmd): result: list = [] @@ -155,44 +357,347 @@ def test_sign_error_transaction_type(cmd): pass except boilerplate_client.exception.errors.UnknownDeviceError as error: # Throw error of transaction type not supported - assert error.args[0] == '0x6501' + assert error.args[0] == '0x6501' -def test_sign_limit_nonce(cmd): +def test_sign_nonce_display(cmd): + # Activate nonce display + # Application is ready + cmd.client.press_and_release('left') + # Quit + cmd.client.press_and_release('left') + # Settings + cmd.client.press_and_release('both') + # Blind signing + cmd.client.press_and_release('right') + # Debug data + cmd.client.press_and_release('right') + # Nonce display + cmd.client.press_and_release('both') + cmd.client.press_and_release('right') + # Back + cmd.client.press_and_release('both') + result: list = [] - + # Ether coin type bip32_path="44'/60'/1'/0/0" - # EIP-2681: Limit account nonce to 2^64-1 transaction = Transaction( txType=0xEB, - nonce=2**64-1, - gasPrice=10, - gasLimit=50000, + nonce=68, + gasPrice=0x0306dc4200, + gasLimit=0x5208, to="0x5a321744667052affa8386ed49e00ef223cbffc3", - value=0x08762, + value=0x6f9c9e7bf61818, chainID=1, ) with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: - # Review transaction - cmd.client.press_and_release('right') - # Amount 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Address 1/3, 2/3, 3/3 - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - cmd.client.press_and_release('right') - # Max Fees - cmd.client.press_and_release('right') - #Accept and send - cmd.client.press_and_release('both') + sleep(0.5) + + if cmd.model == "nanos": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00000.png") + cmd.client.press_and_release('right') + + # Amount 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00003.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00004.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00005.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00006.png") + cmd.client.press_and_release('right') + + # Nonce + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00007.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00008.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00009.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00000.png") + cmd.client.press_and_release('right') + + # Amount + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00001.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00002.png") + cmd.client.press_and_release('right') + + # Nonce + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00003.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00004.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/nonce_display/00005.png") + cmd.client.press_and_release('both') v, r, s = result assert v == 0x26 # 38 - assert r.hex() == "7f17f9efa5a6065f885a44a5f5d68a62381c6b2b23047817b4569c61ccf571c6" - assert s.hex() == "4b67d37cfe473e0b2daf246fa82c7595bcff0c1515d69089037d0c061f14b3b3" + assert r.hex() == "6f389d15320f0501383526ed03de917c14212716f09a262dbc98431086a5db49" + assert s.hex() == "0dc994b7b97230bb35fdf6fec2f4d8ff4cfb8bfeb2a652c364c738ff033c05dd" + + +def test_sign_blind_simple(cmd): + # Activate blind signing + # Application is ready + cmd.client.press_and_release('left') + # Quit + cmd.client.press_and_release('left') + # Settings + cmd.client.press_and_release('both') + # Blind signing + cmd.client.press_and_release('both') + cmd.client.press_and_release('right') + # Debug data + cmd.client.press_and_release('right') + # Nonce display + cmd.client.press_and_release('right') + # Back + cmd.client.press_and_release('both') + + result: list = [] + + # Ether coin type + bip32_path="44'/60'/1'/0/0" + + transaction = Transaction( + txType=0xEB, + nonce=68, + gasPrice=0x0306dc4200, + gasLimit=0x5208, + to="0x5a321744667052affa8386ed49e00ef223cbffc3", + value=0x6f9c9e7bf61818, + chainID=1, + data="ok", + ) + + with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00000.png") + cmd.client.press_and_release('right') + + # Blind Signing + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00001.png") + cmd.client.press_and_release('right') + + # Amount 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00003.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00004.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00005.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00006.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00007.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00008.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00009.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00000.png") + cmd.client.press_and_release('right') + + # Blind Signing + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00001.png") + cmd.client.press_and_release('right') + + # Amount + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00002.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00003.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00004.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_simple/00005.png") + cmd.client.press_and_release('both') + + v, r, s = result + + assert v == 0x26 # 38 + assert r.hex() == "98163696ad14f54e0e7207306b6f66665131cee601052facab8fd24250e15470" + assert s.hex() == "318e573fc809f7dcb8f9718c8bd2946b2c3c83cedf3720e66e06fb63ceea3174" + + +def test_sign_blind_error_disabled(cmd): + result: list = [] + + # Ether coin type + bip32_path="44'/60'/1'/0/0" + + transaction = Transaction( + txType=0xEB, + nonce=68, + gasPrice=0x0306dc4200, + gasLimit=0x5208, + to="0x5a321744667052affa8386ed49e00ef223cbffc3", + value=0x6f9c9e7bf61818, + chainID=1, + data="ok", + ) + + try: + with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + pass + if cmd.model == "nanox": + pass + except boilerplate_client.exception.errors.UnknownDeviceError as error: + assert error.args[0] == '0x6a80' + + +def test_sign_blind_and_nonce_display(cmd): + # Activate blind signing + # Application is ready + cmd.client.press_and_release('left') + # Quit + cmd.client.press_and_release('left') + # Settings + cmd.client.press_and_release('both') + # Blind signing + cmd.client.press_and_release('both') + cmd.client.press_and_release('right') + # Debug data + cmd.client.press_and_release('right') + # Nonce display + cmd.client.press_and_release('both') + cmd.client.press_and_release('right') + # Back + cmd.client.press_and_release('both') + + result: list = [] + + # Ether coin type + bip32_path="44'/60'/1'/0/0" + + transaction = Transaction( + txType=0xEB, + nonce=2**64-1, + gasPrice=0x0306dc4200, + gasLimit=0x5208, + to="0x5a321744667052affa8386ed49e00ef223cbffc3", + value=0x6f9c9e7bf61818, + chainID=1, + data="That's a little message :)", + ) + + with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00000.png") + cmd.client.press_and_release('right') + + # Blind Signing + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00001.png") + cmd.client.press_and_release('right') + + # Amount 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00003.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00004.png") + cmd.client.press_and_release('right') + + # Address 1/3, 2/3, 3/3 + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00005.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00006.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00007.png") + cmd.client.press_and_release('right') + + # Nonce + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00008.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00009.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00010.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox": + # Review transaction + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00000.png") + cmd.client.press_and_release('right') + + # Blind Signing + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00001.png") + cmd.client.press_and_release('right') + + # Amount + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00002.png") + cmd.client.press_and_release('right') + + # Address + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00003.png") + cmd.client.press_and_release('right') + + # Nonce + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00004.png") + cmd.client.press_and_release('right') + + # Max Fees + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00005.png") + cmd.client.press_and_release('right') + + # Accept and send + compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/blind_and_nonce_display/00006.png") + cmd.client.press_and_release('both') + + v, r, s = result + + assert v == 0x25 # 37 + assert r.hex() == "737c07042022d37286216312d62163c4238536d82c5b45937ce9fbf259d11b7d" + assert s.hex() == "5604485e0cf37e465a84290eb26a18e40a430f1b0fda184c56b2c3a51ada2e6c"