slip-0039: further in construction, incorporate feedback

parent 9989187a
......@@ -6,8 +6,8 @@ Title: Shamir's Secret-Sharing for Mnemonic Codes
Type: Standard
Status: Draft
Authors: Pavol Rusnak <stick@satoshilabs.com>
Tomas Susanka <tomas.susanka@satoshilabs.com>
Ondrej Vejpustek <ondrej.vejpustek@satoshilabs.com>
Tomas Susanka <tomas.susanka@satoshilabs.com>
Marek Palatinus <slush@satoshilabs.com>
Jochen Hoenicke <hoenicke@gmail.com>
Created: 2017-12-18
......@@ -31,39 +31,46 @@ In case sufficient `M` values are provided the points exactly define the polynom
![curve](slip-0039/curve.png)
## From entropy to mnemonic secrets
## Generating the mnemonic shares
We propose the following format of the shares:
| nonce (N) | index (I) | threshold (M) | share (SSS) | checksum (C) |
|-----------|------------|---------------|------------------|--------------|
| 20 bits | 5 bits | 5 bits | 130/200/260 bits | 30 bits |
The value to be encoded as the master secret must be a multiple of 8 bits. This is typically a wallet entropy, but may be another secret value which was uniformly chosen from its (key) space. The master secret is divided into `N` Shamir parts and `M` specifies how many of those parts do we need to reconstruct the master secret. We use `GF(256)` reduced by `x^8 + x^4 + x^3 + x + 1` (the Rijndael polynomial) as the underlying field.
* `nonce` field is a random 20-bit identifier which is the same for all shares and it's used for detection whether the shares belong together, it's also later as salt in key derivation functions
* `index` field corresponds to the SSS part's `x` value (see the diagram above) and the SSS part is the corresponding `y` value
* `threshold` field indicates how many shares are needed to reconstruct the secret
* `index` and `threshold` fields values are from range 1-31, value 0 is not considered valid
* `share` field is a randomly generated share
* `checksum` field is a Bech32 checksum (defined in BIP-0173) of the whole share (that is `N || I || M || SSS`)
From this value, every byte is mapped to the specified field in a little-endian fashion (i.e. the first bit maps to `a_7`, the last bit maps to `a_0`). For each such field element, `N`-share field elements are generated and mapped back to bytes. Each participating party receives the following data:
This structure is then converted into a mnemonic code by splitting it up by 10 bits which correspond as an index to the a word list containing exactly 1024 words (see below).
| index | M threshold | set id | SSS part | checksum |
|--------|-------------|---------|-----------------------|----------|
| 5 bits | 5 bits | 16 bits | same as master secret | 16-bit |
| share length | total length | security |
|--------------|------------------------|----------|
| 130 bits | 190 bits = 19 words | 128 bits |
| 200 bits | 260 bits = 26 words | 192 bits |
| 260 bits | 320 bits = 32 words | 256 bits |
* the `index` corresponds to the SSS part's `x` value (see the diagram above) and the SSS part is the corresponding `y` value
* `index` and `threshold` fields are encoded as 5-bit integers and the value 00000 is considered as invalid in both cases.
* `set id` field is a random 16-bit identifier which is the same for all shares and it's used for detection whether the shares belong together
* the `checksum` field is a CRC-16 checksum of the whole share (i.e. index, threshold, set id, SSS part)
Construction has the nice property that nonce transforms into exactly the first two words of the mnemonic code, so user can immediately tell whether the correct shares are being combined (they have to have the same first two words). Moreover the third word encodes exactly the index/threshold values, so for example share #2 of 3 required shares will always correspond to the same word.
This structure is then converted into a mnemonic passphrase by splitting it up by 10 bits which correspond as an index to the a word list containing exactly 1024 words (see below).
## Converting the mnemonic shares to master secret
| master secret | share length |
|---------------|------------------------|
| 128 bits | 170 bits = 17 words |
| 256 bits | 298 bits = 30 words |
Once enough `M` secrets are provided, we can produce the master secret from the shares. First we derive the shares using `PBKDF2(PRF = HMAC-SHA256, Password = SSS, Salt = (N || I || M || C), iterations = 1, dkLen = 256 bits)` where `SSS`, `N`, `I`, `M`, `C` values are encoded as 6 words from the wordlist separated by exactly one space.
The selection of 5-bit sizes for index/threshold values and 10-bit for wordlist index has a nice property that the first word of the mnemonic encodes exactly these two values. And, vice versa, only these two values determine the first word.
The resulting output from `PBKDF2` is a multiple of 8 bits. We can use Shamir Secret Sharing and reconstruct the master secret. We use `GF(256)` reduced by `x^8 + x^4 + x^3 + x + 1` (the Rijndael polynomial) as the underlying field.
## Passphrase
When enough `M` secrets are provided the master secret is reconstructed. To allow an additional protection of the final seed using a passphrase we will use a key derivation function to compute the seed. If no passphrase is provided an empty string should be used as a passphrase.
To allow an additional protection of the final seed using a passphrase we will use a key derivation function to compute the seed. If no passphrase is provided an empty string should be used as a passphrase.
Passphrase should contain only ASCII characters to achieve the best interoperability among various operating systems and wallet implementations.
![passphrase](slip-0039/passphrase.png)
We will use `PBKDF2(PRF = HMAC-SHA256, Password = master_secret, Salt = "SLIP0039" + passphrase, iterations = 20000, dkLen = 256 bits)` as the key derivation function.
We will use `PBKDF2(PRF = HMAC-SHA256, Password = master_secret, Salt = ("SLIP0039" || passphrase || N), iterations = 20000, dkLen = 256 bits)` as the key derivation function. Value `N` is encoded as two words from the wordlist separated by exactly one space.
We suggest to use the obtained seed as a master seed `S` for Hierarchical Deterministic Wallets described in BIP-0032.
......@@ -92,3 +99,4 @@ TBD
* [BIP-0032: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
* [Secret Sharing Step by Step by Point Software](http://www.pointsoftware.ch/en/secret-sharing-step-by-step/)
* [BIP-0173: Base32 address format for native v0-16 witness outputs](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#Bech32)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment