mirror of https://github.com/zcash/zips.git
301 lines
15 KiB
ReStructuredText
301 lines
15 KiB
ReStructuredText
::
|
|
|
|
ZIP: 212
|
|
Title: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext
|
|
Owners: Sean Bowe <sean@electriccoin.co>
|
|
Status: Implemented (zcashd)
|
|
Category: Consensus
|
|
Created: 2019-03-31
|
|
License: MIT
|
|
|
|
|
|
Terminology
|
|
===========
|
|
|
|
The key words "MUST", "MUST NOT", "SHOULD NOT", and "MAY" in this document are
|
|
to be interpreted as described in RFC 2119. [#RFC2119]_
|
|
|
|
The function :math:`\mathsf{ToScalar}` is defined as in Section 4.4.2 of the
|
|
Zcash Protocol Specification. [#protocol]_
|
|
|
|
|
|
Abstract
|
|
========
|
|
|
|
This ZIP proposes a new note plaintext format for Sapling Outputs in
|
|
transactions. The new format allows recipients to check the well-formedness of
|
|
the ephemeral Diffie-Hellman key in the Output to avoid an assumption on
|
|
zk-SNARK soundness for preventing diversified address linkability.
|
|
|
|
|
|
Motivation
|
|
==========
|
|
|
|
The Sapling payment protocol contains a feature called "diversified addresses"
|
|
which allows a single incoming viewing key to receive payments on an enormous
|
|
number of distinct and unlinkable payment addresses. This feature allows users
|
|
to maintain many payment addresses without paying additional overhead during
|
|
blockchain scanning.
|
|
|
|
The feature works by allowing payment addresses to become a tuple
|
|
:math:`(\mathsf{pk_d}, \mathsf{d})` of a public key :math:`\mathsf{pk_d}` and
|
|
:math:`88`-bit diversifier :math:`\mathsf{d}` such that
|
|
:math:`\mathsf{pk_d} = [\mathsf{ivk}] GH(\mathsf{d})` for some incoming viewing key
|
|
:math:`\mathsf{ivk}`. The hash function :math:`GH(\mathsf{d})` maps from a
|
|
diversifier to prime order elements of the Jubjub elliptic curve. It
|
|
is possible for a user to choose many :math:`\mathsf{d}` to create several
|
|
distinct and unlinkable payment addresses of this form.
|
|
|
|
In order to make a payment to a Sapling address, an ephemeral secret
|
|
:math:`\mathsf{esk}` is sampled by the sender and an ephemeral public key
|
|
:math:`\mathsf{epk} = [\mathsf{esk}] GH(\mathsf{d})` is included in the
|
|
Output description. Then, a shared Diffie-Hellman secret is computed by the
|
|
sender as :math:`[\mathsf{esk}] [8] \mathsf{pk_d}`. The recipient can recover
|
|
this shared secret without knowledge of the particular :math:`\mathsf{d}` by
|
|
computing :math:`[\mathsf{ivk}] [8] \mathsf{epk}`. This shared secret is then
|
|
used as part of note decryption.
|
|
|
|
Naively, the recipient cannot know which :math:`(\mathsf{pk_d}, \mathsf{d})`
|
|
was used to compute the shared secret, but the sender is asked to include the
|
|
:math:`\mathsf{d}` within the note plaintext to reconstruct the note. However,
|
|
if the recipient has more than one known address, an attacker could use a
|
|
different payment address to perform secret exchange and, by observing the
|
|
behavior of the recipient, link the two diversified addresses together. (This
|
|
attacker strategy was discovered by Brian Warner earlier in the design of the
|
|
Sapling protocol.)
|
|
|
|
In order to prevent this attack, the protocol currently forces the sender to
|
|
prove knowledge of the discrete logarithm of :math:`\mathsf{epk}` with respect
|
|
to the :math:`\mathsf{g_d} = GH(\mathsf{d})` included within the note
|
|
commitment. This :math:`\mathsf{g_d}` is determined by :math:`\mathsf{d}`
|
|
and recomputed during note decryption, and so the recipient will either be
|
|
unable to decrypt the note or the sender will be unable to perform the attack.
|
|
|
|
However, this check occurs as part of the zero-knowledge proof statement and so
|
|
relies on the soundness of the underlying zk-SNARK in Sapling, and therefore it
|
|
relies on relatively strong cryptographic assumptions and a trusted setup. It
|
|
would be preferable to force the sender to transfer sufficient information in
|
|
the note plaintext to allow deriving :math:`\mathsf{esk}`, so that, during note
|
|
decryption, the recipient can check that :math:`\mathsf{epk} = [\mathsf{esk}] \mathsf{g_d}`
|
|
(for the expected :math:`\mathsf{g_d}`) and ignore the payment as invalid
|
|
otherwise. This forms a line of defense in the case that soundness of the
|
|
zk-SNARK does not hold.
|
|
|
|
Merely sending :math:`\mathsf{esk}` to the recipient in the note plaintext would
|
|
require us to enlarge the note plaintext, but also would compromise the proof
|
|
of IND-CCA2 security for in-band secret distribution. We avoid both of these
|
|
concerns by using a key derivation to obtain both :math:`\mathsf{esk}` and
|
|
:math:`\mathsf{rcm}`.
|
|
|
|
|
|
Specification
|
|
=============
|
|
|
|
The specification in this ZIP is intended to be aligned with version 2020.1.15
|
|
of the Zcash Protocol Specification [#protocol]_. See the Change History of
|
|
that document for relevant corrections.
|
|
|
|
Pseudo random functions (PRFs) are defined in section 4.2.1 of the Zcash
|
|
Protocol Specification [#protocol-abstractprfs]_. We will be adapting
|
|
:math:`\mathsf{PRF^{expand}}` for the purposes of this ZIP. This function is
|
|
keyed by a 256-bit key :math:`\mathsf{sk}` and takes an arbitrary length byte
|
|
sequence as input, returning a :math:`64`-byte sequence as output.
|
|
|
|
Changes to Sapling Note plaintexts
|
|
----------------------------------
|
|
|
|
Note plaintext encodings are specified in section 5.5 of the Zcash Protocol
|
|
Specification [#protocol-notept]_. Currently, the encoding of a Sapling note plaintext
|
|
requires that the first byte take the form :math:`\textbf{0x01}`, indicating
|
|
the version of the note plaintext. In addition, a :math:`256`-bit
|
|
:math:`\mathsf{rcm}` field exists within the note plaintext and encoding.
|
|
|
|
Following the activation of this ZIP, senders of Sapling notes MUST use
|
|
the following new note plaintext format:
|
|
|
|
* The first byte of the encoding MUST take the form :math:`\textbf{0x02}`
|
|
(representing the new note plaintext version).
|
|
* The field :math:`\mathsf{rcm}` of the encoding is renamed to
|
|
:math:`\mathsf{rseed}`. This field :math:`\mathsf{rseed}` of the Sapling note
|
|
plaintext no longer takes the type of :math:`\mathsf{NoteCommit^{Sapling}.Trapdoor}`
|
|
but instead is a :math:`32`-byte sequence.
|
|
|
|
The requirement that :math:`\mathsf{rseed}` (previously, :math:`\mathsf{rcm}`)
|
|
be a scalar of the Jubjub elliptic curve, when interpreted as a little endian
|
|
integer, is removed from the description of note plaintexts in sections 4.17.2
|
|
and 4.17.3 of the Zcash Protocol Specification. [#protocol-saplingdecryptivk]_
|
|
[#protocol-saplingdecryptovk]_
|
|
|
|
Changes to the process of sending Sapling notes
|
|
-----------------------------------------------
|
|
|
|
The process of sending notes in Sapling is described in section 4.6.2 of the
|
|
Zcash Protocol Specification [#protocol-saplingsend]_. During this process, the
|
|
sender samples :math:`\mathsf{rcm^{new}}` uniformly at random. In addition, the
|
|
process of encrypting a note is described in section 4.17.1 of the Zcash Protocol
|
|
Specification [#protocol-saplingencrypt]_. During this process, the sender also
|
|
samples the ephemeral private key :math:`\mathsf{esk}` uniformly at random.
|
|
|
|
After the activation of this ZIP, the sender MUST instead sample a uniformly
|
|
random :math:`32`-byte sequence :math:`\mathsf{rseed}`. The note plaintext takes
|
|
:math:`\mathsf{rseed}` in place of :math:`\mathsf{rcm^{new}}`.
|
|
|
|
:math:`\mathsf{rcm^{new}}` MUST be computed by the sender as the output of
|
|
:math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))`.
|
|
|
|
:math:`\mathsf{esk}` MUST be computed by the sender as the output of
|
|
:math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5]))`.
|
|
|
|
Changes to the process of receiving Sapling notes
|
|
-------------------------------------------------
|
|
|
|
The process of receiving notes in Sapling is described in sections 4.17.2 and
|
|
4.17.3 of the Zcash Protocol Specification. [#protocol-saplingdecryptivk]_
|
|
[#protocol-saplingdecryptovk]_
|
|
|
|
There is a "grace period" of 32256 blocks starting from the block at which this
|
|
ZIP activates, during which note plaintexts with lead byte 0x01 MUST still be
|
|
accepted.
|
|
|
|
Let ActivationHeight be the activation height of this ZIP, and let
|
|
GracePeriodEndHeight be ActivationHeight + 32256.
|
|
|
|
The height of a transaction in a mined block is defined as the height of that
|
|
block. An implementation MAY also decrypt mempool transactions, in which case
|
|
the height used is the height of the next block at the time of the check.
|
|
An implementation SHOULD NOT attempt to decrypt mempool transactions without
|
|
having obtained a best-effort view of the current block chain height.
|
|
|
|
When the recipient of a note (either using an incoming viewing key or a full
|
|
viewing key) is able to decrypt a note plaintext, it performs the following
|
|
check on the plaintext lead byte, based on the height of the containing
|
|
transaction:
|
|
|
|
* If the height is less than ActivationHeight, then only 0x01 is accepted as
|
|
the plaintext lead byte.
|
|
* If the height is at least ActivationHeight and less than GracePeriodEndHeight,
|
|
then either 0x01 or 0x02 is accepted as the plaintext lead byte.
|
|
* If the height is at least GracePeriodEndHeight, then only 0x02 is accepted
|
|
as the plaintext lead byte.
|
|
|
|
If the plaintext lead byte is not accepted then the note MUST be discarded.
|
|
However, if an implementation decrypted the note from a mempool transaction and
|
|
it was accepted at that time, but it is later mined in a block after the end of
|
|
the grace period, then it MAY be retained.
|
|
|
|
A note plaintext with lead byte 0x02 contains a field :math:`\mathsf{rseed}`
|
|
that is a :math:`32`-byte sequence rather than a scalar value :math:`\mathsf{rcm}`.
|
|
The recipient, during decryption and in any later contexts, will interpret the
|
|
value :math:`\mathsf{rcm}` as the output of
|
|
:math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))`.
|
|
Further, the recipient MUST compute :math:`\mathsf{esk}` as
|
|
:math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5]))` and check
|
|
that :math:`\mathsf{epk} = [\mathsf{esk}] \mathsf{g_d}` and fail decryption
|
|
if this check is not satisfied.
|
|
|
|
Consensus rule change for coinbase transactions
|
|
-----------------------------------------------
|
|
|
|
After the activation of this ZIP, any Sapling output of a coinbase transaction
|
|
that is decrypted to a note plaintext as specified in [#zip-0213]_, MUST have
|
|
note plaintext lead byte equal to 0x02.
|
|
|
|
This applies even during the “grace period”, and also applies to funding stream
|
|
outputs [#zip-0207]_ sent to shielded payment addresses, if there are any.
|
|
|
|
|
|
Rationale
|
|
=========
|
|
|
|
The attack that this prevents is an interactive attack that requires an
|
|
adversary to be able to break critical soundness properties of the zk-SNARKs
|
|
underlying Sapling. It is potentially valid to assume that this cannot occur,
|
|
due to other damaging effects on the system such as undetectable counterfeiting.
|
|
However, we have attempted to avoid any instance in the protocol where privacy
|
|
(even against interactive attacks) depended on strong cryptographic assumptions.
|
|
Acting differently here would be confusing for users that have previously been
|
|
told that "privacy does not depend on zk-SNARK soundness" or similar claims.
|
|
|
|
It is possible for us to infringe on the length of the ``memo`` field and ask
|
|
the sender to provide :math:`\mathsf{esk}` within the existing note plaintext
|
|
without modifying the transaction format, but this would harm users who have
|
|
come to expect a :math:`512`-byte memo field to be available to them. Changes
|
|
to the memo field length should be considered in a broader context than changes
|
|
made for cryptographic purposes.
|
|
|
|
It is possible to transmit a signature of knowledge of a correct
|
|
:math:`\mathsf{esk}` rather than :math:`\mathsf{esk}` itself, but this appears
|
|
to be an unnecessary complication and is likely slower than just supplying
|
|
:math:`\mathsf{esk}`.
|
|
|
|
The grace period is intended to mitigate loss-of-funds risk due to
|
|
non-conformant sending wallet implementations. The intention is that during the
|
|
grace period (of about 4 weeks), it will be possible to identify wallets that
|
|
are still sending plaintexts according to the old specification, and cajole
|
|
their developers to make the required updates. For the avoidance of doubt,
|
|
such wallets are non-conformant because it is a "MUST" requirement to
|
|
*immediately* switch to sending note plaintexts with lead byte 0x02 (and the
|
|
other changes in this specification) at the upgrade. Note that nodes will
|
|
clear their mempools when the upgrade activates, which will clear all
|
|
plaintexts with lead byte 0x01 that were sent conformantly and not mined
|
|
before the upgrade.
|
|
|
|
|
|
Security and Privacy Considerations
|
|
===================================
|
|
|
|
The changes made in this proposal prevent an interactive attack that could link
|
|
together diversified addresses by only breaking the knowledge soundness
|
|
assumption of the zk-SNARK. It is already assumed that the adversary cannot
|
|
defeat the EC-DDH assumption of the Jubjub elliptic curve, for it could perform
|
|
a linkability attack trivially in that case.
|
|
|
|
In the naive case where the protocol is modified so that :math:`\mathsf{esk}`
|
|
is supplied directly to the recipient (rather than derived through
|
|
:math:`\mathsf{rseed}`) this would lead to an instance of key-dependent
|
|
encryption, which is difficult or perhaps impossible to prove secure using
|
|
existing security notions. Our approach of using a key derivation, which
|
|
ultimately queries an oracle, allows a proof for IND-CCA2 security to be
|
|
written by reprogramming the oracle to return bogus keys when necessary.
|
|
|
|
|
|
Deployment
|
|
==========
|
|
|
|
This proposal will be deployed with the Canopy network upgrade. [#zip-0251]_
|
|
|
|
|
|
Reference Implementation
|
|
========================
|
|
|
|
In zcashd:
|
|
|
|
* https://github.com/zcash/zcash/pull/4578
|
|
|
|
In librustzcash:
|
|
|
|
* https://github.com/zcash/librustzcash/pull/258
|
|
|
|
|
|
Acknowledgements
|
|
================
|
|
|
|
The discovery that diversified address unlinkability depended on the zk-SNARK
|
|
knowledge assumption was made by Sean Bowe and Zooko Wilcox.
|
|
|
|
|
|
References
|
|
==========
|
|
|
|
.. [#RFC2119] `RFC 2119: Key words for use in RFCs to Indicate Requirement Levels <https://www.rfc-editor.org/rfc/rfc2119.html>`_
|
|
.. [#protocol] `Zcash Protocol Specification, Version 2020.1.15 or later <https://zips.z.cash/protocol/protocol.pdf>`_
|
|
.. [#protocol-saplingencrypt] `Zcash Protocol Specification, Version 2020.1.15. Section 4.17.1: Encryption (Sapling) <https://zips.z.cash/protocol/protocol.pdf#saplingencrypt>`_
|
|
.. [#protocol-abstractprfs] `Zcash Protocol Specification, Version 2020.1.15. Section 4.1.2: Pseudo Random Functions <https://zips.z.cash/protocol/protocol.pdf#abstractprfs>`_
|
|
.. [#protocol-notept] `Zcash Protocol Specification, Version 2020.1.15. Section 5.5: Encodings of Note Plaintexts and Memo Fields <https://zips.z.cash/protocol/protocol.pdf#notept>`_
|
|
.. [#protocol-saplingdecryptivk] `Zcash Protocol Specification, Version 2020.1.15. Section 4.17.2: Decryption using an Incoming Viewing Key (Sapling) <https://zips.z.cash/protocol/protocol.pdf#saplingdecryptivk>`_
|
|
.. [#protocol-saplingdecryptovk] `Zcash Protocol Specification, Version 2020.1.15. Section 4.17.3: Decryption using a Full Viewing Key (Sapling) <https://zips.z.cash/protocol/protocol.pdf#saplingdecryptovk>`_
|
|
.. [#protocol-saplingsend] `Zcash Protocol Specification, Version 2020.1.15. Section 4.6.2: Sending Notes (Sapling) <https://zips.z.cash/protocol/protocol.pdf#saplingsend>`_
|
|
.. [#zip-0207] `ZIP 207: Split Founders' Reward <zip-0207.rst>`_
|
|
.. [#zip-0213] `ZIP 213: Shielded Coinbase <zip-0213.rst>`_
|
|
.. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade <zip-0251.rst>`_
|