bip39::Mnemonic::generate(24) resolves through Mnemonic::generate_in to
&mut rand::thread_rng() INSIDE the bip39 crate (bip39-2.1.0/src/lib.rs:
311-313 -> :296-298 -> :267-283), so the entropy source behind Archipelago's
entire key hierarchy -- node Ed25519 did:key, node Nostr key, FIPS mesh key,
per-identity keys, the BIP-84 wallet, the LND aezeed entropy, and the fleet
release-root SIGNING key -- was chosen by a dependency default rather than
stated at the call site.
Not a vulnerability today: rand 0.8.5's thread_rng is a fork-protected
ChaCha12 CSPRNG seeded from getrandom(2). But it is precisely the structural
shape of the 2026-07-30 COLDCARD entropy defect (T1), where a refactor
silently rebound seed generation to a non-cryptographic PRNG with no compile
error and no test failure.
- New private helper generate_mnemonic_with<R: CryptoRng + RngCore> calls
bip39's injectable generate_in_with; MasterSeed::generate passes OsRng
explicitly, with the rationale pinned in a doc comment
- mnemonic_generation_uses_injected_rng: drives generation from a
deterministic test RNG and asserts the result equals from_entropy(exactly
the bytes that RNG emitted) -- direct proof the INJECTED rng is consumed --
plus a known-answer pin and a determinism check. This test cannot be
written against the previous code: there was no seam to inject through
- mnemonic_generation_is_256_bit: the OsRng path yields 24 words and two
successive productions differ
No change to derivation paths, word count, the empty-BIP-39-passphrase
decision, or the at-rest encryption envelope.
Verified: CARGO_INCREMENTAL=0 cargo test -p archipelago seed:: -> 25 passed,
0 failed.
Full analysis: docs/security/ENTROPY-SEED-AUDIT-2026-07-31.md (F-02, §4, §7).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>