ZIP 32: add internal key derivation for Sapling and Orchard.
Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
98515d003f
commit
79e6a10f0a
Binary file not shown.
After Width: | Height: | Size: 227 KiB |
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 91 KiB |
Binary file not shown.
After Width: | Height: | Size: 228 KiB |
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 89 KiB |
107
zip-0032.rst
107
zip-0032.rst
|
@ -253,6 +253,64 @@ let :math:`\mathcal{H}^\mathsf{Sapling}` be as defined in [#protocol-saplingkeyc
|
|||
- :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 internal key derivation
|
||||
-------------------------------
|
||||
|
||||
The above derivation mechanisms produce external addresses suitable for giving out to senders.
|
||||
For each such external address, we also want to produce another 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 [#bip-0044]_,
|
||||
for each 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.
|
||||
|
||||
Deriving a Sapling internal spending key
|
||||
````````````````````````````````````````
|
||||
|
||||
Let :math:`(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk}, \mathsf{dk})` be the external spending key.
|
||||
|
||||
- Derive the corresponding :math:`\mathsf{ak}` and :math:`\mathsf{nk}` as specified in [#protocol-saplingkeycomponents]_.
|
||||
- Let :math:`I = \textsf{BLAKE2b-256}(\texttt{"Zcash_SaplingInt"}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))`.
|
||||
- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))`.
|
||||
- Let :math:`R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])`.
|
||||
- Let :math:`\mathsf{nsk_{internal}} = (I_\mathsf{nsk} + \mathsf{nsk}) \pmod{r_\mathbb{J}}`.
|
||||
- Split :math:`R` into two 32-byte sequences, :math:`\mathsf{dk_{internal}}` and :math:`\mathsf{ovk_{internal}}`.
|
||||
- Return the internal spending key as :math:`(\mathsf{ask}, \mathsf{nsk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})`.
|
||||
|
||||
Deriving a Sapling internal full viewing key
|
||||
````````````````````````````````````````````
|
||||
|
||||
Let :math:`\mathcal{H}^\mathsf{Sapling}` be as defined in [#protocol-saplingkeycomponents]_.
|
||||
|
||||
Let :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})` be the external full viewing key.
|
||||
|
||||
- Let :math:`I = \textsf{BLAKE2b-256}(\texttt{"Zcash_SaplingInt"}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))`.
|
||||
- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))`.
|
||||
- Let :math:`R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])`.
|
||||
- Let :math:`\mathsf{nk_{internal}} = [I_\mathsf{nsk}] \mathcal{H}^\mathsf{Sapling} + \mathsf{nk}`.
|
||||
- Split :math:`R` into two 32-byte sequences, :math:`\mathsf{dk_{internal}}` and :math:`\mathsf{ovk_{internal}}`.
|
||||
- Return the internal full viewing key as :math:`(\mathsf{ak}, \mathsf{nk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})`.
|
||||
|
||||
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 :math:`\mathsf{ak}`) as the
|
||||
original, but viewing authority only for internal transfers.
|
||||
|
||||
The values of :math:`I`, :math:`I_\mathsf{nsk}`, and :math:`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:
|
||||
|
||||
.. figure:: zip-0032-sapling-internal-key-derivation.png
|
||||
:width: 900px
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
||||
Diagram of Sapling internal key derivation
|
||||
|
||||
(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 [#zip-0316]_.
|
||||
|
||||
Sapling diversifier derivation
|
||||
------------------------------
|
||||
|
||||
|
@ -323,6 +381,8 @@ Sprout child key derivation
|
|||
- 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`.
|
||||
|
||||
There is no support for internal key derivation for Sprout.
|
||||
|
||||
|
||||
Specification: Orchard key derivation
|
||||
=====================================
|
||||
|
@ -365,6 +425,51 @@ Orchard child key derivation
|
|||
- 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 internal key derivation
|
||||
-------------------------------
|
||||
|
||||
As in the case of Sapling, for each external address, we want to produce another address
|
||||
for use by wallets for internal operations such as change and auto-shielding. That is, for
|
||||
each 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 :math:`\mathsf{ask}` be the spend authorizing key if available, and
|
||||
let :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})` be the corresponding external full
|
||||
viewing key, obtained as specified in [#protocol-orchardkeycomponents]_.
|
||||
|
||||
- Let :math:`K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})`.
|
||||
- Let :math:`\mathsf{rivk_{internal}} = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}}(K, [\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk}))`.
|
||||
|
||||
Then the expanded internal spending key is :math:`(\mathsf{ask}, \mathsf{nk}, \mathsf{rivk_{internal}})`,
|
||||
and the internal full viewing key is :math:`(\mathsf{ak}, \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 :math:`\mathsf{rivk_{internal}}`
|
||||
field relative to the external full viewing key, which results in different
|
||||
:math:`\mathsf{dk_{internal}}`, :math:`\mathsf{ivk_{internal}}` and :math:`\mathsf{ovk_{internal}}`
|
||||
fields being derived, as specified in [#protocol-orchardkeycomponents]_.
|
||||
|
||||
The values of :math:`K` and :math:`\mathsf{rivk_{internal}}` 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:
|
||||
|
||||
.. figure:: zip-0032-orchard-internal-key-derivation.png
|
||||
:width: 720px
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
||||
Diagram of Orchard internal key derivation, also showing derivation from the parent extended spending key
|
||||
|
||||
Note that there does not exist an :math:`\mathsf{sk}` that directly generates the internal key
|
||||
components by the procedure described in [#protocol-orchardkeycomponents]_. A similar effect
|
||||
could be obtained by storing a flag that indicates external or internal usage along with the
|
||||
original :math:`\mathsf{sk}`, but we do not define a specific format for this.
|
||||
|
||||
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 [#zip-0316]_.
|
||||
|
||||
Orchard diversifier derivation
|
||||
------------------------------
|
||||
|
||||
|
@ -637,9 +742,11 @@ References
|
|||
.. [#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>`_
|
||||
.. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys <zip-0316.rst>`_
|
||||
.. [#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-orchardkeycomponents] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.2.3: Orchard Key Components <protocol/protocol.pdf#orchardkeycomponents>`_
|
||||
.. [#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>`_
|
||||
|
|
Loading…
Reference in New Issue