2020-05-31 12:47:57 -07:00
::
ZIP: 212
Title: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext
Owners: Sean Bowe <sean@electriccoin.co>
2020-08-11 08:13:57 -07:00
Status: Implemented (zcashd)
2020-05-31 12:47:57 -07:00
Category: Consensus
Created: 2019-03-31
License: MIT
Terminology
===========
2020-08-11 08:07:59 -07:00
The key words "MUST", "MUST NOT", "SHOULD NOT", and "MAY" in this document are
to be interpreted as described in RFC 2119. [#RFC2119]_
2020-05-31 12:47:57 -07:00
2020-05-31 16:29:27 -07:00
The function :math: `\mathsf{ToScalar}` is defined as in Section 4.4.2 of the
Zcash Protocol Specification. [#protocol]_
2020-05-31 12:47:57 -07:00
2020-08-11 08:07:59 -07:00
2020-05-31 12:47:57 -07:00
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
2020-06-05 07:55:07 -07:00
the ephemeral Diffie-Hellman key in the Output to avoid an assumption on
2020-05-31 12:47:57 -07:00
zk-SNARK soundness for preventing diversified address linkability.
2020-08-11 08:07:59 -07:00
2020-05-31 12:47:57 -07:00
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.
2020-05-31 16:29:27 -07:00
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.)
2020-05-31 12:47:57 -07:00
In order to prevent this attack, the protocol currently forces the sender to
2020-05-31 16:29:27 -07:00
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
2020-05-31 12:47:57 -07:00
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
2020-05-31 16:29:27 -07:00
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
2020-05-31 12:47:57 -07:00
otherwise. This forms a line of defense in the case that soundness of the
zk-SNARK does not hold.
2020-05-31 16:29:27 -07:00
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}` .
2020-05-31 12:47:57 -07:00
2020-08-11 08:07:59 -07:00
2020-05-31 12:47:57 -07:00
Specification
=============
2020-11-05 05:50:58 -08:00
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.
2020-05-31 12:47:57 -07:00
Pseudo random functions (PRFs) are defined in section 4.2.1 of the Zcash
2020-11-09 07:59:51 -08:00
Protocol Specification [#protocol-abstractprfs]_ . We will be adapting
2020-05-31 16:29:27 -07:00
: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.
2020-05-31 12:47:57 -07:00
Changes to Sapling Note plaintexts
----------------------------------
Note plaintext encodings are specified in section 5.5 of the Zcash Protocol
2020-11-09 07:59:51 -08:00
Specification [#protocol-notept]_ . Currently, the encoding of a Sapling note plaintext
2020-05-31 16:29:27 -07:00
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.
2020-05-31 12:47:57 -07:00
2020-08-11 08:07:59 -07:00
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
2020-11-09 07:59:51 -08:00
and 4.17.3 of the Zcash Protocol Specification. [#protocol-saplingdecryptivk]_
[#protocol-saplingdecryptovk]_
2020-05-31 12:47:57 -07:00
Changes to the process of sending Sapling notes
-----------------------------------------------
The process of sending notes in Sapling is described in section 4.6.2 of the
2020-11-09 07:59:51 -08:00
Zcash Protocol Specification [#protocol-saplingsend]_ . During this process, the
sender samples :math: `\mathsf{rcm^{new}}` uniformly at random. In addition, the
2020-05-31 16:29:27 -07:00
process of encrypting a note is described in section 4.17.1 of the Zcash Protocol
2020-11-09 07:59:51 -08:00
Specification [#protocol-saplingencrypt]_ . During this process, the sender also
samples the ephemeral private key :math: `\mathsf{esk}` uniformly at random.
2020-05-31 12:47:57 -07:00
2020-08-11 08:07:59 -07:00
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}}` .
2020-05-31 12:47:57 -07:00
2020-08-11 08:07:59 -07:00
:math: `\mathsf{rcm^{new}}` MUST be computed by the sender as the output of
2020-05-31 16:29:27 -07:00
:math: `\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))` .
2020-05-31 12:47:57 -07:00
2020-08-11 08:07:59 -07:00
:math: `\mathsf{esk}` MUST be computed by the sender as the output of
2020-05-31 16:29:27 -07:00
:math: `\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5]))` .
2020-05-31 12:47:57 -07:00
Changes to the process of receiving Sapling notes
-------------------------------------------------
The process of receiving notes in Sapling is described in sections 4.17.2 and
2020-11-09 07:59:51 -08:00
4.17.3 of the Zcash Protocol Specification. [#protocol-saplingdecryptivk]_
[#protocol-saplingdecryptovk]_
2020-05-31 12:47:57 -07:00
2020-08-11 08:07:59 -07:00
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]))` .
2020-05-31 16:29:27 -07:00
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.
2020-05-31 12:47:57 -07:00
2020-07-03 19:21:06 -07:00
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.
2020-05-31 12:47:57 -07:00
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
2020-05-31 16:29:27 -07:00
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.
2020-05-31 12:47:57 -07:00
2020-05-31 16:29:27 -07:00
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}` .
2020-05-31 12:47:57 -07:00
2020-10-23 03:32:46 -07:00
The grace period is intended to mitigate loss-of-funds risk due to
non-conformant sending wallet implementations. The intention is that during the
2020-08-11 08:07:59 -07:00
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,
2020-10-23 03:32:46 -07:00
such wallets are non-conformant because it is a "MUST" requirement to
2020-08-11 08:07:59 -07:00
*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.
2020-07-03 19:21:06 -07:00
2020-05-31 12:47:57 -07:00
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.
2020-05-31 16:29:27 -07:00
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.
2020-05-31 12:47:57 -07:00
2020-08-11 08:08:42 -07:00
2020-08-11 08:28:15 -07:00
Deployment
==========
This proposal will be deployed with the Canopy network upgrade. [#zip-0251]_
2020-05-31 12:47:57 -07:00
Reference Implementation
========================
2020-08-11 08:08:42 -07:00
In zcashd:
* https://github.com/zcash/zcash/pull/4578
In librustzcash:
* https://github.com/zcash/librustzcash/pull/258
2020-05-31 12:47:57 -07:00
Acknowledgements
================
The discovery that diversified address unlinkability depended on the zk-SNARK
knowledge assumption was made by Sean Bowe and Zooko Wilcox.
2020-08-11 08:08:42 -07:00
2020-05-31 12:47:57 -07:00
References
==========
2020-05-31 16:29:27 -07:00
2020-11-09 07:59:51 -08:00
.. [#RFC2119] `RFC 2119: Key words for use in RFCs to Indicate Requirement Levels <https://www.rfc-editor.org/rfc/rfc2119.html> `_
2020-11-05 05:50:58 -08:00
.. [#protocol] `Zcash Protocol Specification, Version 2020.1.15 or later <https://zips.z.cash/protocol/protocol.pdf> `_
2020-11-09 07:59:51 -08:00
.. [#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> `_
2020-07-03 19:21:06 -07:00
.. [#zip-0207] `ZIP 207: Split Founders' Reward <zip-0207.rst> `_
.. [#zip-0213] `ZIP 213: Shielded Coinbase <zip-0213.rst> `_
2020-08-11 08:28:15 -07:00
.. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade <zip-0251.rst> `_