* Don't imply that the non-canonical encoding of (0, -1) is not a problem; it is.

* Rewrite Specification section.
* Additions to Rationale section.
* Wording improvements.
* Note the history of adjustments to the protocol spec.
* Fix rst syntax.
* Change license to MIT.
* MUST NOT is not used.
* Move draft to Proposed.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2021-02-28 21:11:55 +00:00
parent 5a92818183
commit 65026436b7
2 changed files with 126 additions and 46 deletions

View File

@ -92,7 +92,7 @@ Index of ZIPs
<tr> <td>213</td> <td class="left"><a href="zip-0213.rst">Shielded Coinbase</a></td> <td>Final</td>
<tr> <td>214</td> <td class="left"><a href="zip-0214.rst">Consensus rules for a Zcash Development Fund</a></td> <td>Implemented (zcashd)</td>
<tr> <td>215</td> <td class="left"><a href="zip-0215.rst">Explicitly Defining and Modifying Ed25519 Validation Rules</a></td> <td>Implemented (zcashd)</td>
<tr> <td><span class="reserved">216</span></td> <td class="left"><a class="reserved" href="zip-0216.rst">Require Canonical Point Encodings</a></td> <td>Reserved</td>
<tr> <td>216</td> <td class="left"><a href="zip-0216.rst">Require Canonical Jubjub Point Encodings</a></td> <td>Proposed</td>
<tr> <td><span class="reserved">217</span></td> <td class="left"><a class="reserved" href="zip-0217.rst">Aggregate Signatures</a></td> <td>Reserved</td>
<tr> <td><span class="reserved">218</span></td> <td class="left"><a class="reserved" href="zip-0218.rst">User-Defined Assets and Wrapped Assets</a></td> <td>Reserved</td>
<tr> <td><span class="reserved">219</span></td> <td class="left"><a class="reserved" href="zip-0219.rst">Disabling Addition of New Value to the Sapling Chain Value Pool</a></td> <td>Reserved</td>

View File

@ -4,18 +4,21 @@
Title: Require Canonical Jubjub Point Encodings
Owners: Jack Grigg <jack@electriccoin.co>
Daira Hopwood <daira@electriccoin.co>
Status: Draft
Status: Proposed
Category: Consensus
Created: 2021-02-11
License: BSD-2-Clause
License: MIT
Discussions-To: <https://github.com/zcash/zips/issues/400>
Terminology
===========
The key words "MUST" and "MUST NOT" in this document is to be interpreted as described
in RFC 2119. [#RFC2119]_
The key word "MUST" in this document is to be interpreted as described in RFC 2119.
[#RFC2119]_
The term "network upgrade" in this document is to be interpreted as described in
ZIP 200. [#zip-0200]_
Abstract
@ -28,62 +31,111 @@ rejecting all non-canonical representations of Jubjub points.
Motivation
==========
The Sapling specification was written with the intent that all values, including Jubjub
points, are strongly typed with canonical representations. [#protocol-jubjub]_ This has
significant advantages for security analysis, because it allows the protocol to be
The Sapling specification was originally written with the intent that all values, including
Jubjub points, are strongly typed with canonical representations. [#protocol-jubjub]_ This
has significant advantages for security analysis, because it allows the protocol to be
modelled with just the abstract types.
The intention of the Jubjub implementation (both in the `jubjub` crate [#jubjub-crate]_
and its prior implementations) was to ensure that only canonical point encodings would be
accepted by the decoding logic. However, an oversight in the implementation allowed an
edge case to slip through: for each point on the curve where the $u$-coordinate is zero,
there are two encodings that will be accepted:
edge case to slip through: for each point on the curve where the :math:`u\!`-coordinate is
zero, there are two encodings that will be accepted:
```rust
// Fix the sign of `u` if necessary
let flip_sign = Choice::from((u.to_bytes()[0] ^ sign) & 1);
let u_negated = -u;
let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);
```
.. code-block:: rust
This code accepts either sign bit, because `u_negated == u`.
// Fix the sign of `u` if necessary
let flip_sign = Choice::from((u.to_bytes()[0] ^ sign) & 1);
let u_negated = -u;
let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);
There are two points on the Jubjub curve with $u$-coordinate zero:
This code accepts either sign bit, because ``u_negated == u``.
- `(0, -1)`, which is a point of order two, and thus rejected by the implementation
anywhere that a prime-order subgroup point is specified.
- `(0, 1)`, which is the identity, and thus is an element of the prime-order subgroup.
There are two points on the Jubjub curve with :math:`u\!`-coordinate zero:
The non-canonical identity encoding creates a consensus issue because unlike other
non-canonical points that are rejected, a non-canonical identity encoding that is decoded
and then encoded, does not produce the original encoding. For example, if a non-canonical
encoding appeared in a transaction field, then node implementations that store points
internally as abstract curve points, and used those to derive transaction IDs, would
derive different IDs than nodes which store transactions as bytes (such as `zcashd`).
- :math:`(0, 1)`, which is the identity;
- :math:`(0, -1)`, which is a point of order two.
Each of these has a single non-canonical encoding in which the value of the sign bit is
:math:`1`.
This creates a consensus issue because (unlike other non-canonical point encodings that
are rejected) either of the above encodings can be decoded, and then re-encoded to a
*different* encoding. For example, if a non-canonical encoding appeared in a transaction
field, then node implementations that store points internally as abstract curve points,
and used those to derive transaction IDs, would derive different IDs than nodes which
store transactions as bytes (such as `zcashd`).
This issue is not known to cause any security vulnerability, beyond the risk of
consensus incompatibility. Adjustments to the protocol specification were made in
versions 2020.1.8, 2020.1.9, 2020.1.15, and 2021.1.17 to match the `zcashd` implementation.
(The fact that this required 4 specification revisions to get right, conclusively
demonstrates the problem.)
Specification
=============
TODO: Define a non-canonical Jubjub point encoding.
Let :math:`\mathsf{abst}_{\mathbb{J}}`, :math:`\mathsf{repr}_{\mathbb{J}}`, and
:math:`q_{\mathbb{J}}` be as defined in [#protocol-jubjub]_.
When this ZIP activates, the following places within the Sapling consensus protocol
where Jubjub points occur MUST reject non-canonical Jubjub point encodings. (This
is all of the places where Jubjub points occur in compressed representations.)
Define a non-canonical compressed encoding of a Jubjub point to be a sequence of
:math:`256` bits, :math:`b`, such that :math:`\mathsf{abst}_{\mathbb{J}}(b) \neq \bot`
and :math:`\mathsf{repr_{\mathbb{J}}}\big(\mathsf{abst}_{\mathbb{J}}(b)\big) \neq b`.
Non-normative note: There are two such bit sequences,
:math:`\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + 1)` and
:math:`\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + q_{\mathbb{J}} - 1)`.
The Sapling protocol uses little-endian ordering when converting between bit and
byte sequences, so the first of these sequences corresponds to :math:`31` zero bytes
followed by a :math:`\mathtt{0x80}` byte.
Once this ZIP activates, the following places within the Sapling consensus protocol
where Jubjub points occur MUST reject non-canonical Jubjub point encodings.
In Sapling Spend descriptions [#protocol-spenddesc]_:
- :math:`\mathtt{cv}`
- :math:`\mathtt{rk}`
- the :math:`\underline{R}` component (i.e. the first :math:`32` bytes) of the
:math:`\mathtt{spendAuthSig}` RedDSA signature.
In Sapling Output descriptions [#protocol-outputdesc]_:
- :math:`\mathtt{cv}`
- :math:`\mathtt{ephemeralKey}`.
In transactions [#protocol-txnencodingandconsensus]_:
- the :math:`\underline{R}` component (i.e. the first :math:`32` bytes) of the
:math:`\mathtt{bindingSigSapling}` RedDSA signature.
In the plaintext obtained by decrypting the :math:`\mathsf{C^{out}}` field of a
Sapling transmitted note ciphertext [#protocol-decryptovk]_:
- :math:`\mathsf{pk}\star_{\mathsf{d}}`.
(This affects decryption of :math:`\mathsf{C^{out}}` in all cases, but is
consensus-critical only in the case of a shielded coinbase output.
[#protocol-txnencodingandconsensus]_)
In addition, Sapling addresses and full viewing keys MUST be considered invalid if
they contain non-canonical Jubjub point encodings when imported.
In Sapling addresses [#protocol-saplingpaymentaddrencoding]_:
- the encoding of :math:`\mathsf{pk_d}`.
In Sapling full viewing keys [#protocol-saplingfullviewingkeyencoding]_ and extended
full viewing keys [#zip-0032-extfvk]_:
- the encoding of :math:`\mathsf{ak}`.
The above is intended to be a complete list of the places where compressed encodings
of Jubjub points occur in the Zcash consensus protocol and in plaintext, address, or
key formats.
- Sapling addresses:
- `pk_d`
- Full viewing keys and extended full viewing keys:
- `ak`
- Sapling Spend description:
- `cv`
- `rk`
- The `R` component of the `spendAuthSig` RedDSA signature.
- Sapling Output description:
- `cv`
- `ephemeralKey`
- The `R` component of the `bindingSigSapling` RedDSA signature.
TODO: specify when addresses, full viewing keys, and note plaintexts are checked.
Rationale
=========
@ -103,6 +155,23 @@ In Sapling, we are motivated instead to reject these non-canonical points:
- The Jubjub curve has a vastly-smaller scope of usage in the general cryptographic
ecosystem than Curve25519 and Ed25519.
The necessary checks are very simple and do not require cryptographic operations,
therefore the performance impact will be negligible.
The public inputs of Jubjub points to the Spend circuit (:math:`\mathsf{rk}` and
:math:`\mathsf{cv^{old}}`) and Output circuit (:math:`\mathsf{cv^{new}}` and
:math:`\mathsf{epk}`) are not affected because they are represented in affine
coordinates as elements of the correct field
(:math:`\mathbb{F}_{r_\mathbb{S}} = \mathbb{F}_{q_\mathbb{J}}`),
and so no issue of encoding canonicity arises.
Encodings of elliptic curve points on Curve25519, BN-254 :math:`\mathbb{G}_1`,
BN-254 :math:`\mathbb{G}_2`, BLS12-381 :math:`\mathbb{G}_1`, and
BLS12-381 :math:`\mathbb{G}_2` are not affected.
Encodings of elliptic curve points on the Pallas and Vesta curves in the Orchard proposal
[#protocol-pallasandvesta]_ are also not affected.
Security and Privacy Considerations
===================================
@ -123,6 +192,17 @@ References
==========
.. [#RFC2119] `RFC 2119: Key words for use in RFCs to Indicate Requirement Levels <https://www.rfc-editor.org/rfc/rfc2119.html>`_
.. [#protocol-jubjub] `Zcash Protocol Specification, Version 2020.1.15. Section 5.4.8.3: Jubjub <protocol/protocol.pdf#jubjub>`_
.. [#jubjub-crate] `jubjub Rust crate <https://crates.io/crates/jubjub>`_
.. [#protocol] `Zcash Protocol Specification, Version 2021.1.17 or later [Orchard proposal] <protocol/orchard.pdf>`_
.. [#protocol-spenddesc] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 4.4: Spend Descriptions <protocol/orchard.pdf#spenddesc>`_
.. [#protocol-outputdesc] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 4.5: Output Descriptions <protocol/orchard.pdf#outputdesc>`_
.. [#protocol-decryptovk] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 4.19.3 Decryption using a Full Viewing Key (Sapling and Orchard) <protocol/orchard.pdf#decryptovk>`_
.. [#protocol-jubjub] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 5.4.8.3: Jubjub <protocol/orchard.pdf#jubjub>`_
.. [#protocol-pallasandvesta] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 5.4.8.6: Pallas and Vesta <protocol/orchard.pdf#pallasandvesta>`_
.. [#protocol-saplingpaymentaddrencoding] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 5.6.4: Sapling Payment Addresses <protocol/orchard.pdf#saplingpaymentaddrencoding>`_
.. [#protocol-saplingfullviewingkeyencoding] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 5.6.7: Sapling Full Viewing Keys <protocol/orchard.pdf#saplingfullviewingkeyencoding>`_
.. [#protocol-txnencodingandconsensus] `Zcash Protocol Specification, Version 2021.1.17 [Orchard proposal]. Section 7.1: Transaction Encoding and Consensus <protocol/orchard.pdf#txnencodingandconsensus>`_
.. [#zip-0032-extfvk] `ZIP 32: Shielded Hierarchical Deterministic Wallets. Sapling extended full viewing keys <zip-0032.rst#sapling-extended-full-viewing-keys>`_
.. [#zip-0200] `ZIP 200: Network Upgrade Activation Mechanism <zip-0200.rst>`_
.. [#zip-0215] `ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules <zip-0215.rst>`_
.. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade <zip-0251.rst>`_
.. [#jubjub-crate] `jubjub Rust crate <https://crates.io/crates/jubjub>`_