mirror of https://github.com/zcash/zips.git
487 lines
23 KiB
ReStructuredText
487 lines
23 KiB
ReStructuredText
::
|
||
|
||
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-hackworks/zip32
|
||
* https://github.com/zcash/librustzcash/pull/29
|
||
* https://github.com/zcash/zcash/pull/3447
|
||
* https://github.com/zcash/zcash/pull/3492
|
||
|
||
|
||
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>`_
|
||
|