pull/3509/merge
Peter Jaško 3 weeks ago committed by GitHub
commit 9c4548cd20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -500,3 +500,49 @@ message CardanoTxBodyHash {
*/
message CardanoSignTxFinished {
}
/**
* Request: Ask device to sign a message containing arbitrary data
* @start
* @next CardanoMessageItemAck
*/
message CardanoSignMessageInit {
optional uint32 protocol_magic = 1; // network's protocol magic
optional uint32 network_id = 2; // network id - mainnet or testnet
repeated uint32 signing_path = 3; // BIP-32-style path to derive the signing key from master node
required uint32 payload_size = 4; // size of the payload to be signed
required bool hash_payload = 5; // whether to hash the payload before signing
required bool prefer_hex_display = 6; // whether to decode payload as hex even if valid ascii
optional CardanoAddressParametersType address_parameters = 7;
required CardanoDerivationType derivation_type = 8;
}
/**
* @next CardanoMessagePayloadChunk
* @next CardanoMessageItemHostAck
*/
message CardanoMessageItemAck {
}
/**
* @next CardanoMessageItemAck
*/
message CardanoMessagePayloadChunk {
required bytes data = 1; // expected maximum chunk size is 1024 bytes
}
/**
* @next CardanoSignMessageFinished
*/
message CardanoMessageItemHostAck {
}
/**
* Response: Contains signature for message and address used in signed headers
* @end
*/
message CardanoSignMessageFinished {
required bytes signature = 1; // signature for structure containing payload and protected headers
required bytes address = 2; // value of the address field in protected headers
required bytes pub_key = 3; // public key given by signing path
}

@ -297,6 +297,11 @@ enum MessageType {
MessageType_CardanoTxInlineDatumChunk = 335 [(wire_in) = true];
MessageType_CardanoTxReferenceScriptChunk = 336 [(wire_in) = true];
MessageType_CardanoTxReferenceInput = 337 [(wire_in) = true];
MessageType_CardanoSignMessageInit = 338 [(wire_in) = true];
MessageType_CardanoMessagePayloadChunk = 339 [(wire_in) = true];
MessageType_CardanoMessageItemAck = 340 [(wire_out) = true];
MessageType_CardanoMessageItemHostAck = 341 [(wire_in) = true];
MessageType_CardanoSignMessageFinished = 342 [(wire_out) = true];
// Ripple
MessageType_RippleGetAddress = 400 [(wire_in) = true];

@ -0,0 +1,39 @@
{
"setup": {
"mnemonic": "all all all all all all all all all all all all",
"passphrase": ""
},
"tests": [
{
"description": "Missing network id and protocol magic",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"address_parameters": {
"addressType": 0,
"path": "m/1852'/1815'/0'/0/0",
"stakingPath": "m/1852'/1815'/0'/2/0"
},
"payload": "",
"hash_payload": false,
"prefer_hex_display": true
},
"result": {
"error_message": "Must specify network_id and protocol_magic if using address_parameters"
}
},
{
"description": "Unhashed payload too long",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"network_id": 1,
"protocol_magic": 764824073,
"payload": "566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765",
"hash_payload": false,
"prefer_hex_display": true
},
"result": {
"error_message": "Payload too long to sign without hashing"
}
}
]
}

@ -0,0 +1,159 @@
{
"setup": {
"mnemonic": "all all all all all all all all all all all all",
"passphrase": ""
},
"tests": [
{
"description": "Sign short non-ASCII payload",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "ff00",
"hash_payload": false,
"prefer_hex_display": true
},
"result": {
"signature": "5ad6ba670e65353b2c1ad4053a1ed4a9348a73fe965ffa0afafa24bad06e3eb3e325d49029604c09bf665c3c43a750ec81a43b1f8b746b07e999b913b980d006",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Sign short non-ASCII payload with address parameters",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"network_id": 1,
"protocol_magic": 764824073,
"payload": "ff00",
"hash_payload": false,
"address_parameters": {
"addressType": 0,
"path": "m/1852'/1815'/0'/0/0",
"stakingPath": "m/1852'/1815'/0'/2/0"
},
"prefer_hex_display": true
},
"result": {
"signature": "9efaff0b74c0beb2cadd727d8bafe13b31107235c5fc46c6c33e596e024d391c9fbe37072e43965add6ee0a4788562382031486b74fd59d636aa1ca3b1ddfe06",
"address": "0180f9e2c88e6c817008f3a812ed889b4a4da8e0bd103f86e7335422aa122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b4277",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Sign short non-ASCII payload hash",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "ff00",
"hash_payload": true,
"prefer_hex_display": true
},
"result": {
"signature": "2c325e542fa78d76d916e50f50b85e770354a44e071f08fdb8ec5d0bcbf844cf70dcf5c87b7a51cd7f0269a59eec8d438c3c27eb42b971e7ccb7f864714c4b06",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Sign short ASCII payload",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "54657374",
"hash_payload": false,
"prefer_hex_display": false
},
"result": {
"signature": "2201b8e7fa9ea919935e06ecc3e845433855066acaaf61cb8e624a2eb7139b73a9d126e7ee04548fff06ac933bd5419fc78c5aebee9b536cbee1481b52ec3e03",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Sign short ASCII payload rendered as hex",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "54657374",
"hash_payload": false,
"prefer_hex_display": true
},
"result": {
"signature": "2201b8e7fa9ea919935e06ecc3e845433855066acaaf61cb8e624a2eb7139b73a9d126e7ee04548fff06ac933bd5419fc78c5aebee9b536cbee1481b52ec3e03",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Sign empty payload",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "",
"hash_payload": false,
"prefer_hex_display": true
},
"result": {
"signature": "b09177a06cb2deba7ada89fec96fc4380e746f67c6b16a9ef9ae6b7cbbe941fdad8a8a573b809cd88db296b91b476c436033a29d86a63959e270047e47cd5d0d",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Sign empty payload hash",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "",
"hash_payload": true,
"prefer_hex_display": true
},
"result": {
"signature": "a2503039a8ec620e05d9e4345339d61cd11480fbfcc75ea1a10789751a7c5f46ba06786eb1719da62db76c20313ad3445839b8117abac206cc4bd63ea623fc07",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Sign long ASCII payload hash",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765",
"hash_payload": true,
"prefer_hex_display": false
},
"result": {
"signature": "92331e75bb4c3208317ac422f2fc9d8b9b09d3f81cc487edaa7028d262553e5691532fb166a40e45eb2e4addd4280ff7e07bd4249e964d969e91555317b05f08",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Non-ASCII payload falls back to hex",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"network_id": 1,
"protocol_magic": 764824073,
"payload": "ff",
"hash_payload": false,
"prefer_hex_display": false
},
"result": {
"signature": "eb7e48bb2de912b24ea4e295cfbf338e95e2a2d9c5eb41d72ddd8ebf96ca6128696e91e65e20a755821781b8ea0b4aa7ffcfa6ab0c7da2c67ecaf33fcd596509",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
},
{
"description": "Ambiguous ASCII payload falls back to hex",
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"network_id": 1,
"protocol_magic": 764824073,
"payload": "20",
"hash_payload": false,
"prefer_hex_display": false
},
"result": {
"signature": "1cd79c511e58e0d00bc402c24631a982c0f596e13cad38447d4f31213d085b23b9990b45023450f5ab4d47987993af662702b07bfc8195feb80b2c9e1c1dc10f",
"address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba",
"pub_key": "67e3d14e1e0db2a6ff68832994451f63d3e92a4ee85c3681d72634ccfe889f2c"
}
}
]
}

@ -0,0 +1 @@
Cardano: Add support for signing arbitrary messages

@ -457,6 +457,8 @@ if not utils.BITCOIN_ONLY:
import apps.cardano.helpers.account_path_check
apps.cardano.helpers.bech32
import apps.cardano.helpers.bech32
apps.cardano.helpers.chunks
import apps.cardano.helpers.chunks
apps.cardano.helpers.credential
import apps.cardano.helpers.credential
apps.cardano.helpers.hash_builder_collection
@ -475,6 +477,8 @@ if not utils.BITCOIN_ONLY:
import apps.cardano.native_script
apps.cardano.seed
import apps.cardano.seed
apps.cardano.sign_message
import apps.cardano.sign_message
apps.cardano.sign_tx
import apps.cardano.sign_tx
apps.cardano.sign_tx.multisig_signer

@ -46,6 +46,13 @@ ADDRESS_TYPES_PAYMENT_SCRIPT = (
CardanoAddressType.ENTERPRISE_SCRIPT,
)
ADDRESS_TYPES_MESSAGE = (
CardanoAddressType.BASE,
CardanoAddressType.BASE_KEY_SCRIPT,
CardanoAddressType.ENTERPRISE,
CardanoAddressType.REWARD,
)
ADDRESS_TYPES_PAYMENT = ADDRESS_TYPES_PAYMENT_KEY + ADDRESS_TYPES_PAYMENT_SCRIPT
_MIN_ADDRESS_BYTES_LENGTH = const(29)
@ -242,6 +249,13 @@ def validate_cvote_payment_address_parameters(
assert_params_cond(parameters.address_type in ADDRESS_TYPES_SHELLEY)
def validate_message_address_parameters(
parameters: messages.CardanoAddressParametersType,
) -> None:
validate_address_parameters(parameters)
assert_params_cond(parameters.address_type in ADDRESS_TYPES_MESSAGE)
def assert_cond(condition: bool) -> None:
if not condition:
raise ProcessError("Invalid address")

@ -0,0 +1,79 @@
from micropython import const
from typing import TYPE_CHECKING
from trezor import messages, protobuf
from trezor.wire import ProcessError
from trezor.wire.context import call as ctx_call
if TYPE_CHECKING:
from typing import Generic, TypeVar, Union
Chunk = Union[
messages.CardanoTxInlineDatumChunk,
messages.CardanoTxReferenceScriptChunk,
messages.CardanoMessagePayloadChunk,
]
C = TypeVar("C", bound=Chunk)
else:
# typechecker cheat
Generic = (object,)
C = Chunk = 0
MAX_CHUNK_SIZE = const(1024)
def _get_chunks_count(size: int) -> int:
"""Integer-only version of `ceil(size / MAX_CHUNK_SIZE)`."""
assert size >= 0
return 0 if size == 0 else (size - 1) // MAX_CHUNK_SIZE + 1
def _validate_chunk(
chunk: Chunk,
chunk_index: int,
total_size: int,
) -> None:
chunks_count = _get_chunks_count(total_size)
assert chunk_index < chunks_count
if len(chunk.data) > MAX_CHUNK_SIZE:
raise ProcessError("Invalid chunk: Too large")
is_last_chunk = chunk_index == chunks_count - 1
if not is_last_chunk and len(chunk.data) < MAX_CHUNK_SIZE:
raise ProcessError("Invalid intermediate chunk: Too small")
if (
is_last_chunk
# check whether this chunk and preceding chunks add up to the supposed size
and len(chunk.data) + MAX_CHUNK_SIZE * (chunks_count - 1) != total_size
):
raise ProcessError("Invalid last chunk: Size inconsistent with total bytes")
class ChunkIterator(Generic[C]):
def __init__(
self,
total_size: int,
ack_msg: protobuf.MessageType,
chunk_type: type[C],
) -> None:
self.ack_msg = ack_msg
self.chunk_type = chunk_type
self.chunk_index = 0
self.chunks_count = _get_chunks_count(total_size)
self.total_size = total_size
def __aiter__(self) -> "ChunkIterator":
return self
async def __anext__(self) -> tuple[int, C]:
if self.chunk_index >= self.chunks_count:
raise StopAsyncIteration
chunk: C = await ctx_call(self.ack_msg, self.chunk_type)
_validate_chunk(chunk, chunk_index=self.chunk_index, total_size=self.total_size)
result = (self.chunk_index, chunk)
self.chunk_index += 1
return result

@ -113,3 +113,39 @@ def validate_network_info(network_id: int, protocol_magic: int) -> None:
if is_mainnet_network_id != is_mainnet_protocol_magic:
raise wire.ProcessError("Invalid network id/protocol magic combination!")
def is_printable_ascii(bytestring: bytes) -> bool:
"""Includes space character."""
return all(32 <= b <= 126 for b in bytestring)
def is_unambiguous_ascii(bytestring: bytes) -> bool:
"""
Checks whether the bytestring can be printed as ASCII without confusion.
Based on https://github.com/vacuumlabs/ledger-app-cardano-shelley/blob/6ddc60e8fdff13e35bff5cdf108b84b81a79f10c/src/textUtils.c#L274
"""
# no empty strings
if len(bytestring) == 0:
return False
# no non-printable ascii except spaces
if not is_printable_ascii(bytestring):
return False
SPACE = ord(" ")
# no leading space
if bytestring[0] == SPACE:
return False
# no trailing space
if bytestring[-1] == SPACE:
return False
# no consecutive spaces
for a, b in zip(bytestring, bytestring[1:]):
if a == SPACE and b == SPACE:
return False
return True

@ -11,6 +11,7 @@ from trezor.strings import format_amount
from trezor.ui import layouts
from trezor.ui.layouts import confirm_metadata, confirm_properties
from apps.cardano.helpers.chunks import MAX_CHUNK_SIZE
from apps.common.paths import address_n_to_str
from . import addresses
@ -20,10 +21,11 @@ from .helpers.utils import (
format_asset_fingerprint,
format_optional_int,
format_stake_pool_id,
is_unambiguous_ascii,
)
if TYPE_CHECKING:
from typing import Literal
from typing import Callable, Literal
from trezor import messages
from trezor.enums import CardanoNativeScriptHashDisplayFormat
@ -67,6 +69,8 @@ BRT_Other = ButtonRequestType.Other # global_import_cache
CVOTE_REWARD_ELIGIBILITY_WARNING = TR.cardano__reward_eligibility_warning
_DEFAULT_MAX_DISPLAYED_CHUNK_SIZE = 56
def format_coin_amount(amount: int, network_id: int) -> str:
from .helpers import network_ids
@ -270,7 +274,7 @@ async def confirm_datum_hash(datum_hash: bytes) -> None:
async def confirm_inline_datum(first_chunk: bytes, inline_datum_size: int) -> None:
await _confirm_data_chunk(
await _confirm_tx_data_chunk(
"confirm_inline_datum",
TR.cardano__inline_datum,
first_chunk,
@ -281,7 +285,7 @@ async def confirm_inline_datum(first_chunk: bytes, inline_datum_size: int) -> No
async def confirm_reference_script(
first_chunk: bytes, reference_script_size: int
) -> None:
await _confirm_data_chunk(
await _confirm_tx_data_chunk(
"confirm_reference_script",
TR.cardano__reference_script,
first_chunk,
@ -289,24 +293,80 @@ async def confirm_reference_script(
)
async def _confirm_data_chunk(
br_type: str, title: str, first_chunk: bytes, data_size: int
async def confirm_message_payload(
payload_first_chunk: bytes,
payload_hash: bytes,
payload_size: int,
is_signing_hash: bool,
prefer_hex_display: bool,
) -> None:
MAX_DISPLAYED_SIZE = 56
displayed_bytes = first_chunk[:MAX_DISPLAYED_SIZE]
props: list[PropertyType]
max_displayed_bytes = (
_DEFAULT_MAX_DISPLAYED_CHUNK_SIZE if is_signing_hash else MAX_CHUNK_SIZE
)
if not payload_first_chunk:
assert payload_size == 0
props = _get_data_chunk_props(
title="Empty message",
first_chunk=payload_first_chunk,
data_size=payload_size,
)
elif not prefer_hex_display and is_unambiguous_ascii(payload_first_chunk):
props = _get_data_chunk_props(
title="Message text",
first_chunk=payload_first_chunk,
data_size=payload_size,
max_displayed_size=max_displayed_bytes,
decoder=lambda chunk: chunk.decode("ascii"),
)
else:
props = _get_data_chunk_props(
title="Message hex",
first_chunk=payload_first_chunk,
data_size=payload_size,
max_displayed_size=max_displayed_bytes,
)
props.append(("Message hash:", payload_hash))
await confirm_properties(
"confirm_message_payload",
title="Confirm message",
props=props,
br_code=BRT_Other,
)
def _get_data_chunk_props(
title: str,
first_chunk: bytes,
data_size: int,
max_displayed_size: int = _DEFAULT_MAX_DISPLAYED_CHUNK_SIZE,
decoder: Callable[[bytes], bytes | str] | None = None,
) -> list[PropertyType]:
displayed_bytes = first_chunk[:max_displayed_size]
bytes_optional_plural = "byte" if data_size == 1 else "bytes"
props: list[tuple[str, bytes | None]] = [
props: list[PropertyType] = [
(
f"{title} ({data_size} {bytes_optional_plural}):",
displayed_bytes,
decoder(displayed_bytes) if decoder else displayed_bytes,
)
]
if data_size > MAX_DISPLAYED_SIZE:
if data_size > max_displayed_size:
props.append(("...", None))
return props
async def _confirm_tx_data_chunk(
br_type: str, title: str, first_chunk: bytes, data_size: int
) -> None:
await confirm_properties(
br_type,
title=TR.cardano__confirm_transaction,
props=props,
props=_get_data_chunk_props(title, first_chunk, data_size),
br_code=BRT_Other,
)
@ -320,6 +380,12 @@ async def show_credentials(
await _show_credential(stake_credential, intro_text, purpose="address")
async def show_message_header_credentials(credentials: list[Credential]) -> None:
intro_text = "Address"
for credential in credentials:
await _show_credential(credential, intro_text, purpose="message")
async def show_change_output_credentials(
payment_credential: Credential,
stake_credential: Credential,
@ -364,13 +430,14 @@ async def show_cvote_registration_payment_credentials(
async def _show_credential(
credential: Credential,
intro_text: str,
purpose: Literal["address", "output", "cvote_reg_payment_address"],
purpose: Literal["address", "output", "cvote_reg_payment_address", "message"],
extra_text: str | None = None,
) -> None:
title = {
"address": f"{ADDRESS_TYPE_NAMES[credential.address_type]} address",
"output": TR.cardano__confirm_transaction,
"cvote_reg_payment_address": TR.cardano__confirm_transaction,
"message": "Confirm message",
}[purpose]
props: list[PropertyType] = []
@ -480,23 +547,35 @@ async def warn_unknown_total_collateral() -> None:
)
async def confirm_witness_request(
witness_path: list[int],
) -> None:
def _get_path_title(path: list[int]) -> str:
from . import seed
if seed.is_multisig_path(witness_path):
path_title = TR.cardano__multisig_path
elif seed.is_minting_path(witness_path):
path_title = TR.cardano__token_minting_path
if seed.is_multisig_path(path):
return TR.cardano__multisig_path
elif seed.is_minting_path(path):
return TR.cardano__token_minting_path
else:
path_title = TR.cardano__path
return TR.cardano__path
async def confirm_witness_request(
witness_path: list[int],
) -> None:
await layouts.confirm_text(
"confirm_total",
TR.cardano__confirm_transaction,
address_n_to_str(witness_path),
TR.cardano__sign_tx_path_template.format(path_title),
TR.cardano__sign_tx_path_template.format(_get_path_title(witness_path)),
BRT_Other,
)
async def confirm_message_path(path: list[int], is_signing_hash: bool) -> None:
await layouts.confirm_text(
"confirm_message_signing_path",
"Confirm message",
address_n_to_str(path),
f"Sign message{' hash' if is_signing_hash else ''} with {_get_path_title(path)}:",
BRT_Other,
)

@ -24,6 +24,7 @@ if TYPE_CHECKING:
| messages.CardanoGetPublicKey
| messages.CardanoGetNativeScriptHash
| messages.CardanoSignTxInit
| messages.CardanoSignMessageInit
)
MsgIn = TypeVar("MsgIn", bound=CardanoMessages)

@ -0,0 +1,190 @@
from micropython import const
from typing import TYPE_CHECKING
from trezor.wire import ProcessError
from trezor.wire.context import call as ctx_call
from apps.cardano.helpers.chunks import MAX_CHUNK_SIZE, ChunkIterator
from apps.cardano.helpers.credential import Credential
from apps.cardano.helpers.paths import SCHEMA_MINT, SCHEMA_PUBKEY
from apps.cardano.helpers.utils import derive_public_key
from apps.common import cbor
from . import addresses, seed
if TYPE_CHECKING:
from typing import Any
from trezor.messages import CardanoSignMessageFinished, CardanoSignMessageInit
from apps.common.cbor import CborSequence
Headers = dict[str | int, Any]
_COSE_HEADER_ADDRESS_KEY = "address"
_COSE_HEADER_ALGORITHM_KEY = const(1)
_COSE_EDDSA_ALGORITHM_ID = const(-8)
async def _validate_message_signing_path(
path: list[int], keychain: seed.Keychain
) -> None:
from apps.common import paths
await paths.validate_path(keychain, path)
if not SCHEMA_PUBKEY.match(path) and not SCHEMA_MINT.match(path):
raise ProcessError("Invalid signing path")
async def _validate_message_init(
msg: CardanoSignMessageInit, keychain: seed.Keychain
) -> None:
if msg.address_parameters:
if msg.network_id is None or msg.protocol_magic is None:
raise ProcessError(
"Must specify network_id and protocol_magic if using address_parameters"
)
addresses.validate_message_address_parameters(msg.address_parameters)
if msg.payload_size > MAX_CHUNK_SIZE and not msg.hash_payload:
raise ProcessError("Payload too long to sign without hashing")
await _validate_message_signing_path(msg.signing_path, keychain)
async def _get_confirmed_header_address(
msg: CardanoSignMessageInit, keychain: seed.Keychain
) -> bytes:
from . import layout
if msg.address_parameters:
assert (
msg.protocol_magic is not None and msg.network_id is not None
) # _validate_message_init
await layout.show_message_header_credentials(
[
Credential.payment_credential(msg.address_parameters),
Credential.stake_credential(msg.address_parameters),
]
)
return addresses.derive_bytes(
keychain, msg.address_parameters, msg.protocol_magic, msg.network_id
)
else:
return addresses.get_public_key_hash(keychain, msg.signing_path)
async def _get_payload_hash_and_first_chunk(size: int) -> tuple[bytes, bytes]:
"""Returns the hash of the whole payload and the raw first chunk of the payload."""
from trezor.crypto import hashlib
from trezor.messages import (
CardanoMessageItemAck,
CardanoMessageItemHostAck,
CardanoMessagePayloadChunk,
)
first_chunk = b""
hash_fn = hashlib.blake2b(outlen=28)
async for chunk_index, chunk in ChunkIterator(
total_size=size,
ack_msg=CardanoMessageItemAck(),
chunk_type=CardanoMessagePayloadChunk,
):
hash_fn.update(chunk.data)
if chunk_index == 0:
first_chunk = chunk.data
await ctx_call(CardanoMessageItemAck(), CardanoMessageItemHostAck)
return hash_fn.digest(), first_chunk
async def _get_confirmed_payload(
size: int, is_signing_hash: bool, prefer_hex_display: bool
) -> bytes:
from . import layout
hash, first_chunk = await _get_payload_hash_and_first_chunk(size)
await layout.confirm_message_payload(
payload_size=size,
payload_first_chunk=first_chunk,
payload_hash=hash,
is_signing_hash=is_signing_hash,
prefer_hex_display=prefer_hex_display,
)
return hash if is_signing_hash else first_chunk
def _cborize_sig_structure(
payload: bytes,
protected_headers: Headers,
external_aad: bytes | None = None,
) -> CborSequence:
serialized_headers = cbor.encode(protected_headers)
# only "Signature1" context is supported
return ["Signature1", serialized_headers, external_aad or b"", payload]
def _sign_sig_structure(
path: list[int],
keychain: seed.Keychain,
cborized_sig_structure: CborSequence,
) -> bytes:
from trezor.crypto.curve import ed25519
serialized_sig_structure = cbor.encode(cborized_sig_structure)
# Preventing ambiguity with tx body hashes
if len(serialized_sig_structure) == 32:
raise ProcessError("The structure to sign cannot be exactly 32 bytes long")
node = keychain.derive(path)
return ed25519.sign_ext(
node.private_key(), node.private_key_ext(), serialized_sig_structure
)
@seed.with_keychain
async def sign_message(
msg: CardanoSignMessageInit, keychain: seed.Keychain
) -> CardanoSignMessageFinished:
from trezor.messages import CardanoSignMessageFinished
from . import layout
await _validate_message_init(msg, keychain)
payload = await _get_confirmed_payload(
size=msg.payload_size,
is_signing_hash=msg.hash_payload,
prefer_hex_display=msg.prefer_hex_display,
)
address = await _get_confirmed_header_address(msg, keychain)
headers: Headers = {
_COSE_HEADER_ALGORITHM_KEY: _COSE_EDDSA_ALGORITHM_ID,
_COSE_HEADER_ADDRESS_KEY: address,
}
await layout.confirm_message_path(
path=msg.signing_path, is_signing_hash=msg.hash_payload
)
signature = _sign_sig_structure(
msg.signing_path,
keychain,
_cborize_sig_structure(payload=payload, protected_headers=headers),
)
return CardanoSignMessageFinished(
signature=signature,
address=address,
pub_key=derive_public_key(keychain, msg.signing_path),
)

@ -11,6 +11,7 @@ from trezor.messages import CardanoTxItemAck, CardanoTxOutput
from trezor.wire import DataError, ProcessError
from trezor.wire.context import call as ctx_call
from apps.cardano.helpers.chunks import ChunkIterator
from apps.common import safety_checks
from .. import addresses, certificates, layout, seed
@ -62,8 +63,6 @@ _DATUM_OPTION_KEY_INLINE = const(1)
_POOL_REGISTRATION_CERTIFICATE_ITEMS_COUNT = const(10)
_MAX_CHUNK_SIZE = const(1024)
class Signer:
"""
@ -612,17 +611,11 @@ class Signer:
) -> None:
assert inline_datum_size > 0
chunks_count = self._get_chunks_count(inline_datum_size)
for chunk_number in range(chunks_count):
chunk: messages.CardanoTxInlineDatumChunk = await ctx_call(
CardanoTxItemAck(), messages.CardanoTxInlineDatumChunk
)
self._validate_chunk(
chunk.data,
chunk_number,
chunks_count,
ProcessError("Invalid inline datum chunk"),
)
async for chunk_number, chunk in ChunkIterator(
total_size=inline_datum_size,
ack_msg=CardanoTxItemAck(),
chunk_type=messages.CardanoTxInlineDatumChunk,
):
if chunk_number == 0 and should_show:
await self._show_if_showing_details(
layout.confirm_inline_datum(chunk.data, inline_datum_size)
@ -639,17 +632,11 @@ class Signer:
) -> None:
assert reference_script_size > 0
chunks_count = self._get_chunks_count(reference_script_size)
for chunk_number in range(chunks_count):
chunk: messages.CardanoTxReferenceScriptChunk = await ctx_call(
CardanoTxItemAck(), messages.CardanoTxReferenceScriptChunk
)
self._validate_chunk(
chunk.data,
chunk_number,
chunks_count,
ProcessError("Invalid reference script chunk"),
)
async for chunk_number, chunk in ChunkIterator(
total_size=reference_script_size,
ack_msg=CardanoTxItemAck(),
chunk_type=messages.CardanoTxReferenceScriptChunk,
):
if chunk_number == 0 and should_show:
await self._show_if_showing_details(
layout.confirm_reference_script(chunk.data, reference_script_size)
@ -1175,22 +1162,6 @@ class Signer:
self.msg.network_id,
)
def _get_chunks_count(self, data_size: int) -> int:
assert data_size > 0
return (data_size - 1) // _MAX_CHUNK_SIZE + 1
def _validate_chunk(
self,
chunk_data: bytes,
chunk_number: int,
chunks_count: int,
error: ProcessError,
) -> None:
if chunk_number < chunks_count - 1 and len(chunk_data) != _MAX_CHUNK_SIZE:
raise error
if chunk_number == chunks_count - 1 and len(chunk_data) > _MAX_CHUNK_SIZE:
raise error
def _get_byron_witness(
self, path: list[int], tx_hash: bytes
) -> messages.CardanoTxWitnessResponse:

@ -169,6 +169,8 @@ def _find_message_handler_module(msg_type: int) -> str:
return "apps.cardano.sign_tx"
if msg_type == MessageType.CardanoGetNativeScriptHash:
return "apps.cardano.get_native_script_hash"
if msg_type == MessageType.CardanoSignMessageInit:
return "apps.cardano.sign_message"
# tezos
if msg_type == MessageType.TezosGetAddress:

@ -180,6 +180,11 @@ if not utils.BITCOIN_ONLY:
CardanoTxInlineDatumChunk = 335
CardanoTxReferenceScriptChunk = 336
CardanoTxReferenceInput = 337
CardanoSignMessageInit = 338
CardanoMessagePayloadChunk = 339
CardanoMessageItemAck = 340
CardanoMessageItemHostAck = 341
CardanoSignMessageFinished = 342
RippleGetAddress = 400
RippleAddress = 401
RippleSignTx = 402

@ -198,6 +198,11 @@ if TYPE_CHECKING:
CardanoTxInlineDatumChunk = 335
CardanoTxReferenceScriptChunk = 336
CardanoTxReferenceInput = 337
CardanoSignMessageInit = 338
CardanoMessagePayloadChunk = 339
CardanoMessageItemAck = 340
CardanoMessageItemHostAck = 341
CardanoSignMessageFinished = 342
RippleGetAddress = 400
RippleAddress = 401
RippleSignTx = 402

@ -1867,6 +1867,78 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["CardanoSignTxFinished"]:
return isinstance(msg, cls)
class CardanoSignMessageInit(protobuf.MessageType):
protocol_magic: "int | None"
network_id: "int | None"
signing_path: "list[int]"
payload_size: "int"
hash_payload: "bool"
prefer_hex_display: "bool"
address_parameters: "CardanoAddressParametersType | None"
derivation_type: "CardanoDerivationType"
def __init__(
self,
*,
payload_size: "int",
hash_payload: "bool",
prefer_hex_display: "bool",
derivation_type: "CardanoDerivationType",
signing_path: "list[int] | None" = None,
protocol_magic: "int | None" = None,
network_id: "int | None" = None,
address_parameters: "CardanoAddressParametersType | None" = None,
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["CardanoSignMessageInit"]:
return isinstance(msg, cls)
class CardanoMessageItemAck(protobuf.MessageType):
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["CardanoMessageItemAck"]:
return isinstance(msg, cls)
class CardanoMessagePayloadChunk(protobuf.MessageType):
data: "bytes"
def __init__(
self,
*,
data: "bytes",
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["CardanoMessagePayloadChunk"]:
return isinstance(msg, cls)
class CardanoMessageItemHostAck(protobuf.MessageType):
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["CardanoMessageItemHostAck"]:
return isinstance(msg, cls)
class CardanoSignMessageFinished(protobuf.MessageType):
signature: "bytes"
address: "bytes"
pub_key: "bytes"
def __init__(
self,
*,
signature: "bytes",
address: "bytes",
pub_key: "bytes",
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["CardanoSignMessageFinished"]:
return isinstance(msg, cls)
class CipherKeyValue(protobuf.MessageType):
address_n: "list[int]"
key: "str"

@ -0,0 +1 @@
Cardano: Add support for signing arbitrary messages

@ -109,7 +109,9 @@ SignTxResponse = Dict[str, Union[bytes, List[Witness], AuxiliaryDataSupplement]]
Chunk = TypeVar(
"Chunk",
bound=Union[
messages.CardanoTxInlineDatumChunk, messages.CardanoTxReferenceScriptChunk
messages.CardanoTxInlineDatumChunk,
messages.CardanoTxReferenceScriptChunk,
messages.CardanoMessagePayloadChunk,
],
)
@ -329,6 +331,22 @@ def _parse_address_parameters(
)
def parse_optional_address_parameters(
address_parameters: Optional[dict],
) -> Optional[messages.CardanoAddressParametersType]:
if address_parameters is None:
return None
ADDRESS_PARAMETERS_MISSING_FIELDS_ERROR = (
"Address parameters are missing some fields"
)
return _parse_address_parameters(
address_parameters,
ADDRESS_PARAMETERS_MISSING_FIELDS_ERROR,
)
def _parse_chunkable_data(
data: Optional[bytes], chunk_type: Type[Chunk]
) -> Tuple[int, List[Chunk]]:
@ -969,3 +987,47 @@ def sign_tx(
raise UNEXPECTED_RESPONSE_ERROR
return sign_tx_response
def sign_message(
client: "TrezorClient",
signing_path: Path,
payload: bytes,
hash_payload: bool,
prefer_hex_display: bool,
address_parameters: Optional[messages.CardanoAddressParametersType] = None,
derivation_type: messages.CardanoDerivationType = messages.CardanoDerivationType.ICARUS,
protocol_magic: Optional[int] = None,
network_id: Optional[int] = None,
) -> messages.CardanoSignMessageFinished:
UNEXPECTED_RESPONSE_ERROR = exceptions.TrezorException("Unexpected response")
size, chunks = _parse_chunkable_data(payload, messages.CardanoMessagePayloadChunk)
response = client.call(
messages.CardanoSignMessageInit(
signing_path=signing_path,
payload_size=size,
hash_payload=hash_payload,
address_parameters=address_parameters,
prefer_hex_display=prefer_hex_display,
protocol_magic=protocol_magic,
network_id=network_id,
derivation_type=derivation_type,
)
)
if not isinstance(response, messages.CardanoMessageItemAck):
raise UNEXPECTED_RESPONSE_ERROR
for chunk in chunks:
chunk_response = client.call(chunk)
if not isinstance(chunk_response, messages.CardanoMessageItemAck):
raise UNEXPECTED_RESPONSE_ERROR
final_response = client.call(messages.CardanoMessageItemHostAck())
if not isinstance(final_response, messages.CardanoSignMessageFinished):
raise UNEXPECTED_RESPONSE_ERROR
return final_response

@ -15,7 +15,7 @@
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import json
from typing import TYPE_CHECKING, Optional, TextIO
from typing import TYPE_CHECKING, Any, Optional, TextIO
import click
@ -324,3 +324,36 @@ def get_native_script_hash(
return cardano.get_native_script_hash(
client, native_script, display_format, derivation_type=derivation_type
)
@cli.command()
@click.argument("file", type=click.File("r"))
@click.option(
"-D",
"--derivation-type",
type=ChoiceType({m.name: m for m in messages.CardanoDerivationType}),
default=messages.CardanoDerivationType.ICARUS,
)
@with_client
def sign_message(
client: "TrezorClient",
file: TextIO,
derivation_type: messages.CardanoDerivationType,
) -> messages.CardanoSignMessageFinished:
"""Sign Cardano message containing arbitrary data."""
request: dict[Any, Any] = json.load(file)
client.init_device(derive_cardano=True)
return cardano.sign_message(
client,
payload=bytes.fromhex(request["payload"]),
hash_payload=request["hash_payload"],
prefer_hex_display=request["prefer_hex_display"],
signing_path=tools.parse_path(request["signing_path"]),
address_parameters=cardano.parse_optional_address_parameters(
request.get("address_parameters")
),
protocol_magic=request.get("protocol_magic"),
network_id=request.get("network_id"),
derivation_type=derivation_type,
)

@ -206,6 +206,11 @@ class MessageType(IntEnum):
CardanoTxInlineDatumChunk = 335
CardanoTxReferenceScriptChunk = 336
CardanoTxReferenceInput = 337
CardanoSignMessageInit = 338
CardanoMessagePayloadChunk = 339
CardanoMessageItemAck = 340
CardanoMessageItemHostAck = 341
CardanoSignMessageFinished = 342
RippleGetAddress = 400
RippleAddress = 401
RippleSignTx = 402
@ -2917,6 +2922,83 @@ class CardanoSignTxFinished(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 319
class CardanoSignMessageInit(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 338
FIELDS = {
1: protobuf.Field("protocol_magic", "uint32", repeated=False, required=False, default=None),
2: protobuf.Field("network_id", "uint32", repeated=False, required=False, default=None),
3: protobuf.Field("signing_path", "uint32", repeated=True, required=False, default=None),
4: protobuf.Field("payload_size", "uint32", repeated=False, required=True),
5: protobuf.Field("hash_payload", "bool", repeated=False, required=True),
6: protobuf.Field("prefer_hex_display", "bool", repeated=False, required=True),
7: protobuf.Field("address_parameters", "CardanoAddressParametersType", repeated=False, required=False, default=None),
8: protobuf.Field("derivation_type", "CardanoDerivationType", repeated=False, required=True),
}
def __init__(
self,
*,
payload_size: "int",
hash_payload: "bool",
prefer_hex_display: "bool",
derivation_type: "CardanoDerivationType",
signing_path: Optional[Sequence["int"]] = None,
protocol_magic: Optional["int"] = None,
network_id: Optional["int"] = None,
address_parameters: Optional["CardanoAddressParametersType"] = None,
) -> None:
self.signing_path: Sequence["int"] = signing_path if signing_path is not None else []
self.payload_size = payload_size
self.hash_payload = hash_payload
self.prefer_hex_display = prefer_hex_display
self.derivation_type = derivation_type
self.protocol_magic = protocol_magic
self.network_id = network_id
self.address_parameters = address_parameters
class CardanoMessageItemAck(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 340
class CardanoMessagePayloadChunk(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 339
FIELDS = {
1: protobuf.Field("data", "bytes", repeated=False, required=True),
}
def __init__(
self,
*,
data: "bytes",
) -> None:
self.data = data
class CardanoMessageItemHostAck(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 341
class CardanoSignMessageFinished(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 342
FIELDS = {
1: protobuf.Field("signature", "bytes", repeated=False, required=True),
2: protobuf.Field("address", "bytes", repeated=False, required=True),
3: protobuf.Field("pub_key", "bytes", repeated=False, required=True),
}
def __init__(
self,
*,
signature: "bytes",
address: "bytes",
pub_key: "bytes",
) -> None:
self.signature = signature
self.address = address
self.pub_key = pub_key
class CipherKeyValue(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 23
FIELDS = {

@ -149,6 +149,11 @@ trezor_message_impl! {
CardanoTxInlineDatumChunk => MessageType_CardanoTxInlineDatumChunk,
CardanoTxReferenceScriptChunk => MessageType_CardanoTxReferenceScriptChunk,
CardanoTxReferenceInput => MessageType_CardanoTxReferenceInput,
CardanoSignMessageInit => MessageType_CardanoSignMessageInit,
CardanoMessagePayloadChunk => MessageType_CardanoMessagePayloadChunk,
CardanoMessageItemAck => MessageType_CardanoMessageItemAck,
CardanoMessageItemHostAck => MessageType_CardanoMessageItemHostAck,
CardanoSignMessageFinished => MessageType_CardanoSignMessageFinished,
}
#[cfg(feature = "eos")]

@ -382,6 +382,16 @@ pub enum MessageType {
MessageType_CardanoTxReferenceScriptChunk = 336,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_CardanoTxReferenceInput)
MessageType_CardanoTxReferenceInput = 337,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_CardanoSignMessageInit)
MessageType_CardanoSignMessageInit = 338,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_CardanoMessagePayloadChunk)
MessageType_CardanoMessagePayloadChunk = 339,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_CardanoMessageItemAck)
MessageType_CardanoMessageItemAck = 340,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_CardanoMessageItemHostAck)
MessageType_CardanoMessageItemHostAck = 341,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_CardanoSignMessageFinished)
MessageType_CardanoSignMessageFinished = 342,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_RippleGetAddress)
MessageType_RippleGetAddress = 400,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_RippleAddress)
@ -702,6 +712,11 @@ impl ::protobuf::Enum for MessageType {
335 => ::std::option::Option::Some(MessageType::MessageType_CardanoTxInlineDatumChunk),
336 => ::std::option::Option::Some(MessageType::MessageType_CardanoTxReferenceScriptChunk),
337 => ::std::option::Option::Some(MessageType::MessageType_CardanoTxReferenceInput),
338 => ::std::option::Option::Some(MessageType::MessageType_CardanoSignMessageInit),
339 => ::std::option::Option::Some(MessageType::MessageType_CardanoMessagePayloadChunk),
340 => ::std::option::Option::Some(MessageType::MessageType_CardanoMessageItemAck),
341 => ::std::option::Option::Some(MessageType::MessageType_CardanoMessageItemHostAck),
342 => ::std::option::Option::Some(MessageType::MessageType_CardanoSignMessageFinished),
400 => ::std::option::Option::Some(MessageType::MessageType_RippleGetAddress),
401 => ::std::option::Option::Some(MessageType::MessageType_RippleAddress),
402 => ::std::option::Option::Some(MessageType::MessageType_RippleSignTx),
@ -951,6 +966,11 @@ impl ::protobuf::Enum for MessageType {
"MessageType_CardanoTxInlineDatumChunk" => ::std::option::Option::Some(MessageType::MessageType_CardanoTxInlineDatumChunk),
"MessageType_CardanoTxReferenceScriptChunk" => ::std::option::Option::Some(MessageType::MessageType_CardanoTxReferenceScriptChunk),
"MessageType_CardanoTxReferenceInput" => ::std::option::Option::Some(MessageType::MessageType_CardanoTxReferenceInput),
"MessageType_CardanoSignMessageInit" => ::std::option::Option::Some(MessageType::MessageType_CardanoSignMessageInit),
"MessageType_CardanoMessagePayloadChunk" => ::std::option::Option::Some(MessageType::MessageType_CardanoMessagePayloadChunk),
"MessageType_CardanoMessageItemAck" => ::std::option::Option::Some(MessageType::MessageType_CardanoMessageItemAck),
"MessageType_CardanoMessageItemHostAck" => ::std::option::Option::Some(MessageType::MessageType_CardanoMessageItemHostAck),
"MessageType_CardanoSignMessageFinished" => ::std::option::Option::Some(MessageType::MessageType_CardanoSignMessageFinished),
"MessageType_RippleGetAddress" => ::std::option::Option::Some(MessageType::MessageType_RippleGetAddress),
"MessageType_RippleAddress" => ::std::option::Option::Some(MessageType::MessageType_RippleAddress),
"MessageType_RippleSignTx" => ::std::option::Option::Some(MessageType::MessageType_RippleSignTx),
@ -1199,6 +1219,11 @@ impl ::protobuf::Enum for MessageType {
MessageType::MessageType_CardanoTxInlineDatumChunk,
MessageType::MessageType_CardanoTxReferenceScriptChunk,
MessageType::MessageType_CardanoTxReferenceInput,
MessageType::MessageType_CardanoSignMessageInit,
MessageType::MessageType_CardanoMessagePayloadChunk,
MessageType::MessageType_CardanoMessageItemAck,
MessageType::MessageType_CardanoMessageItemHostAck,
MessageType::MessageType_CardanoSignMessageFinished,
MessageType::MessageType_RippleGetAddress,
MessageType::MessageType_RippleAddress,
MessageType::MessageType_RippleSignTx,
@ -1453,72 +1478,77 @@ impl ::protobuf::EnumFull for MessageType {
MessageType::MessageType_CardanoTxInlineDatumChunk => 174,
MessageType::MessageType_CardanoTxReferenceScriptChunk => 175,
MessageType::MessageType_CardanoTxReferenceInput => 176,
MessageType::MessageType_RippleGetAddress => 177,
MessageType::MessageType_RippleAddress => 178,
MessageType::MessageType_RippleSignTx => 179,
MessageType::MessageType_RippleSignedTx => 180,
MessageType::MessageType_MoneroTransactionInitRequest => 181,
MessageType::MessageType_MoneroTransactionInitAck => 182,
MessageType::MessageType_MoneroTransactionSetInputRequest => 183,
MessageType::MessageType_MoneroTransactionSetInputAck => 184,
MessageType::MessageType_MoneroTransactionInputViniRequest => 185,
MessageType::MessageType_MoneroTransactionInputViniAck => 186,
MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 187,
MessageType::MessageType_MoneroTransactionAllInputsSetAck => 188,
MessageType::MessageType_MoneroTransactionSetOutputRequest => 189,
MessageType::MessageType_MoneroTransactionSetOutputAck => 190,
MessageType::MessageType_MoneroTransactionAllOutSetRequest => 191,
MessageType::MessageType_MoneroTransactionAllOutSetAck => 192,
MessageType::MessageType_MoneroTransactionSignInputRequest => 193,
MessageType::MessageType_MoneroTransactionSignInputAck => 194,
MessageType::MessageType_MoneroTransactionFinalRequest => 195,
MessageType::MessageType_MoneroTransactionFinalAck => 196,
MessageType::MessageType_MoneroKeyImageExportInitRequest => 197,
MessageType::MessageType_MoneroKeyImageExportInitAck => 198,
MessageType::MessageType_MoneroKeyImageSyncStepRequest => 199,
MessageType::MessageType_MoneroKeyImageSyncStepAck => 200,
MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 201,
MessageType::MessageType_MoneroKeyImageSyncFinalAck => 202,
MessageType::MessageType_MoneroGetAddress => 203,
MessageType::MessageType_MoneroAddress => 204,
MessageType::MessageType_MoneroGetWatchKey => 205,
MessageType::MessageType_MoneroWatchKey => 206,
MessageType::MessageType_DebugMoneroDiagRequest => 207,
MessageType::MessageType_DebugMoneroDiagAck => 208,
MessageType::MessageType_MoneroGetTxKeyRequest => 209,
MessageType::MessageType_MoneroGetTxKeyAck => 210,
MessageType::MessageType_MoneroLiveRefreshStartRequest => 211,
MessageType::MessageType_MoneroLiveRefreshStartAck => 212,
MessageType::MessageType_MoneroLiveRefreshStepRequest => 213,
MessageType::MessageType_MoneroLiveRefreshStepAck => 214,
MessageType::MessageType_MoneroLiveRefreshFinalRequest => 215,
MessageType::MessageType_MoneroLiveRefreshFinalAck => 216,
MessageType::MessageType_EosGetPublicKey => 217,
MessageType::MessageType_EosPublicKey => 218,
MessageType::MessageType_EosSignTx => 219,
MessageType::MessageType_EosTxActionRequest => 220,
MessageType::MessageType_EosTxActionAck => 221,
MessageType::MessageType_EosSignedTx => 222,
MessageType::MessageType_BinanceGetAddress => 223,
MessageType::MessageType_BinanceAddress => 224,
MessageType::MessageType_BinanceGetPublicKey => 225,
MessageType::MessageType_BinancePublicKey => 226,
MessageType::MessageType_BinanceSignTx => 227,
MessageType::MessageType_BinanceTxRequest => 228,
MessageType::MessageType_BinanceTransferMsg => 229,
MessageType::MessageType_BinanceOrderMsg => 230,
MessageType::MessageType_BinanceCancelMsg => 231,
MessageType::MessageType_BinanceSignedTx => 232,
MessageType::MessageType_WebAuthnListResidentCredentials => 233,
MessageType::MessageType_WebAuthnCredentials => 234,
MessageType::MessageType_WebAuthnAddResidentCredential => 235,
MessageType::MessageType_WebAuthnRemoveResidentCredential => 236,
MessageType::MessageType_SolanaGetPublicKey => 237,
MessageType::MessageType_SolanaPublicKey => 238,
MessageType::MessageType_SolanaGetAddress => 239,
MessageType::MessageType_SolanaAddress => 240,
MessageType::MessageType_SolanaSignTx => 241,
MessageType::MessageType_SolanaTxSignature => 242,
MessageType::MessageType_CardanoSignMessageInit => 177,
MessageType::MessageType_CardanoMessagePayloadChunk => 178,
MessageType::MessageType_CardanoMessageItemAck => 179,
MessageType::MessageType_CardanoMessageItemHostAck => 180,
MessageType::MessageType_CardanoSignMessageFinished => 181,
MessageType::MessageType_RippleGetAddress => 182,
MessageType::MessageType_RippleAddress => 183,
MessageType::MessageType_RippleSignTx => 184,
MessageType::MessageType_RippleSignedTx => 185,
MessageType::MessageType_MoneroTransactionInitRequest => 186,
MessageType::MessageType_MoneroTransactionInitAck => 187,
MessageType::MessageType_MoneroTransactionSetInputRequest => 188,
MessageType::MessageType_MoneroTransactionSetInputAck => 189,
MessageType::MessageType_MoneroTransactionInputViniRequest => 190,
MessageType::MessageType_MoneroTransactionInputViniAck => 191,
MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 192,
MessageType::MessageType_MoneroTransactionAllInputsSetAck => 193,
MessageType::MessageType_MoneroTransactionSetOutputRequest => 194,
MessageType::MessageType_MoneroTransactionSetOutputAck => 195,
MessageType::MessageType_MoneroTransactionAllOutSetRequest => 196,
MessageType::MessageType_MoneroTransactionAllOutSetAck => 197,
MessageType::MessageType_MoneroTransactionSignInputRequest => 198,
MessageType::MessageType_MoneroTransactionSignInputAck => 199,
MessageType::MessageType_MoneroTransactionFinalRequest => 200,
MessageType::MessageType_MoneroTransactionFinalAck => 201,
MessageType::MessageType_MoneroKeyImageExportInitRequest => 202,
MessageType::MessageType_MoneroKeyImageExportInitAck => 203,
MessageType::MessageType_MoneroKeyImageSyncStepRequest => 204,
MessageType::MessageType_MoneroKeyImageSyncStepAck => 205,
MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 206,
MessageType::MessageType_MoneroKeyImageSyncFinalAck => 207,
MessageType::MessageType_MoneroGetAddress => 208,
MessageType::MessageType_MoneroAddress => 209,
MessageType::MessageType_MoneroGetWatchKey => 210,
MessageType::MessageType_MoneroWatchKey => 211,
MessageType::MessageType_DebugMoneroDiagRequest => 212,
MessageType::MessageType_DebugMoneroDiagAck => 213,
MessageType::MessageType_MoneroGetTxKeyRequest => 214,
MessageType::MessageType_MoneroGetTxKeyAck => 215,
MessageType::MessageType_MoneroLiveRefreshStartRequest => 216,
MessageType::MessageType_MoneroLiveRefreshStartAck => 217,
MessageType::MessageType_MoneroLiveRefreshStepRequest => 218,
MessageType::MessageType_MoneroLiveRefreshStepAck => 219,
MessageType::MessageType_MoneroLiveRefreshFinalRequest => 220,
MessageType::MessageType_MoneroLiveRefreshFinalAck => 221,
MessageType::MessageType_EosGetPublicKey => 222,
MessageType::MessageType_EosPublicKey => 223,
MessageType::MessageType_EosSignTx => 224,
MessageType::MessageType_EosTxActionRequest => 225,
MessageType::MessageType_EosTxActionAck => 226,
MessageType::MessageType_EosSignedTx => 227,
MessageType::MessageType_BinanceGetAddress => 228,
MessageType::MessageType_BinanceAddress => 229,
MessageType::MessageType_BinanceGetPublicKey => 230,
MessageType::MessageType_BinancePublicKey => 231,
MessageType::MessageType_BinanceSignTx => 232,
MessageType::MessageType_BinanceTxRequest => 233,
MessageType::MessageType_BinanceTransferMsg => 234,
MessageType::MessageType_BinanceOrderMsg => 235,
MessageType::MessageType_BinanceCancelMsg => 236,
MessageType::MessageType_BinanceSignedTx => 237,
MessageType::MessageType_WebAuthnListResidentCredentials => 238,
MessageType::MessageType_WebAuthnCredentials => 239,
MessageType::MessageType_WebAuthnAddResidentCredential => 240,
MessageType::MessageType_WebAuthnRemoveResidentCredential => 241,
MessageType::MessageType_SolanaGetPublicKey => 242,
MessageType::MessageType_SolanaPublicKey => 243,
MessageType::MessageType_SolanaGetAddress => 244,
MessageType::MessageType_SolanaAddress => 245,
MessageType::MessageType_SolanaSignTx => 246,
MessageType::MessageType_SolanaTxSignature => 247,
};
Self::enum_descriptor().value_by_index(index)
}
@ -1568,7 +1598,7 @@ pub mod exts {
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\x20google/protobuf/de\
scriptor.proto*\x9aT\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
scriptor.proto*\x8fV\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
\x10\0\x1a\x0c\x80\xa6\x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\
\x10MessageType_Ping\x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12\
%\n\x13MessageType_Success\x10\x02\x1a\x0c\x80\xa6\x1d\x01\xa8\xb5\x18\
@ -1769,104 +1799,109 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x10\xce\x02\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType_CardanoTxInlineD\
atumChunk\x10\xcf\x02\x1a\x04\x90\xb5\x18\x01\x124\n)MessageType_Cardano\
TxReferenceScriptChunk\x10\xd0\x02\x1a\x04\x90\xb5\x18\x01\x12.\n#Messag\
eType_CardanoTxReferenceInput\x10\xd1\x02\x1a\x04\x90\xb5\x18\x01\x12'\n\
\x1cMessageType_RippleGetAddress\x10\x90\x03\x1a\x04\x90\xb5\x18\x01\x12\
$\n\x19MessageType_RippleAddress\x10\x91\x03\x1a\x04\x98\xb5\x18\x01\x12\
#\n\x18MessageType_RippleSignTx\x10\x92\x03\x1a\x04\x90\xb5\x18\x01\x12%\
\n\x1aMessageType_RippleSignedTx\x10\x93\x03\x1a\x04\x90\xb5\x18\x01\x12\
3\n(MessageType_MoneroTransactionInitRequest\x10\xf5\x03\x1a\x04\x98\xb5\
\x18\x01\x12/\n$MessageType_MoneroTransactionInitAck\x10\xf6\x03\x1a\x04\
\x98\xb5\x18\x01\x127\n,MessageType_MoneroTransactionSetInputRequest\x10\
\xf7\x03\x1a\x04\x98\xb5\x18\x01\x123\n(MessageType_MoneroTransactionSet\
InputAck\x10\xf8\x03\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTr\
ansactionInputViniRequest\x10\xfb\x03\x1a\x04\x98\xb5\x18\x01\x124\n)Mes\
sageType_MoneroTransactionInputViniAck\x10\xfc\x03\x1a\x04\x98\xb5\x18\
\x01\x12;\n0MessageType_MoneroTransactionAllInputsSetRequest\x10\xfd\x03\
\x1a\x04\x98\xb5\x18\x01\x127\n,MessageType_MoneroTransactionAllInputsSe\
tAck\x10\xfe\x03\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransa\
ctionSetOutputRequest\x10\xff\x03\x1a\x04\x98\xb5\x18\x01\x124\n)Message\
Type_MoneroTransactionSetOutputAck\x10\x80\x04\x1a\x04\x98\xb5\x18\x01\
\x128\n-MessageType_MoneroTransactionAllOutSetRequest\x10\x81\x04\x1a\
\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTransactionAllOutSetAck\
\x10\x82\x04\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransactio\
nSignInputRequest\x10\x83\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType\
_MoneroTransactionSignInputAck\x10\x84\x04\x1a\x04\x98\xb5\x18\x01\x124\
\n)MessageType_MoneroTransactionFinalRequest\x10\x85\x04\x1a\x04\x98\xb5\
\x18\x01\x120\n%MessageType_MoneroTransactionFinalAck\x10\x86\x04\x1a\
\x04\x98\xb5\x18\x01\x126\n+MessageType_MoneroKeyImageExportInitRequest\
\x10\x92\x04\x1a\x04\x98\xb5\x18\x01\x122\n'MessageType_MoneroKeyImageEx\
portInitAck\x10\x93\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_Moner\
oKeyImageSyncStepRequest\x10\x94\x04\x1a\x04\x98\xb5\x18\x01\x120\n%Mess\
ageType_MoneroKeyImageSyncStepAck\x10\x95\x04\x1a\x04\x98\xb5\x18\x01\
\x125\n*MessageType_MoneroKeyImageSyncFinalRequest\x10\x96\x04\x1a\x04\
\x98\xb5\x18\x01\x121\n&MessageType_MoneroKeyImageSyncFinalAck\x10\x97\
\x04\x1a\x04\x98\xb5\x18\x01\x12'\n\x1cMessageType_MoneroGetAddress\x10\
\x9c\x04\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_MoneroAddress\x10\
\x9d\x04\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_MoneroGetWatchKey\
\x10\x9e\x04\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_MoneroWatchKe\
y\x10\x9f\x04\x1a\x04\x98\xb5\x18\x01\x12-\n\"MessageType_DebugMoneroDia\
gRequest\x10\xa2\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_Debug\
MoneroDiagAck\x10\xa3\x04\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_Mon\
eroGetTxKeyRequest\x10\xa6\x04\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessage\
Type_MoneroGetTxKeyAck\x10\xa7\x04\x1a\x04\x98\xb5\x18\x01\x124\n)Messag\
eType_MoneroLiveRefreshStartRequest\x10\xa8\x04\x1a\x04\x90\xb5\x18\x01\
\x120\n%MessageType_MoneroLiveRefreshStartAck\x10\xa9\x04\x1a\x04\x98\
\xb5\x18\x01\x123\n(MessageType_MoneroLiveRefreshStepRequest\x10\xaa\x04\
\x1a\x04\x90\xb5\x18\x01\x12/\n$MessageType_MoneroLiveRefreshStepAck\x10\
\xab\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroLiveRefreshFin\
alRequest\x10\xac\x04\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType_MoneroL\
iveRefreshFinalAck\x10\xad\x04\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessage\
Type_EosGetPublicKey\x10\xd8\x04\x1a\x04\x90\xb5\x18\x01\x12#\n\x18Messa\
geType_EosPublicKey\x10\xd9\x04\x1a\x04\x98\xb5\x18\x01\x12\x20\n\x15Mes\
sageType_EosSignTx\x10\xda\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessage\
Type_EosTxActionRequest\x10\xdb\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMe\
ssageType_EosTxActionAck\x10\xdc\x04\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17\
MessageType_EosSignedTx\x10\xdd\x04\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMe\
ssageType_BinanceGetAddress\x10\xbc\x05\x1a\x04\x90\xb5\x18\x01\x12%\n\
\x1aMessageType_BinanceAddress\x10\xbd\x05\x1a\x04\x98\xb5\x18\x01\x12*\
\n\x1fMessageType_BinanceGetPublicKey\x10\xbe\x05\x1a\x04\x90\xb5\x18\
\x01\x12'\n\x1cMessageType_BinancePublicKey\x10\xbf\x05\x1a\x04\x98\xb5\
\x18\x01\x12$\n\x19MessageType_BinanceSignTx\x10\xc0\x05\x1a\x04\x90\xb5\
\x18\x01\x12'\n\x1cMessageType_BinanceTxRequest\x10\xc1\x05\x1a\x04\x98\
\xb5\x18\x01\x12)\n\x1eMessageType_BinanceTransferMsg\x10\xc2\x05\x1a\
\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceOrderMsg\x10\xc3\x05\
\x1a\x04\x90\xb5\x18\x01\x12'\n\x1cMessageType_BinanceCancelMsg\x10\xc4\
\x05\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceSignedTx\x10\
\xc5\x05\x1a\x04\x98\xb5\x18\x01\x126\n+MessageType_WebAuthnListResident\
Credentials\x10\xa0\x06\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_We\
bAuthnCredentials\x10\xa1\x06\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType\
_WebAuthnAddResidentCredential\x10\xa2\x06\x1a\x04\x90\xb5\x18\x01\x127\
\n,MessageType_WebAuthnRemoveResidentCredential\x10\xa3\x06\x1a\x04\x90\
\xb5\x18\x01\x12)\n\x1eMessageType_SolanaGetPublicKey\x10\x84\x07\x1a\
\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_SolanaPublicKey\x10\x85\x07\
\x1a\x04\x98\xb5\x18\x01\x12'\n\x1cMessageType_SolanaGetAddress\x10\x86\
\x07\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_SolanaAddress\x10\x87\
\x07\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_SolanaSignTx\x10\x88\
\x07\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_SolanaTxSignature\x10\
\x89\x07\x1a\x04\x98\xb5\x18\x01\x1a\x04\xc8\xf3\x18\x01\"\x04\x08Z\x10\
\\\"\x04\x08r\x10z\"\x06\x08\xdb\x01\x10\xdb\x01\"\x06\x08\xe0\x01\x10\
\xe0\x01\"\x06\x08\xac\x02\x10\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\x02:<\n\
\x07wire_in\x18\xd2\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueO\
ptionsR\x06wireIn:>\n\x08wire_out\x18\xd3\x86\x03\x20\x01(\x08\x12!.goog\
le.protobuf.EnumValueOptionsR\x07wireOut:G\n\rwire_debug_in\x18\xd4\x86\
\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0bwireDebugIn:\
I\n\x0ewire_debug_out\x18\xd5\x86\x03\x20\x01(\x08\x12!.google.protobuf.\
EnumValueOptionsR\x0cwireDebugOut:@\n\twire_tiny\x18\xd6\x86\x03\x20\x01\
(\x08\x12!.google.protobuf.EnumValueOptionsR\x08wireTiny:L\n\x0fwire_boo\
tloader\x18\xd7\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptio\
nsR\x0ewireBootloader:C\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\x01(\x08\
\x12!.google.protobuf.EnumValueOptionsR\twireNoFsm:F\n\x0cbitcoin_only\
\x18\xe0\xd4\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0b\
bitcoinOnly:U\n\x17has_bitcoin_only_values\x18\xb9\x8e\x03\x20\x01(\x08\
\x12\x1c.google.protobuf.EnumOptionsR\x14hasBitcoinOnlyValues:T\n\x14exp\
erimental_message\x18\xa1\x96\x03\x20\x01(\x08\x12\x1f.google.protobuf.M\
essageOptionsR\x13experimentalMessage:>\n\twire_type\x18\xa2\x96\x03\x20\
\x01(\r\x12\x1f.google.protobuf.MessageOptionsR\x08wireType:N\n\x12exper\
imental_field\x18\x89\x9e\x03\x20\x01(\x08\x12\x1d.google.protobuf.Field\
OptionsR\x11experimentalField:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\
\x03\x20\x01(\x08\x12\x1c.google.protobuf.FileOptionsR\x14includeInBitco\
inOnlyB8\n#com.satoshilabs.trezor.lib.protobufB\rTrezorMessage\x80\xa6\
\x1d\x01\
eType_CardanoTxReferenceInput\x10\xd1\x02\x1a\x04\x90\xb5\x18\x01\x12-\n\
\"MessageType_CardanoSignMessageInit\x10\xd2\x02\x1a\x04\x90\xb5\x18\x01\
\x121\n&MessageType_CardanoMessagePayloadChunk\x10\xd3\x02\x1a\x04\x90\
\xb5\x18\x01\x12,\n!MessageType_CardanoMessageItemAck\x10\xd4\x02\x1a\
\x04\x98\xb5\x18\x01\x120\n%MessageType_CardanoMessageItemHostAck\x10\
\xd5\x02\x1a\x04\x90\xb5\x18\x01\x121\n&MessageType_CardanoSignMessageFi\
nished\x10\xd6\x02\x1a\x04\x98\xb5\x18\x01\x12'\n\x1cMessageType_RippleG\
etAddress\x10\x90\x03\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_Ripp\
leAddress\x10\x91\x03\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_Ripp\
leSignTx\x10\x92\x03\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_Rippl\
eSignedTx\x10\x93\x03\x1a\x04\x90\xb5\x18\x01\x123\n(MessageType_MoneroT\
ransactionInitRequest\x10\xf5\x03\x1a\x04\x98\xb5\x18\x01\x12/\n$Message\
Type_MoneroTransactionInitAck\x10\xf6\x03\x1a\x04\x98\xb5\x18\x01\x127\n\
,MessageType_MoneroTransactionSetInputRequest\x10\xf7\x03\x1a\x04\x98\
\xb5\x18\x01\x123\n(MessageType_MoneroTransactionSetInputAck\x10\xf8\x03\
\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransactionInputViniRe\
quest\x10\xfb\x03\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTrans\
actionInputViniAck\x10\xfc\x03\x1a\x04\x98\xb5\x18\x01\x12;\n0MessageTyp\
e_MoneroTransactionAllInputsSetRequest\x10\xfd\x03\x1a\x04\x98\xb5\x18\
\x01\x127\n,MessageType_MoneroTransactionAllInputsSetAck\x10\xfe\x03\x1a\
\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransactionSetOutputReques\
t\x10\xff\x03\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTransacti\
onSetOutputAck\x10\x80\x04\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_Mo\
neroTransactionAllOutSetRequest\x10\x81\x04\x1a\x04\x98\xb5\x18\x01\x124\
\n)MessageType_MoneroTransactionAllOutSetAck\x10\x82\x04\x1a\x04\x98\xb5\
\x18\x01\x128\n-MessageType_MoneroTransactionSignInputRequest\x10\x83\
\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTransactionSignInp\
utAck\x10\x84\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTrans\
actionFinalRequest\x10\x85\x04\x1a\x04\x98\xb5\x18\x01\x120\n%MessageTyp\
e_MoneroTransactionFinalAck\x10\x86\x04\x1a\x04\x98\xb5\x18\x01\x126\n+M\
essageType_MoneroKeyImageExportInitRequest\x10\x92\x04\x1a\x04\x98\xb5\
\x18\x01\x122\n'MessageType_MoneroKeyImageExportInitAck\x10\x93\x04\x1a\
\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroKeyImageSyncStepRequest\
\x10\x94\x04\x1a\x04\x98\xb5\x18\x01\x120\n%MessageType_MoneroKeyImageSy\
ncStepAck\x10\x95\x04\x1a\x04\x98\xb5\x18\x01\x125\n*MessageType_MoneroK\
eyImageSyncFinalRequest\x10\x96\x04\x1a\x04\x98\xb5\x18\x01\x121\n&Messa\
geType_MoneroKeyImageSyncFinalAck\x10\x97\x04\x1a\x04\x98\xb5\x18\x01\
\x12'\n\x1cMessageType_MoneroGetAddress\x10\x9c\x04\x1a\x04\x90\xb5\x18\
\x01\x12$\n\x19MessageType_MoneroAddress\x10\x9d\x04\x1a\x04\x98\xb5\x18\
\x01\x12(\n\x1dMessageType_MoneroGetWatchKey\x10\x9e\x04\x1a\x04\x90\xb5\
\x18\x01\x12%\n\x1aMessageType_MoneroWatchKey\x10\x9f\x04\x1a\x04\x98\
\xb5\x18\x01\x12-\n\"MessageType_DebugMoneroDiagRequest\x10\xa2\x04\x1a\
\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_DebugMoneroDiagAck\x10\xa3\
\x04\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_MoneroGetTxKeyRequest\
\x10\xa6\x04\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_MoneroGetTxKe\
yAck\x10\xa7\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroLiveRe\
freshStartRequest\x10\xa8\x04\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType\
_MoneroLiveRefreshStartAck\x10\xa9\x04\x1a\x04\x98\xb5\x18\x01\x123\n(Me\
ssageType_MoneroLiveRefreshStepRequest\x10\xaa\x04\x1a\x04\x90\xb5\x18\
\x01\x12/\n$MessageType_MoneroLiveRefreshStepAck\x10\xab\x04\x1a\x04\x98\
\xb5\x18\x01\x124\n)MessageType_MoneroLiveRefreshFinalRequest\x10\xac\
\x04\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType_MoneroLiveRefreshFinalAc\
k\x10\xad\x04\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_EosGetPublic\
Key\x10\xd8\x04\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_EosPublicK\
ey\x10\xd9\x04\x1a\x04\x98\xb5\x18\x01\x12\x20\n\x15MessageType_EosSignT\
x\x10\xda\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_EosTxActionR\
equest\x10\xdb\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_EosTxAc\
tionAck\x10\xdc\x04\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_EosSi\
gnedTx\x10\xdd\x04\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_Binance\
GetAddress\x10\xbc\x05\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_Bin\
anceAddress\x10\xbd\x05\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_Bi\
nanceGetPublicKey\x10\xbe\x05\x1a\x04\x90\xb5\x18\x01\x12'\n\x1cMessageT\
ype_BinancePublicKey\x10\xbf\x05\x1a\x04\x98\xb5\x18\x01\x12$\n\x19Messa\
geType_BinanceSignTx\x10\xc0\x05\x1a\x04\x90\xb5\x18\x01\x12'\n\x1cMessa\
geType_BinanceTxRequest\x10\xc1\x05\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMe\
ssageType_BinanceTransferMsg\x10\xc2\x05\x1a\x04\x90\xb5\x18\x01\x12&\n\
\x1bMessageType_BinanceOrderMsg\x10\xc3\x05\x1a\x04\x90\xb5\x18\x01\x12'\
\n\x1cMessageType_BinanceCancelMsg\x10\xc4\x05\x1a\x04\x90\xb5\x18\x01\
\x12&\n\x1bMessageType_BinanceSignedTx\x10\xc5\x05\x1a\x04\x98\xb5\x18\
\x01\x126\n+MessageType_WebAuthnListResidentCredentials\x10\xa0\x06\x1a\
\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_WebAuthnCredentials\x10\xa1\
\x06\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_WebAuthnAddResidentCrede\
ntial\x10\xa2\x06\x1a\x04\x90\xb5\x18\x01\x127\n,MessageType_WebAuthnRem\
oveResidentCredential\x10\xa3\x06\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMess\
ageType_SolanaGetPublicKey\x10\x84\x07\x1a\x04\x90\xb5\x18\x01\x12&\n\
\x1bMessageType_SolanaPublicKey\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x12'\
\n\x1cMessageType_SolanaGetAddress\x10\x86\x07\x1a\x04\x90\xb5\x18\x01\
\x12$\n\x19MessageType_SolanaAddress\x10\x87\x07\x1a\x04\x98\xb5\x18\x01\
\x12#\n\x18MessageType_SolanaSignTx\x10\x88\x07\x1a\x04\x90\xb5\x18\x01\
\x12(\n\x1dMessageType_SolanaTxSignature\x10\x89\x07\x1a\x04\x98\xb5\x18\
\x01\x1a\x04\xc8\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08r\x10z\"\x06\x08\
\xdb\x01\x10\xdb\x01\"\x06\x08\xe0\x01\x10\xe0\x01\"\x06\x08\xac\x02\x10\
\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\x02:<\n\x07wire_in\x18\xd2\x86\x03\
\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x06wireIn:>\n\x08wi\
re_out\x18\xd3\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOption\
sR\x07wireOut:G\n\rwire_debug_in\x18\xd4\x86\x03\x20\x01(\x08\x12!.googl\
e.protobuf.EnumValueOptionsR\x0bwireDebugIn:I\n\x0ewire_debug_out\x18\
\xd5\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0cwire\
DebugOut:@\n\twire_tiny\x18\xd6\x86\x03\x20\x01(\x08\x12!.google.protobu\
f.EnumValueOptionsR\x08wireTiny:L\n\x0fwire_bootloader\x18\xd7\x86\x03\
\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0ewireBootloader:C\
\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\x01(\x08\x12!.google.protobuf.Enum\
ValueOptionsR\twireNoFsm:F\n\x0cbitcoin_only\x18\xe0\xd4\x03\x20\x01(\
\x08\x12!.google.protobuf.EnumValueOptionsR\x0bbitcoinOnly:U\n\x17has_bi\
tcoin_only_values\x18\xb9\x8e\x03\x20\x01(\x08\x12\x1c.google.protobuf.E\
numOptionsR\x14hasBitcoinOnlyValues:T\n\x14experimental_message\x18\xa1\
\x96\x03\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\x13experim\
entalMessage:>\n\twire_type\x18\xa2\x96\x03\x20\x01(\r\x12\x1f.google.pr\
otobuf.MessageOptionsR\x08wireType:N\n\x12experimental_field\x18\x89\x9e\
\x03\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x11experimentalF\
ield:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\x03\x20\x01(\x08\x12\x1c\
.google.protobuf.FileOptionsR\x14includeInBitcoinOnlyB8\n#com.satoshilab\
s.trezor.lib.protobufB\rTrezorMessage\x80\xa6\x1d\x01\
";
/// `FileDescriptorProto` object which was a source for this generated file

File diff suppressed because it is too large Load Diff

@ -0,0 +1,54 @@
import pytest
from trezorlib import cardano, messages, tools
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
from ...common import parametrize_using_common_fixtures
pytestmark = [
pytest.mark.altcoin,
pytest.mark.cardano,
pytest.mark.skip_t1,
]
@parametrize_using_common_fixtures("cardano/sign_message.json")
def test_cardano_sign_message(client: Client, parameters, result):
response = call_sign_message(client, parameters)
assert response == _transform_expected_result(result)
@parametrize_using_common_fixtures("cardano/sign_message.failed.json")
def test_cardano_sign_message_failed(client: Client, parameters, result):
with pytest.raises(TrezorFailure, match=result["error_message"]):
call_sign_message(client, parameters)
def call_sign_message(
client: Client,
parameters,
) -> messages.CardanoSignMessageFinished:
client.init_device(new_session=True, derive_cardano=True)
with client:
return cardano.sign_message(
client,
payload=bytes.fromhex(parameters["payload"]),
hash_payload=parameters["hash_payload"],
prefer_hex_display=parameters["prefer_hex_display"],
signing_path=tools.parse_path(parameters["signing_path"]),
address_parameters=cardano.parse_optional_address_parameters(
parameters.get("address_parameters")
),
protocol_magic=parameters.get("protocol_magic"),
network_id=parameters.get("network_id"),
)
def _transform_expected_result(result: dict) -> messages.CardanoSignMessageFinished:
return messages.CardanoSignMessageFinished(
signature=bytes.fromhex(result["signature"]),
address=bytes.fromhex(result["address"]),
pub_key=bytes.fromhex(result["pub_key"]),
)

@ -11560,6 +11560,20 @@
"TR_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[nested_script_w-789238e6": "abcb8f2afc65255be5f3569075c5cec635020344cd98b08fe653bb4fc1ffef49",
"TR_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script]": "a4133c6716f2b34049a3303c0058dba3dc09c518746ef5b4a7ed88ecdb628693",
"TR_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script_-1579fe2a": "9facb40a3379b37d6611a35cc8412339a0f8a5f6c2343c9fd7feb353a6de8877",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[ambiguous_ascii_payload_falls_back_to_hex]": "f9bafd6c5d47fd49089d2bec5b627ca49a55c681000072affb8e95f05b747e90",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[non-ascii_payload_falls_back_to_hex]": "c2a48f71aaaca6811e4b750702ce6faf74368bed2ce78bafc26b2528ff424327",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload]": "e797a0dca23b418d67e46af15b991459b8db4acfd6f349c738f286a3d39d64fc",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload_hash]": "127af94ce9b44121eff6734686c2e04c1c15aa11091b327c542848fc65427378",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_long_ascii_payload_hash]": "dedd7f7e6368003cb0ef68d1acf17ec0a64a76bf341508c854dbe482ec8ab190",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload]": "b476a07b6aea3b8ab37888a8225ba97e59dd0d57ae502280adc557830980d0ce",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload_rendered_as_hex]": "fefccf595f6e67910b7ba2d8c230b4006d9db55c6e4e94061956fb3fc3d551f5",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload]": "d73e43e14b3c4f36033fceecbfb3d35571258a24473bb26020abb8789ac7cf81",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_hash]": "ceeefaed2b715021e44e9a4426b5faaa42fac44bcdfb2f19164ea42d4e5ceceb",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_with_a-1f337ea4": "7641fc23a9b6c8c99b2c7be228274f958dd20506be320158250b49f3515392a5",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[missing_network_id_and_proto-21ec11cf": "b70d9d2aa7a8ace3251763c1d2fcb53dd8c741b7520d717398df8f7ff8ac9128",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[payload_cannot_be_decoded_to_ascii]": "b70d9d2aa7a8ace3251763c1d2fcb53dd8c741b7520d717398df8f7ff8ac9128",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[payload_is_ambiguous_when_de-7bfc867f": "b70d9d2aa7a8ace3251763c1d2fcb53dd8c741b7520d717398df8f7ff8ac9128",
"TR_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[unhashed_payload_too_long]": "b70d9d2aa7a8ace3251763c1d2fcb53dd8c741b7520d717398df8f7ff8ac9128",
"TR_en_cardano-test_sign_tx.py::test_cardano_sign_tx[byron_to_shelley_transfer]": "283161b717285711364ee06a08f65a0d75683dbe5cf2b74417c733e7c605cf83",
"TR_en_cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_change0]": "70609e795063e20a23b96e4d5ce2f982f4a2697c0fb4d3917b6cd0b8fac3a0cf",
"TR_en_cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_change1]": "83ffbe43bda85acaff14fe20fbe34c368f0b2a215e6b70d85892310a2b9d17bf",
@ -18856,6 +18870,20 @@
"TT_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[nested_script_w-789238e6": "48a066f73096f96a685337d3942ada9493abe686f5bf70a2a224a999ba5dab3c",
"TT_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script]": "c3af0c697cfff8e404e6671e5f77f3b556386fbacd25eab158d866c21c6148f6",
"TT_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script_-1579fe2a": "9343101c53fe8b7360ecd5a102b3e507aabf29f37eeb253df3c88f6deecacb7b",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[ambiguous_ascii_payload_falls_back_to_hex]": "3276bc91a6e40e049850c145fede116178596bd95995a4f40491406f05fee01c",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[non-ascii_payload_falls_back_to_hex]": "7ec8d965018b05cb9c5d752c446dd85a45803f4c96c9feb2eea4ba40e8f30f78",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload]": "3064f9ee81498b8ec71bdc18670bcc57859f4091d2de9b00ef06ad557decdde5",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload_hash]": "e0d9af55c6be9a7d6cd47cb9be61837a6a46b78fc063a49eadf8a09422193981",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_long_ascii_payload_hash]": "190da6b7d6811b05b3c50377a43d9582915909356aaa2eb88a717294acf2406a",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload]": "a0df3f3d492e8e837159c28ef8209c7951249e11c1d00150520de8c6b43d1ad1",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload_rendered_as_hex]": "b6fb950a5d535f85814490fe3b2621cc75e94c586d9eb14ec15f644d8f7a0c77",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload]": "ca3fc51fc9c9343a9eb81c14140e8ed96e0a2191ad9f6e9dcbd1d7137c122f7a",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_hash]": "9daafddfef72b316ad74da8df298450cc29cc236bf9c3a5a3a881c940a4b466a",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_with_a-1f337ea4": "8e470a68ad081c270772ef329da832c1ac56578b510d1cacb7cc1b340e667ae6",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[missing_network_id_and_proto-21ec11cf": "3b6c5cf5c6512f1491b77f895d21d2f850f774c2b9d67c1b76eaeb2892e95e6b",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[payload_cannot_be_decoded_to_ascii]": "3b6c5cf5c6512f1491b77f895d21d2f850f774c2b9d67c1b76eaeb2892e95e6b",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[payload_is_ambiguous_when_de-7bfc867f": "3b6c5cf5c6512f1491b77f895d21d2f850f774c2b9d67c1b76eaeb2892e95e6b",
"TT_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[unhashed_payload_too_long]": "3b6c5cf5c6512f1491b77f895d21d2f850f774c2b9d67c1b76eaeb2892e95e6b",
"TT_en_cardano-test_sign_tx.py::test_cardano_sign_tx[byron_to_shelley_transfer]": "2e4d092a9e9348ee51e3527a9b81844e25bb4bca822ad2b817021d66b54357c6",
"TT_en_cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_change0]": "8b67edca40129904893563b0c85d2c86398a078cb740a3ca6e23d6489afc1813",
"TT_en_cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_change1]": "3e13929eb81c8077e946779e4ab3b1d3b5a461bf5a4cf3a886d6ac0a1d5297d4",

Loading…
Cancel
Save