MORE RECENT EDIT: 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, and it works well, scroll down to see it.

OLDER 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.

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.

The problem

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.

Here it is in action:

workaround

The code and usage instructions can be found in the script’s GitLab repository: