EDIT: I have been informed that BIP39 derives the last word from SHA hash of all the others, and thus needs a computer to generate the seeds. Thus, this post is moot and useless. I will leave the post here as a mahnmal, in the hope that someone will find something in it useful.
EDIT 2: After the initial failure, I decided to do the next best thing, and write a short program for the ESP8266 that will generate a random seed every time it boots up and print it to a screen. That should be a good compromise, scroll down to see it.
Being the geek that I am, I find Bitcoin fascinating (if only everybody focused on something other than the price!), and hardware wallets doubly so. If you haven’t heard of them, hardware wallets are small, flash-drive-sized devices that usually connect to a computer’s USB port and hold your wallet keys. That way, even if the computer you’re trying to send bitcoins from is riddled with viruses, you remain very secure and nobody but you can pay on your behalf. Unsurprisingly, I bought one! I was between the Trezor and the Ledger Nano S, but I decided on the Nano S in the end, as their platform looks more exciting, more secure and I was quite satisfied from the two HW1s I had bought for cheap at a sale.
However, since I’m in it for the technology and cryptoparanoia, rather than for any practical purpose, I find that hardware wallets have a few issues. For a short primer, a hardware wallet’s main advantage is that the keys are generated on the device and never, ever leave it, as whoever has the keys can spend your money. Since the keys never leave the device, though, you’re screwed if you ever lose it. To avoid that, wallet designers usually allow you to do a one-time export of the keys (many devices have a screen they show you the keys on), right after creating them. The export is usually a Bitcoin standard called BIP39, and is usually in the form of 12 or 24 everyday words, which you write down on a piece of paper, store it in your safe, and that’s all that’s needed to retrieve your keys if you lose the hardware wallet. No computer ever touches the keys, and you can sleep peacefully.
My problem, though, is that I want to go full paranoia, and don’t want to trust the hardware wallet developers to generate the random keys. If they really wanted to (and they probably don’t want to, but I’m not going to bet my $100 worth of bitcoins on “probably”), they could add a backdoor to the keys that would allow them to know beforehand any key that would ever be generated with their devices, while still looking completely random to the unsuspecting user. This is “easily” avoidable if you supply your own entropy (i.e. basically give them a series of dice rolls, coin tosses, whatever source you have that’s actually random).
Now, getting randomness is easy (albeit slow) if you have a die or coin lying around, but inputting that randomness is not always easy. Most hardware wallets allow you to restore the words you have written down as your backup, which can also be used to create new keys (because they don’t actually know or care if you had these words before, they just know that the words correspond to valid keys), but they usually don’t let you roll some dice and generate the keys that way.
You can also get good randomness the easy way, by generating it on a computer, which has the added benefit that it can convert that to a list of words you can import on your wallet directly, but that means you have to use a (potentially infected, bitcoin-key-stealing) computer. One solution there is to buy a small, cheap computer (like a $30 Raspberry Pi), install an operating system on it, download the proper software, disconnect it from all networks, generate the keys and then physically destroy the computer, burn your house down with your loved ones in it. That’s the only way to be sure, but, as you can tell, it’s a hassle.
The solution Nope, just lots of wasted time
Finally, after that entire introduction, and for the two people that haven’t stopped reading already, I came up with a solution! Here it is:
Since there’s no manual way (that I know of) to convert dice rolls to keys, and since I didn’t want to use a computer for this at all, I created a way! (*Also Sprach Zarathustra plays*). I decided to simply map dice rolls to words directly, and created a PDF that you can download and print. It’s six short pages with tiny words on them (to save paper), and the way it works is easy:
You can either roll a six-sided die (my method only uses four of the sides), or a 32-sided die (which is not common, but you can use a d20 and a d12 together from your D&D dice). Each word has numbers next to it, and the numbers correspond to your dice rolls. For example, the word “pave” has the numbers 221141 in the 6-sided die column, so if you roll 2, 2, 1, 1, 4, 1 in a row, that’s the word you should use for your seed. Keep in mind that the order of the words matters.
The only rule needed, apart from the simple list above, is this: If you don’t see your number in the column that you’re currently at, reroll. This means that, if you roll a 3 as the first number for the 6-sided die, you must reroll, since there’s no 6 anywhere. Just roll until you get either a 1 or a 2, then continue.
You need six rolls per word for the six-sided (really four-sided, as rolls of 5 and 6 will be discarded and rerolled) die, and only three rolls for the 32-sided die. Since the first roll of either method needs only a 1 or 2, you can just flip a coin for the first roll.
Please let me know in the comments section or on Twitter, if the PDF didn’t print well, or if my explanation is too complicated, or if I’m stupid and should kill myself. I’d especially like to know if you used this method to great success. (EDIT: Spoiler alert: You didn’t.)
The actual solution
I figured that, since you definitely need a computer to generate a seed, and I couldn’t be bothered with an airgapped one, I would use a $3 microcontroller that doesn’t even have an OS, and only runs open source code. So, I used an easily obtainable ESP8266 and a $3 screen to show the seed on.
I wrote a MicroPython script that will generate BIP39-compatible words and display them on an OLED screen that you connect to it. The code is trivially auditable (under 70 lines) and doesn’t use networking or anything. If you feel like it, you can just burn the ESP8266 afterwards, it costs next to nothing.
The code uses the ESP8266’s (apparently high-quality) random number generator. I know, I know, if I don’t trust the wallet’s generator, why would I trust the ESP’s, but after spending many hours on the above (failed) solution, my patience is running thin. Getting entropy from 53 d32 dice rolls is left as an exercise for the reader.
The code and usage instructions can be found in the script’s GitLab repository:
I hope you at least find this useful!