feat(core): allow `WebAuthnListResidentCredentials` pagination
What changed, and why it matters
This commit adds pagination support for listing WebAuthn (FIDO2) resident credentials stored on a Trezor device. Previously, the device returned all credentials in one message, which could hit size limits. Now the host can request credentials in smaller batches. There is no obvious security bug in the change; it is a feature addition with a small, well-scoped protocol change.
No immediate security action required. As a defensive review, verify that the wire message parser enforces an upper bound on `batch_size` elsewhere in the codebase to avoid accidental oversized responses, and confirm that the host-side loop cannot be induced into an unbounded exchange by a malicious or compromised device.
Security signals we found
New wire protocol flow using `context.call` with `WebAuthnCredentialsAck` response expected
Input validation added for `batch_size <= 0`
No validation or limits on maximum `batch_size` observed in diff
No authorization or confirmation changes beyond existing `confirm_action`
Feature is additive and preserves non-paginated API path
Evidence from the diff
The patch modifies list_resident_credentials.py to support a new batch_size field in WebAuthnListResidentCredentials. When batch_size is unset, behavior remains backward-compatible (return all credentials). When set, the device streams credentials in batches of the requested size, waiting for a WebAuthnCredentialsAck from the host between batches, and terminates with is_done=True. The Python client trezorlib/fido.py is updated to use a default batch size of 10 and to loop until is_done. Tests and UI fixture hashes are updated accordingly. The only validation added is a DataError for non-positive batch_size.
Changed components
core/src/apps/webauthn/list_resident_credentials.pypython/src/trezorlib/fido.pytests/device_tests/webauthn/test_msg_webauthn.pytests/ui_tests/fixtures.jsonInspect captured patch +70 / −33
diff --git a/core/.changelog.d/6349.added b/core/.changelog.d/6349.added
new file mode 100644
index 00000000..b9713e61
--- /dev/null
+++ b/core/.changelog.d/6349.added
@@ -0,0 +1 @@
+Support WebAuthn credentials' pagination.
diff --git a/core/src/apps/webauthn/list_resident_credentials.py b/core/src/apps/webauthn/list_resident_credentials.py
index 1151cfc7..eaa5216c 100644
--- a/core/src/apps/webauthn/list_resident_credentials.py
+++ b/core/src/apps/webauthn/list_resident_credentials.py
@@ -8,8 +8,13 @@ async def list_resident_credentials(
msg: WebAuthnListResidentCredentials,
) -> WebAuthnCredentials:
from trezor import TR
- from trezor.messages import WebAuthnCredential, WebAuthnCredentials
+ from trezor.messages import (
+ WebAuthnCredential,
+ WebAuthnCredentials,
+ WebAuthnCredentialsAck,
+ )
from trezor.ui.layouts import confirm_action
+ from trezor.wire import DataError, context
from . import resident_credentials
@@ -20,7 +25,7 @@ async def list_resident_credentials(
verb=TR.buttons__export,
prompt_screen=True,
)
- creds = [
+ creds_iter = (
WebAuthnCredential(
index=cred.index,
id=cred.id,
@@ -36,5 +41,17 @@ async def list_resident_credentials(
curve=cred.curve,
)
for cred in resident_credentials.find_all()
- ]
- return WebAuthnCredentials(credentials=creds)
+ )
+ if msg.batch_size is None:
+ return WebAuthnCredentials(credentials=list(creds_iter))
+
+ if msg.batch_size <= 0:
+ raise DataError("Invalid batch size")
+
+ while True:
+ creds = [cred for _, cred in zip(range(msg.batch_size), creds_iter)]
+ if not creds:
+ return WebAuthnCredentials(is_done=True)
+
+ resp = WebAuthnCredentials(credentials=creds, is_done=False)
+ await context.call(resp, expected_type=WebAuthnCredentialsAck)
diff --git a/python/.changelog.d/6349.added b/python/.changelog.d/6349.added
new file mode 100644
index 00000000..b9713e61
--- /dev/null
+++ b/python/.changelog.d/6349.added
@@ -0,0 +1 @@
+Support WebAuthn credentials' pagination.
diff --git a/python/src/trezorlib/fido.py b/python/src/trezorlib/fido.py
index 1f3509ec..928b6a06 100644
--- a/python/src/trezorlib/fido.py
+++ b/python/src/trezorlib/fido.py
@@ -26,10 +26,17 @@ if TYPE_CHECKING:
@workflow()
-def list_credentials(session: "Session") -> Sequence[messages.WebAuthnCredential]:
- return session.call(
- messages.WebAuthnListResidentCredentials(), expect=messages.WebAuthnCredentials
- ).credentials
+def list_credentials(
+ session: "Session", batch_size: int | None = 10
+) -> Sequence[messages.WebAuthnCredential]:
+ creds = []
+ msg = messages.WebAuthnListResidentCredentials(batch_size=batch_size)
+ while True:
+ resp = session.call(msg, expect=messages.WebAuthnCredentials)
+ creds.extend(resp.credentials)
+ if resp.is_done:
+ return creds
+ msg = messages.WebAuthnCredentialsAck()
@workflow()
diff --git a/tests/device_tests/webauthn/test_msg_webauthn.py b/tests/device_tests/webauthn/test_msg_webauthn.py
index 4dc9561c..74e08ff8 100644
--- a/tests/device_tests/webauthn/test_msg_webauthn.py
+++ b/tests/device_tests/webauthn/test_msg_webauthn.py
@@ -41,6 +41,8 @@ def test_add_remove(session: Session):
# List should be empty.
assert fido.list_credentials(session) == []
+ # Check non-paginated API.
+ assert fido.list_credentials(session, batch_size=None) == []
# Add valid credential #1.
fido.add_credential(session, CRED1)
@@ -81,6 +83,8 @@ def test_add_remove(session: Session):
# Check that the invalid credential was not added.
creds = fido.list_credentials(session)
assert len(creds) == 1
+ # Check non-paginated API.
+ assert creds == fido.list_credentials(session, batch_size=None)
# Add valid credential, which has same userId as #2, but different rpId.
fido.add_credential(session, CRED3)
@@ -88,10 +92,17 @@ def test_add_remove(session: Session):
# Check that the credential was added.
creds = fido.list_credentials(session)
assert len(creds) == 2
+ # Check non-paginated API.
+ assert creds == fido.list_credentials(session, batch_size=None)
# Fill up the credential storage to maximum capacity.
- for cred in CREDS[: RK_CAPACITY - 2]:
+ for expected_len, cred in enumerate(CREDS[: RK_CAPACITY - 2], 3):
fido.add_credential(session, cred)
+ creds = fido.list_credentials(session)
+ assert len(creds) == expected_len
+ if expected_len <= 30:
+ # Check non-paginated API for small enough responses.
+ assert creds == fido.list_credentials(session, batch_size=None)
# Adding one more valid credential to full storage should fail.
with pytest.raises(TrezorFailure):
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index 40165c7a..16cd6921 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -2748,7 +2748,7 @@
"T2T1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "1f291dca63b6631780d3020acea04c0141d3824749476ab48bd5a98fb0500ea6",
"T2T1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "ff528f70cb9580cdd05fa64e0ba009a507a7c500abb9999d9a0dfc760f9c701d",
"T2T1_cs_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "b21e56bf848687e440ae3df1b6fbab33d0f1930a63f086934143885f64e69d75",
-"T2T1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "98ce38f5635ac1db1c1003685df0f823fadaaea5ea369ed0cdc7bd9e40659d16",
+"T2T1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "f825a96b361fcb6ac22ab6edfe2703a2f4b80b5c0cab931fb288cbfa8208b145",
"T2T1_cs_webauthn-test_u2f_counter.py::test_u2f_counter": "af84cf50468fbeac774c36ef29be10ebae747d6a2c1a0e46e7118c4d7e1070b9",
"T2T1_cs_zcash-test_sign_tx.py::test_external_presigned": "fb21d051ef7a614ff677db340cd924f9cea5b313d6c641350e52b690a879888b",
"T2T1_cs_zcash-test_sign_tx.py::test_one_two": "b5e03dd4f749e4fc1f473f6accfc6d0614c58c35602fc8487772c6b9b9704ffe",
@@ -4369,7 +4369,7 @@
"T2T1_de_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "20d0c8541e027e36f49f835a6787a241db2d0f66aa6cbf427e6e1ecb7acb511d",
"T2T1_de_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "4428da8d31af45b35bcd6335e2403d0545865bf553997ec4150fd5cb83378c6f",
"T2T1_de_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "7e7d0286404d4ece112137eb94fcbd3df403e782f3f8f84734d09d96d934768c",
-"T2T1_de_webauthn-test_msg_webauthn.py::test_add_remove": "82e777aadabc585da236cdade17db8d98814221c331d9e18cfeafd5b9d6b4322",
+"T2T1_de_webauthn-test_msg_webauthn.py::test_add_remove": "6d8fb6e352ffcfc2da6c0dc1ae0a23b930ebb372786286ec4649c6375e856d81",
"T2T1_de_webauthn-test_u2f_counter.py::test_u2f_counter": "f421530e66cc9657f68cb9fdba5e92d29a0a02ec50c35059e898cffeeef1217a",
"T2T1_de_zcash-test_sign_tx.py::test_external_presigned": "450dbdcd5ef0c579701d7572ac43de8809dff41929ea697eb270bafdea0b0268",
"T2T1_de_zcash-test_sign_tx.py::test_one_two": "a2720caf53da135da499659c9d64c407b184182b6688685107af6a4504de9868",
@@ -5990,7 +5990,7 @@
"T2T1_en_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "9369281f36d48bb799f63417f7c452b634cfb8e2e780256d3ae8eea2cea66ad4",
"T2T1_en_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "d236ba9b13990522cc63360a1a53d7ac2433117f6c613cb8705057b479de6921",
"T2T1_en_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "82def34bb7014faf4794fa5e71a7632f4be3b01cf4f15205ab04beaa514c2c46",
-"T2T1_en_webauthn-test_msg_webauthn.py::test_add_remove": "3e750190e9608a1ea76f00e5ec220576cc7842567c1f01c61a1d5b11ed3ed7c2",
+"T2T1_en_webauthn-test_msg_webauthn.py::test_add_remove": "bc66b2c20f6b669f277d53b70fcd559c88df1096df8b0bb856347ceb51ca050f",
"T2T1_en_webauthn-test_u2f_counter.py::test_u2f_counter": "f740248e1b4e4289052807569a0a1defdd88d8fc0532a47850da0ea26277276d",
"T2T1_en_zcash-test_sign_tx.py::test_external_presigned": "2492bd16ea82738cec9778d3afed746d21da8181d7e2782b701fa240dffbb42a",
"T2T1_en_zcash-test_sign_tx.py::test_one_two": "1b8ab64581bdb61d2937911eba35a08514d3ef5e7d2b8c3ebea643c911ef0655",
@@ -7629,7 +7629,7 @@
"T2T1_es_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "0e643f23abf5592a57cabfd58d532148123c3473620223502ccbe0d71941ce33",
"T2T1_es_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "dd835e203aa1766d49a9dca6071a375ee4604c4163c87a9f819feb59a7be736c",
"T2T1_es_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "f3abf0c5ee58fb8599592e9444d0fbe690b44f7f74fad0eee2662cfb32f7d0e6",
-"T2T1_es_webauthn-test_msg_webauthn.py::test_add_remove": "8678ef3a2a2bce13a5bfad6696800f0f8f925c5ee6a94355e567a4d902642328",
+"T2T1_es_webauthn-test_msg_webauthn.py::test_add_remove": "564ddc17eb2c551762c6bc958133701508f37b95ab1bcd3bb88e547e151fc1f1",
"T2T1_es_webauthn-test_u2f_counter.py::test_u2f_counter": "3f0e81d8c7cab7e9f5d78adbf15d25c4f91a82ea42f46a423b545045030a9603",
"T2T1_es_zcash-test_sign_tx.py::test_external_presigned": "9f681299b9f1120944d4add7c73237fddb7a9c72b0f8b316132771812b607a61",
"T2T1_es_zcash-test_sign_tx.py::test_one_two": "028c3b53718c53f48103b70153c7b06260c43b7a2036eaf5afbf1360b88c03ca",
@@ -9250,7 +9250,7 @@
"T2T1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "3a55fcfe948541ca23d3b04c648da6ca8a493edda51cbce4597ea730c6e6fc52",
"T2T1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "b70602859c79148d9c5ce61f374124795c0398a1c67a427bd7de02dc453503c1",
"T2T1_fr_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "1d3e9d1466372e8f025becdcf3dd7b04e8844e364010e2585d8cf463f8534629",
-"T2T1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "325b695f038f917d0c4ba40ac7abfeaaa8531be5e59154bee5859dce133cc41d",
+"T2T1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "67ea05247ee30b0a0042d3e7f143d5f70917fc6dfa25f0ccefc501a4a49afb5c",
"T2T1_fr_webauthn-test_u2f_counter.py::test_u2f_counter": "34a31a6a0c500259f8c30e801a242e1bcf4baff98fb03af3c87e2a00fca556d1",
"T2T1_fr_zcash-test_sign_tx.py::test_external_presigned": "f961e642c7694e827cb9182950cf5dda35adcb64c3ba44b98fa92656356b87f6",
"T2T1_fr_zcash-test_sign_tx.py::test_one_two": "912280620c7bb83f44db29e16ca580cefb375a929ea8a2506eaacf31625562a9",
@@ -10871,7 +10871,7 @@
"T2T1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "8a80d4dc0a42735ce88c2f10e6c26fbddf2115f232667d7ef9ac33bd70fd840d",
"T2T1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "7f854507a9ca330bcddd2eac654ef95b1d6050651ae73b9a35aa6796efbb9256",
"T2T1_pt_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "fefd653f405e6d37237376d6e7d6b03c93d2b92f3e7e62c1072c0bd9ab8f4bdf",
-"T2T1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "356e3d65eb5d9838fdbfec275d5491a460416f8e157d2c1364db397f8d5302dc",
+"T2T1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "aeebd04e3f1e7feeed9f40df12f0de87d57424ac7279580ac5e1fc6d9b11302a",
"T2T1_pt_webauthn-test_u2f_counter.py::test_u2f_counter": "507d4eef68b980907884cdb055cfe5f78d9288bef0e987d65083009082abad26",
"T2T1_pt_zcash-test_sign_tx.py::test_external_presigned": "9652b526098be999a73dee53f0c64d49c6343463d92bbafcda023f89a6ae2757",
"T2T1_pt_zcash-test_sign_tx.py::test_one_two": "ec16e4ec4e55071cc4bc6a07db111ac500c2c7a5a3e2510a06f6ad9e60f37509",
@@ -12721,7 +12721,7 @@
"T3B1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "c03090028ca896f38de7b01dc8c79716071505e9aa7acc4bef7f38f9c15882f5",
"T3B1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "f51e08584e64ff1299451b328eec4499c8d60a98d204bd5f010a20d809ef4cd1",
"T3B1_cs_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "0c98bf178da7906c8f655c341ac6954e0c287a94b900388c1fdbb711935fe188",
-"T3B1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "1b01ab5508dbcd5a5ee064ec608071b5155ba9606bfdb7b10c5e03a57b36d312",
+"T3B1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "e7a5bc035c90b62eb59c90fe95ee99d926090018b0754712a394d7a49bf0a7a7",
"T3B1_cs_webauthn-test_u2f_counter.py::test_u2f_counter": "62ddcf8e15851755ac555299395cfe10dcefc43bded072f4985b592a398e50ec",
"T3B1_cs_zcash-test_sign_tx.py::test_external_presigned": "a490680ef46207d05a87efa4336d5a7c277ff19ffeec05a6f8a66301136ef347",
"T3B1_cs_zcash-test_sign_tx.py::test_one_two": "d36229d21a51fcd0e712100ac0a3116263ac311adbfe158fcf07892fea8f7859",
@@ -14265,7 +14265,7 @@
"T3B1_de_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "27d00dbe374ba060adb117a2e699d899dfd9740983213509c632fc9499698b34",
"T3B1_de_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "008cc67eb72ee218d649ecf207ebc0320d7534f39ad05a4dfc6222b17e64923b",
"T3B1_de_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "398dfe62f1011ed1c6d3e7adec7fe8c90f93648afa4dc7cc5e753f2e8529573c",
-"T3B1_de_webauthn-test_msg_webauthn.py::test_add_remove": "86db73c48fe88a4cffd01114340f5d4c40283537fcce7e442613518cb6530ade",
+"T3B1_de_webauthn-test_msg_webauthn.py::test_add_remove": "b4779a362d9a280250d63383c5e57ef011e46e1edadebd0012a50d24c6947769",
"T3B1_de_webauthn-test_u2f_counter.py::test_u2f_counter": "a4aad5a86c96cae9667e5147a5b55b5ad5907099412ff606cc10298e8bcef130",
"T3B1_de_zcash-test_sign_tx.py::test_external_presigned": "6319777da3cecae02dda5fc4ad0f8b81e28779cb76b38ae2e7e75075d6b5f116",
"T3B1_de_zcash-test_sign_tx.py::test_one_two": "81e0d235ea2d22f8cb0afe0ddac5d0b57a4693e5f02b1259445f8ac7d80bd4e1",
@@ -15809,7 +15809,7 @@
"T3B1_en_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "679aa3b142f51bf9e6aae85f4e3716ad7952e7ad047aa8ec490da9e03e08116f",
"T3B1_en_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "b0ec0aca3304dc3e5655cbe03d5b2ff9619047e6c0b8f3d9f04142c8a3ec3d28",
"T3B1_en_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "0f26940ee8688301cc19e50d447db1ffbb8474a05c05f77572d43c1355b6ddc2",
-"T3B1_en_webauthn-test_msg_webauthn.py::test_add_remove": "540214b367b638082b9beb67e492b59b5ac523b5dedb972ace9b4caca974ef6e",
+"T3B1_en_webauthn-test_msg_webauthn.py::test_add_remove": "8de07e6773438743a8da5b3cae31afbed688e474b6bf1719ae3fff03af30e827",
"T3B1_en_webauthn-test_u2f_counter.py::test_u2f_counter": "49f01fce798fe9d5a22cea12d7f276fb91cd77c04087b1dd2c3e37a6106cc350",
"T3B1_en_zcash-test_sign_tx.py::test_external_presigned": "6bc1f0b265163f105b4b084e518a23e6a248849f3141d82dbe25538a43d69883",
"T3B1_en_zcash-test_sign_tx.py::test_one_two": "218beca530f1e3bd8ad8151e18afc09cf7728a1c3537ed36e422813cd5d0229e",
@@ -17353,7 +17353,7 @@
"T3B1_es_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "fb46fa646ed5368472102ee71a49c9dcb0734c4af43f6c6035bb665504c9cf60",
"T3B1_es_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "5e9bfa9aec29eee8c70f28611f3cc62bd2ff61373347df0674d738ca72591264",
"T3B1_es_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "eaff1f1b99deec915c5fc97f0b22896755edd44809983cbd8f4c2143bc848d21",
-"T3B1_es_webauthn-test_msg_webauthn.py::test_add_remove": "07d58a3658c5c25a62ca160b8b4a1045575c64673589c99d20769a12efd57ef9",
+"T3B1_es_webauthn-test_msg_webauthn.py::test_add_remove": "c74b656eac01dcf4062cbd64b7b5cd54dd840c5ba0c56917b0c682ad03cd67aa",
"T3B1_es_webauthn-test_u2f_counter.py::test_u2f_counter": "db9781a9acce29167a3ca4a201f2e67ecb3bcbd037fe26a4bebb82f8c234cb13",
"T3B1_es_zcash-test_sign_tx.py::test_external_presigned": "945cf3aa13f8a1b5cdcb4506ce2c0aadf6b79c5b4489b5660298898ba75c7eb6",
"T3B1_es_zcash-test_sign_tx.py::test_one_two": "eab0b586bb1bebacafc46b628a14c1833fdccc511a3d008513b57a91c316ef85",
@@ -18897,7 +18897,7 @@
"T3B1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "070846416aa32a9d2bd1a290abb8523dc67d162984f0fdc277ac139500d0f79a",
"T3B1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "5f79f7cf1d684e53eff784e465683754d18a325637ba342d478e57180c70f89a",
"T3B1_fr_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "d7f57ac3cc1777a464bb8c0206b0477af1af4435d5c0500e30ebb990c07d1c5a",
-"T3B1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "3f946df11aed0e73ba7e21bacc1bace824325f8575c444f67d5d7a2c3394c9d5",
+"T3B1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "ba41b34f86397cc150c449eefdd6a0c3381d814a018af71b0046f62e5af38cc8",
"T3B1_fr_webauthn-test_u2f_counter.py::test_u2f_counter": "186427cd3da75b39add98615c2242bab81efe5ac5e07e66291a7a1b5cf79f084",
"T3B1_fr_zcash-test_sign_tx.py::test_external_presigned": "55f46649b51a9b70a29aaab9c8ae44067e4781e9d56c85ed1b656354823954cb",
"T3B1_fr_zcash-test_sign_tx.py::test_one_two": "5fb88164d18c0d2652b2936949b58f47ac65fc3dc16b78287434b1d52a26bd03",
@@ -20441,7 +20441,7 @@
"T3B1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "c05ffe1727f99ab9320ecf9f024e9e6b5ed1e64939e8db696a170acf7a591d97",
"T3B1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "0b584cd55adb2b6824305c34e33a6c53abbf12d5e41894dbb68cf58d32e8edd5",
"T3B1_pt_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "89b4ab2f6cbd57e3b13c9cbba5f8ab9a75656c13a0c17100f608df03ccb72cb7",
-"T3B1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "d09a8586ac2da47399f9209862c748c327934b37eceab9b5fde02410302e5379",
+"T3B1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "3c7929f451cdbaba4280f2a50b9be8edd0c31f364db30061a0b7b7111ea0e9df",
"T3B1_pt_webauthn-test_u2f_counter.py::test_u2f_counter": "450cbe2f0b48489505a6ea2bbac03f0394bd1b396b596997f3d705f7e10f8ea0",
"T3B1_pt_zcash-test_sign_tx.py::test_external_presigned": "9b4bdced7e74a9a1d1a7dbec357f1d12daea7d6b4365526ee23469c6539ad3ab",
"T3B1_pt_zcash-test_sign_tx.py::test_one_two": "d4a32b7a5ba0fe503e7d173e800bc3f9abe67829bc5dc62069d05a4c498bdabe",
@@ -22394,7 +22394,7 @@
"T3T1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "c7c7db34e8cda0cb99db01fd204169a8493dde636bc5df7847a1c5f1c75ea467",
"T3T1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "82a26998aa127f50832204c9192d115930d9328c010b17c14e522c305d0e9549",
"T3T1_cs_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "85072b650c3b4de2d1fc06a01ac87e40280ffbcf7e9e36ab44c941d2f4601665",
-"T3T1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "7c62ef402935dbc2b2784eb785e16d290247bb293eb7061464b27d237f5d54d0",
+"T3T1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "c2a11dc37b9f8d34de9e3fcf89cb1d538245f63816108ce22a1f189e6e28365a",
"T3T1_cs_webauthn-test_u2f_counter.py::test_u2f_counter": "0a1e90cdaa05275432b5e4bda47626d008da19b488223a39012d10dc58eb2e4f",
"T3T1_cs_zcash-test_sign_tx.py::test_external_presigned": "7f1f29b3a19624cf8bcfbaf97d9c9b561ab127799a6df0fc7815d782c9682c57",
"T3T1_cs_zcash-test_sign_tx.py::test_one_two": "c86bee3d6543f77fc24eea2c227450bad358bd637daf252dddbb893634b34f35",
@@ -23971,7 +23971,7 @@
"T3T1_de_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "1e85752bf77ed6383c65b0187873759c5b375de42abe98bea6b15b2b9ad74cd2",
"T3T1_de_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "e75a021810f49c690a8debb559847222e7822e4bceea7883fb5f27a646dbf4cc",
"T3T1_de_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "d210fa87817e3e45551d2ca06a9d4d846304c7f90de3f7a6d75bb6235c13732b",
-"T3T1_de_webauthn-test_msg_webauthn.py::test_add_remove": "400b1c08d621d1982b62a2ef26c5f456348e86dd51b8f220cce0c2029137af65",
+"T3T1_de_webauthn-test_msg_webauthn.py::test_add_remove": "1750b46d895a19a5cb24f904bf37da5f81f0d435fb741e7a2ab08504af4446bc",
"T3T1_de_webauthn-test_u2f_counter.py::test_u2f_counter": "c84c97b408cfde113ba8ed7f4a67f50c4d846fb97825e75b3bda13009db63da2",
"T3T1_de_zcash-test_sign_tx.py::test_external_presigned": "c8682370d8aef9d2c0c62b08101b9adb13ecae8f2709d25b61bcf692e6f25958",
"T3T1_de_zcash-test_sign_tx.py::test_one_two": "6b7f023cbe132324a340fcc0c05de3c6abe15fc90d641eabbeb8dc8d8f8e3852",
@@ -25548,7 +25548,7 @@
"T3T1_en_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "519886bba9ca4b52d9e3c31aa83b02c5dac6ced889fff9fa2c8aca24b028bc96",
"T3T1_en_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "9a5c467d51f784d44186d575d2b8d1eae5e6ddba952ef07b775ae35815a4c789",
"T3T1_en_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "5f5a707880f454c482cf07bb7f7bac910b6d8f07cc2a48690f7958b112ed5052",
-"T3T1_en_webauthn-test_msg_webauthn.py::test_add_remove": "95351793ff4ed12276b36d9223bff9456adce515a4ec26e72c966b351c32e179",
+"T3T1_en_webauthn-test_msg_webauthn.py::test_add_remove": "0253baf5777f5ff850723ed342b560702bdbfc54a13ab3e4075454cf5403a7fc",
"T3T1_en_webauthn-test_u2f_counter.py::test_u2f_counter": "b81ea8c63aa65f04c3f42b6da5b8c4fda384013d468ca7b24a446863984cc788",
"T3T1_en_zcash-test_sign_tx.py::test_external_presigned": "bd9b80d39f8d7500873d4d385171e1b6ae588b8f792b0639ebcaa99295f90727",
"T3T1_en_zcash-test_sign_tx.py::test_one_two": "18743fad6e925a914af2611ad2a4954b6b478de27108114af091d749900859ef",
@@ -27125,7 +27125,7 @@
"T3T1_es_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "9ca37d232a88d62dafba62a5663bb2f50d909bd38c715355d05af18183db8286",
"T3T1_es_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "7e6e890df589a928082ce37455b1897d0612beac6f38f883f84f578bd1d8ae78",
"T3T1_es_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "3a8eb673f6b288a664934c7e8020ef0897062da3a64a43521103ea8c008a6933",
-"T3T1_es_webauthn-test_msg_webauthn.py::test_add_remove": "f0cf005283047cb5259daa065131e71c7e50488bab14fb3a95390b79ba6ce97a",
+"T3T1_es_webauthn-test_msg_webauthn.py::test_add_remove": "d301cf89c4857c8c6f297ba011a51f17c8474b5a51e9673a7fbc263dcf0ce163",
"T3T1_es_webauthn-test_u2f_counter.py::test_u2f_counter": "65cffffbbe80d2b3a3babd0d5b586eaca830dc3b35a61c4d9a6f5c27ce96556d",
"T3T1_es_zcash-test_sign_tx.py::test_external_presigned": "0e72c833700575f2ab4f9c48296a18696625de11001614b952367e71911cecbd",
"T3T1_es_zcash-test_sign_tx.py::test_one_two": "0d3bdfe89a69d756fe6c997a8df040f4ea7cc08969463650848ad880bcacf733",
@@ -28702,7 +28702,7 @@
"T3T1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "06dbf28e0e46a5d72f568c2244b31ed3d6e47a41e8b79ffb377cf4cd533d68e8",
"T3T1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "c1b5711575f04e091720f7c146a9bc73a339c6a6c505927f0b369300ce69a1db",
"T3T1_fr_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "6dba8b6bfd2af082cd191e9b986f9ea3861ec28a11592e0048eb874b8c432e3b",
-"T3T1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "30db81763d6d91d4c91fdd870e516889c9378efe4ee9ec8ab7940431eaea6a8d",
+"T3T1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "aa199aefbfef7996007ae8dfaa47094d171dc7b362e6d1bd949c038a10b67614",
"T3T1_fr_webauthn-test_u2f_counter.py::test_u2f_counter": "aa72dfd17391ca58696a1e043c0ffd7316cf8fab95a4df864c072c6904127433",
"T3T1_fr_zcash-test_sign_tx.py::test_external_presigned": "f93231b1d054ed3c244ddb1f993d7394c7bacb7d522a8ac183ba2651066ee563",
"T3T1_fr_zcash-test_sign_tx.py::test_one_two": "7b7c1d04dd71013e35b954f21e226f4047b37a2efb520bef7cce0dd98966a6ed",
@@ -30279,7 +30279,7 @@
"T3T1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "47dc1cca5845437205b8866c2daa725f41abd47093a33375fc82b6ecb88a3157",
"T3T1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "6534a0d3474df6cb923e2fabf680997f54365e051168ad44698c71199eddbe74",
"T3T1_pt_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "62e4176ab88b4b5fb6550c7ad9dceb1bab304f4a3cf66aa77623956a28609226",
-"T3T1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "dd0cf886c63379d9550544fa5a763dcf33ae09d5dbe0373bb96757aa93677529",
+"T3T1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "8c9fc3ccf21c8e95cf87921d420f236b375cbb27a464933bf94ae3224945516c",
"T3T1_pt_webauthn-test_u2f_counter.py::test_u2f_counter": "767c0287a73905ef855648d06f2d40fe07b0e4ae7b1dfad0f54e2cc9f253a638",
"T3T1_pt_zcash-test_sign_tx.py::test_external_presigned": "a8db7f034b8bb01675ddadbd03c5451674ab89ff08f991a4893f7313b50beacb",
"T3T1_pt_zcash-test_sign_tx.py::test_one_two": "dc53b1c7e3db251e044379231b09f8573f07a69067651bcb38ecce0857146dc2",
@@ -32510,7 +32510,7 @@
"T3W1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "afbe81d745d95232601d61f2705a60c3fc6e5669a900f57d7fd3bd794d3413d9",
"T3W1_cs_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "9aedfc0fca6c3c9af7e95fabb71e2a7afaa357151be4498d77cb8d27b9539cbc",
"T3W1_cs_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "90b8a2109f0f90e8e9a23e747ee5b96905f998f70025cffecf54eaa6ac0fecc6",
-"T3W1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "41e0ff0345000141e896ac5e1b7efccba213037de18b5eb8c0882be670034b18",
+"T3W1_cs_webauthn-test_msg_webauthn.py::test_add_remove": "5f6831bbaec8072c8a0d35da39692b62886e8de96ab4cde0d7783f5d6a5b714b",
"T3W1_cs_webauthn-test_u2f_counter.py::test_u2f_counter": "3384ce14138163512ed53ca5d68499080d4c54d81ca071585bb552afdd1b6e57",
"T3W1_cs_zcash-test_sign_tx.py::test_external_presigned": "ff4897202e07f79d111bd31e700d34deda41cb83fa7b0802b721287e624e255e",
"T3W1_cs_zcash-test_sign_tx.py::test_one_two": "695270b12a5afbb4dc66e7291041576140ae8c9f82e81d82d93287d0d5cf412b",
@@ -34095,7 +34095,7 @@
"T3W1_de_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "cdcfca9b37047ee12a7ec0fc6ef5b89757c7a155ce6bea2900cbc4d88f883380",
"T3W1_de_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "d66e6deaeb479ec167b00a3763cdc343c9702cc125fdf108b10c9689a348506a",
"T3W1_de_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "55818ffbbc82f11446133d23c07c4249e14d1751536c73e383fc40a883cd065e",
-"T3W1_de_webauthn-test_msg_webauthn.py::test_add_remove": "863a2e211e9f25759e0c0621ec25a265145319c205fdf3ae5770e6eebb7e120e",
+"T3W1_de_webauthn-test_msg_webauthn.py::test_add_remove": "e26be91da6eacfe429537edde5e71f7273435627d5cff436cc0d23e148bfbbec",
"T3W1_de_webauthn-test_u2f_counter.py::test_u2f_counter": "d9ab4afce880a5c149e95a70a5d45af550ae3c186448e16665cc4ca8ffbd6523",
"T3W1_de_zcash-test_sign_tx.py::test_external_presigned": "d5158e7b429f9dadc6c4141521c993fc2a20f27deab63577bc4ec1191eb5f9b8",
"T3W1_de_zcash-test_sign_tx.py::test_one_two": "95bb163462307010eb4fb283fe5796e4e14351041685e16622d75ae81d37c5e6",
@@ -35680,7 +35680,7 @@
"T3W1_en_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "32df03e8f82e6ca4dd5546717a28a736e9b1a2cbcd7d8a1c3a9ffaec9695bd71",
"T3W1_en_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "ce49e7c31c9c7ace469a3d5d9856e6680f2e53a7f392669ec5a170cfe229c5a0",
"T3W1_en_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "16f4c2dbf0ebe7da5fc3828bc212f4bd75a8a1dd6f2586f2b0a3a92eb8ec73e1",
-"T3W1_en_webauthn-test_msg_webauthn.py::test_add_remove": "222e1dc521b9a3ccfb91530fd9246664a62a102f1595b78b7207ec9348036017",
+"T3W1_en_webauthn-test_msg_webauthn.py::test_add_remove": "b21a6f1e244b383a325fe664c5574dff4321846bda66ad695c38df147662a8d0",
"T3W1_en_webauthn-test_u2f_counter.py::test_u2f_counter": "109039621b36fd1ebe09cd76f7e898259aafa80401a8bd91799e448a6e134f79",
"T3W1_en_zcash-test_sign_tx.py::test_external_presigned": "2d4c3a0d35c9c88a2113b355ea1e47d90aa943d3d7b8497bfbd3b8d8f94644cb",
"T3W1_en_zcash-test_sign_tx.py::test_one_two": "ad5b298d48fb7d452c90e6770a6c7a34208311850cfadba3f502b72c646c0ed9",
@@ -37265,7 +37265,7 @@
"T3W1_es_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "93274ff5c17aa5dbd177098a08c514dfe2a39fbd232d14ac6d95aae13627e6d0",
"T3W1_es_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "dcc271fb8dcbe67221c6ac0e8f5516bdc4304d2012b7a1628b5e76ae8b2ee3f2",
"T3W1_es_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "4df17723336d1e05f5fa81f516a326f816321918390a45e0bd62cd03d532df36",
-"T3W1_es_webauthn-test_msg_webauthn.py::test_add_remove": "048cf2fd22ccf58994f9e729252c4a470f417c3a73f42eeb5affe273ebe9cb5b",
+"T3W1_es_webauthn-test_msg_webauthn.py::test_add_remove": "87744e0bdbdd5bc6bf02102b8ee6421dbeb540e250da205c9f514fff02b01297",
"T3W1_es_webauthn-test_u2f_counter.py::test_u2f_counter": "813b59a0c86c9801d39e952d27c2708e3cc35219aeef4bde9d091f6ced445c02",
"T3W1_es_zcash-test_sign_tx.py::test_external_presigned": "3e4c65bc1875f11f7484e5ca0782b108bbe54613fb078e2c3d07f721957a38a7",
"T3W1_es_zcash-test_sign_tx.py::test_one_two": "3add7a8bd59a95f5813daad758ae0012a55a604540013a050cbb557232912f75",
@@ -38850,7 +38850,7 @@
"T3W1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "537ebbf4d403b77ca2cf43ccd4663cffa3f5933cb788508c975065400aa0c573",
"T3W1_fr_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "cd6dff1f49a3e10558fa878e88e3c9212e82eba18598a0fb06ba563536e649ae",
"T3W1_fr_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "d517c87f8f92d6fb47e0f4be7c91157cfeb5d3deb4ffb663ef59cfe42875c113",
-"T3W1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "5346304ff4c3d817f5804c64a656a3bd9e4c353575bb1fcbab46796003f61f64",
+"T3W1_fr_webauthn-test_msg_webauthn.py::test_add_remove": "4924be6afc60e462082f544c067d22e98af12d4f1e971f8a3c9d1220c565a479",
"T3W1_fr_webauthn-test_u2f_counter.py::test_u2f_counter": "033c546199c5ce4a81246ce4acfd1f16ad39fef83bd6deeb8fa5d67ad8842494",
"T3W1_fr_zcash-test_sign_tx.py::test_external_presigned": "fac7b7d229b82603fd045884dfa7006cbd9ebdb3f563d8aa4b57a01a338a411b",
"T3W1_fr_zcash-test_sign_tx.py::test_one_two": "558c4184302a964625e17894e88d6f3ea0386ce177176e6f16feb50b7b304100",
@@ -40440,7 +40440,7 @@
"T3W1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[Stake_for_Energy]": "021a23a4a829f182da664c4f26ee9bcddbd07cacfdda52da3dd3f15c043b9f44",
"T3W1_pt_tron-test_sign_tx.py::test_ui_cancel_flow[TriggerSmartContract_USDT_transfer]": "02373d5633e499a61ae7b028d3cc50166b8528bae0e7878380e388334d616163",
"T3W1_pt_tron-test_sign_tx.py::test_ui_cancel_unknown_contract[TriggerSmartContract_unknown_contract]": "46a2c8f5ff8979cbf2d66c748aeb9f60082674b74f95cbc3bcf4d49b3b31c789",
-"T3W1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "a1ed451071cde0e63427435fd7b65cb69636cf2df720d37f78f4008142a2865b",
+"T3W1_pt_webauthn-test_msg_webauthn.py::test_add_remove": "a2a734331f9e19e5cecfe9b4a894f47409f7f9ddde8a2fdbc3cb74d609680c4e",
"T3W1_pt_webauthn-test_u2f_counter.py::test_u2f_counter": "3fb0b0df6622e98475343c3d518ef83717b0a7d0104b33708d19848035a57390",
"T3W1_pt_zcash-test_sign_tx.py::test_external_presigned": "741944bfedf75294b8807d0e91cca8ed2053cd9b68f5445e84b53c2c72cd2fa0",
"T3W1_pt_zcash-test_sign_tx.py::test_one_two": "0d99b72dc52a4066ca7f8273e7c0b571c4b2620c068318090358bf2b820f1dbc",
Why this scored 21/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.