diff --git a/common/protob/messages-bitcoin.proto b/common/protob/messages-bitcoin.proto index 9d5352af492..2676b2925ab 100644 --- a/common/protob/messages-bitcoin.proto +++ b/common/protob/messages-bitcoin.proto @@ -152,6 +152,7 @@ message SignMessage { required bytes message = 2; // message to be signed optional string coin_name = 3 [default='Bitcoin']; // coin to use for signing optional InputScriptType script_type = 4 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) + optional bool no_script_type = 5; // don't include script type information in the recovery byte of the signature, same as in Bitcoin Core } /** diff --git a/core/.changelog.d/1586.added b/core/.changelog.d/1586.added new file mode 100644 index 00000000000..b740dbe152e --- /dev/null +++ b/core/.changelog.d/1586.added @@ -0,0 +1 @@ +Support no_script_type option in SignMessage. diff --git a/core/.changelog.d/1586.added.1 b/core/.changelog.d/1586.added.1 new file mode 100644 index 00000000000..04f09d2ff19 --- /dev/null +++ b/core/.changelog.d/1586.added.1 @@ -0,0 +1 @@ +Show address confirmation in SignMessage. diff --git a/core/src/apps/bitcoin/sign_message.py b/core/src/apps/bitcoin/sign_message.py index 7dd2e0c5d24..967a70bfdc1 100644 --- a/core/src/apps/bitcoin/sign_message.py +++ b/core/src/apps/bitcoin/sign_message.py @@ -7,7 +7,7 @@ from apps.common.paths import validate_path from apps.common.signverify import decode_message, message_digest -from .addresses import get_address +from .addresses import address_short, get_address from .keychain import with_keychain if False: @@ -26,22 +26,33 @@ async def sign_message( script_type = msg.script_type or InputScriptType.SPENDADDRESS await validate_path(ctx, keychain, address_n) - await confirm_signverify(ctx, coin.coin_shortcut, decode_message(message)) node = keychain.derive(address_n) + address = get_address(script_type, coin, node) + await confirm_signverify( + ctx, + coin.coin_shortcut, + decode_message(message), + address_short(coin, address), + verify=False, + ) + seckey = node.private_key() - address = get_address(script_type, coin, node) digest = message_digest(coin, message) signature = secp256k1.sign(seckey, digest) if script_type == InputScriptType.SPENDADDRESS: - pass + script_type_info = 0 elif script_type == InputScriptType.SPENDP2SHWITNESS: - signature = bytes([signature[0] + 4]) + signature[1:] + script_type_info = 4 elif script_type == InputScriptType.SPENDWITNESS: - signature = bytes([signature[0] + 8]) + signature[1:] + script_type_info = 8 else: raise wire.ProcessError("Unsupported script type") + # Add script type information to the recovery byte. + if script_type_info != 0 and not msg.no_script_type: + signature = bytes([signature[0] + script_type_info]) + signature[1:] + return MessageSignature(address=address, signature=signature) diff --git a/core/src/apps/bitcoin/verify_message.py b/core/src/apps/bitcoin/verify_message.py index 660396fb049..95b439b9f56 100644 --- a/core/src/apps/bitcoin/verify_message.py +++ b/core/src/apps/bitcoin/verify_message.py @@ -67,6 +67,7 @@ async def verify_message(ctx: wire.Context, msg: VerifyMessage) -> Success: coin.coin_shortcut, decode_message(message), address=address_short(coin, address), + verify=True, ) return Success(message="Message verified") diff --git a/core/src/apps/ethereum/sign_message.py b/core/src/apps/ethereum/sign_message.py index 921e7af6495..84218546a7b 100644 --- a/core/src/apps/ethereum/sign_message.py +++ b/core/src/apps/ethereum/sign_message.py @@ -31,9 +31,13 @@ async def sign_message( ctx: Context, msg: EthereumSignMessage, keychain: Keychain ) -> EthereumMessageSignature: await paths.validate_path(ctx, keychain, msg.address_n) - await confirm_signverify(ctx, "ETH", decode_message(msg.message)) node = keychain.derive(msg.address_n) + address = address_from_bytes(node.ethereum_pubkeyhash()) + await confirm_signverify( + ctx, "ETH", decode_message(msg.message), address, verify=False + ) + signature = secp256k1.sign( node.private_key(), message_digest(msg.message), @@ -42,6 +46,6 @@ async def sign_message( ) return EthereumMessageSignature( - address=address_from_bytes(node.ethereum_pubkeyhash()), + address=address, signature=signature[1:] + bytearray([signature[0]]), ) diff --git a/core/src/apps/ethereum/verify_message.py b/core/src/apps/ethereum/verify_message.py index 26b9130f953..a04bb349a37 100644 --- a/core/src/apps/ethereum/verify_message.py +++ b/core/src/apps/ethereum/verify_message.py @@ -33,6 +33,8 @@ async def verify_message(ctx: Context, msg: EthereumVerifyMessage) -> Success: address = address_from_bytes(address_bytes) - await confirm_signverify(ctx, "ETH", decode_message(msg.message), address=address) + await confirm_signverify( + ctx, "ETH", decode_message(msg.message), address=address, verify=True + ) return Success(message="Message verified") diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 46c7cfa9120..ee600be3a5a 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -526,6 +526,7 @@ class SignMessage(protobuf.MessageType): message: "bytes" coin_name: "str" script_type: "InputScriptType" + no_script_type: "bool | None" def __init__( self, @@ -534,6 +535,7 @@ def __init__( address_n: "list[int] | None" = None, coin_name: "str | None" = None, script_type: "InputScriptType | None" = None, + no_script_type: "bool | None" = None, ) -> None: pass diff --git a/core/src/trezor/ui/layouts/tt/__init__.py b/core/src/trezor/ui/layouts/tt/__init__.py index 55c8d8c568f..71637334e00 100644 --- a/core/src/trezor/ui/layouts/tt/__init__.py +++ b/core/src/trezor/ui/layouts/tt/__init__.py @@ -25,7 +25,6 @@ AskPaginated, Paginated, paginate_paragraphs, - paginate_text, ) from ...components.tt.text import LINE_WIDTH_PAGINATED, Span, Text from ...constants.tt import ( @@ -983,33 +982,26 @@ async def confirm_sign_identity( async def confirm_signverify( - ctx: wire.GenericContext, coin: str, message: str, address: str | None = None + ctx: wire.GenericContext, coin: str, message: str, address: str, verify: bool ) -> None: - if address: + if verify: header = f"Verify {coin} message" - font = ui.MONO br_type = "verify_message" - - text = Text(header, new_lines=False) - text.bold("Confirm address:\n") - text.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) - await raise_if_cancelled( - interact(ctx, Confirm(text), br_type, ButtonRequestType.Other) - ) else: header = f"Sign {coin} message" - font = ui.NORMAL br_type = "sign_message" + text = Text(header, new_lines=False) + text.bold("Confirm address:\n") + text.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) await raise_if_cancelled( - interact( - ctx, - paginate_text(message, header, font=font), - br_type, - ButtonRequestType.Other, - ) + interact(ctx, Confirm(text), br_type, ButtonRequestType.Other) ) + para = [(ui.BOLD, "Confirm message:"), (ui.MONO, message)] + content = paginate_paragraphs(para, header) + await raise_if_cancelled(interact(ctx, content, br_type, ButtonRequestType.Other)) + async def show_popup( title: str, diff --git a/legacy/firmware/.changelog.d/1586.added b/legacy/firmware/.changelog.d/1586.added new file mode 100644 index 00000000000..b740dbe152e --- /dev/null +++ b/legacy/firmware/.changelog.d/1586.added @@ -0,0 +1 @@ +Support no_script_type option in SignMessage. diff --git a/legacy/firmware/.changelog.d/1586.added.1 b/legacy/firmware/.changelog.d/1586.added.1 new file mode 100644 index 00000000000..04f09d2ff19 --- /dev/null +++ b/legacy/firmware/.changelog.d/1586.added.1 @@ -0,0 +1 @@ +Show address confirmation in SignMessage. diff --git a/legacy/firmware/.changelog.d/1586.added.2 b/legacy/firmware/.changelog.d/1586.added.2 new file mode 100644 index 00000000000..5ddfd8e9ef1 --- /dev/null +++ b/legacy/firmware/.changelog.d/1586.added.2 @@ -0,0 +1 @@ +Implement pagination in SignMessage and VerifyMessage. diff --git a/legacy/firmware/crypto.c b/legacy/firmware/crypto.c index 7b3d498359d..139975a1579 100644 --- a/legacy/firmware/crypto.c +++ b/legacy/firmware/crypto.c @@ -146,28 +146,33 @@ static void cryptoMessageHash(const CoinInfo *coin, const uint8_t *message, } int cryptoMessageSign(const CoinInfo *coin, HDNode *node, - InputScriptType script_type, const uint8_t *message, - size_t message_len, uint8_t *signature) { + InputScriptType script_type, bool no_script_type, + const uint8_t *message, size_t message_len, + uint8_t *signature) { uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; cryptoMessageHash(coin, message, message_len, hash); uint8_t pby = 0; int result = hdnode_sign_digest(node, hash, signature + 1, &pby, NULL); if (result == 0) { - switch (script_type) { - case InputScriptType_SPENDP2SHWITNESS: - // segwit-in-p2sh - signature[0] = 35 + pby; - break; - case InputScriptType_SPENDWITNESS: - // segwit - signature[0] = 39 + pby; - break; - default: - // p2pkh - signature[0] = 31 + pby; - break; + uint8_t script_type_info = 0; + if (!no_script_type) { + switch (script_type) { + case InputScriptType_SPENDP2SHWITNESS: + // segwit-in-p2sh + script_type_info = 4; + break; + case InputScriptType_SPENDWITNESS: + // segwit + script_type_info = 8; + break; + default: + // p2pkh + script_type_info = 0; + break; + } } + signature[0] = 31 + pby + script_type_info; } return result; } diff --git a/legacy/firmware/crypto.h b/legacy/firmware/crypto.h index 006db4bf249..7b716e6a063 100644 --- a/legacy/firmware/crypto.h +++ b/legacy/firmware/crypto.h @@ -54,8 +54,9 @@ int signifyMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature); int cryptoMessageSign(const CoinInfo *coin, HDNode *node, - InputScriptType script_type, const uint8_t *message, - size_t message_len, uint8_t *signature); + InputScriptType script_type, bool no_script_type, + const uint8_t *message, size_t message_len, + uint8_t *signature); int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t message_len, const char *address, diff --git a/legacy/firmware/ethereum.c b/legacy/firmware/ethereum.c index e13d6ffe77d..a11cbc0e501 100644 --- a/legacy/firmware/ethereum.c +++ b/legacy/firmware/ethereum.c @@ -905,16 +905,6 @@ static void ethereum_message_hash(const uint8_t *message, size_t message_len, void ethereum_message_sign(const EthereumSignMessage *msg, const HDNode *node, EthereumMessageSignature *resp) { - uint8_t pubkeyhash[20] = {0}; - if (!hdnode_get_ethereum_pubkeyhash(node, pubkeyhash)) { - return; - } - - resp->address[0] = '0'; - resp->address[1] = 'x'; - ethereum_address_checksum(pubkeyhash, resp->address + 2, false, 0); - // ethereum_address_checksum adds trailing zero - uint8_t hash[32] = {0}; ethereum_message_hash(msg->message.bytes, msg->message.size, hash); diff --git a/legacy/firmware/fsm.c b/legacy/firmware/fsm.c index aa6d1cb302a..b315cb213c6 100644 --- a/legacy/firmware/fsm.c +++ b/legacy/firmware/fsm.c @@ -304,6 +304,49 @@ static bool fsm_layoutAddress(const char *address, const char *desc, } } +static bool fsm_layoutPaginated(const char *description, const uint8_t *msg, + uint32_t len, bool is_ascii) { + const char **str = NULL; + const uint32_t row_len = is_ascii ? 18 : 8; + do { + const uint32_t show_len = MIN(len, row_len * 4); + if (is_ascii) { + str = split_message(msg, show_len, row_len); + } else { + str = split_message_hex(msg, show_len); + } + + msg += show_len; + len -= show_len; + + const char *label = len > 0 ? _("Next") : _("Confirm"); + layoutDialogSwipeEx(&bmp_icon_question, _("Cancel"), label, description, + str[0], str[1], str[2], str[3], NULL, NULL, FONT_FIXED); + + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + return false; + } + } while (len > 0); + + return true; +} + +bool fsm_layoutSignMessage(const uint8_t *msg, uint32_t len) { + if (is_valid_ascii(msg, len)) { + return fsm_layoutPaginated(_("Sign message?"), msg, len, true); + } else { + return fsm_layoutPaginated(_("Sign binary message?"), msg, len, false); + } +} + +bool fsm_layoutVerifyMessage(const uint8_t *msg, uint32_t len) { + if (is_valid_ascii(msg, len)) { + return fsm_layoutPaginated(_("Verified message?"), msg, len, true); + } else { + return fsm_layoutPaginated(_("Verified binary message?"), msg, len, false); + } +} + void fsm_msgRebootToBootloader(void) { layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you want to"), _("restart device in"), diff --git a/legacy/firmware/fsm.h b/legacy/firmware/fsm.h index bffb24ad8f0..57a5e7ecee3 100644 --- a/legacy/firmware/fsm.h +++ b/legacy/firmware/fsm.h @@ -135,4 +135,7 @@ void fsm_msgStellarBumpSequenceOp(const StellarBumpSequenceOp *msg); void fsm_msgRebootToBootloader(void); +bool fsm_layoutSignMessage(const uint8_t *msg, uint32_t len); +bool fsm_layoutVerifyMessage(const uint8_t *msg, uint32_t len); + #endif diff --git a/legacy/firmware/fsm_msg_coin.h b/legacy/firmware/fsm_msg_coin.h index 7cc7dac97a9..af03a5066f3 100644 --- a/legacy/firmware/fsm_msg_coin.h +++ b/legacy/firmware/fsm_msg_coin.h @@ -256,13 +256,6 @@ void fsm_msgSignMessage(const SignMessage *msg) { CHECK_INITIALIZED - layoutSignMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); - layoutHome(); - return; - } - CHECK_PIN const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name); @@ -271,23 +264,38 @@ void fsm_msgSignMessage(const SignMessage *msg) { msg->address_n_count, NULL); if (!node) return; - layoutProgressSwipe(_("Signing"), 0); - if (cryptoMessageSign(coin, node, msg->script_type, msg->message.bytes, - msg->message.size, resp->signature.bytes) == 0) { - if (hdnode_fill_public_key(node) != 0) { - fsm_sendFailure(FailureType_Failure_ProcessError, - _("Failed to derive public key")); - layoutHome(); - return; - } + if (hdnode_fill_public_key(node) != 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, + _("Failed to derive public key")); + layoutHome(); + return; + } - if (!compute_address(coin, msg->script_type, node, false, NULL, - resp->address)) { - fsm_sendFailure(FailureType_Failure_ProcessError, - _("Error computing address")); - layoutHome(); - return; - } + if (!compute_address(coin, msg->script_type, node, false, NULL, + resp->address)) { + fsm_sendFailure(FailureType_Failure_ProcessError, + _("Error computing address")); + layoutHome(); + return; + } + + layoutVerifyAddress(coin, resp->address); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + if (!fsm_layoutSignMessage(msg->message.bytes, msg->message.size)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + layoutProgressSwipe(_("Signing"), 0); + if (cryptoMessageSign(coin, node, msg->script_type, msg->no_script_type, + msg->message.bytes, msg->message.size, + resp->signature.bytes) == 0) { resp->signature.size = 65; msg_write(MessageType_MessageType_MessageSignature, resp); } else { @@ -310,12 +318,13 @@ void fsm_msgVerifyMessage(const VerifyMessage *msg) { layoutHome(); return; } - layoutVerifyMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + + if (!fsm_layoutVerifyMessage(msg->message.bytes, msg->message.size)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); layoutHome(); return; } + fsm_sendSuccess(_("Message verified")); } else { fsm_sendFailure(FailureType_Failure_DataError, _("Invalid signature")); diff --git a/legacy/firmware/fsm_msg_crypto.h b/legacy/firmware/fsm_msg_crypto.h index dcf933cfbea..da9e76cd4c7 100644 --- a/legacy/firmware/fsm_msg_crypto.h +++ b/legacy/firmware/fsm_msg_crypto.h @@ -135,7 +135,7 @@ void fsm_msgSignIdentity(const SignIdentity *msg) { sha256_Raw((const uint8_t *)msg->challenge_visual, strlen(msg->challenge_visual), digest + 32); result = cryptoMessageSign(&(coins[0]), node, InputScriptType_SPENDADDRESS, - digest, 64, resp->signature.bytes); + false, digest, 64, resp->signature.bytes); } if (result == 0) { diff --git a/legacy/firmware/fsm_msg_ethereum.h b/legacy/firmware/fsm_msg_ethereum.h index fb503217785..e95637de821 100644 --- a/legacy/firmware/fsm_msg_ethereum.h +++ b/legacy/firmware/fsm_msg_ethereum.h @@ -150,19 +150,35 @@ void fsm_msgEthereumSignMessage(const EthereumSignMessage *msg) { CHECK_INITIALIZED - layoutSignMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); - layoutHome(); - return; - } - CHECK_PIN const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count, NULL); if (!node) return; + uint8_t pubkeyhash[20] = {0}; + if (!hdnode_get_ethereum_pubkeyhash(node, pubkeyhash)) { + return; + } + + resp->address[0] = '0'; + resp->address[1] = 'x'; + ethereum_address_checksum(pubkeyhash, resp->address + 2, false, 0); + // ethereum_address_checksum adds trailing zero + + layoutVerifyAddress(NULL, resp->address); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + if (!fsm_layoutSignMessage(msg->message.bytes, msg->message.size)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + ethereum_message_sign(msg, node, resp); layoutHome(); } @@ -185,12 +201,13 @@ void fsm_msgEthereumVerifyMessage(const EthereumVerifyMessage *msg) { layoutHome(); return; } - layoutVerifyMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + + if (!fsm_layoutVerifyMessage(msg->message.bytes, msg->message.size)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); layoutHome(); return; } + fsm_sendSuccess(_("Message verified")); layoutHome(); diff --git a/legacy/firmware/layout2.c b/legacy/firmware/layout2.c index 708fd59cdcc..0994ce86059 100644 --- a/legacy/firmware/layout2.c +++ b/legacy/firmware/layout2.c @@ -189,18 +189,17 @@ const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen) { if (rowlen > 32) { rowlen = 32; } + memzero(str, sizeof(str)); - strlcpy(str[0], (char *)msg, rowlen + 1); - if (len > rowlen) { - strlcpy(str[1], (char *)msg + rowlen, rowlen + 1); - } - if (len > rowlen * 2) { - strlcpy(str[2], (char *)msg + rowlen * 2, rowlen + 1); + for (int i = 0; i < 4; ++i) { + size_t show_len = strnlen((char *)msg, MIN(rowlen, len)); + memcpy(str[i], (char *)msg, show_len); + str[i][show_len] = '\0'; + msg += show_len; + len -= show_len; } - if (len > rowlen * 3) { - strlcpy(str[3], (char *)msg + rowlen * 3, rowlen + 1); - } - if (len > rowlen * 4) { + + if (len > 0) { str[3][rowlen - 1] = '.'; str[3][rowlen - 2] = '.'; str[3][rowlen - 3] = '.'; @@ -230,10 +229,19 @@ void layoutDialogSwipe(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6) { + layoutDialogSwipeEx(icon, btnNo, btnYes, desc, line1, line2, line3, line4, + line5, line6, FONT_STANDARD); +} + +void layoutDialogSwipeEx(const BITMAP *icon, const char *btnNo, + const char *btnYes, const char *desc, + const char *line1, const char *line2, + const char *line3, const char *line4, + const char *line5, const char *line6, uint8_t font) { layoutLast = layoutDialogSwipe; layoutSwipe(); - layoutDialog(icon, btnNo, btnYes, desc, line1, line2, line3, line4, line5, - line6); + layoutDialogEx(icon, btnNo, btnYes, desc, line1, line2, line3, line4, line5, + line6, font); } void layoutProgressSwipe(const char *desc, int permil) { @@ -445,7 +453,7 @@ void layoutConfirmOmni(const uint8_t *data, uint32_t size) { NULL); } -static bool is_valid_ascii(const uint8_t *data, uint32_t size) { +bool is_valid_ascii(const uint8_t *data, uint32_t size) { for (uint32_t i = 0; i < size; i++) { if (data[i] < ' ' || data[i] > '~') { return false; @@ -603,36 +611,6 @@ void layoutConfirmNondefaultLockTime(uint32_t lock_time, } } -void layoutSignMessage(const uint8_t *msg, uint32_t len) { - const char **str = NULL; - if (!is_valid_ascii(msg, len)) { - str = split_message_hex(msg, len); - layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), - _("Sign binary message?"), str[0], str[1], str[2], str[3], - NULL, NULL); - } else { - str = split_message(msg, len, 20); - layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), - _("Sign message?"), str[0], str[1], str[2], str[3], NULL, - NULL); - } -} - -void layoutVerifyMessage(const uint8_t *msg, uint32_t len) { - const char **str = NULL; - if (!is_valid_ascii(msg, len)) { - str = split_message_hex(msg, len); - layoutDialogSwipe(&bmp_icon_info, _("Cancel"), _("Confirm"), - _("Verified binary message"), str[0], str[1], str[2], - str[3], NULL, NULL); - } else { - str = split_message(msg, len, 20); - layoutDialogSwipe(&bmp_icon_info, _("Cancel"), _("Confirm"), - _("Verified message"), str[0], str[1], str[2], str[3], - NULL, NULL); - } -} - void layoutVerifyAddress(const CoinInfo *coin, const char *address) { render_address_dialog(coin, address, _("Confirm address?"), _("Message signed by:"), 0); diff --git a/legacy/firmware/layout2.h b/legacy/firmware/layout2.h index 52427b7647a..6c286925869 100644 --- a/legacy/firmware/layout2.h +++ b/legacy/firmware/layout2.h @@ -43,6 +43,11 @@ void layoutDialogSwipe(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6); +void layoutDialogSwipeEx(const BITMAP *icon, const char *btnNo, + const char *btnYes, const char *desc, + const char *line1, const char *line2, + const char *line3, const char *line4, + const char *line5, const char *line6, uint8_t font); void layoutProgressSwipe(const char *desc, int permil); void layoutScreensaver(void); @@ -65,9 +70,7 @@ void layoutFeeOverThreshold(const CoinInfo *coin, AmountUnit amount_unit, void layoutChangeCountOverThreshold(uint32_t change_count); void layoutConfirmNondefaultLockTime(uint32_t lock_time, bool lock_time_disabled); -void layoutSignMessage(const uint8_t *msg, uint32_t len); void layoutVerifyAddress(const CoinInfo *coin, const char *address); -void layoutVerifyMessage(const uint8_t *msg, uint32_t len); void layoutCipherKeyValue(bool encrypt, const char *key); void layoutEncryptMessage(const uint8_t *msg, uint32_t len, bool signing); void layoutDecryptMessage(const uint8_t *msg, uint32_t len, @@ -110,4 +113,6 @@ void layoutConfirmSafetyChecks(SafetyCheckLevel safety_checks_level); const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen); const char **split_message_hex(const uint8_t *msg, uint32_t len); +bool is_valid_ascii(const uint8_t *data, uint32_t size); + #endif diff --git a/legacy/layout.c b/legacy/layout.c index 51c8bfefb2c..02fcb91a895 100644 --- a/legacy/layout.c +++ b/legacy/layout.c @@ -51,16 +51,24 @@ void layoutDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6) { + layoutDialogEx(icon, btnNo, btnYes, desc, line1, line2, line3, line4, line5, + line6, FONT_STANDARD); +} + +void layoutDialogEx(const BITMAP *icon, const char *btnNo, const char *btnYes, + const char *desc, const char *line1, const char *line2, + const char *line3, const char *line4, const char *line5, + const char *line6, uint8_t font) { int left = 0; oledClear(); if (icon) { oledDrawBitmap(0, 0, icon); left = icon->width + 4; } - if (line1) oledDrawString(left, 0 * 9, line1, FONT_STANDARD); - if (line2) oledDrawString(left, 1 * 9, line2, FONT_STANDARD); - if (line3) oledDrawString(left, 2 * 9, line3, FONT_STANDARD); - if (line4) oledDrawString(left, 3 * 9, line4, FONT_STANDARD); + if (line1) oledDrawString(left, 0 * 9, line1, font); + if (line2) oledDrawString(left, 1 * 9, line2, font); + if (line3) oledDrawString(left, 2 * 9, line3, font); + if (line4) oledDrawString(left, 3 * 9, line4, font); if (desc) { oledDrawStringCenter(OLED_WIDTH / 2, OLED_HEIGHT - 2 * 9 - 1, desc, FONT_STANDARD); @@ -68,8 +76,8 @@ void layoutDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, oledHLine(OLED_HEIGHT - 21); } } else { - if (line5) oledDrawString(left, 4 * 9, line5, FONT_STANDARD); - if (line6) oledDrawString(left, 5 * 9, line6, FONT_STANDARD); + if (line5) oledDrawString(left, 4 * 9, line5, font); + if (line6) oledDrawString(left, 5 * 9, line6, font); if (btnYes || btnNo) { oledHLine(OLED_HEIGHT - 13); } diff --git a/legacy/layout.h b/legacy/layout.h index 4b3f92acf53..bb6baa2fc1f 100644 --- a/legacy/layout.h +++ b/legacy/layout.h @@ -30,6 +30,10 @@ void layoutDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6); +void layoutDialogEx(const BITMAP *icon, const char *btnNo, const char *btnYes, + const char *desc, const char *line1, const char *line2, + const char *line3, const char *line4, const char *line5, + const char *line6, uint8_t font); void layoutProgressUpdate(bool refresh); void layoutProgress(const char *desc, int permil); diff --git a/python/.changelog.d/1586.added b/python/.changelog.d/1586.added new file mode 100644 index 00000000000..b740dbe152e --- /dev/null +++ b/python/.changelog.d/1586.added @@ -0,0 +1 @@ +Support no_script_type option in SignMessage. diff --git a/python/src/trezorlib/btc.py b/python/src/trezorlib/btc.py index 8b65d3fc005..de73a3c635a 100644 --- a/python/src/trezorlib/btc.py +++ b/python/src/trezorlib/btc.py @@ -156,12 +156,21 @@ def get_ownership_proof( @expect(messages.MessageSignature) def sign_message( - client, coin_name, n, message, script_type=messages.InputScriptType.SPENDADDRESS + client, + coin_name, + n, + message, + script_type=messages.InputScriptType.SPENDADDRESS, + no_script_type=False, ): message = normalize_nfc(message) return client.call( messages.SignMessage( - coin_name=coin_name, address_n=n, message=message, script_type=script_type + coin_name=coin_name, + address_n=n, + message=message, + script_type=script_type, + no_script_type=no_script_type, ) ) diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index d933a508f00..e8f24869ea8 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -1067,6 +1067,7 @@ class SignMessage(protobuf.MessageType): 2: protobuf.Field("message", "bytes", repeated=False, required=True), 3: protobuf.Field("coin_name", "string", repeated=False, required=False), 4: protobuf.Field("script_type", "InputScriptType", repeated=False, required=False), + 5: protobuf.Field("no_script_type", "bool", repeated=False, required=False), } def __init__( @@ -1076,11 +1077,13 @@ def __init__( address_n: Optional[List["int"]] = None, coin_name: Optional["str"] = 'Bitcoin', script_type: Optional["InputScriptType"] = InputScriptType.SPENDADDRESS, + no_script_type: Optional["bool"] = None, ) -> None: self.address_n = address_n if address_n is not None else [] self.message = message self.coin_name = coin_name self.script_type = script_type + self.no_script_type = no_script_type class MessageSignature(protobuf.MessageType): diff --git a/tests/device_tests/test_cancel.py b/tests/device_tests/test_cancel.py index 8520f4a8cf8..8a5f7263990 100644 --- a/tests/device_tests/test_cancel.py +++ b/tests/device_tests/test_cancel.py @@ -84,6 +84,11 @@ def test_cancel_on_paginated(client): ) resp = client.call_raw(message) assert isinstance(resp, m.ButtonRequest) + client._raw_write(m.ButtonAck()) + client.debug.press_yes() + + resp = client._raw_read() + assert isinstance(resp, m.ButtonRequest) assert resp.pages is not None client._raw_write(m.ButtonAck()) diff --git a/tests/device_tests/test_msg_signmessage.py b/tests/device_tests/test_msg_signmessage.py index 87d818950d2..bb777293cfa 100644 --- a/tests/device_tests/test_msg_signmessage.py +++ b/tests/device_tests/test_msg_signmessage.py @@ -43,6 +43,7 @@ def case(id, *args, altcoin=False): "Bitcoin", "44h/0h/0h/0/0", S.SPENDADDRESS, + False, "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL", "This is an example of a signed message.", "20fd8f2f7db5238fcdd077d5204c3e6949c261d700269cefc1d9d2dcef6b95023630ee617f6c8acf9eb40c8edd704c9ca74ea4afc393f43f35b4e8958324cbdd1c", @@ -52,6 +53,7 @@ def case(id, *args, altcoin=False): "Bitcoin", "49h/0h/0h/0/0", S.SPENDP2SHWITNESS, + False, "3L6TyTisPBmrDAj6RoKmDzNnj4eQi54gD2", "This is an example of a signed message.", "23744de4516fac5c140808015664516a32fead94de89775cec7e24dbc24fe133075ac09301c4cc8e197bea4b6481661d5b8e9bf19d8b7b8a382ecdb53c2ee0750d", @@ -61,16 +63,48 @@ def case(id, *args, altcoin=False): "Bitcoin", "84h/0h/0h/0/0", S.SPENDWITNESS, + False, "bc1qannfxke2tfd4l7vhepehpvt05y83v3qsf6nfkk", "This is an example of a signed message.", "28b55d7600d9e9a7e2a49155ddf3cfdb8e796c207faab833010fa41fb7828889bc47cf62348a7aaa0923c0832a589fab541e8f12eb54fb711c90e2307f0f66b194", ), + case( + "p2pkh", + "Bitcoin", + "44h/0h/0h/0/0", + S.SPENDADDRESS, + True, + "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL", + "This is an example of a signed message.", + "20fd8f2f7db5238fcdd077d5204c3e6949c261d700269cefc1d9d2dcef6b95023630ee617f6c8acf9eb40c8edd704c9ca74ea4afc393f43f35b4e8958324cbdd1c", + ), + case( + "segwit-p2sh", + "Bitcoin", + "49h/0h/0h/0/0", + S.SPENDP2SHWITNESS, + True, + "3L6TyTisPBmrDAj6RoKmDzNnj4eQi54gD2", + "This is an example of a signed message.", + "1f744de4516fac5c140808015664516a32fead94de89775cec7e24dbc24fe133075ac09301c4cc8e197bea4b6481661d5b8e9bf19d8b7b8a382ecdb53c2ee0750d", + ), + case( + "segwit-native", + "Bitcoin", + "84h/0h/0h/0/0", + S.SPENDWITNESS, + True, + "bc1qannfxke2tfd4l7vhepehpvt05y83v3qsf6nfkk", + "This is an example of a signed message.", + "20b55d7600d9e9a7e2a49155ddf3cfdb8e796c207faab833010fa41fb7828889bc47cf62348a7aaa0923c0832a589fab541e8f12eb54fb711c90e2307f0f66b194", + ), # ==== Bitcoin with long message ==== case( "p2pkh long message", "Bitcoin", "44h/0h/0h/0/0", S.SPENDADDRESS, + False, "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL", "VeryLongMessage!" * 64, "200a46476ceb84d06ef5784828026f922c8815f57aac837b8c013007ca8a8460db63ef917dbebaebd108b1c814bbeea6db1f2b2241a958e53fe715cc86b199d9c3", @@ -80,6 +114,7 @@ def case(id, *args, altcoin=False): "Bitcoin", "49h/0h/0h/0/0", S.SPENDP2SHWITNESS, + False, "3L6TyTisPBmrDAj6RoKmDzNnj4eQi54gD2", "VeryLongMessage!" * 64, "236eadee380684f70749c52141c8aa7c3b6afd84d0e5f38cfa71823f3b1105a5f34e23834a5bb6f239ff28ad87f409f44e4ce6269754adc00388b19507a5d9386f", @@ -89,6 +124,7 @@ def case(id, *args, altcoin=False): "Bitcoin", "84h/0h/0h/0/0", S.SPENDWITNESS, + False, "bc1qannfxke2tfd4l7vhepehpvt05y83v3qsf6nfkk", "VeryLongMessage!" * 64, "28c6f86e255eaa768c447d635d91da01631ac54af223c2c182d4fa3676cfecae4a199ad33a74fe04fb46c39432acb8d83de74da90f5f01123b3b7d8bc252bc7f71", @@ -99,6 +135,7 @@ def case(id, *args, altcoin=False): "Bitcoin", "44h/0h/0h/0/1", S.SPENDADDRESS, + False, "1GWFxtwWmNVqotUPXLcKVL2mUKpshuJYo", MESSAGE_NFKD, NFKD_NFC_SIGNATURE, @@ -108,6 +145,7 @@ def case(id, *args, altcoin=False): "Bitcoin", "44h/0h/0h/0/1", S.SPENDADDRESS, + False, "1GWFxtwWmNVqotUPXLcKVL2mUKpshuJYo", MESSAGE_NFC, NFKD_NFC_SIGNATURE, @@ -118,6 +156,7 @@ def case(id, *args, altcoin=False): "Testnet", "44h/1h/0h/0/0", S.SPENDADDRESS, + False, "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q", "This is an example of a signed message.", "2030cd7f116c0481d1936cfef48137fd23ee56aaf00787bfa08a94837466ec9909390c3efacfc56bae5782f1db4cf49ae05f242b5f62a47f871ec46bf1a3253e7f", @@ -127,6 +166,7 @@ def case(id, *args, altcoin=False): "Testnet", "49h/1h/0h/0/0", S.SPENDP2SHWITNESS, + False, "2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp", "This is an example of a signed message.", "23ef39fd388c3425d6aaa04274dcd5c7dd4c283a411b616443474fbcde5dd966050d91bc7c57e9578f28efdd84c9a9bcba415f93c5727b5d3f2bf3de46d7084896", @@ -136,6 +176,7 @@ def case(id, *args, altcoin=False): "Testnet", "84h/1h/0h/0/0", S.SPENDWITNESS, + False, "tb1qkvwu9g3k2pdxewfqr7syz89r3gj557l3uuf9r9", "This is an example of a signed message.", "27758b3393396ad9fe48f6ce81f63410145e7b2b69a5dfc1d48b5e6e623e91e08e3afb60bda1546f9c6f9fb5bd0a41887b784c266036dd4b4015a0abc1137daa1d", @@ -146,6 +187,7 @@ def case(id, *args, altcoin=False): "Bcash", "44h/145h/0h/0/0", S.SPENDADDRESS, + False, "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv", "This is an example of a signed message.", "1fda7733e666a4ab8ba86f3cfc3728d318ecf824a3bf99597570297aa131607c10316959136b2c500b2b478a73c563ba314c0b7b2a22065b6d9596118f246d360e", @@ -156,6 +198,7 @@ def case(id, *args, altcoin=False): "Groestlcoin", "44h/17h/0h/0/0", S.SPENDADDRESS, + False, "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM", "test", "20d39869afe38fc631cf7983e64f9b65f5268e48c1f55ce857874d1bbf91b015322b7d312fb23dc8c816595bec2f8e82e7242dc6d658d1c45193babd37a6fe6133", @@ -166,6 +209,7 @@ def case(id, *args, altcoin=False): "Groestlcoin", "49h/17h/0h/0/0", S.SPENDP2SHWITNESS, + False, "31inaRqambLsd9D7Ke4USZmGEVd3PHkh7P", "test", "23f340fc9f9ea6469e13dbc743b70313e4d076bcd8ce867eddd71ec41160d02a4a462205d21ec6e49502bf3e2a8463d48e895ca56f6b385b15ec2cc7556292ecae", @@ -176,6 +220,7 @@ def case(id, *args, altcoin=False): "Groestlcoin", "84h/17h/0h/0/0", S.SPENDWITNESS, + False, "grs1qw4teyraux2s77nhjdwh9ar8rl9dt7zww8r6lne", "test", "288253db4b4a1d5dac059296385310a353ef80992c4777a44133a335d12d3444da6c287d32aec4071ec49ae327e208f89ba0a115a129f106221c8dd5590fd3df13", @@ -186,6 +231,7 @@ def case(id, *args, altcoin=False): "Decred", "44h/42h/0h/0/0", S.SPENDADDRESS, + False, "DsZtHtXHwvNR3nWf1PqfxrEdnRJisKEyzp1", "This is an example of a signed message.", "206b1f8ba47ef9eaf87aa900e41ab1e97f67e8c09292faa4acf825228d074c4b774484046dcb1d9bbf0603045dbfb328c3e1b0c09c5ae133e89e604a67a1fc6cca", @@ -196,6 +242,7 @@ def case(id, *args, altcoin=False): "Decred", "44h/42h/0h/0/0", S.SPENDADDRESS, + False, "DsZtHtXHwvNR3nWf1PqfxrEdnRJisKEyzp1", "", "1fd2d57490b44a0361c7809768cad032d41ba1d4b7a297f935fc65ae05f71de7ea0c6c6fd265cc5154f1fa4acd7006b6a00ddd67fb7333c1594aff9120b3ba8024", @@ -205,14 +252,17 @@ def case(id, *args, altcoin=False): @pytest.mark.parametrize( - "coin_name, path, script_type, address, message, signature", VECTORS + "coin_name, path, script_type, no_script_type, address, message, signature", VECTORS ) -def test_signmessage(client, coin_name, path, script_type, address, message, signature): +def test_signmessage( + client, coin_name, path, script_type, no_script_type, address, message, signature +): sig = btc.sign_message( client, coin_name=coin_name, n=parse_path(path), script_type=script_type, + no_script_type=no_script_type, message=message, ) assert sig.address == address @@ -240,6 +290,11 @@ def input_flow(): # Join lines that are separated by a single "-" string, space-separate lines otherwise. nonlocal message_read + # confirm address + br = yield + layout = client.debug.wait_layout() + client.debug.press_yes() + # start assuming there was a word break; this avoids prepending space at start word_break = True br = yield @@ -271,17 +326,19 @@ def input_flow(): n=parse_path("m/44h/0h/0h/0/0"), message=message, ) - assert message.replace("\n", " ") == message_read + assert "Confirm message: " + message.replace("\n", " ") == message_read @pytest.mark.skip_t1 def test_signmessage_pagination_trailing_newline(client): - message = "THIS\nMUST\nNOT\nBE\nPAGINATED\n" + message = "THIS\nMUST NOT\nBE\nPAGINATED\n" # The trailing newline must not cause a new paginated screen to appear. # The UI must be a single dialog without pagination. with client: client.set_expected_responses( [ + # expect address confirmation + message_filters.ButtonRequest(code=messages.ButtonRequestType.Other), # expect a ButtonRequest that does not have pagination set message_filters.ButtonRequest(pages=None), messages.MessageSignature, diff --git a/tests/device_tests/test_protection_levels.py b/tests/device_tests/test_protection_levels.py index b9085123d7f..9e0457750af 100644 --- a/tests/device_tests/test_protection_levels.py +++ b/tests/device_tests/test_protection_levels.py @@ -273,26 +273,7 @@ def test_recovery_device(client): ) -@pytest.mark.skip_t2 -def test_sign_message_t1(client): - _assert_protection(client) - with client: - client.use_pin_sequence([PIN4]) - client.set_expected_responses( - [ - messages.ButtonRequest, - _pin_request(client), - messages.PassphraseRequest, - messages.MessageSignature, - ] - ) - btc.sign_message( - client, "Bitcoin", parse_path("44h/0h/0h/0/0"), "testing message" - ) - - -@pytest.mark.skip_t1 -def test_sign_message_t2(client): +def test_sign_message(client): _assert_protection(client) with client: client.use_pin_sequence([PIN4]) @@ -301,6 +282,7 @@ def test_sign_message_t2(client): _pin_request(client), messages.PassphraseRequest, messages.ButtonRequest, + messages.ButtonRequest, messages.MessageSignature, ] ) diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index f0c6477ad94..1fb811facb8 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -209,23 +209,23 @@ "ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[struct_list_v4]": "b7e3475d4906942bc0e8d62203ae91a13ea0d702c3a7a53b9777bea670c4a7f7", "ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_cancel": "08712efae2d007610289bbfb3a8fe6800547e884636c83c5bf0e25f33728789e", "ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_show_more_button": "1adbea797586685ce09aae58b0a2b89e1617e4eaad23a8c1ac6fc10b041e57a5", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters0-result0]": "9e2383084cfa23440e7ff9cf95029c73b851f5732de0cb4fb5e89a0ee024fbed", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters1-result1]": "bd669f3ddc72582d3af7aa2e9757e68008690b78533f40eafacf0d071734c108", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters2-result2]": "6ccc6102d1289bce13e28ec2207c96abe4aa1ac0810a13181a874070e7bcf8f3", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters3-result3]": "83a4f41c4ac8b6c1fd8ac930cfd510d233cbdcfb5bf950a92a77211105154202", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters4-result4]": "cf30fc10cf7b3843d923b6c57e632e54e996a87f36caa87411a983eb31206d5a", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters5-result5]": "67a3e0391c12c24e51d838bc100602e678503bad4972f1218f336fe7264de6f9", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters6-result6]": "d7092b022ee0d523e6fd9d81d64e5e8b438b1926248e3bc178d9834a3eb00bca", -"ethereum-test_sign_verify_message.py::test_signmessage[parameters7-result7]": "5c4d93b80d19a92662655dc2e5e5196869ed431dd5ce5a94230885396c396fdd", -"ethereum-test_sign_verify_message.py::test_verify[parameters0-result0]": "7e83f210ce98fee92e34bcc95d311701ec79702f8430239921efa72ff7759af6", -"ethereum-test_sign_verify_message.py::test_verify[parameters1-result1]": "6695a0f1762c5b2b591d3b11df5e94ccafd9b7690fcb7a4eb86eeb993e935900", -"ethereum-test_sign_verify_message.py::test_verify[parameters2-result2]": "13cdad44a69c985c7680f2e963edd151f382a0895fb7d5f2767da21d953c292d", -"ethereum-test_sign_verify_message.py::test_verify[parameters3-result3]": "aafb7c1fabbf46436848a192c80207cc151c9422be510aebbd5feac500151c2f", -"ethereum-test_sign_verify_message.py::test_verify[parameters4-result4]": "fa639fabbd3cf543736d88384ad0522f2546a2ee576232b608e80c207d75569f", -"ethereum-test_sign_verify_message.py::test_verify[parameters5-result5]": "3abbabc6ed8aa2a95d2a5a0a3fcf21010911a8f79d653cc67f1c63e5f8da72bf", -"ethereum-test_sign_verify_message.py::test_verify[parameters6-result6]": "3a8312fc9f26f2bdf6569d44b4c6f103ea6300da84d4353678ec9a66b42aa05d", -"ethereum-test_sign_verify_message.py::test_verify[parameters7-result7]": "8fb2aeb728da4fb973a8cf058d975a78214c3aea7cf09280155fb167077f8951", -"ethereum-test_sign_verify_message.py::test_verify_invalid": "7e83f210ce98fee92e34bcc95d311701ec79702f8430239921efa72ff7759af6", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters0-result0]": "7aa14b29e5005d8fdc0a8b497ed5d3ebea15c7017f9c457d09214f2d05fbc532", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters1-result1]": "c5fb9393267c3d9b9bf5839aab6c641d3931286411f291cd1d8e937cb224ae2d", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters2-result2]": "8499b87474becc06010e9b4356398a3e29ee2ef152e04653f15dcc227fc486d6", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters3-result3]": "19357e0a59d6cac9af69fe7099360e6789e3a25b646075bbcf4afd542a7edaa7", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters4-result4]": "a3f8ac9d46ddd57ac4172606f69e8ef5e0005be17a04e5fda0b91fef8727d1c1", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters5-result5]": "f37e3cbb718493c0abe9ec76c297594e1ac87253b46273cca74fa498ca7f2703", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters6-result6]": "f6a32113e2edbd33648a8fda20e2cf8c7cfff53d3cf765ff2b945990733a696e", +"ethereum-test_sign_verify_message.py::test_signmessage[parameters7-result7]": "5127f94dd3eec514faec78eedfb22151eef1fd787ea26b4da718a85adb4f8523", +"ethereum-test_sign_verify_message.py::test_verify[parameters0-result0]": "10ec761b50bf9557aac79d885b4dbc64f57b8367e66838f169c86fcbeaba9b50", +"ethereum-test_sign_verify_message.py::test_verify[parameters1-result1]": "1dfc74e93def641c35c7670ffdefc23f9fb0ab6c10e1c208e1c00817f071028c", +"ethereum-test_sign_verify_message.py::test_verify[parameters2-result2]": "2fd7c36a17e41a9a55e92431e3040f569534153d8c2f51e77fc212da283fa0c3", +"ethereum-test_sign_verify_message.py::test_verify[parameters3-result3]": "748d7b99b54d47128ec15291caa7369d0044e629ca294e4560c3a9a092188ca0", +"ethereum-test_sign_verify_message.py::test_verify[parameters4-result4]": "771052d14c6f55be5e054c365b41f83d86e7e8cd02331258c0dba4288253818a", +"ethereum-test_sign_verify_message.py::test_verify[parameters5-result5]": "8cf46785319de4cb4e8112878db17e483e05814479637138dc2b005c8c873fa4", +"ethereum-test_sign_verify_message.py::test_verify[parameters6-result6]": "53034f00e1cbe4bdd3a1ec7bb190ff19c3f913e39cdbb26a2ea1bf7c4d89e09c", +"ethereum-test_sign_verify_message.py::test_verify[parameters7-result7]": "328fd3be37dc09ec3716557d4b70eda5a7cf3f7852e52c5a07950aec9cae80a4", +"ethereum-test_sign_verify_message.py::test_verify_invalid": "10ec761b50bf9557aac79d885b4dbc64f57b8367e66838f169c86fcbeaba9b50", "ethereum-test_signtx.py::test_data_streaming": "e0e6179a08c7a96958814d95ddfe09996a96aefeec3f538acfa58844c664d90f", "ethereum-test_signtx.py::test_sanity_checks": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "ethereum-test_signtx.py::test_sanity_checks_eip1559": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", @@ -282,7 +282,7 @@ "test_cancel.py::test_cancel_message_via_cancel[message1]": "b014449cbf1a45739d64a370b30af75df2228f48c090a02227bac8ed20c7b2dc", "test_cancel.py::test_cancel_message_via_initialize[message0]": "b014449cbf1a45739d64a370b30af75df2228f48c090a02227bac8ed20c7b2dc", "test_cancel.py::test_cancel_message_via_initialize[message1]": "b014449cbf1a45739d64a370b30af75df2228f48c090a02227bac8ed20c7b2dc", -"test_cancel.py::test_cancel_on_paginated": "b014449cbf1a45739d64a370b30af75df2228f48c090a02227bac8ed20c7b2dc", +"test_cancel.py::test_cancel_on_paginated": "6b8a80b8e81a14c0183805fac48a36f9cc61daa290d04d295032ab76ec83300f", "test_debuglink.py::test_softlock_instability": "9750df55cb4716f1d497d57de57257a0c5188fb652fcdb66a9d436d9c396c62b", "test_descriptors.py::test_descriptors[Bitcoin-0-InputScriptType.SPENDADDRESS-pkh([5c9e228d--320142b4": "24290396b20f26b49204a5551676d6f3c831009e30582d92d5b44fcc3c12fdb7", "test_descriptors.py::test_descriptors[Bitcoin-0-InputScriptType.SPENDP2SHWITNESS-sh(wpkh([5-b24e2107": "8977c539f5680a5196ad0a4c6e16c44ca1bbdb79235dbf97e33aad8d47fe5d0c", @@ -537,31 +537,34 @@ "test_msg_sd_protect.py::test_refresh": "19d6d1a7bfa9a6dcf7da2c320d01ba03152d08faa08a11ea2b3dc28ad57b1b91", "test_msg_sd_protect.py::test_wipe": "9e4b9968e7967e93f19d669acadd53c128a857b72afd7e354a1a350274b8aeba", "test_msg_signidentity.py-test_sign": "60cec9c50d0456731be185a29f8b06f7dfc8a2fff16db21e7b619a4078543f0f", -"test_msg_signmessage.py::test_signmessage[NFC message]": "fa2675d3a42768493a69a9d30bedec48eec3927c7cceef6b79a997bf5fec6057", -"test_msg_signmessage.py::test_signmessage[NFKD message]": "fa2675d3a42768493a69a9d30bedec48eec3927c7cceef6b79a997bf5fec6057", -"test_msg_signmessage.py::test_signmessage[bcash]": "78d23d6c96abf9992211e59283bd9232d014608974cf95630f7e51cf89e0cb93", -"test_msg_signmessage.py::test_signmessage[decred-empty]": "9c7cfd0146cf4b3215683c2a5d3548b4211485aad1dcbc52f2457f648ae569f6", -"test_msg_signmessage.py::test_signmessage[decred]": "bf26a48caf51c59fd377806ce7e26964a10980f4ad3fefbe252613e543ac4dc8", -"test_msg_signmessage.py::test_signmessage[grs-p2pkh]": "c97bf391b6625b818c5ece666fefa54536bbc063d63397f352b478197650be41", -"test_msg_signmessage.py::test_signmessage[grs-segwit-native]": "c97bf391b6625b818c5ece666fefa54536bbc063d63397f352b478197650be41", -"test_msg_signmessage.py::test_signmessage[grs-segwit-p2sh]": "c97bf391b6625b818c5ece666fefa54536bbc063d63397f352b478197650be41", -"test_msg_signmessage.py::test_signmessage[p2pkh long message]": "d289a26ee93d2a97370c6d93597463ee8625e90532338696ab3e858be2dea3c7", -"test_msg_signmessage.py::test_signmessage[p2pkh0]": "d16c46e129097121171e14acc28247058f502b8240380cc909e5ce3fdb948e44", -"test_msg_signmessage.py::test_signmessage[p2pkh1]": "542e21113b386389f1fd1cfc632eb2847e946cdf44d5ca759edf6082b5e1712b", -"test_msg_signmessage.py::test_signmessage[segwit-native long message]": "d289a26ee93d2a97370c6d93597463ee8625e90532338696ab3e858be2dea3c7", -"test_msg_signmessage.py::test_signmessage[segwit-native0]": "d16c46e129097121171e14acc28247058f502b8240380cc909e5ce3fdb948e44", -"test_msg_signmessage.py::test_signmessage[segwit-native1]": "542e21113b386389f1fd1cfc632eb2847e946cdf44d5ca759edf6082b5e1712b", -"test_msg_signmessage.py::test_signmessage[segwit-p2sh long message]": "d289a26ee93d2a97370c6d93597463ee8625e90532338696ab3e858be2dea3c7", -"test_msg_signmessage.py::test_signmessage[segwit-p2sh0]": "d16c46e129097121171e14acc28247058f502b8240380cc909e5ce3fdb948e44", -"test_msg_signmessage.py::test_signmessage[segwit-p2sh1]": "542e21113b386389f1fd1cfc632eb2847e946cdf44d5ca759edf6082b5e1712b", -"test_msg_signmessage.py::test_signmessage_pagination[long_words]": "32b7822628c8652ae558a715390421cd2e29b707b58b60e012338eb9e3ff956b", -"test_msg_signmessage.py::test_signmessage_pagination[newlines]": "d54bdc38376cd70b658b189fcad3b0c58e88c23ebcba023420ff81b45329dea9", -"test_msg_signmessage.py::test_signmessage_pagination[no_spaces]": "af5eeda691036de08ffa76e0ce95901a76594736c6f7f90ad27362fd3acd0e70", -"test_msg_signmessage.py::test_signmessage_pagination[normal_text]": "78a1a9cd4efccc296ff606a9bad1b7490e290d3042643e1ac7d7025925cff368", -"test_msg_signmessage.py::test_signmessage_pagination[single_line_over]": "ecfaf919f71300f8c48e5bb548f14065aab65713323faba29a65c60539d0c115", -"test_msg_signmessage.py::test_signmessage_pagination[utf_nospace]": "2d9e03852e371de72d91b1fe8ed8349d81732ba636d509e9892450749f3a7a26", -"test_msg_signmessage.py::test_signmessage_pagination[utf_text]": "d417b11d5f2dd2118f67ef3c6798442ef082c0d44e468e4fc86554126da1053d", -"test_msg_signmessage.py::test_signmessage_pagination_trailing_newline": "f092598b69d0dbd79dc702f6fee19d3b3dfd8bc5b768d42940538addd50ee20f", +"test_msg_signmessage.py::test_signmessage[NFC message]": "4c41515a7f5fe9ffd5805ed060cb9e3ca8e578c92fefa79479df738ca1636235", +"test_msg_signmessage.py::test_signmessage[NFKD message]": "4c41515a7f5fe9ffd5805ed060cb9e3ca8e578c92fefa79479df738ca1636235", +"test_msg_signmessage.py::test_signmessage[bcash]": "096a2d5f0c75af22be673fd1550e86987a61bb348b0102eec4913fe9cc8fbcf7", +"test_msg_signmessage.py::test_signmessage[decred-empty]": "6ba13378ae58cc21e899764f521939b9446fd18581bbfec7f4a1438129e4c18b", +"test_msg_signmessage.py::test_signmessage[decred]": "992473cf8731a3ef5dabea09d88439aded159a537fce9e976b8923177eb73a77", +"test_msg_signmessage.py::test_signmessage[grs-p2pkh]": "74c8d5bf71dfc718e4e0225230b21a8c2976d8f7700023909d3827b71732a51b", +"test_msg_signmessage.py::test_signmessage[grs-segwit-native]": "f12f76355d0988213c1087b2bb1f77a7a125a4f0ea87ef6a8742c835f8b869f9", +"test_msg_signmessage.py::test_signmessage[grs-segwit-p2sh]": "f4986d7c9c353c3d5fefac9b9800bf577d8cc45b9f2df7b11e984274290e10ff", +"test_msg_signmessage.py::test_signmessage[p2pkh long message]": "458a09cc5a36df6e6ebf9f26b349008c536549b32ced686a9a5730afa6d7c046", +"test_msg_signmessage.py::test_signmessage[p2pkh0]": "aafdfaea9121deb76494339d07df0c306c6cc529c265926a45a1b8734b290b7a", +"test_msg_signmessage.py::test_signmessage[p2pkh1]": "aafdfaea9121deb76494339d07df0c306c6cc529c265926a45a1b8734b290b7a", +"test_msg_signmessage.py::test_signmessage[p2pkh2]": "790387a4949fce238116732fc91d317cff51736fc34faae91e4739376a9754dd", +"test_msg_signmessage.py::test_signmessage[segwit-native long message]": "171b18768d897b3fd80d8667ae70fe7bdbc2c48bbb602d33be1aeff27e58de26", +"test_msg_signmessage.py::test_signmessage[segwit-native0]": "8ec78e680c7881afc9e0d67398975d9ec0e8c930f77c33abb70a648ae3a65630", +"test_msg_signmessage.py::test_signmessage[segwit-native1]": "8ec78e680c7881afc9e0d67398975d9ec0e8c930f77c33abb70a648ae3a65630", +"test_msg_signmessage.py::test_signmessage[segwit-native2]": "22cbc418d6b71a6294fadec30b0fc867af6d33c5c4064ce9fa3947ce30004976", +"test_msg_signmessage.py::test_signmessage[segwit-p2sh long message]": "1148f799b7251e8b80b1d542a58285eed7e735183144870e562835b0cc43360b", +"test_msg_signmessage.py::test_signmessage[segwit-p2sh0]": "324709c25d73c33379c80524a48cfc396890095fd78fb68f733a897aec9acd57", +"test_msg_signmessage.py::test_signmessage[segwit-p2sh1]": "324709c25d73c33379c80524a48cfc396890095fd78fb68f733a897aec9acd57", +"test_msg_signmessage.py::test_signmessage[segwit-p2sh2]": "1a26c0061ea5780c87b91e40dcb84ce23b25359c980bc52a6316a62774f20dfb", +"test_msg_signmessage.py::test_signmessage_pagination[long_words]": "8d413ae4f9b1d11bf213d23f949bce5b24bfb2267bea1e0c037b7b25a2164ae3", +"test_msg_signmessage.py::test_signmessage_pagination[newlines]": "ce6b27448dfdadc90d864a5733ffd3d864ce853c07f67eb443acb30b67adffed", +"test_msg_signmessage.py::test_signmessage_pagination[no_spaces]": "22abfcdac7583a5dd6c88af8801aec2ba1acee29197164e050a780478ac0998b", +"test_msg_signmessage.py::test_signmessage_pagination[normal_text]": "9e51a59dfd677cfaa1cd7de0c7fc43fb95c7143e8872b06dba45015e7a73298c", +"test_msg_signmessage.py::test_signmessage_pagination[single_line_over]": "3920f85a9833cc564b56c8810c41492c37e12d5029dcff7346ee36bc8133a99d", +"test_msg_signmessage.py::test_signmessage_pagination[utf_nospace]": "9a36cae6e21029e403b4f30ec88fc6da92ac8643b2c63ad7da7b7bc57ecc106b", +"test_msg_signmessage.py::test_signmessage_pagination[utf_text]": "4ac1d8e2491164d442b700ea65e430867d74a941ac0d0dc8d4f51f4494fd0bb0", +"test_msg_signmessage.py::test_signmessage_pagination_trailing_newline": "3ecd60468981b8c59cae21ae1189ad42b9d69b87e86c17e51b40185e31a5c52d", "test_msg_signtx.py-test_attack_change_input_address": "5f230e46301f0af85b5c40944cae1a8e4d3fc576fb19d7b7374decb463c8be62", "test_msg_signtx.py-test_attack_change_outputs": "2e8e05aa366da0ce2990a2b8b76f13973af8eaa11ec0cb5591412a9a5ba48da4", "test_msg_signtx.py-test_attack_modify_change_address": "72b96c639ac76ecccbe5d710a1c84eba6711879c329952b18ffab385ca79bafd", @@ -722,21 +725,21 @@ "test_msg_tezos_sign_tx.py-test_tezos_smart_contract_delegation": "a77ff1f39fa92ef310e3a69263a86cda7e01d18b22955f55e12f4ff3a33e0489", "test_msg_tezos_sign_tx.py-test_tezos_smart_contract_transfer": "f4c0775f55db8718ef56e684f376d5326afa4ee97b0ea85c42820a356ebff0d4", "test_msg_tezos_sign_tx.py-test_tezos_smart_contract_transfer_to_contract": "cadca03c9ce7db592663bc0224364c0d4bf99fcae60e0982b4a844ce629e500c", -"test_msg_verifymessage.py-test_message_grs": "e941c841a24c59587c4dcffa35cab4b37d4b2485497b6574d18d96f6853a8939", -"test_msg_verifymessage.py-test_message_long": "b3dfb293684ff4d6d61ea37cd18f39486d5c63e0bc7e40ba03c344e2ab92c85c", -"test_msg_verifymessage.py-test_message_testnet": "99f5553a7b7d746012c1b17989de910071e088f419632a5e76231b6c1b70f1c5", -"test_msg_verifymessage.py-test_message_verify": "43ff8a53d1c825446a3e29c1dde89608112a8c4a57d420f227ad42aba7d5e388", -"test_msg_verifymessage.py-test_message_verify_bcash": "20226a69debcc0fc1cc7ca6365ff6c346117b7871fa047cfa429c8699c30aea4", -"test_msg_verifymessage.py-test_verify_bitcoind": "26194cf36587b54a25251b36dafc33cd8ab243e820f30c8a13b5087a543b2f83", -"test_msg_verifymessage.py-test_verify_utf": "c803737c4ccf74484f67369edebb28cf1c5d960e0bdd7cc19e25383edb3bf608", -"test_msg_verifymessage_segwit.py-test_message_long": "3f16291f542a118abe21f69e7f191b649975814c9da92777acba95bea58b13a4", -"test_msg_verifymessage_segwit.py-test_message_testnet": "bedfb0ba558bfdf53aa21f05973a91d3ae9b82bb76ce8b6ffa69011301d0279a", -"test_msg_verifymessage_segwit.py-test_message_verify": "c0e4858996fe06fc14efd9640d2a22483c67f0cd79ce4f122dacd3b73e789071", -"test_msg_verifymessage_segwit.py-test_verify_utf": "2dcdff7a9b6bde6e97e5978e5bc81d611a99ee18a965e9c9e0280d35b84a1f08", -"test_msg_verifymessage_segwit_native.py-test_message_long": "76fbe665450c7675dd622446d5b7f1b0f1591e184ff24eff61ce88c7e4bd896a", -"test_msg_verifymessage_segwit_native.py-test_message_testnet": "28e0a91c31c6bdcee76b98064efe0097631bc77c3f59a263e71989bd66ccbc2e", -"test_msg_verifymessage_segwit_native.py-test_message_verify": "e4565794ed49fc946fb7b7c11737f400b6870458e55c79335e5725635bdb3006", -"test_msg_verifymessage_segwit_native.py-test_verify_utf": "d4e56561eca643eab79dfb7cc43c6d7fded5e5c3297e42aa018186a762823630", +"test_msg_verifymessage.py-test_message_grs": "a927ec214a2ac0a8e0d6d13bde6f20d9cf3847367bf48795dfe43d8b2402d40f", +"test_msg_verifymessage.py-test_message_long": "8dc8c73c4c91bdd98709585ed6df8ffc321845eb29a2e72b7bc6c13d90a42123", +"test_msg_verifymessage.py-test_message_testnet": "fc8de2115ecb5da834a4b8cf9444a98fc4af095e1f0d2c28e9904761ff25924c", +"test_msg_verifymessage.py-test_message_verify": "adc89f7a24565c2fb0cd00ba9b3fdf923268d70f2413df9afaf757a6d2da75c7", +"test_msg_verifymessage.py-test_message_verify_bcash": "a4b2355a8b7649515c67aee5a6a1438ecc94f4c772dc001e624a80f80f719cb7", +"test_msg_verifymessage.py-test_verify_bitcoind": "aa53ce95442a3c78e6a3f559237e1fce2e1c4eba124e32a374a8017ee7a35ab5", +"test_msg_verifymessage.py-test_verify_utf": "5a21d0ce4f5622001a6d54280c10424045a5b4a295dc943b7aa5509e15e3c1cb", +"test_msg_verifymessage_segwit.py-test_message_long": "5a6dbb32d55989eae02b6e6b69b1980172b17c100c3f61175ebd08d3425d8c8f", +"test_msg_verifymessage_segwit.py-test_message_testnet": "9b3605d74cf4787c3d22aa847e2a9009a6a49cd18fd704801b6592972fad09c9", +"test_msg_verifymessage_segwit.py-test_message_verify": "26b96652d888fb9ea63f1f6cdd8e55b81fdb22240952837364df1d56c403d24e", +"test_msg_verifymessage_segwit.py-test_verify_utf": "65509f8958bd561e7a35b33e82ebb74bceca54f4108c2ee10f04f4e491248204", +"test_msg_verifymessage_segwit_native.py-test_message_long": "3939f3b0c021f7116d5c9e34c0f7de7f8358a52af7a24fef27469ee0a62326d6", +"test_msg_verifymessage_segwit_native.py-test_message_testnet": "fafb5d434ce0c8df8b2913253cfc9a6458c83edcf103bfa44168d7911a16e83d", +"test_msg_verifymessage_segwit_native.py-test_message_verify": "b05637d691ee73f2178a85575335559512b038fa779c3476eebeec1f8ef4e63a", +"test_msg_verifymessage_segwit_native.py-test_verify_utf": "eb411fa9e3adfa39c7e801b1917babb7ff1f0a939172b907b686f4b3e5e44d04", "test_msg_webauthn.py::test_add_remove": "3219e5ad2719319e74b5c75b1096ca7e3d30467215c15f57e57e475afdaa188f", "test_msg_wipedevice.py::test_autolock_not_retained": "c18d2809f505e79bf61aef073a33897b251a3dadab7db9c890f5baaaa4412f4c", "test_msg_wipedevice.py::test_wipe_device": "365729fd052a9765fb68444b0ec0661037db712bf077d2e2126d6a4e892710bd", @@ -769,11 +772,11 @@ "test_nonstandard_paths.py::test_getpublicnode[m-3'-100'-4-255-script_types1]": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "test_nonstandard_paths.py::test_getpublicnode[m-4-255-script_types0]": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "test_nonstandard_paths.py::test_getpublicnode[m-49-0-63-0-255-script_types4]": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", -"test_nonstandard_paths.py::test_signmessage[m-1195487518-6-255-script_types3]": "31eaf6185c2ea572503638387fe115f95b4cde2f2019e107783c82e463550dd3", -"test_nonstandard_paths.py::test_signmessage[m-1195487518-script_types2]": "31eaf6185c2ea572503638387fe115f95b4cde2f2019e107783c82e463550dd3", -"test_nonstandard_paths.py::test_signmessage[m-3'-100'-4-255-script_types1]": "31eaf6185c2ea572503638387fe115f95b4cde2f2019e107783c82e463550dd3", -"test_nonstandard_paths.py::test_signmessage[m-4-255-script_types0]": "31eaf6185c2ea572503638387fe115f95b4cde2f2019e107783c82e463550dd3", -"test_nonstandard_paths.py::test_signmessage[m-49-0-63-0-255-script_types4]": "d16c46e129097121171e14acc28247058f502b8240380cc909e5ce3fdb948e44", +"test_nonstandard_paths.py::test_signmessage[m-1195487518-6-255-script_types3]": "da9682c495ea2cdc7513404ed533461de199d5abde5e2d269acb99c013debfb3", +"test_nonstandard_paths.py::test_signmessage[m-1195487518-script_types2]": "4a625dc911357f101240d0a39c8e7091a0f0ae684ff3796ef32a36021f5c9d45", +"test_nonstandard_paths.py::test_signmessage[m-3'-100'-4-255-script_types1]": "4f73135d2ec9add695e0a22d855816558b4ba9329a2828f9c9930be6245bdc2d", +"test_nonstandard_paths.py::test_signmessage[m-4-255-script_types0]": "0988cc8bdc5879744bd33190fddc5b5aa137fdd7214abb003c8000a871d98f14", +"test_nonstandard_paths.py::test_signmessage[m-49-0-63-0-255-script_types4]": "540df94c73a4eed8fe88cdb475e2b31df752dca9e47b102792c01064ee432752", "test_nonstandard_paths.py::test_signtx[m-1195487518-6-255-script_types3]": "37cfe119620536464ae42b3fbcae7b89d9272ad904da2bd8e8ae47b1024b4007", "test_nonstandard_paths.py::test_signtx[m-1195487518-script_types2]": "27a03a5be542d1f5f76a839e65daec766c1d7de8ae4637404ffcfea8267ea0ec", "test_nonstandard_paths.py::test_signtx[m-3'-100'-4-255-script_types1]": "efbe785820901471b0e55f9fd743c84a29fe719c2e1c8e6b2f87b0a20ce43cb2", @@ -807,10 +810,10 @@ "test_protection_levels.py::test_passphrase_reporting[False]": "233f8978b159ec8fb4092599d63f001c8059222ca14a9e84d185560d3c32ce24", "test_protection_levels.py::test_passphrase_reporting[True]": "d9e9bdb39d15d6737ed6234f16c36bb7ad95ca54067ff8f10cffccaa3caa96cb", "test_protection_levels.py::test_ping": "5551c263e8e09c8ae683f4dec3dd9d7ecc05ebbd3f2556604b27479c8f1fbc82", -"test_protection_levels.py::test_sign_message_t2": "bdcc7268caf112c3ba1708d9387fcca8384b330ba5a1e500df87e5fa3b0a4320", +"test_protection_levels.py::test_sign_message": "045d2faee841a79441683a6fdc912c3c69ecc0289b6c9801580942d47af7f0de", "test_protection_levels.py::test_signtx": "f13f1687e062bd407dc781ae93ebb6619eee5ea3d37ee031ffdc98d5bd7aea33", "test_protection_levels.py::test_unlocked": "f2be4c8c13c6a201770966438ffa9bcfe0eb031683920f93a55fa92921a28b51", -"test_protection_levels.py::test_verify_message_t2": "c258650c3697a46c61b67306b89cec1d67900095aeed05d4a691600a2cc12c2f", +"test_protection_levels.py::test_verify_message_t2": "794f6cad5b4903944061e49e6d0fb74a35786b29b399384736c19ee5ebacd85f", "test_protection_levels.py::test_wipe_device": "a30d958dda50b06e8bfc1c861c0ff2c0eb4acd0656bdf1dcd6474660882e3cd5", "test_reset_backup.py::test_skip_backup_manual[BackupType.Bip39-backup_flow_bip39]": "cad035eb013b620849f10638ca8559f1734bcc9a2242873b64cf98267d037d14", "test_reset_backup.py::test_skip_backup_manual[BackupType.Slip39_Advanced-backup_flow_slip39-799d9907": "cfdd178988740145a245f90cd6c66e425779ddf239f77a48fa4c1eec24e1f407", @@ -860,8 +863,8 @@ "test_stellar.py::test_sign_tx[StellarChangeTrustOp-delete]": "ec26e6883ba9405412674431e0ec07504b3f25682ce7d76ebd445b809194198a", "test_stellar.py::test_sign_tx[StellarCreateAccountOp]": "2582717c25974d2b3ee156624b00375148ff7fd12eeea73625a7c367fa610373", "test_stellar.py::test_sign_tx[StellarCreatePassiveSellOfferOp]": "6b0f0d2b746f98e2c85006ea7e2d5c49cd9277662e47f223138ff418066791e3", -"test_stellar.py::test_sign_tx[StellarManageDataOp]": "8fbec6547a8f9d1f002181db0cbe57fe86abef8d365b1c06fd14292cd0b068a7", "test_stellar.py::test_sign_tx[StellarManageBuyOfferOp]": "fc57e1ca8b65588aa16cc3524d6dc0f01e094ad5d16a6f7e739a69c101b554bc", +"test_stellar.py::test_sign_tx[StellarManageDataOp]": "8fbec6547a8f9d1f002181db0cbe57fe86abef8d365b1c06fd14292cd0b068a7", "test_stellar.py::test_sign_tx[StellarManageSellOfferOp]": "6ed84765b2ed46711be0ed1219d91c27e927119d352f37b2baf8c6501186bbce", "test_stellar.py::test_sign_tx[StellarPathPaymentStrictReceiveOp]": "58f3bfaece0706bc172d6e6564b728ec0b7f8e2629d8c64dc60672786586076d", "test_stellar.py::test_sign_tx[StellarPathPaymentStrictSendOp]": "fdd36a59520317d514e03f535dfeb93339af0f7ea5ee07c556bee3c8784c94ed",