Combine: fork alpha into master (master becomes the single target) - #111
Merged
Merged
Conversation
- Hand-written messages_zcash_pb2.py (protobuf 3.x compatible) - Restore original messages_pb2.py / types_pb2.py (don't recompile) - Manual Zcash wire ID registration in mapping.py (1300-1307) - Add zcash_get_orchard_fvk() client method - Add test_msg_zcash_orchard.py with 5 FVK validation tests
- Add zcash_sign_pczt() session helper with ZcashPCZTActionAck loop - Remove stale n_transparent_inputs field from ZcashSignPCZT - Remove stale ZcashTransparentInput/ZcashTransparentSig messages - Proto bindings now match messages-zcash.proto exactly
The reference vectors are from the orchard Rust crate but the firmware currently uses seed_proxy instead of the real BIP-39 seed, so the emulator cannot produce matching output. Mark as @expectedfailure until the seed derivation is fixed.
- Change account default from 0 to None — only send account field when caller explicitly sets it, otherwise firmware derives from address_n[2]. Fixes silent wrong-account signing. - Add @session decorator to keep entire PCZT signing flow in one transport session, matching ethereum_sign_tx and eos_sign_tx_raw.
- Add test_msg_zcash_sign_pczt.py: single-action, multi-action, signature format, account separation tests - Remove @expectedfailure from FVK reference test (seed fix landed)
- Restore @expectedfailure on FVK reference vectors (C derivation doesn't match orchard crate yet — separate from seed access fix) - Fix TypeError in signing test: remove msg arg from assertEqual (test framework doesn't support 3-arg form)
- Regenerate proto files from device-protocol feature/evm-clear-signing - Add ethereum_send_tx_metadata() client method - New messages: EthereumTxMetadata (115), EthereumMetadataAck (116) - All proto files regenerated with protoc 33.0 Backwards compatible — new method is optional, existing API unchanged.
Change zcash_get_orchard_fvk account default from 0 to None. Only serialize account field when explicitly set — firmware derives from address_n[2] otherwise. Same fix as zcash_sign_pczt. Update tests to rely on address_n path derivation.
- signed_metadata.py: canonical binary serializer + secp256k1 signer
matching firmware's parse_metadata_binary() format exactly
- test_msg_ethereum_clear_signing.py: 19 test vectors covering:
- Valid: Aave supply, zero-arg, max-arg (8), Polygon chain
- Invalid signature: wrong key, tampered method/contract/amount, zero sig
- Structural: truncated, empty, wrong version, too many args, invalid
format byte, wrong key slot, extra trailing bytes
- Binding mismatch: wrong chain/contract/selector (sig valid, binding fails)
- Policy: EthBlindSigning disabled → hard reject
- Backwards compat: no metadata → existing flow unchanged
Test key: private=0x01 (secp256k1 generator point G)
Requires: pip install ecdsa
Remove @expectedfailure — the 3 ZIP-32 derivation bugs are now fixed: 1. Child derivation personal: "ZcashIP32Orchard" → "Zcash_ExpandSeed" 2. Domain separator: 0x11 → 0x81 3. Index encoding: big-endian → little-endian (I2LEOSP32)
Identity: keepkey.com/insight (proto=ssh for raw SHA256 signing) Path: m/13'/44358944'/1285410994'/2003068762'/1451542600' Pubkey: 02e3b3015c47ddcaabe4f8e872f1ed8f09ca145a8d81770d92213d56da31ab5107 Cross-validated against pioneer-insight TypeScript derivation.
… tests - zcash_sign_pczt_hybrid(): two-phase signing (transparent ECDSA + Orchard) - 11 tests: happy path, path validation (7 cases), phase ordering
- Happy path tests now verify DER signatures cryptographically: derives pubkey from device, verifies ECDSA against the sighash - Cross-key test: sig for key[0] must not verify against key[1] - Multi-input test: each sig verifies against its own sighash only - Edge cases: out-of-order transparent index, too many inputs (>8) - Total: 14 tests (3 crypto-verified happy path, 7 path validation, 1 phase ordering, 3 edge cases)
- Remove Pillow dependency from screenshot capture (client.py) Pure Python PNG writer using stdlib struct+zlib. Zero build time. - Move screenshot capture from call_raw to callback_ButtonRequest Captures the actual confirmation screen, not idle state. - Per-test screenshot directories in common.py setUp KEEPKEY_SCREENSHOT=1 SCREENSHOT_DIR=path enables capture. - Add scripts/generate-test-report.py (stdlib only, no deps) Auto-detects firmware version, reads JUnit XML for pass/fail, embeds real OLED PNGs in PDF, version-gated sections. - Remove old generate-zoo-report.py Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…ress - .gitmodules: device-protocol URL → BitHighlander/device-protocol - device-protocol: pin to 93d251a (includes ZcashDisplayAddress + ZcashAddress) - Regenerate messages_zcash_pb2.py and messages_pb2.py with protoc 3.5.1 (via kktech/firmware:v15 Docker image for CI compatibility)
Blind-sign policy gating (AdvancedMode blocking) is 7.15+ scope. On 7.10-7.14 blind signing is always permitted. Remove test_ethereum_blind_sign_blocked which expected 7.15 firmware behavior and update report section V accordingly.
The test's own docstring says the feature it exercises requires firmware 7.15.1+, but the gate admitted 7.15.0. Any 7.15.0 build therefore runs a test for behaviour that release is not expected to have: entering a word outside the BIP-39 wordlist returns a CharacterRequest for the next word rather than a Failure, and the assertion fails. No behaviour change -- the gate now matches the docstring beside it.
keepkey#216 landed as one squashed commit whose content had already reached keepkey#197 by another route, so most of the 31 conflicts are the two branches doing the same thing in different words. Resolved by hand, hunk by hunk; no --ours/--theirs. Every keepkey#216 addition is verified present in the merged tree, including the files that never conflicted (test_msg_display_disclosure.py, the eip155 vectors, the ripple/ping/tron/eth-signtx disclosure tests, and the `chain_id is not None` fix in keepkeylib/client.py -- that one matters, it is what lets an explicit chain_id=0 reach the wire to be refused). tests/test_sign_typed_data.py (1 hunk) -- keepkey#197 Same policy call on both sides; the only difference is `with open(...)` vs open/close and one extra clause of comment. Nothing asserted differs. tests/test_msg_thorchain_signtx.py (2 hunks) -- keepkey#197, and this one is a real divergence, not a restatement. keepkey#197 repointed test_sign_eth_add_liquidity at the firmware-pinned THORChain router (to=0xd37bbe57...); that line auto-merged, so it IS the transaction the merged test signs. keepkey#216 regenerated exact r/s against the OLD to=0x41e55600.... `to` is an RLP field of the legacy sighash, so keepkey#216's vectors do not describe the transaction under test and would fail. keepkey#197's structural assertions win on those grounds -- NOT because structural is preferable. They are genuinely weaker than what keepkey#216 had, and the superseded vectors are recorded in a comment at the assertion so the gap is visible and regenerable on-device. Same treatment for the memo-length hunk: both sides independently corrected 0x3b -> 0x3a (the memo is 58 bytes; the 59th was ABI padding), so the comments were combined rather than one dropped. tests/test_msg_mayachain_signtx.py (2 hunks) -- keepkey#197 Same router story (to=0xe3985e6b..., Maya router v4), so keepkey#216's exact r/s -- byte-identical to the thorchain pair, same base fixture -- are stale here too. keepkey#197 does not merely relax: it reconstructs the sighash host-side and recovers the signer, so a wrong digest, wrong calldata or wrong key fails. Taking keepkey#216 would also have re-added a stray `)` and restored @unittest.skip on test_mayachain_remove_liquidity, which keepkey#197 unskipped. Raw assertion count in this file drops 26 -> 13 because seven frozen-vector memo cases became one loop over the same seven memos and three skipped tests now actually run; memo coverage is unchanged at nine cases and none of them are skipped any more. tests/test_msg_ton_signtx.py (9 hunks) -- union Both sides added the identical AdvancedMode opt-in to nine tests; keepkey#216 also carried the four-line reason. Kept keepkey#216's comment and call on all nine. keepkey#197 additionally gated three tests keepkey#216 did not -- the reject-path tests -- and those auto-merged; annotated them, because opening the gate is what stops them passing for the wrong reason (with the gate shut the firmware refuses every TonSignTx and the raises-assertion is satisfied without the parser ever validating a field). scripts/generate-test-report.py (17 hunks) -- keepkey#197 Fifteen hunks are section-letter collisions: keepkey#216 filed Display Binding under 'S' and Display Disclosure under 'D', but 'S' is already Solana and 'D' is already BIP-85 Child Derivation, so keepkey#216's own catalog carries each letter twice. keepkey#197 assigns 'J' and 'Q' and does not collide; _audit_catalog() asserts letter and id uniqueness and would have tripped on keepkey#216's scheme. Entries are otherwise identical -- same module, same test, same prose -- so nothing keepkey#216 catalogued is lost, only relettered. Fixed one cross-reference keepkey#197's rename left dangling: J13's prose said "the control for S12", which now points at a Solana test; it means J12. The other two hunks are keepkey#197-only additions (the F, I, L, U, TD sections and MUST_RUN_MODULES) against an empty keepkey#216 side. tests/test_msg_ethereum_erc20_0x_signtx.py -- union, and git got this one wrong Not one of the 31: it merged clean and merged badly. Both sides inserted an AdvancedMode opt-in into test__sign_transformERC20 at different offsets, so the merged file called apply_policy twice in a row. Deduped to one call carrying both rationales (keepkey#216's 1480-bytes-past-the-1024-chunk mechanism, which is what atlas J1 actually claims, plus keepkey#197's no-recognised-handler note). Folded in the comment keepkey#197 left three lines above it saying "No AdvancedMode policy is set here on purpose", which contradicted its own apply_policy call and both sides' findings; kept as an explicitly superseded note rather than deleted, so the behaviour change stays legible. Verified: 0 conflict markers; every .py under tests/, scripts/ and keepkeylib/ parses; _audit_catalog() passes and the report renders 27 sections / 381 distinct tests; all 383 catalog rows resolve to a test that exists (V17-V67 against CLEARSIGN_FLOWS, which generates those methods by the same transform; K3-K11 are native gtest suites the JUnit parser handles by bare classname). Not verified: no test was executed against firmware. The one suite that runs offline, test_storage_version_gate.py, needs the firmware sources checked out above this tree and errors in setUp without them -- unchanged by this merge.
These three tests lost their emulator guard, and without it they do not fail on the emulator -- they HANG. The ETH/FOX pool contract is not in the token table, and approving an unknown token contract never completes, so the device keeps answering while the approval never finishes. The socket timeout never fires because reads keep succeeding, so the job goes silent until CI kills it on its no-output timeout, taking every later test with it. That is why the suite died at 34% having reported no failure. Gated rather than deleted, so the coverage comes back on its own once the firmware completes this path. Known-token approves still run here, and on hardware the app exercises this path.
TestStorageVersionGateSource asserted STORAGE_VERSION_LAST_SHIPPED exists, so all eleven of its tests failed at setUp against any firmware that predates the storage version gate -- which is every branch except alpha. That is what has been red on CircleCI, which builds firmware master. The gate is a firmware FEATURE, so gate on the capability. A tree that never had it has nothing here to assert. The skip is deliberately narrow: if storage.c references the constant but storage.h no longer defines it, that is the floor being deleted out from under the static assert -- the exact regression this suite exists to catch -- and it still FAILS. The skip cannot swallow the deletion it guards. Verified against three real trees: 7.14.3 runs (floor 17), upstream develop skips, alpha runs (V20, floor 17).
Firmware alpha (6816915a3) replaced direct dice entry with a host-selected mode and an on-device consent screen, then shows the device's 24 words before any roll. That firmware pinned python-keepkey f00e62f; a later re-pin to b44f1b3 (this alpha line) dropped the matching test, so test_reset_device_dice acked the consent screen as roll input and the device answered "Reset cancelled". Rewrite the test body for consent -> device words -> rolls -> digest confirm, and check the mnemonic against the published MIXED formula (device words + rolls; EntropyAck bytes excluded). Seed helpers and the requires_dice_modes capability gate come from f00e62f. Same test name, same two captures the report declares.
Firmware refuses a 68-byte approve(spender, 2^256-1) with "Unlimited ERC20 approval is disabled" (release-line policy since 7.14.2). This alpha line still expected signatures, so three tests failed on every full-variant run. Take the audit-line versions (f00e62f) that assert the refusal: test_approve_all, test_sign_uni_approve_liquidity_ETH, and the erc20-approve-unlimited clear-sign flow. Adds common.firmware_at_least.
Firmware authenticates before showing the SignMessage confirm since 7.14.2; this alpha line still expected the old order. Take the audit-line version (f00e62f), which gates the order on firmware_at_least.
The blocked-without-AdvancedMode case now uses a binary payload, so it holds on every firmware. New 7.16.0 case: a SIWS-style text login signs with AdvancedMode off (BitHighlander/keepkey-firmware#816).
…nonical-protoc fix(protocol): regenerate bindings with the canonical protoc (unblocks firmware integration CI)
…-advanced-mode test(solana): plain-text SignMessage signs without AdvancedMode
Brings keepkey/python-keepkey's consolidated harness line (PR keepkey#197 to upstream master; contains master, hive wire-symbol fix, 7.15 audit fixes, bitcoin-only capability gates) into fork alpha: 84 commits. Resolution rules: - device-protocol pin, .gitmodules and generated bindings: alpha. Upstream's dp 27d3fa1 lacks the ERC-7730 and dice-mode protocol (moving to it deletes ~590 proto lines); bindings stay canonical-protoc (py3.6/protobuf 3.17). - Harness (conftest network guard, common, client capture): upstream. Its guard admits only the exact configured UDP emulator endpoints plus owned leases. Removed the duplicate screenshot-selection hook alpha had ported. - generate-test-report.py: upstream, keeping --build-variant as an alias of --variant (firmware CI passes --build-variant), alpha's --section option, and alpha's uniswap-liquidity must-run floor (GH #516) + its bitcoin-only waiver. - test_msg_resetdevice.py: dice-modes version (f00e62f); firmware alpha runs the consented MIXED/ONLY flow, reconcile still has the old one. - test_storage_version_gate.py: alpha's framed-record before/after pair (refresh_crc + sector) — firmware alpha stores framed journal records. - test_msg_solana_signtx.py: alpha's stake layouts (validated against firmware alpha in CI) and the plain-text SignMessage test. - test_msg_eos_signtx.py: alpha's version-gated golden. - Dropped the unused noncanonical taproot prevtx fixture (upstream fc12c6d). - CI configs: alpha's firmware targets; upstream's SHA check and the printf fix for the backtick-in-echo summary bug, applied to all four. Offline: test_tx_fixture_integrity, test_network_policy, protocol bindings 15 passed; tx_fixture_manifest --check clean.
The host-selected dice modes with on-device consent that firmware alpha implements (MIXED, ONLY, bias gate, supports_dice_modes gating) plus the report catalog entries for the new native dice tests. Bindings and the device-protocol pin stay alpha's (canonical protoc; already carry the dice fields). Dropped the requires_dice_modes copy alpha had ported.
Content was already on alpha under different commits; this records the ancestry. Kept alpha's KK_EXPECTED_FIRMWARE_REVISION provenance check (upstream's GITHUB_SHA is the synthetic PR merge ref) and alpha's device-protocol pin.
Takes the CircleCI retirement (alpha's workflow already documents it as retired). Keeps alpha's integration workflow, which runs against the fork firmware candidates; this branch's version runs against a published emulator image and so tests stale firmware by its own note.
Ancestry only, no tree change: - feat/dice-modes: all 5 patches present via feat/dice-modes-rebased - fix/defer-blind-sign-to-715: patch present - feat/test-report-generator: the original March generator; superseded by the current scripts/generate-test-report.py - pre-squash-197-backup: 3428e0b (storage-gate skip) already present via reconcile; 1f6c240 (skip the FOX-pool uniswap tests on the emulator) intentionally NOT taken -- those tests no longer hang, they assert the unlimited-approve refusal and are must-run (GH #516)
The upstream harness stopped capturing a screenshot on every wire Failure (capture explicitly where firmware renders), so the "Home screen at the refusal" frames I4/I6 declared no longer exist, and E17 now asserts the unlimited-approve refusal (one AdvancedMode confirm) rather than a signed approval. Take the entries from origin/merge/alpha-715, which already describe these flows. Firmware CI captured exactly 1/3/4 frames.
The debug build raises one ButtonRequest per physical subpage and every
subpage of a word group reports the same reset_word; whether a group
spills to a second subpage depends on glyph widths. With a random
mnemonic this made the test flaky ("Invalid mnemonic, are words in
correct order?"): it passed and then failed on consecutive CI runs of
the same firmware. Same de-duplication test_msg_resetdevice already uses.
…ctations 8d3f4cc aligned these to keepkey/release/7.15 f3d9e058e, which is wrong on the wire in both places: - XRP: MemoData is Blob field 13 (0x7D). 0x72 is MessageKey, which rippled rejects inside a Memo object (ripple-binary-codec definitions.json). Every other firmware line, alpha included, emits 0x7D. - Hive: memo_key is optional<> in account_update2 (op 43) in both dhive and hive-tx; it is mandatory only in legacy account_update (op 10). The builder dropped the presence byte, so firmware read 0x02 as a bool and failed with "malformed". Vectors 2/3 now carry a present memo key and must be refused as an authority change on every line.
Merge all keepkey/python-keepkey upstream branches into alpha
Emulator tests for keepkey-firmware feat/solana-schema-v2 (issue #828),
asserting what the OLED says rather than how many screens there are.
tests/oled_text.py reads text off a DebugLink frame. DebugLinkState.layout
is pixels only, so it renders the expected string with the firmware's own
title and body glyphs (tables generated from lib/board/font.c; `python
oled_text.py font.c` regenerates them), wraps it as draw_string_walk()
does, and requires every line whole and left-aligned on consecutive rows of
one screen. On recorded frames it rejects one-character changes, dropped
characters and prefixes of every checked string.
test_msg_solana_schema_v2.py:
- Certified (public Vault 501 certificate + the real Relay v1 delegate
signature): a static System Transfer companion is reviewed ("Funding
account", then "Send 0.002000000 SOL to <dest>?" under INSTR 2/2); with
SetComputeUnitPrice the review shows "Fee payer <key>" and "Max priority
fee 0.000200000 SOL" on consecutive FEE screens; a duplicate price or limit
is refused with "Invalid priority fee". These skip when the emulator
refuses the certificate because it was built without the alpha ClearSign
root, and fail on any other refusal.
- Runtime (CI signer in slots 2 and 3): a Transfer companion is refused;
on the real SoltoshiDICE join signed by slot 2, slot 2's SDICE definition
shows "1000.000000 SDICE" with the mint beneath it for all three
TOKEN_AMOUNTs, while slot 3's definition renders pixel-identical to none
("1000000000 base units of mint" + mint).
- ClearsignAttestor: a v2 TOKEN_AMOUNT arg costs exactly one extra screen,
"Arg 1 token mint is / account #3", right after the arg, and the returned
signature verifies over sha256(payload).
Each of these firmware mutations fails at least one test: certified reviews
not binding the priority fee, the attestor mint screen removed, the mint
dropped beside a trusted symbol, companion instructions not screened, the
fee computed without the explicit compute-unit limit (same screen count,
different text), and runtime token definitions accepted from any slot.
test(solana): KKSOLSC1 v2 schema reviews asserted by screen text
The job starts container kkemu-7143 and reads junit-7143.xml and status-7143, but its test step still inspected kkemu-rc18 and wrote junit-rc18.xml / status-rc18. docker inspect failed before pytest ran, so the 7.14.3 gate reported red with zero tests executed.
e07a95e7d predates keepkey-firmware#824 (unknown-token consent review, EIP-712 outermost-first dimensions, the release draw.c paging rule, unlimited-approve refusal), which the suite on this head now expects. Firmware CI already runs this python-keepkey head against b452f011c.
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.
The class gated only on the bitcoin-only variant, so on 7.14.3 all 13
tests hit "Unknown message" on their first message. No 7.14.x release
or 7.14.3 candidate carries the privacy engine; it ships from 7.15.0.
Gate on requires_firmware("7.15.0") (develop builds labelled 7.14.x
speak the draft protocol) plus a probe of ZcashSignPCZT, the session
opener. ZcashTransparentInput cannot be probed (required field, the
probe no-ops) and ZcashPCZTAction is refused outside a session (the
probe would skip on 7.15/7.16).
The 7.16.0 gate recorded the branch the fix first landed on, not the firmware that has it. The eos_hashAuthorization() fix (fork #568/#563) is on the 7.14.3, 7.15 and 7.16 release heads, so 7.14.3 fell through to the old golden and failed on a correct digest. Assert 5938294e... from 7.14.3 on. It matches two independent EOSIO ABI serializers and same-shape mainnet updateauth transactions. The old golden fb936ef1... hashed a phantom zero wait; older firmware now skips the SLIP-48 half instead of asserting that known-bad digest.
…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.
…ified test(solana): certified SoltoshiDICE join asserted screen by screen
651f2a462 merges keepkey-firmware#829 (KKSOLSC1 schema v2), which the certified and runtime schema-v2 tests on this head require. b452f011c predates it and fails those 5 tests while reporting the same 7.16.0.
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.
Why
The fork had two live targets. The ERC-7730 pyk PRs (#92, #93) went to
master. The firmware-alpha work (#108 upstream sync, #109, #110) went toalpha. Firmware alpha's.gitmodulesalready tracksbranch = master. From now onmasteris the single target, andalphais retired once this lands.What
alpha(1c5e544e) is 179 commits ahead ofmaster(54d4f6d5) and 0 behind, so this is a fast-forward and every commit the firmware pins stays reachable. Contents:keepkey/python-keepkeymerged in (Merge all keepkey/python-keepkey upstream branches into alpha #109).account_update2and XRP MemoData expectations restored to wire-correct values (fork issue keepkey-firmware#827).tests/oled_text.py,tests/test_msg_solana_schema_v2.py, test(solana): KKSOLSC1 v2 schema reviews asserted by screen text #110).Evidence so far
Firmware alpha CI ran this exact pyk head:
python-integration-testsfull = 777 passed, 0 failed; bitcoin-only is green. This PR is the first run of pyk's own CI (7.15 / 7.14.3 release candidates) on the combined content. Its results are compared againstmaster's existing baseline (integrationandintegration-rc18already fail on54d4f6d5).