OSC-2026-0003 · github.com/SeedSigner/seedsigner
info clean-run claude-fable-5 2026-08-04 signed: nostr
- Repository
- github.com/SeedSigner/seedsigner
- Commit
- 1fb2956322ea978428a6a96b955baa93e965c877
- Scope path
- src/seedsigner/helpers/mnemonic_generation.py
- Model
- claude-fable-5
- Harness
- claude-code
- Prompts
- prompts/entropy-rng-audit-v1.md
- Independent runs
- 1
- Transcript sha256
- 8c35aee9b10e377ac0530c581a1f323c12c674ce6285fc7d5f637f199c939573
- Auditor
- TheIcarusWings (theicaruswings)
- Signature
- nostr-schnorr · npub19tzp8lf3klmqj3dz9mz0qnuvjp7uyy9993gmljmyaxs8phztj7wsnujvq5
Scope. The entropy paths that produce a BIP-39 mnemonic on this airgapped signer: dice rolls and coin flips (helpers/mnemonic_generation.py) and camera-image entropy (views/tools_views.py). In scope: the entropy-extraction method (SHA-256 over user input), dice-to-bits modulo bias, entropy sizing/truncation, and memory hygiene of seed material. NOT in scope: PSBT/signing, QR encode/decode, the camera driver, the embit/bip39 dependency internals, or the physical unpredictability of any specific user's dice/image.
Findings
info OSC-2026-0003-F1 unreviewed
Entropy extraction is sound; no weakness found in scope. Dice/coin-flip input is hashed as a full string via SHA-256 (generate_mnemonic_from_dice), which avoids the classic per-die modulo bias; 50 d6 rolls carry ~129 bits (>=128 target), 99 rolls ~256. A full 32-byte digest is correctly sliced to 16 bytes for 12 words with the checksum added by the bip39 layer (no truncation/reuse bug). Image entropy chains SHA-256 over CPU serial + time + all camera frames + the final capture. Good hygiene: the image, frames, and intermediate hashes are zeroed (set to None) after mnemonic generation. Observation (not a defect): the image path mixes in NO system CSPRNG (os.urandom/secrets) by deliberate airgapped-device design, so its seed strength depends entirely on the captured image's min-entropy; SeedSigner's guidance to use a busy image or prefer dice is the mitigation.