Clarifications of the algorithm

parent c5b6871c
......@@ -35,16 +35,25 @@ 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.
We adapt the master key generation from BIP-0032. To use different
private keys for different curves we use different keys for the HMAC
hash that generates the master key. For the NIST P-256 curve the only
other difference is the different group order. In the algorithm below
we denote the group order of the elliptic curve with n. For ed25519
curve the private keys are no longer multipliers for the group
generator; instead the hash of the private key is the multiplier. For
this reason, our scheme for ed25519 does not support public key
derivation and uses the produced hashes directly as private keys.
To avoid invalid master keys, the algorithm is retried with the
intermediate hash as new seed if the key is invalid.
1. Generate a seed byte sequence S of 512 bits according to BIP-0039.
2. Calculate I = HMAC-SHA512(Key = Curve, Data = S)
3. Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.
4. Use parse<sub>256</sub>(I<sub>L</sub>) as master secret key, and I<sub>R</sub> as master chain code.
5. If curve is not ed25519 and I<sub>L</sub> is 0 or ≥ n (invalid key):
* Set S := I and continue at step 2.
The supported curves are
......@@ -74,17 +83,18 @@ or public keys.
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).
1. 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.
* If curve is ed25519: return failure.
* 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).
2. Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.
3. The returned chain code c<sub>i</sub> is I<sub>R</sub>.
4. If curve is ed25519: The returned child key k<sub>i</sub> is parse<sub>256</sub>(I<sub>L</sub>).
5. If parse<sub>256</sub>(I<sub>L</sub>) ≥ n or parse<sub>256</sub>(I<sub>L</sub>) + k<sub>par</sub> = 0 (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 step 2.
6. 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].
......@@ -93,14 +103,15 @@ The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC
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).
1. 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.
2. Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.
3. The returned child key K<sub>i</sub> is point(parse<sub>256</sub>(I<sub>L</sub>)) + K<sub>par</sub>.
4. The returned chain code c<sub>i</sub> is I<sub>R</sub>.
5. If 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 step 2.
## Test vectors
......
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