mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-18 05:28:40 +00:00
103 lines
3.0 KiB
Python
103 lines
3.0 KiB
Python
|
from ubinascii import unhexlify # noqa: F401
|
||
|
|
||
|
from trezor import messages, protobuf
|
||
|
from trezor.enums import EthereumDefinitionType
|
||
|
from trezor.crypto.curve import ed25519
|
||
|
from trezor.crypto.hashlib import sha256
|
||
|
|
||
|
DEFINITIONS_DEV_PRIVATE_KEY = unhexlify(
|
||
|
"4141414141414141414141414141414141414141414141414141414141414141"
|
||
|
)
|
||
|
|
||
|
|
||
|
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(
|
||
|
prefix: bytes = b"trzd1",
|
||
|
data_type: EthereumDefinitionType = EthereumDefinitionType.NETWORK,
|
||
|
timestamp: int = 0xFFFF_FFFF,
|
||
|
message: messages.EthereumNetworkInfo
|
||
|
| messages.EthereumTokenInfo
|
||
|
| bytes = make_network(),
|
||
|
) -> bytes:
|
||
|
payload = prefix
|
||
|
payload += data_type.to_bytes(1, "little")
|
||
|
payload += timestamp.to_bytes(4, "little")
|
||
|
if isinstance(message, bytes):
|
||
|
message_bytes = message
|
||
|
else:
|
||
|
message_bytes = protobuf.dump_message_buffer(message)
|
||
|
payload += len(message_bytes).to_bytes(2, "little")
|
||
|
payload += message_bytes
|
||
|
return payload
|
||
|
|
||
|
|
||
|
def sign_payload(payload: bytes, merkle_neighbors: list[bytes]) -> 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 = ed25519.sign(DEFINITIONS_DEV_PRIVATE_KEY, digest)
|
||
|
return merkle_proof, 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=EthereumDefinitionType.NETWORK, message=network)
|
||
|
proof, signature = sign_payload(payload, [])
|
||
|
return payload + proof + signature
|
||
|
|
||
|
|
||
|
def encode_token(
|
||
|
token: messages.EthereumTokenInfo | None = None,
|
||
|
symbol: str = "FAKE",
|
||
|
decimals: int = 18,
|
||
|
address: bytes = b"",
|
||
|
chain_id: int = 0,
|
||
|
name: str = "Fake token",
|
||
|
) -> bytes:
|
||
|
if token is None:
|
||
|
token = make_token(symbol, decimals, address, chain_id, name)
|
||
|
payload = make_payload(data_type=EthereumDefinitionType.TOKEN, message=token)
|
||
|
proof, signature = sign_payload(payload, [])
|
||
|
return payload + proof + signature
|