Skip to content

Commit

Permalink
ZIP 231: rendering fixes.
Browse files Browse the repository at this point in the history
Signed-off-by: Daira-Emma Hopwood <daira@katava.local>
  • Loading branch information
Daira-Emma Hopwood authored and nuttycom committed Nov 5, 2024
1 parent ff885d3 commit 2c9772f
Showing 1 changed file with 55 additions and 28 deletions.
83 changes: 55 additions & 28 deletions zips/zip-0231.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
> ZIP: 231
> Title: Memo Bundles
> Owners: Jack Grigg <jack@electriccoin.co>
> Kris Nuttycombe <kris@electriccoin.co>
> Daira-Emma Hopwood <daira@electriccoin.co>
> Arya Solhi <arya@zfnd.org>
> Credits: Sean Bowe
> Nate Wilcox
> Status: Draft
> Category: Consensus / Wallet
> Created: 2024-04-26
> License: MIT
ZIP: 231
Title: Memo Bundles
Owners: Jack Grigg <jack@electriccoin.co>
Kris Nuttycombe <kris@electriccoin.co>
Daira-Emma Hopwood <daira@electriccoin.co>
Arya Solhi <arya@zfnd.org>
Credits: Sean Bowe
Nate Wilcox
Status: Draft
Category: Consensus / Wallet
Created: 2024-04-26
License: MIT


# Terminology
Expand Down Expand Up @@ -105,7 +105,7 @@ to both Sapling and Orchard outputs.

## Changes to the Zcash Protocol Specification

The following changes are to be made affecting note plaintexts, note ciphertexts,
The following changes affecting the definitions of note plaintexts and note ciphertexts,
and the algorithms for encryption and decryption.

In § 3.2.1 ‘Note Plaintexts and Memo Fields’:
Expand Down Expand Up @@ -139,8 +139,9 @@ In § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ [^protocol-notepten

> The encoding of a v6-onward Sapling or Orchard note plaintext consists of:
>
> |---------------------------|---------------------|--------------------------|-----------------------------|
> | 8-bit $\mathsf{leadByte}$ | 88-bit $\mathsf{d}$ | 256-bit $\mathsf{rseed}$ | 32-byte $\mathsf{K^{memo}}$ |
> | | | | | |
> |---------------------------|---------------------|---------------------|--------------------------|-----------------------------|
> | 8-bit $\mathsf{leadByte}$ | 88-bit $\mathsf{d}$ | 64-bit $\mathsf{v}$ | 256-bit $\mathsf{rseed}$ | 32-byte $\mathsf{K^{memo}}$ |
>
> * A byte 0x03, indicating this version of the encoding of a v6-onward
> Sapling or Orchard note plaintext.
Expand Down Expand Up @@ -188,8 +189,8 @@ In § 4.20.1 ‘Encryption (Sapling and Orchard)’ [^protocol-saplingandorchard
> * $\mathsf{C^{enc}}$ will be of length either 580 or 100 bytes, depending on whether
> $\mathbf{np}$ is a pre-v6 or v6-onward note plaintext.
In § 4.20.2 ‘Decryption using an Incoming Viewing Key (Sapling and Orchard)’ and
§ 4.20.3 ‘Decryption using a full Incoming Viewing Key (Sapling and Orchard)’:
In § 4.20.2 ‘Decryption using an Incoming Viewing Key (Sapling and Orchard)’ [^protocol-decryptivk]
and § 4.20.3 ‘Decryption using a Full Viewing Key (Sapling and Orchard)’ [^protocol-decryptovk]:

* Replace $\mathsf{memo} ⦂ \mathbb{B^{Y[512]}}$ with $\mathsf{memoOrKey}$.
* Specify that the type of $\mathsf{memoOrKey}$ is $\mathbb{B^{Y[512]}}$ when
Expand Down Expand Up @@ -228,7 +229,7 @@ A new salt MUST be generated for each memo bundle.

The symmetric encryption key for a memo is derived from its $\mathsf{K^{memo}}$ as follows:

$$\mathsf{encryption\_key} = \mathsf{PRF^{expand}_{K^{memo}}}([\mathtt{0xE0}] \,||\, \mathsf{salt})$$
$\hspace{2em}\mathsf{encryption\_key} = \mathsf{PRF^{expand}_{K^{memo}}}([\mathtt{0xE0}] \,||\, \mathsf{salt})$

The first byte $\mathtt{0xE0}$ should be added to the documentation of inputs to
$\mathsf{PRF^{expand}}$ in § 4.1.2 ‘Pseudo Random Functions’ [^protocol-abstractprfs].
Expand All @@ -239,14 +240,15 @@ misinterpreting the output as having no memo data. Since that has negligible
probability, it alternatively MAY omit this check.

Each memo is padded to a multiple of 256 bytes with zeroes, and split into
256-byte chunks. Each memo chunk is encrypted with ChaCha20Poly1305 [^rfc-7539] as
follows:
256-byte chunks. Each memo chunk is encrypted with ChaCha20Poly1305 [^rfc-8439]
as follows:

$$\mathsf{IETF\_AEAD\_CHACHA20\_POLY1305}(\mathsf{encryption\_key}, \mathsf{nonce}, \mathsf{memo\_chunk})$$
$\hspace{2em}\mathsf{IETF\_AEAD\_CHACHA20\_POLY1305}(\mathsf{encryption\_key}, \mathsf{nonce}, \mathsf{memo\_chunk})$

where $\mathsf{nonce} = \mathsf{I2BEOSP}_{88}(\mathsf{counter}) || [\mathsf{final\_chunk}]\!$.

This is a variant of the STREAM construction [^stream].

- $\mathsf{counter}$ is a big-endian chunk counter starting at zero and incrementing by
one for each subsequent chunk within a particular memo.
- $\mathsf{final\_chunk}$ is the byte $\mathtt{0x01}$ for the final memo chunk, and
Expand All @@ -270,8 +272,8 @@ memos:
```
## Memo decryption

When a recipient decrypts a shielded output, they obtain a `memo_key`. From this
they derive `encryption_key` as above, and then proceed as follows:
When a recipient decrypts a shielded output, they obtain a memo key $\mathsf{K^{memo}}$.
From this they derive `encryption_key` as above, and then proceed as follows:

- Set `counter = 0` and `final_chunk = 0x00`.
- Attempt to decrypt each memo chunk in order. Pruned memo chunks are skipped.
Expand Down Expand Up @@ -314,6 +316,7 @@ If `fAllPruned == 0`, then:
contains the `memo_chunk_digest` for a pruned chunk.

If `fAllPruned == 1`, then:

- `nonceOrHash` represents the overall hash for the memo bundle as defined in
[Transaction sighash].
- The `nMemoChunks`, `pruned`, and `vMemoChunks` fields will be absent.
Expand All @@ -325,7 +328,7 @@ memo_chunk_digest = H(AEAD(MemoChunk, memo_key))
memo_bundle_digest = H(concat(memo_chunk_digests))
```

The memo bundle digest structure is a performance optimisation for the case
The memo bundle digest structure is a performance optimization for the case
where all memo chunks in a transaction have been pruned.

TODO: finish this to be a modification to the equivalent of ZIP 244 for
Expand Down Expand Up @@ -375,8 +378,9 @@ maximum number of unique memos you can create, and the cost in bytes of that
memo data plus auth when using a 32-byte memo key, is:

| | Memo size |
| Chunk size | ≤ 256 bytes | 512 bytes |
|------------|----------------------|----------------------|
| Chunk size | ≤ 256 bytes | 512 bytes |
|============|======================|======================|
| Pre-231 | 20 @ 10240 ( 0.00%) | 20 @ 10240 ( 0.00%) |
| 512 | 20 @ 11220 (+ 9.57%) | 20 @ 11220 (+ 9.57%) |
| 256 | 40 @ 12200 (+19.14%) | 20 @ 11540 (+12.70%) |
Expand All @@ -395,8 +399,9 @@ If we used a 16-byte memo key instead of 32 bytes, the transaction size overhead
becomes:

| | Memo size |
| Chunk size | ≤ 256 bytes | 512 bytes |
|------------|----------------------|----------------------|
| Chunk size | ≤ 256 bytes | 512 bytes |
|============|======================|======================|
| Pre-231 | 20 @ 10240 ( 0.00%) | 20 @ 10240 ( 0.00%) |
| 512 | 20 @ 10900 (+ 6.45%) | 20 @ 10900 (+ 6.45%) |
| 256 | 40 @ 11560 (+12.89%) | 20 @ 11220 (+ 9.57%) |
Expand All @@ -409,6 +414,7 @@ However, 128-bit keys don't meet Zcash's target security level of 125 bits,
as argued in [^protocol-inbandrationale].

The benefits of 256-bit keys are:

- They incur only a small transaction size overhead above the minimum key size
that _would_ meet the target security level.
- This key length matches what we already use elsewhere for symmetric keys.
Expand All @@ -426,6 +432,7 @@ get a nonsensical and potentially insecure "spliced" memo).

We do not include commitments to the shielded outputs in the derivation of
$\mathsf{encryption_key}$ for two reasons:

- It would force the transaction builder to fully define all shielded outputs
before encrypting the memos, which might prevent potential use cases of PCZTs [^pczt].
- We don't want to unnecessarily prevent the ability to create a transaction
Expand Down Expand Up @@ -485,12 +492,32 @@ TBD

[^BCP14]: [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"](https://www.rfc-editor.org/info/bcp14)

[^protocol-noteptconcept]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.2.1: Note Plaintexts and Memo Fields](protocol/protocol.pdf)
[^protocol]: [Zcash Protocol Specification, Version 2024.5.1 [NU6] or later](protocol/protocol.pdf)

[^protocol-noteptconcept]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.2.1: Note Plaintexts and Memo Fields](protocol/protocol.pdf#noteptconcept)

[^protocol-abstractprfs]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.1.2: Pseudo Random Functions](protocol/protocol.pdf#abstractprfs)

[^protocol-saplingsend]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.2: Sending Notes (Sapling)](protocol/protocol.pdf#saplingsend)

[^protocol-orchardsend]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.3: Sending Notes (Orchard)](protocol/protocol.pdf#orchardsend)

[^protocol-saplingandorchardinband]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.1: Encryption (Sapling and Orchard)](protocol/protocol.pdf#saplingandorchardinband)

[^protocol-decryptivk]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.2: Decryption using an Incoming Viewing Key (Sapling and Orchard)](protocol/protocol.pdf#decryptivk)

[^protocol-decryptovk]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.3: Decryption using a Full Viewing Key (Sapling and Orchard)](protocol/protocol.pdf#decryptovk)

[^protocol-noteptencoding]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.5: Encodings of Note Plaintexts and Memo Fields](protocol/protocol.pdf#noteptencoding)

[^protocol-inbandrationale]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 8.7: In-band secret distribution](protocol/protocol.pdf#inbandrationale)

[^stream]: [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance](https://eprint.iacr.org/2015/189)

[^zip-0307]: [ZIP 307: Light Client Protocol for Payment Detection](zip-0307.rst)

[^zip-0317]: [ZIP 317: Proportional Transfer Fee Mechanism](zip-0317.rst)

[^pczt]: [zcash/zips issue #693: Standardize a protocol for creating shielded transactions offline](https://github.com/zcash/zips/issues/693)
[^pczt]: [zcash/zips issue #693: Standardize a protocol for creating shielded transactions offline](https://github.com/zcash/zips/issues/693)

[^rfc-8439] [RFC 8439: ChaCha20 and Poly1305 for IETF Protocols](https://www.rfc-editor.org/rfc/rfc8439.html)

0 comments on commit 2c9772f

Please sign in to comment.