Skip to content

Commit

Permalink
tests: update device_tests for external definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
matejcik committed Mar 24, 2023
1 parent abbe553 commit e2d6003
Show file tree
Hide file tree
Showing 8 changed files with 621 additions and 90 deletions.
18 changes: 0 additions & 18 deletions common/tests/fixtures/ethereum/getaddress.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,6 @@
"address": "0xF410e37E9C8BCf8CF319c84Ae9dCEbe057804a04"
}
},
{
"name": "GoChain",
"parameters": {
"path": "m/44'/6060'/0'/0/0"
},
"result": {
"address": "0xA26a450ef46a5f11a510eBA2119A3236fa0Aca92"
}
},
{
"name": "Wanchain",
"parameters": {
"path": "m/44'/5718350'/0'/0/0"
},
"result": {
"address": "0xe432a7533D689ceed00B7EE91d9368b8A1693bD2"
}
},
{
"name": "Ledger Live legacy path",
"parameters": {
Expand Down
22 changes: 1 addition & 21 deletions common/tests/fixtures/ethereum/sign_tx.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,7 @@
},
"tests": [
{
"name": "known_erc20_token",
"parameters": {
"comment": "Sending 200,000,000 ADT tokens to address 0x574bbb36871ba6b78e27f4b4dcfb76ea0091880b",
"data": "a9059cbb000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b000000000000000000000000000000000000000000000000000000000bebc200",
"path": "m/44'/60'/0'/0/0",
"to_address": "0xd0d6d6c5fe4a677d343cc433536bb717bae167dd",
"chain_id": 1,
"nonce": "0x0",
"gas_price": "0x14",
"gas_limit": "0x14",
"tx_type": null,
"value": "0x0"
},
"result": {
"sig_v": 37,
"sig_r": "ec1df922115d256745410fbc2070296756583c8786e4d402a88d4e29ec513fa9",
"sig_s": "7001bfe3ba357e4a9f9e0d3a3f8a8962257615a4cf215db93e48b98999fc51b7"
}
},
{
"name": "unknown_erc20_token",
"name": "erc20_token",
"parameters": {
"comment": "Sending 291 Grzegorz Brzęczyszczykiewicz tokens to address 0x574bbb36871ba6b78e27f4b4dcfb76ea0091880b",
"data": "a9059cbb000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b0000000000000000000000000000000000000000000000000000000000000123",
Expand Down
22 changes: 1 addition & 21 deletions common/tests/fixtures/ethereum/sign_tx_eip1559.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,27 +62,7 @@
}
},
{
"name": "known_erc20",
"parameters": {
"comment": "Sending 200,000,000 ADT tokens to address 0x574bbb36871ba6b78e27f4b4dcfb76ea0091880b",
"data": "a9059cbb000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b000000000000000000000000000000000000000000000000000000000bebc200",
"path": "m/44'/60'/0'/0/0",
"to_address": "0xd0d6d6c5fe4a677d343cc433536bb717bae167dd",
"chain_id": 1,
"nonce": "0x0",
"gas_limit": "0x14",
"max_gas_fee": "0x14",
"max_priority_fee": "0x1",
"value": "0x0"
},
"result": {
"sig_v": 1,
"sig_r": "94d67bacb7966f881339d91103f5d738d9c491fff4c01a6513c554ab15e86cc0",
"sig_s": "405bd19a7bf4ae62d41fcb7844e36c786b106b456185c3d0877a7ce7eab6c751"
}
},
{
"name": "unknown_erc20",
"name": "erc20",
"parameters": {
"comment": "Sending 291 Grzegorz Brzęczyszczykiewicz tokens to address 0x574bbb36871ba6b78e27f4b4dcfb76ea0091880b",
"data": "a9059cbb000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b0000000000000000000000000000000000000000000000000000000000000123",
Expand Down
145 changes: 145 additions & 0 deletions tests/device_tests/ethereum/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
from __future__ import annotations

import io
import typing as t
from hashlib import sha256

from trezorlib import cosi, definitions, messages, protobuf

PRIVATE_KEYS_DEV = [byte * 32 for byte in (b"\xdd", b"\xde", b"\xdf")]


def sign_with_privkeys(digest: bytes, privkeys: t.Sequence[bytes]) -> bytes:
"""Locally produce a CoSi signature."""
pubkeys = [cosi.pubkey_from_privkey(sk) for sk in privkeys]
nonces = [cosi.get_nonce(sk, digest, i) for i, sk in enumerate(privkeys)]

global_pk = cosi.combine_keys(pubkeys)
global_R = cosi.combine_keys(R for _, R in nonces)

sigs = [
cosi.sign_with_privkey(digest, sk, global_pk, r, global_R)
for sk, (r, _) in zip(privkeys, nonces)
]

return cosi.combine_sig(global_R, sigs)


def make_network(
chain_id: int = 0,
slip44: int = 0,
symbol: str = "FAKE",
name: str = "Fake network",
) -> messages.EthereumNetworkInfo:
return messages.EthereumNetworkInfo(
chain_id=chain_id,
slip44=slip44,
symbol=symbol,
name=name,
)


def make_token(
symbol: str = "FAKE",
decimals: int = 18,
address: bytes = b"",
chain_id: int = 0,
name: str = "Fake token",
) -> messages.EthereumTokenInfo:
return messages.EthereumTokenInfo(
symbol=symbol,
decimals=decimals,
address=address,
chain_id=chain_id,
name=name,
)


def make_payload(
data_type: messages.EthereumDefinitionType = messages.EthereumDefinitionType.NETWORK,
timestamp: int = 0xFFFF_FFFF,
message: messages.EthereumNetworkInfo
| messages.EthereumTokenInfo
| bytes = make_network(),
) -> bytes:
if isinstance(message, bytes):
message_bytes = message
else:
writer = io.BytesIO()
protobuf.dump_message(writer, message)
message_bytes = writer.getvalue()

payload = definitions.DefinitionPayload(
magic=b"trzd1",
data_type=data_type,
timestamp=timestamp,
data=message_bytes,
)
return payload.build()


def sign_payload(
payload: bytes,
merkle_neighbors: list[bytes],
threshold: int = 3,
) -> tuple[bytes, bytes]:
digest = sha256(b"\x00" + payload).digest()
merkle_proof = []
for item in merkle_neighbors:
left, right = min(digest, item), max(digest, item)
digest = sha256(b"\x01" + left + right).digest()
merkle_proof.append(digest)

merkle_proof = len(merkle_proof).to_bytes(1, "little") + b"".join(merkle_proof)
signature = sign_with_privkeys(digest, PRIVATE_KEYS_DEV[:threshold])
sigmask = 0
for i in range(threshold):
sigmask |= 1 << i
sigmask_byte = sigmask.to_bytes(1, "little")
return merkle_proof, sigmask_byte + signature


def encode_network(
network: messages.EthereumNetworkInfo | None = None,
chain_id: int = 0,
slip44: int = 0,
symbol: str = "FAKE",
name: str = "Fake network",
) -> bytes:
if network is None:
network = make_network(chain_id, slip44, symbol, name)
payload = make_payload(
data_type=messages.EthereumDefinitionType.NETWORK, message=network
)
proof, signature = sign_payload(payload, [])
return payload + proof + signature


def encode_token(
token: messages.EthereumTokenInfo | None = None,
symbol: str = "FakeTok",
decimals: int = 18,
address: t.AnyStr = b"",
chain_id: int = 0,
name: str = "Fake token",
) -> bytes:
if token is None:
if isinstance(address, str):
if address.startswith("0x"):
address = address[2:]
address = bytes.fromhex(address) # type: ignore (typechecker is lying)
token = make_token(symbol, decimals, address, chain_id, name) # type: ignore (typechecker is lying)
payload = make_payload(
data_type=messages.EthereumDefinitionType.TOKEN, message=token
)
proof, signature = sign_payload(payload, [])
return payload + proof + signature


def make_defs(
network: bytes | None, token: bytes | None
) -> messages.EthereumDefinitions:
return messages.EthereumDefinitions(
encoded_network=network,
encoded_token=token,
)
Loading

0 comments on commit e2d6003

Please sign in to comment.