Skip to content

About

Physical-entropy-first BIP-39 seed generation for air-gapped machines

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SeedPrimer

Physical-entropy-first BIP-39 seed generation for air-gapped machines.

SeedPrimer generates BIP-39 mnemonics (12 or 24 words) from physical entropy sources — playing cards, D6 dice, and DnD dice sets — with optional Raspberry Pi Pico 2 TRNG hardware injection and a full statistical test suite to audit your physical draw before committing to a seed.

Designed to run offline on an air-gapped laptop. No network code. No external dependencies beyond Python 3 and tkinter (pyserial optional, for Pico TRNG).

See TUTORIAL.md for a complete step-by-step guide covering installation, every input mode, Pico 2 firmware setup and qualification, safe mnemonic recording, and air-gapped operation.


Input modes

Mode Source Min input Words Target
Cards only 27 cards from a shuffled deck 27 cards 12 128-bit
Cards + D6 Full deck + dice 52 cards + 20 rolls 24 256-bit
D6 only (128-bit) D6 dice rolls in groups 60 rolls (12 groups of 5) 12 128-bit
D6 only (256-bit) D6 dice rolls in groups 120 rolls (24 groups of 5) 24 256-bit
DnD (128-bit) D4/D6/D8/D10/D12/D20 full set 10 throws 12 128-bit
DnD (256-bit) D4/D6/D8/D10/D12/D20 full set 20 throws 24 256-bit
D8+D16×2 (128-bit) D8 + D16 + D16 12 throws 12 128-bit
D8+D16×2 (256-bit) D8 + D16 + D16 24 throws 24 256-bit

Pipeline

Every session follows the same four phases:

Settings → Physical input → Statistical analysis → Hash + mnemonic

1. Settings

Choose your input mode, dice quality (consumer / precision), and shuffle count (card modes). The Pico 2 TRNG panel lets you scan for a connected Pico and enable hardware entropy injection.

Shuffle quality (card modes): the entropy deduction for imperfect shuffling is computed from the Bayer-Diaconis (1992) total variation distance for a riffle-shuffled deck. At 7 shuffles: ~76 bits lost. At 10 shuffles: ~10 bits lost. At 12+: under 3 bits. Fewer than 7 shuffles is blocked outright.

2. Physical input

Depending on mode:

  • Cards: click cards in draw order. Each card is clickable once. A live entropy gauge tracks discounted bits against the target.
  • D6: select how many dice you roll per throw (1-12). Click each face value. Rolls commit in groups; the progress tracker shows groups complete and remaining.
  • DnD: six columns, one per die. Click one face value per column. The throw commits automatically when all six are selected. D10 face "0" is entered as 0. D20 is split into two sub-columns (1-10, 11-20) for readability.

3. Statistical analysis

14 symbol-level tests on your raw physical draw — before whitening. Tests catch realistic failure modes: weak shuffles, dice bias, human rolling patterns, and periodicity. Results are shown as PASS / BORDERLINE / FLAG with explanations.

Shannon entropy is shown informationally for all modes but does not gate the session — at the sample sizes used here, Shannon compounding across multiple tests produces unacceptable false-positive rates and is excluded from the STOP/CAUTION decision.

False-positive rates (fair input, 5000-trial Monte Carlo):

Mode Effective FP (STOP + CAUTION)
Cards only 128-bit ~6%
Cards + D6 256-bit ~19%
D6-only 128-bit ~8%
D6-only 256-bit ~9%
DnD 128-bit ~0%
DnD 256-bit ~0%

4. Hash + mnemonic

Your physical draw is combined with optional Pico TRNG bytes (XOR, pre-whitening), then whitened with SHA-256, then encoded as a BIP-39 mnemonic. The mnemonic is shown masked by default with a reveal button. A QR code (CompactSeedQR format) is generated for air-gap transfer.


Pico 2 TRNG hardware injection

If a Raspberry Pi Pico 2 (RP2350) running the SeedPrimer TRNG firmware is connected via USB, its output is XOR'd into your raw physical entropy before SHA-256 whitening.

The XOR independence property means: if either input is uniform and independent, the output is uniform — regardless of the other input. This means:

  • A weak physical draw + good Pico = strong seed
  • A good physical draw + compromised Pico = still strong seed
  • The Pico can never make your seed weaker than the physical draw alone

The Pico is optional. The app runs without it; the Pico panel simply does not appear if no device is found.

Qualification: Pico 2 (RP2350) assessed at 7.466 bits/byte non-IID under NIST SP 800-90B. Full qualification record and raw capture data in the secure-mint-devices repository. See TUTORIAL.md Section 8 for the qualification procedure and how to run it on your own device.

The Pico is stateless and stores nothing. The firmware is 52 lines of C. The full protocol is: host sends one byte R, Pico replies with 256 raw TRNG bytes, loop. No flash writes. No session state. No memory of prior requests. The output buffer is stack-allocated and exists only for the duration of one response. Unplug the Pico and nothing is retained — there is nothing to retain. You can read and verify this yourself: pico-firmware/main.c (included in this repo).

See PICO_TRNG.md for the full adversarial explainer, including per-mode analysis and skeptical Q&A.


Wordlist

Uses the official BIP-39 English wordlist (2048 words).

SHA-256: 2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda

Verify against the official source:

https://github.com/trezor/python-mnemonic/blob/master/src/mnemonic/wordlist/english.txt

Installation

Requirements: Python 3.8+, tkinter (usually bundled with Python).

Optional: pyserial (for Pico 2 TRNG injection).

# Check all dependencies
python3 check_dependencies.py

# Install pyserial if you have a Pico (optional)
pip install pyserial

# Run
./run_gui.sh
# or
python3 seed_primer_gui.py

Air-gapped machines: copy the entire folder via USB. Run check_dependencies.py on the target machine to confirm everything is available. If tkinter is missing, see the remediation steps it prints.


Files

File Purpose
seed_primer_gui.py Main GUI application
seed_primer_core.py Core logic: encoding, tests, whitening, BIP-39
pico_trng_source.py Pico TRNG interface: scan, probe, bulk fetch
qr_encoder.py From-scratch QR generation (no external library)
wordlist_english.txt Official BIP-39 English wordlist
check_dependencies.py Dependency checker for new/air-gapped machines
test_bip39_checksum.py BIP-39 checksum correctness test (27 PASS)
dev_test_harness.py Dev-only: batch testing across all six modes
monte_carlo_pico.py Pipeline Monte Carlo test with real Pico TRNG
capture_nist.py NIST SP 800-90B raw capture tool for Pico
PICO_TRNG.md Pico TRNG explainer and adversarial Q&A
HARDENING.md Testing and hardening record (dated, append-only)
ADVERSARIAL_NOTES.md Statistical test suite adversarial test results

Testing

# BIP-39 checksum correctness (all six modes, known vectors, edge cases)
python3 test_bip39_checksum.py

# Statistical test false-positive rates (all six modes, 1000 trials each)
python3 dev_test_harness.py --all-modes 1000

# Monte Carlo pipeline test with real Pico (requires Pico connected)
python3 monte_carlo_pico.py --trials 1000 --source mic --no-xor

See HARDENING.md for the full testing record including Monte Carlo results with real hardware (H1essential mic + Pico 2, n=1000 and n=10000, bias 0%/30%/70% — all conditions PASS).


Security notes

  • No CSPRNG in the seed path. Physical entropy sources only. The Pico TRNG is the only software-adjacent entropy source, and it is optional and XOR'd (cannot reduce security below physical draw alone).
  • No network code. Verified: grep -r "socket\|urllib\|requests\|http" .
  • No disk writes of entropy or mnemonic data. Everything stays in process memory and is cleared on restart.
  • Deterministic pipeline. Same physical input always produces the same mnemonic (given the same Pico bytes, if used). This is by design — it allows independent verification of the implementation.

Credits

See CREDITS.md.

Developed by NoQuarter21M in collaboration with Claude (Anthropic).

About

Physical-entropy-first BIP-39 seed generation for air-gapped machines

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages