Factor out Sprout a_sk encoding/decoding into helper functions.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2018-07-13 10:02:09 +01:00
parent 3018efc0f3
commit 5cdc69196a
1 changed files with 13 additions and 15 deletions

View File

@ -253,6 +253,15 @@ We therefore only define and derive Sprout extended spending keys.
We represent a Sprout extended spending key as (*a*\ :sub:`sk`\ , *c*), where *a*\ :sub:`sk` is the normal
Sprout spending key, and *c* is the chain code.
Helper functions
----------------
Let EncodeASK(*a*\ :sub:`sk`) be the 32-byte encoding of *a*\ :sub:`sk` in the raw encoding of a Sprout
spending key (excluding lead bytes) as specified in [#sapling-spec]_ section 5.6.8.
Let DecodeASK(*ASK*) be the result of clearing the 4 most significant bits of the first byte of *ASK*,
and decoding the 32-byte result according to the inverse of EncodeASK.
Master key generation
---------------------
@ -260,10 +269,7 @@ Let *S* be a seed byte sequence of a chosen length.
- Calculate *I* = BLAKE2b-512("ZcashIP32_Sprout", *S*).
- Split *I* into two 32-byte sequences, I\ :sub:`L` and I\ :sub:`R`\ .
- Interpret *I*\ :sub:`L` as the master spending key a\ :sub:`sk,m` \ by clearing the 4 most
significant bits of the first byte, and decoding the 32-byte result in the same way as for
*a*\ :sub:`sk` \ in the raw encoding of a Sprout spending key (excluding lead bytes) in
[#sapling-spec]_ section 5.6.8.
- Use DecodeASK(*I*\ :sub:`L`\ ) as the master spending key a\ :sub:`sk,m`\ .
- Use *I*\ :sub:`R` as the master chain code *c*\ :sub:`m`\ .
Child key derivation
@ -273,16 +279,11 @@ CDKsk((*a*\ :sub:`sk,par`\ , *c*\ :sub:`par`\ ), *i*) → (*a*\ :sub:`sk,i`\ , *
- Check whether *i* ≥ 2\ :sup:`31` (whether the child is a hardened key).
- If so (hardened child): let *I* = PRF\ :sup:`expand`\ (*c*\ :sub:`par`\ , [0x80] || *ASK*\ :sub:`par` || I2LEOSP\ :sub:`32`\ (*i*))
where *ASK*\ :sub:`par` is the encoding of *a*\ :sub:`sk,par` excluding lead bytes from
[#sapling-spec]_ section 5.6.8.
- If so (hardened child): let *I* = PRF\ :sup:`expand`\ (*c*\ :sub:`par`\ , [0x80] || EncodeASK(*a*\ :sub:`sk,par`\ ) || I2LEOSP\ :sub:`32`\ (*i*))
- If not (normal child): return failure
- Split *I* into two 32-byte sequences, *I*\ :sub:`L` and *I*\ :sub:`R`\ .
- Interpret *I*\ :sub:`L` as the child spending key a\ :sub:`sk,i` \ by clearing the 4 most
significant bits of the first byte, and decoding the 32-byte result in the same way as for
*a*\ :sub:`sk` \ in the raw encoding of a Sprout spending key (excluding lead bytes) in
[#sapling-spec]_ section 5.6.8.
- Use DecodeASK(*I*\ :sub:`L`\ ) as the child spending key a\ :sub:`sk,i`\ .
- Use *I*\ :sub:`R` as the child chain code *c*\ :sub:`i`\ .
@ -424,10 +425,7 @@ A Sprout extended spending key (*a*\ :sub:`sk`\ , *c*), at depth *depth*, with
parent address tag *parent_addr_tag* and child number *i*, is represented as a
byte sequence:
I2LEOSP\ :sub:`8`\ (*depth*) || *parent_addr_tag* || I2LEOSP\ :sub:`32`\ (*i*) || *c* || *ASK*
where *ASK* is the 32-byte encoding of *a*\ :sub:`sk` in the raw encoding of a Sprout
spending key (excluding lead bytes) as specified in [#sapling-spec]_ section 5.6.8.
I2LEOSP\ :sub:`8`\ (*depth*) || *parent_addr_tag* || I2LEOSP\ :sub:`32`\ (*i*) || *c* || EncodeASK(*a*\ :sub:`sk`\ )
For the master extended spending key, *depth* is 0, *parent_addr_tag* is 4 zero bytes,
and *i* is 0.