diff --git a/tests/speculos/ethereum_client/ethereum_cmd.py b/tests/speculos/ethereum_client/ethereum_cmd.py index 2bbb133..a9949b2 100644 --- a/tests/speculos/ethereum_client/ethereum_cmd.py +++ b/tests/speculos/ethereum_client/ethereum_cmd.py @@ -1,7 +1,5 @@ from ast import List from contextlib import contextmanager -from ctypes.wintypes import INT -from re import A import struct from typing import Tuple @@ -9,8 +7,9 @@ from speculos.client import SpeculosClient, ApduException from ethereum_client.ethereum_cmd_builder import EthereumCommandBuilder, InsType from ethereum_client.exception import DeviceException -from ethereum_client.transaction import Transaction +from ethereum_client.transaction import PersonalTransaction, Transaction from ethereum_client.plugin import Plugin +from ethereum_client.utils import parse_sign_response class EthereumCommand: @@ -122,47 +121,8 @@ class EthereumCommand: except ApduException as error: raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - # Not use @contextmanager - def test_zemu_hard_apdu_sign(self) -> Tuple[int, int, int]: - sign: bytes = b'\xe0\x04\x00\x00\x80\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x69\x46\x85\x06\xa8\xb1\x5e\x00\x82\xeb\xeb\x94\x6b\x17\x54\x74\xe8\x90\x94\xc4\x4d\xa9\x8b\x95\x4e\xed\xea\xc4\x95\x27\x1d\x0f\x80\xb8\x44\x09\x5e\xa7\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7d\x27\x68\xde\x32\xb0\xb8\x0b\x7a\x34\x54\xc0\x6b\xda\xc9\x4a\x69\xdd\xc7\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x80' - simple_eth: bytes = b'\xe0\x04\x00\x00\x41\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xeb\x44\x85\x03\x06\xdc\x42\x00\x82\x52\x08\x94\x5a\x32\x17\x44\x66\x70\x52\xaf\xfa\x83\x86\xed\x49\xe0\x0e\xf2\x23\xcb\xff\xc3\x87\x6f\x9c\x9e\x7b\xf6\x18\x18\x80\x01\x80\x80' - provide_erc20: bytes = b'\xe0\x0a\x00\x00\x67\x03\x44\x41\x49\x6b\x17\x54\x74\xe8\x90\x94\xc4\x4d\xa9\x8b\x95\x4e\xed\xea\xc4\x95\x27\x1d\x0f\x00\x00\x00\x12\x00\x00\x00\x01\x30\x45\x02\x21\x00\xb3\xaa\x97\x96\x33\x28\x4e\xb0\xf5\x54\x59\x09\x93\x33\xab\x92\xcf\x06\xfd\xd5\x8d\xc9\x0e\x9c\x07\x00\x00\xc8\xe9\x68\x86\x4c\x02\x20\x7b\x10\xec\x7d\x66\x09\xf5\x1d\xda\x53\xd0\x83\xa6\xe1\x65\xa0\xab\xf3\xa7\x7e\x13\x25\x0e\x6f\x26\x07\x72\x80\x9b\x49\xaf\xf5' - - b: bytes = b'\xe0\x04\x00\x00\x56\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x3f\x26\x8e\x02\xcc\x9b\xe5\xc5\x3e\xa4\x4b\xd4\x3c\x28\x9d\xcd\xdc\x82\x52\x08\x94\xda\xc1\x7f\x95\x8d\x2e\xe5\x23\xa2\x20\x62\x06\x99\x45\x97\xc1\x3d\x83\x1e\xc7\x92\x8d\xb8\xb0\x86\x1b\x8f\x7f\xe5\xdf\x83\xcd\x55\x3a\x82\x98\x78\x00\x00\x80\x01\x80\x80' - test: bytes = b"".join([b'\xe0\x04\x00\x00\x89\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02', - b'\xf8\x70\x02', - b'\x02', #nonce - b'\x85', - b'\x02\x54\x0b\xe4\x00', # max priority fee per gas - b'\x85', - b'\x02\x54\x0b\xe4\x00', # max fee per gas - b'\x86', - b'\x24\x61\x39\xca\x80\x80', # gas limit - b'\x94', - b'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc', # destination - b'\x81'+ - b'\xFF' + # Amount - b'\x00' + # Payload - b'\xc0\x01\xa0\xe0\x7f\xb8\xa6\x4e\xa3\x78\x6c\x9a\x66\x49\xe5\x44\x29\xe2\x78\x6a\xf3\xea\x31\xc6\xd0\x61\x65\x34\x66\x78\xcf\x8c\xe4\x4f\x9b\xa0\x0e\x4a\x05\x26\xdb\x1e\x90\x5b\x71\x64\xa8\x58\xfd\x5e\xbd\x2f\x17\x59\xe2\x2e\x69\x55\x49\x94\x48\xbd\x27\x6a\x6a\xa6\x28\x30']) - - - - try: - with self.client._apdu_exchange_nowait(test) as ex: - yield ex - - #response = self.client._apdu_exchange( - # sign - #) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - - @contextmanager - def simple_sign_tx(self, bip32_path: str, transaction: Transaction, result: List = list()) -> Tuple[int, bytes]: + def simple_sign_tx(self, bip32_path: str, transaction: Transaction, result: List = list()) -> None: try: chunk: bytes = self.builder.simple_sign_tx(bip32_path=bip32_path, transaction=transaction) @@ -177,19 +137,34 @@ class EthereumCommand: # response = V (1) || R (32) || S (32) assert len(response) == 65 + v, r, s = parse_sign_response(response) + + result.append(v) + result.append(r) + result.append(s) + - offset: int = 0 + @contextmanager + def simple_personal_sign_tx(self, bip32_path: str, transaction: PersonalTransaction, result: List = list()) -> None: + try: + chunk: bytes = self.builder.simple_personal_sign_tx(bip32_path=bip32_path, transaction=transaction) - v: bytes = response[offset] - offset += 1 + with self.client.apdu_exchange_nowait(cla=chunk[0], ins=chunk[1], + p1=chunk[2], p2=chunk[3], + data=chunk[5:]) as exchange: + yield exchange + response: bytes = exchange.receive() + + except ApduException as error: + raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - r: bytes = response[offset:offset + 32] - offset += 32 - - s: bytes = response[offset:] + # response = V (1) || R (32) || S (32) + assert len(response) == 65 + v, r, s = parse_sign_response(response) result.append(v) result.append(r) result.append(s) + diff --git a/tests/speculos/ethereum_client/ethereum_cmd_builder.py b/tests/speculos/ethereum_client/ethereum_cmd_builder.py index a02facf..c96bf70 100644 --- a/tests/speculos/ethereum_client/ethereum_cmd_builder.py +++ b/tests/speculos/ethereum_client/ethereum_cmd_builder.py @@ -4,7 +4,7 @@ import struct from typing import List, Tuple, Union, Iterator, cast -from ethereum_client.transaction import Transaction +from ethereum_client.transaction import PersonalTransaction, Transaction from ethereum_client.plugin import Plugin from ethereum_client.utils import bip32_path_from_string @@ -274,3 +274,38 @@ class EthereumCommandBuilder: p1=0x00, p2=0x00, cdata=cdata) + + + def simple_personal_sign_tx(self, bip32_path: str, transaction: PersonalTransaction) -> bytes: + """Command builder for INS_SIGN_PERSONAL_TX. + + Parameters + ---------- + bip32_path : str + String representation of BIP32 path. + transaction : Transaction + Representation of the transaction to be signed. + + Yields + ------- + bytes + APDU command chunk for INS_SIGN_PERSONAL_TX. + + """ + bip32_paths: List[bytes] = bip32_path_from_string(bip32_path) + + cdata: bytes = b"".join([ + len(bip32_paths).to_bytes(1, byteorder="big"), + *bip32_paths + ]) + + + tx: bytes = transaction.serialize() + + cdata = cdata + tx + + return self.serialize(cla=self.CLA, + ins=InsType.INS_SIGN_PERSONAL_TX, + p1=0x00, + p2=0x00, + cdata=cdata) diff --git a/tests/speculos/ethereum_client/transaction.py b/tests/speculos/ethereum_client/transaction.py index f7aec02..f1c4d9e 100644 --- a/tests/speculos/ethereum_client/transaction.py +++ b/tests/speculos/ethereum_client/transaction.py @@ -11,6 +11,23 @@ class TransactionError(Exception): EIP2930 = 1 EIP1559 = 2 +# e0 + 08 + 00 + 00 + 38 + 05 + 8000002c 8000003c 80000000 00000000 00000000 + 0000001f + 4578616d706c652060706572736f6e616c5f7369676e60206d657373616765 +# E0 + 08 + 00 + 00 + 34 + 05 + 8000002C 8000003C 80000000 00000000 00000000 + 4578616D706C652060706572736F6E616C5F7369676E60206D657373616765 +# E0 08 00 00 35058000002C8000003C8000000000000000000000001F4578616D706C652060706572736F6E616C5F7369676E60206D657373616765 + +class PersonalTransaction: + def __init__(self, msg: Union[str, bytes]) -> None: + # If you want to send bytes directly you have to put "0x" before the string + if msg[0:2] == "0x": + self.msg: bytes = bytes.fromhex(msg[2:]) + else: + self.msg: bytes = bytes(msg, "utf-8") + + def serialize(self) -> bytes: + return b"".join([ + len(self.msg).to_bytes(4, byteorder="big"), + self.msg, + ]) class Transaction: def __init__(self, txType: int, nonce: int, gasPrice: int, gasLimit: int, to: Union[str, bytes], value: int, data: Union[str, bytes] = "", chainID: int = -1) -> None: diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00000.png new file mode 100644 index 0000000..ab16f62 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00001.png new file mode 100644 index 0000000..b90315c Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00002.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00002.png new file mode 100644 index 0000000..3d90dfd Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00003.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00003.png new file mode 100644 index 0000000..f5c2d67 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00003.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00000.png new file mode 100644 index 0000000..ab16f62 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00001.png new file mode 100644 index 0000000..ad00cb8 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00002.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00002.png new file mode 100644 index 0000000..b435297 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00003.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00003.png new file mode 100644 index 0000000..fcd68b2 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00003.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00004.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00004.png new file mode 100644 index 0000000..251c562 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00004.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00005.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00005.png new file mode 100644 index 0000000..f5c2d67 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00005.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00000.png new file mode 100644 index 0000000..ab16f62 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00001.png new file mode 100644 index 0000000..bdbb3a0 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00002.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00002.png new file mode 100644 index 0000000..0676953 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00003.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00003.png new file mode 100644 index 0000000..582648d Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00003.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00004.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00004.png new file mode 100644 index 0000000..53e1317 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00004.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00005.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00005.png new file mode 100644 index 0000000..228f924 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00005.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00006.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00006.png new file mode 100644 index 0000000..f5c2d67 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00006.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00000.png new file mode 100644 index 0000000..ab16f62 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00001.png new file mode 100644 index 0000000..6603459 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00002.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00002.png new file mode 100644 index 0000000..f5c2d67 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00003.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00003.png new file mode 100644 index 0000000..d55782f Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00003.png differ diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00004.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00004.png new file mode 100644 index 0000000..d55782f Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00004.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00000.png new file mode 100644 index 0000000..1b27154 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00001.png new file mode 100644 index 0000000..58f0606 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00002.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00002.png new file mode 100644 index 0000000..c9da92b Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00000.png new file mode 100644 index 0000000..1b27154 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00001.png new file mode 100644 index 0000000..93eda35 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00002.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00002.png new file mode 100644 index 0000000..873634e Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00003.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00003.png new file mode 100644 index 0000000..c9da92b Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00003.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00000.png new file mode 100644 index 0000000..1b27154 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00001.png new file mode 100644 index 0000000..802fad5 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00002.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00002.png new file mode 100644 index 0000000..a3ba739 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00003.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00003.png new file mode 100644 index 0000000..4601bca Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00003.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00004.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00004.png new file mode 100644 index 0000000..eab9f1d Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00004.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00005.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00005.png new file mode 100644 index 0000000..0b4bdbd Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00005.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00006.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00006.png new file mode 100644 index 0000000..c9da92b Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00006.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00000.png new file mode 100644 index 0000000..1b27154 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00000.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00001.png new file mode 100644 index 0000000..717f3a5 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00001.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00002.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00002.png new file mode 100644 index 0000000..c9da92b Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00002.png differ diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00003.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00003.png new file mode 100644 index 0000000..121cfd5 Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00003.png differ diff --git a/tests/speculos/test_eip191.py b/tests/speculos/test_eip191.py new file mode 100644 index 0000000..579ba7e --- /dev/null +++ b/tests/speculos/test_eip191.py @@ -0,0 +1,223 @@ +from time import sleep +import ethereum_client + +from ethereum_client.utils import UINT64_MAX, apdu_as_string, compare_screenshot, compare_screenshot, parse_sign_response, save_screenshot, PATH_IMG +from ethereum_client.transaction import PersonalTransaction + +def test_personal_sign_metamask(cmd): + result: list = [] + + bip32_path="44'/60'/0'/0/0" + transaction = PersonalTransaction( + msg="Example `personal_sign` message" + ) + + with cmd.simple_personal_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00000.png") + cmd.client.press_and_release('right') + + # Message 1/2, 2/2 + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00002.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00003.png") + cmd.client.press_and_release('both') + if cmd.model == "nanox" or cmd.model == "nanosp": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00000.png") + cmd.client.press_and_release('right') + + # Message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00001.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00002.png") + cmd.client.press_and_release('both') + + v, r, s = result + + assert v == 0x1c # 28 + assert r.hex() == "916099cf0d9c21911c85f0770a47a9696a8189e78c259cf099749748c507baae" + assert s.hex() == "0d72234bc0ac2e94c5f7a5f4f9cd8610a52be4ea55515a85b9703f1bb158415c" + + +def test_personal_sign_reject(cmd): + result: list = [] + + bip32_path="44'/60'/0'/0/0" + transaction = PersonalTransaction( + msg="This is an reject sign" + ) + + try: + with cmd.simple_personal_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00000.png") + cmd.client.press_and_release('right') + + # Message 1/2, 2/2 + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00002.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00003.png") + cmd.client.press_and_release('right') + + # Cancel signature + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00004.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox" or cmd.model == "nanosp": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00000.png") + cmd.client.press_and_release('right') + + # Message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00001.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00002.png") + cmd.client.press_and_release('right') + + # Cancel signature + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00003.png") + cmd.client.press_and_release('both') + + except ethereum_client.exception.errors.DenyError as error: + assert error.args[0] == '0x6985' + +def test_personal_sign_non_ascii(cmd): + result: list = [] + + bip32_path="44'/60'/0'/0/0" + transaction = PersonalTransaction( + msg="0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658" + ) + + with cmd.simple_personal_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00000.png") + cmd.client.press_and_release('right') + + # Message 1/4, 2/4, 3/4, 4/4 + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00003.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00004.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00005.png") + cmd.client.press_and_release('both') + if cmd.model == "nanox" or cmd.model == "nanosp": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00000.png") + cmd.client.press_and_release('right') + + # Message 1/2, 2/2 + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00002.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00003.png") + cmd.client.press_and_release('both') + + v, r, s = result + + assert v == 0x1c # 28 + assert r.hex() == "64bdbdb6959425445d00ff2536a7018d2dce904e1f7475938fe4221c3c72500c" + assert s.hex() == "7c9208e99b6b9266a73aae17b73472d06499746edec34fd47a9dab42f06f2e42" + +# ============================ +# The encoded message is greater than the maximum length of an apdu, that's why we cut it into 3 apdu +# ============================ + +FIRST_PART = apdu_as_string("e008000096058000002c8000003c8000000000000000000000000000015357656c636f6d6520746f204f70656e536561210a0a436c69636b20746f207369676e20696e20616e642061636365707420746865204f70656e536561205465726d73206f6620536572766963653a2068747470733a2f2f6f70656e7365612e696f2f746f730a0a5468697320726571756573742077696c6c206e6f7420") +SECOND_PART = apdu_as_string("e00880009674726967676572206120626c6f636b636861696e207472616e73616374696f6e206f7220636f737420616e792067617320666565732e0a0a596f75722061757468656e7469636174696f6e207374617475732077696c6c20726573657420616674657220323420686f7572732e0a0a57616c6c657420616464726573733a0a3078393835386566666432333262343033336534376439") +THIRD_PART = apdu_as_string("e008800040303030336434316563333465636165646139340a0a4e6f6e63653a0a32623032633861302d663734662d343535342d393832312d613238303534646339313231") + +def test_personal_sign_opensea(cmd): + result: list = [] + + # useless but allows to see which info are in the apdu + bip32_path="44'/60'/0'/0/0" + transaction = PersonalTransaction( + msg="Welcome to OpenSea!\n\nClick to sign in and accept the OpenSea Terms of Service: https://opensea.io/tos\n\nThis request will not trigger a blockchain transaction or cost any gas fees.\n\nYour authentication status will reset after 24 hours.\n\nWallet address:\n0x9858effd232b4033e47d90003d41ec34ecaeda94\n\nNonce:\n2b02c8a0-f74f-4554-9821-a28054dc9121" + ) + + cmd.send_apdu(FIRST_PART) + cmd.send_apdu(SECOND_PART) + + with cmd.send_apdu_context(THIRD_PART, result=result) as ex: + sleep(0.5) + + if cmd.model == "nanos": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00000.png") + cmd.client.press_and_release('right') + + # Message 1/5, 2/5, 3/5, 4/5, 5/5 + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00003.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00004.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00005.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00006.png") + cmd.client.press_and_release('both') + + if cmd.model == "nanox" or cmd.model == "nanosp": + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00000.png") + cmd.client.press_and_release('right') + + # Message 1/5, 2/5, 3/5, 4/5, 5/5 + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00001.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00002.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00003.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00004.png") + cmd.client.press_and_release('right') + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00005.png") + cmd.client.press_and_release('right') + + # Sign message + compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00006.png") + cmd.client.press_and_release('both') + + response: bytes = result[0] + v, r, s = parse_sign_response(response) + + assert v == 0x1c # 28 + assert r.hex() == "61a68c986f087730d2f6ecf89d6d1e48ab963ac461102bb02664bc05c3db75bb" + assert s.hex() == "5714729ef441e097673a7b29a681e97f6963d875eeed2081f26b0b6686cd2bd2" \ No newline at end of file