mirror of https://github.com/zcash/zips.git
792 lines
45 KiB
HTML
792 lines
45 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>ZIP 231: Memo Bundles</title>
|
||
<meta charset="utf-8" />
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
|
||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script>
|
||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="css/style.css">
|
||
</head>
|
||
<body>
|
||
<pre><code>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
|
||
Discussions-To: <<a href="https://github.com/zcash/zips/issues/627">https://github.com/zcash/zips/issues/627</a>>
|
||
</code></pre>
|
||
|
||
<h1 id="terminology"><span class="section-heading">Terminology</span><span class="section-anchor"> <a rel="bookmark" href="#terminology"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<p>The key words “MUST”, “MUST NOT”, “SHOULD”, and “MAY” in this document are to
|
||
be interpreted as described in BCP 14 <a href="#fn:1" id="fnref:1" title="see footnote" class="footnote"><sup>1</sup></a> when, and only when, they appear
|
||
in all capitals.</p>
|
||
|
||
<p>The term “network upgrade” in this document is to be interpreted as described in
|
||
ZIP 200. <a href="#fn:2" id="fnref:2" title="see footnote" class="footnote"><sup>2</sup></a></p>
|
||
|
||
<p>The character § is used when referring to sections of the Zcash Protocol
|
||
Specification. <a href="#fn:3" id="fnref:3" title="see footnote" class="footnote"><sup>3</sup></a></p>
|
||
|
||
<p>The terms “Mainnet” and “Testnet” are to be interpreted as described in
|
||
§ 3.12 ‘Mainnet and Testnet’. <a href="#fn:4" id="fnref:4" title="see footnote" class="footnote"><sup>4</sup></a></p>
|
||
|
||
<h1 id="abstract"><span class="section-heading">Abstract</span><span class="section-anchor"> <a rel="bookmark" href="#abstract"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<p>Currently, the memo sent in a shielded output is limited to at most 512 bytes.
|
||
This ZIP proposes to allow larger memos, and to enable memo data to be shared
|
||
between multiple recipients of a transaction.</p>
|
||
|
||
<h1 id="motivation"><span class="section-heading">Motivation</span><span class="section-anchor"> <a rel="bookmark" href="#motivation"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<p>In Zcash transaction versions v2 to v5 inclusive, each Sapling or Orchard
|
||
shielded output contains a ciphertext comprised of a 52-byte note plaintext,
|
||
and a corresponding 512-byte memo field. <a href="#fn:5" id="fnref:5" title="see footnote" class="footnote"><sup>5</sup></a> Recipients
|
||
can only decrypt the outputs sent to them, and thus can also only observe the
|
||
memo fields included with the outputs they can decrypt.</p>
|
||
|
||
<p>The shielded transaction protocol hides the sender(s) (that is, the addresses
|
||
corresponding to the keys used to spend the input notes) from all of the
|
||
recipients. For certain kinds of transactions, it is desirable to make one or
|
||
more sender addresses available to one or more recipients (for example, a reply
|
||
address). In such circumstances it is important to authenticate the sender
|
||
addresses, to give the recipient a guarantee that the address is controlled by
|
||
a sender of the transaction; failure to authenticate this address can enable
|
||
phishing attacks. These Authenticated Reply Addresses require zero-knowledge
|
||
proofs, and for the Orchard protocol these proofs are too large to fit into a
|
||
512-byte memo field.</p>
|
||
|
||
<p>It is also desirable, for clients with more stringent bandwidth constraints,
|
||
to be able to transmit encrypted notes to the client without including the
|
||
encrypted memo data. In the current light client protocol <a href="#fn:6" id="fnref:6" title="see footnote" class="footnote"><sup>6</sup></a>, this
|
||
is done by truncating the note ciphertext to just the part that encrypts the
|
||
memo. However, that has the effect of truncating the authentication tag, and
|
||
so the resulting decryption algorithm does not meet standard security notions
|
||
for an authenticated encryption scheme. It is a goal of this proposal to
|
||
rectify this, simplifying the security argument.</p>
|
||
|
||
<p>Instead of the memo data, this ZIP proposes that it is possible to indicate whether
|
||
a memo is present for the recipient. When using the light client protocol, a recipient
|
||
need not download full transaction information if this indication tells them that they
|
||
have not received any memo in the transaction.</p>
|
||
|
||
<p>At present, it is not possible to transmit the same memo data to multiple
|
||
transaction recipients without redundantly encoding that data, and sending
|
||
memo data greater than 512 bytes requires sending multiple outputs; the
|
||
problem is compounded when attempting to send more than 512 bytes to each
|
||
recipient. By separating memo data from the decryption capability for those
|
||
memos, it admits a greater variety of applications that utilize memo data,
|
||
while decreasing the amount of data that needs to be stored on-chain overall.</p>
|
||
|
||
<h1 id="privacyimplications"><span class="section-heading">Privacy Implications</span><span class="section-anchor"> <a rel="bookmark" href="#privacyimplications"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<p>Prior to the activation of this ZIP, every shielded output has an associated
|
||
memo field. A chain observer can therefore infer a likely 1:1 correlation
|
||
between transaction recipients and memo payloads. The maximum number of
|
||
distinct memos is precisely known, and the bounds on possible memo sizes are
|
||
very small (between 0 and 512 bytes). It is possible to send additional data to
|
||
a single recipient by adding (potentially zero-valued) outputs; on-chain this is
|
||
indistinguishable from sending more memos to more recipients or (in the case of
|
||
Orchard) spending more input notes.</p>
|
||
|
||
<p>After the activation of this ZIP, recipient count and memo count are decoupled.
|
||
It becomes possible to construct transactions for which there are many more
|
||
recipients than distinct memos, or vice versa. This may result in more observably
|
||
distinct patterns relating the number of recipients to the number of possible
|
||
memos. One important example is that if a wallet includes an authenticated
|
||
reply-to address, this may be distinguishable from other ordinary wallet
|
||
behaviour.</p>
|
||
|
||
<p>On the flip side, a chain observer now only knows upper bounds on the amount
|
||
of memo data being conveyed, and the number of possible distinct memos.
|
||
They have no information about how memo data is split among the recipients.
|
||
This can provide a privacy improvement in some situations. For example, it is
|
||
not possible to distinguish between many recipients receiving many small
|
||
memos, and the same set of recipients receiving one large shared memo.</p>
|
||
|
||
<p>In summary, when sending large amounts of memo data, the change introduced by
|
||
this ZIP eliminates a potential distinguisher along one axis in exchange for a
|
||
potential distinguisher along another.</p>
|
||
|
||
<h1 id="requirements"><span class="section-heading">Requirements</span><span class="section-anchor"> <a rel="bookmark" href="#requirements"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<ul>
|
||
<li>Recipients can receive memo data that is greater than 512 bytes in length.</li>
|
||
<li>Multiple recipients, across any of the shielded pools, can be given the
|
||
capability to view the same memo data.</li>
|
||
<li>The exact number and exact lengths of distinct decryptable memos should not
|
||
be revealed, even to the transaction recipients, although an upper bound on
|
||
the total length of memo data that the observer does not have the capability
|
||
to view will be leaked to transaction recipients, and the overall maximum
|
||
possible length of memo data will be revealed on-chain.</li>
|
||
<li>A recipient can determine whether or not they have been given the capability
|
||
to view any memo solely by decrypting the note ciphertext.</li>
|
||
<li>Memo chunks within a transaction can be individually pruned from block storage
|
||
without preventing the transaction from being verified when transmitting block
|
||
data to peers.</li>
|
||
<li>The ciphertext of the note alone can be decrypted using a scheme that meets
|
||
a standard security notion for authenticated encryption, without more than a
|
||
small constant overhead in ciphertext size.</li>
|
||
</ul>
|
||
|
||
<h1 id="non-requirements"><span class="section-heading">Non-requirements</span><span class="section-anchor"> <a rel="bookmark" href="#non-requirements"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<ul>
|
||
<li>Recipients do not need to be able to receive multiple memos per note. This
|
||
capability can however be enabled under the existing proposal by “chaining”
|
||
memos, including the decryption key for another memo within the memo that
|
||
is decryptable by a recipient.</li>
|
||
</ul>
|
||
|
||
<h1 id="specification"><span class="section-heading">Specification</span><span class="section-anchor"> <a rel="bookmark" href="#specification"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<p>Since this proposal is defined only for v6 and later transactions, it is not
|
||
necessary to consider Sprout JoinSplit outputs. The following sections apply
|
||
to both Sapling and Orchard outputs.</p>
|
||
|
||
<h2 id="memobundle"><span class="section-heading">Memo bundle</span><span class="section-anchor"> <a rel="bookmark" href="#memobundle"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>A memo bundle consists of a sequence of 256-byte memo chunks, each individually
|
||
encrypted. These memo chunks represent zero or more encrypted memos.</p>
|
||
|
||
<p>Each transaction may contain a single memo bundle, and a memo bundle may contain
|
||
at most <span class="math">\(\mathsf{memo\_chunk\_limit}\)</span> = 64 memo chunks. This limits the total amount
|
||
of memo data that can be conveyed within a single transaction to
|
||
<span class="math">\(\mathsf{memo\_chunk\_limit}\)</span> × 256 = 16384 bytes, or 16 KiB.</p>
|
||
|
||
<p>Memo bundles are encoded in transactions in a prunable manner: each memo chunk
|
||
can be replaced by its representative digest.</p>
|
||
|
||
<h2 id="memoencryption"><span class="section-heading">Memo encryption</span><span class="section-anchor"> <a rel="bookmark" href="#memoencryption"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>During transaction construction, each output with memo data is assigned a 32-byte
|
||
memo key <span class="math">\(\mathsf{K^{memo}}\)</span>. These keys SHOULD be generated randomly, and MUST NOT
|
||
be used to encrypt more than one memo within a single transaction. If an output has
|
||
no memo data, it is assigned the memo key consisting of 32 <span class="math">\(\mathtt{0xFF}\)</span> bytes.</p>
|
||
|
||
<p>In note plaintexts of v6-onward transactions, the 512-byte memo field is replaced
|
||
by <span class="math">\(\mathsf{K^{memo}}\)</span>.</p>
|
||
|
||
<p>The transaction builder generates a 32-byte salt value <span class="math">\(\mathsf{salt}\)</span> from a CSPRNG.
|
||
A new salt MUST be generated for each memo bundle.</p>
|
||
|
||
<p>The symmetric encryption key for a memo is derived from its <span class="math">\(\mathsf{K^{memo}}\)</span> as follows:</p>
|
||
|
||
<p><span class="math">\(\hspace{2em}\mathsf{encryptionKey} = \mathsf{PRF^{expand}_{K^{memo}}}([\mathtt{0xE0}] \,||\, \mathsf{salt})\)</span></p>
|
||
|
||
<p>The first byte <span class="math">\(\mathtt{0xE0}\)</span> should be added to the documentation of inputs to
|
||
<span class="math">\(\mathsf{PRF^{expand}}\)</span> in § 4.1.2 ‘Pseudo Random Functions’ <a href="#fn:7" id="fnref:7" title="see footnote" class="footnote"><sup>7</sup></a>.</p>
|
||
|
||
<p>If the generated key is 32 <span class="math">\(\mathtt{0xFF}\)</span> bytes, the transaction constructor MAY
|
||
repeat this procedure with a different salt, in order to avoid the recipient
|
||
misinterpreting the output as having no memo data. Since that has negligible
|
||
probability, it alternatively MAY omit this check.</p>
|
||
|
||
<p>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 <a href="#fn:8" id="fnref:8" title="see footnote" class="footnote"><sup>8</sup></a>
|
||
as follows:</p>
|
||
|
||
<p><span class="math">\(\hspace{2em}\mathsf{IETF\_AEAD\_CHACHA20\_POLY1305}(\mathsf{encryptionKey}, \mathsf{nonce}, \mathsf{memo\_chunk})\)</span></p>
|
||
|
||
<p>where <span class="math">\(\mathsf{nonce} = \mathsf{I2BEOSP}_{88}(\mathsf{counter}) \,||\, [\mathsf{final\_chunk}]\)</span>.</p>
|
||
|
||
<p>This is a variant of the STREAM construction <a href="#fn:9" id="fnref:9" title="see footnote" class="footnote"><sup>9</sup></a>.</p>
|
||
|
||
<ul>
|
||
<li><span class="math">\(\mathsf{counter}\)</span> is a big-endian chunk counter starting at zero and incrementing
|
||
by one for each subsequent chunk within a particular memo.</li>
|
||
<li><span class="math">\(\mathsf{final\_chunk}\)</span> is the byte <span class="math">\(\mathtt{0x01}\)</span> for the final memo chunk, and
|
||
<span class="math">\(\mathtt{0x00}\)</span> for all preceding chunks.</li>
|
||
</ul>
|
||
|
||
<p>Finally, the encrypted memo chunks for all memos are combined into a single
|
||
sequence using an order-preserving shuffle. Memo chunks from different memos MAY
|
||
be interleaved in any order, but memo chunks from the same memo MUST have the
|
||
same relative order. The following diagram shows an example shuffle of three
|
||
memos:</p>
|
||
|
||
<pre><code>[
|
||
(memo_a, 0),
|
||
(memo_b, 0),
|
||
(memo_a, 1),
|
||
(memo_c, 0),
|
||
(memo_c, 1),
|
||
(memo_a, 2),
|
||
]
|
||
</code></pre>
|
||
|
||
<h2 id="memodecryption"><span class="section-heading">Memo decryption</span><span class="section-anchor"> <a rel="bookmark" href="#memodecryption"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>When a recipient decrypts a shielded output, they obtain a memo key <span class="math">\(\mathsf{K^{memo}}\)</span>.
|
||
From this they derive <code>encryption_key</code> as above, and then proceed as follows:</p>
|
||
|
||
<p><span class="math">\(\hspace{1.5em}\)</span> let mutable <span class="math">\(\mathsf{memo} \;{\small ⦂}\; \mathbb{N} \leftarrow 0 \\\)</span>
|
||
<span class="math">\(\hspace{1.5em}\)</span> let mutable <span class="math">\(\mathsf{counter} \;{\small ⦂}\; \mathbb{N} \leftarrow 0 \\\)</span>
|
||
<span class="math">\(\hspace{1.5em}\)</span> let mutable <span class="math">\(\mathsf{potential\_last\_chunk} \;{\small ⦂}\; \mathbb{N} \leftarrow 0 \\\)</span>
|
||
<span class="math">\(\hspace{1.5em}\)</span> for <span class="math">\(i\)</span> from <span class="math">\(0\)</span> up to <span class="math">\(\mathsf{len}(\mathsf{memo\_chunks})-1\)</span>: <span class="math">\(\\\)</span>
|
||
<span class="math">\(\hspace{3.0em}\)</span> if <span class="math">\(\mathsf{memo\_chunks}[i]\)</span> is not pruned: <span class="math">\(\\\)</span>
|
||
<span class="math">\(\hspace{4.5em}\)</span> let <span class="math">\(\mathsf{nonce} = \mathsf{I2BEOSP}_{88}(\mathsf{counter}) \,||\, [\mathtt{0x00}] \\\)</span>
|
||
<span class="math">\(\hspace{4.5em}\)</span> let <span class="math">\(P = \mathsf{IETF\_AEAD\_CHACHA20\_POLY1305.Decrypt}(\mathsf{encryptionKey}, \mathsf{nonce}, \mathsf{memo\_chunks}[i]) \\\)</span>
|
||
<span class="math">\(\hspace{4.5em}\)</span> if <span class="math">\(P \neq \bot\)</span>: <span class="math">\(\\\)</span>
|
||
<span class="math">\(\hspace{6.0em}\)</span> set <span class="math">\(\mathsf{memo} \leftarrow \mathsf{memo} \,||\, P \\\)</span>
|
||
<span class="math">\(\hspace{6.0em}\)</span> set <span class="math">\(\mathsf{counter} \leftarrow \mathsf{counter} + 1 \\\)</span>
|
||
<span class="math">\(\hspace{6.0em}\)</span> set <span class="math">\(\mathsf{potential\_last\_chunk} \leftarrow i + 1 \\\)</span>
|
||
<span class="math">\(\,\\\)</span>
|
||
<span class="math">\(\hspace{1.5em}\)</span> let <span class="math">\(\mathsf{nonce} = \mathsf{I2BEOSP}_{88}(\mathsf{counter}) \,||\, [\mathtt{0x01}] \\\)</span>
|
||
<span class="math">\(\hspace{1.5em}\)</span> let mutable <span class="math">\(\mathsf{success} \leftarrow \kern0.05em\)</span> false <span class="math">\(\\\)</span>
|
||
<span class="math">\(\hspace{1.5em}\)</span> for <span class="math">\(i\)</span> from <span class="math">\(0\)</span> up to <span class="math">\(\mathsf{len}(\mathsf{memo\_chunks})-1\)</span>: <span class="math">\(\\\)</span>
|
||
<span class="math">\(\hspace{3.0em}\)</span> if <span class="math">\(\mathsf{memo\_chunks}[i]\)</span> is not pruned: <span class="math">\(\\\)</span>
|
||
<span class="math">\(\hspace{4.5em}\)</span> let <span class="math">\(P = \mathsf{IETF\_AEAD\_CHACHA20\_POLY1305.Decrypt}(\mathsf{encryptionKey}, \mathsf{nonce}, \mathsf{memo\_chunks}[i]) \\\)</span>
|
||
<span class="math">\(\hspace{4.5em}\)</span> if <span class="math">\(i \geq \mathsf{potential\_last\_chunk}\)</span> and <span class="math">\(P \neq \bot\)</span> and not <span class="math">\(\mathsf{success}\)</span>: <span class="math">\(\\\)</span>
|
||
<span class="math">\(\hspace{6.0em}\)</span> set <span class="math">\(\mathsf{memo} \leftarrow \mathsf{memo} \,||\, P \\\)</span>
|
||
<span class="math">\(\hspace{6.0em}\)</span> set <span class="math">\(\mathsf{success} \leftarrow \kern0.05em\)</span> true <span class="math">\(\\\)</span>
|
||
<span class="math">\(\,\\\)</span>
|
||
<span class="math">\(\hspace{1.5em}\)</span> if <span class="math">\(\mathsf{success}\)</span> then return <span class="math">\(\mathsf{memo}\)</span> else return <span class="math">\(\bot \\\)</span></p>
|
||
|
||
<p>If any chunk of the memo encrypted to <span class="math">\(\mathsf{encryptionKey}\)</span> has been pruned, the decryption
|
||
process above returns nothing (as <span class="math">\(\mathsf{final_chunk}\)</span> will be set to <span class="math">\(\mathtt{0x01}\)</span> with the
|
||
wrong counter value), ensuring that a malformed memo is not returned.</p>
|
||
|
||
<h2 id="encodingintransactions"><span class="section-heading">Encoding in transactions</span><span class="section-anchor"> <a rel="bookmark" href="#encodingintransactions"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<table>
|
||
<colgroup>
|
||
<col />
|
||
<col />
|
||
<col />
|
||
<col />
|
||
</colgroup>
|
||
|
||
<thead>
|
||
<tr>
|
||
<th> Bytes </th>
|
||
<th> Name </th>
|
||
<th> Data Type </th>
|
||
<th> Description </th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
<tr>
|
||
<td> 1 </td>
|
||
<td> <code>fAllPruned</code> </td>
|
||
<td> <code>uint8</code> </td>
|
||
<td> 1 if all chunks have been pruned, otherwise 0. </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 32 </td>
|
||
<td> <code>nonceOrHash</code> </td>
|
||
<td> <code>byte[32]</code> </td>
|
||
<td> The nonce for deriving encryption keys, or the overall hash. </td>
|
||
</tr>
|
||
<tr>
|
||
<td> † varies </td>
|
||
<td> <code>nMemoChunks</code> </td>
|
||
<td> <code>compactSize</code> </td>
|
||
<td> The number of memo chunks. </td>
|
||
</tr>
|
||
<tr>
|
||
<td> † varies </td>
|
||
<td> <code>pruned</code> </td>
|
||
<td> <code>byte[</code><span class="math">\(\mathsf{ceiling}(\mathtt{nMemoChunks}/8)\)</span><code>]</code> </td>
|
||
<td> Bitflags indicating the type of each entry in <code>vMemoChunks</code>. </td>
|
||
</tr>
|
||
<tr>
|
||
<td> † varies </td>
|
||
<td> <code>vMemoChunks</code> </td>
|
||
<td> <code>MemoChunk[nMemoChunks]</code> </td>
|
||
<td> A sequence of encrypted memo chunks. </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>† These fields are present if and only if <code>fAllPruned == 0</code>.</p>
|
||
|
||
<p>If <code>fAllPruned == 0</code>, then:</p>
|
||
|
||
<ul>
|
||
<li><code>nonceOrHash</code> represents the nonce for deriving encryption keys.</li>
|
||
<li>Each bit of <code>pruned</code>, in little-endian order, indicates the type of the
|
||
corresponding entry in <code>vMemoChunks</code>. A bit value of 0 indicates that
|
||
the entry will be of type <code>byte[272]</code> representing an encrypted memo
|
||
chunk. A bit value of 1 indicates the entry will be a <code>byte[32]</code> and
|
||
contains the <code>memo_chunk_digest</code> for a pruned chunk.</li>
|
||
</ul>
|
||
|
||
<p>If <code>fAllPruned == 1</code>, then:</p>
|
||
|
||
<ul>
|
||
<li><code>nonceOrHash</code> represents the overall hash for the memo bundle as defined in
|
||
<a href="#transactionsighash">Transaction sighash</a>.</li>
|
||
<li>The <code>nMemoChunks</code>, <code>pruned</code>, and <code>vMemoChunks</code> fields will be absent.</li>
|
||
</ul>
|
||
|
||
<h2 id="transactionsighash"><span class="section-heading">Transaction sighash</span><span class="section-anchor"> <a rel="bookmark" href="#transactionsighash"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<pre><code>memo_chunk_digest = H(AEAD(MemoChunk, memo_key))
|
||
memo_bundle_digest = H(concat(memo_chunk_digests))
|
||
</code></pre>
|
||
|
||
<p>The memo bundle digest structure is a performance optimization for the case
|
||
where all memo chunks in a transaction have been pruned.</p>
|
||
|
||
<p>TODO: finish this to be a modification to the equivalent of ZIP 244 for
|
||
transaction v6.</p>
|
||
|
||
<h2 id="changestozip317zip-0317">Changes to ZIP 317 <a href="#fn:10" id="fnref:10" title="see footnote" class="footnote"><sup>10</sup></a></h2>
|
||
|
||
<p>The conventional fee in ZEC is altered such that a memo bundle may contain two
|
||
free chunks if there are any shielded outputs in the transaction. Any memo chunk
|
||
beyond this requires <code>marginal_fee</code>. See the Fee calculation section of ZIP 317
|
||
<a href="#fn:11" id="fnref:11" title="see footnote" class="footnote"><sup>11</sup></a> for details.</p>
|
||
|
||
<h2 id="networkprotocol"><span class="section-heading">Network protocol</span><span class="section-anchor"> <a rel="bookmark" href="#networkprotocol"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>Nodes must reject <code>GetData</code> responses having an <code>fAllPruned</code> value that is nonzero,
|
||
or any byte of <code>pruned</code> that is nonzero.</p>
|
||
|
||
<h2 id="changestothezcashprotocolspecification"><span class="section-heading">Changes to the Zcash Protocol Specification</span><span class="section-anchor"> <a rel="bookmark" href="#changestothezcashprotocolspecification"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>The following changes affecting the definitions of note plaintexts and note ciphertexts,
|
||
and the algorithms for encryption and decryption.</p>
|
||
|
||
<p>In § 3.2.1 ‘Note Plaintexts and Memo Fields’:</p>
|
||
|
||
<ul>
|
||
<li><p>Change</p>
|
||
|
||
<blockquote>
|
||
<p>Each Sapling or Orchard note plaintext (denoted <span class="math">\(\mathbf{np}\)</span>) consists of</p>
|
||
|
||
<p><span class="math">\(\hspace{2em}(\mathsf{leadByte} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}}, \mathsf{d} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{rseed} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[32]}, \mathsf{memo} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]})\)</span></p>
|
||
</blockquote>
|
||
|
||
<p>to</p>
|
||
|
||
<blockquote>
|
||
<p>The form of a Sapling or Orchard note plaintext depends on the version of
|
||
the transaction in which it will be included; specifically whether that
|
||
version is pre-v6, or v6-onward.</p>
|
||
|
||
<p>Each pre-v6 Sapling or Orchard note plaintext (denoted <span class="math">\(\mathbf{np}\)</span>) consists of</p>
|
||
|
||
<p><span class="math">\(\hspace{2em}(\mathsf{leadByte} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}}, \mathsf{d} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{rseed} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[32]}, \mathsf{memo} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]})\)</span></p>
|
||
|
||
<p>Each v6-onward Sapling or Orchard note plaintext (denoted <span class="math">\(\mathbf{np}\)</span>) consists of</p>
|
||
|
||
<p><span class="math">\(\hspace{2em}(\mathsf{leadByte} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}}, \mathsf{d} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{rseed} \;⦂\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[32]}, \mathsf{K^{memo}} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]})\)</span></p>
|
||
</blockquote></li>
|
||
</ul>
|
||
|
||
<p>In § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ <a href="#fn:12" id="fnref:12" title="see footnote" class="footnote"><sup>12</sup></a>:</p>
|
||
|
||
<ul>
|
||
<li><p>Change the paragraph that describes “The encoding of a Sapling or Orchard note plaintext”
|
||
to refer to “The encoding of a pre-v6 Sapling or Orchard note plaintext”.</p></li>
|
||
<li><p>Add a new paragraph at the end of the section:</p>
|
||
|
||
<blockquote>
|
||
<p>The encoding of a v6-onward Sapling or Orchard note plaintext consists of:</p>
|
||
|
||
<p>| 8-bit <span class="math">\(\mathsf{leadByte}\)</span> | 88-bit <span class="math">\(\mathsf{d}\)</span> | 64-bit <span class="math">\(\mathsf{v}\)</span> | 256-bit <span class="math">\(\mathsf{rseed}\)</span> | 32-byte <span class="math">\(\mathsf{K^{memo}}\)</span> |</p>
|
||
|
||
<ul>
|
||
<li>A byte 0x03, indicating this version of the encoding of a v6-onward
|
||
Sapling or Orchard note plaintext.</li>
|
||
<li>11 bytes specifying <span class="math">\(\mathsf{d}\)</span>.</li>
|
||
<li>8 bytes specifying <span class="math">\(\mathsf{v}\)</span>.</li>
|
||
<li>32 bytes specifying <span class="math">\(\mathsf{rseed}\)</span>.</li>
|
||
<li>32 bytes specifying <span class="math">\(\mathsf{K^{memo}}\)</span>.</li>
|
||
</ul>
|
||
|
||
<p>A value consisting of 32 <span class="math">\(\mathtt{0xFF}\)</span> bytes for <span class="math">\(\mathsf{K^{memo}}\)</span> is used
|
||
to indicate that there is no memo for this note plaintext.</p>
|
||
</blockquote></li>
|
||
</ul>
|
||
|
||
<p>In § 4.7.2 ‘Sending Notes (Sapling)’ <a href="#fn:13" id="fnref:13" title="see footnote" class="footnote"><sup>13</sup></a> and
|
||
§ 4.7.3 ‘Sending Notes (Orchard)’ <a href="#fn:14" id="fnref:14" title="see footnote" class="footnote"><sup>14</sup></a>:</p>
|
||
|
||
<ul>
|
||
<li><p>Add a reference to this ZIP specifying the construction of the memo bundle and
|
||
derivation of <span class="math">\(\mathsf{K^{memo}}\)</span> in the case of a v6-onward note plaintext.</p></li>
|
||
<li><p>Change</p>
|
||
|
||
<blockquote>
|
||
<p>Let <span class="math">\(\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})\)</span>.</p>
|
||
</blockquote>
|
||
|
||
<p>to</p>
|
||
|
||
<blockquote>
|
||
<p>Let <span class="math">\(\mathbf{np}\)</span> be the encoding of a Sapling note plaintext using <span class="math">\(\mathsf{leadByte}\)</span>, <span class="math">\(\mathsf{d}\)</span>,
|
||
<span class="math">\(\mathsf{v}\)</span>, <span class="math">\(\mathsf{rseed}\)</span>, and either <span class="math">\(\mathsf{memo}\)</span> for a pre-v6 note plaintext or
|
||
<span class="math">\(\mathsf{K^{memo}}\)</span> for a v6-onward note plaintext.</p>
|
||
</blockquote>
|
||
|
||
<p>replacing “Sapling” with Orchard in the case of § 4.7.3.</p></li>
|
||
</ul>
|
||
|
||
<p>In § 4.20.1 ‘Encryption (Sapling and Orchard)’ <a href="#fn:15" id="fnref:15" title="see footnote" class="footnote"><sup>15</sup></a>:</p>
|
||
|
||
<ul>
|
||
<li><p>Change</p>
|
||
|
||
<blockquote>
|
||
<p>Let <span class="math">\(\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})\)</span>
|
||
be the Sapling or Orchard note plaintext. <span class="math">\(\mathbf{np}\)</span> is encoded as defined
|
||
in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’.</p>
|
||
</blockquote>
|
||
|
||
<p>to</p>
|
||
|
||
<blockquote>
|
||
<p>Let <span class="math">\(\mathbf{np}\)</span> be the encoding of the Sapling or Orchard note plaintext (which may be
|
||
pre-v6 or v6-onward), as defined in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’.</p>
|
||
</blockquote></li>
|
||
<li><p>Add another normative note to that section:</p>
|
||
|
||
<blockquote>
|
||
<ul>
|
||
<li><span class="math">\(\mathsf{C^{enc}}\)</span> will be of length either 580 or 100 bytes, depending on whether
|
||
<span class="math">\(\mathbf{np}\)</span> is a pre-v6 or v6-onward note plaintext.</li>
|
||
</ul>
|
||
</blockquote></li>
|
||
</ul>
|
||
|
||
<p>In § 4.20.2 ‘Decryption using an Incoming Viewing Key (Sapling and Orchard)’ <a href="#fn:16" id="fnref:16" title="see footnote" class="footnote"><sup>16</sup></a>
|
||
and § 4.20.3 ‘Decryption using a Full Viewing Key (Sapling and Orchard)’ <a href="#fn:17" id="fnref:17" title="see footnote" class="footnote"><sup>17</sup></a>:</p>
|
||
|
||
<ul>
|
||
<li>Replace <span class="math">\(\mathsf{memo} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]}\)</span> with
|
||
<span class="math">\(\mathsf{memoOrKey}\)</span>.</li>
|
||
<li>Specify that the type of <span class="math">\(\mathsf{memoOrKey}\)</span> is <span class="math">\(\mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]}\)</span>
|
||
when decrypting a pre-v6 note ciphertext, or <span class="math">\(\mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[32]}\)</span> when
|
||
decrypting a v6-onward note ciphertext. In the latter case, it is used as <span class="math">\(\mathsf{K^{memo}}\)</span>
|
||
to decrypt the memo bundle as described in <a href="#memobundle">Memo bundle</a>.</li>
|
||
</ul>
|
||
|
||
<h2 id="applicability"><span class="section-heading">Applicability</span><span class="section-anchor"> <a rel="bookmark" href="#applicability"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>All of these changes apply identically to Mainnet and Testnet.</p>
|
||
|
||
<h1 id="openissues"><span class="section-heading">Open issues</span><span class="section-anchor"> <a rel="bookmark" href="#openissues"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<h2 id="interactionwithzip302zip-0302">Interaction with ZIP 302 <a href="#fn:18" id="fnref:18" title="see footnote" class="footnote"><sup>18</sup></a></h2>
|
||
|
||
<p>TBD</p>
|
||
|
||
<h1 id="rationale"><span class="section-heading">Rationale</span><span class="section-anchor"> <a rel="bookmark" href="#rationale"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<h2 id="memobundlesizerestriction"><span class="section-heading">Memo bundle size restriction</span><span class="section-anchor"> <a rel="bookmark" href="#memobundlesizerestriction"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>Restricting the total amount of memo data in a bundle, for example to 16 KiB,
|
||
limits the rate at which the chain size can grow cheaply (from a computational
|
||
perspective; memo bundles are much easier to produce than proofs or signatures).</p>
|
||
|
||
<p>The current behaviour for previous transaction versions (no limit on the number
|
||
of memos) is not altered by this ZIP, because memos in those transactions are
|
||
tied to individual shielded outputs (incurring their computational cost), and
|
||
are not natively aggregatable.</p>
|
||
|
||
<h2 id="memochunksize"><span class="section-heading">Memo chunk size</span><span class="section-anchor"> <a rel="bookmark" href="#memochunksize"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>To understand the effect of memo chunk size, we construct a table showing the
|
||
total amount of data stored on-chain when encoding 16 KiB of memo data to as
|
||
many recipients as possible.</p>
|
||
|
||
<p>Each table entry has the format “<span class="math">\(N\)</span> @ <span class="math">\(M\)</span> (<span class="math">\(O\)</span>)” where <span class="math">\(N\)</span> is the maximum
|
||
number of distinct recipients you can have within the memo data limits, <span class="math">\(M\)</span>
|
||
is the cost in bytes of that memo data plus memo keys and authentication tags
|
||
when using a 32-byte memo key, and <span class="math">\(O\)</span> is the relative overhead compared to
|
||
pre-ZIP-231 memos.</p>
|
||
|
||
<details>
|
||
<summary>
|
||
Calculation details
|
||
</summary>
|
||
|
||
<p>Let:</p>
|
||
|
||
<ul>
|
||
<li><span class="math">\(D\)</span> be the limit on total memo data (16384 bytes);</li>
|
||
<li><span class="math">\(C\)</span> be the chunk size (256 or 512 bytes);</li>
|
||
<li><span class="math">\(S\)</span> be the maximum length of an individual memo (256 or 512 bytes);</li>
|
||
<li><span class="math">\(K\)</span> be the key size (32 bytes);</li>
|
||
<li><span class="math">\(A\)</span> be the authentication tag size (16 bytes);</li>
|
||
<li><span class="math">\(L\)</span> be the limit on the number of chunks (32 or <span class="math">\(\infty\)</span>).</li>
|
||
</ul>
|
||
|
||
<p>Then</p>
|
||
|
||
<ul>
|
||
<li><span class="math">\(N = \mathsf{min}(L, \mathsf{ceiling}(D / \mathsf{max}(C, S))\)</span>;</li>
|
||
<li><span class="math">\(M = N × (S+K+A)\)</span>; and</li>
|
||
<li><span class="math">\(O = (M / D - 1) × 100\%\)</span>.
|
||
</details>
|
||
<br/></li>
|
||
</ul>
|
||
|
||
<table>
|
||
<colgroup>
|
||
<col />
|
||
<col />
|
||
<col />
|
||
</colgroup>
|
||
|
||
<thead>
|
||
<tr>
|
||
<th> Chunk size </th>
|
||
<th> Memo size ≤ 256 bytes</th>
|
||
<th> Memo size = 512 bytes</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
<tr>
|
||
<td> Pre-231 </td>
|
||
<td> 32 @ 16384 ( 0.00%) </td>
|
||
<td> 32 @ 16384 ( 0.00%) </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 512 </td>
|
||
<td> 32 @ 17920 (+ 9.38%) </td>
|
||
<td> 32 @ 17920 (+ 9.38%) </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 256 </td>
|
||
<td> 64 @ 19456 (+18.75%) </td>
|
||
<td> 32 @ 18432 (+12.50%) </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 256 32-out </td>
|
||
<td> 32 @ 9728 (-40.63%) </td>
|
||
<td> </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>In the “256 32-out” case you have a distinguisher compared to old transactions,
|
||
in that you can tell the transaction is sending at most 256 bytes per recipient
|
||
rather than 512 if it is sending the maximum number of memos. But that’s inherently
|
||
baked into the decision to use a smaller memo chunk size (and it is still
|
||
possible for the chunks to all be a single memo sent to all outputs, or anything
|
||
in between).</p>
|
||
|
||
<h2 id="memokeysize"><span class="section-heading">Memo key size</span><span class="section-anchor"> <a rel="bookmark" href="#memokeysize"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>16-byte (128-bit) keys don’t meet Zcash’s target security level of 125 bits,
|
||
as argued in <a href="#fn:19" id="fnref:19" title="see footnote" class="footnote"><sup>19</sup></a>.</p>
|
||
|
||
<p>However, for the sake of argument, if we used a 16-byte memo key instead of
|
||
32 bytes, the transaction size overhead would become:</p>
|
||
|
||
<table>
|
||
<colgroup>
|
||
<col />
|
||
<col />
|
||
<col />
|
||
</colgroup>
|
||
|
||
<thead>
|
||
<tr>
|
||
<th> Chunk size </th>
|
||
<th> Memo size ≤ 256 bytes</th>
|
||
<th> Memo size = 512 bytes</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
<tr>
|
||
<td> Pre-231 </td>
|
||
<td> 32 @ 16384 ( 0.00%) </td>
|
||
<td> 32 @ 16384 ( 0.00%) </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 512 </td>
|
||
<td> 32 @ 17408 (+ 6.25%) </td>
|
||
<td> 32 @ 17408 (+ 6.25%) </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 256 </td>
|
||
<td> 64 @ 18432 (+12.50%) </td>
|
||
<td> 32 @ 17920 (+ 9.38%) </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 256 32-out </td>
|
||
<td> 32 @ 9216 (-43.75%) </td>
|
||
<td> </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>The decrease in overhead is relatively modest in most cases, but more noticeable
|
||
for small memos with a 256-byte memo chunk.</p>
|
||
|
||
<p>The benefits of 256-bit keys are:</p>
|
||
|
||
<ul>
|
||
<li>They incur only a small transaction size overhead above the minimum key size
|
||
that <em>would</em> meet the target security level.</li>
|
||
<li>This key length matches what we already use elsewhere for symmetric keys.</li>
|
||
</ul>
|
||
|
||
<h2 id="encryptionformat"><span class="section-heading">Encryption format</span><span class="section-anchor"> <a rel="bookmark" href="#encryptionformat"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>Including a per-transaction <span class="math">\(\mathsf{salt}\)</span> in the derivation of
|
||
<span class="math">\(\mathsf{encryption_key}\)</span> gives protection against accidental (or intentional)
|
||
reuse of <span class="math">\(\mathsf{K^{memo}}\)</span> reuse across multiple transactions. We do not
|
||
protect against <span class="math">\(\mathsf{K^{memo}}\)</span> reuse within a transaction; it is up to
|
||
the transaction builder to ensure that the same <span class="math">\(\mathsf{K^{memo}}\)</span> is not
|
||
used to encrypt two different memos (and if they did so, normal clients would
|
||
either never observe the second memo, or would decrypt parts of each memo and
|
||
get a nonsensical and potentially insecure “spliced” memo).</p>
|
||
|
||
<p>We do not include commitments to the shielded outputs in the derivation of
|
||
<span class="math">\(\mathsf{encryptionKey}\)</span> for two reasons:</p>
|
||
|
||
<ul>
|
||
<li>It would force the transaction builder to fully define all shielded outputs
|
||
before encrypting the memos, which might prevent potential use cases of PCZTs <a href="#fn:20" id="fnref:20" title="see footnote" class="footnote"><sup>20</sup></a>.</li>
|
||
<li>We don’t want to unnecessarily prevent the ability to create a transaction
|
||
with a memo bundle and no shielded outputs, as there may be use cases for,
|
||
e.g. a fully-transparent transaction with encrypted memo, or a ZSA issuance
|
||
transaction with exposed memo data using a well-known <span class="math">\(\mathsf{K^{memo}}\)</span>.</li>
|
||
</ul>
|
||
|
||
<h2 id="prunedencoding"><span class="section-heading">Pruned encoding</span><span class="section-anchor"> <a rel="bookmark" href="#prunedencoding"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||
|
||
<p>The separation of memo data from note data, and the new ability to easily store
|
||
variable-length memo data, opens up an attack vector against node operators for
|
||
storing arbitrary data. The transaction digest commitments to the memo bundle
|
||
are structured such that if a node operator is presented with a memo key (i.e.
|
||
they are given the capability to decrypt a particular memo), they can identify
|
||
and prune the corresponding memo chunks, while still enabling the transaction to
|
||
be validated as part of its corresponding block and broadcast over the network.</p>
|
||
|
||
<p>The transaction encoding permits pruning at the individual chunk level in order
|
||
to facilitate pruning an individual memo from a transaction without affecting the
|
||
other memos. This enables node operators to be responsive to, for example, GDPR
|
||
deletion requests.</p>
|
||
|
||
<p>Note that broadcasting a partially-pruned transaction means that the pruned
|
||
chunks no longer contribute to the upper bound on memo data.</p>
|
||
|
||
<p>The prunable structure does not introduce a censorship axis; memo bundles do not
|
||
reveal which memo chunks correspond to which memos, and therefore a network
|
||
adversary cannot selectively censor individual memos. They can censor any/all
|
||
chunks within specific transactions, however shielded transactions do not reveal
|
||
their senders, recipients, or amounts, and thus also cannot be individually
|
||
targeted for censorship.</p>
|
||
|
||
<h1 id="deployment"><span class="section-heading">Deployment</span><span class="section-anchor"> <a rel="bookmark" href="#deployment"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<p>This ZIP is proposed to activate with Network Upgrade 7. <a href="#fn:21" id="fnref:21" title="see footnote" class="footnote"><sup>21</sup></a></p>
|
||
|
||
<h1 id="referenceimplementation"><span class="section-heading">Reference implementation</span><span class="section-anchor"> <a rel="bookmark" href="#referenceimplementation"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<p>TBD</p>
|
||
|
||
<h1 id="references"><span class="section-heading">References</span><span class="section-anchor"> <a rel="bookmark" href="#references"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h1>
|
||
|
||
<div class="footnotes">
|
||
<hr />
|
||
<ol>
|
||
|
||
<li id="fn:1">
|
||
<p><a href="https://www.rfc-editor.org/info/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”</a> <a href="#fnref:1" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:2">
|
||
<p><a href="zip-0200">ZIP 200: Network Upgrade Mechanism</a> <a href="#fnref:2" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:3">
|
||
<p><a href="protocol/protocol.pdf">Zcash Protocol Specification, Version 2024.5.1 [NU6] or later</a> <a href="#fnref:3" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:4">
|
||
<p><a href="protocol/protocol.pdf#networks">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet</a> <a href="#fnref:4" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:5">
|
||
<p><a href="protocol/protocol.pdf#noteptconcept">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.2.1: Note Plaintexts and Memo Fields</a> <a href="#fnref:5" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:6">
|
||
<p><a href="zip-0307">ZIP 307: Light Client Protocol for Payment Detection</a> <a href="#fnref:6" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:7">
|
||
<p><a href="protocol/protocol.pdf#abstractprfs">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.1.2: Pseudo Random Functions</a> <a href="#fnref:7" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:8">
|
||
<p><a href="https://www.rfc-editor.org/rfc/rfc8439.html">RFC 8439: ChaCha20 and Poly1305 for IETF Protocols</a> <a href="#fnref:8" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:9">
|
||
<p><a href="https://eprint.iacr.org/2015/189">Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance</a> <a href="#fnref:9" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:10">
|
||
<p><a href="zip-0317">ZIP 317: Proportional Transfer Fee Mechanism</a> <a href="#fnref:10" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:11">
|
||
<p><a href="zip-0317#fee-calculation">ZIP 317: Proportional Transfer Fee Mechanism - Fee calculation</a> <a href="#fnref:11" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:12">
|
||
<p><a href="protocol/protocol.pdf#noteptencoding">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.5: Encodings of Note Plaintexts and Memo Fields</a> <a href="#fnref:12" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:13">
|
||
<p><a href="protocol/protocol.pdf#saplingsend">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.2: Sending Notes (Sapling)</a> <a href="#fnref:13" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:14">
|
||
<p><a href="protocol/protocol.pdf#orchardsend">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.3: Sending Notes (Orchard)</a> <a href="#fnref:14" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:15">
|
||
<p><a href="protocol/protocol.pdf#saplingandorchardinband">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.1: Encryption (Sapling and Orchard)</a> <a href="#fnref:15" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:16">
|
||
<p><a href="protocol/protocol.pdf#decryptivk">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.2: Decryption using an Incoming Viewing Key (Sapling and Orchard)</a> <a href="#fnref:16" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:17">
|
||
<p><a href="protocol/protocol.pdf#decryptovk">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.3: Decryption using a Full Viewing Key (Sapling and Orchard)</a> <a href="#fnref:17" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:18">
|
||
<p><a href="zip-0302">ZIP 302: Standardized Memo Field Format</a> <a href="#fnref:18" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:19">
|
||
<p><a href="protocol/protocol.pdf#inbandrationale">Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 8.7: In-band secret distribution</a> <a href="#fnref:19" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:20">
|
||
<p><a href="https://github.com/zcash/zips/issues/693">zcash/zips issue #693: Standardize a protocol for creating shielded transactions offline</a> <a href="#fnref:20" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
<li id="fn:21">
|
||
<p><a href="zip-0254">ZIP 254: Deployment of the NU7 Network Upgrade</a> <a href="#fnref:21" title="return to body" class="reversefootnote"> ↩︎</a></p>
|
||
</li>
|
||
|
||
</ol>
|
||
</div>
|
||
</body>
|
||
</html>
|