feat(cardano): stop hashing in message signing
What changed, and why it matters
This commit removes the option to sign a hash of a Cardano message instead of the message itself. The device now always signs the actual message payload directly, up to a size limit. This is a feature/API change rather than a fix for an active security flaw, but it does eliminate a mode where users might have signed data they could not fully inspect.
Treat this as a breaking API change. Wallets and integrations using `hash_payload=true` must be updated to send the full payload and remove the field. Users relying on hashed-message signing should verify compatibility before upgrading firmware or client libraries.
Security signals we found
Removed hash-then-sign mode for Cardano message signing
Firmware now signs raw message payload instead of a hash
Payload size capped at MAX_CHUNK_SIZE and only one chunk accepted
User confirmation now shows the raw payload rather than a message hash
Protobuf field renumbering breaks backward compatibility for the removed option
Evidence from the diff
The change drops the hash_payload boolean from CardanoSignMessageInit across the protobuf definitions, firmware, Python/Rust clients, and tests. The firmware no longer computes a BLAKE2b-256 hash of streamed payload chunks; it now expects a single chunk, displays the raw payload to the user, and signs the raw payload directly. Payloads larger than MAX_CHUNK_SIZE are rejected. UI strings and test vectors are updated accordingly.
Changed components
core/src/apps/cardano/sign_message.pycore/src/apps/cardano/layout.pycommon/protob/messages-cardano.protocore/src/trezor/messages.pypython/src/trezorlib/cardano.pypython/src/trezorlib/cli/cardano.pypython/src/trezorlib/messages.pyrust/trezor-client/src/protos/generated/messages_cardano.rstests/device_tests/cardano/test_sign_message.pycommon/tests/fixtures/cardano/sign_message.jsoncommon/tests/fixtures/cardano/sign_message.failed.jsonInspect captured patch +80 / −199
diff --git a/common/protob/messages-cardano.proto b/common/protob/messages-cardano.proto
index 0cbaf7f6..7ad685dd 100644
--- a/common/protob/messages-cardano.proto
+++ b/common/protob/messages-cardano.proto
@@ -537,10 +537,9 @@ message CardanoSignMessageInit {
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;
+ required bool prefer_hex_display = 5; // whether to decode payload as hex even if valid ascii
+ optional CardanoAddressParametersType address_parameters = 6;
+ required CardanoDerivationType derivation_type = 7;
}
/**
diff --git a/common/tests/fixtures/cardano/sign_message.failed.json b/common/tests/fixtures/cardano/sign_message.failed.json
index b9c9dc67..e54304b3 100644
--- a/common/tests/fixtures/cardano/sign_message.failed.json
+++ b/common/tests/fixtures/cardano/sign_message.failed.json
@@ -14,7 +14,6 @@
"stakingPath": "m/1852'/1815'/0'/2/0"
},
"payload": "",
- "hash_payload": false,
"prefer_hex_display": true
},
"result": {
@@ -22,17 +21,16 @@
}
},
{
- "description": "Unhashed payload too long",
+ "description": "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"
+ "error_message": "Payload too long to sign"
}
}
]
diff --git a/common/tests/fixtures/cardano/sign_message.json b/common/tests/fixtures/cardano/sign_message.json
index dd8e92b7..85688c2a 100644
--- a/common/tests/fixtures/cardano/sign_message.json
+++ b/common/tests/fixtures/cardano/sign_message.json
@@ -9,7 +9,6 @@
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "ff00",
- "hash_payload": false,
"prefer_hex_display": true
},
"result": {
@@ -25,7 +24,6 @@
"network_id": 1,
"protocol_magic": 764824073,
"payload": "ff00",
- "hash_payload": false,
"address_parameters": {
"addressType": 0,
"path": "m/1852'/1815'/0'/0/0",
@@ -39,26 +37,11 @@
"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": {
@@ -72,7 +55,6 @@
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "54657374",
- "hash_payload": false,
"prefer_hex_display": true
},
"result": {
@@ -86,7 +68,6 @@
"parameters": {
"signing_path": "m/1852'/1815'/4'/0/0",
"payload": "",
- "hash_payload": false,
"prefer_hex_display": true
},
"result": {
@@ -95,34 +76,6 @@
"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": {
@@ -130,7 +83,6 @@
"network_id": 1,
"protocol_magic": 764824073,
"payload": "ff",
- "hash_payload": false,
"prefer_hex_display": false
},
"result": {
@@ -146,7 +98,6 @@
"network_id": 1,
"protocol_magic": 764824073,
"payload": "20",
- "hash_payload": false,
"prefer_hex_display": false
},
"result": {
diff --git a/core/src/apps/cardano/layout.py b/core/src/apps/cardano/layout.py
index 3a0b6a35..59c29af3 100644
--- a/core/src/apps/cardano/layout.py
+++ b/core/src/apps/cardano/layout.py
@@ -324,16 +324,12 @@ async def confirm_reference_script(
async def confirm_message_payload(
payload_first_chunk: bytes,
- payload_hash: bytes,
payload_size: int,
- is_signing_hash: bool,
prefer_hex_display: bool,
) -> None:
props: list[PropertyType]
- max_displayed_bytes = (
- _DEFAULT_MAX_DISPLAYED_CHUNK_SIZE if is_signing_hash else MAX_CHUNK_SIZE
- )
+ max_displayed_bytes = MAX_CHUNK_SIZE
if not payload_first_chunk:
assert payload_size == 0
@@ -358,8 +354,6 @@ async def confirm_message_payload(
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,
@@ -602,13 +596,9 @@ async def confirm_witness_request(
)
-async def confirm_message_path(path: list[int], is_signing_hash: bool) -> None:
+async def confirm_message_path(path: list[int]) -> 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)
- )
+ text = TR.cardano__sign_message_path_template.format(path_title)
await layouts.confirm_text(
"confirm_message_signing_path",
TR.cardano__confirm_message,
diff --git a/core/src/apps/cardano/sign_message.py b/core/src/apps/cardano/sign_message.py
index 98579c97..8694020e 100644
--- a/core/src/apps/cardano/sign_message.py
+++ b/core/src/apps/cardano/sign_message.py
@@ -48,8 +48,8 @@ async def _validate_message_init(
)
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")
+ if msg.payload_size > MAX_CHUNK_SIZE:
+ raise ProcessError("Payload too long to sign")
await _validate_message_signing_path(msg.signing_path, keychain)
@@ -78,9 +78,8 @@ async def _get_confirmed_header_address(
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
+async def _get_payload_first_chunk(size: int) -> bytes:
+ """Returns the first chunk of the payload."""
from trezor.messages import (
CardanoMessageItemAck,
CardanoMessageItemHostAck,
@@ -88,37 +87,33 @@ async def _get_payload_hash_and_first_chunk(size: int) -> tuple[bytes, bytes]:
)
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
+ else:
+ raise ProcessError("Expected only one chunk")
await ctx_call(CardanoMessageItemAck(), CardanoMessageItemHostAck)
- return hash_fn.digest(), first_chunk
+ return first_chunk
-async def _get_confirmed_payload(
- size: int, is_signing_hash: bool, prefer_hex_display: bool
-) -> bytes:
+async def _get_confirmed_payload(size: int, prefer_hex_display: bool) -> bytes:
from . import layout
- hash, first_chunk = await _get_payload_hash_and_first_chunk(size)
+ first_chunk = await _get_payload_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
+ return first_chunk
def _cborize_sig_structure(
@@ -165,7 +160,6 @@ async def sign_message(
payload = await _get_confirmed_payload(
size=msg.payload_size,
- is_signing_hash=msg.hash_payload,
prefer_hex_display=msg.prefer_hex_display,
)
@@ -176,9 +170,7 @@ async def sign_message(
_COSE_HEADER_ADDRESS_KEY: address,
}
- await layout.confirm_message_path(
- path=msg.signing_path, is_signing_hash=msg.hash_payload
- )
+ await layout.confirm_message_path(path=msg.signing_path)
signature = _sign_sig_structure(
msg.signing_path,
diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py
index c8067fd7..fc562724 100644
--- a/core/src/trezor/messages.py
+++ b/core/src/trezor/messages.py
@@ -1789,7 +1789,6 @@ if TYPE_CHECKING:
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"
@@ -1798,7 +1797,6 @@ if TYPE_CHECKING:
self,
*,
payload_size: "int",
- hash_payload: "bool",
prefer_hex_display: "bool",
derivation_type: "CardanoDerivationType",
signing_path: "list[int] | None" = None,
diff --git a/python/src/trezorlib/cardano.py b/python/src/trezorlib/cardano.py
index 31f5ca5e..f9f77a7b 100644
--- a/python/src/trezorlib/cardano.py
+++ b/python/src/trezorlib/cardano.py
@@ -1024,7 +1024,6 @@ def sign_message(
session: "Session",
signing_path: Path,
payload: bytes,
- hash_payload: bool,
prefer_hex_display: bool,
address_parameters: Optional[m.CardanoAddressParametersType] = None,
derivation_type: m.CardanoDerivationType = m.CardanoDerivationType.ICARUS,
@@ -1038,7 +1037,6 @@ def sign_message(
m.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,
diff --git a/python/src/trezorlib/cli/cardano.py b/python/src/trezorlib/cli/cardano.py
index 6208e7c6..51f68d90 100644
--- a/python/src/trezorlib/cli/cardano.py
+++ b/python/src/trezorlib/cli/cardano.py
@@ -345,7 +345,6 @@ def sign_message(
return cardano.sign_message(
session,
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(
diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py
index 37899490..f8640fa0 100644
--- a/python/src/trezorlib/messages.py
+++ b/python/src/trezorlib/messages.py
@@ -2910,17 +2910,15 @@ class CardanoSignMessageInit(protobuf.MessageType):
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),
+ 5: protobuf.Field("prefer_hex_display", "bool", repeated=False, required=True),
+ 6: protobuf.Field("address_parameters", "CardanoAddressParametersType", repeated=False, required=False, default=None),
+ 7: 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,
@@ -2930,7 +2928,6 @@ class CardanoSignMessageInit(protobuf.MessageType):
) -> 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
diff --git a/rust/trezor-client/src/protos/generated/messages_cardano.rs b/rust/trezor-client/src/protos/generated/messages_cardano.rs
index af791997..5a7e5c95 100644
--- a/rust/trezor-client/src/protos/generated/messages_cardano.rs
+++ b/rust/trezor-client/src/protos/generated/messages_cardano.rs
@@ -9635,8 +9635,6 @@ pub struct CardanoSignMessageInit {
pub signing_path: ::std::vec::Vec<u32>,
// @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.payload_size)
pub payload_size: ::std::option::Option<u32>,
- // @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.hash_payload)
- pub hash_payload: ::std::option::Option<bool>,
// @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.prefer_hex_display)
pub prefer_hex_display: ::std::option::Option<bool>,
// @@protoc_insertion_point(field:hw.trezor.messages.cardano.CardanoSignMessageInit.address_parameters)
@@ -9716,26 +9714,7 @@ impl CardanoSignMessageInit {
self.payload_size = ::std::option::Option::Some(v);
}
- // required bool hash_payload = 5;
-
- pub fn hash_payload(&self) -> bool {
- self.hash_payload.unwrap_or(false)
- }
-
- pub fn clear_hash_payload(&mut self) {
- self.hash_payload = ::std::option::Option::None;
- }
-
- pub fn has_hash_payload(&self) -> bool {
- self.hash_payload.is_some()
- }
-
- // Param is passed by value, moved
- pub fn set_hash_payload(&mut self, v: bool) {
- self.hash_payload = ::std::option::Option::Some(v);
- }
-
- // required bool prefer_hex_display = 6;
+ // required bool prefer_hex_display = 5;
pub fn prefer_hex_display(&self) -> bool {
self.prefer_hex_display.unwrap_or(false)
@@ -9754,7 +9733,7 @@ impl CardanoSignMessageInit {
self.prefer_hex_display = ::std::option::Option::Some(v);
}
- // required .hw.trezor.messages.cardano.CardanoDerivationType derivation_type = 8;
+ // required .hw.trezor.messages.cardano.CardanoDerivationType derivation_type = 7;
pub fn derivation_type(&self) -> CardanoDerivationType {
match self.derivation_type {
@@ -9777,7 +9756,7 @@ impl CardanoSignMessageInit {
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
- let mut fields = ::std::vec::Vec::with_capacity(8);
+ let mut fields = ::std::vec::Vec::with_capacity(7);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"protocol_magic",
@@ -9799,11 +9778,6 @@ impl CardanoSignMessageInit {
|m: &CardanoSignMessageInit| { &m.payload_size },
|m: &mut CardanoSignMessageInit| { &mut m.payload_size },
));
- fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
- "hash_payload",
- |m: &CardanoSignMessageInit| { &m.hash_payload },
- |m: &mut CardanoSignMessageInit| { &mut m.hash_payload },
- ));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"prefer_hex_display",
|m: &CardanoSignMessageInit| { &m.prefer_hex_display },
@@ -9834,9 +9808,6 @@ impl ::protobuf::Message for CardanoSignMessageInit {
if self.payload_size.is_none() {
return false;
}
- if self.hash_payload.is_none() {
- return false;
- }
if self.prefer_hex_display.is_none() {
return false;
}
@@ -9870,15 +9841,12 @@ impl ::protobuf::Message for CardanoSignMessageInit {
self.payload_size = ::std::option::Option::Some(is.read_uint32()?);
},
40 => {
- self.hash_payload = ::std::option::Option::Some(is.read_bool()?);
- },
- 48 => {
self.prefer_hex_display = ::std::option::Option::Some(is.read_bool()?);
},
- 58 => {
+ 50 => {
::protobuf::rt::read_singular_message_into_field(is, &mut self.address_parameters)?;
},
- 64 => {
+ 56 => {
self.derivation_type = ::std::option::Option::Some(is.read_enum_or_unknown()?);
},
tag => {
@@ -9905,9 +9873,6 @@ impl ::protobuf::Message for CardanoSignMessageInit {
if let Some(v) = self.payload_size {
my_size += ::protobuf::rt::uint32_size(4, v);
}
- if let Some(v) = self.hash_payload {
- my_size += 1 + 1;
- }
if let Some(v) = self.prefer_hex_display {
my_size += 1 + 1;
}
@@ -9916,7 +9881,7 @@ impl ::protobuf::Message for CardanoSignMessageInit {
my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
}
if let Some(v) = self.derivation_type {
- my_size += ::protobuf::rt::int32_size(8, v.value());
+ my_size += ::protobuf::rt::int32_size(7, v.value());
}
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
self.special_fields.cached_size().set(my_size as u32);
@@ -9936,17 +9901,14 @@ impl ::protobuf::Message for CardanoSignMessageInit {
if let Some(v) = self.payload_size {
os.write_uint32(4, v)?;
}
- if let Some(v) = self.hash_payload {
- os.write_bool(5, v)?;
- }
if let Some(v) = self.prefer_hex_display {
- os.write_bool(6, v)?;
+ os.write_bool(5, v)?;
}
if let Some(v) = self.address_parameters.as_ref() {
- ::protobuf::rt::write_message_field_with_cached_size(7, v, os)?;
+ ::protobuf::rt::write_message_field_with_cached_size(6, v, os)?;
}
if let Some(v) = self.derivation_type {
- os.write_enum(8, ::protobuf::EnumOrUnknown::value(&v))?;
+ os.write_enum(7, ::protobuf::EnumOrUnknown::value(&v))?;
}
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
@@ -9969,7 +9931,6 @@ impl ::protobuf::Message for CardanoSignMessageInit {
self.network_id = ::std::option::Option::None;
self.signing_path.clear();
self.payload_size = ::std::option::Option::None;
- self.hash_payload = ::std::option::Option::None;
self.prefer_hex_display = ::std::option::Option::None;
self.address_parameters.clear();
self.derivation_type = ::std::option::Option::None;
@@ -9982,7 +9943,6 @@ impl ::protobuf::Message for CardanoSignMessageInit {
network_id: ::std::option::Option::None,
signing_path: ::std::vec::Vec::new(),
payload_size: ::std::option::Option::None,
- hash_payload: ::std::option::Option::None,
prefer_hex_display: ::std::option::Option::None,
address_parameters: ::protobuf::MessageField::none(),
derivation_type: ::std::option::Option::None,
@@ -11696,50 +11656,49 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x03\x20\x02(\x0cR\tsignature\x12\x1d\n\nchain_code\x18\x04\x20\x01(\x0c\
R\tchainCode\"\x12\n\x10CardanoTxHostAck\",\n\x11CardanoTxBodyHash\x12\
\x17\n\x07tx_hash\x18\x01\x20\x02(\x0cR\x06txHash\"\x17\n\x15CardanoSign\
- TxFinished\"\xba\x03\n\x16CardanoSignMessageInit\x12%\n\x0eprotocol_magi\
+ TxFinished\"\x97\x03\n\x16CardanoSignMessageInit\x12%\n\x0eprotocol_magi\
c\x18\x01\x20\x01(\rR\rprotocolMagic\x12\x1d\n\nnetwork_id\x18\x02\x20\
\x01(\rR\tnetworkId\x12!\n\x0csigning_path\x18\x03\x20\x03(\rR\x0bsignin\
- gPath\x12!\n\x0cpayload_size\x18\x04\x20\x02(\rR\x0bpayloadSize\x12!\n\
- \x0chash_payload\x18\x05\x20\x02(\x08R\x0bhashPayload\x12,\n\x12prefer_h\
- ex_display\x18\x06\x20\x02(\x08R\x10preferHexDisplay\x12g\n\x12address_p\
- arameters\x18\x07\x20\x01(\x0b28.hw.trezor.messages.cardano.CardanoAddre\
- ssParametersTypeR\x11addressParameters\x12Z\n\x0fderivation_type\x18\x08\
- \x20\x02(\x0e21.hw.trezor.messages.cardano.CardanoDerivationTypeR\x0eder\
- ivationType\"\x17\n\x15CardanoMessageItemAck\"0\n\x1aCardanoMessagePaylo\
- adChunk\x12\x12\n\x04data\x18\x01\x20\x02(\x0cR\x04data\"\x1b\n\x19Carda\
- noMessageItemHostAck\"m\n\x1aCardanoSignMessageFinished\x12\x1c\n\tsigna\
- ture\x18\x01\x20\x02(\x0cR\tsignature\x12\x18\n\x07address\x18\x02\x20\
- \x02(\x0cR\x07address\x12\x17\n\x07pub_key\x18\x03\x20\x02(\x0cR\x06pubK\
- ey*B\n\x15CardanoDerivationType\x12\n\n\x06LEDGER\x10\0\x12\n\n\x06ICARU\
- S\x10\x01\x12\x11\n\rICARUS_TREZOR\x10\x02*\xd2\x01\n\x12CardanoAddressT\
- ype\x12\x08\n\x04BASE\x10\0\x12\x13\n\x0fBASE_SCRIPT_KEY\x10\x01\x12\x13\
- \n\x0fBASE_KEY_SCRIPT\x10\x02\x12\x16\n\x12BASE_SCRIPT_SCRIPT\x10\x03\
- \x12\x0b\n\x07POINTER\x10\x04\x12\x12\n\x0ePOINTER_SCRIPT\x10\x05\x12\
- \x0e\n\nENTERPRISE\x10\x06\x12\x15\n\x11ENTERPRISE_SCRIPT\x10\x07\x12\t\
- \n\x05BYRON\x10\x08\x12\n\n\x06REWARD\x10\x0e\x12\x11\n\rREWARD_SCRIPT\
- \x10\x0f*o\n\x17CardanoNativeScriptType\x12\x0b\n\x07PUB_KEY\x10\0\x12\
- \x07\n\x03ALL\x10\x01\x12\x07\n\x03ANY\x10\x02\x12\n\n\x06N_OF_K\x10\x03\
- \x12\x12\n\x0eINVALID_BEFORE\x10\x04\x12\x15\n\x11INVALID_HEREAFTER\x10\
- \x05*K\n$CardanoNativeScriptHashDisplayFormat\x12\x08\n\x04HIDE\x10\0\
- \x12\n\n\x06BECH32\x10\x01\x12\r\n\tPOLICY_ID\x10\x02*G\n\"CardanoTxOutp\
- utSerializationFormat\x12\x10\n\x0cARRAY_LEGACY\x10\0\x12\x0f\n\x0bMAP_B\
- ABBAGE\x10\x01*\xd2\x01\n\x16CardanoCertificateType\x12\x16\n\x12STAKE_R\
- EGISTRATION\x10\0\x12\x18\n\x14STAKE_DEREGISTRATION\x10\x01\x12\x14\n\
- \x10STAKE_DELEGATION\x10\x02\x12\x1b\n\x17STAKE_POOL_REGISTRATION\x10\
- \x03\x12\x1d\n\x19STAKE_REGISTRATION_CONWAY\x10\x07\x12\x1f\n\x1bSTAKE_D\
- EREGISTRATION_CONWAY\x10\x08\x12\x13\n\x0fVOTE_DELEGATION\x10\t*P\n\x0fC\
- ardanoDRepType\x12\x0c\n\x08KEY_HASH\x10\0\x12\x0f\n\x0bSCRIPT_HASH\x10\
- \x01\x12\x0b\n\x07ABSTAIN\x10\x02\x12\x11\n\rNO_CONFIDENCE\x10\x03*X\n\
- \x14CardanoPoolRelayType\x12\x12\n\x0eSINGLE_HOST_IP\x10\0\x12\x14\n\x10\
- SINGLE_HOST_NAME\x10\x01\x12\x16\n\x12MULTIPLE_HOST_NAME\x10\x02*R\n$Car\
- danoTxAuxiliaryDataSupplementType\x12\x08\n\x04NONE\x10\0\x12\x20\n\x1cC\
- VOTE_REGISTRATION_SIGNATURE\x10\x01*6\n\x1eCardanoCVoteRegistrationForma\
- t\x12\t\n\x05CIP15\x10\0\x12\t\n\x05CIP36\x10\x01*\x82\x01\n\x14CardanoT\
- xSigningMode\x12\x18\n\x14ORDINARY_TRANSACTION\x10\0\x12\x1e\n\x1aPOOL_R\
- EGISTRATION_AS_OWNER\x10\x01\x12\x18\n\x14MULTISIG_TRANSACTION\x10\x02\
- \x12\x16\n\x12PLUTUS_TRANSACTION\x10\x03*>\n\x14CardanoTxWitnessType\x12\
- \x11\n\rBYRON_WITNESS\x10\0\x12\x13\n\x0fSHELLEY_WITNESS\x10\x01B;\n#com\
- .satoshilabs.trezor.lib.protobufB\x14TrezorMessageCardano\
+ gPath\x12!\n\x0cpayload_size\x18\x04\x20\x02(\rR\x0bpayloadSize\x12,\n\
+ \x12prefer_hex_display\x18\x05\x20\x02(\x08R\x10preferHexDisplay\x12g\n\
+ \x12address_parameters\x18\x06\x20\x01(\x0b28.hw.trezor.messages.cardano\
+ .CardanoAddressParametersTypeR\x11addressParameters\x12Z\n\x0fderivation\
+ _type\x18\x07\x20\x02(\x0e21.hw.trezor.messages.cardano.CardanoDerivatio\
+ nTypeR\x0ederivationType\"\x17\n\x15CardanoMessageItemAck\"0\n\x1aCardan\
+ oMessagePayloadChunk\x12\x12\n\x04data\x18\x01\x20\x02(\x0cR\x04data\"\
+ \x1b\n\x19CardanoMessageItemHostAck\"m\n\x1aCardanoSignMessageFinished\
+ \x12\x1c\n\tsignature\x18\x01\x20\x02(\x0cR\tsignature\x12\x18\n\x07addr\
+ ess\x18\x02\x20\x02(\x0cR\x07address\x12\x17\n\x07pub_key\x18\x03\x20\
+ \x02(\x0cR\x06pubKey*B\n\x15CardanoDerivationType\x12\n\n\x06LEDGER\x10\
+ \0\x12\n\n\x06ICARUS\x10\x01\x12\x11\n\rICARUS_TREZOR\x10\x02*\xd2\x01\n\
+ \x12CardanoAddressType\x12\x08\n\x04BASE\x10\0\x12\x13\n\x0fBASE_SCRIPT_\
+ KEY\x10\x01\x12\x13\n\x0fBASE_KEY_SCRIPT\x10\x02\x12\x16\n\x12BASE_SCRIP\
+ T_SCRIPT\x10\x03\x12\x0b\n\x07POINTER\x10\x04\x12\x12\n\x0ePOINTER_SCRIP\
+ T\x10\x05\x12\x0e\n\nENTERPRISE\x10\x06\x12\x15\n\x11ENTERPRISE_SCRIPT\
+ \x10\x07\x12\t\n\x05BYRON\x10\x08\x12\n\n\x06REWARD\x10\x0e\x12\x11\n\rR\
+ EWARD_SCRIPT\x10\x0f*o\n\x17CardanoNativeScriptType\x12\x0b\n\x07PUB_KEY\
+ \x10\0\x12\x07\n\x03ALL\x10\x01\x12\x07\n\x03ANY\x10\x02\x12\n\n\x06N_OF\
+ _K\x10\x03\x12\x12\n\x0eINVALID_BEFORE\x10\x04\x12\x15\n\x11INVALID_HERE\
+ AFTER\x10\x05*K\n$CardanoNativeScriptHashDisplayFormat\x12\x08\n\x04HIDE\
+ \x10\0\x12\n\n\x06BECH32\x10\x01\x12\r\n\tPOLICY_ID\x10\x02*G\n\"Cardano\
+ TxOutputSerializationFormat\x12\x10\n\x0cARRAY_LEGACY\x10\0\x12\x0f\n\
+ \x0bMAP_BABBAGE\x10\x01*\xd2\x01\n\x16CardanoCertificateType\x12\x16\n\
+ \x12STAKE_REGISTRATION\x10\0\x12\x18\n\x14STAKE_DEREGISTRATION\x10\x01\
+ \x12\x14\n\x10STAKE_DELEGATION\x10\x02\x12\x1b\n\x17STAKE_POOL_REGISTRAT\
+ ION\x10\x03\x12\x1d\n\x19STAKE_REGISTRATION_CONWAY\x10\x07\x12\x1f\n\x1b\
+ STAKE_DEREGISTRATION_CONWAY\x10\x08\x12\x13\n\x0fVOTE_DELEGATION\x10\t*P\
+ \n\x0fCardanoDRepType\x12\x0c\n\x08KEY_HASH\x10\0\x12\x0f\n\x0bSCRIPT_HA\
+ SH\x10\x01\x12\x0b\n\x07ABSTAIN\x10\x02\x12\x11\n\rNO_CONFIDENCE\x10\x03\
+ *X\n\x14CardanoPoolRelayType\x12\x12\n\x0eSINGLE_HOST_IP\x10\0\x12\x14\n\
+ \x10SINGLE_HOST_NAME\x10\x01\x12\x16\n\x12MULTIPLE_HOST_NAME\x10\x02*R\n\
+ $CardanoTxAuxiliaryDataSupplementType\x12\x08\n\x04NONE\x10\0\x12\x20\n\
+ \x1cCVOTE_REGISTRATION_SIGNATURE\x10\x01*6\n\x1eCardanoCVoteRegistration\
+ Format\x12\t\n\x05CIP15\x10\0\x12\t\n\x05CIP36\x10\x01*\x82\x01\n\x14Car\
+ danoTxSigningMode\x12\x18\n\x14ORDINARY_TRANSACTION\x10\0\x12\x1e\n\x1aP\
+ OOL_REGISTRATION_AS_OWNER\x10\x01\x12\x18\n\x14MULTISIG_TRANSACTION\x10\
+ \x02\x12\x16\n\x12PLUTUS_TRANSACTION\x10\x03*>\n\x14CardanoTxWitnessType\
+ \x12\x11\n\rBYRON_WITNESS\x10\0\x12\x13\n\x0fSHELLEY_WITNESS\x10\x01B;\n\
+ #com.satoshilabs.trezor.lib.protobufB\x14TrezorMessageCardano\
";
/// `FileDescriptorProto` object which was a source for this generated file
diff --git a/tests/device_tests/cardano/test_sign_message.py b/tests/device_tests/cardano/test_sign_message.py
index 0188f880..34a711b3 100644
--- a/tests/device_tests/cardano/test_sign_message.py
+++ b/tests/device_tests/cardano/test_sign_message.py
@@ -33,7 +33,6 @@ def call_sign_message(
return cardano.sign_message(
session=session,
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(
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index 189ade1e..45d24a4c 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -4775,17 +4775,18 @@
"T2T1_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[nested_script_w-789238e6": "3b24b2bd4189f9bf9bac54636aa1326ff888de9eec3ce0bd47b8b9bfa6c9a4cb",
"T2T1_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script]": "85ddca2717fb3723e1389b8f8d6d23378aa276e4dfd4df937eb4d20541c1ce56",
"T2T1_en_cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[pub_key_script_-1579fe2a": "86267107419ea723cb89eeb09afecef96bdb8682175a24445d14dc0224dbb7fb",
-"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[ambiguous_ascii_payload_falls_back_to_hex]": "70e89a43a3db6f42cce715a7e63ba70e1114dbe531400936c5441e04e0787a8e",
-"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[non-ascii_payload_falls_back_to_hex]": "2d4712e66b63f90c5dda380cfbb6b82b824bdc4e22713c84d1e0f22164b33819",
-"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload]": "2de9116c5979a808e3f1507bdbc037155a6fe0be41be9dea74fbe40a3749be3d",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[ambiguous_ascii_payload_falls_back_to_hex]": "cd85ec9132c113cad52c87f904a16a196c14616ff014af6c8c59b9b3dd71b089",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[non-ascii_payload_falls_back_to_hex]": "cf06306192fa8d9d64068fe53602438985f60383e8a28667670bea7c507db4ad",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload]": "ec2ed38c1c598db6bbb008316863e244edce57dc2aa7dd2d0f0bd143c6133e27",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_empty_payload_hash]": "f719612b4903f74aeeef1cf8ecad21cf744a919bae21c25667915708e85fd931",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_long_ascii_payload_hash]": "396b51143a83cedd45e359410d2a445205588825c9a7b6cbd41e9cc0c75d4efb",
-"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload]": "cb81e264c7add093d24743a769621b235f923f7a20afa122f8786086df415919",
-"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload_rendered_as_hex]": "d64a7592306207a6778c45eaeec8cef08cdc30f5d0d8b09834b73421734d9bd8",
-"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload]": "8698f74946e7fba97a9c6a427d8b0aefeac65291d3cbcb6095a08c0b32fab72b",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload]": "ef411108a0f3bdb2756170ce0f26e358887dc635b7e7b1133e5472d8fd980ff2",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_ascii_payload_rendered_as_hex]": "227e0da0a0c0119fe7f8462f8bf27c90771fe2b4fa86f6305c7d82381628645d",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload]": "e85e3217bc4c3240db6c9b9771ba6ee34db0b61c62b33619679822ba51b5f164",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_hash]": "61818bbd8095343382190f7b983cf7eaca996999681f68cd4b4b85f18f9a7949",
-"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_with_a-1f337ea4": "070c21dbcde8e14ae33a5de627ea205485b18455d23ecbfa67cc4eaf0e3d4936",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message[sign_short_non-ascii_payload_with_a-1f337ea4": "ac01ee961a5524fcbba7a327b417816e0e6e6ceb4fe8489e5078b547ab3b831c",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[missing_network_id_and_proto-21ec11cf": "8b1ccc0dbd6e6e3d02a896650ab90dd332ba4edbbcc4095e0fbb6a96e5256f75",
+"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[payload_too_long]": "8b1ccc0dbd6e6e3d02a896650ab90dd332ba4edbbcc4095e0fbb6a96e5256f75",
"T2T1_en_cardano-test_sign_message.py::test_cardano_sign_message_failed[unhashed_payload_too_long]": "8b1ccc0dbd6e6e3d02a896650ab90dd332ba4edbbcc4095e0fbb6a96e5256f75",
"T2T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx[byron_to_shelley_transfer]": "2ebaaf8458ac58fe0a9237238299dae01927bce1a29b5695510d039034134602",
"T2T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_change0]": "7a20525b47412bf3835dd4fc5374166342dba4492a35d40761291d9c8089a617",
Why this scored 32/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.