What changed, and why it matters
This commit adds a new feature to Trezor hardware wallets: the ability to sign arbitrary Cardano messages. It introduces new protocol messages, device firmware code to handle signing, and client libraries to use the feature. The signing process requires user confirmation on the device screen and includes safety checks, such as limiting unhashed payload length and validating ASCII display options. There is no direct evidence in the commit of a security vulnerability, but any new signing feature carries inherent risks if not fully reviewed.
Treat this as a feature addition requiring normal security review. Focus review on: (1) correct binding between displayed payload and signed payload, (2) that user confirmation cannot be bypassed, (3) that the 32-byte guard and hash_payload logic prevent transaction-hash confusion attacks, and (4) that chunk validation prevents size mismatch or memory issues. No immediate patch or incident response is indicated by the commit itself.
Security signals we found
New signing surface added to Cardano app
User confirmation required before signing
Payload size and ASCII ambiguity validation present
32-byte signature structure ambiguity guard
No vendor disclosure of security relevance
No CVE or advisory referenced in commit
Evidence from the diff
The commit implements Cardano message signing (CIP-8 style COSE_Sign1) across Trezor firmware, Python client, Rust client, and tests. New protobuf messages include CardanoSignMessageInit, CardanoMessagePayloadChunk, CardanoMessageItemAck, CardanoMessageItemHostAck, and CardanoSignMessageFinished. The firmware validates signing paths, address parameters, payload size, and ASCII ambiguity before signing. It hashes payloads with BLAKE2b-28 and signs a CBOR ‘Signature1’ structure using Ed25519. A guard rejects signing structures exactly 32 bytes long to avoid ambiguity with transaction body hashes. The feature is gated by user confirmation on the device display.
Changed components
core/src/apps/cardano/sign_message.pycore/src/apps/cardano/helpers/chunks.pycore/src/apps/cardano/layout.pycore/src/apps/cardano/addresses.pycore/src/apps/cardano/helpers/utils.pycommon/protob/messages-cardano.protopython/src/trezorlib/cardano.pypython/src/trezorlib/cli/cardano.pyrust/trezor-clientInspect captured patch +2100 / −208
diff --git a/common/protob/messages-cardano.proto b/common/protob/messages-cardano.proto
index 0f93004c..e0011cd4 100644
--- a/common/protob/messages-cardano.proto
+++ b/common/protob/messages-cardano.proto
@@ -526,3 +526,48 @@ 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 display_ascii = 6; // decode payload as 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;
+ required bytes address = 2;
+}
diff --git a/common/protob/messages.proto b/common/protob/messages.proto
index ab81366b..17013f62 100644
--- a/common/protob/messages.proto
+++ b/common/protob/messages.proto
@@ -250,6 +250,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 00000000..dff5d7dd
--- /dev/null
+++ b/common/tests/fixtures/cardano/sign_message.failed.json
@@ -0,0 +1,67 @@
+{
+ "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,
+ "display_ascii": false
+ },
+ "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,
+ "display_ascii": false
+ },
+ "result": {
+ "error_message": "Payload too long to sign without hashing"
+ }
+ },
+ {
+ "description": "Payload cannot be decoded to ASCII",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "network_id": 1,
+ "protocol_magic": 764824073,
+ "payload": "ff",
+ "hash_payload": false,
+ "display_ascii": true
+ },
+ "result": {
+ "error_message": "Payload cannot be decoded as ASCII or its decoding leads to a visually ambiguous string"
+ }
+ },
+ {
+ "description": "Payload is ambiguous when decoded as ASCII",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "network_id": 1,
+ "protocol_magic": 764824073,
+ "payload": "20",
+ "hash_payload": false,
+ "display_ascii": true
+ },
+ "result": {
+ "error_message": "Payload cannot be decoded as ASCII or its decoding leads to a visually ambiguous string"
+ }
+ }
+ ]
+}
diff --git a/common/tests/fixtures/cardano/sign_message.json b/common/tests/fixtures/cardano/sign_message.json
new file mode 100644
index 00000000..d3b72a67
--- /dev/null
+++ b/common/tests/fixtures/cardano/sign_message.json
@@ -0,0 +1,119 @@
+{
+ "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,
+ "display_ascii": false
+ },
+ "result": {
+ "signature": "5ad6ba670e65353b2c1ad4053a1ed4a9348a73fe965ffa0afafa24bad06e3eb3e325d49029604c09bf665c3c43a750ec81a43b1f8b746b07e999b913b980d006",
+ "address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba"
+ }
+ },
+ {
+ "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"
+ },
+ "display_ascii": false
+ },
+ "result": {
+ "signature": "9efaff0b74c0beb2cadd727d8bafe13b31107235c5fc46c6c33e596e024d391c9fbe37072e43965add6ee0a4788562382031486b74fd59d636aa1ca3b1ddfe06",
+ "address": "0180f9e2c88e6c817008f3a812ed889b4a4da8e0bd103f86e7335422aa122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b4277"
+ }
+ },
+ {
+ "description": "Sign short non-ASCII payload hash",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "payload": "ff00",
+ "hash_payload": true,
+ "display_ascii": false
+ },
+ "result": {
+ "signature": "2c325e542fa78d76d916e50f50b85e770354a44e071f08fdb8ec5d0bcbf844cf70dcf5c87b7a51cd7f0269a59eec8d438c3c27eb42b971e7ccb7f864714c4b06",
+ "address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba"
+ }
+ },
+ {
+ "description": "Sign short ASCII payload",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "payload": "54657374",
+ "hash_payload": false,
+ "display_ascii": true
+ },
+ "result": {
+ "signature": "2201b8e7fa9ea919935e06ecc3e845433855066acaaf61cb8e624a2eb7139b73a9d126e7ee04548fff06ac933bd5419fc78c5aebee9b536cbee1481b52ec3e03",
+ "address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba"
+ }
+ },
+ {
+ "description": "Sign short ASCII payload rendered as hex",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "payload": "54657374",
+ "hash_payload": false,
+ "display_ascii": false
+ },
+ "result": {
+ "signature": "2201b8e7fa9ea919935e06ecc3e845433855066acaaf61cb8e624a2eb7139b73a9d126e7ee04548fff06ac933bd5419fc78c5aebee9b536cbee1481b52ec3e03",
+ "address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba"
+ }
+ },
+ {
+ "description": "Sign empty payload",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "payload": "",
+ "hash_payload": false,
+ "display_ascii": false
+ },
+ "result": {
+ "signature": "b09177a06cb2deba7ada89fec96fc4380e746f67c6b16a9ef9ae6b7cbbe941fdad8a8a573b809cd88db296b91b476c436033a29d86a63959e270047e47cd5d0d",
+ "address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba"
+ }
+ },
+ {
+ "description": "Sign empty payload hash",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "payload": "",
+ "hash_payload": true,
+ "display_ascii": false
+ },
+ "result": {
+ "signature": "a2503039a8ec620e05d9e4345339d61cd11480fbfcc75ea1a10789751a7c5f46ba06786eb1719da62db76c20313ad3445839b8117abac206cc4bd63ea623fc07",
+ "address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba"
+ }
+ },
+ {
+ "description": "Sign long ASCII payload hash",
+ "parameters": {
+ "signing_path": "m/1852'/1815'/4'/0/0",
+ "payload": "566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765566572794c6f6e674d657373616765",
+ "hash_payload": true,
+ "display_ascii": true
+ },
+ "result": {
+ "signature": "92331e75bb4c3208317ac422f2fc9d8b9b09d3f81cc487edaa7028d262553e5691532fb166a40e45eb2e4addd4280ff7e07bd4249e964d969e91555317b05f08",
+ "address": "d9553a4de9c7ad8532abdb1d0a7f425b8007d25c9f1edcf0b5f5c3ba"
+ }
+ }
+ ]
+}
diff --git a/core/.changelog.d/noissue.added b/core/.changelog.d/noissue.added
new file mode 100644
index 00000000..32c2f72d
--- /dev/null
+++ b/core/.changelog.d/noissue.added
@@ -0,0 +1 @@
+Cardano: Add support for signing arbitrary messages
diff --git a/core/embed/upymod/qstrdefsport.h b/core/embed/upymod/qstrdefsport.h
index 6e879e5c..9a94deef 100644
--- a/core/embed/upymod/qstrdefsport.h
+++ b/core/embed/upymod/qstrdefsport.h
@@ -485,6 +485,7 @@ Q(apps.cardano.get_public_key)
Q(apps.cardano.helpers)
Q(apps.cardano.helpers.account_path_check)
Q(apps.cardano.helpers.bech32)
+Q(apps.cardano.helpers.chunks)
Q(apps.cardano.helpers.credential)
Q(apps.cardano.helpers.hash_builder_collection)
Q(apps.cardano.helpers.network_ids)
@@ -494,6 +495,7 @@ Q(apps.cardano.helpers.utils)
Q(apps.cardano.layout)
Q(apps.cardano.native_script)
Q(apps.cardano.seed)
+Q(apps.cardano.sign_message)
Q(apps.cardano.sign_tx)
Q(apps.cardano.sign_tx.multisig_signer)
Q(apps.cardano.sign_tx.ordinary_signer)
@@ -652,6 +654,7 @@ Q(byron_addresses)
Q(cardano)
Q(certificates)
Q(chacha_poly)
+Q(chunks)
Q(clsag)
Q(common)
Q(constants)
diff --git a/core/src/apps/cardano/addresses.py b/core/src/apps/cardano/addresses.py
index 917172c4..af40b1ad 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 00000000..762cbdd9
--- /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 (size + MAX_CHUNK_SIZE - 1) // MAX_CHUNK_SIZE
+
+
+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 0cc1f8fd..8b7357c4 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 5aea73ea..632245fc 100644
--- a/core/src/apps/cardano/layout.py
+++ b/core/src/apps/cardano/layout.py
@@ -11,6 +11,7 @@ from trezor.enums import (
from trezor.strings import format_amount, format_amount_unit
from trezor.ui import layouts
from trezor.ui.layouts import confirm_metadata, confirm_properties
+from trezor.wire import ProcessError
from apps.common.paths import address_n_to_str
@@ -21,6 +22,7 @@ from .helpers.utils import (
format_asset_fingerprint,
format_optional_int,
format_stake_pool_id,
+ is_unambiguous_ascii,
)
if TYPE_CHECKING:
@@ -299,7 +301,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,
@@ -310,7 +312,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,
@@ -318,9 +320,52 @@ async def confirm_reference_script(
)
-async def _confirm_data_chunk(
- br_name: 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,
+ display_ascii: bool,
) -> None:
+ props: list[PropertyType]
+
+ 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 display_ascii:
+ if not is_unambiguous_ascii(payload_first_chunk):
+ raise ProcessError(
+ "Payload cannot be decoded as ASCII or its decoding leads to a visually ambiguous string"
+ )
+ props = _get_data_chunk_props(
+ title="Message text",
+ first_chunk=payload_first_chunk.decode("ascii"),
+ data_size=payload_size,
+ )
+ else:
+ props = _get_data_chunk_props(
+ title="Message hex",
+ first_chunk=payload_first_chunk,
+ data_size=payload_size,
+ )
+
+ props.append(("Message hash:", payload_hash))
+
+ await confirm_properties(
+ "confirm_message_payload",
+ title="Confirm message hash" if is_signing_hash else "Confirm message",
+ props=props,
+ br_code=BRT_Other,
+ )
+
+
+def _get_data_chunk_props(
+ title: str, first_chunk: bytes | str, data_size: int
+) -> list[PropertyType]:
MAX_DISPLAYED_SIZE = 56
displayed_bytes = first_chunk[:MAX_DISPLAYED_SIZE]
bytes_optional_plural = "byte" if data_size == 1 else "bytes"
@@ -333,10 +378,17 @@ async def _confirm_data_chunk(
]
if data_size > MAX_DISPLAYED_SIZE:
props.append(("...", None, None))
+
+ return props
+
+
+async def _confirm_tx_data_chunk(
+ br_name: str, title: str, first_chunk: bytes, data_size: int
+) -> None:
await confirm_properties(
br_name,
title=TR.cardano__confirm_transaction,
- props=props,
+ props=_get_data_chunk_props(title, first_chunk, data_size),
br_code=BRT_Other,
)
diff --git a/core/src/apps/cardano/seed.py b/core/src/apps/cardano/seed.py
index ac15baf2..4fc02ca6 100644
--- a/core/src/apps/cardano/seed.py
+++ b/core/src/apps/cardano/seed.py
@@ -32,6 +32,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 00000000..91c829b8
--- /dev/null
+++ b/core/src/apps/cardano/sign_message.py
@@ -0,0 +1,158 @@
+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.paths import SCHEMA_PUBKEY
+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)
+
+
+def _validate_message_signing_path(path: list[int]) -> None:
+ if not SCHEMA_PUBKEY.match(path):
+ raise ProcessError("Invalid signing path")
+
+
+def _validate_message_init(msg: CardanoSignMessageInit) -> 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")
+
+ _validate_message_signing_path(msg.signing_path)
+
+
+def _get_header_address(msg: CardanoSignMessageInit, keychain: seed.Keychain) -> bytes:
+ if msg.address_parameters:
+ assert (
+ msg.protocol_magic is not None and msg.network_id is not None
+ ) # _validate_message_init
+ 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, display_ascii: 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,
+ display_ascii=display_ascii,
+ )
+
+ 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
+
+ _validate_message_init(msg)
+
+ address = _get_header_address(msg, keychain)
+
+ headers: Headers = {
+ _COSE_HEADER_ALGORITHM_KEY: _COSE_EDDSA_ALGORITHM_ID,
+ _COSE_HEADER_ADDRESS_KEY: address,
+ }
+
+ payload = await _get_confirmed_payload(
+ size=msg.payload_size,
+ is_signing_hash=msg.hash_payload,
+ display_ascii=msg.display_ascii,
+ )
+
+ signature = _sign_sig_structure(
+ msg.signing_path,
+ keychain,
+ _cborize_sig_structure(payload=payload, protected_headers=headers),
+ )
+
+ return CardanoSignMessageFinished(signature=signature, address=address)
diff --git a/core/src/apps/cardano/sign_tx/signer.py b/core/src/apps/cardano/sign_tx/signer.py
index 1c1a62bc..6b20fb0a 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
@@ -71,8 +72,6 @@ _DATUM_OPTION_KEY_INLINE = const(1)
_POOL_REGISTRATION_CERTIFICATE_ITEMS_COUNT = const(10)
-_MAX_CHUNK_SIZE = const(1024)
-
class SuiteTxType(IntEnum):
"""
@@ -680,17 +679,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)
@@ -707,17 +700,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)
@@ -1246,22 +1233,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 bd1df493..eda64dda 100644
--- a/core/src/apps/workflow_handlers.py
+++ b/core/src/apps/workflow_handlers.py
@@ -188,6 +188,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 30489f27..ca812968 100644
--- a/core/src/trezor/enums/MessageType.py
+++ b/core/src/trezor/enums/MessageType.py
@@ -195,6 +195,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 01c9b7c9..25668e85 100644
--- a/core/src/trezor/enums/__init__.py
+++ b/core/src/trezor/enums/__init__.py
@@ -554,6 +554,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 61bd3959..211277b2 100644
--- a/core/src/trezor/messages.py
+++ b/core/src/trezor/messages.py
@@ -1784,6 +1784,76 @@ 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"
+ display_ascii: "bool"
+ address_parameters: "CardanoAddressParametersType | None"
+ derivation_type: "CardanoDerivationType"
+
+ def __init__(
+ self,
+ *,
+ payload_size: "int",
+ hash_payload: "bool",
+ display_ascii: "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"
+
+ def __init__(
+ self,
+ *,
+ signature: "bytes",
+ address: "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/noissue.added b/python/.changelog.d/noissue.added
new file mode 100644
index 00000000..32c2f72d
--- /dev/null
+++ b/python/.changelog.d/noissue.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 a46c04c9..77284eca 100644
--- a/python/src/trezorlib/cardano.py
+++ b/python/src/trezorlib/cardano.py
@@ -105,7 +105,11 @@ AuxiliaryDataSupplement = Dict[str, Union[int, bytes]]
SignTxResponse = Dict[str, Union[bytes, List[Witness], AuxiliaryDataSupplement]]
Chunk = TypeVar(
"Chunk",
- bound=Union[m.CardanoTxInlineDatumChunk, m.CardanoTxReferenceScriptChunk],
+ bound=Union[
+ m.CardanoTxInlineDatumChunk,
+ m.CardanoTxReferenceScriptChunk,
+ m.CardanoMessagePayloadChunk,
+ ],
)
@@ -324,6 +328,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]]:
@@ -998,3 +1018,47 @@ def sign_tx(
response = session.call(m.CardanoTxHostAck(), expect=m.CardanoSignTxFinished)
return sign_tx_response
+
+
+def sign_message(
+ client: "TrezorClient",
+ signing_path: Path,
+ payload: bytes,
+ hash_payload: bool,
+ display_ascii: 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,
+ display_ascii=display_ascii,
+ 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 04d67f51..2b7f7f85 100644
--- a/python/src/trezorlib/cli/cardano.py
+++ b/python/src/trezorlib/cli/cardano.py
@@ -15,7 +15,7 @@
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import json
-from typing import TYPE_CHECKING, Optional, TextIO
+from typing import TYPE_CHECKING, Any, Optional, TextIO
import click
@@ -323,3 +323,36 @@ def get_native_script_hash(
return cardano.get_native_script_hash(
session, 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"],
+ display_ascii=request["display_ascii"],
+ 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 a261ecff..734fa41d 100644
--- a/python/src/trezorlib/messages.py
+++ b/python/src/trezorlib/messages.py
@@ -607,6 +607,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
@@ -2898,6 +2903,80 @@ 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("display_ascii", "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",
+ display_ascii: "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.display_ascii = display_ascii
+ 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),
+ }
+
+ def __init__(
+ self,
+ *,
+ signature: "bytes",
+ address: "bytes",
+ ) -> None:
+ self.signature = signature
+ self.address = address
+
+
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 7da533d8..9e3cd9f2 100644
--- a/rust/trezor-client/src/messages/generated.rs
+++ b/rust/trezor-client/src/messages/generated.rs
@@ -148,6 +148,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 fe2d6546..c6da4b6d 100644
--- a/rust/trezor-client/src/protos/generated/messages.rs
+++ b/rust/trezor-client/src/protos/generated/messages.rs
@@ -393,6 +393,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)
@@ -721,6 +731,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),
@@ -977,6 +992,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),
@@ -1232,6 +1252,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,
@@ -1493,73 +1518,78 @@ impl ::protobuf::EnumFull for MessageType {
MessageType::MessageType_CardanoTxInlineDatumChunk => 180,
MessageType::MessageType_CardanoTxReferenceScriptChunk => 181,
MessageType::MessageType_CardanoTxReferenceInput => 182,
- MessageType::MessageType_RippleGetAddress => 183,
- MessageType::MessageType_RippleAddress => 184,
- MessageType::MessageType_RippleSignTx => 185,
- MessageType::MessageType_RippleSignedTx => 186,
- MessageType::MessageType_MoneroTransactionInitRequest => 187,
- MessageType::MessageType_MoneroTransactionInitAck => 188,
- MessageType::MessageType_MoneroTransactionSetInputRequest => 189,
- MessageType::MessageType_MoneroTransactionSetInputAck => 190,
- MessageType::MessageType_MoneroTransactionInputViniRequest => 191,
- MessageType::MessageType_MoneroTransactionInputViniAck => 192,
- MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 193,
- MessageType::MessageType_MoneroTransactionAllInputsSetAck => 194,
- MessageType::MessageType_MoneroTransactionSetOutputRequest => 195,
- MessageType::MessageType_MoneroTransactionSetOutputAck => 196,
- MessageType::MessageType_MoneroTransactionAllOutSetRequest => 197,
- MessageType::MessageType_MoneroTransactionAllOutSetAck => 198,
- MessageType::MessageType_MoneroTransactionSignInputRequest => 199,
- MessageType::MessageType_MoneroTransactionSignInputAck => 200,
- MessageType::MessageType_MoneroTransactionFinalRequest => 201,
- MessageType::MessageType_MoneroTransactionFinalAck => 202,
- MessageType::MessageType_MoneroKeyImageExportInitRequest => 203,
- MessageType::MessageType_MoneroKeyImageExportInitAck => 204,
- MessageType::MessageType_MoneroKeyImageSyncStepRequest => 205,
- MessageType::MessageType_MoneroKeyImageSyncStepAck => 206,
- MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 207,
- MessageType::MessageType_MoneroKeyImageSyncFinalAck => 208,
- MessageType::MessageType_MoneroGetAddress => 209,
- MessageType::MessageType_MoneroAddress => 210,
- MessageType::MessageType_MoneroGetWatchKey => 211,
- MessageType::MessageType_MoneroWatchKey => 212,
- MessageType::MessageType_DebugMoneroDiagRequest => 213,
- MessageType::MessageType_DebugMoneroDiagAck => 214,
- MessageType::MessageType_MoneroGetTxKeyRequest => 215,
- MessageType::MessageType_MoneroGetTxKeyAck => 216,
- MessageType::MessageType_MoneroLiveRefreshStartRequest => 217,
- MessageType::MessageType_MoneroLiveRefreshStartAck => 218,
- MessageType::MessageType_MoneroLiveRefreshStepRequest => 219,
- MessageType::MessageType_MoneroLiveRefreshStepAck => 220,
- MessageType::MessageType_MoneroLiveRefreshFinalRequest => 221,
- MessageType::MessageType_MoneroLiveRefreshFinalAck => 222,
- MessageType::MessageType_EosGetPublicKey => 223,
- MessageType::MessageType_EosPublicKey => 224,
- MessageType::MessageType_EosSignTx => 225,
- MessageType::MessageType_EosTxActionRequest => 226,
- MessageType::MessageType_EosTxActionAck => 227,
- MessageType::MessageType_EosSignedTx => 228,
- MessageType::MessageType_WebAuthnListResidentCredentials => 229,
- MessageType::MessageType_WebAuthnCredentials => 230,
- MessageType::MessageType_WebAuthnAddResidentCredential => 231,
- MessageType::MessageType_WebAuthnRemoveResidentCredential => 232,
- MessageType::MessageType_SolanaGetPublicKey => 233,
- MessageType::MessageType_SolanaPublicKey => 234,
- MessageType::MessageType_SolanaGetAddress => 235,
- MessageType::MessageType_SolanaAddress => 236,
- MessageType::MessageType_SolanaSignTx => 237,
- MessageType::MessageType_SolanaTxSignature => 238,
- MessageType::MessageType_ThpCreateNewSession => 239,
- MessageType::MessageType_ThpCredentialRequest => 240,
- MessageType::MessageType_ThpCredentialResponse => 241,
- MessageType::MessageType_NostrGetPubkey => 242,
- MessageType::MessageType_NostrPubkey => 243,
- MessageType::MessageType_NostrSignEvent => 244,
- MessageType::MessageType_NostrEventSignature => 245,
- MessageType::MessageType_BenchmarkListNames => 246,
- MessageType::MessageType_BenchmarkNames => 247,
- MessageType::MessageType_BenchmarkRun => 248,
- MessageType::MessageType_BenchmarkResult => 249,
+ MessageType::MessageType_CardanoSignMessageInit => 183,
+ MessageType::MessageType_CardanoMessagePayloadChunk => 184,
+ MessageType::MessageType_CardanoMessageItemAck => 185,
+ MessageType::MessageType_CardanoMessageItemHostAck => 186,
+ MessageType::MessageType_CardanoSignMessageFinished => 187,
+ MessageType::MessageType_RippleGetAddress => 188,
+ MessageType::MessageType_RippleAddress => 189,
+ MessageType::MessageType_RippleSignTx => 190,
+ MessageType::MessageType_RippleSignedTx => 191,
+ MessageType::MessageType_MoneroTransactionInitRequest => 192,
+ MessageType::MessageType_MoneroTransactionInitAck => 193,
+ MessageType::MessageType_MoneroTransactionSetInputRequest => 194,
+ MessageType::MessageType_MoneroTransactionSetInputAck => 195,
+ MessageType::MessageType_MoneroTransactionInputViniRequest => 196,
+ MessageType::MessageType_MoneroTransactionInputViniAck => 197,
+ MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 198,
+ MessageType::MessageType_MoneroTransactionAllInputsSetAck => 199,
+ MessageType::MessageType_MoneroTransactionSetOutputRequest => 200,
+ MessageType::MessageType_MoneroTransactionSetOutputAck => 201,
+ MessageType::MessageType_MoneroTransactionAllOutSetRequest => 202,
+ MessageType::MessageType_MoneroTransactionAllOutSetAck => 203,
+ MessageType::MessageType_MoneroTransactionSignInputRequest => 204,
+ MessageType::MessageType_MoneroTransactionSignInputAck => 205,
+ MessageType::MessageType_MoneroTransactionFinalRequest => 206,
+ MessageType::MessageType_MoneroTransactionFinalAck => 207,
+ MessageType::MessageType_MoneroKeyImageExportInitRequest => 208,
+ MessageType::MessageType_MoneroKeyImageExportInitAck => 209,
+ MessageType::MessageType_MoneroKeyImageSyncStepRequest => 210,
+ MessageType::MessageType_MoneroKeyImageSyncStepAck => 211,
+ MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 212,
+ MessageType::MessageType_MoneroKeyImageSyncFinalAck => 213,
+ MessageType::MessageType_MoneroGetAddress => 214,
+ MessageType::MessageType_MoneroAddress => 215,
+ MessageType::MessageType_MoneroGetWatchKey => 216,
+ MessageType::MessageType_MoneroWatchKey => 217,
+ MessageType::MessageType_DebugMoneroDiagRequest => 218,
+ MessageType::MessageType_DebugMoneroDiagAck => 219,
+ MessageType::MessageType_MoneroGetTxKeyRequest => 220,
+ MessageType::MessageType_MoneroGetTxKeyAck => 221,
+ MessageType::MessageType_MoneroLiveRefreshStartRequest => 222,
+ MessageType::MessageType_MoneroLiveRefreshStartAck => 223,
+ MessageType::MessageType_MoneroLiveRefreshStepRequest => 224,
+ MessageType::MessageType_MoneroLiveRefreshStepAck => 225,
+ MessageType::MessageType_MoneroLiveRefreshFinalRequest => 226,
+ MessageType::MessageType_MoneroLiveRefreshFinalAck => 227,
+ MessageType::MessageType_EosGetPublicKey => 228,
+ MessageType::MessageType_EosPublicKey => 229,
+ MessageType::MessageType_EosSignTx => 230,
+ MessageType::MessageType_EosTxActionRequest => 231,
+ MessageType::MessageType_EosTxActionAck => 232,
+ MessageType::MessageType_EosSignedTx => 233,
+ MessageType::MessageType_WebAuthnListResidentCredentials => 234,
+ MessageType::MessageType_WebAuthnCredentials => 235,
+ MessageType::MessageType_WebAuthnAddResidentCredential => 236,
+ MessageType::MessageType_WebAuthnRemoveResidentCredential => 237,
+ MessageType::MessageType_SolanaGetPublicKey => 238,
+ MessageType::MessageType_SolanaPublicKey => 239,
+ MessageType::MessageType_SolanaGetAddress => 240,
+ MessageType::MessageType_SolanaAddress => 241,
+ MessageType::MessageType_SolanaSignTx => 242,
+ MessageType::MessageType_SolanaTxSignature => 243,
+ MessageType::MessageType_ThpCreateNewSession => 244,
+ MessageType::MessageType_ThpCredentialRequest => 245,
+ MessageType::MessageType_ThpCredentialResponse => 246,
+ MessageType::MessageType_NostrGetPubkey => 247,
+ MessageType::MessageType_NostrPubkey => 248,
+ MessageType::MessageType_NostrSignEvent => 249,
+ MessageType::MessageType_NostrEventSignature => 250,
+ MessageType::MessageType_BenchmarkListNames => 251,
+ MessageType::MessageType_BenchmarkNames => 252,
+ MessageType::MessageType_BenchmarkRun => 253,
+ MessageType::MessageType_BenchmarkResult => 254,
};
Self::enum_descriptor().value_by_index(index)
}
@@ -1578,7 +1608,7 @@ impl MessageType {
}
static file_descriptor_proto_data: &'static [u8] = b"\
- \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\x90W\
+ \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\x85Y\
\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_S\
@@ -1788,87 +1818,92 @@ 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\x126\n+Messa\
- geType_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_WebAuthnAddResidentCredential\x10\xa2\
- \x06\x1a\x04\x90\xb5\x18\x01\x127\n,MessageType_WebAuthnRemoveResidentCr\
- edential\x10\xa3\x06\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_Solan\
- aGetPublicKey\x10\x84\x07\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_\
- SolanaPublicKey\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x12'\n\x1cMessageTyp\
- e_SolanaGetAddress\x10\x86\x07\x1a\x04\x90\xb5\x18\x01\x12$\n\x19Message\
- Type_SolanaAddress\x10\x87\x07\x1a\x04\x98\xb5\x18\x01\x12#\n\x18Message\
- Type_SolanaSignTx\x10\x88\x07\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageT\
- ype_SolanaTxSignature\x10\x89\x07\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMess\
- ageType_ThpCreateNewSession\x10\xe8\x07\x1a\x04\x80\xa6\x1d\x01\x12+\n\
- \x20MessageType_ThpCredentialRequest\x10\xf8\x07\x1a\x04\x80\xa6\x1d\x01\
- \x12,\n!MessageType_ThpCredentialResponse\x10\xf9\x07\x1a\x04\x80\xa6\
- \x1d\x01\x12%\n\x1aMessageType_NostrGetPubkey\x10\xd1\x0f\x1a\x04\x90\
- \xb5\x18\x01\x12\"\n\x17MessageType_NostrPubkey\x10\xd2\x0f\x1a\x04\x98\
- \xb5\x18\x01\x12%\n\x1aMessageType_NostrSignEvent\x10\xd3\x0f\x1a\x04\
- \x90\xb5\x18\x01\x12*\n\x1fMessageType_NostrEventSignature\x10\xd4\x0f\
- \x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_BenchmarkListNames\x10\
- \x8cG\x1a\x04\x80\xa6\x1d\x01\x12%\n\x1aMessageType_BenchmarkNames\x10\
- \x8dG\x1a\x04\x80\xa6\x1d\x01\x12#\n\x18MessageType_BenchmarkRun\x10\x8e\
- G\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1bMessageType_BenchmarkResult\x10\x8fG\
- \x1a\x04\x80\xa6\x1d\x01\x1a\x08\xc8\xf3\x18\x01\xd0\xf3\x18\x01\"\x04\
- \x08Z\x10\\\"\x04\x08G\x10J\"\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\"\x06\x08\xbc\x05\x10\xc5\x05\"\x06\x08\xe9\x07\
- \x10\xf7\x07\"\x06\x08\xfa\x07\x10\xcb\x08B8\n#com.satoshilabs.trezor.li\
- b.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\x126\n+MessageType_WebAuthnLi\
+ stResidentCredentials\x10\xa0\x06\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMess\
+ ageType_WebAuthnCredentials\x10\xa1\x06\x1a\x04\x98\xb5\x18\x01\x124\n)M\
+ essageType_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_SolanaTxSigna\
+ ture\x10\x89\x07\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_ThpCreate\
+ NewSession\x10\xe8\x07\x1a\x04\x80\xa6\x1d\x01\x12+\n\x20MessageType_Thp\
+ CredentialRequest\x10\xf8\x07\x1a\x04\x80\xa6\x1d\x01\x12,\n!MessageType\
+ _ThpCredentialResponse\x10\xf9\x07\x1a\x04\x80\xa6\x1d\x01\x12%\n\x1aMes\
+ sageType_NostrGetPubkey\x10\xd1\x0f\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17M\
+ essageType_NostrPubkey\x10\xd2\x0f\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMes\
+ sageType_NostrSignEvent\x10\xd3\x0f\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMe\
+ ssageType_NostrEventSignature\x10\xd4\x0f\x1a\x04\x98\xb5\x18\x01\x12)\n\
+ \x1eMessageType_BenchmarkListNames\x10\x8cG\x1a\x04\x80\xa6\x1d\x01\x12%\
+ \n\x1aMessageType_BenchmarkNames\x10\x8dG\x1a\x04\x80\xa6\x1d\x01\x12#\n\
+ \x18MessageType_BenchmarkRun\x10\x8eG\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1b\
+ MessageType_BenchmarkResult\x10\x8fG\x1a\x04\x80\xa6\x1d\x01\x1a\x08\xc8\
+ \xf3\x18\x01\xd0\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08G\x10J\"\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\"\x06\x08\xbc\x05\
+ \x10\xc5\x05\"\x06\x08\xe9\x07\x10\xf7\x07\"\x06\x08\xfa\x07\x10\xcb\x08\
+ B8\n#com.satoshilabs.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 a7b34c1a..64f2bd1a 100644
--- a/rust/trezor-client/src/protos/generated/messages_cardano.rs
+++ b/rust/trezor-client/src/protos/generated/messages_cardano.rs
@@ -9623,6 +9623,977 @@ impl ::protobuf::reflect::ProtobufValue for CardanoSignTxFinished {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
+// @@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<u32>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.network_id)
+ pub network_id: ::std::option::Option<u32>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.signing_path)
+ pub signing_path: ::std::vec::Vec<u32>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.payload_size)
+ pub payload_size: ::std::option::Option<u32>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.hash_payload)
+ pub hash_payload: ::std::option::Option<bool>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.display_ascii)
+ pub display_ascii: ::std::option::Option<bool>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.address_parameters)
+ pub address_parameters: ::protobuf::MessageField<CardanoAddressParametersType>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.derivation_type)
+ pub derivation_type: ::std::option::Option<::protobuf::EnumOrUnknown<CardanoDerivationType>>,
+ // 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 {
+ <CardanoSignMessageInit as ::protobuf::Message>::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 display_ascii = 6;
+
+ pub fn display_ascii(&self) -> bool {
+ self.display_ascii.unwrap_or(false)
+ }
+
+ pub fn clear_display_ascii(&mut self) {
+ self.display_ascii = ::std::option::Option::None;
+ }
+
+ pub fn has_display_ascii(&self) -> bool {
+ self.display_ascii.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_display_ascii(&mut self, v: bool) {
+ self.display_ascii = ::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::<_, _>(
+ "display_ascii",
+ |m: &CardanoSignMessageInit| { &m.display_ascii },
+ |m: &mut CardanoSignMessageInit| { &mut m.display_ascii },
+ ));
+ 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>(
+ "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.display_ascii.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.display_ascii = ::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.display_ascii {
+ 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.display_ascii {
+ 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.display_ascii = ::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,
+ display_ascii: ::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<Self>;
+}
+
+// @@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 {
+ <CardanoMessageItemAck as ::protobuf::Message>::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>(
+ "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<Self>;
+}
+
+// @@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<u8>>,
+ // 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 {
+ <CardanoMessagePayloadChunk as ::protobuf::Message>::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<u8>) {
+ 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<u8> {
+ 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<u8> {
+ 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>(
+ "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<Self>;
+}
+
+// @@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 {
+ <CardanoMessageItemHostAck as ::protobuf::Message>::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>(
+ "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<Self>;
+}
+
+// @@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<u8>>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageFinished.address)
+ pub address: ::std::option::Option<::std::vec::Vec<u8>>,
+ // 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 {
+ <CardanoSignMessageFinished as ::protobuf::Message>::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<u8>) {
+ 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<u8> {
+ 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<u8> {
+ 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<u8>) {
+ 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<u8> {
+ 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<u8> {
+ self.address.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
+ let mut fields = ::std::vec::Vec::with_capacity(2);
+ 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 },
+ ));
+ ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<CardanoSignMessageFinished>(
+ "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;
+ }
+ 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()?);
+ },
+ 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);
+ }
+ 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)?;
+ }
+ 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.special_fields.clear();
+ }
+
+ fn default_instance() -> &'static CardanoSignMessageFinished {
+ static instance: CardanoSignMessageFinished = CardanoSignMessageFinished {
+ signature: ::std::option::Option::None,
+ address: ::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<Self>;
+}
+
#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
// @@protoc_insertion_point(enum:hw.trezor.messages.cardano.CardanoDerivationType)
pub enum CardanoDerivationType {
@@ -10668,17 +11639,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x03\x20\x02(\x0cR\tsignature\x12\x1d\n\nchain_code\x18\x04\x20\x01(\x0c\
R\tchainCode\"\x12\n\x10CardanoTxHostAck\",\n\x11CardanoTxBodyHash\x12\
\x17\n\x07tx_hash\x18\x01\x20\x02(\x0cR\x06txHash\"\x17\n\x15CardanoSign\
- TxFinished*B\n\x15CardanoDerivationType\x12\n\n\x06LEDGER\x10\0\x12\n\n\
- \x06ICARUS\x10\x01\x12\x11\n\rICARUS_TREZOR\x10\x02*\xd2\x01\n\x12Cardan\
- oAddressType\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_SCRIP\
- T\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\rREWAR\
- D_SCRIPT\x10\x0f*o\n\x17CardanoNativeScriptType\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_HEREAF\
- TER\x10\x05*K\n$CardanoNativeScriptHashDisplayFormat\x12\x08\n\x04HIDE\
+ TxFinished\"\xb1\x03\n\x16CardanoSignMessageInit\x12%\n\x0eprotocol_magi\
+ c\x18\x01\x20\x01(\rR\rprotocolMagic\x12\x1d\n\nnetwork_id\x18\x02\x20\
+ \x01(\rR\tnetworkId\x12!\n\x0csigning_path\x18\x03\x20\x03(\rR\x0bsignin\
+ gPath\x12!\n\x0cpayload_size\x18\x04\x20\x02(\rR\x0bpayloadSize\x12!\n\
+ \x0chash_payload\x18\x05\x20\x02(\x08R\x0bhashPayload\x12#\n\rdisplay_as\
+ cii\x18\x06\x20\x02(\x08R\x0cdisplayAscii\x12g\n\x12address_parameters\
+ \x18\x07\x20\x01(\x0b28.hw.trezor.messages.cardano.CardanoAddressParamet\
+ ersTypeR\x11addressParameters\x12Z\n\x0fderivation_type\x18\x08\x20\x02(\
+ \x0e21.hw.trezor.messages.cardano.CardanoDerivationTypeR\x0ederivationTy\
+ pe\"\x17\n\x15CardanoMessageItemAck\"0\n\x1aCardanoMessagePayloadChunk\
+ \x12\x12\n\x04data\x18\x01\x20\x02(\x0cR\x04data\"\x1b\n\x19CardanoMessa\
+ geItemHostAck\"T\n\x1aCardanoSignMessageFinished\x12\x1c\n\tsignature\
+ \x18\x01\x20\x02(\x0cR\tsignature\x12\x18\n\x07address\x18\x02\x20\x02(\
+ \x0cR\x07address*B\n\x15CardanoDerivationType\x12\n\n\x06LEDGER\x10\0\
+ \x12\n\n\x06ICARUS\x10\x01\x12\x11\n\rICARUS_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_SCRIP\
+ T_SCRIPT\x10\x03\x12\x0b\n\x07POINTER\x10\x04\x12\x12\n\x0ePOINTER_SCRIP\
+ T\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\rR\
+ EWARD_SCRIPT\x10\x0f*o\n\x17CardanoNativeScriptType\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_HERE\
+ AFTER\x10\x05*K\n$CardanoNativeScriptHashDisplayFormat\x12\x08\n\x04HIDE\
\x10\0\x12\n\n\x06BECH32\x10\x01\x12\r\n\tPOLICY_ID\x10\x02*G\n\"Cardano\
TxOutputSerializationFormat\x12\x10\n\x0cARRAY_LEGACY\x10\0\x12\x0f\n\
\x0bMAP_BABBAGE\x10\x01*\xd2\x01\n\x16CardanoCertificateType\x12\x16\n\
@@ -10717,7 +11701,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
let mut deps = ::std::vec::Vec::with_capacity(2);
deps.push(super::messages_common::file_descriptor().clone());
deps.push(super::options::file_descriptor().clone());
- let mut messages = ::std::vec::Vec::with_capacity(37);
+ let mut messages = ::std::vec::Vec::with_capacity(42);
messages.push(CardanoBlockchainPointerType::generated_message_descriptor_data());
messages.push(CardanoNativeScript::generated_message_descriptor_data());
messages.push(CardanoGetNativeScriptHash::generated_message_descriptor_data());
@@ -10755,6 +11739,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(12);
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 00000000..e134396d
--- /dev/null
+++ b/tests/device_tests/cardano/test_sign_message.py
@@ -0,0 +1,53 @@
+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"],
+ display_ascii=parameters["display_ascii"],
+ 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"]),
+ )
Why this scored 28/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.