Skip to content

wallet: Add checksummed recovery-record evidence #43

Description

@BenWestgate

The wallet record is the human-scale, second-class accident-safety evidence below the encrypted descriptor backup (#55). Fresh creation does not need to authenticate a pre-existing wallet, but it does need to verify that the operator copied the new fingerprint correctly: after showing it, GUI/CLI setup should hide it and require the operator to type it back from the paper record before finishing.

This issue improves the record itself and what restore can accept:

  • Fingerprint error correction: write the fingerprint as its 8 hex digits, #, and 4 Reed-Solomon check characters in the bech32 alphabet. Example: 3f3521a6#ly6e.
    • Code: Reed-Solomon over codex32's GF(32) (x^5 + x^3 + 1). The hex digit values are the 8 data symbols, first digit highest. The check characters are the remainder of d(x)·x^4 mod (x − α)(x − α^2)(x − α^3)(x − α^4), with α = 2. Hex and checksum are case-insensitive.
    • It corrects any 2 wrong characters or fills 4 unreadable ones (2s + e ≤ 4). That covers any single typo and any swap of two characters, including across the #. At the same typo rate per character, a record is about as likely to be unrepairable as a 48-character codex32 share.
    • The decoder works like codex32 correction. It handles substitutions, unreadable characters, and one missing or extra character, and offers a suggestion the operator confirms against the paper record.
    • Matching against a recovered fingerprint needs no decoder: accept when 2s + e ≤ 4. At most one fingerprint is that close to any typed record, so the check keeps all 32 bits (cli: Ask for the wallet record fingerprint before the shares or seed #91).
    • Not chosen: a 6-character bech32m checksum (distance 6, corrects 2 typos or 5 unreadable), Core's 8-character descriptor checksum (distance 7, 3 or 6), and 2 or 3 Reed-Solomon characters, which can't guarantee correcting every swap.
    • Plain 8-hex fingerprints from older/other wallets remain accepted, but are explicitly unchecked for record damage.
  • Fresh creation type-back: after the operator records the new fingerprint, hide the on-screen value and require re-entry from the paper record. A mismatch must stay in the record-confirmation step and must not be replaced by a simple “I wrote it down” acknowledgment.
  • Single-sig descriptor evidence: also record the checksum of a canonical single-sig descriptor (or the compact canonical descriptor identity chosen by the wallet format). Restore may accept a matching typed fingerprint, a matching typed descriptor checksum, or both. This is an accident check tied to the actual wallet descriptor; it is not a replacement for authenticating the full descriptor backup in wallet: Encrypted descriptor backup keyed by the seed #55.
    • Define the exact canonical descriptor form before implementation so apostrophe/h, origin formatting, range and network presentation cannot change the checksum for the same intended wallet.
    • The record should say which descriptor the checksum names; do not pick an arbitrary receive template without documenting the contract.
  • Restore entry: GUI and CLI use the same parsers and diagnostics for fingerprint/checksummed fingerprint and descriptor-checksum evidence.
  • QR: qr: Add codex32 and wallet-record QR codes #44 tracks a QR containing the exact wallet-record fields, including fingerprint and descriptor checksum.

Restore evidence order is documented in #26/#30: #55 first class; this wallet-record evidence second class; explicit visual fingerprint + codex32/Bails identifier confirmation when no record exists.

Refs the Tails 7.13 Bails create/restore test feedback in #230.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: securitySecurity invariants, hardening, and security-sensitive boundaries.area: wallet/coreWallet integration and Bitcoin Core boundaries.enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions