test(solana): certified SoltoshiDICE join asserted screen by screen - #112
Merged
Merged
Conversation
The real SoltoshiDICE "Blackjack join" (legacy, no lookup tables), re-keyed so its fee payer is the emulator's key, signed through the certified path with the deployed ClearSign Worker's material: the delegate signature over the 154-byte KKSOLSC1 v2 schema, the public 501-scope certificate, and the KeepKeySolanaTokenDef/2 definition of SDICE. None of it binds a transaction. AdvancedMode stays off. - every screen's text, in order: compute-unit limit, the Transfer companion (funding account, then 0.002 SOL to the session key), the certified signer, Round 86, Revision 980, Seat 1, Buy-in / Allowance / Max wager as 1000.000000 SDICE over the full mint, the session key, Expires in 1 h, the sign prompt; then the ed25519 signature is verified over the message - the real join sets no compute-unit price, so it has no Fee screens; a priced variant shows Fee payer and Max priority fee before the sign prompt - no definition, or a one-byte-changed definition signature: raw base units beside the mint, identical frames, still signs - AdvancedMode on: the same certified review frame for frame, no Blind Sign Catalogued as S30-S33 (7.16.0+); S30 declares its 14 screens and shows them all, in order, in the report.
…t skips
TestSolanaSchemaCertified skipped whenever the device refused the public
501-scope certificate ("Invalid certified Solana certificate"). Every 7.16
build embeds the ClearSign root, so that refusal is a regression, and the
skip turned it into a green run: a scope mutant turned all seven certified
tests into skips. setUp now fails with "7.16+ firmware must embed the
ClearSign root". The version and bitcoin-only skips are unchanged.
No other pyk test skips on a missing root.
test_relay_certified_v0_no_lookup_proof_reaches_signer_check already fails.
Documented: CERT_501 chains to the ALPHA root. Production gets its own
root key after the 7.15 re-release, not before, so the certified tier is
alpha-only. The S30 report text no longer says root-less builds skip.
…efused
An adversarial check found that deleting the delegate-attestation check
from the certified branch of fsm_msg_solana.h (fw 88ed0390c) left every
unit and pyk test green: that firmware signed the SoltoshiDICE join under
a schema renamed "Claim airdrop!" with a signature of 64 x 0x01, AdvancedMode
off, under the "KeepKey Vault / Signer A9531B9D" header.
Three refusals on the real join re-keyed to this device, with the SDICE
definition, so the schema proof is the only thing wrong. Each asserts the
exact Failure (code and message), that no screen was shown, and that no
signature came back:
- the delegate's schema signature with one byte changed:
"Certified Solana schema does not match transaction"
- the instruction renamed (same length) under the original signature:
"Certified Solana schema does not match transaction"
- no schema_signature: "Incomplete certified Solana ClearSign proof"
There is no case for a schema signed under another scope: the delegate
signs sha256(schema), which carries no scope, and the alpha root has
issued no public certificate for any scope but 501.
Proven on native kkemu builds of fw 88ed0390c: all pass on the control;
the first two fail on the mutant without the check ("signed after 14
screens"); the third guards the completeness check, which that mutant
keeps.
…ture Adversarial mutants of fw 88ed0390c lib/firmware/fsm_msg_solana.h left every pyk and unit test green: - Sf passes the certificate's own scope instead of 501 (:882, :927). - L passes a fixed 64 instead of msg->schema_signature.size (:928). Both signed the SoltoshiDICE join after 14 screens. Two refusals now cover them, on the real join re-keyed to this device with the SDICE definition: - test_certified_wrong_scope_certificate_refused: the delegate's real schema signature under CERT_SCOPE1, the public alpha EVM-scope (scope 1) certificate for the same delegate 0342f5f9. The delegate signs sha256(schema), which carries no scope, so only the scope check refuses it: "Invalid certified Solana certificate". - test_certified_short_schema_signature_refused: SOLTOSHI_SCHEMA_SIG[:63]. Its last byte is 0x00, so the zeroed 64-byte field holds the real signature again: "Certified Solana schema does not match transaction". CERT_SCOPE1 is a fixed constant, fetched once on 2026-09-19 from POST https://keepkey-clearsign.bithighlander.workers.dev/v1/evm/schema (the chainId 1 Relay bridgeDeposit shape): bytes [1:140] of its signedPayload. Nothing is fetched at test time. This also corrects the comment that said the alpha root had issued no public certificate for any scope but 501. Proven on native kkemu builds of fw 88ed0390c (KK_FORCE_UDP=1): test_msg_solana_schema_v2.py passes 15/15 on the control. The scope test fails on Sf and on S (the scope comparison dropped from clearsign_root.c). The length test fails on L. Each failure is "signed after 14 screens". All six test_msg_solana_*.py files pass 68/68 on the control.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Emulator coverage for the certified SoltoshiDICE "Blackjack join", using the material the deployed ClearSign Worker returns for it. The four new tests are in
tests/test_msg_solana_schema_v2.py(classTestSolanaSchemaCertified) and are catalogued as S30-S33 inscripts/generate-test-report.py.__tests__/fixtures/solana/soltoshidice-blackjack-join.json). Account 0, the fee payer and only signer, is replaced with the emulator's key.schema_signer_key_id=128), the public 501-scope certificate, and the KeepKeySolanaTokenDef/2 definition of SDICE (6 decimals, key id 128). None of these signatures covers a transaction, so they still apply after the re-key.Tests
test_certified_soltoshi_join_reviews_every_screenSet compute unit limit to 200000?,Funding account <device>,Send 0.002000000 SOL to BqtZ8PRQywD9Z5xXeB5112wtPG3xtj7TqF56hroicGjX?,KeepKey Vault / Signer A9531B9D,SoltoshiDICE / Blackjack join, Round86, Revision980, Seat1, Buy-in / Allowance / Max wager1000.000000 SDICEwith the full mint on the next line, Session keyBqtZ8..., Expires in1 h,Sign this Solana transaction?. Then it checks a 64-byte ed25519 signature against the device key over the message (pycryptodomeeddsa, which the CI test image already installs).test_certified_soltoshi_join_priority_fee_names_fee_payerFee payerscreen (fsm_msg_solana.hsolana_confirmPriorityFeereturns early). This test adds a SetComputeUnitPrice and checks all 17 screens, includingFee payer <device>andMax priority fee 0.000200000 SOLright before the sign prompt.test_certified_soltoshi_join_untrusted_definition_shows_base_unitstoken_info, all three amounts show1000000000 base units of mintplus the mint. A definition with one byte of its signature changed produces frames identical to that. Both still sign.test_certified_soltoshi_join_ignores_blind_sign_policyBLIND SIGNscreen.Report catalog
FULL_SEQUENCE_TESTS, so the PDF shows every review screen in order._TEST_MIN_VERSION)._require_alpha_root("7.16+ firmware must embed the ClearSign root"). It used to skip, and a skip passes both validation and the audit (see round 2 below).Verification (local)
All runs used kkemu built from a
git archiveexport of keepkey-firmware4e2fd13a7(draft PR #829 head) withKK_CLEARSIGN_ALPHA_ROOT=ON. Every run setKK_FORCE_UDP=1and used private UDP ports 24844/24845.tests/test_msg_solana_*.pyfiles ran with 63 passed, 0 skipped. That is round 3's 59 plus these 4.--section S --screenshot-test-list; all passed, with 113 PNGs.--section S --screenshot-auditthen reported "every declared screen was captured".--section S --validate-junitpasses for full and bitcoin-only at 7.16.0, and for 7.15.0. Control: with the four tests removed from the JUnit, it fails with S30-S33missing.tests/test_report_variant_validation.pyhas 4 passed./1certified=falseat the fsm call siteRound 2: refusals, and fail instead of skip (
adfa293,61cb412)An adversarial check found that deleting
clearsign_root_verify_delegate_attestation(...)from the certified branch offsm_msg_solana.h(fw88ed0390c) left 200/200 unit and 63 pyk tests green, and that firmware signed the join under a schema renamedClaim airdrop!with a signature of 64 x0x01.New tests in
TestSolanaSchemaCertified. Each uses the real join re-keyed to the device, with the SDICE definition, and asserts the exact Failure (code 3 and message), that no screen was shown, and that no signature came back:test_certified_schema_signature_one_byte_changed_refusedCertified Solana schema does not match transactiontest_certified_edited_schema_refusedBlackjack joinrenamedClaim airdrop!(same length), original signatureCertified Solana schema does not match transactiontest_certified_proof_without_schema_signature_refusedschema_signatureIncomplete certified Solana ClearSign proofThere is no case for a schema signed under another scope. The delegate signs sha256(schema), which carries no scope, and the alpha root has issued no public certificate for any scope except 501.
_require_alpha_rootnow fails instead of skipping. The version and bitcoin-only skips are unchanged. No other pyk test skips when the root is missing;test_relay_certified_v0_no_lookup_proof_reaches_signer_checkalready fails.Alpha only:
CERT_501chains to the ALPHA ClearSign root (02de9231...dae7). Production gets its own root key after the 7.15 re-release, not before, so this certified tier stays alpha-only. This is documented in the test module and in the S30 report text.Verification: native kkemu builds of fw
88ed0390c, run withKK_FORCE_UDP=1on private UDP ports:test_msg_solana_schema_v2.py13 passed. All sixtest_msg_solana_*.pyfiles: 66 passed, 0 skipped.signed after 14 screens. The third passes, because it guards the completeness check, which that mutant keeps.7.16+ firmware must embed the ClearSign root(they skipped before). The 3 runtime and attestor tests pass.ast.parse(feature_version=(3,6))).Not done here
deps/python-keepkey) needs to pin this commit. pyk's own CI does not trigger for a PR intoalpha.ast.parse(feature_version=(3,6))). No local 3.6 interpreter was available.