1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-04 21:48:17 +00:00
This commit is contained in:
Peter Jaško 2024-12-03 11:17:29 +01:00 committed by GitHub
commit 09ddbeb8dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 2370 additions and 254 deletions

View File

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

View File

@ -240,6 +240,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];

View File

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

View File

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

View File

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

View File

@ -859,6 +859,7 @@ static void _librust_qstrs(void) {
MP_QSTR_cardano__collateral_output_contains_tokens;
MP_QSTR_cardano__collateral_return;
MP_QSTR_cardano__confirm;
MP_QSTR_cardano__confirm_message;
MP_QSTR_cardano__confirm_signing_stake_pool;
MP_QSTR_cardano__confirm_transaction;
MP_QSTR_cardano__confirming_a_multisig_transaction;
@ -872,6 +873,7 @@ static void _librust_qstrs(void) {
MP_QSTR_cardano__delegating_to_key_hash;
MP_QSTR_cardano__delegating_to_script;
MP_QSTR_cardano__deposit;
MP_QSTR_cardano__empty_message;
MP_QSTR_cardano__for_account_and_index_template;
MP_QSTR_cardano__for_account_template;
MP_QSTR_cardano__for_key_hash;
@ -884,6 +886,9 @@ static void _librust_qstrs(void) {
MP_QSTR_cardano__intro_text_registration_payment;
MP_QSTR_cardano__key_hash;
MP_QSTR_cardano__margin;
MP_QSTR_cardano__message_hash;
MP_QSTR_cardano__message_hex;
MP_QSTR_cardano__message_text;
MP_QSTR_cardano__multisig_path;
MP_QSTR_cardano__nested_scripts_template;
MP_QSTR_cardano__network;
@ -918,6 +923,8 @@ static void _librust_qstrs(void) {
MP_QSTR_cardano__script_reward;
MP_QSTR_cardano__sending;
MP_QSTR_cardano__show_simple;
MP_QSTR_cardano__sign_message_hash_path_template;
MP_QSTR_cardano__sign_message_path_template;
MP_QSTR_cardano__sign_tx_path_template;
MP_QSTR_cardano__stake_delegation;
MP_QSTR_cardano__stake_deregistration;

View File

@ -1382,6 +1382,20 @@ pub enum TranslatedString {
misc__enable_labeling = 973, // "Enable labeling?"
#[cfg(feature = "universal_fw")]
ethereum__unknown_contract_address_short = 974, // "Unknown contract address."
#[cfg(feature = "universal_fw")]
cardano__confirm_message = 975, // "Confirm message"
#[cfg(feature = "universal_fw")]
cardano__empty_message = 976, // "Empty message"
#[cfg(feature = "universal_fw")]
cardano__message_hash = 977, // "Message hash:"
#[cfg(feature = "universal_fw")]
cardano__message_hex = 978, // "Message hex"
#[cfg(feature = "universal_fw")]
cardano__message_text = 979, // "Message text"
#[cfg(feature = "universal_fw")]
cardano__sign_message_hash_path_template = 980, // "Sign message hash with {0}:"
#[cfg(feature = "universal_fw")]
cardano__sign_message_path_template = 981, // "Sign message with {0}:"
}
impl TranslatedString {
@ -2758,6 +2772,20 @@ impl TranslatedString {
Self::misc__enable_labeling => "Enable labeling?",
#[cfg(feature = "universal_fw")]
Self::ethereum__unknown_contract_address_short => "Unknown contract address.",
#[cfg(feature = "universal_fw")]
Self::cardano__confirm_message => "Confirm message",
#[cfg(feature = "universal_fw")]
Self::cardano__empty_message => "Empty message",
#[cfg(feature = "universal_fw")]
Self::cardano__message_hash => "Message hash:",
#[cfg(feature = "universal_fw")]
Self::cardano__message_hex => "Message hex",
#[cfg(feature = "universal_fw")]
Self::cardano__message_text => "Message text",
#[cfg(feature = "universal_fw")]
Self::cardano__sign_message_hash_path_template => "Sign message hash with {0}:",
#[cfg(feature = "universal_fw")]
Self::cardano__sign_message_path_template => "Sign message with {0}:",
}
}
@ -4135,6 +4163,20 @@ impl TranslatedString {
Qstr::MP_QSTR_misc__enable_labeling => Some(Self::misc__enable_labeling),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_ethereum__unknown_contract_address_short => Some(Self::ethereum__unknown_contract_address_short),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_cardano__confirm_message => Some(Self::cardano__confirm_message),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_cardano__empty_message => Some(Self::cardano__empty_message),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_cardano__message_hash => Some(Self::cardano__message_hash),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_cardano__message_hex => Some(Self::cardano__message_hex),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_cardano__message_text => Some(Self::cardano__message_text),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_cardano__sign_message_hash_path_template => Some(Self::cardano__sign_message_hash_path_template),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_cardano__sign_message_path_template => Some(Self::cardano__sign_message_path_template),
_ => None,
}
}

View File

@ -146,6 +146,7 @@ class TR:
cardano__collateral_input_index: str = "Collateral input index:"
cardano__collateral_output_contains_tokens: str = "The collateral return output contains tokens."
cardano__collateral_return: str = "Collateral return"
cardano__confirm_message: str = "Confirm message"
cardano__confirm_signing_stake_pool: str = "Confirm signing the stake pool registration as an owner."
cardano__confirm_transaction: str = "Confirm transaction"
cardano__confirming_a_multisig_transaction: str = "Confirming a multisig transaction."
@ -159,6 +160,7 @@ class TR:
cardano__delegating_to_key_hash: str = "Delegating to key hash:"
cardano__delegating_to_script: str = "Delegating to script:"
cardano__deposit: str = "Deposit:"
cardano__empty_message: str = "Empty message"
cardano__for_account_and_index_template: str = "for account {0} and index {1}:"
cardano__for_account_template: str = "for account {0}:"
cardano__for_key_hash: str = "for key hash:"
@ -171,6 +173,9 @@ class TR:
cardano__intro_text_registration_payment: str = "The vote key registration payment address is owned by this device. Its"
cardano__key_hash: str = "key hash"
cardano__margin: str = "Margin"
cardano__message_hash: str = "Message hash:"
cardano__message_hex: str = "Message hex"
cardano__message_text: str = "Message text"
cardano__multisig_path: str = "multi-sig path"
cardano__nested_scripts_template: str = "Contains {0} nested scripts."
cardano__network: str = "Network:"
@ -205,6 +210,8 @@ class TR:
cardano__script_reward: str = "script reward"
cardano__sending: str = "Sending"
cardano__show_simple: str = "Show Simple"
cardano__sign_message_hash_path_template: str = "Sign message hash with {0}:"
cardano__sign_message_path_template: str = "Sign message with {0}:"
cardano__sign_tx_path_template: str = "Sign transaction with {0}:"
cardano__stake_delegation: str = "Stake delegation"
cardano__stake_deregistration: str = "Stake key deregistration"

View File

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

View File

@ -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")

View File

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

View File

@ -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

View File

@ -12,6 +12,7 @@ from trezor.strings import format_amount
from trezor.ui import layouts
from trezor.ui.layouts import confirm_metadata, confirm_properties
from apps.cardano.helpers.chunks import MAX_CHUNK_SIZE
from apps.common.paths import address_n_to_str
from . import addresses
@ -21,10 +22,11 @@ from .helpers.utils import (
format_asset_fingerprint,
format_optional_int,
format_stake_pool_id,
is_unambiguous_ascii,
)
if TYPE_CHECKING:
from typing import Literal
from typing import Callable, Literal
from trezor import messages
from trezor.enums import CardanoNativeScriptHashDisplayFormat
@ -71,6 +73,8 @@ BRT_Other = ButtonRequestType.Other # global_import_cache
CVOTE_REWARD_ELIGIBILITY_WARNING = TR.cardano__reward_eligibility_warning
_DEFAULT_MAX_DISPLAYED_CHUNK_SIZE = 56
def format_coin_amount(amount: int, network_id: int) -> str:
from .helpers import network_ids
@ -281,7 +285,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,
@ -292,7 +296,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,
@ -300,24 +304,80 @@ 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,
prefer_hex_display: bool,
) -> None:
MAX_DISPLAYED_SIZE = 56
displayed_bytes = first_chunk[:MAX_DISPLAYED_SIZE]
props: list[PropertyType]
max_displayed_bytes = (
_DEFAULT_MAX_DISPLAYED_CHUNK_SIZE if is_signing_hash else MAX_CHUNK_SIZE
)
if not payload_first_chunk:
assert payload_size == 0
props = _get_data_chunk_props(
title=TR.cardano__empty_message,
first_chunk=payload_first_chunk,
data_size=payload_size,
)
elif not prefer_hex_display and is_unambiguous_ascii(payload_first_chunk):
props = _get_data_chunk_props(
title=TR.cardano__message_text,
first_chunk=payload_first_chunk,
data_size=payload_size,
max_displayed_size=max_displayed_bytes,
decoder=lambda chunk: chunk.decode("ascii"),
)
else:
props = _get_data_chunk_props(
title=TR.cardano__message_hex,
first_chunk=payload_first_chunk,
data_size=payload_size,
max_displayed_size=max_displayed_bytes,
)
props.append((TR.cardano__message_hash, payload_hash))
await confirm_properties(
"confirm_message_payload",
title=TR.cardano__confirm_message,
props=props,
br_code=BRT_Other,
)
def _get_data_chunk_props(
title: str,
first_chunk: bytes,
data_size: int,
max_displayed_size: int = _DEFAULT_MAX_DISPLAYED_CHUNK_SIZE,
decoder: Callable[[bytes], bytes | str] | None = None,
) -> list[PropertyType]:
displayed_bytes = first_chunk[:max_displayed_size]
bytes_optional_plural = "byte" if data_size == 1 else "bytes"
props: list[tuple[str, bytes | None]] = [
props: list[PropertyType] = [
(
f"{title} ({data_size} {bytes_optional_plural}):",
displayed_bytes,
decoder(displayed_bytes) if decoder else displayed_bytes,
)
]
if data_size > MAX_DISPLAYED_SIZE:
if data_size > max_displayed_size:
props.append(("...", None))
return props
async def _confirm_tx_data_chunk(
br_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,
)
@ -331,6 +391,12 @@ async def show_credentials(
await _show_credential(stake_credential, intro_text, purpose="address")
async def show_message_header_credentials(credentials: list[Credential]) -> None:
intro_text = TR.words__address
for credential in credentials:
await _show_credential(credential, intro_text, purpose="message")
async def show_change_output_credentials(
payment_credential: Credential,
stake_credential: Credential,
@ -375,13 +441,14 @@ async def show_cvote_registration_payment_credentials(
async def _show_credential(
credential: Credential,
intro_text: str,
purpose: Literal["address", "output", "cvote_reg_payment_address"],
purpose: Literal["address", "output", "cvote_reg_payment_address", "message"],
extra_text: str | None = None,
) -> None:
title = {
"address": f"{ADDRESS_TYPE_NAMES[credential.address_type]} address",
"output": TR.cardano__confirm_transaction,
"cvote_reg_payment_address": TR.cardano__confirm_transaction,
"message": TR.cardano__confirm_message,
}[purpose]
props: list[PropertyType] = []
@ -491,23 +558,41 @@ async def warn_unknown_total_collateral() -> None:
)
def _get_path_title(path: list[int]) -> str:
from . import seed
if seed.is_multisig_path(path):
return TR.cardano__multisig_path
elif seed.is_minting_path(path):
return TR.cardano__token_minting_path
else:
return TR.cardano__path
async def confirm_witness_request(
witness_path: list[int],
) -> None:
from . import seed
if seed.is_multisig_path(witness_path):
path_title = TR.cardano__multisig_path
elif seed.is_minting_path(witness_path):
path_title = TR.cardano__token_minting_path
else:
path_title = TR.cardano__path
await layouts.confirm_text(
"confirm_total",
TR.cardano__confirm_transaction,
address_n_to_str(witness_path),
TR.cardano__sign_tx_path_template.format(path_title),
TR.cardano__sign_tx_path_template.format(_get_path_title(witness_path)),
BRT_Other,
)
async def confirm_message_path(path: list[int], is_signing_hash: bool) -> None:
path_title = _get_path_title(path)
text = (
TR.cardano__sign_message_hash_path_template.format(path_title)
if is_signing_hash
else TR.cardano__sign_message_path_template.format(path_title)
)
await layouts.confirm_text(
"confirm_message_signing_path",
TR.cardano__confirm_message,
address_n_to_str(path),
text,
BRT_Other,
)

View File

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

View File

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

View File

@ -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
@ -70,8 +71,6 @@ _DATUM_OPTION_KEY_INLINE = const(1)
_POOL_REGISTRATION_CERTIFICATE_ITEMS_COUNT = const(10)
_MAX_CHUNK_SIZE = const(1024)
class SuiteTxType(IntEnum):
"""
@ -647,17 +646,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)
@ -674,17 +667,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)
@ -1213,22 +1200,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:

View File

@ -179,6 +179,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:

View File

@ -182,6 +182,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

View File

@ -523,6 +523,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

View File

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

View File

@ -148,6 +148,7 @@
"cardano__collateral_input_index": "Collateral input index:",
"cardano__collateral_output_contains_tokens": "The collateral return output contains tokens.",
"cardano__collateral_return": "Collateral return",
"cardano__confirm_message": "Confirm message",
"cardano__confirm_signing_stake_pool": "Confirm signing the stake pool registration as an owner.",
"cardano__confirm_transaction": "Confirm transaction",
"cardano__confirming_a_multisig_transaction": "Confirming a multisig transaction.",
@ -161,6 +162,7 @@
"cardano__delegating_to_key_hash": "Delegating to key hash:",
"cardano__delegating_to_script": "Delegating to script:",
"cardano__deposit": "Deposit:",
"cardano__empty_message": "Empty message",
"cardano__for_account_and_index_template": "for account {0} and index {1}:",
"cardano__for_account_template": "for account {0}:",
"cardano__for_key_hash": "for key hash:",
@ -173,6 +175,9 @@
"cardano__intro_text_registration_payment": "The vote key registration payment address is owned by this device. Its",
"cardano__key_hash": "key hash",
"cardano__margin": "Margin",
"cardano__message_hash": "Message hash:",
"cardano__message_hex": "Message hex",
"cardano__message_text": "Message text",
"cardano__multisig_path": "multi-sig path",
"cardano__nested_scripts_template": "Contains {0} nested scripts.",
"cardano__network": "Network:",
@ -207,6 +212,8 @@
"cardano__script_reward": "script reward",
"cardano__sending": "Sending",
"cardano__show_simple": "Show Simple",
"cardano__sign_message_hash_path_template": "Sign message hash with {0}:",
"cardano__sign_message_path_template": "Sign message with {0}:",
"cardano__sign_tx_path_template": "Sign transaction with {0}:",
"cardano__stake_delegation": "Stake delegation",
"cardano__stake_deregistration": "Stake key deregistration",

View File

@ -973,5 +973,12 @@
"971": "instructions__view_all_data",
"972": "ethereum__interaction_contract",
"973": "misc__enable_labeling",
"974": "ethereum__unknown_contract_address_short"
"974": "ethereum__unknown_contract_address_short",
"975": "cardano__confirm_message",
"976": "cardano__empty_message",
"977": "cardano__message_hash",
"978": "cardano__message_hex",
"979": "cardano__message_text",
"980": "cardano__sign_message_hash_path_template",
"981": "cardano__sign_message_path_template"
}

View File

@ -1,8 +1,8 @@
{
"current": {
"merkle_root": "007f67665e08d5512c3d287949ada4fab7ef7de33dd5edc0539f090d0d3d2d98",
"datetime": "2024-11-28T12:34:57.070219",
"commit": "66e992540ecc37e77c8fc40f626039fa6a68eeb2"
"merkle_root": "db076d53e2834814d4238523057137b7701961f34767667b6864934c475212ea",
"datetime": "2024-11-29T12:56:35.610859",
"commit": "887e07b47123df226edf01ccae00f54b5159b641"
},
"history": [
{

View File

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

View File

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

View File

@ -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
@ -327,3 +327,36 @@ def get_native_script_hash(
return cardano.get_native_script_hash(
client, native_script, display_format, derivation_type=derivation_type
)
@cli.command()
@click.argument("file", type=click.File("r"))
@click.option(
"-D",
"--derivation-type",
type=ChoiceType({m.name: m for m in messages.CardanoDerivationType}),
default=messages.CardanoDerivationType.ICARUS,
)
@with_client
def sign_message(
client: "TrezorClient",
file: TextIO,
derivation_type: messages.CardanoDerivationType,
) -> messages.CardanoSignMessageFinished:
"""Sign Cardano message containing arbitrary data."""
request: dict[Any, Any] = json.load(file)
client.init_device(derive_cardano=True)
return cardano.sign_message(
client,
payload=bytes.fromhex(request["payload"]),
hash_payload=request["hash_payload"],
prefer_hex_display=request["prefer_hex_display"],
signing_path=tools.parse_path(request["signing_path"]),
address_parameters=cardano.parse_optional_address_parameters(
request.get("address_parameters")
),
protocol_magic=request.get("protocol_magic"),
network_id=request.get("network_id"),
derivation_type=derivation_type,
)

View File

@ -576,6 +576,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
@ -3054,6 +3059,83 @@ class CardanoSignTxFinished(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 319
class CardanoSignMessageInit(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 338
FIELDS = {
1: protobuf.Field("protocol_magic", "uint32", repeated=False, required=False, default=None),
2: protobuf.Field("network_id", "uint32", repeated=False, required=False, default=None),
3: protobuf.Field("signing_path", "uint32", repeated=True, required=False, default=None),
4: protobuf.Field("payload_size", "uint32", repeated=False, required=True),
5: protobuf.Field("hash_payload", "bool", repeated=False, required=True),
6: protobuf.Field("prefer_hex_display", "bool", repeated=False, required=True),
7: protobuf.Field("address_parameters", "CardanoAddressParametersType", repeated=False, required=False, default=None),
8: protobuf.Field("derivation_type", "CardanoDerivationType", repeated=False, required=True),
}
def __init__(
self,
*,
payload_size: "int",
hash_payload: "bool",
prefer_hex_display: "bool",
derivation_type: "CardanoDerivationType",
signing_path: Optional[Sequence["int"]] = None,
protocol_magic: Optional["int"] = None,
network_id: Optional["int"] = None,
address_parameters: Optional["CardanoAddressParametersType"] = None,
) -> None:
self.signing_path: Sequence["int"] = signing_path if signing_path is not None else []
self.payload_size = payload_size
self.hash_payload = hash_payload
self.prefer_hex_display = prefer_hex_display
self.derivation_type = derivation_type
self.protocol_magic = protocol_magic
self.network_id = network_id
self.address_parameters = address_parameters
class CardanoMessageItemAck(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 340
class CardanoMessagePayloadChunk(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 339
FIELDS = {
1: protobuf.Field("data", "bytes", repeated=False, required=True),
}
def __init__(
self,
*,
data: "bytes",
) -> None:
self.data = data
class CardanoMessageItemHostAck(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 341
class CardanoSignMessageFinished(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 342
FIELDS = {
1: protobuf.Field("signature", "bytes", repeated=False, required=True),
2: protobuf.Field("address", "bytes", repeated=False, required=True),
3: protobuf.Field("pub_key", "bytes", repeated=False, required=True),
}
def __init__(
self,
*,
signature: "bytes",
address: "bytes",
pub_key: "bytes",
) -> None:
self.signature = signature
self.address = address
self.pub_key = pub_key
class CipherKeyValue(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 23
FIELDS = {

View File

@ -151,6 +151,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")]

View File

@ -378,6 +378,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)
@ -704,6 +714,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),
@ -955,6 +970,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),
@ -1205,6 +1225,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,
@ -1461,76 +1486,81 @@ impl ::protobuf::EnumFull for MessageType {
MessageType::MessageType_CardanoTxInlineDatumChunk => 172,
MessageType::MessageType_CardanoTxReferenceScriptChunk => 173,
MessageType::MessageType_CardanoTxReferenceInput => 174,
MessageType::MessageType_RippleGetAddress => 175,
MessageType::MessageType_RippleAddress => 176,
MessageType::MessageType_RippleSignTx => 177,
MessageType::MessageType_RippleSignedTx => 178,
MessageType::MessageType_MoneroTransactionInitRequest => 179,
MessageType::MessageType_MoneroTransactionInitAck => 180,
MessageType::MessageType_MoneroTransactionSetInputRequest => 181,
MessageType::MessageType_MoneroTransactionSetInputAck => 182,
MessageType::MessageType_MoneroTransactionInputViniRequest => 183,
MessageType::MessageType_MoneroTransactionInputViniAck => 184,
MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 185,
MessageType::MessageType_MoneroTransactionAllInputsSetAck => 186,
MessageType::MessageType_MoneroTransactionSetOutputRequest => 187,
MessageType::MessageType_MoneroTransactionSetOutputAck => 188,
MessageType::MessageType_MoneroTransactionAllOutSetRequest => 189,
MessageType::MessageType_MoneroTransactionAllOutSetAck => 190,
MessageType::MessageType_MoneroTransactionSignInputRequest => 191,
MessageType::MessageType_MoneroTransactionSignInputAck => 192,
MessageType::MessageType_MoneroTransactionFinalRequest => 193,
MessageType::MessageType_MoneroTransactionFinalAck => 194,
MessageType::MessageType_MoneroKeyImageExportInitRequest => 195,
MessageType::MessageType_MoneroKeyImageExportInitAck => 196,
MessageType::MessageType_MoneroKeyImageSyncStepRequest => 197,
MessageType::MessageType_MoneroKeyImageSyncStepAck => 198,
MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 199,
MessageType::MessageType_MoneroKeyImageSyncFinalAck => 200,
MessageType::MessageType_MoneroGetAddress => 201,
MessageType::MessageType_MoneroAddress => 202,
MessageType::MessageType_MoneroGetWatchKey => 203,
MessageType::MessageType_MoneroWatchKey => 204,
MessageType::MessageType_DebugMoneroDiagRequest => 205,
MessageType::MessageType_DebugMoneroDiagAck => 206,
MessageType::MessageType_MoneroGetTxKeyRequest => 207,
MessageType::MessageType_MoneroGetTxKeyAck => 208,
MessageType::MessageType_MoneroLiveRefreshStartRequest => 209,
MessageType::MessageType_MoneroLiveRefreshStartAck => 210,
MessageType::MessageType_MoneroLiveRefreshStepRequest => 211,
MessageType::MessageType_MoneroLiveRefreshStepAck => 212,
MessageType::MessageType_MoneroLiveRefreshFinalRequest => 213,
MessageType::MessageType_MoneroLiveRefreshFinalAck => 214,
MessageType::MessageType_EosGetPublicKey => 215,
MessageType::MessageType_EosPublicKey => 216,
MessageType::MessageType_EosSignTx => 217,
MessageType::MessageType_EosTxActionRequest => 218,
MessageType::MessageType_EosTxActionAck => 219,
MessageType::MessageType_EosSignedTx => 220,
MessageType::MessageType_BinanceGetAddress => 221,
MessageType::MessageType_BinanceAddress => 222,
MessageType::MessageType_BinanceGetPublicKey => 223,
MessageType::MessageType_BinancePublicKey => 224,
MessageType::MessageType_BinanceSignTx => 225,
MessageType::MessageType_BinanceTxRequest => 226,
MessageType::MessageType_BinanceTransferMsg => 227,
MessageType::MessageType_BinanceOrderMsg => 228,
MessageType::MessageType_BinanceCancelMsg => 229,
MessageType::MessageType_BinanceSignedTx => 230,
MessageType::MessageType_WebAuthnListResidentCredentials => 231,
MessageType::MessageType_WebAuthnCredentials => 232,
MessageType::MessageType_WebAuthnAddResidentCredential => 233,
MessageType::MessageType_WebAuthnRemoveResidentCredential => 234,
MessageType::MessageType_SolanaGetPublicKey => 235,
MessageType::MessageType_SolanaPublicKey => 236,
MessageType::MessageType_SolanaGetAddress => 237,
MessageType::MessageType_SolanaAddress => 238,
MessageType::MessageType_SolanaSignTx => 239,
MessageType::MessageType_SolanaTxSignature => 240,
MessageType::MessageType_BenchmarkListNames => 241,
MessageType::MessageType_BenchmarkNames => 242,
MessageType::MessageType_BenchmarkRun => 243,
MessageType::MessageType_BenchmarkResult => 244,
MessageType::MessageType_CardanoSignMessageInit => 175,
MessageType::MessageType_CardanoMessagePayloadChunk => 176,
MessageType::MessageType_CardanoMessageItemAck => 177,
MessageType::MessageType_CardanoMessageItemHostAck => 178,
MessageType::MessageType_CardanoSignMessageFinished => 179,
MessageType::MessageType_RippleGetAddress => 180,
MessageType::MessageType_RippleAddress => 181,
MessageType::MessageType_RippleSignTx => 182,
MessageType::MessageType_RippleSignedTx => 183,
MessageType::MessageType_MoneroTransactionInitRequest => 184,
MessageType::MessageType_MoneroTransactionInitAck => 185,
MessageType::MessageType_MoneroTransactionSetInputRequest => 186,
MessageType::MessageType_MoneroTransactionSetInputAck => 187,
MessageType::MessageType_MoneroTransactionInputViniRequest => 188,
MessageType::MessageType_MoneroTransactionInputViniAck => 189,
MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 190,
MessageType::MessageType_MoneroTransactionAllInputsSetAck => 191,
MessageType::MessageType_MoneroTransactionSetOutputRequest => 192,
MessageType::MessageType_MoneroTransactionSetOutputAck => 193,
MessageType::MessageType_MoneroTransactionAllOutSetRequest => 194,
MessageType::MessageType_MoneroTransactionAllOutSetAck => 195,
MessageType::MessageType_MoneroTransactionSignInputRequest => 196,
MessageType::MessageType_MoneroTransactionSignInputAck => 197,
MessageType::MessageType_MoneroTransactionFinalRequest => 198,
MessageType::MessageType_MoneroTransactionFinalAck => 199,
MessageType::MessageType_MoneroKeyImageExportInitRequest => 200,
MessageType::MessageType_MoneroKeyImageExportInitAck => 201,
MessageType::MessageType_MoneroKeyImageSyncStepRequest => 202,
MessageType::MessageType_MoneroKeyImageSyncStepAck => 203,
MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 204,
MessageType::MessageType_MoneroKeyImageSyncFinalAck => 205,
MessageType::MessageType_MoneroGetAddress => 206,
MessageType::MessageType_MoneroAddress => 207,
MessageType::MessageType_MoneroGetWatchKey => 208,
MessageType::MessageType_MoneroWatchKey => 209,
MessageType::MessageType_DebugMoneroDiagRequest => 210,
MessageType::MessageType_DebugMoneroDiagAck => 211,
MessageType::MessageType_MoneroGetTxKeyRequest => 212,
MessageType::MessageType_MoneroGetTxKeyAck => 213,
MessageType::MessageType_MoneroLiveRefreshStartRequest => 214,
MessageType::MessageType_MoneroLiveRefreshStartAck => 215,
MessageType::MessageType_MoneroLiveRefreshStepRequest => 216,
MessageType::MessageType_MoneroLiveRefreshStepAck => 217,
MessageType::MessageType_MoneroLiveRefreshFinalRequest => 218,
MessageType::MessageType_MoneroLiveRefreshFinalAck => 219,
MessageType::MessageType_EosGetPublicKey => 220,
MessageType::MessageType_EosPublicKey => 221,
MessageType::MessageType_EosSignTx => 222,
MessageType::MessageType_EosTxActionRequest => 223,
MessageType::MessageType_EosTxActionAck => 224,
MessageType::MessageType_EosSignedTx => 225,
MessageType::MessageType_BinanceGetAddress => 226,
MessageType::MessageType_BinanceAddress => 227,
MessageType::MessageType_BinanceGetPublicKey => 228,
MessageType::MessageType_BinancePublicKey => 229,
MessageType::MessageType_BinanceSignTx => 230,
MessageType::MessageType_BinanceTxRequest => 231,
MessageType::MessageType_BinanceTransferMsg => 232,
MessageType::MessageType_BinanceOrderMsg => 233,
MessageType::MessageType_BinanceCancelMsg => 234,
MessageType::MessageType_BinanceSignedTx => 235,
MessageType::MessageType_WebAuthnListResidentCredentials => 236,
MessageType::MessageType_WebAuthnCredentials => 237,
MessageType::MessageType_WebAuthnAddResidentCredential => 238,
MessageType::MessageType_WebAuthnRemoveResidentCredential => 239,
MessageType::MessageType_SolanaGetPublicKey => 240,
MessageType::MessageType_SolanaPublicKey => 241,
MessageType::MessageType_SolanaGetAddress => 242,
MessageType::MessageType_SolanaAddress => 243,
MessageType::MessageType_SolanaSignTx => 244,
MessageType::MessageType_SolanaTxSignature => 245,
MessageType::MessageType_BenchmarkListNames => 246,
MessageType::MessageType_BenchmarkNames => 247,
MessageType::MessageType_BenchmarkRun => 248,
MessageType::MessageType_BenchmarkResult => 249,
};
Self::enum_descriptor().value_by_index(index)
}
@ -1549,7 +1579,7 @@ impl MessageType {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\x89U\
\n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\xfeV\
\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\
@ -1749,89 +1779,95 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x10\xce\x02\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType_CardanoTxInlineD\
atumChunk\x10\xcf\x02\x1a\x04\x90\xb5\x18\x01\x124\n)MessageType_Cardano\
TxReferenceScriptChunk\x10\xd0\x02\x1a\x04\x90\xb5\x18\x01\x12.\n#Messag\
eType_CardanoTxReferenceInput\x10\xd1\x02\x1a\x04\x90\xb5\x18\x01\x12'\n\
\x1cMessageType_RippleGetAddress\x10\x90\x03\x1a\x04\x90\xb5\x18\x01\x12\
$\n\x19MessageType_RippleAddress\x10\x91\x03\x1a\x04\x98\xb5\x18\x01\x12\
#\n\x18MessageType_RippleSignTx\x10\x92\x03\x1a\x04\x90\xb5\x18\x01\x12%\
\n\x1aMessageType_RippleSignedTx\x10\x93\x03\x1a\x04\x90\xb5\x18\x01\x12\
3\n(MessageType_MoneroTransactionInitRequest\x10\xf5\x03\x1a\x04\x98\xb5\
\x18\x01\x12/\n$MessageType_MoneroTransactionInitAck\x10\xf6\x03\x1a\x04\
\x98\xb5\x18\x01\x127\n,MessageType_MoneroTransactionSetInputRequest\x10\
\xf7\x03\x1a\x04\x98\xb5\x18\x01\x123\n(MessageType_MoneroTransactionSet\
InputAck\x10\xf8\x03\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTr\
ansactionInputViniRequest\x10\xfb\x03\x1a\x04\x98\xb5\x18\x01\x124\n)Mes\
sageType_MoneroTransactionInputViniAck\x10\xfc\x03\x1a\x04\x98\xb5\x18\
\x01\x12;\n0MessageType_MoneroTransactionAllInputsSetRequest\x10\xfd\x03\
\x1a\x04\x98\xb5\x18\x01\x127\n,MessageType_MoneroTransactionAllInputsSe\
tAck\x10\xfe\x03\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransa\
ctionSetOutputRequest\x10\xff\x03\x1a\x04\x98\xb5\x18\x01\x124\n)Message\
Type_MoneroTransactionSetOutputAck\x10\x80\x04\x1a\x04\x98\xb5\x18\x01\
\x128\n-MessageType_MoneroTransactionAllOutSetRequest\x10\x81\x04\x1a\
\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTransactionAllOutSetAck\
\x10\x82\x04\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransactio\
nSignInputRequest\x10\x83\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType\
_MoneroTransactionSignInputAck\x10\x84\x04\x1a\x04\x98\xb5\x18\x01\x124\
\n)MessageType_MoneroTransactionFinalRequest\x10\x85\x04\x1a\x04\x98\xb5\
\x18\x01\x120\n%MessageType_MoneroTransactionFinalAck\x10\x86\x04\x1a\
\x04\x98\xb5\x18\x01\x126\n+MessageType_MoneroKeyImageExportInitRequest\
\x10\x92\x04\x1a\x04\x98\xb5\x18\x01\x122\n'MessageType_MoneroKeyImageEx\
portInitAck\x10\x93\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_Moner\
oKeyImageSyncStepRequest\x10\x94\x04\x1a\x04\x98\xb5\x18\x01\x120\n%Mess\
ageType_MoneroKeyImageSyncStepAck\x10\x95\x04\x1a\x04\x98\xb5\x18\x01\
\x125\n*MessageType_MoneroKeyImageSyncFinalRequest\x10\x96\x04\x1a\x04\
\x98\xb5\x18\x01\x121\n&MessageType_MoneroKeyImageSyncFinalAck\x10\x97\
\x04\x1a\x04\x98\xb5\x18\x01\x12'\n\x1cMessageType_MoneroGetAddress\x10\
\x9c\x04\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_MoneroAddress\x10\
\x9d\x04\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_MoneroGetWatchKey\
\x10\x9e\x04\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_MoneroWatchKe\
y\x10\x9f\x04\x1a\x04\x98\xb5\x18\x01\x12-\n\"MessageType_DebugMoneroDia\
gRequest\x10\xa2\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_Debug\
MoneroDiagAck\x10\xa3\x04\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_Mon\
eroGetTxKeyRequest\x10\xa6\x04\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessage\
Type_MoneroGetTxKeyAck\x10\xa7\x04\x1a\x04\x98\xb5\x18\x01\x124\n)Messag\
eType_MoneroLiveRefreshStartRequest\x10\xa8\x04\x1a\x04\x90\xb5\x18\x01\
\x120\n%MessageType_MoneroLiveRefreshStartAck\x10\xa9\x04\x1a\x04\x98\
\xb5\x18\x01\x123\n(MessageType_MoneroLiveRefreshStepRequest\x10\xaa\x04\
\x1a\x04\x90\xb5\x18\x01\x12/\n$MessageType_MoneroLiveRefreshStepAck\x10\
\xab\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroLiveRefreshFin\
alRequest\x10\xac\x04\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType_MoneroL\
iveRefreshFinalAck\x10\xad\x04\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessage\
Type_EosGetPublicKey\x10\xd8\x04\x1a\x04\x90\xb5\x18\x01\x12#\n\x18Messa\
geType_EosPublicKey\x10\xd9\x04\x1a\x04\x98\xb5\x18\x01\x12\x20\n\x15Mes\
sageType_EosSignTx\x10\xda\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessage\
Type_EosTxActionRequest\x10\xdb\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMe\
ssageType_EosTxActionAck\x10\xdc\x04\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17\
MessageType_EosSignedTx\x10\xdd\x04\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMe\
ssageType_BinanceGetAddress\x10\xbc\x05\x1a\x04\x90\xb5\x18\x01\x12%\n\
\x1aMessageType_BinanceAddress\x10\xbd\x05\x1a\x04\x98\xb5\x18\x01\x12*\
\n\x1fMessageType_BinanceGetPublicKey\x10\xbe\x05\x1a\x04\x90\xb5\x18\
\x01\x12'\n\x1cMessageType_BinancePublicKey\x10\xbf\x05\x1a\x04\x98\xb5\
\x18\x01\x12$\n\x19MessageType_BinanceSignTx\x10\xc0\x05\x1a\x04\x90\xb5\
\x18\x01\x12'\n\x1cMessageType_BinanceTxRequest\x10\xc1\x05\x1a\x04\x98\
\xb5\x18\x01\x12)\n\x1eMessageType_BinanceTransferMsg\x10\xc2\x05\x1a\
\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceOrderMsg\x10\xc3\x05\
\x1a\x04\x90\xb5\x18\x01\x12'\n\x1cMessageType_BinanceCancelMsg\x10\xc4\
\x05\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceSignedTx\x10\
\xc5\x05\x1a\x04\x98\xb5\x18\x01\x126\n+MessageType_WebAuthnListResident\
Credentials\x10\xa0\x06\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_We\
bAuthnCredentials\x10\xa1\x06\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType\
_WebAuthnAddResidentCredential\x10\xa2\x06\x1a\x04\x90\xb5\x18\x01\x127\
\n,MessageType_WebAuthnRemoveResidentCredential\x10\xa3\x06\x1a\x04\x90\
\xb5\x18\x01\x12)\n\x1eMessageType_SolanaGetPublicKey\x10\x84\x07\x1a\
\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_SolanaPublicKey\x10\x85\x07\
\x1a\x04\x98\xb5\x18\x01\x12'\n\x1cMessageType_SolanaGetAddress\x10\x86\
\x07\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_SolanaAddress\x10\x87\
\x07\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_SolanaSignTx\x10\x88\
\x07\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_SolanaTxSignature\x10\
\x89\x07\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_BenchmarkListName\
s\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\x1bMessageType_BenchmarkResult\x10\
\x8fG\x1a\x04\x80\xa6\x1d\x01\x1a\x04\xc8\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\xe8\x07\x10\xcb\x08B8\n#com.satoshilabs.trezor.lib.pr\
otobufB\rTrezorMessage\x80\xa6\x1d\x01\
eType_CardanoTxReferenceInput\x10\xd1\x02\x1a\x04\x90\xb5\x18\x01\x12-\n\
\"MessageType_CardanoSignMessageInit\x10\xd2\x02\x1a\x04\x90\xb5\x18\x01\
\x121\n&MessageType_CardanoMessagePayloadChunk\x10\xd3\x02\x1a\x04\x90\
\xb5\x18\x01\x12,\n!MessageType_CardanoMessageItemAck\x10\xd4\x02\x1a\
\x04\x98\xb5\x18\x01\x120\n%MessageType_CardanoMessageItemHostAck\x10\
\xd5\x02\x1a\x04\x90\xb5\x18\x01\x121\n&MessageType_CardanoSignMessageFi\
nished\x10\xd6\x02\x1a\x04\x98\xb5\x18\x01\x12'\n\x1cMessageType_RippleG\
etAddress\x10\x90\x03\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_Ripp\
leAddress\x10\x91\x03\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_Ripp\
leSignTx\x10\x92\x03\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_Rippl\
eSignedTx\x10\x93\x03\x1a\x04\x90\xb5\x18\x01\x123\n(MessageType_MoneroT\
ransactionInitRequest\x10\xf5\x03\x1a\x04\x98\xb5\x18\x01\x12/\n$Message\
Type_MoneroTransactionInitAck\x10\xf6\x03\x1a\x04\x98\xb5\x18\x01\x127\n\
,MessageType_MoneroTransactionSetInputRequest\x10\xf7\x03\x1a\x04\x98\
\xb5\x18\x01\x123\n(MessageType_MoneroTransactionSetInputAck\x10\xf8\x03\
\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransactionInputViniRe\
quest\x10\xfb\x03\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTrans\
actionInputViniAck\x10\xfc\x03\x1a\x04\x98\xb5\x18\x01\x12;\n0MessageTyp\
e_MoneroTransactionAllInputsSetRequest\x10\xfd\x03\x1a\x04\x98\xb5\x18\
\x01\x127\n,MessageType_MoneroTransactionAllInputsSetAck\x10\xfe\x03\x1a\
\x04\x98\xb5\x18\x01\x128\n-MessageType_MoneroTransactionSetOutputReques\
t\x10\xff\x03\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTransacti\
onSetOutputAck\x10\x80\x04\x1a\x04\x98\xb5\x18\x01\x128\n-MessageType_Mo\
neroTransactionAllOutSetRequest\x10\x81\x04\x1a\x04\x98\xb5\x18\x01\x124\
\n)MessageType_MoneroTransactionAllOutSetAck\x10\x82\x04\x1a\x04\x98\xb5\
\x18\x01\x128\n-MessageType_MoneroTransactionSignInputRequest\x10\x83\
\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTransactionSignInp\
utAck\x10\x84\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroTrans\
actionFinalRequest\x10\x85\x04\x1a\x04\x98\xb5\x18\x01\x120\n%MessageTyp\
e_MoneroTransactionFinalAck\x10\x86\x04\x1a\x04\x98\xb5\x18\x01\x126\n+M\
essageType_MoneroKeyImageExportInitRequest\x10\x92\x04\x1a\x04\x98\xb5\
\x18\x01\x122\n'MessageType_MoneroKeyImageExportInitAck\x10\x93\x04\x1a\
\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroKeyImageSyncStepRequest\
\x10\x94\x04\x1a\x04\x98\xb5\x18\x01\x120\n%MessageType_MoneroKeyImageSy\
ncStepAck\x10\x95\x04\x1a\x04\x98\xb5\x18\x01\x125\n*MessageType_MoneroK\
eyImageSyncFinalRequest\x10\x96\x04\x1a\x04\x98\xb5\x18\x01\x121\n&Messa\
geType_MoneroKeyImageSyncFinalAck\x10\x97\x04\x1a\x04\x98\xb5\x18\x01\
\x12'\n\x1cMessageType_MoneroGetAddress\x10\x9c\x04\x1a\x04\x90\xb5\x18\
\x01\x12$\n\x19MessageType_MoneroAddress\x10\x9d\x04\x1a\x04\x98\xb5\x18\
\x01\x12(\n\x1dMessageType_MoneroGetWatchKey\x10\x9e\x04\x1a\x04\x90\xb5\
\x18\x01\x12%\n\x1aMessageType_MoneroWatchKey\x10\x9f\x04\x1a\x04\x98\
\xb5\x18\x01\x12-\n\"MessageType_DebugMoneroDiagRequest\x10\xa2\x04\x1a\
\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_DebugMoneroDiagAck\x10\xa3\
\x04\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_MoneroGetTxKeyRequest\
\x10\xa6\x04\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_MoneroGetTxKe\
yAck\x10\xa7\x04\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_MoneroLiveRe\
freshStartRequest\x10\xa8\x04\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType\
_MoneroLiveRefreshStartAck\x10\xa9\x04\x1a\x04\x98\xb5\x18\x01\x123\n(Me\
ssageType_MoneroLiveRefreshStepRequest\x10\xaa\x04\x1a\x04\x90\xb5\x18\
\x01\x12/\n$MessageType_MoneroLiveRefreshStepAck\x10\xab\x04\x1a\x04\x98\
\xb5\x18\x01\x124\n)MessageType_MoneroLiveRefreshFinalRequest\x10\xac\
\x04\x1a\x04\x90\xb5\x18\x01\x120\n%MessageType_MoneroLiveRefreshFinalAc\
k\x10\xad\x04\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_EosGetPublic\
Key\x10\xd8\x04\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_EosPublicK\
ey\x10\xd9\x04\x1a\x04\x98\xb5\x18\x01\x12\x20\n\x15MessageType_EosSignT\
x\x10\xda\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_EosTxActionR\
equest\x10\xdb\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_EosTxAc\
tionAck\x10\xdc\x04\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_EosSi\
gnedTx\x10\xdd\x04\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_Binance\
GetAddress\x10\xbc\x05\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_Bin\
anceAddress\x10\xbd\x05\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_Bi\
nanceGetPublicKey\x10\xbe\x05\x1a\x04\x90\xb5\x18\x01\x12'\n\x1cMessageT\
ype_BinancePublicKey\x10\xbf\x05\x1a\x04\x98\xb5\x18\x01\x12$\n\x19Messa\
geType_BinanceSignTx\x10\xc0\x05\x1a\x04\x90\xb5\x18\x01\x12'\n\x1cMessa\
geType_BinanceTxRequest\x10\xc1\x05\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMe\
ssageType_BinanceTransferMsg\x10\xc2\x05\x1a\x04\x90\xb5\x18\x01\x12&\n\
\x1bMessageType_BinanceOrderMsg\x10\xc3\x05\x1a\x04\x90\xb5\x18\x01\x12'\
\n\x1cMessageType_BinanceCancelMsg\x10\xc4\x05\x1a\x04\x90\xb5\x18\x01\
\x12&\n\x1bMessageType_BinanceSignedTx\x10\xc5\x05\x1a\x04\x98\xb5\x18\
\x01\x126\n+MessageType_WebAuthnListResidentCredentials\x10\xa0\x06\x1a\
\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_WebAuthnCredentials\x10\xa1\
\x06\x1a\x04\x98\xb5\x18\x01\x124\n)MessageType_WebAuthnAddResidentCrede\
ntial\x10\xa2\x06\x1a\x04\x90\xb5\x18\x01\x127\n,MessageType_WebAuthnRem\
oveResidentCredential\x10\xa3\x06\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMess\
ageType_SolanaGetPublicKey\x10\x84\x07\x1a\x04\x90\xb5\x18\x01\x12&\n\
\x1bMessageType_SolanaPublicKey\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x12'\
\n\x1cMessageType_SolanaGetAddress\x10\x86\x07\x1a\x04\x90\xb5\x18\x01\
\x12$\n\x19MessageType_SolanaAddress\x10\x87\x07\x1a\x04\x98\xb5\x18\x01\
\x12#\n\x18MessageType_SolanaSignTx\x10\x88\x07\x1a\x04\x90\xb5\x18\x01\
\x12(\n\x1dMessageType_SolanaTxSignature\x10\x89\x07\x1a\x04\x98\xb5\x18\
\x01\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\x1bMessageType_BenchmarkResult\x10\x8fG\x1a\x04\x80\xa6\x1d\
\x01\x1a\x04\xc8\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\xe8\x07\
\x10\xcb\x08B8\n#com.satoshilabs.trezor.lib.protobufB\rTrezorMessage\x80\
\xa6\x1d\x01\
";
/// `FileDescriptorProto` object which was a source for this generated file

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -4531,6 +4531,18 @@
"T2T1_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[nested_script_w-789238e6": "1db5dbed03169637cf677e3d60876d74c30e34da0ac5afc92b28e499afb8af4a",
"T2T1_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script]": "8891c8f3c1fae3c45ac3345732246489f156dae10694b447dd84075e6d2d9668",
"T2T1_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script_-1579fe2a": "129f7385876304d12889babfbc0659b82e8d6ab1711ad1201182bddbd06d8c42",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[ambiguous_ascii_payload_falls_back_to_hex]": "b85baab1972ff7537371b761ea8d820d7434c13fffd4ec2883144c0cdf2ef3d9",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[non-ascii_payload_falls_back_to_hex]": "8b3fc07e6d9a8a069da69c81b0ebd1bb1856a125de4d74abf98d257d6e650096",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload]": "f1533faf31a51bb4f25dffd3f032e4d6b3fdcc1f56f4a465bcc7ffffabb6e094",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload_hash]": "f14232dbd80897aa9fcd6c53a9e7d3101dea467c0ee1cb150b4a61e6e2e84b06",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_long_ascii_payload_hash]": "f9c8c201d4ccb548f869eb25a202c7ae21f79aaabb66a0a6db8074cf877b5f79",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload]": "b63d79d3409417d7bef5bcb41d7ba7af383274b27c3cef03d5ab19dd51256cc5",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload_rendered_as_hex]": "f98074da41c9d0df079a6c6373d0f5bcd3c64443af46de5398b2eb3828aceb2c",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload]": "3dfafb7b60627b40d961734ebc42d60503570b232553dd25c02bf7ddbdd81390",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_hash]": "efe5e3b12602cf144f8f36f7e110806b856f2c35f55d3ced05ce2267b6c8b360",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_with_a-1f337ea4": "4b295dd7b0a262f6b7326907b4d78ac65df3bc0063afb74827baa9060aa51a51",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[missing_network_id_and_proto-21ec11cf": "659182762aefa7393004327f2b545f15209a1fe59c0201e8ec191a2054170a48",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[unhashed_payload_too_long]": "659182762aefa7393004327f2b545f15209a1fe59c0201e8ec191a2054170a48",
"T2T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx[byron_to_shelley_transfer]": "828103a77c7fce200c7312e6aa4171fe36c0d26409a27c230470d32d0faffe26",
"T2T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_change0]": "2f3b186b7ba85ea7782a74eb90b80e501a203f0cbca781090accfb155773625c",
"T2T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_change1]": "44da05888ef7853362588fe28068c568f73318b2730cbffab054233d49474d13",