In the beginning of bitcoin (2009~2013), people created private keys by their own preferred random number generator. The most common ways were:
- rolling a dice
- flipping a coin
Those more concerned with security recommended flipping a box full of coins and shake it very well to guarantee maximum entropy. The explanation at that time was quite reasonable:
- Software randomness is not truly random and can be tampered by malicious attackers.
- Choosing a strong passphrase in order to avoid brute force attacks can be very tricky. If you are able to memorize it, then most likely it is not as strong as you think.
- It is common to see off the shelf dices with some bias.
"Physical randomness is better than computer generated pseudo-randomness."
However, storing these private keys in hexadecimal (or some compressed format) is very unfriendly. This motivated an improvement proposal in 2013, so that users could store seed phrases (24 easy to remember words from BIP39 wordlist) instead.
Unfortunately, soon after that, the industry standard quickly moved towards letting wallets automatically generate the private keys and users should only store the seed phrases in a safe place. The explanation given elsewhere in the web is that users are not reliable to generate randomness. Therefore, they should leave this task to the software. Which contradicts previous recommendations and even the core principal of bitcoin: trust no one.
Nowadays, if you want to create a private key by the old fashion way (but still very safe if done properly) like rolling a dice or flipping a coin, you will have a hard time looking for a software to automatically generate the seed phrase of such private key.
Therefore, this article simply tries to solve that by proposing such standard procedure.
One way to create a seed phrase from a private key is to use the aforementioned BIP39 wordlist, which has 2048 (= 211) words, and map bits of the private key to the corresponding word.
However, 11 is not a multiple of 256. Therefore, it is necessary to split the 256 bits of the private key into 11-bit segments with padding/checksum appended to make it a multiple of 11. A reasonable way is to take the sha256 checksum of the private key and append the first 8 bits to get 264 bits. Which maps to 24 words.
In short, follow the steps below:
Take the sha256 of the private key.
Take the first 8 bits of the sha256 calculate above and append to the private key.
You should get 264 bits.
Split into 11-bits
Split the 264 bits calculated above into 11 bits segments.
You should get 24 segments.
Map to Words
Map each 11 bits segment calculated above to the correspondent word from the BIP39 word list.
Hexadecimal Format 8BFA0399016B9FCEE2F543F90701495583723D14E0C6A0AE69BF528CB4CB38C8 Binary Format 1000101111111010000000111001100100000001011010111001111111001110 1110001011110101010000111111100100000111000000010100100101010101 1000001101110010001111010001010011100000110001101010000010101110 0110100110111111010100101000110010110100110010110011100011001000
SHA256 of Private Key:
Hexadecimal Format 3BBE1C86172DB67C6E6261E1AE455AF02CF01C86CE538A81C1EB03C9CC73ED12 Binary Format 0011101110111110000111001000011000010111001011011011011001111100 0110111001100010011000011110000110101110010001010101101011110000 0010110011110000000111001000011011001110010100111000101010000001 1100000111101011000000111100100111001100011100111110110100010010
Private Key with 8 bits checksum appended:
1000101111111010000000111001100100000001011010111001111111001110 1110001011110101010000111111100100000111000000010100100101010101 1000001101110010001111010001010011100000110001101010000010101110 0110100110111111010100101000110010110100110010110011100011001000 00111011
11-bits segments with corresponding BIP39 word:
01 10001011111 1119 message 02 11010000000 1664 source 03 11100110010 1842 town 04 00000010110 0022 actress 05 10111001111 1487 rigid 06 11100111011 1851 trash 07 10001011110 1118 mesh 08 10101000011 1347 position 09 11111001000 1992 weekend 10 00111000000 0448 day 11 01010010010 0658 false 12 10101011000 1368 prison 13 00110111001 0441 damp 14 00011110100 0244 burden 15 01010011100 0668 fatal 16 00011000110 0198 boat 17 10100000101 1285 pass 18 01110011010 0922 infant 19 01101111110 0894 hurt 20 10100101000 1320 pink 21 11001011010 1626 slender 22 01100101100 0812 grain 23 11100011001 1817 tobacco 24 00000111011 0059 alter