2013-10-21 06:56:42 +02:00
|
|
|
<pre>
|
2016-02-03 08:02:36 +01:00
|
|
|
BIP: 39
|
2016-11-30 10:45:33 +01:00
|
|
|
Layer: Applications
|
2016-02-03 08:02:36 +01:00
|
|
|
Title: Mnemonic code for generating deterministic keys
|
|
|
|
Author: Marek Palatinus <slush@satoshilabs.com>
|
|
|
|
Pavol Rusnak <stick@satoshilabs.com>
|
|
|
|
Aaron Voisine <voisine@gmail.com>
|
|
|
|
Sean Bowe <ewillbefull@gmail.com>
|
Propagate summary tone of BIP Comments to their applicable BIP preambles
Affects: BIPs 38, 39, 42, 44, 47, 60, 61, 74, 75, 90, 150, 151, 152
2017-03-15 00:27:57 +01:00
|
|
|
Comments-Summary: Unanimously Discourage for implementation
|
2016-11-30 10:47:31 +01:00
|
|
|
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0039
|
|
|
|
Status: Proposed
|
2016-02-03 08:02:36 +01:00
|
|
|
Type: Standards Track
|
2014-04-05 13:46:56 +02:00
|
|
|
Created: 2013-09-10
|
2013-10-21 06:56:42 +02:00
|
|
|
</pre>
|
|
|
|
|
|
|
|
==Abstract==
|
|
|
|
|
2014-01-20 20:21:43 +01:00
|
|
|
This BIP describes the implementation of a mnemonic code or mnemonic sentence --
|
|
|
|
a group of easy to remember words -- for the generation of deterministic wallets.
|
2013-12-15 17:23:44 +01:00
|
|
|
|
2014-07-09 16:18:59 +02:00
|
|
|
It consists of two parts: generating the mnemonic, and converting it into a
|
2014-01-20 20:21:43 +01:00
|
|
|
binary seed. This seed can be later used to generate deterministic wallets using
|
|
|
|
BIP-0032 or similar methods.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
|
|
|
==Motivation==
|
|
|
|
|
2014-07-09 16:18:59 +02:00
|
|
|
A mnemonic code or sentence is superior for human interaction compared to the
|
2017-08-24 13:50:20 +02:00
|
|
|
handling of raw binary or hexadecimal representations of a wallet seed. The
|
2014-02-07 20:57:43 +01:00
|
|
|
sentence could be written on paper or spoken over the telephone.
|
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
This guide is meant to be a way to transport computer-generated randomness with
|
|
|
|
a human readable transcription. It's not a way to process user-created
|
|
|
|
sentences (also known as brainwallets) into a wallet seed.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2013-12-15 17:23:44 +01:00
|
|
|
==Generating the mnemonic==
|
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
The mnemonic must encode entropy in a multiple of 32 bits. With more entropy
|
|
|
|
security is improved but the sentence length increases. We refer to the
|
2016-11-03 10:14:41 +01:00
|
|
|
initial entropy length as ENT. The allowed size of ENT is 128-256 bits.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-01-20 20:21:43 +01:00
|
|
|
First, an initial entropy of ENT bits is generated. A checksum is generated by
|
|
|
|
taking the first <pre>ENT / 32</pre> bits of its SHA256 hash. This checksum is
|
2014-09-25 02:55:33 +02:00
|
|
|
appended to the end of the initial entropy. Next, these concatenated bits
|
2014-01-20 20:21:43 +01:00
|
|
|
are split into groups of 11 bits, each encoding a number from 0-2047, serving
|
2014-07-09 20:21:34 +02:00
|
|
|
as an index into a wordlist. Finally, we convert these numbers into words and
|
2014-01-20 20:21:43 +01:00
|
|
|
use the joined words as a mnemonic sentence.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-01-20 20:21:43 +01:00
|
|
|
The following table describes the relation between the initial entropy
|
2014-07-09 20:21:34 +02:00
|
|
|
length (ENT), the checksum length (CS) and the length of the generated mnemonic
|
2014-01-20 20:21:43 +01:00
|
|
|
sentence (MS) in words.
|
2013-12-15 17:23:44 +01:00
|
|
|
|
|
|
|
<pre>
|
|
|
|
CS = ENT / 32
|
|
|
|
MS = (ENT + CS) / 11
|
|
|
|
|
|
|
|
| ENT | CS | ENT+CS | MS |
|
|
|
|
+-------+----+--------+------+
|
|
|
|
| 128 | 4 | 132 | 12 |
|
|
|
|
| 160 | 5 | 165 | 15 |
|
|
|
|
| 192 | 6 | 198 | 18 |
|
|
|
|
| 224 | 7 | 231 | 21 |
|
|
|
|
| 256 | 8 | 264 | 24 |
|
|
|
|
</pre>
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2013-12-15 17:23:44 +01:00
|
|
|
==Wordlist==
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-01-20 20:21:43 +01:00
|
|
|
An ideal wordlist has the following characteristics:
|
2013-10-21 06:56:42 +02:00
|
|
|
|
|
|
|
a) smart selection of words
|
2014-07-09 20:21:34 +02:00
|
|
|
- the wordlist is created in such way that it's enough to type the first four
|
2013-10-21 06:56:42 +02:00
|
|
|
letters to unambiguously identify the word
|
|
|
|
|
|
|
|
b) similar words avoided
|
2014-01-20 20:21:43 +01:00
|
|
|
- word pairs like "build" and "built", "woman" and "women", or "quick" and "quickly"
|
2013-10-21 06:56:42 +02:00
|
|
|
not only make remembering the sentence difficult, but are also more error
|
2014-01-20 20:21:43 +01:00
|
|
|
prone and more difficult to guess
|
2013-10-21 06:56:42 +02:00
|
|
|
|
|
|
|
c) sorted wordlists
|
2014-07-09 20:21:34 +02:00
|
|
|
- the wordlist is sorted which allows for more efficient lookup of the code words
|
|
|
|
(i.e. implementations can use binary search instead of linear search)
|
|
|
|
- this also allows trie (a prefix tree) to be used, e.g. for better compression
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
The wordlist can contain native characters, but they must be encoded in UTF-8
|
2014-02-07 21:01:10 +01:00
|
|
|
using Normalization Form Compatibility Decomposition (NFKD).
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2013-12-15 17:23:44 +01:00
|
|
|
==From mnemonic to seed==
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
A user may decide to protect their mnemonic with a passphrase. If a passphrase is not
|
2014-01-20 20:21:43 +01:00
|
|
|
present, an empty string "" is used instead.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
To create a binary seed from the mnemonic, we use the PBKDF2 function with a mnemonic
|
|
|
|
sentence (in UTF-8 NFKD) used as the password and the string "mnemonic" + passphrase (again
|
|
|
|
in UTF-8 NFKD) used as the salt. The iteration count is set to 2048 and HMAC-SHA512 is used as
|
|
|
|
the pseudo-random function. The length of the derived key is 512 bits (= 64 bytes).
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2013-12-15 17:23:44 +01:00
|
|
|
This seed can be later used to generate deterministic wallets using BIP-0032 or
|
|
|
|
similar methods.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
The conversion of the mnemonic sentence to a binary seed is completely independent
|
2014-01-20 20:21:43 +01:00
|
|
|
from generating the sentence. This results in rather simple code; there are no
|
2013-12-15 17:23:44 +01:00
|
|
|
constraints on sentence structure and clients are free to implement their own
|
2014-01-20 20:21:43 +01:00
|
|
|
wordlists or even whole sentence generators, allowing for flexibility in wordlists
|
|
|
|
for typo detection or other purposes.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
Although using a mnemonic not generated by the algorithm described in "Generating the
|
|
|
|
mnemonic" section is possible, this is not advised and software must compute a
|
|
|
|
checksum for the mnemonic sentence using a wordlist and issue a warning if it is
|
2014-02-07 20:57:43 +01:00
|
|
|
invalid.
|
|
|
|
|
2014-07-09 20:21:34 +02:00
|
|
|
The described method also provides plausible deniability, because every passphrase
|
|
|
|
generates a valid seed (and thus a deterministic wallet) but only the correct one
|
2013-12-15 17:23:44 +01:00
|
|
|
will make the desired wallet available.
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-02-07 20:43:04 +01:00
|
|
|
==Wordlists==
|
|
|
|
|
2014-08-15 18:51:56 +02:00
|
|
|
* [[bip-0039/bip-0039-wordlists.md|Moved to separate document]]
|
2014-02-07 20:43:04 +01:00
|
|
|
|
2013-10-21 06:56:42 +02:00
|
|
|
==Test vectors==
|
|
|
|
|
2014-07-03 02:58:05 +02:00
|
|
|
The test vectors include input entropy, mnemonic and seed. The
|
|
|
|
passphrase "TREZOR" is used for all vectors.
|
|
|
|
|
|
|
|
https://github.com/trezor/python-mnemonic/blob/master/vectors.json
|
2013-10-21 06:56:42 +02:00
|
|
|
|
2014-09-03 16:49:33 +02:00
|
|
|
Also see https://github.com/bip32JP/bip32JP.github.io/blob/master/test_JP_BIP39.json
|
2014-09-03 16:52:24 +02:00
|
|
|
|
2014-09-03 16:49:33 +02:00
|
|
|
(Japanese wordlist test with heavily normalized symbols as passphrase)
|
|
|
|
|
2013-10-21 06:56:42 +02:00
|
|
|
==Reference Implementation==
|
|
|
|
|
|
|
|
Reference implementation including wordlists is available from
|
|
|
|
|
|
|
|
http://github.com/trezor/python-mnemonic
|
2013-12-15 17:23:44 +01:00
|
|
|
|
2014-02-28 18:28:09 +01:00
|
|
|
==Other Implementations==
|
|
|
|
|
2018-02-03 03:03:23 +01:00
|
|
|
Go:
|
|
|
|
* https://github.com/tyler-smith/go-bip39
|
|
|
|
|
2017-09-23 11:31:47 +02:00
|
|
|
Elixir:
|
|
|
|
* https://github.com/izelnakri/mnemonic
|
|
|
|
|
2016-02-23 04:24:29 +01:00
|
|
|
Objective-C:
|
|
|
|
* https://github.com/nybex/NYMnemonic
|
2014-02-28 18:28:09 +01:00
|
|
|
|
2016-02-23 04:24:29 +01:00
|
|
|
Haskell:
|
|
|
|
* https://github.com/haskoin/haskoin
|
2014-08-21 23:18:05 +02:00
|
|
|
|
2016-02-23 04:24:29 +01:00
|
|
|
.NET C# (PCL):
|
|
|
|
* https://github.com/Thashiznets/BIP39.NET
|
2014-12-16 07:59:57 +01:00
|
|
|
|
2016-02-23 04:24:29 +01:00
|
|
|
.NET C# (PCL):
|
|
|
|
* https://github.com/NicolasDorier/NBitcoin
|
2015-01-28 18:57:28 +01:00
|
|
|
|
2016-02-22 08:10:48 +01:00
|
|
|
JavaScript:
|
|
|
|
* https://github.com/bitpay/bitcore-mnemonic
|
2016-07-18 20:43:23 +02:00
|
|
|
* https://github.com/bitcoinjs/bip39 (used by [[https://github.com/blockchain/My-Wallet-V3/blob/v3.8.0/src/hd-wallet.js#L121-L146|blockchain.info]])
|
2016-08-10 18:38:22 +02:00
|
|
|
|
|
|
|
Ruby:
|
|
|
|
* https://github.com/sreekanthgs/bip_mnemonic
|
2017-07-26 05:33:34 +02:00
|
|
|
|
2017-10-01 01:36:44 +02:00
|
|
|
Rust:
|
2017-10-03 07:28:55 +02:00
|
|
|
* https://github.com/infincia/bip39-rs
|
2017-10-01 01:36:44 +02:00
|
|
|
|
2017-07-26 05:33:34 +02:00
|
|
|
Swift:
|
|
|
|
* https://github.com/CikeQiu/CKMnemonic
|
2018-01-02 15:29:07 +01:00
|
|
|
* https://github.com/yuzushioh/WalletKit
|
2017-08-07 15:05:42 +02:00
|
|
|
|
2017-07-26 21:42:43 +02:00
|
|
|
C++:
|
|
|
|
* https://github.com/libbitcoin/libbitcoin/blob/master/include/bitcoin/bitcoin/wallet/mnemonic.hpp
|
2017-08-11 22:31:00 +02:00
|
|
|
|
|
|
|
C (with Python/Java/Javascript bindings):
|
|
|
|
* https://github.com/ElementsProject/libwally-core
|