mirror of https://github.com/zcash/zips.git
667 lines
36 KiB
ReStructuredText
667 lines
36 KiB
ReStructuredText
::
|
|
|
|
ZIP: 32
|
|
Title: Shielded Hierarchical Deterministic Wallets
|
|
Owners: Jack Grigg <str4d@electriccoin.co>
|
|
Daira Hopwood <daira@electriccoin.co>
|
|
Credits: Pieter Wuille
|
|
Marek Palatinus
|
|
Pavol Rusnak
|
|
Status: Final
|
|
Category: Standards / Wallet
|
|
Created: 2018-05-22
|
|
License: MIT
|
|
|
|
:math:`% This ZIP makes heavy use of mathematical markup. If you can see this, you may want to instead view the rendered version at https://zips.z.cash/zip-0032 .`
|
|
|
|
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 [#protocol-jubjub]_.
|
|
|
|
A "chain code" is a cryptovalue that is needed, in addition to a spending key, in order to derive
|
|
descendant keys and addresses of that key.
|
|
|
|
The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash
|
|
Protocol Specification [#protocol-networks]_.
|
|
|
|
|
|
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 initial parts of the specification define (mostly) equivalent, but independent, systems for deriving a
|
|
tree of key components from a single seed, for the following shielded pools (which have different internal
|
|
key structures):
|
|
|
|
- Sapling
|
|
- Sprout (for compatibility, effectively unused)
|
|
- Orchard
|
|
|
|
The last 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.
|
|
- Viewing authority or spending 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 Zcash protocol specification
|
|
[#protocol]_. They are reproduced here for convenience:
|
|
|
|
- :math:`\mathsf{truncate}_k(S)` means the sequence formed from the first :math:`k` elements of :math:`S`.
|
|
|
|
- :math:`a\,||\,b` means the concatenation of sequences :math:`a` then :math:`b`.
|
|
|
|
- :math:`[k] P` means scalar multiplication of the elliptic curve point :math:`P` by the scalar :math:`k`.
|
|
|
|
- :math:`\mathsf{LEOS2IP}_\ell(S)` is the integer in range :math:`\{ 0\,.\!. 2^\ell - 1 \}` represented in
|
|
little-endian order by the byte sequence :math:`S` of length :math:`\ell/8`.
|
|
|
|
- :math:`\mathsf{I2LEBSP}_\ell(k)` is the sequence of :math:`\ell` bits representing :math:`k` in
|
|
little-endian order.
|
|
|
|
- :math:`\mathsf{LEBS2OSP}_\ell(B)` is defined as follows when :math:`\ell` is a multiple of :math:`8`:
|
|
convert each group of 8 bits in :math:`B` to a byte value with the least significant bit first, and
|
|
concatenate the resulting bytes in the same order as the groups.
|
|
|
|
- :math:`\mathsf{repr}_\mathbb{J}(P)` is the representation of the Jubjub elliptic curve point :math:`P`
|
|
as a bit sequence, defined in [#protocol-jubjub]_.
|
|
|
|
- :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)` refers to unkeyed BLAKE2b-256 in sequential mode,
|
|
with an output digest length of 32 bytes, 16-byte personalization string :math:`p`, and input :math:`x`.
|
|
|
|
- :math:`\mathsf{BLAKE2b}\text{-}\mathsf{512}(p, x)` refers to unkeyed BLAKE2b-512 in sequential mode,
|
|
with an output digest length of 64 bytes, 16-byte personalization string :math:`p`, and input :math:`x`.
|
|
|
|
- :math:`\mathsf{PRF^{expand}}(\mathsf{sk}, t) :=`:math:`\mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“Zcash_ExpandSeed”},`:math:`\mathsf{sk}\,||\,t)`
|
|
|
|
- :math:`r_\mathbb{J}` is the order of the Jubjub large prime subgroup.
|
|
|
|
- :math:`\mathsf{ToScalar}(x) :=`:math:`\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{J}}`.
|
|
|
|
- :math:`\mathsf{DiversifyHash}(d)` maps a diversifier :math:`d` to a base point on the Jubjub elliptic
|
|
curve, or to :math:`\bot` if the diversifier is invalid. It is instantiated in [#protocol-concretediversifyhash]_.
|
|
|
|
The following algorithm standardized in [#NIST-SP-800-38G]_ is used:
|
|
|
|
- :math:`\mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(key, tweak, x)` refers to the FF1 encryption algorithm
|
|
using AES with a 256-bit :math:`key`, and parameters :math:`radix = 2,`:math:`minlen = 88,`:math:`maxlen = 88`.
|
|
It will be used only with the empty string :math:`\texttt{“”}` as the :math:`tweak`. :math:`x` is a
|
|
sequence of 88 bits, as is the output.
|
|
|
|
We also define the following conversion function:
|
|
|
|
- :math:`\mathsf{I2LEOSP}_\ell(k)` is the byte sequence :math:`S` of length :math:`\ell/8` representing in
|
|
little-endian order the integer :math:`k` in range :math:`\{ 0\,.\!. 2^\ell - 1 \}`. It is the reverse
|
|
operation of :math:`\mathsf{LEOS2IP}_\ell(S)`.
|
|
|
|
Implementors should note that this ZIP is consistently little-endian (in keeping with the Sapling and Orchard
|
|
specifications), which is the opposite of BIP 32.
|
|
|
|
We adapt the path notation of BIP 32 [#bip-0032]_ to describe shielded HD paths, using prime marks (:math:`'`) to
|
|
indicate hardened derivation (:math:`i' = i + 2^{31}`) as in BIP 44 [#bip-0044]_:
|
|
|
|
- :math:`\mathsf{CDKsk}(\mathsf{CDKsk}(\mathsf{CDKsk}(m_\mathsf{Sprout}, a'), b), c)` is written as :math:`m_\mathsf{Sprout} / a' / b / c`
|
|
- :math:`\mathsf{CDKfvk}(\mathsf{CDKfvk}(\mathsf{CDKfvk}(m_\mathsf{Sapling}, a), b), c)` is written as :math:`m_\mathsf{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 :math:`(\mathsf{ask, nsk, ovk, dk, c})`, where
|
|
:math:`(\mathsf{ask, nsk, ovk})` is the normal Sapling expanded spending key, :math:`\mathsf{dk}` is a
|
|
diversifier key, and :math:`\mathsf{c}` is the chain code.
|
|
|
|
We represent a Sapling extended full viewing key as :math:`(\mathsf{ak, nk, ovk, dk, c})`, where
|
|
:math:`(\mathsf{ak, nk, ovk})` is the normal Sapling full viewing key, :math:`\mathsf{dk}` is the same
|
|
diversifier key as above, and :math:`\mathsf{c}` is the chain code.
|
|
|
|
Sapling helper functions
|
|
------------------------
|
|
|
|
Define
|
|
|
|
* :math:`\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk}) :=`:math:`\mathsf{I2LEOSP}_{256}(\mathsf{ask})`:math:`||\,\mathsf{I2LEOSP}_{256}(\mathsf{nsk})`:math:`||\,\mathsf{ovk}`:math:`||\,\mathsf{dk}`
|
|
* :math:`\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk}) :=`:math:`\mathsf{LEBS2OS}_{256}(\mathsf{repr}_\mathbb{J}(\mathsf{ak}))`:math:`||\,\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_\mathbb{J}(\mathsf{nk}))`:math:`||\,\mathsf{ovk}`:math:`||\,\mathsf{dk}`
|
|
|
|
Sapling master key generation
|
|
-----------------------------
|
|
|
|
Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
|
|
|
|
- Calculate :math:`I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32Sapling”}, S)`.
|
|
- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`.
|
|
- Use :math:`I_L` as the master spending key :math:`\mathsf{sk}_m`, and :math:`I_R` as the master chain code
|
|
:math:`\mathsf{c}_m`.
|
|
- Calculate :math:`\mathsf{ask}_m`, :math:`\mathsf{nsk}_m`, and :math:`\mathsf{ovk}_m` via the standard
|
|
Sapling derivation [#protocol-saplingkeycomponents]_:
|
|
|
|
- :math:`\mathsf{ask}_m = \mathsf{ToScalar}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x00}]))`
|
|
- :math:`\mathsf{nsk}_m = \mathsf{ToScalar}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x01}]))`
|
|
- :math:`\mathsf{ovk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x02}]))`.
|
|
|
|
- Calculate :math:`\mathsf{dk}_m` similarly:
|
|
|
|
- :math:`\mathsf{dk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x10}]))`.
|
|
|
|
- Return :math:`(\mathsf{ask}_m, \mathsf{nsk}_m, \mathsf{ovk}_m, \mathsf{dk}_m, \mathsf{c}_m)` as the
|
|
master extended spending key :math:`m_\mathsf{Sapling}`.
|
|
|
|
Sapling child key derivation
|
|
----------------------------
|
|
|
|
As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index :math:`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
|
|
``````````````````````````````````````
|
|
|
|
:math:`\mathsf{CDKsk}((\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{ask}_i, \mathsf{nsk}_i, \mathsf{ovk}_i, \mathsf{dk}_i, \mathsf{c}_i)`
|
|
|
|
- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key).
|
|
|
|
- If so (hardened child):
|
|
let :math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x11}]`:math:`||\,\mathsf{EncodeExtSKParts}(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})`:math:`||\,\mathsf{I2LEOSP}_{32}(i))`.
|
|
- If not (normal child):
|
|
let :math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x12}]`:math:`||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})`:math:`||\,\mathsf{I2LEOSP}_{32}(i))`
|
|
where :math:`(\mathsf{nk}_{par}, \mathsf{ak}_{par}, \mathsf{ovk}_{par})` is the full viewing key derived from
|
|
:math:`(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par})` as described in [#protocol-saplingkeycomponents]_.
|
|
|
|
- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`.
|
|
- Let :math:`I_\mathsf{ask} = \mathsf{ToScalar}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))`.
|
|
- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))`.
|
|
- Return:
|
|
|
|
- :math:`\mathsf{ask}_i = (I_\mathsf{ask} + \mathsf{ask}_{par}) \pmod{r_\mathbb{J}}`
|
|
- :math:`\mathsf{nsk}_i = (I_\mathsf{nsk} + \mathsf{nsk}_{par}) \pmod{r_\mathbb{J}}`
|
|
- :math:`\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x15}]`:math:`||\,\mathsf{ovk}_{par}))`
|
|
- :math:`\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]`:math:`||\,\mathsf{dk}_{par}))`
|
|
- :math:`\mathsf{c}_i = I_R`.
|
|
|
|
Deriving a child extended full viewing key
|
|
``````````````````````````````````````````
|
|
|
|
Let :math:`\mathcal{G}` be as defined in [#protocol-concretespendauthsig]_ and let :math:`\mathcal{H}` be as defined
|
|
in [#protocol-saplingkeycomponents]_.
|
|
|
|
:math:`\mathsf{CDKfvk}((\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{ak}_{i}, \mathsf{nk}_{i}, \mathsf{ovk}_{i}, \mathsf{dk}_{i}, \mathsf{c}_{i})`
|
|
|
|
- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key).
|
|
|
|
- If so (hardened child): return failure.
|
|
- If not (normal child): let
|
|
:math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x12}]`:math:`||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})`:math:`||\,\mathsf{I2LEOSP}_{32}(i))`.
|
|
|
|
- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`.
|
|
- Let :math:`I_\mathsf{ask} = \mathsf{ToScalar}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))`.
|
|
- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))`.
|
|
- Return:
|
|
|
|
- :math:`\mathsf{ak}_i = [I_\mathsf{ask}]\,\mathcal{G} + \mathsf{ak}_{par}`
|
|
- :math:`\mathsf{nk}_i = [I_\mathsf{nsk}]\,\mathcal{H} + \mathsf{nk}_{par}`
|
|
- :math:`\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x15}]`:math:`||\,\mathsf{ovk}_{par}))`
|
|
- :math:`\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]`:math:`||\,\mathsf{dk}_{par}))`
|
|
- :math:`\mathsf{c}_i = I_R`.
|
|
|
|
Sapling diversifier derivation
|
|
------------------------------
|
|
|
|
The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key :math:`\mathsf{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 :math:`j` be the index of the desired diversifier, in the range :math:`0\,.\!. 2^{88} - 1`.
|
|
- :math:`d_j = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))`.
|
|
|
|
A valid diversifier :math:`d_j` is one for which :math:`\mathsf{DiversifyHash}(d_j) \neq \bot`.
|
|
For a given :math:`\mathsf{dk}`, approximately half of the possible values of :math:`j` yield valid
|
|
diversifiers.
|
|
|
|
The default diversifier for a Sapling extended key is defined to be :math:`d_j`, where :math:`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 :math:`(\mathsf{a_{sk}, c})`, where :math:`\mathsf{a_{sk}}`
|
|
is the normal Sprout spending key, and :math:`\mathsf{c}` is the chain code.
|
|
|
|
Sprout helper functions
|
|
-----------------------
|
|
|
|
Let :math:`\mathsf{EncodeASK}(\mathsf{a_{sk}})` be the 32-byte encoding of :math:`\mathsf{a_{sk}}` in the
|
|
raw encoding of a Sprout spending key (excluding lead bytes) as specified in [#protocol-sproutspendingkeyencoding]_.
|
|
|
|
Let :math:`\mathsf{DecodeASK}(ASK)` be the result of clearing the 4 most significant bits of the first byte
|
|
of :math:`ASK`, and decoding the 32-byte result according to the inverse of :math:`\mathsf{EncodeASK}`.
|
|
|
|
Sprout master key generation
|
|
----------------------------
|
|
|
|
Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
|
|
|
|
- Calculate :math:`I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32_Sprout”}, S)`.
|
|
- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`.
|
|
- Use :math:`\mathsf{DecodeASK}(I_L)` as the master spending key :math:`\mathsf{a}_{\mathsf{sk},m}`.
|
|
- Use :math:`I_R` as the master chain code :math:`\mathsf{c}_m`.
|
|
|
|
Sprout child key derivation
|
|
---------------------------
|
|
|
|
:math:`\mathsf{CDKsk}((\mathsf{a}_{\mathsf{sk},par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{a}_{\mathsf{sk},i}, \mathsf{c}_i)`
|
|
|
|
- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key).
|
|
|
|
- If so (hardened child): let
|
|
:math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x80}]`:math:`||\,\mathsf{EncodeASK}(\mathsf{a}_{\mathsf{sk},par})`:math:`||\,\mathsf{I2LEOSP}_{32}(i))`.
|
|
- If not (normal child): return failure.
|
|
|
|
- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`.
|
|
- Use :math:`\mathsf{DecodeASK}(I_L)` as the child spending key :math:`\mathsf{a}_{\mathsf{sk},i}`.
|
|
- Use :math:`I_R` as the child chain code :math:`\mathsf{c}_i`.
|
|
|
|
|
|
Specification: Orchard key derivation
|
|
=====================================
|
|
|
|
The derivation mechanism for Sapling addresses specified above incurs significant complexity to support
|
|
non-hardened derivation. In the several years since Sapling was deployed, we have seen no use cases for
|
|
non-hardened derivation appear. With that in mind, we define Orchard key derivation very similarly to
|
|
Sprout above: only hardened derivation is supported.
|
|
|
|
Orchard extended keys
|
|
---------------------
|
|
|
|
We represent an Orchard extended spending key as :math:`(\mathsf{sk, c}),` where :math:`\mathsf{sk}`
|
|
is the normal Orchard spending key (opaque 32 bytes), and :math:`\mathsf{c}` is the chain code.
|
|
|
|
Orchard master key generation
|
|
-----------------------------
|
|
|
|
Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
|
|
|
|
- Calculate :math:`I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32Orchard”}, S)`.
|
|
- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`.
|
|
- Use :math:`I_L` as the master spending key :math:`\mathsf{sk}_m`.
|
|
- Use :math:`I_R` as the master chain code :math:`\mathsf{c}_m`.
|
|
- Return :math:`(\mathsf{sk}_m, \mathsf{c}_m)` as the master extended spending key
|
|
:math:`m_\mathsf{Orchard}`.
|
|
|
|
Orchard child key derivation
|
|
----------------------------
|
|
|
|
:math:`\mathsf{CDKsk}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{sk}_{i}, \mathsf{c}_i)`
|
|
|
|
- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key).
|
|
|
|
- If so (hardened child): let
|
|
:math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x81}]\,||\,\mathsf{sk}_{par}\,||\,\mathsf{I2LEOSP}_{32}(i))`.
|
|
- If not (normal child): return failure.
|
|
|
|
- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`.
|
|
- Use :math:`I_L` as the child spending key :math:`\mathsf{sk}_{i}`.
|
|
- Use :math:`I_R` as the child chain code :math:`\mathsf{c}_i`.
|
|
|
|
Orchard diversifier derivation
|
|
------------------------------
|
|
|
|
As with Sapling, we define a mechanism for deterministically deriving a sequence of diversifiers, without
|
|
leaking how many diversified addresses have already been generated for an account. Unlike Sapling, we do so
|
|
by deriving a diversifier key directly from the full viewing key, instead of as part of the extended spending
|
|
key. This means that the full viewing key provides the capability to determine the position of a diversifier
|
|
within the sequence, which matches the capabilities of a Sapling extended full viewing key but simplifies the
|
|
key structure.
|
|
|
|
Given an Orchard extended spending key :math:`(\mathsf{sk}_i, \mathsf{c}_i)`:
|
|
|
|
- Let :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})` be the Orchard full viewing key for :math:`\mathsf{sk}_i`.
|
|
- Let :math:`\mathsf{K} = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})` and let :math:`\mathsf{B} = \mathsf{repr}_{\mathbb{P}}(\mathsf{ak})\,||\,\mathsf{I2LEBSP}_{256}(\mathsf{nk})`.
|
|
- :math:`\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{K}, [\texttt{0x82}]\,||\,\mathsf{LEBS2OSP}_{512}(\mathsf{B})))`.
|
|
- Let :math:`j` be the index of the desired diversifier, in the range :math:`0\,.\!. 2^{88} - 1`.
|
|
- :math:`d_{i,j} = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}_i, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))`.
|
|
|
|
Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values of :math:`j` yield
|
|
valid diversifiers.
|
|
|
|
The default diversifier for :math:`(\mathsf{sk}_i, \mathsf{c}_i)` is defined to be :math:`d_{i,0}.`
|
|
|
|
Although the diversifier *key* is derived from the full viewing key which is at the Account level, the
|
|
resulting diversified addresses are derived from the key at the non-change child of that level, as described
|
|
in `Orchard key path`_ below.
|
|
|
|
|
|
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
|
|
---------------
|
|
|
|
Sprout, Sapling, and Orchard key paths have the following three path levels at the top, all of which use
|
|
hardened derivation:
|
|
|
|
- :math:`purpose`: a constant set to :math:`32'` (or :math:`\texttt{0x80000020}`) following the BIP 43
|
|
recommendation. It indicates that the subtree of this node is used according to this specification.
|
|
|
|
- :math:`coin\_type`: a constant identifying the cryptocurrency 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 cryptocurrency testnets share :math:`coin\_type`
|
|
index :math:`1`.
|
|
|
|
- :math:`account`: numbered from index :math:`0` in sequentially increasing manner. Defined as in
|
|
BIP 44 [#bip-0044]_.
|
|
|
|
In BIP 44, there is also a :math:`change` unhardened path level as a child of :math:`account`. This
|
|
level is not present in the Sprout and Sapling key paths. It *is* present in Orchard, but as a hardened
|
|
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. For Sprout and Sapling, it
|
|
was reasoned that shielded addresses are never publicly visible in transactions, and so sending change
|
|
back to the originating address would be indistinguishable from using a change address. However, this
|
|
reasoning does not apply if we give out incoming viewing keys, and so for Orchard the :math:`change`
|
|
level has been reintroduced. This ensures that an Orchard incoming viewing key will only be able to view
|
|
incoming payments, not incoming change, which was deemed to be more useful for anticipated applications
|
|
of incoming viewing keys (such as a merchant terminal or a charity donation 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 :math:`\{ 0\,.\!. 2^{31} - 1 \}`:
|
|
|
|
* :math:`m_\mathsf{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 :math:`2^{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 :math:`address\_index` path level as in [#bip-0044]_:
|
|
|
|
* :math:`m_\mathsf{Sapling} / purpose' / coin\_type' / account' / address\_index`.
|
|
|
|
`zcashd` version 4.5.2 and later uses this to derive "legacy" Sapling addresses from a mnemonic seed phrase
|
|
under account :math:`\mathtt{0x7FFFFFFE}`.
|
|
|
|
Sprout key path
|
|
---------------
|
|
|
|
Wallets implementing Sprout ZIP 32 derivation MUST support the following path:
|
|
|
|
* :math:`m_\mathsf{Sprout} / purpose' / coin\_type' / account' / address\_index`.
|
|
|
|
Orchard key path
|
|
----------------
|
|
|
|
Orchard supports diversified addresses with the same spending authority (like Sapling). Unlike Sapling and
|
|
Sprout, we reintroduce the :math:`change'` level of the key path, so that the spending authorities generated
|
|
for incoming payments and for change are distinct. The motivation for this distinction is to allow giving
|
|
out an incoming viewing key that is only able to see incoming payments, and not incoming change.
|
|
|
|
A group of diversified addresses with the same spending authority 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 key path levels include an account identifier, which in all user interfaces should be represented as
|
|
a "bucket of funds" under the control of a single spending authority. Wallets implementing Orchard ZIP 32
|
|
derivation MUST support the following two paths for any account in range :math:`\{ 0\,.\!. 2^{31} - 1 \}`:
|
|
|
|
* :math:`m_\mathsf{Orchard} / purpose' / coin\_type' / account' / 0'` (for incoming payments);
|
|
* :math:`m_\mathsf{Orchard} / purpose' / coin\_type' / account' / 1'` (for change).
|
|
|
|
Furthermore, wallets MUST support generating a default payment address and a default change address (each
|
|
corresponding to the default diversifier for Orchard) for any account they support. They MAY also support
|
|
generating a stream of diversified payment addresses (based on the non-change key path) for a given account,
|
|
if they wish to enable users to give a unique address to each recipient. A single address using the default
|
|
diversifier SHOULD be used for change.
|
|
|
|
Note that a given account can have a maximum of :math:`2^{88}` payment addresses (unlike Sapling, all Orchard
|
|
diversifiers are valid).
|
|
|
|
|
|
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 :math:`\mathit{FVK}` (as specified
|
|
in [#protocol-saplingfullviewingkeyencoding]_) is given by:
|
|
|
|
* :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashSaplingFVFP”}, \mathit{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 :math:`\mathit{ADDR}` (as specified in
|
|
[#protocol-sproutpaymentaddrencoding]_, including the lead bytes) is given by:
|
|
|
|
* :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“Zcash_Sprout_AFP”}, \mathit{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.
|
|
|
|
Orchard Full Viewing Key Fingerprints and Tags
|
|
----------------------------------------------
|
|
|
|
An "Orchard full viewing key fingerprint" of a full viewing key with raw encoding :math:`\mathit{FVK}` (as
|
|
specified in [#protocol-orchardfullviewingkeyencoding]_) is given by:
|
|
|
|
* :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashOrchardFVFP”}, \mathit{FVK})`.
|
|
|
|
It MAY be used to uniquely identify a particular Orchard full viewing key.
|
|
|
|
An "Orchard full viewing key tag" is the first 4 bytes of the corresponding Orchard full viewing key
|
|
fingerprint. It is intended for optimizing performance of key lookups, and MUST NOT be assumed to
|
|
uniquely identify a particular key.
|
|
|
|
Seed Fingerprints
|
|
-----------------
|
|
|
|
A "seed fingerprint" for the master seed :math:`S` of a hierarchical deterministic wallet is given by:
|
|
|
|
* :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“Zcash_HD_Seed_FP”},`:math:`[\mathsf{length}(S)]\,||\,S)`.
|
|
|
|
It MAY be used to uniquely identify a particular hierarchical deterministic wallet.
|
|
|
|
No corresponding short tag is defined.
|
|
|
|
Note: a previous version of this specification did not have the length byte prefixing the seed.
|
|
The current specification reflects the implementation in `zcashd`.
|
|
|
|
|
|
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 :math:`(\mathsf{ask, nsk, ovk, dk, c})`, at depth :math:`depth`,
|
|
with parent full viewing key tag :math:`parent\_fvk\_tag` and child number :math:`i`, is
|
|
represented as a byte sequence:
|
|
|
|
* :math:`\mathsf{I2LEOSP}_{8}(depth)`:math:`||\,parent\_fvk\_tag`:math:`||\,\mathsf{I2LEOSP}_{32}(i)`:math:`||\,\mathsf{c}`:math:`||\,\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk})`.
|
|
|
|
For the master extended spending key, :math:`depth` is :math:`0`, :math:`parent\_fvk\_tag` is
|
|
4 zero bytes, and :math:`i` is :math:`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 :math:`(\mathsf{ak, nk, ovk, dk, c})`, at depth :math:`depth`,
|
|
with parent full viewing key tag :math:`parent\_fvk\_tag` and child number :math:`i`, is
|
|
represented as a byte sequence:
|
|
|
|
* :math:`\mathsf{I2LEOSP}_{8}(depth)`:math:`||\,parent\_fvk\_tag`:math:`||\,\mathsf{I2LEOSP}_{32}(i)`:math:`||\,\mathsf{c}`:math:`||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk})`.
|
|
|
|
For the master extended full viewing key, :math:`depth` is :math:`0`, :math:`parent\_fvk\_tag`
|
|
is 4 zero bytes, and :math:`i` is :math:`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 :math:`(\mathsf{a_{sk}, c})`, at depth :math:`depth`, with
|
|
parent address tag :math:`parent\_addr\_tag` and child number :math:`i`, is represented as a
|
|
byte sequence:
|
|
|
|
* :math:`\mathsf{I2LEOSP}_{8}(depth)`:math:`||\,parent\_addr\_tag`:math:`||\,\mathsf{I2LEOSP}_{32}(i)`:math:`||\,\mathsf{c}`:math:`||\,\mathsf{EncodeASK}(\mathsf{a_{sk}})`.
|
|
|
|
For the master extended spending key, :math:`depth` is :math:`0`, :math:`parent\_addr\_tag`
|
|
is 4 zero bytes, and :math:`i` is :math:`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.
|
|
|
|
Orchard extended spending keys
|
|
------------------------------
|
|
|
|
An Orchard extended spending key :math:`(\mathsf{sk, c})`, at depth :math:`depth`, with parent full viewing
|
|
key tag :math:`parent\_fvk\_tag` and child number :math:`i`, is represented as a byte sequence:
|
|
|
|
* :math:`\mathsf{I2LEOSP}_{8}(depth)\,||\,parent\_fvk\_tag\,||\,\mathsf{I2LEOSP}_{32}(i)\,||\,\mathsf{c}\,||\,\mathsf{sk}`.
|
|
|
|
For the master extended spending key, :math:`depth` is :math:`0`, :math:`parent\_fvk\_tag` is
|
|
4 zero bytes, and :math:`i` is :math:`0`.
|
|
|
|
When encoded as Bech32, the Human-Readable Part is ``secret-orchard-extsk-main``
|
|
for Mainnet, or ``secret-orchard-extsk-test`` for Testnet.
|
|
|
|
We define this encoding for completeness, however given that it includes the capability to derive child
|
|
spending keys, we expect that most wallets will only expose the regular Orchard spending key encoding to
|
|
users [#protocol-orchardspendingkeyencoding]_.
|
|
|
|
|
|
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] `RFC 2119: Key words for use in RFCs to Indicate Requirement Levels <https://www.rfc-editor.org/rfc/rfc2119.html>`_
|
|
.. [#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>`_
|
|
.. [#protocol] `Zcash Protocol Specification, Version 2021.2.16 or later [NU5 proposal] <protocol/protocol.pdf>`_
|
|
.. [#protocol-networks] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.12: Mainnet and Testnet <protocol/protocol.pdf#networks>`_
|
|
.. [#protocol-saplingkeycomponents] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.2.2: Sapling Key Components <protocol/protocol.pdf#saplingkeycomponents>`_
|
|
.. [#protocol-concretediversifyhash] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions <protocol/protocol.pdf#concretediversifyhash>`_
|
|
.. [#protocol-concretespendauthsig] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.6.1: Spend Authorization Signature <protocol/protocol.pdf#concretespendauthsig>`_
|
|
.. [#protocol-jubjub] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.9.3: Jubjub <protocol/protocol.pdf#jubjub>`_
|
|
.. [#protocol-sproutpaymentaddrencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.2.1: Sprout Payment Addresses <protocol/protocol.pdf#sproutpaymentaddrencoding>`_
|
|
.. [#protocol-sproutspendingkeyencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.2.3: Sprout Spending Keys <protocol/protocol.pdf#sproutspendingkeyencoding>`_
|
|
.. [#protocol-saplingfullviewingkeyencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.3.3: Sapling Full Viewing Keys <protocol/protocol.pdf#saplingfullviewingkeyencoding>`_
|
|
.. [#protocol-saplingspendingkeyencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.3.4: Sapling Spending Keys <protocol/protocol.pdf#saplingspendingkeyencoding>`_
|
|
.. [#protocol-orchardfullviewingkeyencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.4.4: Orchard Raw Full Viewing Keys <protocol/protocol.pdf#orchardfullviewingkeyencoding>`_
|
|
.. [#protocol-orchardspendingkeyencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.4.5: Orchard Spending Keys <protocol/protocol.pdf#orchardspendingkeyencoding>`_
|
|
.. [#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>`_
|