Skip to content

test(reset): host-selected dice modes, verified against the published derivations - #222

Draft
BitHighlander wants to merge 5 commits into
reconcile/upstream-syncfrom
feat/dice-modes
Draft

test(reset): host-selected dice modes, verified against the published derivations#222
BitHighlander wants to merge 5 commits into
reconcile/upstream-syncfrom
feat/dice-modes

Conversation

@BitHighlander

Copy link
Copy Markdown
Contributor

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_only without dice_entropy is refused.

Bindings regenerated inside kktech/firmware:v8 from keepkey/device-protocol feat/dice-only-field. Regeneration also surfaced that the checked-in Solana bindings lacked clearsign_certificate (field 13), which the pinned submodule has carried since f54f0a7; 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.

…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant