ZIP: 32 Title: Shielded Hierarchical Deterministic Wallets Owners: Jack Grigg <str4d@electriccoin.co> Daira-Emma Hopwood <daira-emma@electriccoin.co> Credits: Sean Bowe Kris Nuttycombe Ying Tong Lai Pieter Wuille Marek Palatinus Pavol Rusnak Status: Final Category: Standards / Wallet Created: 2018-05-22 License: MIT
\(% 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 .\)
The key words "MUST", "MUST NOT", "SHOULD", "RECOMMENDED", and "MAY" in this document are to be interpreted as described in BCP 14 1 when, and only when, they appear in all capitals.
"Jubjub" refers to the elliptic curve defined in 15.
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 10.
This proposal defines a mechanism for extending hierarchical deterministic wallets, as described in BIP 32 2, 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):
Previous versions of this document also defined a similar derivation system for the Sprout shielded pool. This has been removed since it was never used, and is unlikely to be used given that zcashd no longer generates Sprout addresses (and neither Zebra nor the mobile SDKs have ever done so).
The last part shows how to use these trees in the context of existing BIP 44 5 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).
BIP 32 2 is the standard mechanism by which wallets for Bitcoin and its derivatives (including Zcash's transparent addresses 6) generate keys and addresses deterministically. This has several advantages over random generation:
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.
Most of the notation and functions used in this ZIP are defined in the Zcash protocol specification 9. They are reproduced here for convenience:
The following algorithm standardized in 22 is used:
We also define the following conversion function:
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 2 to describe shielded HD paths, using prime marks ( \(\kern-0.1em{}'\!\) ) to indicate hardened derivation ( \(\!i' = i + 2^{31}\!\) ) as in BIP 44 5:
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 represent a Sapling extended spending key as \((\mathsf{ask, nsk, ovk, dk, c})\!\) , where \((\mathsf{ask, nsk, ovk})\) is the normal Sapling expanded spending key, \(\mathsf{dk}\) is a diversifier key, and \(\mathsf{c}\) is the chain code.
We represent a Sapling extended full viewing key as \((\mathsf{ak, nk, ovk, dk, c})\!\) , where \((\mathsf{ak, nk, ovk})\) is the normal Sapling full viewing key, \(\mathsf{dk}\) is the same diversifier key as above, and \(\mathsf{c}\) is the chain code.
Define
Let \(S\) be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
Note that the master extended key is invalid if \(\mathsf{ask}_m\) is \(0\!\) , or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is \(0\!\) .
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.
\(\mathsf{CKDsk}((\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{ask}_i, \mathsf{nsk}_i, \mathsf{ovk}_i, \mathsf{dk}_i, \mathsf{c}_i)\) :
Note that the child extended key is invalid if \(\mathsf{ask}_i\) is \(0\!\) , or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is \(0\!\) .
Let \(\mathcal{G}^\mathsf{Sapling}\) be as defined in 14 and let \(\mathcal{H}^\mathsf{Sapling}\) be as defined in 11.
\(\mathsf{CKDfvk}((\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{ak}_{i}, \mathsf{nk}_{i}, \mathsf{ovk}_{i}, \mathsf{dk}_{i}, \mathsf{c}_{i})\) :
Note that the child extended key is invalid if \(\mathsf{ak}_i\) is the zero point of Jubjub, or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is \(0\!\) .
The above derivation mechanisms produce external addresses suitable for giving out to senders. We also want to be able to produce another address derived from a given external address, for use by wallets for internal operations such as change and auto-shielding. Unlike BIP 44 that allows deriving a stream of external and internal addresses in the same hierarchical derivation tree 5, for any external full viewing key we only need to be able to derive a single internal full viewing key that has viewing authority for just internal transfers. We also need to be able to derive the corresponding internal spending key if we have the external spending key.
Let \((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk}, \mathsf{dk})\) be the external spending key.
Note that the child extended key is invalid if \(\mathsf{ak}\) is the zero point of Jubjub, or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is \(0\!\) .
Let \(\mathcal{H}^\mathsf{Sapling}\) be as defined in 11.
Let \((\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})\) be the external full viewing key.
This design uses the same technique as non-hardened derivation to obtain a full viewing key with the same spend authority (the private key corresponding to \(\mathsf{ak}\!\) ) as the original, but viewing authority only for internal transfers.
The values of \(I\!\) , \(I_\mathsf{nsk}\!\) , and \(R\) are the same between deriving a full viewing key, and deriving the corresponding spending key. Both of these derivations are shown in the following diagram:
(For simplicity, the proof authorizing key is not shown.)
This method of deriving internal keys is applied to external keys that are children of the Account level. It was implemented in zcashd as part of support for ZIP 316 8.
Note that the internal extended key is invalid if \(\mathsf{ak}\) is the zero point of Jubjub, or if the corresponding \(\mathsf{ivk_{internal}}\) derived from the internal full viewing key as specified in 11 is \(0\!\) .
The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key \(\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:
A valid diversifier \(d_j\) is one for which \(\mathsf{DiversifyHash^{Sapling}}(d_j) \neq \bot\!\) . For a given \(\mathsf{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_j\!\) , where \(j\) is the least nonnegative integer yielding a valid diversifier.
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 now have a general hardened-only derivation process that retains compatibility with existing derivation path semantics (to enable deriving the same path across multiple contexts).
Let \(\mathsf{Context}\) be the context in which the hardened-only key derivation process is instantiated (e.g. a shielded protocol). We define two context-specific constants:
Let \(\mathsf{IKM}\) be an input key material byte sequence, which MUST use an unambiguous encoding within the given context, and SHOULD contain at least 256 bits of entropy. It is RECOMMENDED to use a prefix-free encoding, which may require the use of length fields if multiple fields need to be encoded.
\(\mathsf{MKGh}^\mathsf{Context}(\mathsf{IKM}) \rightarrow (\mathsf{sk}_m, \mathsf{c}_m)\) :
\(\mathsf{CKDh}^\mathsf{Context}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)\) :
We only support hardened key derivation for Orchard. We instantiate the hardened key generation process with the following constants:
We represent an Orchard extended spending key as \((\mathsf{sk, c}),\) where \(\mathsf{sk}\) is the normal Orchard spending key (opaque 32 bytes), and \(\mathsf{c}\) is the chain code.
Let \(S\) be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
\(\mathsf{CKDsk}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{sk}_{i}, \mathsf{c}_i)\) :
Note that the resulting child spending key may produce an invalid external FVK, as specified in 12, with small probability. The corresponding internal FVK derived as specified in the next section may also be invalid with small probability.
As in the case of Sapling, for a given external address, we want to produce another address for use by wallets for internal operations such as change and auto-shielding. That is, for any external full viewing key we need to be able to derive a single internal full viewing key that has viewing authority for just internal transfers. We also need to be able to derive the corresponding internal spending key if we have the external spending key.
Let \(\mathsf{ask}\) be the spend authorizing key if available, and let \((\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})\) be the corresponding external full viewing key, obtained as specified in 12.
Define \(\mathsf{DeriveInternalFVK^{Orchard}}(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})\) as follows:
The result of applying \(\mathsf{DeriveInternalFVK^{Orchard}}\) to the external full viewing key is the internal full viewing key. The corresponding expanded internal spending key is \((\mathsf{ask}, \mathsf{nk}, \mathsf{rivk_{internal}})\!\) .
Unlike Sapling internal key derivation, we do not base this internal key derivation procedure on non-hardened derivation, which is not defined for Orchard. We can obtain the desired separation of viewing authority by modifying only the \(\mathsf{rivk_{internal}}\) field relative to the external full viewing key, which results in different \(\mathsf{dk_{internal}}\!\) , \(\mathsf{ivk_{internal}}\) and \(\mathsf{ovk_{internal}}\) fields being derived, as specified in 12 and shown in the following diagram:
This method of deriving internal keys is applied to external keys that are children of the Account level. It was implemented in zcashd as part of support for ZIP 316 8.
Note that the resulting FVK may be invalid, as specified in 12.
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 \((\mathsf{sk}_i, \mathsf{c}_i)\!\) :
Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values of \(j\) yield valid diversifiers.
The default diversifier for \((\mathsf{sk}_i, \mathsf{c}_i)\) is defined to be \(d_{i,0}.\)
In some contexts there is a need for deriving arbitrary keys with the same derivation path as existing key material (for example, deriving an arbitrary account-level key), without the need for ecosystem-wide coordination. The following instantiation of the hardened key generation process may be used for this purpose.
Let \(\mathsf{ContextString}\) be a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context.
We instantiate the hardened key generation process with the following constants:
Let \(S\) be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
The master extended arbitrary key is:
\(m_\mathsf{Arbitrary} = \mathsf{MKGh}^\mathsf{Arbitrary}([\mathsf{length}(\mathsf{ContextString})]\,||\,\mathsf{ContextString}\,||\,[\mathsf{length}(S)]\,||\,S)\!\) .
\(\mathsf{CKDarb}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)\) :
If the context requires a 64-byte key (for example, to avoid an entropy bottleneck in its particular subsequent operations), and \(i\) is the last element of an HD path, the concatenation \(\mathsf{sk}_i\,||\,\mathsf{c}_i\) MAY be used as a key. In this case, \((\mathsf{sk}_i, \mathsf{c}_i)\) MUST NOT be given as input to \(\mathsf{CKDarb}\) (this is a restatement of the requirement that \(i\) is the last element of an HD path).
Existing Zcash-supporting HD wallets all use BIP 44 5 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.
Sapling and Orchard key paths have the following three path levels at the top, all of which use hardened derivation:
Unlike BIP 44, none of the shielded key paths 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 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^{31} - 1 \}\!\) :
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^{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 5:
zcashd version 4.6.0 and later uses this to derive "legacy" Sapling addresses from a mnemonic seed phrase under account \(\mathtt{0x7FFFFFFF}\!\) , using hardened derivation for \(address\_index\!\) .
Orchard supports diversified addresses with the same spending authority (like Sapling). 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 Orchard ZIP 32 derivation MUST support the following path for any account in range \(\{ 0\,..\, 2^{31} - 1 \}\!\) :
Furthermore, wallets MUST support generating the default payment address (corresponding to the default diversifier for Orchard) for any account they support. They MAY also support generating a stream of diversified payment addresses for a given account, if they wish to enable users to give a unique address to each recipient.
Note that a given account can have a maximum of \(2^{88}\) payment addresses (unlike Sapling, all Orchard diversifiers are valid).
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 7 encoding.
A Sapling extended spending key \((\mathsf{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:
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.
A Sapling extended full viewing key \((\mathsf{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:
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.
An Orchard extended spending key \((\mathsf{sk, c})\!\) , at depth \(depth\!\) , with parent full viewing key tag \(parent\_fvk\_tag\) and child number \(i\!\) , is represented as a byte sequence:
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-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 21.
The following values were previously used in the specification of hierarchical derivation for Sprout, and therefore SHOULD NOT be used in future Zcash-related specifications:
zxsprout
and zxtestsprout
, formerly specified for Sprout extended spending keys on Mainnet and Testnet respectively.TBC
1 | Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" |
---|
2 | BIP 32: Hierarchical Deterministic Wallets |
---|
3 | BIP 39: Mnemonic code for generating deterministic keys |
---|
4 | BIP 43: Purpose Field for Deterministic Wallets |
---|
5 | BIP 44: Multi-Account Hierarchy for Deterministic Wallets |
---|
6 | SLIP 44: Registered coin types for BIP-0044 |
---|
7 | BIP 173: Base32 address format for native v0-16 witness outputs |
---|
8 | ZIP 316: Unified Addresses and Unified Viewing Keys |
---|
9 | Zcash Protocol Specification, Version 2022.2.19 or later [NU5 proposal] |
---|
10 | Zcash Protocol Specification, Version 2022.2.19. Section 3.12: Mainnet and Testnet |
---|
11 | Zcash Protocol Specification, Version 2022.2.19. Section 4.2.2: Sapling Key Components |
---|
12 | Zcash Protocol Specification, Version 2022.2.19. Section 4.2.3: Orchard Key Components |
---|
13 | Zcash Protocol Specification, Version 2022.2.19. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions |
---|
14 | Zcash Protocol Specification, Version 2022.2.19. Section 5.4.6.1: Spend Authorization Signature |
---|
15 | Zcash Protocol Specification, Version 2022.2.19. Section 5.4.9.3: Jubjub |
---|
16 | Zcash Protocol Specification, Version 2022.2.19. Section 5.6.2.1: Sprout Payment Addresses |
---|
17 | Zcash Protocol Specification, Version 2022.2.19. Section 5.6.2.3: Sprout Spending Keys |
---|
18 | Zcash Protocol Specification, Version 2022.2.19. Section 5.6.3.3: Sapling Full Viewing Keys |
---|
19 | Zcash Protocol Specification, Version 2022.2.19. Section 5.6.3.4: Sapling Spending Keys |
---|
20 | Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.4: Orchard Raw Full Viewing Keys |
---|
21 | Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.5: Orchard Spending Keys |
---|
22 | NIST Special Publication 800-38G — Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption |
---|