Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

How does BIP 39 mnemonic work?

Asked 3 years, 8 months ago Modified 9 months ago Viewed 2k times

As I already understood the mnemonics are the private key separated in 12 words which joined
together in the very same order produces the private key.
4
1. How are mnemonics generated?

2. Why Ledger mnemonics have 24 words?

3. How those words are converted to private keys?

private-key bip32-hd-wallets mnemonic-seed

Share Improve this question Follow edited Aug 19, 2019 at 22:20 asked Aug 19, 2019 at 21:19
Ugam Kamat Allan Romanato
7,183 2 13 38 322 1 13

Sorted by:
2 Answers
Highest score (default)

Mnemonics are the private key separated in 12 words which joined together in the very
same order produces the private key
8

That is incorrect. A mnemonic represents an entropy that is passed to a PBKDF2 key-stretching


function with 2048 rounds of hashing to generate a 512 bits seed. This seed then acts like a
keychain that is used to generate different keys. Check the last section of the answer to see how
private keys are generated from seed.

How are mnemonics generated?

As said above, mnemonics are representation of entropy along with a checksum. First step
involves making a decision as to how much entropy you consider safe for your operations.
Assume, for now that you have decided on 128 bits of entropy. Below are the steps that you will
follow to convert this entropy to mnemonic.

1. Use some cryptographically secure entropy generator to generate 128 bits of entropy.
. Use so e c yptog ap ca y secu e e t opy ge e ato to ge e ate 8 b ts o e t opy.
2. Calculate the SHA256 of the entropy.

3. Append the first entropy_length/32 bits of the SHA256 of the entropy at the end of the
entropy. For example, in our case we will append the first 4 bits of the SHA256(entropy) to
the entropy since our entropy is 128 bits.

4. Each word of the mnemonic represents 11 bits. Hence, if you check the wordlist you will find
2048 unique words. Now, divide the entropy + checksum into parts of 11 bits each.

5. Match this 11 bit fragments to the words in the lookup table in the wordlist. Since we used
128 bits of entropy our checksum was 4 bits. So our entropy along with checksum
represented a total of 132 bits. Thus our mnemonic will be 12 words.

If you had used 256 bits of entropy, your checksum would have been (256/32 =) 8 bits. That
would represent (264/11) = 24 words.

One thing to note is that any 12/24 words cannot be used as a mnemonic. Some 'portion' of the
last word generally contains the checksum of the words chosen and hence has to be calculated.
It is also discouraged to generate words directly from thought and use a secure cryptographic
function to do so.

Why Ledger Mnemonics have 24 words?

That is a design choice of security. More the number of words higher the entropy. 24 words will
provide 256 bits of entropy. It is also important to note that a mnemonic phrase cannot be used
back and forth between different number of words. For example you cannot convert a 24 word
representation to 12 words and vice versa.

How those words are converted to a private key?

The mnemonic is passed to key-stretching function PBKDF2 with 2048 rounds of hashing. The
PBKDF2 function also has the ability to take a 'salt' that can be an optional passphrase. This
passphrase provides an additional layer of security and prevents brute-force attack with look-up
tables. The output of this function is a 512 bit seed.

This seed is then passed to HMAC-SHA512 with key "Bitcoin seed". The resulting hash is used to
create the master private key (m) and master chain code (c). The left 256 bits of that resulting
hash represents m while the right 256 bits represents c . The master private key m is then used
to generate master public key M ( M = m*G ).

From here a number of derivation paths existing for different wallets. The most common one is a
hardened derivation method as specified in BIP 44. Essentially, hardened keys use the parent
private key in the hash function to generate child private key, while non-hardened uses parent
public key in the hash function. This improves the security in the generation of child keys. In the
below derivation, k and K represents private key and the associated public key respectively.
We would first need to show that we have used BIP 44 derivation path. That can be done with an
index number and generate a private key one level deeper from the master private key. The child
private key one level deeper is generated by: kchild = kpar + hash(kpar, cpar, i) where i is
the index number. For hardened derivation of BIP 44, i will be 0x80000044 (we use the latter 231
half of the index number for hardened derivation). This result will give us a 512 bit number. The
left 256 bits will represent the child private key and the right 256 bits will represent the child chain
code.

The next level represents the coin. For Bitcoin, that is 0 or 0x80000000 in hardened derivation.
You then calculate the child private key and child chain code one level deeper using the formula
above.

The next level represents account. You can use multiple accounts to represent different functions
and help manage your funds better. You can use the above logic to generate the account private
key and chain code. Again, this is hardened derivation so the first account will have index number
as 0x80000000 .

From here onward we do not use the hardened derivation. The next level represents receiving
address vs change. This allows you to have different bunch for receiving private keys and
different key bunch for change private keys. The function we will use to generate the child private
from parent will be: kchild = kpar + hash(Kpar, cpar, i) . Now i will be 0x00000000 for
receiving and 0x00000001 for change. Also note, now we have public key in the hash function
rather than private key which shows this is not hardened derivation.

Now, at the next level we use these receiving and change key bunch to generate individual private
keys. Use the above generate private keys and chain code and pass them to the above mentioned
function kchild = kpar + hash(Kpar, cpar, i) to generate individual keys. Every increment of
i will give you a different private key.

Now use these private keys to generate bitcoin addresses.

Share Improve this answer Follow edited Aug 20, 2019 at 7:23 answered Aug 19, 2019 at 22:19
Ugam Kamat
7,183 2 13 38

Do you have any code references on how to derive private key from mnemonic for BIP44 path, such as
"m/44'/60'/0'/0/0"? – us_david Oct 4, 2021 at 2:30

I encountered the same situation where I needed to dig further into the process of generating an
Ethereum wallet. I have read through the material I could search for but none is giving me an
0 answer I need to complete my programming task of creating a wallet. Here is a brief summary on
what I have learnt so far:
1. generate mnemonic

2. generate a seed from mnemonic. For example: bip39.mnemonicToSeed(mnemonic).

3. derive a master key from this seed.


4. derive child key from a path such as: "m/44'/60'/0'/0/0".

5. this child key is your wallet's private key (for Ethereum).

6. you can extract the address for the wallet from this private key.

Even though the above process is not code you can directly use, but at least you may have a
better understanding on the steps and what's involved.

In dart, the whole process can be achieved using the following libraries:

bip39, bip32, dart_bip32_bip44, dart crypto etc..

Share Improve this answer Follow edited Oct 13, 2021 at 16:41 answered Oct 5, 2021 at 17:08
Glorfindel us_david
529 3 7 19 101 1

You might also like