diff --git a/common/protob/messages-cardano.proto b/common/protob/messages-cardano.proto index b1331beee..e7fd52d78 100644 --- a/common/protob/messages-cardano.proto +++ b/common/protob/messages-cardano.proto @@ -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 +} diff --git a/common/protob/messages.proto b/common/protob/messages.proto index f0a5d0cf5..4a1289d2e 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -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]; diff --git a/common/tests/fixtures/cardano/sign_message.failed.json b/common/tests/fixtures/cardano/sign_message.failed.json new file mode 100644 index 000000000..b9c9dc677 --- /dev/null +++ b/common/tests/fixtures/cardano/sign_message.failed.json @@ -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" + } + } + ] +} diff --git a/common/tests/fixtures/cardano/sign_message.json b/common/tests/fixtures/cardano/sign_message.json new file mode 100644 index 000000000..dd8e92b73 --- /dev/null +++ b/common/tests/fixtures/cardano/sign_message.json @@ -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" + } + } + ] +} diff --git a/core/.changelog.d/3509.added b/core/.changelog.d/3509.added new file mode 100644 index 000000000..32c2f72d4 --- /dev/null +++ b/core/.changelog.d/3509.added @@ -0,0 +1 @@ +Cardano: Add support for signing arbitrary messages diff --git a/core/src/all_modules.py b/core/src/all_modules.py index 571e7cda5..deb602082 100644 --- a/core/src/all_modules.py +++ b/core/src/all_modules.py @@ -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 diff --git a/core/src/apps/cardano/addresses.py b/core/src/apps/cardano/addresses.py index 2bab21834..74d3870bc 100644 --- a/core/src/apps/cardano/addresses.py +++ b/core/src/apps/cardano/addresses.py @@ -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") diff --git a/core/src/apps/cardano/helpers/chunks.py b/core/src/apps/cardano/helpers/chunks.py new file mode 100644 index 000000000..bc5136012 --- /dev/null +++ b/core/src/apps/cardano/helpers/chunks.py @@ -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 diff --git a/core/src/apps/cardano/helpers/utils.py b/core/src/apps/cardano/helpers/utils.py index 0cc1f8fd0..8b7357c45 100644 --- a/core/src/apps/cardano/helpers/utils.py +++ b/core/src/apps/cardano/helpers/utils.py @@ -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 diff --git a/core/src/apps/cardano/layout.py b/core/src/apps/cardano/layout.py index 1651e0ee0..ba8a4eac4 100644 --- a/core/src/apps/cardano/layout.py +++ b/core/src/apps/cardano/layout.py @@ -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, ) diff --git a/core/src/apps/cardano/seed.py b/core/src/apps/cardano/seed.py index 4a7f7b267..2c1775848 100644 --- a/core/src/apps/cardano/seed.py +++ b/core/src/apps/cardano/seed.py @@ -24,6 +24,7 @@ if TYPE_CHECKING: | messages.CardanoGetPublicKey | messages.CardanoGetNativeScriptHash | messages.CardanoSignTxInit + | messages.CardanoSignMessageInit ) MsgIn = TypeVar("MsgIn", bound=CardanoMessages) diff --git a/core/src/apps/cardano/sign_message.py b/core/src/apps/cardano/sign_message.py new file mode 100644 index 000000000..edf01fb89 --- /dev/null +++ b/core/src/apps/cardano/sign_message.py @@ -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), + ) diff --git a/core/src/apps/cardano/sign_tx/signer.py b/core/src/apps/cardano/sign_tx/signer.py index 602bdc200..399d8d828 100644 --- a/core/src/apps/cardano/sign_tx/signer.py +++ b/core/src/apps/cardano/sign_tx/signer.py @@ -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: diff --git a/core/src/apps/workflow_handlers.py b/core/src/apps/workflow_handlers.py index d8d320098..4a38821aa 100644 --- a/core/src/apps/workflow_handlers.py +++ b/core/src/apps/workflow_handlers.py @@ -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: diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index 0023ef9f1..12a647c1d 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -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 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index 3335f1b27..e019c159d 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -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 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 1ca0b322e..14e98a79e 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -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" diff --git a/python/.changelog.d/3509.added b/python/.changelog.d/3509.added new file mode 100644 index 000000000..32c2f72d4 --- /dev/null +++ b/python/.changelog.d/3509.added @@ -0,0 +1 @@ +Cardano: Add support for signing arbitrary messages diff --git a/python/src/trezorlib/cardano.py b/python/src/trezorlib/cardano.py index 9e9869965..32b13b0d4 100644 --- a/python/src/trezorlib/cardano.py +++ b/python/src/trezorlib/cardano.py @@ -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 diff --git a/python/src/trezorlib/cli/cardano.py b/python/src/trezorlib/cli/cardano.py index 91e3a540a..780e9314c 100644 --- a/python/src/trezorlib/cli/cardano.py +++ b/python/src/trezorlib/cli/cardano.py @@ -15,7 +15,7 @@ # If not, see . 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, + ) diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index a8ae02096..69e22ce4c 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -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 = { diff --git a/rust/trezor-client/src/messages/generated.rs b/rust/trezor-client/src/messages/generated.rs index f0737a52a..a8d6afea6 100644 --- a/rust/trezor-client/src/messages/generated.rs +++ b/rust/trezor-client/src/messages/generated.rs @@ -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")] diff --git a/rust/trezor-client/src/protos/generated/messages.rs b/rust/trezor-client/src/protos/generated/messages.rs index ebd3224f2..9f0be2958 100644 --- a/rust/trezor-client/src/protos/generated/messages.rs +++ b/rust/trezor-client/src/protos/generated/messages.rs @@ -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 diff --git a/rust/trezor-client/src/protos/generated/messages_cardano.rs b/rust/trezor-client/src/protos/generated/messages_cardano.rs index da2d0c7e5..e3dd0f955 100644 --- a/rust/trezor-client/src/protos/generated/messages_cardano.rs +++ b/rust/trezor-client/src/protos/generated/messages_cardano.rs @@ -9193,6 +9193,1034 @@ impl ::protobuf::reflect::ProtobufValue for CardanoSignTxFinished { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +// @@protoc_insertion_point(message:hw.trezor.messages.cardano.CardanoSignMessageInit) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct CardanoSignMessageInit { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.protocol_magic) + pub protocol_magic: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.network_id) + pub network_id: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.signing_path) + pub signing_path: ::std::vec::Vec, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.payload_size) + pub payload_size: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.hash_payload) + pub hash_payload: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.prefer_hex_display) + pub prefer_hex_display: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.address_parameters) + pub address_parameters: ::protobuf::MessageField, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.derivation_type) + pub derivation_type: ::std::option::Option<::protobuf::EnumOrUnknown>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.cardano.CardanoSignMessageInit.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a CardanoSignMessageInit { + fn default() -> &'a CardanoSignMessageInit { + ::default_instance() + } +} + +impl CardanoSignMessageInit { + pub fn new() -> CardanoSignMessageInit { + ::std::default::Default::default() + } + + // optional uint32 protocol_magic = 1; + + pub fn protocol_magic(&self) -> u32 { + self.protocol_magic.unwrap_or(0) + } + + pub fn clear_protocol_magic(&mut self) { + self.protocol_magic = ::std::option::Option::None; + } + + pub fn has_protocol_magic(&self) -> bool { + self.protocol_magic.is_some() + } + + // Param is passed by value, moved + pub fn set_protocol_magic(&mut self, v: u32) { + self.protocol_magic = ::std::option::Option::Some(v); + } + + // optional uint32 network_id = 2; + + pub fn network_id(&self) -> u32 { + self.network_id.unwrap_or(0) + } + + pub fn clear_network_id(&mut self) { + self.network_id = ::std::option::Option::None; + } + + pub fn has_network_id(&self) -> bool { + self.network_id.is_some() + } + + // Param is passed by value, moved + pub fn set_network_id(&mut self, v: u32) { + self.network_id = ::std::option::Option::Some(v); + } + + // required uint32 payload_size = 4; + + pub fn payload_size(&self) -> u32 { + self.payload_size.unwrap_or(0) + } + + pub fn clear_payload_size(&mut self) { + self.payload_size = ::std::option::Option::None; + } + + pub fn has_payload_size(&self) -> bool { + self.payload_size.is_some() + } + + // Param is passed by value, moved + pub fn set_payload_size(&mut self, v: u32) { + self.payload_size = ::std::option::Option::Some(v); + } + + // required bool hash_payload = 5; + + pub fn hash_payload(&self) -> bool { + self.hash_payload.unwrap_or(false) + } + + pub fn clear_hash_payload(&mut self) { + self.hash_payload = ::std::option::Option::None; + } + + pub fn has_hash_payload(&self) -> bool { + self.hash_payload.is_some() + } + + // Param is passed by value, moved + pub fn set_hash_payload(&mut self, v: bool) { + self.hash_payload = ::std::option::Option::Some(v); + } + + // required bool prefer_hex_display = 6; + + pub fn prefer_hex_display(&self) -> bool { + self.prefer_hex_display.unwrap_or(false) + } + + pub fn clear_prefer_hex_display(&mut self) { + self.prefer_hex_display = ::std::option::Option::None; + } + + pub fn has_prefer_hex_display(&self) -> bool { + self.prefer_hex_display.is_some() + } + + // Param is passed by value, moved + pub fn set_prefer_hex_display(&mut self, v: bool) { + self.prefer_hex_display = ::std::option::Option::Some(v); + } + + // required .hw.trezor.messages.cardano.CardanoDerivationType derivation_type = 8; + + pub fn derivation_type(&self) -> CardanoDerivationType { + match self.derivation_type { + Some(e) => e.enum_value_or(CardanoDerivationType::LEDGER), + None => CardanoDerivationType::LEDGER, + } + } + + pub fn clear_derivation_type(&mut self) { + self.derivation_type = ::std::option::Option::None; + } + + pub fn has_derivation_type(&self) -> bool { + self.derivation_type.is_some() + } + + // Param is passed by value, moved + pub fn set_derivation_type(&mut self, v: CardanoDerivationType) { + self.derivation_type = ::std::option::Option::Some(::protobuf::EnumOrUnknown::new(v)); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(8); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "protocol_magic", + |m: &CardanoSignMessageInit| { &m.protocol_magic }, + |m: &mut CardanoSignMessageInit| { &mut m.protocol_magic }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "network_id", + |m: &CardanoSignMessageInit| { &m.network_id }, + |m: &mut CardanoSignMessageInit| { &mut m.network_id }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "signing_path", + |m: &CardanoSignMessageInit| { &m.signing_path }, + |m: &mut CardanoSignMessageInit| { &mut m.signing_path }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "payload_size", + |m: &CardanoSignMessageInit| { &m.payload_size }, + |m: &mut CardanoSignMessageInit| { &mut m.payload_size }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "hash_payload", + |m: &CardanoSignMessageInit| { &m.hash_payload }, + |m: &mut CardanoSignMessageInit| { &mut m.hash_payload }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "prefer_hex_display", + |m: &CardanoSignMessageInit| { &m.prefer_hex_display }, + |m: &mut CardanoSignMessageInit| { &mut m.prefer_hex_display }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, CardanoAddressParametersType>( + "address_parameters", + |m: &CardanoSignMessageInit| { &m.address_parameters }, + |m: &mut CardanoSignMessageInit| { &mut m.address_parameters }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "derivation_type", + |m: &CardanoSignMessageInit| { &m.derivation_type }, + |m: &mut CardanoSignMessageInit| { &mut m.derivation_type }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "CardanoSignMessageInit", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for CardanoSignMessageInit { + const NAME: &'static str = "CardanoSignMessageInit"; + + fn is_initialized(&self) -> bool { + if self.payload_size.is_none() { + return false; + } + if self.hash_payload.is_none() { + return false; + } + if self.prefer_hex_display.is_none() { + return false; + } + if self.derivation_type.is_none() { + return false; + } + for v in &self.address_parameters { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 8 => { + self.protocol_magic = ::std::option::Option::Some(is.read_uint32()?); + }, + 16 => { + self.network_id = ::std::option::Option::Some(is.read_uint32()?); + }, + 26 => { + is.read_repeated_packed_uint32_into(&mut self.signing_path)?; + }, + 24 => { + self.signing_path.push(is.read_uint32()?); + }, + 32 => { + self.payload_size = ::std::option::Option::Some(is.read_uint32()?); + }, + 40 => { + self.hash_payload = ::std::option::Option::Some(is.read_bool()?); + }, + 48 => { + self.prefer_hex_display = ::std::option::Option::Some(is.read_bool()?); + }, + 58 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.address_parameters)?; + }, + 64 => { + self.derivation_type = ::std::option::Option::Some(is.read_enum_or_unknown()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.protocol_magic { + my_size += ::protobuf::rt::uint32_size(1, v); + } + if let Some(v) = self.network_id { + my_size += ::protobuf::rt::uint32_size(2, v); + } + for value in &self.signing_path { + my_size += ::protobuf::rt::uint32_size(3, *value); + }; + if let Some(v) = self.payload_size { + my_size += ::protobuf::rt::uint32_size(4, v); + } + if let Some(v) = self.hash_payload { + my_size += 1 + 1; + } + if let Some(v) = self.prefer_hex_display { + my_size += 1 + 1; + } + if let Some(v) = self.address_parameters.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + if let Some(v) = self.derivation_type { + my_size += ::protobuf::rt::int32_size(8, v.value()); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.protocol_magic { + os.write_uint32(1, v)?; + } + if let Some(v) = self.network_id { + os.write_uint32(2, v)?; + } + for v in &self.signing_path { + os.write_uint32(3, *v)?; + }; + if let Some(v) = self.payload_size { + os.write_uint32(4, v)?; + } + if let Some(v) = self.hash_payload { + os.write_bool(5, v)?; + } + if let Some(v) = self.prefer_hex_display { + os.write_bool(6, v)?; + } + if let Some(v) = self.address_parameters.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(7, v, os)?; + } + if let Some(v) = self.derivation_type { + os.write_enum(8, ::protobuf::EnumOrUnknown::value(&v))?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> CardanoSignMessageInit { + CardanoSignMessageInit::new() + } + + fn clear(&mut self) { + self.protocol_magic = ::std::option::Option::None; + self.network_id = ::std::option::Option::None; + self.signing_path.clear(); + self.payload_size = ::std::option::Option::None; + self.hash_payload = ::std::option::Option::None; + self.prefer_hex_display = ::std::option::Option::None; + self.address_parameters.clear(); + self.derivation_type = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static CardanoSignMessageInit { + static instance: CardanoSignMessageInit = CardanoSignMessageInit { + protocol_magic: ::std::option::Option::None, + network_id: ::std::option::Option::None, + signing_path: ::std::vec::Vec::new(), + payload_size: ::std::option::Option::None, + hash_payload: ::std::option::Option::None, + prefer_hex_display: ::std::option::Option::None, + address_parameters: ::protobuf::MessageField::none(), + derivation_type: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for CardanoSignMessageInit { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("CardanoSignMessageInit").unwrap()).clone() + } +} + +impl ::std::fmt::Display for CardanoSignMessageInit { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CardanoSignMessageInit { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.cardano.CardanoMessageItemAck) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct CardanoMessageItemAck { + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.cardano.CardanoMessageItemAck.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a CardanoMessageItemAck { + fn default() -> &'a CardanoMessageItemAck { + ::default_instance() + } +} + +impl CardanoMessageItemAck { + pub fn new() -> CardanoMessageItemAck { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "CardanoMessageItemAck", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for CardanoMessageItemAck { + const NAME: &'static str = "CardanoMessageItemAck"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> CardanoMessageItemAck { + CardanoMessageItemAck::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static CardanoMessageItemAck { + static instance: CardanoMessageItemAck = CardanoMessageItemAck { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for CardanoMessageItemAck { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("CardanoMessageItemAck").unwrap()).clone() + } +} + +impl ::std::fmt::Display for CardanoMessageItemAck { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CardanoMessageItemAck { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.cardano.CardanoMessagePayloadChunk) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct CardanoMessagePayloadChunk { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoMessagePayloadChunk.data) + pub data: ::std::option::Option<::std::vec::Vec>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.cardano.CardanoMessagePayloadChunk.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a CardanoMessagePayloadChunk { + fn default() -> &'a CardanoMessagePayloadChunk { + ::default_instance() + } +} + +impl CardanoMessagePayloadChunk { + pub fn new() -> CardanoMessagePayloadChunk { + ::std::default::Default::default() + } + + // required bytes data = 1; + + pub fn data(&self) -> &[u8] { + match self.data.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_data(&mut self) { + self.data = ::std::option::Option::None; + } + + pub fn has_data(&self) -> bool { + self.data.is_some() + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::vec::Vec) { + self.data = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { + if self.data.is_none() { + self.data = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.data.as_mut().unwrap() + } + + // Take field + pub fn take_data(&mut self) -> ::std::vec::Vec { + self.data.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "data", + |m: &CardanoMessagePayloadChunk| { &m.data }, + |m: &mut CardanoMessagePayloadChunk| { &mut m.data }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "CardanoMessagePayloadChunk", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for CardanoMessagePayloadChunk { + const NAME: &'static str = "CardanoMessagePayloadChunk"; + + fn is_initialized(&self) -> bool { + if self.data.is_none() { + return false; + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.data = ::std::option::Option::Some(is.read_bytes()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.data.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.data.as_ref() { + os.write_bytes(1, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> CardanoMessagePayloadChunk { + CardanoMessagePayloadChunk::new() + } + + fn clear(&mut self) { + self.data = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static CardanoMessagePayloadChunk { + static instance: CardanoMessagePayloadChunk = CardanoMessagePayloadChunk { + data: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for CardanoMessagePayloadChunk { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("CardanoMessagePayloadChunk").unwrap()).clone() + } +} + +impl ::std::fmt::Display for CardanoMessagePayloadChunk { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CardanoMessagePayloadChunk { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.cardano.CardanoMessageItemHostAck) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct CardanoMessageItemHostAck { + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.cardano.CardanoMessageItemHostAck.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a CardanoMessageItemHostAck { + fn default() -> &'a CardanoMessageItemHostAck { + ::default_instance() + } +} + +impl CardanoMessageItemHostAck { + pub fn new() -> CardanoMessageItemHostAck { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "CardanoMessageItemHostAck", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for CardanoMessageItemHostAck { + const NAME: &'static str = "CardanoMessageItemHostAck"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> CardanoMessageItemHostAck { + CardanoMessageItemHostAck::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static CardanoMessageItemHostAck { + static instance: CardanoMessageItemHostAck = CardanoMessageItemHostAck { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for CardanoMessageItemHostAck { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("CardanoMessageItemHostAck").unwrap()).clone() + } +} + +impl ::std::fmt::Display for CardanoMessageItemHostAck { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CardanoMessageItemHostAck { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.cardano.CardanoSignMessageFinished) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct CardanoSignMessageFinished { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageFinished.signature) + pub signature: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageFinished.address) + pub address: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageFinished.pub_key) + pub pub_key: ::std::option::Option<::std::vec::Vec>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.cardano.CardanoSignMessageFinished.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a CardanoSignMessageFinished { + fn default() -> &'a CardanoSignMessageFinished { + ::default_instance() + } +} + +impl CardanoSignMessageFinished { + pub fn new() -> CardanoSignMessageFinished { + ::std::default::Default::default() + } + + // required bytes signature = 1; + + pub fn signature(&self) -> &[u8] { + match self.signature.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_signature(&mut self) { + self.signature = ::std::option::Option::None; + } + + pub fn has_signature(&self) -> bool { + self.signature.is_some() + } + + // Param is passed by value, moved + pub fn set_signature(&mut self, v: ::std::vec::Vec) { + self.signature = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signature(&mut self) -> &mut ::std::vec::Vec { + if self.signature.is_none() { + self.signature = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.signature.as_mut().unwrap() + } + + // Take field + pub fn take_signature(&mut self) -> ::std::vec::Vec { + self.signature.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required bytes address = 2; + + pub fn address(&self) -> &[u8] { + match self.address.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_address(&mut self) { + self.address = ::std::option::Option::None; + } + + pub fn has_address(&self) -> bool { + self.address.is_some() + } + + // Param is passed by value, moved + pub fn set_address(&mut self, v: ::std::vec::Vec) { + self.address = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_address(&mut self) -> &mut ::std::vec::Vec { + if self.address.is_none() { + self.address = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.address.as_mut().unwrap() + } + + // Take field + pub fn take_address(&mut self) -> ::std::vec::Vec { + self.address.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required bytes pub_key = 3; + + pub fn pub_key(&self) -> &[u8] { + match self.pub_key.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_pub_key(&mut self) { + self.pub_key = ::std::option::Option::None; + } + + pub fn has_pub_key(&self) -> bool { + self.pub_key.is_some() + } + + // Param is passed by value, moved + pub fn set_pub_key(&mut self, v: ::std::vec::Vec) { + self.pub_key = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_pub_key(&mut self) -> &mut ::std::vec::Vec { + if self.pub_key.is_none() { + self.pub_key = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.pub_key.as_mut().unwrap() + } + + // Take field + pub fn take_pub_key(&mut self) -> ::std::vec::Vec { + self.pub_key.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "signature", + |m: &CardanoSignMessageFinished| { &m.signature }, + |m: &mut CardanoSignMessageFinished| { &mut m.signature }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "address", + |m: &CardanoSignMessageFinished| { &m.address }, + |m: &mut CardanoSignMessageFinished| { &mut m.address }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "pub_key", + |m: &CardanoSignMessageFinished| { &m.pub_key }, + |m: &mut CardanoSignMessageFinished| { &mut m.pub_key }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "CardanoSignMessageFinished", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for CardanoSignMessageFinished { + const NAME: &'static str = "CardanoSignMessageFinished"; + + fn is_initialized(&self) -> bool { + if self.signature.is_none() { + return false; + } + if self.address.is_none() { + return false; + } + if self.pub_key.is_none() { + return false; + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.signature = ::std::option::Option::Some(is.read_bytes()?); + }, + 18 => { + self.address = ::std::option::Option::Some(is.read_bytes()?); + }, + 26 => { + self.pub_key = ::std::option::Option::Some(is.read_bytes()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.signature.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(v) = self.address.as_ref() { + my_size += ::protobuf::rt::bytes_size(2, &v); + } + if let Some(v) = self.pub_key.as_ref() { + my_size += ::protobuf::rt::bytes_size(3, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.signature.as_ref() { + os.write_bytes(1, v)?; + } + if let Some(v) = self.address.as_ref() { + os.write_bytes(2, v)?; + } + if let Some(v) = self.pub_key.as_ref() { + os.write_bytes(3, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> CardanoSignMessageFinished { + CardanoSignMessageFinished::new() + } + + fn clear(&mut self) { + self.signature = ::std::option::Option::None; + self.address = ::std::option::Option::None; + self.pub_key = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static CardanoSignMessageFinished { + static instance: CardanoSignMessageFinished = CardanoSignMessageFinished { + signature: ::std::option::Option::None, + address: ::std::option::Option::None, + pub_key: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for CardanoSignMessageFinished { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("CardanoSignMessageFinished").unwrap()).clone() + } +} + +impl ::std::fmt::Display for CardanoSignMessageFinished { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CardanoSignMessageFinished { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + #[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)] // @@protoc_insertion_point(enum:hw.trezor.messages.cardano.CardanoDerivationType) pub enum CardanoDerivationType { @@ -10134,33 +11162,47 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x0cR\x06pubKey\x12\x1c\n\tsignature\x18\x03\x20\x02(\x0cR\tsignature\ \x12\x1d\n\nchain_code\x18\x04\x20\x01(\x0cR\tchainCode\"\x12\n\x10Carda\ noTxHostAck\",\n\x11CardanoTxBodyHash\x12\x17\n\x07tx_hash\x18\x01\x20\ - \x02(\x0cR\x06txHash\"\x17\n\x15CardanoSignTxFinished*B\n\x15CardanoDeri\ - vationType\x12\n\n\x06LEDGER\x10\0\x12\n\n\x06ICARUS\x10\x01\x12\x11\n\r\ - ICARUS_TREZOR\x10\x02*\xd2\x01\n\x12CardanoAddressType\x12\x08\n\x04BASE\ - \x10\0\x12\x13\n\x0fBASE_SCRIPT_KEY\x10\x01\x12\x13\n\x0fBASE_KEY_SCRIPT\ - \x10\x02\x12\x16\n\x12BASE_SCRIPT_SCRIPT\x10\x03\x12\x0b\n\x07POINTER\ - \x10\x04\x12\x12\n\x0ePOINTER_SCRIPT\x10\x05\x12\x0e\n\nENTERPRISE\x10\ - \x06\x12\x15\n\x11ENTERPRISE_SCRIPT\x10\x07\x12\t\n\x05BYRON\x10\x08\x12\ - \n\n\x06REWARD\x10\x0e\x12\x11\n\rREWARD_SCRIPT\x10\x0f*o\n\x17CardanoNa\ - tiveScriptType\x12\x0b\n\x07PUB_KEY\x10\0\x12\x07\n\x03ALL\x10\x01\x12\ - \x07\n\x03ANY\x10\x02\x12\n\n\x06N_OF_K\x10\x03\x12\x12\n\x0eINVALID_BEF\ - ORE\x10\x04\x12\x15\n\x11INVALID_HEREAFTER\x10\x05*K\n$CardanoNativeScri\ - ptHashDisplayFormat\x12\x08\n\x04HIDE\x10\0\x12\n\n\x06BECH32\x10\x01\ - \x12\r\n\tPOLICY_ID\x10\x02*G\n\"CardanoTxOutputSerializationFormat\x12\ - \x10\n\x0cARRAY_LEGACY\x10\0\x12\x0f\n\x0bMAP_BABBAGE\x10\x01*}\n\x16Car\ - danoCertificateType\x12\x16\n\x12STAKE_REGISTRATION\x10\0\x12\x18\n\x14S\ - TAKE_DEREGISTRATION\x10\x01\x12\x14\n\x10STAKE_DELEGATION\x10\x02\x12\ - \x1b\n\x17STAKE_POOL_REGISTRATION\x10\x03*X\n\x14CardanoPoolRelayType\ - \x12\x12\n\x0eSINGLE_HOST_IP\x10\0\x12\x14\n\x10SINGLE_HOST_NAME\x10\x01\ - \x12\x16\n\x12MULTIPLE_HOST_NAME\x10\x02*R\n$CardanoTxAuxiliaryDataSuppl\ - ementType\x12\x08\n\x04NONE\x10\0\x12\x20\n\x1cCVOTE_REGISTRATION_SIGNAT\ - URE\x10\x01*6\n\x1eCardanoCVoteRegistrationFormat\x12\t\n\x05CIP15\x10\0\ - \x12\t\n\x05CIP36\x10\x01*\x82\x01\n\x14CardanoTxSigningMode\x12\x18\n\ - \x14ORDINARY_TRANSACTION\x10\0\x12\x1e\n\x1aPOOL_REGISTRATION_AS_OWNER\ - \x10\x01\x12\x18\n\x14MULTISIG_TRANSACTION\x10\x02\x12\x16\n\x12PLUTUS_T\ - RANSACTION\x10\x03*>\n\x14CardanoTxWitnessType\x12\x11\n\rBYRON_WITNESS\ - \x10\0\x12\x13\n\x0fSHELLEY_WITNESS\x10\x01B;\n#com.satoshilabs.trezor.l\ - ib.protobufB\x14TrezorMessageCardano\ + \x02(\x0cR\x06txHash\"\x17\n\x15CardanoSignTxFinished\"\xba\x03\n\x16Car\ + danoSignMessageInit\x12%\n\x0eprotocol_magic\x18\x01\x20\x01(\rR\rprotoc\ + olMagic\x12\x1d\n\nnetwork_id\x18\x02\x20\x01(\rR\tnetworkId\x12!\n\x0cs\ + igning_path\x18\x03\x20\x03(\rR\x0bsigningPath\x12!\n\x0cpayload_size\ + \x18\x04\x20\x02(\rR\x0bpayloadSize\x12!\n\x0chash_payload\x18\x05\x20\ + \x02(\x08R\x0bhashPayload\x12,\n\x12prefer_hex_display\x18\x06\x20\x02(\ + \x08R\x10preferHexDisplay\x12g\n\x12address_parameters\x18\x07\x20\x01(\ + \x0b28.hw.trezor.messages.cardano.CardanoAddressParametersTypeR\x11addre\ + ssParameters\x12Z\n\x0fderivation_type\x18\x08\x20\x02(\x0e21.hw.trezor.\ + messages.cardano.CardanoDerivationTypeR\x0ederivationType\"\x17\n\x15Car\ + danoMessageItemAck\"0\n\x1aCardanoMessagePayloadChunk\x12\x12\n\x04data\ + \x18\x01\x20\x02(\x0cR\x04data\"\x1b\n\x19CardanoMessageItemHostAck\"m\n\ + \x1aCardanoSignMessageFinished\x12\x1c\n\tsignature\x18\x01\x20\x02(\x0c\ + R\tsignature\x12\x18\n\x07address\x18\x02\x20\x02(\x0cR\x07address\x12\ + \x17\n\x07pub_key\x18\x03\x20\x02(\x0cR\x06pubKey*B\n\x15CardanoDerivati\ + onType\x12\n\n\x06LEDGER\x10\0\x12\n\n\x06ICARUS\x10\x01\x12\x11\n\rICAR\ + US_TREZOR\x10\x02*\xd2\x01\n\x12CardanoAddressType\x12\x08\n\x04BASE\x10\ + \0\x12\x13\n\x0fBASE_SCRIPT_KEY\x10\x01\x12\x13\n\x0fBASE_KEY_SCRIPT\x10\ + \x02\x12\x16\n\x12BASE_SCRIPT_SCRIPT\x10\x03\x12\x0b\n\x07POINTER\x10\ + \x04\x12\x12\n\x0ePOINTER_SCRIPT\x10\x05\x12\x0e\n\nENTERPRISE\x10\x06\ + \x12\x15\n\x11ENTERPRISE_SCRIPT\x10\x07\x12\t\n\x05BYRON\x10\x08\x12\n\n\ + \x06REWARD\x10\x0e\x12\x11\n\rREWARD_SCRIPT\x10\x0f*o\n\x17CardanoNative\ + ScriptType\x12\x0b\n\x07PUB_KEY\x10\0\x12\x07\n\x03ALL\x10\x01\x12\x07\n\ + \x03ANY\x10\x02\x12\n\n\x06N_OF_K\x10\x03\x12\x12\n\x0eINVALID_BEFORE\ + \x10\x04\x12\x15\n\x11INVALID_HEREAFTER\x10\x05*K\n$CardanoNativeScriptH\ + ashDisplayFormat\x12\x08\n\x04HIDE\x10\0\x12\n\n\x06BECH32\x10\x01\x12\r\ + \n\tPOLICY_ID\x10\x02*G\n\"CardanoTxOutputSerializationFormat\x12\x10\n\ + \x0cARRAY_LEGACY\x10\0\x12\x0f\n\x0bMAP_BABBAGE\x10\x01*}\n\x16CardanoCe\ + rtificateType\x12\x16\n\x12STAKE_REGISTRATION\x10\0\x12\x18\n\x14STAKE_D\ + EREGISTRATION\x10\x01\x12\x14\n\x10STAKE_DELEGATION\x10\x02\x12\x1b\n\ + \x17STAKE_POOL_REGISTRATION\x10\x03*X\n\x14CardanoPoolRelayType\x12\x12\ + \n\x0eSINGLE_HOST_IP\x10\0\x12\x14\n\x10SINGLE_HOST_NAME\x10\x01\x12\x16\ + \n\x12MULTIPLE_HOST_NAME\x10\x02*R\n$CardanoTxAuxiliaryDataSupplementTyp\ + e\x12\x08\n\x04NONE\x10\0\x12\x20\n\x1cCVOTE_REGISTRATION_SIGNATURE\x10\ + \x01*6\n\x1eCardanoCVoteRegistrationFormat\x12\t\n\x05CIP15\x10\0\x12\t\ + \n\x05CIP36\x10\x01*\x82\x01\n\x14CardanoTxSigningMode\x12\x18\n\x14ORDI\ + NARY_TRANSACTION\x10\0\x12\x1e\n\x1aPOOL_REGISTRATION_AS_OWNER\x10\x01\ + \x12\x18\n\x14MULTISIG_TRANSACTION\x10\x02\x12\x16\n\x12PLUTUS_TRANSACTI\ + ON\x10\x03*>\n\x14CardanoTxWitnessType\x12\x11\n\rBYRON_WITNESS\x10\0\ + \x12\x13\n\x0fSHELLEY_WITNESS\x10\x01B;\n#com.satoshilabs.trezor.lib.pro\ + tobufB\x14TrezorMessageCardano\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -10179,7 +11221,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(1); deps.push(super::messages_common::file_descriptor().clone()); - let mut messages = ::std::vec::Vec::with_capacity(36); + let mut messages = ::std::vec::Vec::with_capacity(41); messages.push(CardanoBlockchainPointerType::generated_message_descriptor_data()); messages.push(CardanoNativeScript::generated_message_descriptor_data()); messages.push(CardanoGetNativeScriptHash::generated_message_descriptor_data()); @@ -10216,6 +11258,11 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(CardanoTxHostAck::generated_message_descriptor_data()); messages.push(CardanoTxBodyHash::generated_message_descriptor_data()); messages.push(CardanoSignTxFinished::generated_message_descriptor_data()); + messages.push(CardanoSignMessageInit::generated_message_descriptor_data()); + messages.push(CardanoMessageItemAck::generated_message_descriptor_data()); + messages.push(CardanoMessagePayloadChunk::generated_message_descriptor_data()); + messages.push(CardanoMessageItemHostAck::generated_message_descriptor_data()); + messages.push(CardanoSignMessageFinished::generated_message_descriptor_data()); let mut enums = ::std::vec::Vec::with_capacity(11); enums.push(CardanoDerivationType::generated_enum_descriptor_data()); enums.push(CardanoAddressType::generated_enum_descriptor_data()); diff --git a/tests/device_tests/cardano/test_sign_message.py b/tests/device_tests/cardano/test_sign_message.py new file mode 100644 index 000000000..93898ade8 --- /dev/null +++ b/tests/device_tests/cardano/test_sign_message.py @@ -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"]), + ) diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 1cc6ba14f..f6d913b73 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -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",