Skip to content

Commit a1be309

Browse files
authored
BIP85: Update/clarify spec, add change log, Portuguese language code, dice application (bitcoin#1600)
* BIP-85: * Add new maintainer (author unreachable) * Swap chain code and private key bytes in application 32' for consistentcy with BIP-32 (major change) * Correct derived entropy for application 128169' test vector (major change) * Clarify big endian serialization * Add the Portuguese language (9') to application 39' * Add dice application 89101' * Clarify Testnet support for XPRV application 32' * Minor grammar, format, clarity improvements
1 parent 34db0e9 commit a1be309

File tree

2 files changed

+87
-15
lines changed

2 files changed

+87
-15
lines changed

README.mediawiki

+1-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ Those proposing changes should consider that ultimately consent may rest with th
452452
| [[bip-0085.mediawiki|85]]
453453
| Applications
454454
| Deterministic Entropy From BIP32 Keychains
455-
| Ethan Kosakovsky
455+
| Ethan Kosakovsky, Aneesh Karve
456456
| Informational
457457
| Draft
458458
|- style="background-color: #cfffcf"

bip-0085.mediawiki

+86-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Layer: Applications
44
Title: Deterministic Entropy From BIP32 Keychains
55
Author: Ethan Kosakovsky <[email protected]>
6+
Aneesh Karve <[email protected]>
67
Comments-Summary: No comments yet.
78
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0085
89
Status: Draft
@@ -14,10 +15,10 @@
1415

1516
==Abstract==
1617

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."''
18+
''One Seed to rule them all,''<br>
19+
''One Key to find them,''<br>
20+
''One Path to bring them all,''<br>
21+
''And in cryptography bind them.''
2122

2223
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.
2324

@@ -33,6 +34,9 @@ The terminology related to keychains used in the wild varies widely, for example
3334
# '''BIP39 mnemonic''' is the mnemonic phrase that is calculated from the entropy used before hashing of the mnemonic in BIP39.
3435
# '''BIP39 seed''' is the result of hashing the BIP39 mnemonic seed.
3536
37+
When in doubt, assume '''big endian''' byte serialization, such that the leftmost
38+
byte is the most significant.
39+
3640
==Motivation==
3741

3842
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 to 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.
@@ -51,6 +55,9 @@ For each application that requires its own wallet, a unique private key is deriv
5155

5256
The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC 4231].
5357

58+
Application codes may be arbitrary but should be semantic, such as a BIP number,
59+
ASCII character code sequence, or similar.
60+
5461
===Test vectors===
5562

5663
====Test case 1====
@@ -78,7 +85,7 @@ BIP85-DRNG-SHAKE256 is a deterministic random number generator for cryptographic
7885
RSA key generation is an example of a function that requires orders of magnitude more than 64 bytes of random input. Further, it is not possible to precalculate the amount of random input required until the function has completed.
7986

8087
drng_reader = BIP85DRNG.new(bip85_entropy)
81-
rsa_key = RSA.generate_key(4096, drng_reader.read())
88+
rsa_key = RSA.generate_key(4096, drng_reader.read)
8289
8390
===Test Vectors===
8491
INPUT:
@@ -93,14 +100,15 @@ OUTPUT
93100
94101
==Reference Implementation==
95102

96-
* Python library implementation: [https://github.com/ethankosakovsky/bip85]
97-
* JavaScript library implementation: [https://github.com/hoganri/bip85-js]
103+
* 2.0 Python library implementation: [https://github.com/akarve/bipsea]
104+
* 1.0 Python library implementation: [https://github.com/ethankosakovsky/bip85]
105+
* 1.0 JavaScript library implementation: [https://github.com/hoganri/bip85-js]
98106
99107
==Applications==
100108

101109
The Application number defines how entropy will be used post processing. Some basic examples follow:
102110

103-
Derivation path uses the format <code>m/83696968'/{app_no}'/{index}'</code> where ''{app_no}'' is the path for the application, and ''{index}'' is the index.
111+
Derivation path uses the format <code>m/83696968'/{app}'/{index}'</code> where ''{app}'' is the '''path''' for the application, and ''{index}'' is the index.
104112

105113
===BIP39===
106114
Application number: 39'
@@ -143,6 +151,10 @@ Language Table
143151
|-
144152
| Czech
145153
| 8'
154+
|-
155+
| Portuguese
156+
| 9'
157+
|-
146158
|}
147159

148160
Words Table
@@ -207,7 +219,12 @@ OUTPUT:
207219
===HD-Seed WIF===
208220
Application number: 2'
209221

210-
Uses 256 bits[1] 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.
222+
Uses the most significant 32 bytes<ref name="curve-order">
223+
There is a very small chance that you'll make an invalid
224+
key that is zero or bigger than the order of the curve. If this occurs, software
225+
should hard fail (forcing users to iterate to the next index).</ref>
226+
of entropy as the secret exponent to derive a private key and encode as a compressed
227+
WIF which will be used as the hdseed for Bitcoin Core wallets.
211228

212229
Path format is <code>m/83696968'/2'/{index}'</code>
213230

@@ -222,17 +239,26 @@ OUTPUT
222239
===XPRV===
223240
Application number: 32'
224241

225-
Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and second 32 bytes[1] are the private key for BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero.
242+
Consistent with BIP32, use the first (leftmost) 32 bytes of the derived entropy as the
243+
private key<ref name="curve-order" />. Prepend an empty byte (<code>0x00</code>)
244+
per BIP32 on master key serialization. Use the last (rightmost) 32 bytes as the chain code.
245+
246+
Child number, depth, and parent fingerprint are forced to zero, as with any root
247+
private key.
248+
226249

227250
Path format is <code>m/83696968'/32'/{index}'</code>
228251

252+
253+
Applications may support Testnet by emitting TPRV keys if and only if the input root key is a Testnet key.
254+
229255
INPUT:
230256
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
231257
* PATH: m/83696968'/32'/0'
232258
233259
OUTPUT
234260
* DERIVED ENTROPY=ead0b33988a616cf6a497f1c169d9e92562604e38305ccd3fc96f2252c177682
235-
* DERIVED XPRV=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX
261+
* DERIVED XPRV=xprv9s21ZrQH143K4Px85utdpu6DFvY2NpHkJajPoupAznfiacH2MC9LasyW4uvqKXNxLWcjqGTbHKAhoZoMAbmRe5g9tAPA7cUUX4UVA1vFKFm
236262
237263
===HEX===
238264
Application number: 128169'
@@ -285,7 +311,7 @@ INPUT:
285311
* PATH: m/83696968'/707764'/21'/0'
286312
287313
OUTPUT
288-
* DERIVED ENTROPY=d7ad61d4a76575c5bad773feeb40299490b224e8e5df6c8ad8fe3d0a6eed7b85ead9fef7bcca8160f0ee48dc6e92b311fc71f2146623cc6952c03ce82c7b63fe
314+
* DERIVED ENTROPY=74a2e87a9ba0cdd549bdd2f9ea880d554c6c355b08ed25088cfa88f3f1c4f74632b652fd4a8f5fda43074c6f6964a3753b08bb5210c8f5e75c07a4c2a20bf6e9
289315
* DERIVED PWD=dKLoepugzdVJvdL56ogNV
290316
291317
===PWD BASE85===
@@ -295,7 +321,7 @@ The derivation path format is: <code>m/83696968'/707785'/{pwd_len}'/{index}'</co
295321

296322
`10 <= pwd_len <= 80`
297323

298-
Base85 encode the all 64 bytes of entropy.
324+
Base85 encode all 64 bytes of entropy.
299325
Remove any spaces or new lines inserted by Base64 encoding process. Slice base85 result string
300326
on index 0 to `pwd_len`. This slice is the password. `pwd_len` is limited to 80 characters.
301327

@@ -326,6 +352,40 @@ OUTPUT
326352
* DERIVED ENTROPY=f7cfe56f63dca2490f65fcbf9ee63dcd85d18f751b6b5e1c1b8733af6459c904a75e82b4a22efff9b9e69de2144b293aa8714319a054b6cb55826a8e51425209
327353
* DERIVED PWD=_s`{TW89)i4`
328354
355+
===DICE===
356+
357+
Application number: 89101'
358+
359+
The derivation path format is: <code>m/83696968'/89101'/{sides}'/{rolls}'/{index}'</code>
360+
361+
2 <= sides <= 2^32 - 1
362+
1 <= rolls <= 2^32 - 1
363+
364+
Use this application to generate PIN numbers or any other numeric secret.
365+
Roll values are zero-indexed, such that an N-sided die produces values in the range
366+
<code>[0, N-1]</code>, inclusive. Applications should separate printed rolls by a comma or similar.
367+
368+
Create a BIP85 DRNG whose seed is the derived entropy.
369+
370+
Calculate the following integers:
371+
372+
bits_per_roll = ceil(log_2(sides))
373+
bytes_per_roll = ceil(bits_per_roll / 8)
374+
375+
Read <code>bytes_per_roll</code> bytes from the DRNG.
376+
Trim any bits in excess of <code>bits_per_roll</code> (retain the most
377+
significant bits). The resulting integer represents a single roll or trial.
378+
If the trial is greater than or equal to the number of sides, skip it and
379+
move on to the next one. Repeat as needed until all rolls are complete.
380+
381+
INPUT:
382+
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
383+
* PATH: m/83696968'/89101'/6'/10'/0'
384+
385+
OUTPUT
386+
* DERIVED ENTROPY=5e41f8f5d5d9ac09a20b8a5797a3172b28c806aead00d27e36609e2dd116a59176a738804236586f668da8a51b90c708a4226d7f92259c69f64c51124b6f6cd2
387+
* DERIVED ROLLS=1,0,0,2,0,1,5,5,2,4
388+
329389
===RSA===
330390

331391
Application number: 828365'
@@ -374,9 +434,21 @@ Many thanks to Peter Gray and Christopher Allen for their input, and to Peter fo
374434

375435
BIP32, BIP39
376436

437+
==Change Log==
438+
439+
* 1.0 (2020-07)
440+
* 2.0.0 (2024-09-22)
441+
* Swap chain code and private key bytes in application 32' for consistentcy with BIP-32 (major change)
442+
* Correct derived entropy for application 128169' test vector (major change)
443+
* Clarify big endian serialization
444+
* Add the Portuguese language (9') to application 39'
445+
* Add dice application 89101'
446+
* Clarify Testnet support for XPRV application 32'
447+
* Minor grammar, format, clarity improvements
448+
377449
==Footnotes==
378450

379-
[1] 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 to iterate to the next index).
451+
<references />
380452

381453
From BIP32:
382454
In case parse<sub>256</sub>(I<sub>L</sub>) is 0 or ≥ n, 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>.)

0 commit comments

Comments
 (0)