3
3
<pre>
4
4
BIP: BIP-0039
5
5
Title: Mnemonic code for generating deterministic keys
6
- Author: Pavol Rusnak <
[email protected] >
7
- Marek Palatinus <
[email protected] >
6
+ Authors: Marek Palatinus <
[email protected] >
7
+
8
+
8
9
9
10
Status: Draft
10
11
Type: Standards Track
11
12
Created: 10-09-2013
12
13
</pre>
13
14
14
- ==Abstract==
15
+ == Abstract ==
15
16
16
- This BIP proposes a scheme for translating binary data (usually master seeds
17
- for deterministic keys, but it can be applied to any binary data) into a group
18
- of easy to remember words also known as mnemonic code or mnemonic sentence.
17
+ This BIP describes an usage of mnemonic code or mnemonic sentence - a group of
18
+ easy to remember words - to generate deterministic wallets.
19
19
20
- ==Motivation==
20
+ It consists of two parts: generating the mnemonic and converting it into
21
+ a binary seed. This seed can be later used to generate deterministic wallets
22
+ using BIP-0032 or similar methods.
23
+
24
+ == Motivation ==
21
25
22
26
Such mnemonic code or mnemonic sentence is much easier to work with than working
23
27
with the binary data directly (or its hexadecimal interpretation). The sentence
24
28
could be writen down on paper (e.g. for storing in a secure location such as
25
29
safe), told over telephone or other voice communication method, or memorized
26
30
in ones memory (this method is called brainwallet).
27
31
28
- ==Backwards Compatibility==
32
+ == Generating the mnemonic ==
33
+
34
+ First, we decide how much entropy we want mnemonic to encode. Recommended size
35
+ is 128-256 bits, but basically any multiple of 32 bits will do. More bits
36
+ mean more security, but also longer word sentence.
37
+
38
+ We take initial entropy of ENT bits and compute its checksum by taking first
39
+ ENT / 32 bits of its SHA256 hash. We append these bits to the end of the initial
40
+ entropy. Next we take these concatenated bits and split them into groups of 11
41
+ bits. Each group encodes number from 0-2047 which is a position in a wordlist.
42
+ We convert numbers into words and use joined words as mnemonic sentence.
29
43
30
- As this BIP is written, only one Bitcoin client (Electrum) implements mnemonic
31
- codes, but it uses a different wordlist than the proposed one .
44
+ The following table describes the relation between initial entropy length (ENT),
45
+ checksum length (CS) and length of the generated mnemonic sentence (MS) in words .
32
46
33
- For compatibility reasons we propose adding a checkbox to Electrum, which will
34
- allow user to indicate if the legacy code is being entered during import or
35
- it is a new one that is BIP-0039 compatible. For exporting, only the new format
36
- will be used, so this is not an issue.
47
+ CS = ENT / 32
48
+ MS = (ENT + CS) / 11
37
49
38
- ==Rationale==
50
+ | ENT | CS | ENT+CS | MS |
51
+ +-------+----+--------+------+
52
+ | 128 | 4 | 132 | 12 |
53
+ | 160 | 5 | 165 | 15 |
54
+ | 192 | 6 | 198 | 18 |
55
+ | 224 | 7 | 231 | 21 |
56
+ | 256 | 8 | 264 | 24 |
39
57
40
- Our proposal is inspired by implementation used in Electrum, but we enhanced
41
- the wordlist and algorithm so it meets the following criteria:
58
+ == Wordlist ==
59
+
60
+ In previous section we described how to pick words from a wordlist. Now we
61
+ describe how does a good wordlist look like.
42
62
43
63
a) smart selection of words
44
64
- wordlist is created in such way that it's enough to type just first four
@@ -55,90 +75,45 @@ c) sorted wordlists
55
75
(i.e. implementation can use binary search instead of linear search)
56
76
- this also allows trie (prefix tree) to be used, e.g. for better compression
57
77
58
- d) localized wordlists
59
- - we would like to allow localized wordlists, so it is easier for users
60
- to remember the code in their native language
61
- - by using wordlists with no colliding words among languages, it's easy to
62
- determine which language was used just by checking the first word of
63
- the sentence
64
-
65
- e) mnemonic checksum
66
- - this leads to better user experience, because user can be notified
67
- if the mnemonic sequence is wrong, instead of showing the confusing
68
- data generated from the wrong sequence.
69
-
70
- f) seed stretching
71
- - before the encoding and after the decoding the binary sequence is
72
- stretched using a symmetric cipher (Rijndael) in order to prevent
73
- brute-force attacks in case some of the mnemonic words are leaked
74
- - this also provides a method for password protection of the seed
78
+ Wordlist can contain native characters, but they have to be encoded using UTF-8.
75
79
76
- ==Specification ==
80
+ == From mnemonic to seed ==
77
81
78
- <pre>
79
- Our proposal implements two methods - "encode" and "decode".
80
-
81
- The first method takes a binary data which have length of 128, 192 or 256 bits
82
- and returns a sentence that consists of 12, 18 or 24 words from the wordlist.
83
-
84
- The second method takes sentences generated by the first method (number of words
85
- is 12, 18 or 24 and reconstructs the original binary data of length 128, 192 or
86
- 256 bits.
82
+ User can decide to protect his mnemonic by passphrase. If passphrase is not present
83
+ an empty string "" is used instead.
87
84
88
- Words can repeat in the sentence more than one time.
85
+ To create binary seed from mnemonic, we use HMAC-SHA512 function with string
86
+ "mnemonic" + passphrase (in UTF-8) as key and mnemonic sentence (again in UTF-8)
87
+ as the message. We perform 10000 HMAC rounds and use the final result as the binary
88
+ seed.
89
89
90
- Wordlist contains 2048 words (instead of 1626 words in Electrum), allowing
91
- the code to compute the checksum of the whole mnemonic sequence.
92
- Each 32 bits of input data add 1 bit of checksum.
90
+ Pseudocode:
93
91
94
- See the following table for relation between input lengths, output lengths and
95
- checksum sizes:
92
+ K = "mnemonic" + passphrase
93
+ M = mnemonic_sentence
94
+ for i in 1 ... 10000 do
95
+ M = hmac_sha512(K, M)
96
+ done
97
+ seed = M
96
98
97
- +--------+---------+---------+----------+
98
- | input | input | output | checksum |
99
- | (bits) | (bytes) | (words) | (bits) |
100
- +--------+---------+---------+----------+
101
- | 128 | 16 | 12 | 4 |
102
- | 192 | 24 | 18 | 6 |
103
- | 256 | 32 | 24 | 8 |
104
- +--------+---------+---------+----------+
105
- </pre>
99
+ This seed can be later used to generate deterministic wallets using BIP-0032 or
100
+ similar methods.
106
101
107
- ===Algorithm:===
102
+ The conversion of the mnemonic sentence to binary seed is completely independent
103
+ from generating the sentence. This results in rather simple code, there are no
104
+ constraints on sentence structure and clients are free to implement their own
105
+ wordlists or even whole sentence generators (they'll lose the proposed method
106
+ for typo detection in that case, but they can come up with their own).
108
107
109
- <pre>
110
- Encoding:
111
- 1. Read input data (I).
112
- 2. Make sure its length (L) is 128, 192 or 256 bits.
113
- 3. Encrypt input data 10000x with Rijndael (ECB mode).
114
- Set key to SHA256 hash of string ("mnemonic" + user_password).
115
- Set block size to input size (that's why Rijndael is used, not AES).
116
- 4. Compute the length of the checkum (LC). LC = L/32
117
- 5. Split I into chunks of LC bits (I1, I2, I3, ...).
118
- 6. XOR them altogether and produce the checksum C. C = I1 xor I2 xor I3 ... xor In.
119
- 7. Concatenate I and C into encoded data (E). Length of E is divisable by 33 bits.
120
- 8. Keep taking 11 bits from E until there are none left.
121
- 9. Treat them as integer W, add word with index W to the output.
122
-
123
- Decoding:
124
- 1. Read input mnemonic (M).
125
- 2. Make sure the number of words is 12, 18 or 24.
126
- 3. Figure out word indexes in a dictionary and output them as binary stream E.
127
- 4. Length of E (L) is divisable by 33 bits.
128
- 5. Split E into two parts: B and C, where B are first L/33*32 bits, C are last L/33 bits.
129
- 6. Make sure C is the checksum of B (using the step 5 from the above paragraph).
130
- 7. If it's not we have invalid mnemonic code.
131
- 8. Treat B as binary data.
132
- 9. Decrypt this data 10000x with Rijndael (ECB mode),
133
- use the same parameters as used in step 3 of encryption.
134
- 10. Return the result as output.
135
- </pre>
108
+ Described method also provides plausable deniability, because every passphrase
109
+ generates a valid seed (and thus deterministic wallet) but only the correct one
110
+ will make the desired wallet available.
136
111
137
- ==Test vectors==
112
+ == Test vectors ==
138
113
139
114
See https://github.com/trezor/python-mnemonic/blob/master/vectors.json
140
115
141
- ==Reference Implementation==
116
+ == Reference Implementation ==
142
117
143
118
Reference implementation including wordlists is available from
144
119
0 commit comments