new file: Seed-Splitting,-Theory-and-Practice.md

The MMGen Project 2019-11-18 21:13:17 +00:00
commit 545d92705b
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2

@ -0,0 +1,119 @@
### Contents
+ [N-of-N Seed Splitting: A Theoretical Introduction](#a_nn)
+ [Seed Splitting with MMGen](#a_ss)
#### <a name='a_nn'>N-of-N Seed Splitting: A Theoretical Introduction</a>
The bitwise exclusive-or operation (usually denoted as `XOR`, or “![⊕]”)
has interesting properties that make it very useful in cryptography.
Suppose we have two bytes, *a* and *b*:
![]["a: 1 0 0 1 0 1 0 0"]
![]["b: 0 1 0 1 1 1 1 0"]
To XOR the two bytes, we compare each of their bits. If the bit is the same for
both *a* and *b,* the corresponding bit of the result is 0. If it differs, the
result is 1:
![]["a ⊖ b: 1 1 0 0 1 0 1 0"]
Thus XOR can be thought of logically as “one or the other but not both”, or
arithmetically as addition [modulo][wm] 2 without carry, since 1 plus 1 equals 0
in base-2 arithmetic.
As is clear from our above example, switching the order of *a* and *b* has no
effect on the result. So XOR, like addition, is commutative:
![]["a ⊕ b = b ⊕ a"]
And like addition, grouping has no effect on the result. XOR is associative:
![]["a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c"]
But unlike addition, XOR has an extra property: *invertibility.* The result can
be switched with any of the operands, making XOR sort of like addition and
subtraction rolled into one. Thus, if
![]["a ⊕ b = c"]
then
![]["c ⊕ a = b"]
![]["b ⊕ c = a"]
and so forth.
This last property makes XOR very handy for encryption and decryption. Given
a plaintext *P* and a random value *r* with the same bit length as *P*, we
encrypt *P* by XOR’ing it with *r* to obtain the ciphertext *C:*
![]["P ⊕ r = C"]
To decrypt, we just XOR the ciphertext with *r* to recover the plaintext:
![]["C ⊕ r = P"]
The randomness of the ciphertext is guaranteed to be no less than that of the
random value. Thus if *r* is perfectly random, then *C* is perfectly
undecipherable without knowledge of *r.* This is the principle underlying the
[one-time pads][otp] used by spies and diplomats before the computer age, as
well as modern [stream ciphers][sc].
To demonstrate how this can be used for seed splitting, all we do is change
the names of the variables:
![]["seed ⊕ share1 = share2"]
Here *seed* is analogous to *P* in the previous example, *share<sub>1</sub>* is
a random value with the same bit length as *seed,* and *share<sub>2</sub>* is
the resulting “ciphertext”. Just as the ciphertext reveals nothing about the
plaintext in the previous example, *share<sub>2</sub>* reveals nothing about
*seed* without knowledge of *share<sub>1</sub>.* And *share<sub>1</sub>,* of
course, being a random value, reveals nothing about *seed* either. To recover
the seed, we just XOR the two shares. Since XOR is commutative, the order in
which we combine them isn’t important:
![]["share2 ⊕ share1 = seed"]
Thanks to XOR’s associativity, splits of arbitrary length can be created by
using an arbitrary number of random shares:
Perform an *n*-way split:
![]["seed ⊕ share1 ⊕ share2 ... ⊕ shareN-1 = shareN"]
Recover the seed:
![]["share1 ⊕ share2 ... ⊕ shareN = seed"]
Knowledge of anything less than *n* shares reveals nothing about the seed.
#### <a name='a_ss'>Seed Splitting with MMGen</a>
The MMGen wallet implements seed-splitting functionality via the commands
`mmgen-seedsplit` and `mmgen-seedjoin`.
TBD
[⊕]: https://mmgen.github.io/images/ss/o_xor.svg "⊕"
["a: 1 0 0 1 0 1 0 0"]: https://mmgen.github.io/images/ss/byte_a.svg "a: 1 0 0 1 0 1 0 0"
["b: 0 1 0 1 1 1 1 0"]: https://mmgen.github.io/images/ss/byte_b.svg "b: 0 1 0 1 1 1 1 0"
["a ⊖ b: 1 1 0 0 1 0 1 0"]: https://mmgen.github.io/images/ss/byte_ab.svg "a ⊖ b: 1 1 0 0 1 0 1 0"
["a ⊕ b = b ⊕ a"]: https://mmgen.github.io/images/ss/ab-ba.svg "a ⊕ b = b ⊕ a"
["a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c"]: https://mmgen.github.io/images/ss/abc.svg "a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c"
["a ⊕ b = c"]: https://mmgen.github.io/images/ss/ab-c.svg "a ⊕ b = c"
["c ⊕ a = b"]: https://mmgen.github.io/images/ss/ca-b.svg "c ⊕ a = b"
["b ⊕ c = a"]: https://mmgen.github.io/images/ss/bc-a.svg "b ⊕ c = a"
["P ⊕ r = C"]: https://mmgen.github.io/images/ss/Pr-C.svg "P ⊕ r = C"
["C ⊕ r = P"]: https://mmgen.github.io/images/ss/Cr-P.svg "C ⊕ r = P"
["seed ⊕ share1 = share2"]: https://mmgen.github.io/images/ss/ss-enc.svg "seed ⊕ share1 = share2"
["share2 ⊕ share1 = seed"]: https://mmgen.github.io/images/ss/ss-dec.svg "share2 ⊕ share1 = seed"
["seed ⊕ share1 ⊕ share2 ... ⊕ shareN-1 = shareN"]: https://mmgen.github.io/images/ss/ssN-enc.svg "seed ⊕ share1 ⊕ share2 ... ⊕ shareN-1 = shareN"
["share1 ⊕ share2 ... ⊕ shareN = seed"]: https://mmgen.github.io/images/ss/ssN-dec.svg "share1 ⊕ share2 ... ⊕ shareN = seed"
[wm]: https://en.wikipedia.org/wiki/Modular_arithmetic
[otp]: https://en.wikipedia.org/wiki/One-time_pad
[sc]: https://en.wikipedia.org/wiki/Stream_cipher