Commit 0a7fcef6 authored by Jochen Hoenicke's avatar Jochen Hoenicke

Added contents to slip-0010

parent c8ee00e4
......@@ -12,18 +12,102 @@ Created: 2015-12-25
##Abstract
This is a section for an abstract.
SLIP-0010 describes how to derive private and public key pairs for curve
types different from secp256k1.
##Motivation
This is a section for a motivation.
Some Trezor applications, in particular SSH and GPG, need different
curve types, e.g., NIST P-256 and ed25519. For security reasons different
private and public key pairs should be used for these curves. This SLIP
describes how to derive a master private/public key for these curves and
how a BIP-0032 like derivation is used.
##Body
This is a section for a body. The title of the section should be changed
and the section can be split into multiple sections and subsections.
Trezor generates all keys from a 12 to 24 word mnemonic sequence and
optionally a passphrase. The BIP-0039 standard describes the procedure
to compute a 512 bit seed from this passphrase. From this seed Trezor
can create several master keys, one for each curve. It uses a process
similar and compatible to BIP-0032. For other curves it uses a
different salt than BIP-0032. This avoids using the same private key
for different elliptic curves with different orders.
###Master key generation
We adapt the master key generation from BIP-0032 to use a different
key for different curve types. To avoid invalid master keys, the
algorithm is retried with the intermediate hash as new seed if the key
is invalid.
* Generate a seed byte sequence S of 512 bits according to BIP-0039.
* Calculate I = HMAC-SHA512(Key = Curve, Data = S)
* Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.
* Use parse<sub>256</sub>(I<sub>L</sub>) as master secret key, and I<sub>R</sub> as master chain code.
In case I<sub>L</sub> is 0 or ≥n, the master key would be invalid. In this case the procedure is repeated with S := I.
The supported curves are
* Curve = "Bitcoin seed" for the secp256k1 curve (this is compatible to BIP-0032).
* Curve = "Nist256p1 seed" for the NIST P-256 curve.
* Curve = "ed25519 seed" for the ed25519 curve.
For ed25519, the last step always succeeds since every 256-bit number
(even 0) is a valid private key.
###Child key derivation (CKD) functions
Private and public key derivation for NIST P-256 is identical to the
generation for secp256k1 but uses the order of that curve as modulo.
We change BIP-32 to not fail if the resulting key is not valid but
retry hashing until a valid key is found. For ed25519 only hardened
key generation from Private parent key to private child key is supported.
Given a parent extended key and an index i, it is possible to compute
the corresponding child extended key. The algorithm to do so depends
on whether the child is a hardened key or not (or, equivalently,
whether i ≥ 2<sup>31</sup>), and whether we're talking about private
or public keys.
####Private parent key &rarr; private child key
Let n denote the order of the curve.
The function CKDpriv((k<sub>par</sub>, c<sub>par</sub>), i) &rarr; (k<sub>i</sub>, c<sub>i</sub>) computes a child extended private key from the parent extended private key:
* Check whether i ≥ 2<sup>31</sup> (whether the child is a hardened key).
* If so (hardened child): let I = HMAC-SHA512(Key = c<sub>par</sub>, Data = 0x00 || ser<sub>256</sub>(k<sub>par</sub>) || ser<sub>32</sub>(i)). (Note: The 0x00 pads the private key to make it 33 bytes long.)
* If not (normal child):
* If curve is ed25519 fail.
* let I = HMAC-SHA512(Key = c<sub>par</sub>, Data = ser<sub>P</sub>(point(k<sub>par</sub>)) || ser<sub>32</sub>(i)).
* Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.
* The returned chain code c<sub>i</sub> is I<sub>R</sub>.
* If curve is ed25519: The returned child key is I<sub>L</sub>.
* In case parse<sub>256</sub>(I<sub>L</sub>) ≥ n or k<sub>i</sub> = 0, the resulting key is invalid.
let I = HMAC-SHA512(Key = c<sub>par</sub>, Data = 0x01 || I<sub>R</sub> || ser<sub>32</sub>(i) and restart at the third step.
* Otherwise: The returned child key k<sub>i</sub> is parse<sub>256</sub>(I<sub>L</sub>) + k<sub>par</sub> (mod n).
The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC 4231].
####Public parent key &rarr; public child key
This function always fails for ed25519 since normal derivation is not supported.
The function CKDpub((K<sub>par</sub>, c<sub>par</sub>), i) &rarr; (K<sub>i</sub>, c<sub>i</sub>) computes a child extended public key from the parent extended public key. It is only defined for non-hardened child keys.
* Check whether i ≥ 2<sup>31</sup> (whether the child is a hardened key).
* If so (hardened child): return failure
* If not (normal child): let I = HMAC-SHA512(Key = c<sub>par</sub>, Data = ser<sub>P</sub>(K<sub>par</sub>) || ser<sub>32</sub>(i)).
* Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.
* The returned child key K<sub>i</sub> is point(parse<sub>256</sub>(I<sub>L</sub>)) + K<sub>par</sub>.
* The returned chain code c<sub>i</sub> is I<sub>R</sub>.
* In case parse<sub>256</sub>(I<sub>L</sub>) ≥ n or K<sub>i</sub> is the point at infinity, the resulting key is invalid.
let I = HMAC-SHA512(Key = c<sub>par</sub>, Data = 0x01 || I<sub>R</sub> || ser<sub>32</sub>(i)) and restart at the third step.
##Test vectors
... to be included ...
##References
This is a section for references such as links to other documents (BIP or SLIP)
or to reference implementations.
- [BIP-0032: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
- [BIP-0039: Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
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