mirror of https://github.com/zcash/zips.git
Merge pull request #157 from str4d/zip-0032
[ZIP 32] Shielded Hierarchical Deterministic Wallets
This commit is contained in:
commit
f6f47a0ecd
|
@ -0,0 +1,483 @@
|
||||||
|
::
|
||||||
|
|
||||||
|
ZIP: 32
|
||||||
|
Title: Shielded Hierarchical Deterministic Wallets
|
||||||
|
Author: Jack Grigg <jack@z.cash>
|
||||||
|
Daira Hopwood <daira@z.cash>
|
||||||
|
Credits: Pieter Wuille <pieter.wuille@gmail.com>
|
||||||
|
Marek Palatinus <slush@satoshilabs.com>
|
||||||
|
Pavol Rusnak <stick@satoshilabs.com>
|
||||||
|
Category: Standards Track
|
||||||
|
Created: 2018-05-22
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
|
||||||
|
Terminology
|
||||||
|
===========
|
||||||
|
|
||||||
|
The key words "MUST", "MUST NOT", and "MAY" in this document are to be interpreted as described in RFC 2119.
|
||||||
|
[#RFC2119]_
|
||||||
|
|
||||||
|
"Jubjub" refers to the elliptic curve defined in [#sapling-spec]_ section 5.4.8.3.
|
||||||
|
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
========
|
||||||
|
|
||||||
|
This proposal defines a mechanism for extending hierarchical deterministic wallets, as decribed in BIP 32
|
||||||
|
[#bip-0032]_, to support Zcash's shielded addresses.
|
||||||
|
|
||||||
|
The specification has three parts. The first part defines a system for deriving a tree of Sapling key
|
||||||
|
components from a single seed. The second part defines an equivalent, but independent, system for Sprout key
|
||||||
|
components (which have a different internal construction). The third part shows how to use these trees in the
|
||||||
|
context of existing BIP 44 [#bip-0044]_ wallets.
|
||||||
|
|
||||||
|
This specification complements the existing use by some Zcash wallets of BIP 32 and BIP 44 for transparent
|
||||||
|
Zcash addresses, and is not intended to deprecate that usage (privacy risks of using transparent addresses
|
||||||
|
notwithstanding).
|
||||||
|
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
==========
|
||||||
|
|
||||||
|
BIP 32 [#bip-0032]_ is the standard mechanism by which wallets for Bitcoin and its derivatives (including
|
||||||
|
Zcash's transparent addresses [#slip-0044]_) generate keys and addresses deterministically. This has several
|
||||||
|
advantages over random generation:
|
||||||
|
|
||||||
|
- Wallets only need to store a single seed (particularly useful for hardware wallets).
|
||||||
|
- A one-time backup of the seed (usually stored as a word phrase [#bip-0039]_) can be used to recover funds
|
||||||
|
from all future addresses.
|
||||||
|
- Keys are arranged into a tree of chains, enabling wallets to represent "accounts" or other high-level
|
||||||
|
structures.
|
||||||
|
- View authority or spend authority can be delegated independently for sub-trees without compromising the
|
||||||
|
master seed.
|
||||||
|
|
||||||
|
At present, no such equivalent exists for Zcash's shielded addresses. This is of particular concern for
|
||||||
|
hardware wallets; all currently-marketed devices only store a seed internally, and have trained their users
|
||||||
|
to only backup that seed. Given that the Sapling upgrade will make it feasible to use hardware wallets with
|
||||||
|
shielded addresses, it is desirable to have a standard mechanism for deriving them.
|
||||||
|
|
||||||
|
|
||||||
|
Conventions
|
||||||
|
===========
|
||||||
|
|
||||||
|
Most of the notation and functions used in this ZIP are defined in the Sapling protocol specification
|
||||||
|
[#sapling-spec]_. They are reproduced here for convenience:
|
||||||
|
|
||||||
|
- truncate\ :sub:`k`\ (*S*) means the sequence formed from the first *k* elements of *S*.
|
||||||
|
|
||||||
|
- *a* || *b* means the concatenation of sequences *a* then *b*.
|
||||||
|
|
||||||
|
- [*k*] *P* means scalar multiplication of the elliptic curve point *P* by the scalar *k*.
|
||||||
|
|
||||||
|
- LEOS2IP\ :sub:`l`\ (*S*) is the integer in range {0..2\ :sup:`l`\ -1} represented in little-endian order
|
||||||
|
by the byte sequence *S* of length *l*/8.
|
||||||
|
|
||||||
|
- I2LEBSP\ :sub:`l`\ (*k*) is the sequence of *l* bits representing *k* in little-endian order.
|
||||||
|
|
||||||
|
- LEBS2OSP\ :sub:`l`\ (*B*) is defined as follows when *l* is a multiple of 8: convert each group of 8 bits
|
||||||
|
in *B* to a byte value with the least significant bit first, and concatenate the resulting bytes in the
|
||||||
|
same order as the groups.
|
||||||
|
|
||||||
|
- repr\ :sub:`𝕁`\ (*P*) is the representation of the Jubjub elliptic curve point *P* as a bit sequence,
|
||||||
|
defined in [#sapling-spec]_ section 5.4.8.3.
|
||||||
|
|
||||||
|
- BLAKE2b-256(*p*, *x*) refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of
|
||||||
|
32 bytes, 16-byte personalization string *p*, and input *x*.
|
||||||
|
|
||||||
|
- BLAKE2b-512(*p*, *x*) refers to unkeyed BLAKE2b-512 in sequential mode, with an output digest length of
|
||||||
|
64 bytes, 16-byte personalization string *p*, and input *x*.
|
||||||
|
|
||||||
|
- PRF\ :sup:`expand`\ (*sk*, *t*) := BLAKE2b-512("Zcash_ExpandSeed", *sk* || *t*)
|
||||||
|
|
||||||
|
- ToScalar(*x*) := LEOS2IP\ :sub:`512`\ (*x*) (mod *r*\ :sub:`𝕁`\ ), where *r*\ :sub:`𝕁` \ is the order
|
||||||
|
of the Jubjub large prime subgroup.
|
||||||
|
|
||||||
|
- DiversifyHash(*d*) maps a diversifier *d* to a base point on the Jubjub elliptic curve, or to ⊥ if the
|
||||||
|
diversifier is invalid. It is instantiated in [#sapling-spec]_ section 5.4.1.6.
|
||||||
|
|
||||||
|
The following algorithm standardized in [#NIST-SP-800-38G]_ is used:
|
||||||
|
|
||||||
|
- FF1-AES256.Encrypt(*key*, *tweak*, *x*) refers to the FF1 encryption algorithm using AES with a
|
||||||
|
256-bit *key*, and parameters *radix* = 2, *minlen* = 88, *maxlen* = 88. It will be used only with
|
||||||
|
the empty string "" as the *tweak*. *x* is a sequence of 88 bits, as is the output.
|
||||||
|
|
||||||
|
We also define the following conversion function:
|
||||||
|
|
||||||
|
- I2LEOSP\ :sub:`l`\ (*k*) is the byte sequence *S* of length *l*/8 representing in little-endian order the
|
||||||
|
integer *k* in range {0..2\ :sup:`l`\ -1}. It is the reverse operation of LEOS2IP\ :sub:`l`\ (*S*).
|
||||||
|
|
||||||
|
Implementors should note that this ZIP is consistently little-endian (in keeping with the Sapling
|
||||||
|
specification), which is the opposite of BIP 32.
|
||||||
|
|
||||||
|
We adapt the path notation of BIP 32 [#bip-0032]_ to describe shielded HD paths, using apostrophes to
|
||||||
|
indicate hardened derivation (i' = i + 2\ :sup:`31`\ ) as in BIP 44 [#bip-0044]_:
|
||||||
|
|
||||||
|
- CDKsk(CDKsk(CDKsk(m\ :sub:`Sprout`\ , a'), b), c) is written as m\ :sub:`Sprout` / a' / b / c
|
||||||
|
- CDKfvk(CDKfvk(CDKfvk(M\ :sub:`Sapling`\ , a), b), c) is written as M\ :sub:`Sapling` / a / b / c
|
||||||
|
|
||||||
|
|
||||||
|
Specification: Sapling key derivation
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Sapling extended keys
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
BIP 32 defines a method to derive a number of child keys from a parent key. In order to prevent these from
|
||||||
|
depending solely on the parent key itself, both the private and public keys are extended with a 32-byte chain
|
||||||
|
code. We similarly extend Sapling keys with a chain code here. However, the concepts of "private" and "public"
|
||||||
|
keys in BIP 32 do not map cleanly to Sapling's key components. We take the following approach:
|
||||||
|
|
||||||
|
- We derive child Sapling expanded spending keys, rather than Sapling spending keys. This enables us to
|
||||||
|
implement both hardened and non-hardened derivation modes (the latter being incompatible with Sapling
|
||||||
|
spending keys).
|
||||||
|
|
||||||
|
- We do not derive Sapling public keys directly, as this would prevent the use of diversified addresses.
|
||||||
|
Instead, we derive Sapling full viewing keys, from which payment addresses can be generated. This maintains
|
||||||
|
the trust semantics of BIP 32: someone with access to a BIP 32 extended public key is able to view all
|
||||||
|
transactions involving that address, which a Sapling full viewing key also enables.
|
||||||
|
|
||||||
|
We represent a Sapling extended spending key as (*ask*, *nsk*, *ovk*, *dk*, *c*), where (*ask*, *nsk*, *ovk*)
|
||||||
|
is the normal Sapling expanded spending key, *dk* is a diversifier key, and *c* is the chain code.
|
||||||
|
|
||||||
|
We represent a Sapling extended full viewing key as (*ak*, *nk*, *ovk*, *dk*, *c*), where (*ak*, *nk*, *ovk*)
|
||||||
|
is the normal Sapling full viewing key, *dk* is the same diversifier key as above, and *c* is the chain code.
|
||||||
|
|
||||||
|
Helper functions
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Define EncodeExtSKParts(*ask*, *nsk*, *ovk*, *dk*) := I2LEOSP\ :sub:`256`\ (*ask*) || I2LEOSP\ :sub:`256`\ (*nsk*) || *ovk* || *dk*.
|
||||||
|
|
||||||
|
Define EncodeExtFVKParts(*ak*, *nk*, *ovk*, *dk*) := LEBS2OSP\ :sub:`256`\ (repr\ :sub:`𝕁`\ (*ak*)) || LEBS2OSP\ :sub:`256`\ (repr\ :sub:`𝕁`\ (*nk*)) || *ovk* || *dk*.
|
||||||
|
|
||||||
|
Master key generation
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Let *S* be a seed byte sequence of a chosen length, which MUST be at least 32 bytes.
|
||||||
|
|
||||||
|
- Calculate *I* = BLAKE2b-512("ZcashIP32Sapling", *S*).
|
||||||
|
- Split *I* into two 32-byte sequences, *I*\ :sub:`L` and *I*\ :sub:`R`\ .
|
||||||
|
- Use *I*\ :sub:`L` as the master spending key *sk*\ :sub:`m`\ , and *I*\ :sub:`R` as the master chain code
|
||||||
|
*c*\ :sub:`m`\ .
|
||||||
|
- Calculate *ask*\ :sub:`m`\ , *nsk*\ :sub:`m`\ , and *ovk*\ :sub:`m` via the standard Sapling derivation
|
||||||
|
[#sapling-key-components]_:
|
||||||
|
|
||||||
|
- *ask*\ :sub:`m` = ToScalar(PRF\ :sup:`expand`\ (*sk*\ :sub:`m`\ , [0x00]))
|
||||||
|
- *nsk*\ :sub:`m` = ToScalar(PRF\ :sup:`expand`\ (*sk*\ :sub:`m`\ , [0x01]))
|
||||||
|
- *ovk*\ :sub:`m` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*sk*\ :sub:`m`\ , [0x02]))
|
||||||
|
|
||||||
|
- Calculate *dk*\ :sub:`m` similarly:
|
||||||
|
|
||||||
|
- *dk*\ :sub:`m` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*sk*\ :sub:`m`\ , [0x10]))
|
||||||
|
|
||||||
|
- Return (*ask*\ :sub:`m`\ , *nsk*\ :sub:`m`\ , *ovk*\ :sub:`m`\ , *dk*\ :sub:`m`\ , *c*\ :sub:`m`\ ) as the
|
||||||
|
master extended spending key *m*\ :sub:`Sapling`\ .
|
||||||
|
|
||||||
|
Child key derivation
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index *i*,
|
||||||
|
depends on the type of key being derived, and whether this is a hardened or non-hardened derivation.
|
||||||
|
|
||||||
|
Deriving a child extended spending key
|
||||||
|
``````````````````````````````````````
|
||||||
|
CDKsk((*ask*\ :sub:`par`\ , *nsk*\ :sub:`par`\ , *ovk*\ :sub:`par`\ , *dk*\ :sub:`par`\ , *c*\ :sub:`par`\ ), *i*) →
|
||||||
|
(*ask*\ :sub:`i`\ , *nsk*\ :sub:`i`\ , *ovk*\ :sub:`i`\ , *dk*\ :sub:`i`\ , *c*\ :sub:`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`\ , [0x11] || EncodeExtSKParts(*ask*\ :sub:`par`\ , *nsk*\ :sub:`par`\ , *ovk*\ :sub:`par`\ , *dk*\ :sub:`par`\ ) || I2LEOSP\ :sub:`32`\ (*i*))
|
||||||
|
- If not (normal child): let *I* = PRF\ :sup:`expand`\ (*c*\ :sub:`par`\ , [0x12] || EncodeExtFVKParts(*ak*\ :sub:`par`\ , *nk*\ :sub:`par`\ , *ovk*\ :sub:`par`\ , *dk*\ :sub:`par`\ ) || I2LEOSP\ :sub:`32`\ (*i*))
|
||||||
|
where (*nk*\ :sub:`par`\ , *ak*\ :sub:`par`\ , *ovk*\ :sub:`par`\ ) is the full viewing key derived from
|
||||||
|
(*ask*\ :sub:`par`\ , *nsk*\ :sub:`par`\ , *ovk*\ :sub:`par`\ ) as described in [#sapling-key-components]_.
|
||||||
|
|
||||||
|
- Split *I* into two 32-byte sequences, *I*\ :sub:`L` and *I*\ :sub:`R`\ .
|
||||||
|
- Let *I*\ :sub:`ask` = ToScalar(PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x13]))
|
||||||
|
- Let *I*\ :sub:`nsk` = ToScalar(PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x14]))
|
||||||
|
- Return:
|
||||||
|
|
||||||
|
- *ask*\ :sub:`i` = *I*\ :sub:`ask` + *ask*\ :sub:`par`
|
||||||
|
- *nsk*\ :sub:`i` = *I*\ :sub:`nsk` + *nsk*\ :sub:`par`
|
||||||
|
- *ovk*\ :sub:`i` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x15] || *ovk*\ :sub:`par`\ ))
|
||||||
|
- *dk*\ :sub:`i` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x16] || *dk*\ :sub:`par`\ ))
|
||||||
|
- *c*\ :sub:`i` = *I*\ :sub:`R`
|
||||||
|
|
||||||
|
Deriving a child extended full viewing key
|
||||||
|
``````````````````````````````````````````
|
||||||
|
Let 𝓖 be as defined in [#sapling-spec]_ section 5.4.6.1 and let 𝓗 be as defined in [#sapling-key-components]_.
|
||||||
|
|
||||||
|
CDKfvk((*ak*\ :sub:`par`\ , *nk*\ :sub:`par`\ , *ovk*\ :sub:`par`\ , *dk*\ :sub:`par`\ , *c*\ :sub:`par`\ ), *i*) →
|
||||||
|
(*ak*\ :sub:`i`\ , *nk*\ :sub:`i`\ , *ovk*\ :sub:`i`\ , *dk*\ :sub:`i`\ , *c*\ :sub:`i`\ )
|
||||||
|
|
||||||
|
- Check whether *i* ≥ 2\ :sup:`31` (whether the child is a hardened key).
|
||||||
|
|
||||||
|
- If so (hardened child): return failure
|
||||||
|
- If not (normal child): let *I* = PRF\ :sup:`expand`\ (*c*\ :sub:`par`\ , [0x12] || EncodeExtFVKParts(*ak*\ :sub:`par`\ , *nk*\ :sub:`par`\ , *ovk*\ :sub:`par`\ , *dk*\ :sub:`par`\ ) || I2LEOSP\ :sub:`32`\ (*i*))
|
||||||
|
|
||||||
|
- Split *I* into two 32-byte sequences, *I*\ :sub:`L` and *I*\ :sub:`R`\ .
|
||||||
|
- Let *I*\ :sub:`ask` = ToScalar(PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x13]))
|
||||||
|
- Let *I*\ :sub:`nsk` = ToScalar(PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x14]))
|
||||||
|
- Return:
|
||||||
|
|
||||||
|
- *ak*\ :sub:`i` = [*I*\ :sub:`ask`\ ] 𝓖 + *ak*\ :sub:`par`
|
||||||
|
- *nk*\ :sub:`i` = [*I*\ :sub:`nsk`\ ] 𝓗 + *nk*\ :sub:`par`
|
||||||
|
- *ovk*\ :sub:`i` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x15] || *ovk*\ :sub:`par`\ ))
|
||||||
|
- *dk*\ :sub:`i` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x16] || *dk*\ :sub:`par`\ ))
|
||||||
|
- *c*\ :sub:`i` = *I*\ :sub:`R`
|
||||||
|
|
||||||
|
Diversifier derivation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key *dk*. To prevent the
|
||||||
|
diversifier leaking how many diversified addresses have already been generated for an account, we make the
|
||||||
|
sequence of diversifiers pseudorandom and uncorrelated to that of any other account. In order to reach the
|
||||||
|
maximum possible diversifier range without running into repetitions due to the birthday bound, we use
|
||||||
|
FF1-AES256 as a Pseudo-Random Permutation as follows:
|
||||||
|
|
||||||
|
- Let *j* be the index of the desired diversifier, in the range 0 .. 2\ :sup:`88`\ -1.
|
||||||
|
- *d*\ :sub:`j` = FF1-AES256.Encrypt(*dk*, "", I2LEBSP\ :sub:`88`\ (*j*)).
|
||||||
|
|
||||||
|
A valid diversifier *d*\ :sub:`j` is one for which DiversifyHash(*d*\ :sub:`j`) ≠ ⊥.
|
||||||
|
For a given *dk*, approximately half of the possible values of *j* yield valid diversifiers.
|
||||||
|
|
||||||
|
The default diversifier for a Sapling extended key is defined to be *d*\ :sub:`j`\ , where *j* is the
|
||||||
|
least nonnegative integer yielding a valid diversifier.
|
||||||
|
|
||||||
|
|
||||||
|
Specification: Sprout key derivation
|
||||||
|
====================================
|
||||||
|
|
||||||
|
For completeness, we define a system for deriving a tree of Sprout key components. It is unlikely that this
|
||||||
|
will garner much usage once Sapling activates, but is presented for those users who may require it.
|
||||||
|
|
||||||
|
Sprout extended keys
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Due to the way Sprout keys are constructed and used, it is not possible to derive incoming viewing keys or
|
||||||
|
payment addresses in parallel with spending keys. Nor is it possible to implement non-hardened derivation.
|
||||||
|
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
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Let *S* be a seed byte sequence of a chosen length, which MUST be at least 32 bytes.
|
||||||
|
|
||||||
|
- Calculate *I* = BLAKE2b-512("ZcashIP32_Sprout", *S*).
|
||||||
|
- Split *I* into two 32-byte sequences, I\ :sub:`L` and I\ :sub:`R`\ .
|
||||||
|
- 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
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
CDKsk((*a*\ :sub:`sk,par`\ , *c*\ :sub:`par`\ ), *i*) → (*a*\ :sub:`sk,i`\ , *c*\ :sub:`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] || 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`\ .
|
||||||
|
- 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`\ .
|
||||||
|
|
||||||
|
|
||||||
|
Specification: Wallet usage
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Existing Zcash-supporting HD wallets all use BIP 44 [#bip-0044]_ to organize their derived keys. In order to
|
||||||
|
more easily mesh with existing user experiences, we broadly follow BIP 44's design here. However, we have
|
||||||
|
altered the design where it makes sense to leverage features of shielded addresses.
|
||||||
|
|
||||||
|
Key path levels
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Both Sprout and Sapling key paths have the following three path levels at the top, all of which use hardened
|
||||||
|
derivation:
|
||||||
|
|
||||||
|
- ``purpose``: a constant set to 32' (or 0x80000020) following the BIP 43 recommendation. It indicates that
|
||||||
|
the subtree of this node is used according to this specification.
|
||||||
|
|
||||||
|
- ``coin_type``: a constant identifying the cybercoin that this subtree's keys are used with. For
|
||||||
|
compatibility with existing BIP 44 implementations, we use the same constants as defined in SLIP 44
|
||||||
|
[#slip-0044]_. Note that in keeping with that document, all cybercoin testnets share ``coin_type`` index 1.
|
||||||
|
|
||||||
|
- ``account``: numbered from index 0 in sequentially increasing manner. Defined as in BIP 44 [#bip-0044]_.
|
||||||
|
|
||||||
|
Unlike BIP 44, neither Sprout nor Sapling have a `change` path level. The use of change addresses in Bitcoin
|
||||||
|
is a (failed) attempt to increase the difficulty of tracking users on the transaction graph, by segregating
|
||||||
|
external and internal address usage. Shielded addresses are never publicly visible in transactions, which
|
||||||
|
means that sending change back to the originating address is indistinguishable from using a change address.
|
||||||
|
|
||||||
|
Sapling key path
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Sapling provides a mechanism to allow the efficient creation of diversified payment addresses with the same
|
||||||
|
spending authority. A group of such addresses shares the same full viewing key and incoming viewing key, and
|
||||||
|
so creating as many unlinkable addresses as needed does not increase the cost of scanning the block chain for
|
||||||
|
relevant transactions.
|
||||||
|
|
||||||
|
The above key path levels include an account identifier, which in all user interfaces is represented as a
|
||||||
|
"bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Sapling
|
||||||
|
ZIP 32 derivation MUST support the following path for any account in range {0..2\ :sup:`31`\ -1}::
|
||||||
|
|
||||||
|
m_Sapling / purpose' / coin_type' / account'
|
||||||
|
|
||||||
|
Furthermore, wallets MUST support generating the default payment address (corresponding to the default
|
||||||
|
diversifier as defined above) for any account they support. They MAY also support generating a stream of
|
||||||
|
payment addresses for a given account, if they wish to maintain the user experience of giving a unique
|
||||||
|
address to each recipient.
|
||||||
|
|
||||||
|
Note that a given account can have a maximum of approximately 2\ :sup:`87` payment addresses, because each
|
||||||
|
diversifier has around a 50% chance of being invalid.
|
||||||
|
|
||||||
|
If in certain circumstances a wallet needs to derive independent spend authorities within a single account,
|
||||||
|
they MAY additionally support a non-hardened ``address_index`` path level as in [#bip-0044]_::
|
||||||
|
|
||||||
|
m_Sapling / purpose' / coin_type' / account' / address_index
|
||||||
|
|
||||||
|
Sprout key path
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Wallets implementing Sprout ZIP 32 derivation MUST support the following path::
|
||||||
|
|
||||||
|
m_Sprout / purpose' / coin_type' / account' / address_index
|
||||||
|
|
||||||
|
|
||||||
|
Specification: Fingerprints and Tags
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Sapling Full Viewing Key Fingerprints and Tags
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
A "Sapling full viewing key fingerprint" of a full viewing key with raw encoding *FVK* (as specified
|
||||||
|
in [#sapling-spec]_ section 5.6.7) is given by:
|
||||||
|
|
||||||
|
BLAKE2b-256("ZcashSaplingFVFP", *FVK*)
|
||||||
|
|
||||||
|
It MAY be used to uniquely identify a particular Sapling full viewing key.
|
||||||
|
|
||||||
|
A "Sapling full viewing key tag" is the first 4 bytes of the corresponding Sapling full viewing key
|
||||||
|
fingerprint. It is intended for optimizing performance of key lookups, and MUST NOT be assumed to
|
||||||
|
uniquely identify a particular key.
|
||||||
|
|
||||||
|
Sprout Address Fingerprints and Tags
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
A "Sprout address fingerprint" of a Sprout payment address with raw encoding *ADDR* (as specified in
|
||||||
|
[#sapling-spec]_ section 5.6.3, including the lead bytes) is given by:
|
||||||
|
|
||||||
|
BLAKE2b-256("Zcash_Sprout_AFP", *ADDR*)
|
||||||
|
|
||||||
|
It MAY be used to uniquely identify a particular Sprout payment address.
|
||||||
|
|
||||||
|
A "Sprout address tag" is the first 4 bytes of the corresponding Sprout address fingerprint. It is
|
||||||
|
intended for optimizing performance of address lookups, and MUST NOT be assumed to uniquely identify
|
||||||
|
a particular address.
|
||||||
|
|
||||||
|
Seed Fingerprints
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
A "seed fingerprint" for the master seed *S* of a hierarchical deterministic wallet is given by:
|
||||||
|
|
||||||
|
BLAKE2b-256("Zcash_HD_Seed_FP", *S*)
|
||||||
|
|
||||||
|
It MAY be used to uniquely identify a particular hierarchical deterministic wallet.
|
||||||
|
|
||||||
|
No corresponding short tag is defined.
|
||||||
|
|
||||||
|
|
||||||
|
Specification: Key Encodings
|
||||||
|
============================
|
||||||
|
|
||||||
|
The following encodings are analogous to the ``xprv`` and ``xpub`` encodings defined
|
||||||
|
in BIP 32 for transparent keys and addresses. Each key type has a raw representation
|
||||||
|
and a Bech32 [#bip-0173]_ encoding.
|
||||||
|
|
||||||
|
|
||||||
|
Sapling extended spending keys
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
A Sapling extended spending key (*ask*, *nsk*, *ovk*, *dk*, *c*), at depth *depth*,
|
||||||
|
with parent full viewing key tag *parent_fvk_tag* and child number *i*, is
|
||||||
|
represented as a byte sequence:
|
||||||
|
|
||||||
|
I2LEOSP\ :sub:`8`\ (*depth*) || *parent_fvk_tag* || I2LEOSP\ :sub:`32`\ (*i*) || *c* || EncodeExtSKParts(*ask*, *nsk*, *ovk*, *dk*)
|
||||||
|
|
||||||
|
For the master extended spending key, *depth* is 0, *parent_fvk_tag* is 4 zero bytes,
|
||||||
|
and *i* is 0.
|
||||||
|
|
||||||
|
When encoded as Bech32, the Human-Readable Part is ``secret-extended-key-main``
|
||||||
|
for the production network, or ``secret-extended-key-test`` for the test network.
|
||||||
|
|
||||||
|
Sapling extended full viewing keys
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
A Sapling extended full viewing key (*ak*, *nk*, *ovk*, *dk*, *c*), at depth *depth*,
|
||||||
|
with parent full viewing key tag *parent_fvk_tag* and child number *i*, is
|
||||||
|
represented as a byte sequence:
|
||||||
|
|
||||||
|
I2LEOSP\ :sub:`8`\ (*depth*) || *parent_fvk_tag* || I2LEOSP\ :sub:`32`\ (*i*) || *c* || EncodeExtFVKParts(*ak*, *nk*, *ovk*, *dk*)
|
||||||
|
|
||||||
|
For the master extended full viewing key, *depth* is 0, *parent_fvk_tag* is 4 zero bytes,
|
||||||
|
and *i* is 0.
|
||||||
|
|
||||||
|
When encoded as Bech32, the Human-Readable Part is ``zxviews`` for the production
|
||||||
|
network, or ``zxviewtestsapling`` for the test network.
|
||||||
|
|
||||||
|
Sprout extended spending keys
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
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* || EncodeASK(*a*\ :sub:`sk`\ )
|
||||||
|
|
||||||
|
For the master extended spending key, *depth* is 0, *parent_addr_tag* is 4 zero bytes,
|
||||||
|
and *i* is 0.
|
||||||
|
|
||||||
|
When encoded as Bech32, the Human-Readable Part is ``zxsprout`` for the production
|
||||||
|
network, or ``zxtestsprout`` for the test network. Sprout extended spending keys
|
||||||
|
are encoded using Bech32 even though other Sprout keys and addresses are encoded
|
||||||
|
using Base58Check.
|
||||||
|
|
||||||
|
|
||||||
|
Test Vectors
|
||||||
|
============
|
||||||
|
|
||||||
|
TBC
|
||||||
|
|
||||||
|
|
||||||
|
Reference Implementation
|
||||||
|
========================
|
||||||
|
|
||||||
|
https://github.com/zcash/zcash/pull/XXXX
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. [#RFC2119] `Key words for use in RFCs to Indicate Requirement Levels <https://tools.ietf.org/html/rfc2119>`_
|
||||||
|
.. [#bip-0032] `BIP 32: Hierarchical Deterministic Wallets <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>`_
|
||||||
|
.. [#bip-0039] `BIP 39: Mnemonic code for generating deterministic keys <https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki>`_
|
||||||
|
.. [#bip-0043] `BIP 43: Purpose Field for Deterministic Wallets <https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki>`_
|
||||||
|
.. [#bip-0044] `BIP 44: Multi-Account Hierarchy for Deterministic Wallets <https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki>`_
|
||||||
|
.. [#slip-0044] `SLIP 44: Registered coin types for BIP-0044 <https://github.com/satoshilabs/slips/blob/master/slip-0044.md>`_
|
||||||
|
.. [#bip-0173] `BIP 173: Base32 address format for native v0-16 witness outputs <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>`_
|
||||||
|
.. [#sapling-spec] `Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling] <https://github.com/zcash/zips/blob/master/protocol/protocol.pdf>`_
|
||||||
|
.. [#sapling-key-components] `Section 4.2.2: Sapling Key Components. Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling] <https://github.com/zcash/zips/blob/master/protocol/protocol.pdf>`_
|
||||||
|
.. [#NIST-SP-800-38G] `NIST Special Publication 800-38G -- Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption <https://dx.doi.org/10.6028/NIST.SP.800-38G>`_
|
||||||
|
|
Loading…
Reference in New Issue