Custom mnemonic for Ledger Nano S
I’ve found out recently that it’s possible to create my own mnemonic sentence for Ledger Nano S or any other hardware or software wallet that uses BIP-39 proposal for generating deterministic keys. This standard describes an algorithm for generating a sentence from a predefined wordlist containing 2048 words, then converting it into a binary seed that can be later used to generate deterministic wallets using BIP-32 or similar methods.
A mnemonic code or sentence is superior for human interaction compared to the handling of raw binary or hexadecimal representations of a wallet seed. The sentence could be written on paper or spoken over the telephone.
Note that this is different from Brainwallets which are generally not recommended. Brainwallets generated by humans are insecure and should not be used. Humans are not a good source of entropy. There is pretty concrete evidence that users are resistant to good advice in this space, and they are shocked when their favorite quotation is cracked and they lose their coins (But it was 60 characters long! I even added a special character! how is this possible?!). There is an interesting DEFCON Talk covering this topic in depth.
So make sure your custom mnemonic sentence is derived from true entropy e.g. you used coin flipping or a secure random number generator or otherwise confident your phrase is random enough.
The reason you might want to generate your own mnemonic phrase in the first place instead of relying on Ledger Nano S is simple curiousity; or you might be paranoid like me and afraid that the developers or resellers tempered the software, firmware or the hardware of the device and now it gives you a predefined mnemonic instead of a randomly generated one, which of course would give them access to your money :)
BTW you can also read the blog post about how you can check that your Ledger device in genuine https://www.ledger.fr/2015/03/27/how-to-protect-hardware-wallets-against-tampering/.
Example of Generating Mnemonic Phrase
The trickiest part in the whole process is the checksum — you need to make sure the last word validates against it.
- You need to choose how many words your mnemonic will contain. The numbers you can choose from can be looked up in BIP-39 standard. Let’s say for our example we chose 24 words.
- Pick 23 words randomly from this list: English wordlist. You need to note the index (0-based) of each word in that list and the binary representation of the index. The binary representation should contain exactly 11 bits. Let’s say you randomly picked the following 23 words from the list:
+----------+-------+-----------------+
| Word | Index | Index in Binary |
+----------+-------+-----------------+
| access | 10 | 00000001010 |
| practice | 1355 | 10101001011 |
| able | 2 | 00000000010 |
| about | 3 | 00000000011 |
| acid | 15 | 00000001111 |
| absent | 5 | 00000000101 |
| above | 4 | 00000000100 |
| abstract | 7 | 00000000111 |
| act | 19 | 00000010011 |
| abuse | 9 | 00000001001 |
| absorb | 6 | 00000000110 |
| accident | 11 | 00000001011 |
| term | 1787 | 11011111011 |
| accuse | 13 | 00000001101 |
| achieve | 14 | 00000001110 |
| machine | 1068 | 10000101100 |
| acoustic | 16 | 00000010000 |
| acquire | 17 | 00000010001 |
| across | 18 | 00000010010 |
| abandon | 0 | 00000000000 |
| fix | 704 | 01011000000 |
| actor | 21 | 00000010101 |
| actress | 22 | 00000010110 |
+----------+-------+-----------------+
- Concat the binary indexes and pad them with 3 random bits of your choice. The total number of bits should be 264. Then calculate sha256 hash of this binary data. You can use
shasum
command in MacOS:
> echo '0000000101010101001011000000000100000000001100000001111000000001010000000010000000000111000000100110000000100100000000110000000010111101111101100000001101000000011101000010110000000010000000000100010000001001000000000000010110000000000001010100000010110010' | shasum --01 --algorithm 256a6c77eaaa8bbc4251928a2d408e601082f3c42d5702289fd2d325d9459719bbc
You can find the full sequence in this spreadsheet.
- The sha256 hash for this example is
a6c77eaaa8bbc4251928a2d408e601082f3c42d5702289fd2d325d9459719bbc
. We need to take 8 first bits of this hash which is10100110
and append them to the 3 random bits from the previous step and use it as an index to look up the 24th word from the word list. For our example the index is 678 (01010100110
in binary) and the corresponding word isfeel
. - The resulting mnemonic that will pass the checksum validation thus is:
+----------+
| Word |
+----------+
| access |
| practice |
| able |
| about |
| acid |
| absent |
| above |
| abstract |
| act |
| abuse |
| absorb |
| accident |
| term |
| accuse |
| achieve |
| machine |
| acoustic |
| acquire |
| across |
| abandon |
| fix |
| actor |
| actress |
| feel |
+----------+
P.S. BIP-39 is discouraged for implementation due to the reasons outlined here https://github.com/bitcoin/bips/wiki/Comments:BIP-0039. The issues, however, are mostly UX related.