@@ -34,7 +34,7 @@ When any *T* points are provided, they exactly define the polynomial. The polyno
...
@@ -34,7 +34,7 @@ When any *T* points are provided, they exactly define the polynomial. The polyno
## Generating the mnemonic shares
## Generating the mnemonic shares
The pre-master secret is divided into *N* Shamir parts and *T* specifies how many of those parts are needed to reconstruct the pre-master secret. Shamir's secret sharing scheme is applied seperately to each byte of the pre-master secret and GF(256) is used as the underlying finite field<sup>[1](#FiniteField)</sup>. Bytes are interpreted as elements of GF(256) using polynomial representation with operations modulo the Rijndael irreducible polynomial *x*<sup>8</sup> + *x*<sup>4</sup> + *x*<sup>3</sup> + *x* + 1, see [AES](https://doi.org/10.6028/NIST.FIPS.197) sections 3.2, 4.1 and 4.4.
The pre-master secret is divided into *N* Shamir parts and *T* specifies how many of those parts are needed to reconstruct the pre-master secret. Shamir's secret sharing scheme is applied separately to each byte of the pre-master secret and GF(256) is used as the underlying finite field<sup>[1](#FiniteField)</sup>. Bytes are interpreted as elements of GF(256) using polynomial representation with operations modulo the Rijndael irreducible polynomial *x*<sup>8</sup> + *x*<sup>4</sup> + *x*<sup>3</sup> + *x* + 1, see [AES](https://doi.org/10.6028/NIST.FIPS.197) sections 3.2, 4.1 and 4.4.
We propose the following format of the shares:
We propose the following format of the shares:
...
@@ -46,7 +46,7 @@ We propose the following format of the shares:
...
@@ -46,7 +46,7 @@ We propose the following format of the shares:
* threshold (*t*) field<sup>[2](#IndexEncoding)</sup> indicates how many shares are needed to reconstruct the secret. The actual value is encoded as *t*=*T*−1, so a value of 0 indicates that a single share is needed (*T*=1), a value of 1 indicates that two shares are needed (*T*=2) etc.
* threshold (*t*) field<sup>[2](#IndexEncoding)</sup> indicates how many shares are needed to reconstruct the secret. The actual value is encoded as *t*=*T*−1, so a value of 0 indicates that a single share is needed (*T*=1), a value of 1 indicates that two shares are needed (*T*=2) etc.
* index (*I*) field<sup>[2](#IndexEncoding)</sup> corresponds to the SSS part's *x* value, *x*=*I*+1, (see the diagram above).
* index (*I*) field<sup>[2](#IndexEncoding)</sup> corresponds to the SSS part's *x* value, *x*=*I*+1, (see the diagram above).
* share (*s*) field is the corresponding SSS part's *f*(*x*) values (see the diagram above), right-padded with "0" bits so that the length of the padded share in bits becomes a multiple of ten.
* share (*s*) field is the corresponding SSS part's *f*(*x*) values (see the diagram above), right-padded with "0" bits so that the length of the padded share in bits becomes a multiple of ten.
* checksum (*C*) field is an RS1024 checksum (see below) of the data part of the share (that is *id* || *t* || *I* || *s*); the human-readable part (hrp) of RS1024 is "slip0039"
* checksum (*C*) field is an RS1024 checksum (see below) of the data part of the share (that is *id* || *t* || *I* || *s*); the customization string (cs) of RS1024 is "slip0039"
This structure is then converted into a mnemonic code by splitting it up into 10 bit segments with each becoming an index to a word list containing exactly 1024 words (see below).
This structure is then converted into a mnemonic code by splitting it up into 10 bit segments with each becoming an index to a word list containing exactly 1024 words (see below).
...
@@ -61,7 +61,7 @@ This construction yields a beneficial property where the identifier transforms i
...
@@ -61,7 +61,7 @@ This construction yields a beneficial property where the identifier transforms i
The last three words of the mnemonic form a checksum and contain no information. Valid mnemonics MUST pass the criteria for validity specified by the Python3 code snippet below. The function `rs1024_verify_checksum` must return true when its arguments are:
The last three words of the mnemonic form a checksum and contain no information. Valid mnemonics MUST pass the criteria for validity specified by the Python3 code snippet below. The function `rs1024_verify_checksum` must return true when its arguments are:
-`hrp`: the human-readable part as a string
-`cs`: the customization string
-`data`: the data part as a list of integers representing the words after conversion using the wordlist
-`data`: the data part as a list of integers representing the words after conversion using the wordlist
```
```
...
@@ -75,17 +75,17 @@ def rs1024_polymod(values):
...
@@ -75,17 +75,17 @@ def rs1024_polymod(values):
chk ^= GEN[i] if ((b >> i) & 1) else 0
chk ^= GEN[i] if ((b >> i) & 1) else 0
return chk
return chk
def rs1024_verify_checksum(hrp, data):
def rs1024_verify_checksum(cs, data):
return rs1024_polymod([ord(x) for x in hrp] + data) == 1
return rs1024_polymod([ord(x) for x in cs] + data) == 1
```
```
This implements a Reed-Solomon code over GF(1024) that guarantees detection of any error affecting at most 3 words and has less than a 1 in 10<sup>9</sup> chance of failing to detect more errors. More details about the properties can be found in the Checksum Design appendix<sup>[3](#ChecksumDesign)</sup>. The human-readable part is processed by feeding each character's US-ASCII value into the checksum calculation prior to the data.
This implements a Reed-Solomon code over GF(1024) that guarantees detection of any error affecting at most 3 words and has less than a 1 in 10<sup>9</sup> chance of failing to detect more errors. More details about the properties can be found in the Checksum Design appendix<sup>[3](#ChecksumDesign)</sup>. The customization string is processed by feeding each character's US-ASCII value into the checksum calculation prior to the data.
To construct a valid checksum given the human-readable part and (non-checksum) values of the data-part words, the code below can be used:
To construct a valid checksum given the customization string and (non-checksum) values of the data-part words, the code below can be used:
```
```
def rs1024_create_checksum(hrp, data):
def rs1024_create_checksum(cs, data):
values = [ord(x) for x in hrp] + data
values = [ord(x) for x in cs] + data
polymod = rs1024_polymod(values + [0,0,0]) ^ 1
polymod = rs1024_polymod(values + [0,0,0]) ^ 1
return [(polymod >> 10 * (2 - i)) & 1023 for i in range(3)]
return [(polymod >> 10 * (2 - i)) & 1023 for i in range(3)]
```
```
...
@@ -178,7 +178,7 @@ The master secret shall be computed as:
...
@@ -178,7 +178,7 @@ The master secret shall be computed as:
### Advantages and disadvantages
### Advantages and disadvantages
Each of the proposed derivation functions has its pros and cons, we tried to summarise the most important ones in the following table:
Each of the proposed derivation functions has its pros and cons, we tried to summarize the most important ones in the following table: