
Generating air-gapped seeds with coins/dice/card entropy on a Raspberry Pi Zero
With the whole Coldcard thing, I've been reevaluating my setup and felt it was worth redoing everything for peace of mind but I didn't want to make the same mistake of remaining uninformed and placing my trust in some random seed generation code. So I went ahead and built my own from the ground up.
Full transparency, I used AI, but it was all built one thing at a time, with extensive testing at each step in the process to ensure functionality, and I audited/verified the cryptographic flow each time any part of it was touched. I loathe AI slop and the last thing I want to do is contribute to the living nightmare that now is, so I was very careful to ensure everything was correct and functional.
It uses the Linux CSPRNG to produce 256bits of system entropy, with the option to use purely manual entropy via flipping coins, rolling dice or drawing from a deck of cards. There's also a mixed entropy mode that combines manual entropy with fresh CSPRNG output. Once entropy has been generated/entered, it generates a 25-word Monero seed, primary address and the corresponding public/private keys. It's also capable of verifying an existing seed or private spend key, deriving and displaying the same wallet information so it can be checked independently. It doesn't connect to the blockchain, store wallets, or sign transactions - it boots into an initramfs environment, doesn't mount persistent storage for writing, and the wallet secrets only exist in RAM during the session.
I designed it specifically for a Raspberry Pi Zero W (purely because that's all I could get my hands on due to shortages) and the 1.44" 128x128 Waveshare LCD/button HAT, so just a pre-warning that compatibility with other boards/displays is likely not good, and as the Zero W's radios kinda go directly against the whole purpose of an air-gapped device, Wi-Fi/Bluetooth are disabled through the boot configuration, their firmware blobs aren't included in the production image, and there's a runtime check that prevents wallet generation if an unexpected active network interface is detected. A non-wireless Pi Zero 1.3 is definitely the better hardware choice but I figured this is at least a sufficient solution while we wait for the rampocalypse to blow over.
I've tested it in both directions: generated a wallet on the device and restored it in Monero GUI, then generated a wallet in Monero GUI and entered that seed + private spend key into the device to verify - addresses and keys matched. I won't claim that I've mathematically proven the entire device "unhackable" because I haven't, but I will say that I've done my best to make sure it does what it's supposed to correctly with no funny business. The physical randomness assumptions, Linux CSPRNG, hardware/boot chain etc are still assumptions/trust boundaries, which I've tried my best to document.
Anyway, all that to say, the project got way more serious than the little weekend paper-wallet generator I originally intended to make, so figured why not clean up the codebase and release it as others might find it helpful, useful or interesting to dig into. I've uploaded the source code to GitHub, along with a ready-to-flash build to the releases page. I'd absolutely love any and all feedback!