test(reset): host-selected dice modes, verified against the published derivations - #222
Draft
BitHighlander wants to merge 5 commits into
Draft
test(reset): host-selected dice modes, verified against the published derivations#222BitHighlander wants to merge 5 commits into
BitHighlander wants to merge 5 commits into
Conversation
…odes The dice ceremony now opens an on-device selector (MIXED / DICE ONLY) and both modes derive a seed the user can recompute. The old test expected the roll screen first and a seed that mixed the host's EntropyAck bytes; it is replaced by a shared driver plus three tests. Expected values come from the published formulas, restated here and NOT read back from the device: a fixture from the code under test would only prove the firmware agrees with itself. The 24 device-entropy words MIXED shows are decoded by a BIP-39 decoder written here, checksum included, so the words a user would copy down are checked by code the device did not write and the test does not depend on the mnemonic library version in the test image. - mixed: 99 rolls, 24 words; seed = SHA256d(tag || device || SHA256(tag || rolls)) from the shown words and the injected rolls, with the host's nonzero EntropyAck nowhere in it. - only: 50 rolls, 12 words; seed = SHA256(rolls), host bytes ignored. - biased: fifty ones is refused with SyntaxError before any digest. The roll pattern's top-up chunk is now uniform so it clears the 30% bias gate at both targets (max face 17/99, 9/50). This lives on a feature branch, not canonical reconcile/upstream-sync: the release products do not carry the selector yet, and a version gate cannot tell the 7.15 candidate from the 7.15 unit that does. Canonical takes it when both products do.
…e-protocol The checked-in Solana bindings predate the pinned device-protocol: they lack SolanaSignTx.clearsign_certificate (field 13), which up/release-protocol has carried since f54f0a7. Regenerated inside kktech/firmware:v8, the pinned generator, so the old-style _pb2 stays loadable by the test image's runtime. Surfaced by regenerating for the dice_only field; committed separately because it is not part of that change.
… gating The dice mode is now a host-side selection made before the ceremony starts, so a wallet can explain what is coming: ResetDevice.dice_entropy alone is MIXED, with dice_only it is DICE ONLY. The device answers with a consent screen naming the mode it was asked for; holding proceeds, and the only "no" is cancelling the reset. The on-device selector from the previous revision is gone, and with it the DebugLink '1'/'2' injection the tests used. Bindings regenerated from device-protocol feat/dice-only-field @ 451e9a7 (canonical up/release-protocol + the one field) inside kktech/firmware:v8, the pinned generator. The regenerated diff is the new field and the shifted descriptor offsets only. Expected values still come from the published formulas restated here, not from the device, and the 24 device words are decoded by a checksum-verified BIP-39 decoder written here. Adds a test that dice_only without dice_entropy is refused with SyntaxError before any screen.
… the driver Findings from an adversarial review of the unit, all confirmed against the firmware's own font tables and message pump: - The full 32-byte digest wraps to two constant-power subpages, and under DEBUG_LINK each subpage after a debug decision raises its own ButtonRequest. The driver acked once and asserted EntropyRequest, so both verifiability tests would have failed before proving anything. It now holds through every digest page, as the backup-word loop already did. - _inject_rolls diverged from dice_input_collect() once the target was reached: the device stops consuming a chunk at that point, undo included, and leaves the roll screen, so a later chunk would arrive at the digest confirm as a "no" decision. The host simulation now mirrors that exactly and stops sending. - The dice tests were gated on a version. Firmware without the unit skips the unknown dice_only field and runs the older ceremony, so a version gate fails red on such a build -- and a host on the same signal would derive a different wallet without complaint. A Features.supports_dice_modes capability now gates both (requires_dice_modes(), after requires_taproot). Adds tests for the two refusals the review asked for -- dice with no_backup, and Cancel at the consent screen leaving nothing armed -- and catalogues all six dice tests in the report atlas in place of the renamed original, with screen lists matching what each captures. Bindings regenerated inside kktech/firmware:v8 from device-protocol feat/dice-only-field @ fbaf8ec (adds Features.supports_dice_modes = 28).
The K section catalogued the four Dice.Mix* gtests by name; those went with dice_mix(). The 7.15 bitcoin-only leg's catalog validation reported them missing. Replaced with the eight gtests the unit actually has: the two derivation vectors, the zero-draw vector, in-place aliasing, non-collision with the old formula, exact-count, and the two bias-gate tests.
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.
Tests for the verifiable dice ceremony (MIXED / DICE ONLY, host-selected via
ResetDevice.dice_only, on-device consent). Expected values come from the published formulas restated in the test, not from the device; the 24 device-entropy words MIXED shows are decoded by a checksum-verified BIP-39 decoder written in the test. Also: fifty ones are refused as biased before any digest;dice_onlywithoutdice_entropyis refused.Bindings regenerated inside
kktech/firmware:v8from keepkey/device-protocolfeat/dice-only-field. Regeneration also surfaced that the checked-in Solana bindings lackedclearsign_certificate(field 13), which the pinned submodule has carried sincef54f0a7; that is its own commit here.Draft, and must stay unmerged until BOTH release products carry the consent flow: the 7.15 release candidate and the 7.15 unit report the same version, so a version gate cannot tell them apart, and canonical would break the candidate's CI.