Skip to content

Commit d0d2bc9

Browse files
authored
Merge pull request bitcoin#910 from ethankosakovsky/entropy_bip
BIP 85: Deterministic Entropy From BIP32 Keychains
2 parents d2b795f + 9692734 commit d0d2bc9

File tree

2 files changed

+266
-0
lines changed

2 files changed

+266
-0
lines changed

README.mediawiki

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,13 @@ Those proposing changes should consider that ultimately consent may rest with th
421421
| Informational
422422
| Draft
423423
|-
424+
| [[bip-0085.mediawiki|85]]
425+
| Applications
426+
| Deterministic Entropy From BIP32 Keychains
427+
| Ethan Kosakovsky
428+
| Informational
429+
| Draft
430+
|-
424431
| [[bip-0090.mediawiki|90]]
425432
|
426433
| Buried Deployments

bip-0085.mediawiki

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
<pre>
2+
BIP: 85
3+
Layer: Applications
4+
Title: Deterministic Entropy From BIP32 Keychains
5+
Author: Ethan Kosakovsky <[email protected]>
6+
Comments-Summary: No comments yet.
7+
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0085
8+
Status: Draft
9+
Type: Informational
10+
Created: 2020-03-20
11+
License: BSD-2-Clause
12+
OPL
13+
</pre>
14+
15+
==Abstract==
16+
17+
''"One Seed to rule them all,''
18+
''One Key to find them,''
19+
''One Path to bring them all,''
20+
''And in cryptography bind them."''
21+
22+
It is not possible to maintain one single (mnemonic) seed backup for all keychains used across various wallets because there are a variety of incompatible standards. Sharing of seeds across multiple wallets is not desirable for security reasons. Physical storage of multiple seeds is difficult depending on the security and redundancy required.
23+
24+
As HD keychains are essentially derived from initial entropy, this proposal provides a way to derive entropy from the keychain which can be fed into whatever method a wallet uses to derive the initial mnemonic seed or root key.
25+
26+
==Definitions==
27+
28+
The terminology related to keychains used in the wild varies widely, for example `seed` has various different meanings. In this document we define the terms
29+
30+
# '''BIP32 root key''' is the root extended private key that is represented as the top root of the keychain in BIP32.
31+
# '''BIP39 mnemonic''' is the mnemonic phrase that is calculated from the entropy used before hashing of the mnemonic in BIP39.
32+
# '''BIP39 seed''' is the result of hashing the BIP39 mnemonic seed.
33+
34+
==Motivation==
35+
36+
Most wallets implement BIP32 which defines how a BIP32 root key can be used to derive keychains. As a consequence, a backup of just the BIP32 root key is sufficient to include all keys derived from it. BIP32 does not have a human friendly serialization of the BIP32 root key (or BIP32 extended keys in general) which makes paper backups or manually restoring the key more error-prone. BIP39 was designed solve this problem but rather than serialize the BIP32 root key, it takes some entropy, encoded to a "seed mnemonic", which is then hashed to derive the BIP39 seed which can be turned into the BIP32 root key. Saving the BIP39 mnemonic is enough to reconstruct the entire BIP32 keychain, but a BIP32 root key cannot be reversed back to the BIP39 mnemonic.
37+
38+
Most wallets implement BIP39, so on initialization or restoration, the user must interact with a BIP39 mnemonic. Most wallets do not support of BIP32 extended private keys so each wallet must either share the same BIP39 mnemonic, or have a separate BIP39 mnemonic entirely. Neither scenarios are particularly satisfactory for security reasons. For example, some wallets may be inherently less secure like hot wallets on smartphones, Join Market servers, Lightning Network nodes. Having multiple seeds is far from desirable especially for those who rely on split key or redundancy backups in different geological locations. Adding is necessarily difficult and may result in users being more lazy with subsequent keys, such that compromises security or leads to key loss.
39+
40+
There is added complication with wallets that implement other standards, or no standards at all. Bitcoin Core wallet uses a WIF as the ''hdseed'', and yet other wallets use different mnemonic schemes like Electrum to derive the BIP32 root key. Other cryptocurrencies like Monero also use a different mnemonic scheme entirely.
41+
42+
Ultimately, all of the mnemonic/seed schemes start with some "initial entropy" to derive a mnemonic/seed, and then process the mnemonic into a BIP32 key, or private key. We can use BIP32 itself to derive the "initial entropy" to then recreate the same mnemonic or seed according the specific application standard of the target wallet. We can use a BIP44 like categorization to ensure unitform derivation according to the target application type.
43+
44+
==Specification==
45+
46+
We assume a single BIP32 master root key. This specification is not concerned with how this was derived (e.g. directly or via a mnemonic scheme such as BIP39).
47+
48+
For each application that requires its own wallet, a unique private key is derived from the BIP32 master root key using fully hardened derivation path. The resulting private key (k) is then processed with HMAC-SHA512, where the key is "bip-entropy-from-k", and the message payload is the private key k: <code>HMAC-SHA512(key="bip-entropy-from-k", msg=k)</code>. The result produces 512 bits of entropy. Each application SHOULD use up to the required number of bits necessary for their operation truncating the rest
49+
50+
The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC 4231].
51+
52+
===Test vectors===
53+
54+
====Test case 1====
55+
INPUT:
56+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
57+
* PATH: m/83696968'/0'/0'
58+
59+
OUTPUT:
60+
* DERIVED KEY=cca20ccb0e9a90feb0912870c3323b24874b0ca3d8018c4b96d0b97c0e82ded0
61+
* DERIVED ENTROPY=6bea85e51a05e6dbaf2ccee05097758213807997ba936589cef01c8f19c0079f395a0cd045efa3438677f3ef9ad34c9a68506626c5a17e51ed5e177852ee7fdc
62+
63+
====Test case 2====
64+
INPUT:
65+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
66+
*PATH: m/83696968'/0'/1'
67+
68+
OUTPUT
69+
* DERIVED KEY=503776919131758bb7de7beb6c0ae24894f4ec042c26032890c29359216e21ba
70+
* DERIVED ENTROPY=6da87ce3a71869b7a644c9d574f67df168fee8c6b24bc0832ef3cc43e23ca5055dd0458431caa5b5b33113b1d7bbd706c20a5ea3b408808402f553ddf1a3d6d4
71+
72+
==Reference Implementation==
73+
74+
Python library implementation: [https://github.com/ethankosakovsky/bipentropy python-bipentropy]
75+
76+
===Other Implementations===
77+
78+
Coldcard Firmware: [https://github.com/Coldcard/firmware/pull/39]
79+
80+
==Applications==
81+
82+
Application number define how entropy will be used post processing. Some basic examples follow:
83+
84+
Derivation path uses the format <code>m/83696968/' + /app_no' + /index'</code> where ''app_no'' path for the application, and `index` in the index.
85+
86+
===BIP39===
87+
Application number: 39'
88+
89+
Truncate trailing (least significant) bytes of the entropy to the number of bits required to map to the relevant word length 128 bits for 12 words, 256 bits for 24 words.
90+
91+
The derivation path format is: <code>m/83696968'/39'/{language}'/{words}'/{index}'</code>
92+
93+
Example a BIP39 mnemonic with 12 English words (first index) would have the path <code>m/83696968'/39'/0'/12'/0'</code> the next key would be <code>m/83696968'/39'/0'/12'/1'</code> etc.
94+
95+
Language Table
96+
97+
{|
98+
!Wordlist
99+
!Code
100+
|-
101+
| English
102+
| 0'
103+
|-
104+
| Japanese
105+
| 1'
106+
|-
107+
| Korean
108+
| 2'
109+
|-
110+
| Spanish
111+
| 3'
112+
|-
113+
| Chinese (Simplified)
114+
| 4'
115+
|-
116+
| Chinese (Traditional)
117+
| 5'
118+
|-
119+
| French
120+
| 6'
121+
|-
122+
| Italian
123+
| 7'
124+
|-
125+
| Czech
126+
| 8'
127+
|}
128+
129+
Words Table
130+
131+
{|
132+
!Words
133+
!Entropy
134+
!Code
135+
|-
136+
| 12 words
137+
| 128 bits
138+
| 12'
139+
|-
140+
| 18 words
141+
| 192 bits
142+
| 18'
143+
|-
144+
| 24 words
145+
| 256 bits
146+
| 24'
147+
|}
148+
149+
====12 English words====
150+
BIP39 English 12 word mnemonic seed
151+
152+
128 bits of entropy as input to BIP39 to derive 12 word mnemonic
153+
154+
INPUT:
155+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
156+
* PATH: m/83696968'/39'/0'/12'/0'
157+
158+
OUTPUT:
159+
* DERIVED ENTROPY=6250b68daf746d12a24d58b4787a714b
160+
* DERIVED BIP39 MNEMONIC=girl mad pet galaxy egg matter matrix prison refuse sense ordinary nose
161+
162+
====18 English words====
163+
BIP39 English 18 word mnemonic seed
164+
165+
196 bits of entropy as input to BIP39 to derive 18 word mnemonic
166+
167+
INPUT:
168+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
169+
* PATH: m/83696968'/39'/0'/18'/0'
170+
171+
OUTPUT:
172+
* DERIVED ENTROPY=938033ed8b12698449d4bbca3c853c66b293ea1b1ce9d9dc
173+
* DERIVED BIP39 MNEMONIC=near account window bike charge season chef number sketch tomorrow excuse sniff circle vital hockey outdoor supply token
174+
175+
====24 English words====
176+
Derives 24 word BIP39 mnemonic seed
177+
178+
256 bits of entropy as input to BIP39 to derive 24 word mnemonic
179+
180+
INPUT:
181+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
182+
* PATH: m/83696968'/39'/0'/24'/0'
183+
184+
OUTPUT:
185+
* DERIVED ENTROPY=ae131e2312cdc61331542efe0d1077bac5ea803adf24b313a4f0e48e9c51f37f
186+
* DERIVED BIP39 MNEMONIC=puppy ocean match cereal symbol another shed magic wrap hammer bulb intact gadget divorce twin tonight reason outdoor destroy simple truth cigar social volcano
187+
188+
===HD-Seed WIF===
189+
Application number: 2'
190+
191+
Uses 256 bits of entropy as the secret exponent to derive a private key and encode as a compressed WIF which will be used as the hdseed for Bitcoin Core wallets.
192+
193+
There is a very small chance that you'll make an invalid key that is zero or bigger than the order of the curve. If this occurs, software should hard fail (forcing users should iterate to the next index).
194+
195+
From BIP32:
196+
> In case parse<sub>256</sub>(I<sub>L</sub>) ≥ n or k<sub>i</sub> = 0, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2<sup>127</sup>.)
197+
198+
Path format is <code>m/83696968'/2'/{index}'</code>
199+
200+
INPUT:
201+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
202+
* PATH: m/83696968'/2'/0'
203+
204+
OUTPUT
205+
* DERIVED ENTROPY=7040bb53104f27367f317558e78a994ada7296c6fde36a364e5baf206e502bb1
206+
* DERIVED WIF=Kzyv4uF39d4Jrw2W7UryTHwZr1zQVNk4dAFyqE6BuMrMh1Za7uhp
207+
208+
===XPRV===
209+
Application number: 32'
210+
211+
Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and second 32 bytes are the private key for BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero.
212+
213+
Path format is <code>m/83696968'/32'/{index}'</code>
214+
215+
INPUT:
216+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
217+
* PATH: m/83696968'/39'/0'
218+
219+
OUTPUT
220+
* DERIVED ENTROPY=7040bb53104f27367f317558e78a994ada7296c6fde36a364e5baf206e502bb1
221+
* DERIVED WIF=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX
222+
223+
===HEX===
224+
Application number: 128169'
225+
226+
The derivation path format is: <code>m/83696968'/128169'/{num_bytes}'/{index}'</code>
227+
228+
`16 <= num_bytes <= 64`
229+
230+
Truncate trailing (least significant) bytes of the entropy after `num_bytes`.
231+
232+
INPUT:
233+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
234+
* PATH: m/83696968'/128169'/64'/0'
235+
236+
OUTPUT
237+
* DERIVED ENTROPY=492db4698cf3b73a5a24998aa3e9d7fa96275d85724a91e71aa2d645442f878555d078fd1f1f67e368976f04137b1f7a0d19232136ca50c44614af72b5582a5c
238+
239+
==Backwards Compatibility==
240+
241+
This specification is not backwards compatible with any other existing specification.
242+
243+
This specification relies on BIP32 but is agnostic to how the BIP32 root key is derived, as such this standard is allows it to derive wallets with initialization schemes like BIP39 or Electrum wallet style mnemonics.
244+
245+
==Discussion==
246+
247+
The reason for running the derived key through HMAC-SHA512 and truncating the result as necessary is to prevent leakage of the parent tree should the derived key (k) be compromized. While the specification requires the use of hardended key derivation which would prevent this, we cannot enforce hardened derivation, so this method ensures the derived entropy is hardened. Also from a semantic point of view, since the purpose is to derive entropy and not a private key, we are required to transform the child key. This acts in an abundance of caution to ward off unwanted side effects should k be used for a dual purpose, including as a nonce hash(k), where undesirable and unforeseen interactions could occur.
248+
249+
==Acknowledgements==
250+
251+
Many thanks to Peter Gray and Christopher Allen for their input, and to Peter for suggesting extra application use cases.
252+
253+
==References==
254+
255+
BIP32, BIP39
256+
257+
==Copyright==
258+
259+
This BIP is dual-licensed under the Open Publication License and BSD 2-clause license.

0 commit comments

Comments
 (0)