diff --git a/README.rst b/README.rst
index 53f690b3..376ea6ae 100644
--- a/README.rst
+++ b/README.rst
@@ -181,6 +181,7 @@ written.
| 235 | Remove 60% of Transaction Fees From Circulation | Draft | zips#924 |
| 245 | Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions | Draft | zips#384 |
| 246 | Digests for the Version 6 Transaction Format | Draft | |
+
| 248 | Extensible Transaction Format | Draft | zips/pull/1163 |
| 270 | Key Rotation for Tracked Signing Keys | Reserved | zips#1047 |
| 302 | Standardized Memo Field Format | Draft | zips#366 |
| 303 | Sprout Payment Disclosure | Reserved | |
@@ -209,9 +210,10 @@ written.
| 2002 | Explicit Fees | Draft | zips#803 |
| 2003 | Disallow version 4 transactions | Draft | zips#825 |
| 2004 | Remove the dependency of consensus on note encryption | Draft | zips#917 |
-
| 2005 | Quantum Recoverability | Draft | zips#1135 |
+
| 2005 | Orchard Quantum Recoverability | Draft | zips#1135 |
| guide-markdown | {Something Short and To the Point} | Draft | |
| guide | {Something Short and To the Point} | Draft | |
+
| template | {Something Short and To the Point} | Draft | |
Drafts without assigned ZIP numbers
@@ -320,6 +322,7 @@ Index of ZIPs
| 244 | Transaction Identifier Non-Malleability | Final |
| 245 | Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions | Draft |
| 246 | Digests for the Version 6 Transaction Format | Draft |
+
| 248 | Extensible Transaction Format | Draft |
| 250 | Deployment of the Heartwood Network Upgrade | Final |
| 251 | Deployment of the Canopy Network Upgrade | Final |
| 252 | Deployment of the NU5 Network Upgrade | Final |
@@ -381,7 +384,8 @@ Index of ZIPs
| 2002 | Explicit Fees | Draft |
| 2003 | Disallow version 4 transactions | Draft |
| 2004 | Remove the dependency of consensus on note encryption | Draft |
-
| 2005 | Quantum Recoverability | Draft |
+
| 2005 | Orchard Quantum Recoverability | Draft |
| guide-markdown | {Something Short and To the Point} | Draft |
| guide | {Something Short and To the Point} | Draft |
+
| template | {Something Short and To the Point} | Draft |
diff --git a/protocol/protocol.tex b/protocol/protocol.tex
index 80b64a81..1c438b68 100644
--- a/protocol/protocol.tex
+++ b/protocol/protocol.tex
@@ -1690,6 +1690,7 @@
\newcommand{\DiversifierIndex}{\mathsf{index}}
\newcommand{\FVK}{\mathsf{FVK}}
\newcommand{\DeriveInternalFVKOrchard}{\mathsf{DeriveInternalFVK^{Orchard}}}
+\newcommand{\DeriveDkAndOvkOrchard}{\mathsf{DeriveDkAndOvk^{Orchard}}}
\newcommand{\DiversifiedTransmitBase}{\mathsf{g_d}}
\newcommand{\DiversifiedTransmitBaseRepr}{\mathsf{g\Repr_d}}
\newcommand{\DiversifiedTransmitBaseOld}{\mathsf{g^{old}_d}}
@@ -4256,8 +4257,7 @@
$\PRFexpand{}$ is used in the following places:
\begin{itemize}
\item \sapling{\crossref{saplingkeycomponents}, with inputs $[\hexint{00}]$, $[\hexint{01}]$, $[\hexint{02}]$, and $[\hexint{03}, i \typecolon \byte]$;}
- \nufiveonwarditem{in \crossref{orchardkeycomponents}, with inputs $[\hexint{06}]$, $[\hexint{07}]$, $[\hexint{08}]$, and with first byte $\hexint{82}$
- (the last of these is also specified in \cite{ZIP-32});}
+ \nufiveonwarditem{in \crossref{orchardkeycomponents}, with inputs $[\hexint{06}]$, $[\hexint{07}]$, $[\hexint{08}]$, and with first byte $\hexint{82}$;}
\notnufive{
\item \sapling{sending (\crossref{saplingsend}) and receiving (\shortcrossref{saplingandorchardinband}) \Sapling \notes,
with inputs $[\hexint{04}]$ and $[\hexint{05}]$;}
@@ -4269,7 +4269,7 @@
} %notbeforenufive
\item in \cite{ZIP-32}, \sapling{with inputs $[\hexint{00}]$, $[\hexint{01}]$, $[\hexint{02}]$ (intentionally matching \shortcrossref{saplingkeycomponents}),
$[\hexint{10}]$, $[\hexint{13}]$, $[\hexint{14}]$, and} with first byte in
- $\setof{\sapling{\hexint{11}, \hexint{12}, \hexint{15}, \hexint{16}, \hexint{17}, \hexint{18},\,}\hexint{80}\nufive{, \hexint{81}, \hexint{82}, \hexint{83}}}$;
+ $\setof{\sapling{\hexint{11}, \hexint{12}, \hexint{15}, \hexint{16}, \hexint{17}, \hexint{18},\,}\hexint{80}\nufive{, \hexint{81}, \hexint{83}}}$;
\item in \cite{ZIP-316}, with first byte $\hexint{D0}$.
\end{itemize}
@@ -5354,53 +5354,64 @@
\introsection
\lsubsubsection{\OrchardText{} Key Components}{orchardkeycomponents}
-\vspace{-1ex}
Let $\PRFOutputLengthExpand$, $\SpendingKeyLength$, $\OutViewingKeyLength$, $\DiversifierLength$,
and $\DiversifierKeyLength$ be as defined in \crossref{constants}.
Let $\GroupP$, $\reprP$, $\ellP$, $\ParamP{q}$, and $\ParamP{r}$ be as defined in
\crossref{pallasandvesta}.
-\vspace{-0.25ex}
+\vspace{-0.2ex}
Let $\ExtractP$ be as defined in \crossref{concreteextractorpallas}.
-\vspace{-0.35ex}
+\vspace{-0.3ex}
Let $\GroupPHash$ be as defined in \crossref{concretegrouphashpallasandvesta}.
-\vspace{-0.25ex}
+\vspace{-0.2ex}
Let $\PRFexpand{}$ and $\PRFock{Orchard}{}$ be as defined in \crossref{concreteprfs}.
-\vspace{-0.5ex}
+\vspace{-0.4ex}
Let $\DeriveInternalFVKOrchard$ be as defined in \cite[Orchard internal key derivation]{ZIP-32}.
-\vspace{-0.25ex}
+\vspace{-0.2ex}
Let $\PRPd{} \typecolon \DiversifierKeyType \times \DiversifierType \rightarrow \DiversifierType$
be as defined in \crossref{concreteprps}.
-\vspace{-0.35ex}
+\vspace{-0.3ex}
Let $\KA{Orchard}$, instantiated in \crossref{concreteorchardkeyagreement},
be a \keyAgreementScheme.
-\vspace{-0.35ex}
+\vspace{-0.3ex}
Let $\CommitIvk{}$, instantiated in \crossref{concretesinsemillacommit},
be a \commitmentScheme.
-\vspace{-0.25ex}
+\vspace{-0.2ex}
Let $\DiversifyHash{Orchard}$ be as defined in \crossref{concretediversifyhash}.
-\vspace{-0.25ex}
+\vspace{-0.2ex}
Let $\SpendAuthSig{Orchard}$ instantiated in \crossref{concretespendauthsig}
be a \rerandomizableSignatureScheme.
-\vspace{-0.25ex}
+\vspace{-0.2ex}
Let $\ItoLEBSP{}$, $\ItoLEOSP{}$, and $\LEOStoIP{}$ be as defined in \crossref{endian}.
-\vspace{0.5ex}
+\vspace{0.4ex}
Define $\ToBase{Orchard}(x \typecolon \PRFOutputExpand) := \LEOStoIPOf{\PRFOutputLengthExpand}{x} \pmod{\ParamP{q}}$.
-\vspace{-1.5ex}
+\vspace{-1.3ex}
Define $\ToScalar{Orchard}(x \typecolon \PRFOutputExpand) := \LEOStoIPOf{\PRFOutputLengthExpand}{x} \pmod{\ParamP{r}}$.
+Define $\DeriveDkAndOvkOrchard(\CommitIvkRand \typecolon \CommitIvkRandType, \AuthSignPublic \typecolon \AuthSignPublicTypeOrchard, \NullifierKey \typecolon \NullifierKeyTypeOrchard)$
+as follows:
+
+\begin{algorithm}
+ \item let $K = \ItoLEBSPOf{\SpendingKeyLength}{\CommitIvkRand}$
+ \vspace{-0.3ex}
+ \item let $R = \PRFexpand{\!K}\big([\hexint{82}] \bconcat \ItoLEOSPOf{256}{\AuthSignPublic} \bconcat \ItoLEOSPOf{256}{\NullifierKey}\kern-0.25em\big)$
+ \item let $\DiversifierKey \typecolon \DiversifierKeyType$ be the first $\DiversifierKeyLength/8$ bytes of $R$ and
+ let $\OutViewingKey \typecolon \OutViewingKeyType$ be the remaining $\OutViewingKeyLength/8$ bytes of $R$.
+ \item return $(\DiversifierKey, \OutViewingKey)$
+\end{algorithm}
+
\introlist
A new \Orchard \spendingKey $\SpendingKey$ is generated by choosing a \bitSequence
uniformly at random from $\SpendingKeyType$.
@@ -5435,12 +5446,7 @@
\vspace{-0.3ex}
\item if $\InViewingKey \in \setof{0, \bot}$, discard this key and repeat with a new $\SpendingKey$.
\vspace{-0.2ex}
- \item let $K = \ItoLEBSPOf{\SpendingKeyLength}{\CommitIvkRand}$
- \vspace{-0.5ex}
- \item let $R = \PRFexpand{K}\big([\hexint{82}] \bconcat \ItoLEOSPOf{256}{\AuthSignPublic} \bconcat \ItoLEOSPOf{256}{\NullifierKey}\kern-0.25em\big)$
- \vspace{-0.2ex}
- \item let $\DiversifierKey$ be the first $\DiversifierKeyLength/8$ bytes of $R$ and
- let $\OutViewingKey$ be the remaining $\OutViewingKeyLength/8$ bytes of $R$.
+ \item let $(\DiversifierKey, \OutViewingKey) = \DeriveDkAndOvkOrchard(\CommitIvkRand, \AuthSignPublic, \NullifierKey)$
\vspace{-0.4ex}
\item let $(\Internal{\AuthSignPublic}, \Internal{\NullifierKey}, \Internal{\CommitIvkRand}) = \DeriveInternalFVKOrchard(\AuthSignPublic, \NullifierKey, \CommitIvkRand)$
\vspace{-0.3ex}
@@ -5448,17 +5454,14 @@
\vspace{-0.2ex}
\item if $\Internal{\InViewingKey} \in \setof{0, \bot}$, discard this key and repeat with a new $\SpendingKey$.
\vspace{-0.2ex}
- \item let $\Internal{K} = \ItoLEBSPOf{\SpendingKeyLength}{\Internal{\CommitIvkRand}}$
- \vspace{-0.5ex}
- \item let $\Internal{R} = \PRFexpand{\Internal{K}}\big([\hexint{82}] \bconcat \ItoLEOSPOf{256}{\Internal{\AuthSignPublic}} \bconcat \ItoLEOSPOf{256}{\Internal{\NullifierKey}}\kern-0.25em\big)$
- \vspace{-0.2ex}
- \item let $\Internal{\DiversifierKey}$ be the first $\DiversifierKeyLength/8$ bytes of $\Internal{R}$ and
- let $\Internal{\OutViewingKey}$ be the remaining $\OutViewingKeyLength/8$ bytes of $\Internal{R}$.
+ \item let $(\Internal{\DiversifierKey}, \Internal{\OutViewingKey}) = \DeriveDkAndOvkOrchard\big(\Internal{\CommitIvkRand}, \Internal{\AuthSignPublic}, \Internal{\NullifierKey}\big)$.
\end{algorithm}
+\vspace{-1ex}
\introlist
\pnote{$\Internal{\AuthSignPublic} = \AuthSignPublic$ and $\Internal{\NullifierKey} = \NullifierKey$.}
+\vspace{1ex}
As explained in \crossref{addressesandkeys}, \Orchard allows the efficient
creation of multiple \diversifiedPaymentAddresses with the same \spendingAuthority.
A group of such addresses shares the same \fullViewingKey, \incomingViewingKey, and
@@ -5577,9 +5580,9 @@
a sequence of ciphertext components for the encrypted output \notes.
\end{itemize}
-\introlist
The $\ephemeralKey$ and $\encCiphertexts$ fields together form the \notesCiphertextSprout.
+\introlist
The value $\hSig$ is also computed from $\RandomSeed$, $\nfOld{\allOld}$, and the
$\joinSplitPubKey$ of the containing \transaction:
\begin{formulae}
@@ -5747,9 +5750,11 @@
} %sapling
+\vspace{-2ex}
\nufive{
\lsubsection{Action Descriptions}{actiondesc}
+\vspace{-1ex}
An \actionTransfer, as specified in \crossref{actions}, is encoded in \transactions as an
\defining{\actionDescription}.
Each version 5 \transaction includes a sequence of zero or more \defining{\actionDescriptions}.
@@ -5775,45 +5780,47 @@
Let $\Action$ be as defined in \crossref{abstractzk}.
-\vspace{1ex}
+\vspace{0.5ex}
\introsection
-An \actionDescription comprises $(\cvNet{}, \rt{Orchard}, \nf, \AuthSignRandomizedPublic, \spendAuthSig,
-\cmX, \EphemeralPublic, \TransmitCiphertext{}, \OutCiphertext, \enableSpends, \enableOutputs,$ $\Proof{})$
-where
+An \actionDescription comprises $(\cvNet{}\kern-0.2em, \rt{Orchard}\kern-0.2em, \nf, \AuthSignRandomizedPublic, \spendAuthSig,
+\cmX\kern-0.1em, \EphemeralPublic, \TransmitCiphertext{}\kern-0.2em, \OutCiphertext\kern-0.2em, \enableSpends, \enableOutputs, \Proof{})$:
+\vspace{-1.5ex}
\begin{itemize}
\item $\cvNet{} \typecolon \ValueCommitOutput{Orchard}$ is the \valueCommitment to the value of the
input \note minus the value of the output \note;
\vspace{-0.5ex}
\item $\rt{Orchard} \typecolon \MerkleHashOrchard$ is an \anchor, as defined in \crossref{transactions},
for the output \treestate of a previous \block;
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\nf \typecolon \range{0}{\ParamP{q}-1}$ is the \nullifier for the input \note;
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\AuthSignRandomizedPublic \typecolon \SpendAuthSigPublic{Orchard}$ is a randomized \validatingKey
that should be used to validate $\spendAuthSig$;
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\spendAuthSig \typecolon \SpendAuthSigSignature{Orchard}$ is a \spendAuthSignature,
validated as specified in \crossref{spendauthsig};
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\cmX \typecolon \MerkleHashOrchard$ is the result of applying $\ExtractP$ to the \noteCommitment for
the output \note;
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\EphemeralPublic \typecolon \KAPublic{Orchard}$ is
a key agreement \publicKey, used to derive the key for encryption
of the \noteCiphertextOrchard (\crossref{saplinginband});
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\TransmitCiphertext{} \typecolon \Ciphertext$ is
a ciphertext component for the encrypted output \note;
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\OutCiphertext{} \typecolon \Ciphertext$ is a ciphertext component that allows the holder of
the \outgoingCipherKey (which can be derived from a \fullViewingKey) to recover the recipient
\diversifiedTransmissionKey $\DiversifiedTransmitPublic$ and the \ephemeralPrivateKey
$\EphemeralPrivate$, hence the entire \notePlaintext;
+ \vspace{-0.15ex}
\item $\enableSpends \typecolon \bit$ is a flag that is set in order to enable \nh{non-zero-valued}
spends in this Action;
+ \vspace{-0.15ex}
\item $\enableOutputs \typecolon \bit$ is a flag that is set in order to enable \nh{non-zero-valued}
outputs in this Action;
- \vspace{-0.25ex}
+ \vspace{-0.3ex}
\item $\Proof{} \typecolon \ActionProof$ is a \zkSNARKProof with \primaryInput
$(\cv, \rt{Orchard}\kern-0.1em, \nf\kern-0.1em, \AuthSignRandomizedPublic, \cmX, \enableSpends, \enableOutputs)$
for the \actionStatement defined in \crossref{actionstatement}.
@@ -5821,10 +5828,9 @@
\vspace{-1.5ex}
\pnote{The $\rt{Orchard}$, $\enableSpends$, and $\enableOutputs$ components are the same for all
-\actionTransfers in a \transaction. They are encoded once in the \transaction body (see
-\crossref{txnencoding}), not in the $\type{ActionDescription}$ structure.
-$\Proof{}$ is aggregated with other Action proofs and encoded in the $\proofsOrchard$ field of a
-\transaction.}
+\actionTransfers in a \transaction, and are encoded once in the \transaction body
+(\crossref{txnencoding}), not the $\type{ActionDescription}$ structure.
+$\Proof{}$ is aggregated with other Action proofs and encoded in the $\proofsOrchard$ field.}
\begin{consensusrules}
\vspace{-0.25ex}
@@ -5844,7 +5850,7 @@
i.e.\ $\ActionVerify\big(\kern-0.1em(\cv, \rt{Orchard}, \nf, \AuthSignRandomizedPublic, \cmX, \enableSpends, \enableOutputs), \Proof{}\big) = 1$.
\end{consensusrules}
-\vspace{-1.5ex}
+\vspace{-2ex}
\begin{nnotes}
\vspace{-0.25ex}
\item $\cv$ and $\AuthSignRandomizedPublic$ can be the zero point $\ZeroP$. $\EphemeralPublic$ cannot
@@ -5856,7 +5862,7 @@
} %nufive
-\vspace{-3ex}
+\vspace{-2.5ex}
\lsubsection{Sending Notes}{send}
\vspace{-1ex}
@@ -5869,15 +5875,16 @@
\introlist
Let $\JoinSplitSig$ be as specified in \crossref{abstractsig}.
-\vspace{-0.5ex}
+\vspace{-0.6ex}
Let $\NoteCommitAlg{Sprout}$ be as specified in \crossref{abstractcommit}.
-\vspace{-0.5ex}
+\vspace{-0.6ex}
Let $\RandomSeedLength$ and $\NoteUniquePreRandLength$ be as specified in \crossref{constants}.
Sending a \transaction containing \joinSplitDescriptions involves first
generating a new $\JoinSplitSig$ key pair:
+\vspace{-0.4ex}
\begin{formulae}
\item $\joinSplitPrivKey \leftarrowR \JoinSplitSigGenPrivate()$
\item $\joinSplitPubKey := \JoinSplitSigDerivePublic(\joinSplitPrivKey)$.
@@ -5902,10 +5909,10 @@
\item Let $\NotePlaintext{i} = (\hexint{00}, \Value_i, \NoteUniqueRand_i, \NoteCommitRand_i, \Memo_i)$.
\end{itemize}
-\vspace{-1ex}
+\vspace{-1.3ex}
$\NotePlaintext{\allNew}$ are then encrypted to the recipient \transmissionKeys
$\TransmitPublicSub{\allNew}$, giving the \notesCiphertextSprout
-$(\EphemeralPublic, \TransmitCiphertext{\allNew})$, as described in \crossref{sproutinband}.
+$\big(\EphemeralPublic, \TransmitCiphertext{\allNew}\big)$, as described in \crossref{sproutinband}.
In order to minimize information leakage, the sender \SHOULD randomize the order
of the input \notes and of the output \notes. Other considerations relating to
@@ -5920,7 +5927,7 @@
\item $\joinSplitSig \leftarrowR \JoinSplitSigSign{\text{\small\joinSplitPrivKey}}(\dataToBeSigned)$
\end{formulae}
-\vspace{-0.5ex}
+\vspace{-1ex}
Then the encoded \transaction including $\joinSplitSig$ is submitted to the \peerToPeerNetwork.
\canopyonwardpnote{\cite{ZIP-211} specifies that nodes and wallets \MUST disable any facilities
diff --git a/zips/zip-0032.rst b/zips/zip-0032.rst
index 5ced05e5..ce63227d 100644
--- a/zips/zip-0032.rst
+++ b/zips/zip-0032.rst
@@ -473,7 +473,7 @@ Define $\mathsf{DeriveInternalFVK^{Orchard}}(\mathsf{ak}, \mathsf{nk}, \mathsf{r
as follows:
- Let $K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})$.
-- Let $\mathsf{rivk_{internal}} = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}}(K, [\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk})))$.
+- Let $\mathsf{rivk_{internal}} = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF}^{\mathsf{expand}}_{K}\big([\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$.
- Return $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk_{internal}})$.
The result of applying $\mathsf{DeriveInternalFVK^{Orchard}}$ to the external full viewing
@@ -500,8 +500,8 @@ Account level. It was implemented in `zcashd` as part of support for ZIP 316 [#z
Note that the resulting FVK may be invalid, as specified in [#protocol-orchardkeycomponents]_.
-Orchard diversifier derivation
-------------------------------
+Orchard diversifier and OVK derivation
+--------------------------------------
As with Sapling, we define a mechanism for deterministically deriving a sequence of diversifiers, without
leaking how many diversified addresses have already been generated for an account. Unlike Sapling, we do so
@@ -510,18 +510,24 @@ key. This means that the full viewing key provides the capability to determine t
within the sequence, which matches the capabilities of a Sapling extended full viewing key but simplifies the
key structure.
-Given an Orchard extended spending key $(\mathsf{sk}_i, \mathsf{c}_i)$:
+Let $\mathsf{DeriveDkAndOvk^{Orchard}}$ be as defined in [#protocol-orchardkeycomponents]_.
-- Let $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ be the Orchard full viewing key for $\mathsf{sk}_i$.
-- Let $K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})$.
-- $\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(K, [\mathtt{0x82}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))$.
+Given an Orchard full viewing key $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ (which may be
+either external or internal):
+
+- $(\mathsf{dk}, \mathsf{ovk}) = \mathsf{DeriveDkAndOvk^{Orchard}}(\mathsf{rivk}, \mathsf{ak}, \mathsf{nk})$.
- Let $j$ be the index of the desired diversifier, in the range $0\,..\, 2^{88} - 1$.
-- $d_{i,j} = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}_i, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))$.
+- $\mathsf{d}_j = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}\big(\mathsf{dk}, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j)\kern-0.1em\big)$.
+
+Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values
+of $j$ yield valid diversifiers.
-Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values of $j$ yield
-valid diversifiers.
+The default diversifier for $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ is defined to be
+$\mathsf{d}_0.$
-The default diversifier for $(\mathsf{sk}_i, \mathsf{c}_i)$ is defined to be $d_{i,0}.$
+No mechanism is provided to derive distinct Outgoing Viewing Keys ($\!\mathsf{ovk}$) for
+each diversified address. This is because payments are sent from accounts (with external
+or internal scope), not from specific diversified addresses [#zip-0316-usage-of-outgoing-viewing-keys]_.
Specification: Registered key derivation
@@ -892,3 +898,4 @@ References
.. [#NIST-SP-800-38G] `NIST Special Publication 800-38G — Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption `_
.. [#zip-0000] `ZIP 0: ZIP Process `_
.. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_
+.. [#zip-0316-usage-of-outgoing-viewing-keys] `ZIP 316: Unified Addresses and Unified Viewing Keys — Usage of Outgoing Viewing Keys `_
\ No newline at end of file
diff --git a/zips/zip-0226.rst b/zips/zip-0226.rst
index 4b42c005..f65bf23f 100644
--- a/zips/zip-0226.rst
+++ b/zips/zip-0226.rst
@@ -83,6 +83,27 @@ Privacy Implications
- When including new Assets we would like to maintain the amount and identifiers
of Assets private, which is achieved with the design.
+Bundle Type Registration
+========================
+
+This ZIP registers the OrchardZSA bundle type in the V6 transaction bundle
+type registry defined in ZIP 248 [#zip-0248]_:
+
++------------+----------------------+--------------------+------------------+-------------+
+| BundleType | ``mValuePoolDeltas`` | ``mEffectBundles`` | ``mAuthBundles`` | Bundle kind |
++============+======================+====================+==================+=============+
+| TBD |✅ |✅ |✅ | OrchardZSA |
++------------+----------------------+--------------------+------------------+-------------+
+
+The OrchardZSA bundle has value pool deltas (transfers move value in and out of
+the transparent transaction value pool), effecting data (the OrchardZSA actions
+and burn information), and authorizing data (the proofs and binding signature).
+
+A transaction MUST NOT contain both an Orchard bundle (type 3) and an OrchardZSA
+bundle. The OrchardZSA bundle replaces the Orchard bundle for transactions that
+transfer Custom Assets.
+
+
Specification
=============
@@ -370,7 +391,7 @@ The transaction format for v6 transactions is described in ZIP 230 [#zip-0230]_.
The ZSA-related changes in v6 include:
* updates to the transaction structure [#zip-0230-transaction-format]_ and the
- sighash digest computation [#zip-0246]_;
+ sighash digest computation [#zip-0248]_;
* new note plaintext formats for both Sapling and Orchard outputs [#zip-0230-note-plaintexts]_,
with corresponding changes to the note decryption algorithms for incoming and
outgoing viewing keys [#zip-2005]_.
@@ -394,13 +415,18 @@ The following requirements on wallets are specified and motivated in ZIP 230
temporarily inaccessible, until the wallet is upgraded to fully support v6 and to
rescan outputs since v6 activation.
-Sighash modifications relative to ZIP 244 [#zip-0244]_
-------------------------------------------------------
+Modifications to Digest Algorithms
+----------------------------------
+
+The OrchardZSA bundle contributes to the transaction identifier and signature
+digest via the ``effects_bundles_digest`` and ``auth_bundles_digest`` defined
+in ZIP 248 [#zip-0248]_.
-Relative to the sighash algorithm defined in ZIP 244 [#zip-0244]_, the sighash algorithm
-that applies to v6 transactions differs by altering the Orchard bundle within
-the tree hash to match the corresponding OrchardZSA changes. See ZIP 246 [#zip-0246]_
-for details.
+The OrchardZSA bundle's value pool deltas (for both ZEC and Custom Assets) are
+committed via ``value_pool_deltas_digest``. The OrchardZSA effecting data
+(actions and burn information) is committed via ``effects_bundles_digest``.
+The OrchardZSA authorizing data (proofs and binding signature) is committed
+via ``auth_bundles_digest``.
Transaction Fees
----------------
@@ -456,8 +482,7 @@ References
.. [#zip-0230-note-plaintexts] `ZIP 230: Version 6 Transaction Format — Note Plaintexts `_
.. [#zip-0230-orchard-note-plaintext] `ZIP 230: Version 6 Transaction Format — Orchard Note Plaintext `_
.. [#zip-0230-implications-for-wallets] `ZIP 230: Version 6 Transaction Format — Implications for Wallets `_
-.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_
-.. [#zip-0246] `ZIP 246: Digests for the Version 6 Transaction Format `_
+.. [#zip-0248] `ZIP 248: Extensible Transaction Format `_
.. [#zip-0307] `ZIP 307: Light Client Protocol for Payment Detection `_
.. [#zip-2005] `ZIP 2005: Quantum Recoverability `_
.. [#protocol] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later. `_
diff --git a/zips/zip-0227.rst b/zips/zip-0227.rst
index 51841ad6..98b184f7 100644
--- a/zips/zip-0227.rst
+++ b/zips/zip-0227.rst
@@ -308,6 +308,28 @@ where $\mathsf{GroupHash}^\mathbb{P}$ is defined as in [#protocol-concretegrouph
Diagram relating the Issuer identifier, asset description, asset description hash, Asset Identifier, Asset Digest, and Asset Base for the OrchardZSA Protocol.
+Bundle Type Registration
+========================
+
+This ZIP registers the ZSA Issuance bundle type in the V6 transaction bundle
+type registry defined in ZIP 248 [#zip-0248]_:
+
++------------+----------------------+--------------------+------------------+--------------+
+| BundleType | ``mValuePoolDeltas`` | ``mEffectBundles`` | ``mAuthBundles`` | Bundle kind |
++============+======================+====================+==================+==============+
+| TBD |✅ |✅ |✅ | ZSA Issuance |
++------------+----------------------+--------------------+------------------+--------------+
+
+The ZSA Issuance bundle has value pool deltas (issuance adds value to the
+transparent transaction value pool for Custom Assets), effecting data (the
+issuance actions and issue notes), and authorizing data (the issuance
+authorization signature).
+
+The effecting data for the ZSA Issuance bundle is encoded as specified in
+`Issuance Bundle`_. The authorizing data consists of the ``issueAuthSig``
+field.
+
+
Specification: Issue Note, Issuance Action, Issuance Bundle and Issuance Protocol
=================================================================================
@@ -593,12 +615,17 @@ Concrete Applications
-Modifications relative to ZIP 244 [#zip-0244]_
-==============================================
+Modifications to Digest Algorithms
+==================================
+
+The ZSA Issuance bundle contributes to the transaction identifier and signature
+digest via the ``effects_bundles_digest`` and ``auth_bundles_digest`` defined
+in ZIP 248 [#zip-0248]_.
-Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm
-that applies to v6 transactions differs by including the issuance bundle
-components within the tree hash. See ZIP 246 [#zip-0246]_ for details.
+The issuance bundle's value pool deltas are committed via
+``value_pool_deltas_digest``. The issuance effecting data (issuance actions and
+issue notes) is committed via ``effects_bundles_digest``. The issuance
+authorization signature is committed via ``auth_bundles_digest``.
Changes to ZIP 317 [#zip-0317]_
@@ -695,8 +722,7 @@ References
.. [#zip-0230-issuance-action-description] `ZIP 230: Version 6 Transaction Format — Issuance Action Description (IssueAction) `_
.. [#zip-0230-issue-note] `ZIP 230: Version 6 Transaction Format — Issue Note Description (IssueNoteDescription) `_
.. [#zip-0230-transaction-format] `ZIP 230: Version 6 Transaction Format — Transaction Format `_
-.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_
-.. [#zip-0246] `ZIP 246: Digests for the Version 6 Transaction Format `_
+.. [#zip-0248] `ZIP 248: Extensible Transaction Format `_
.. [#zip-0317] `ZIP 317: Proportional Transfer Fee Mechanism `_
.. [#zip-0317-fee-calculation] `ZIP 317: Proportional Transfer Fee Mechanism — Fee calculation `_
.. [#bip-0043] `BIP 43: Purpose Field for Deterministic Wallets `_
diff --git a/zips/zip-0231.md b/zips/zip-0231.md
index 05e29ade..b555267b 100644
--- a/zips/zip-0231.md
+++ b/zips/zip-0231.md
@@ -143,6 +143,149 @@ 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.
+## Bundle Type Registration
+
+This ZIP registers the following bundle types in the V6 transaction bundle type
+registry defined in ZIP 248 [^zip-0248]:
+
+| BundleType | `mValuePoolDeltas` | `mEffectBundles` | `mAuthBundles` | Bundle kind |
+|------------|--------------------| -----------------|----------------|----------------------|
+| TBD |❌ |✅ |❌ | Memos |
+| TBD |✅ |✅ |✅ | Sapling-post-ZIP 231 |
+| TBD |✅ |✅ |✅ | Orchard-post-ZIP 231 |
+
+The Memos bundle has no value pool deltas (memo data does not involve value
+transfers) and no authorizing data. The effecting data consists of the encoded
+memo bundle as defined in [Encoding in transactions].
+
+If this ZIP is activated in the same network upgrade as ZIP 248, the encoding
+of the Sapling and Orchard bundles described in this ZIP will be used for
+bundle types 2 and 3, respectively, and ZIP 248's definition of the Sapling and
+Orchard bundles must be updated accordingly. If this ZIP is activated in a
+network upgrade AFTER the network upgrade in which ZIP 248 is activated, the
+encodings it describes will be assigned distinct bundle identifiers. In this
+latter case, a transaction MUST NOT contain both a Sapling-pre-ZIP 231 bundle
+and a Sapling-post-ZIP 231 bundle, or both an Orchard-pre-ZIP 231 bundle and an
+Orchard-post-ZIP 231 bundle.
+
+## Sapling-post-ZIP 231 Bundle
+
+The Sapling-post-ZIP 231 bundle replaces the Sapling bundle defined in
+ZIP 248 [^zip-0248]. The only change is that the note plaintext in each
+Sapling output is shortened: the 512-byte memo field is replaced by a
+32-byte $\mathsf{K^{memo}}$, reducing `encCiphertext` from 580 bytes to
+100 bytes.
+
+### Sapling-post-ZIP 231 Effecting Data
+
+The effecting data for the Sapling-post-ZIP 231 bundle describes the Sapling
+spends and outputs.
+
+| Bytes | Name | Data Type | Description |
+|--------------------------|--------------------|---------------------------------------------|------------------------------------------------------------------------------|
+| varies | `nSpendsSapling` | `compactSize` | Number of Sapling Spend descriptions. |
+| 96 \* nSpendsSapling | `vSpendsSapling` | `SaplingSpendEffecting[nSpendsSapling]` | Effecting data for each Sapling Spend. |
+| varies | `nOutputsSapling` | `compactSize` | Number of Sapling Output descriptions. |
+| 276 \* nOutputsSapling | `vOutputsSapling` | `SaplingOutputPostZIP231[nOutputsSapling]` | Sapling Output descriptions. |
+| 32 | `anchorSapling` | `byte[32]` | A root of the Sapling note commitment tree at some block height in the past. |
+
+* The field `anchorSapling` is present if and only if $\mathtt{nSpendsSapling} > 0$.
+
+`SaplingSpendEffecting` is unchanged from ZIP 248 [^zip-0248].
+
+#### SaplingOutputPostZIP231
+
+| Bytes | Name | Data Type | Description |
+|-------|-----------------|-------------|---------------------------------------------------------------------------------------------------------------------------|
+| 32 | `cv` | `byte[32]` | A value commitment to the net value of the output note. |
+| 32 | `cmu` | `byte[32]` | The $u$-coordinate of the note commitment for the output note. |
+| 32 | `ephemeralKey` | `byte[32]` | An encoding of an ephemeral Jubjub public key. |
+| 100 | `encCiphertext` | `byte[100]` | The encrypted contents of the note plaintext, which contains $\mathsf{K^{memo}}$ in place of the 512-byte memo field. |
+| 80 | `outCiphertext` | `byte[80]` | The encrypted contents of the byte string created by concatenation of the transmission key with the ephemeral secret key. |
+
+### Sapling-post-ZIP 231 Authorizing Data
+
+The authorizing data is unchanged from the Sapling bundle defined in
+ZIP 248 [^zip-0248].
+
+| Bytes | Name | Data Type | Description |
+|--------------------------|--------------------------|-----------------------------------|--------------------------------------------------------------|
+| 192 \* nSpendsSapling | `vSpendProofsSapling` | `byte[192 * nSpendsSapling]` | Encodings of the zk-SNARK proofs for each Sapling Spend. |
+| 64 \* nSpendsSapling | `vSpendAuthSigsSapling` | `byte[64 * nSpendsSapling]` | Authorizing signatures for each Sapling Spend. |
+| 192 \* nOutputsSapling | `vOutputProofsSapling` | `byte[192 * nOutputsSapling]` | Encodings of the zk-SNARK proofs for each Sapling Output. |
+| 64 | `bindingSigSapling` | `byte[64]` | A Sapling binding signature on the SIGHASH transaction hash. |
+
+* The values of `nSpendsSapling` and `nOutputsSapling` are not re-encoded in
+ the authorizing data; they are taken from the corresponding effecting data.
+* The field `bindingSigSapling` is present if and only if
+ $\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0$.
+* The elements of `vSpendProofsSapling` and `vSpendAuthSigsSapling` have a
+ 1:1 correspondence to the elements of `vSpendsSapling` in the effecting data
+ and MUST be ordered such that the element at a given index corresponds to the
+ `SaplingSpendEffecting` at the same index.
+* The elements of `vOutputProofsSapling` have a 1:1 correspondence to the
+ elements of `vOutputsSapling` in the effecting data and MUST be ordered such
+ that the proof at a given index corresponds to the `SaplingOutputPostZIP231`
+ at the same index.
+
+## Orchard-post-ZIP 231 Bundle
+
+The Orchard-post-ZIP 231 bundle replaces the Orchard bundle defined in
+ZIP 248 [^zip-0248]. As with Sapling, the only change is that the note
+plaintext in each Orchard action is shortened: the 512-byte memo field is
+replaced by a 32-byte $\mathsf{K^{memo}}$, reducing `encCiphertext` from
+580 bytes to 100 bytes.
+
+### Orchard-post-ZIP 231 Effecting Data
+
+The effecting data for the Orchard-post-ZIP 231 bundle describes the Orchard
+actions.
+
+| Bytes | Name | Data Type | Description |
+|--------------------------|--------------------|-------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
+| varies | `nActionsOrchard` | `compactSize` | The number of Orchard Action descriptions. |
+| 340 \* nActionsOrchard | `vActionsOrchard` | `OrchardActionEffecting[nActionsOrchard]` | Effecting data for each Orchard Action. |
+| 1 | `flagsOrchard` | `byte` | An 8-bit value representing a set of flags. Ordered from LSB to MSB: `enableSpendsOrchard`, `enableOutputsOrchard`. The remaining bits are set to $0$. |
+| 32 | `anchorOrchard` | `byte[32]` | A root of the Orchard note commitment tree at some block height in the past. |
+
+* The fields `flagsOrchard` and `anchorOrchard` are present if and only if
+ $\mathtt{nActionsOrchard} > 0$.
+* For coinbase transactions, the `enableSpendsOrchard` bit MUST be set to $0$.
+
+#### OrcharActionEffecting
+
+| Bytes | Name | Data Type | Description |
+|-------|-----------------|-------------|---------------------------------------------------------------------------------------------------------------------------|
+| 32 | `cv` | `byte[32]` | A value commitment to the net value of the input note minus the output note. |
+| 32 | `nullifier` | `byte[32]` | The nullifier of the input note. |
+| 32 | `rk` | `byte[32]` | The randomized validating key for this Action. |
+| 32 | `cmx` | `byte[32]` | The $x$-coordinate of the note commitment for the output note. |
+| 32 | `ephemeralKey` | `byte[32]` | An encoding of an ephemeral Pallas public key. |
+| 100 | `encCiphertext` | `byte[100]` | The encrypted contents of the note plaintext, which contains $\mathsf{K^{memo}}$ in place of the 512-byte memo field. |
+| 80 | `outCiphertext` | `byte[80]` | The encrypted contents of the byte string created by concatenation of the transmission key with the ephemeral secret key. |
+
+### Orchard-post-ZIP 231 Authorizing Data
+
+The authorizing data is unchanged from the Orchard bundle defined in
+ZIP 248 [^zip-0248].
+
+| Bytes | Name | Data Type | Description |
+|--------------------------|--------------------------|-----------------------------------|--------------------------------------------------------------------------------------------|
+| varies | `sizeProofsOrchard` | `compactSize` | Length in bytes of `proofsOrchard`. Value is $2720 + 2272 \cdot \mathtt{nActionsOrchard}$. |
+| sizeProofsOrchard | `proofsOrchard` | `byte[sizeProofsOrchard]` | Encoding of aggregated zk-SNARK proofs for Orchard Actions. |
+| 64 \* nActionsOrchard | `vSpendAuthSigsOrchard` | `byte[64 * nActionsOrchard]` | Authorizing signatures for each Orchard Action. |
+| 64 | `bindingSigOrchard` | `byte[64]` | An Orchard binding signature on the SIGHASH transaction hash. |
+
+* The value of `nActionsOrchard` is not re-encoded in the authorizing data; it
+ is taken from the corresponding effecting data.
+* The fields `sizeProofsOrchard`, `proofsOrchard`, and `bindingSigOrchard` are
+ present if and only if $\mathtt{nActionsOrchard} > 0$.
+* The proofs aggregated in `proofsOrchard`, and the elements of
+ `vSpendAuthSigsOrchard`, each have a 1:1 correspondence to the elements of
+ `vActionsOrchard` in the effecting data and MUST be ordered such that the
+ proof or signature at a given index corresponds to the
+ `OrchardActionEffecting` value at the same index.
+
## Memo bundle
A memo bundle consists of a sequence of 272-byte memo chunks, each encrypting
@@ -254,6 +397,9 @@ followed by $\mathtt{0x01}$), ensuring that a malformed memo is not returned.
## Encoding in transactions
+The following describes the effecting data for the memo bundle. This data
+appears in `mEffectBundles` with the memo bundle type identifier.
+
| Bytes | Name | Data Type | Description |
|----------|------------------------|-----------------------------------------------------------|-----------------------------------------------------------------------|
| 1 | $\mathtt{fAllPruned}$ | $\mathtt{uint8}$ | 1 if all chunks have been pruned, otherwise 0. |
@@ -276,19 +422,28 @@ If $\mathtt{fAllPruned} = 0$, then:
If $\mathtt{fAllPruned} = 1$, then:
- $\mathtt{nonceOrHash}$ represents the overall hash for the memo bundle as defined in
- [Transaction sighash].
+ [Transaction Digest].
- The $\mathtt{nMemoChunks}$, $\mathtt{pruned}$, and $\mathtt{vMemoChunks}$ fields will be absent.
-## Transaction sighash
+## Transaction Digest
+
+The memo bundle contributes to the transaction identifier via the
+`effects_bundles_digest` defined in ZIP 248 [^zip-0248].
-$\mathsf{memo\_chunk\_digest}[i] = H(\mathtt{vMemoChunks}[i]) \\$
-$\mathsf{memo\_bundle\_digest} = H(\mathsf{concat}(\mathsf{memo\_chunk\_digests}))$
+The memo bundle's effect digest is computed as follows:
+
+$\mathsf{memo\_chunk\_digest}[i] = \mathsf{BLAKE2b\text{-}256}(\texttt{"ZTxIdMemoChunkHs"}, \mathtt{vMemoChunks}[i]) \\$
+$\mathsf{memo\_bundle\_digest} = \mathsf{BLAKE2b\text{-}256}(\texttt{"ZTxIdMemoBundHsh"}, \mathsf{concat}(\mathsf{memo\_chunk\_digests}))$
+
+For pruned chunks, the $\mathsf{memo\_chunk\_digest}$ stored in the transaction
+encoding is used directly.
The memo bundle digest structure is a performance optimization for the case
-where all memo chunks in a transaction have been pruned.
+where all memo chunks in a transaction have been pruned. When $\mathtt{fAllPruned} = 1$,
+the $\mathtt{nonceOrHash}$ field contains the pre-computed $\mathsf{memo\_bundle\_digest}$.
-TODO: finish this to be a modification to the equivalent of ZIP 244 for
-transaction v6.
+Since the memo bundle has no authorizing data, it does not contribute to the
+`auth_bundles_digest`.
## Changes to ZIP 317 [^zip-0317]
@@ -581,9 +736,11 @@ TBD
[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst)
+[^zip-0248]: [ZIP 248: Extensible Transaction Format](zip-0248.rst)
+
[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md)
-[^zip-0230-orchard-note-plaintext]: [ZIP 230: Version 6 Transaction Format — Orchard Note Plaintext](zip-0230.rst#orchard-note-plaintext)
+[^zip-0230-note-plaintexts]: [ZIP 230: Version 6 Transaction Format — Note Plaintexts](zip-0230.rst#note-plaintexts)
[^zip-0302]: [ZIP 302: Standardized Memo Field Format](zip-0302.rst)
diff --git a/zips/zip-0233.md b/zips/zip-0233.md
index bca2ef1f..2f17c166 100644
--- a/zips/zip-0233.md
+++ b/zips/zip-0233.md
@@ -75,82 +75,83 @@ design shared by Bitcoin-like systems:
# Privacy Implications
-ZIP 233 adds a new type of transparent transaction event that is fully visible to chain
-observers, and linked to other events performed in the transaction. The removal of
-funds from circulation does not affect shielded outputs, and therefore does not alter
-the privacy properties of shielded funds.
+ZIP 233 adds a new type of transparent transaction event that is fully visible
+to chain observers, and linked to other events performed in the transaction.
+The removal of funds from circulation does represent a potential distinguisher;
+transactions that intentionally remove funds from circulation are likely to
+represent a small fraction of Zcash transactions, and so this will provide
+another tool that adversaries may use to be able to segment users of the
+network.
# Requirements
-- The mechanism enables users to remove funds from the circulating supply, and each removal event is explicitly specified in the corresponding transaction.
-- The process is publicly auditable, allowing network participants to verify the amount and occurrence of funds removed from circulation.
+- The mechanism enables users to remove funds from the circulating supply, and
+ each removal event is explicitly specified in the corresponding transaction.
+- The process is publicly auditable, allowing network participants to verify
+ the amount and occurrence of funds removed from circulation.
# Specification
-## Transaction Field
+## Bundle Type Registration
-Each transaction gains a $\mathsf{zip233\_amount}$ property, specifying the
-value in zatoshis that is removed from circulation when the transaction is
-mined. The value removed from circulation subtracts from the remaining value in
-the "transparent transaction value pool" as described in § 3.4 ‘Transactions and
-Treestates’ [^protocol-transactions].
+This ZIP registers bundle type 5 ("ZIP 233 NSM field") in the V6 transaction
+bundle type registry defined in ZIP 248 [^zip-0248].
-$\mathsf{zip233\_amount}$ does not result in an output being produced in any
-chain value pool, and therefore from the point at which the transaction is
-applied to the global chain state, $\mathsf{zip233\_amount}$ is subtracted from
-the issued supply. It is unavailable for circulation on the network at least
-through to the end of the block in which the transaction is mined. ZIP 234
-[^zip-0234] specifies a potential mechanism by which the funds removed from
-circulation would again become available.
+| BundleType | `mValuePoolDeltas` | `mEffectBundles` | `mAuthBundles` |
+|------------|--------------------| -----------------|----------------|
+| 5 |✅ |❌ |❌ |
-## Changes to ZIP 230 [^zip-0230]
+The NSM bundle has no effecting data and no authorizing data. The amount to be
+removed from circulation is represented solely as an entry in `mValuePoolDeltas`
+with `bundleType = 5` and `assetClass = 0` (ZEC).
-The following field is appended to the Common Transaction Fields of the v6
-transaction format after `nExpiryHeight` [^zip-0230-transaction-format]:
+## NSM Amount
-| Bytes | Name | Data Type | Description |
-|-------|----------------|-----------|----------------------------------------------------------------------------|
-| 8 | `zip233Amount` | `uint64` | The value to be removed from circulation in this transaction, in zatoshis. |
+When the `mValuePoolDeltas` map contains an entry with `bundleType = 5`, the
+transaction removes funds from circulation. The entry's `value` field MUST BE
+nonpositive; its negation is denoted $\mathsf{zip233\_amount}$ and represents
+the value in zatoshis removed from circulation when the transaction is mined.
+If no such entry is present, $\mathsf{zip233\_amount}$ is defined to be 0.
-The $\mathsf{zip233\_amount}$ of a transaction is defined to be the value of the
-`zip233Amount` field if present, and otherwise 0.
-
-Notes:
-
-* If both this ZIP and ZIP 2002 are selected for inclusion in the same Network
- Upgrade, then the ordering of fields in the transaction format will be ``fee``
- and then ``zip233Amount``.
-* Older transaction versions can continue to be supported after a network
- upgrade, but removing funds from circulation is not possible for these
- transactions. For example, NU5 supports both v4 and v5 transaction formats,
- for both coinbase and non-coinbase transactions.
+The NSM bundle's effect on the transparent transaction value pool does not
+reflect an output being produced in any chain value pool. At the point at which
+the transaction is applied to the global chain state, $\mathsf{zip233\_amount}$
+is subtracted from the issued supply. It is unavailable for circulation on the
+network at least through to the end of the block in which the transaction is
+mined. ZIP 234 [^zip-0234] specifies a potential mechanism by which the funds
+removed from circulation would become available for reintroduction into the
+issued supply in subsequent blocks.
## Changes to the Zcash Protocol Specification
-Make a change to § 3.4 ‘Transactions and Treestates’ [^protocol-transactions]
-implementing the specification in [ZIP-233 Amount].
+Let $\mathsf{NSMBundleId} = 5.$
-In § 7.1 ‘Transaction Encoding and Consensus’ [^protocol-txnconsensus], add:
-
-> [NU7 onward] $\mathsf{zip233\_amount}$ MUST be in the range $\{ 0 .. \mathsf{MAX\_MONEY} \}$.
+Let $\mathsf{Zec}$ be the asset UUID for ZEC as defined in ZIP 248 [^zip-0248].
-In § 7.1.2 ‘Transaction Consensus Rules’ [^protocol-txnconsensus], add a note:
+Make a change to § 3.4 'Transactions and Treestates' [^protocol-transactions]
+adding the following consensus rules:
-> [NU7 onward] $\mathsf{zip233\_amount}$ does not result in an output being produced in any
-chain value pool.
+> * [NU7 onward] The `assetClass` for any entry in `mValuePoolDeltas` having
+> `bundleType` $= \mathsf{NSMBundleId}$ MUST be 0. That is, amounts to remove
+> from circulation MUST be denominated in ZEC.
+>
+> * [NU7 onward] The value of $\mathsf{mValuePoolDeltas}[(\mathsf{NSMBundleId}, \mathsf{Zec})]$,
+> if present, MUST be nonpositive. Its absolute value is $\mathsf{zip233\_amount}$.
+>
+> * [NU7 onward] $\mathsf{zip233\_amount}$ does not result in an output being
+> produced in any chain value pool.
-## Modifications relative to ZIP 244 [^zip-0244]
+In § 7.1 'Transaction Encoding and Consensus' [^protocol-txnconsensus], add:
-Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm
-that applies to v6 transactions differs by appending the encoding of
-$\mathsf{zip233\_amount}$ to the Common Transaction Fields that are the input
-to the digest in T.1: `header_digest` [^zip-0244-t-1-header-digest]:
+> [NU7 onward] $\mathsf{zip233\_amount}$ MUST be in the range $\{ 0 .. \mathsf{MAX\_MONEY} \}$.
-> T.1f: zip233_amount (8-byte little-endian amount to remove from circulation)
+## Modifications to Digest Algorithms
-Note: If both this ZIP and ZIP 2002 are selected for inclusion in the same
-Network Upgrade, then the ambiguity in ordering of the fields added by these
-ZIPs would need to be resolved.
+The $\mathsf{zip233\_amount}$ is committed to the transaction identifier and
+signature digest via the `value_pool_deltas_digest` defined in ZIP 248 [^zip-0248].
+Since the NSM bundle (bundle type 5) has no effecting data and no authorizing
+data, its only contribution to the transaction digest is through its entry
+in `mValuePoolDeltas`.
## Applicability
@@ -192,14 +193,10 @@ This ZIP is proposed to activate with Network Upgrade 7. [^draft-arya-deploy-nu7
[^zip-0230]: [ZIP 230: Version 6 Transaction Format](zip-0230.rst)
-[^zip-0230-transaction-format]: [ZIP 230: Version 6 Transaction Format. Section 'Transaction Format'](zip-0230.rst#transaction-format)
-
[^zip-0234]: [ZIP 234: Network Sustainability Mechanism: Issuance Smoothing](zip-0234.rst)
[^zip-0235]: [ZIP 235: Remove 60% of Transaction Fees From Circulation](zip-0235.rst)
-[^zip-0244]: [ZIP 244: Transaction Identifier Non-Malleability](zip-0244.rst)
-
-[^zip-0244-t-1-header-digest]: [ZIP 244: Transaction Identifier Non-Malleability. Section T.1: header_digest](zip-0244.rst#t-1-header-digest)
+[^zip-0248]: [ZIP 248: Extensible Transaction Format](zip-0248.rst)
[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md)
diff --git a/zips/zip-0248.rst b/zips/zip-0248.rst
new file mode 100644
index 00000000..41b575d4
--- /dev/null
+++ b/zips/zip-0248.rst
@@ -0,0 +1,1658 @@
+::
+
+ ZIP: 248
+ Title: Extensible Transaction Format
+ Owners: Jack Grigg
+ Kris Nuttycombe
+ Daira-Emma Hopwood
+ Schell Scivally
+ Status: Draft
+ Category: Consensus / Wallet
+ Created: 2025-12-17
+ License: MIT
+ Discussions-To:
+ Pull-Request:
+
+Terminology
+===========
+
+{Edit this to reflect the key words that are actually used.}
+The key words "MUST", "REQUIRED", "MUST NOT", "SHOULD", and "MAY" in this
+document are to be interpreted as described in BCP 14 [^BCP14] when, and only
+when, they appear in all capitals.
+
+The character § is used when referring to sections of the Zcash Protocol
+Specification. [#protocol]_
+
+The terms "Mainnet" and "Testnet" are to be interpreted as described in § 3.12
+‘Mainnet and Testnet’. [#protocol-networks]_
+
+The term "full validator" in this document is to be interpreted as defined in §
+3.3 ‘The Block Chain’. [#protocol-blockchain]_
+
+The terms below are to be interpreted as follows:
+
+transparent transaction value pool
+ An ephemeral value for the balance of an asset within the scope of a single
+ transaction, which is modified by additions and subtractions in the
+ processing of the effects of transaction bundles. When all of the effects of
+ a transaction are accounted for, each such balance is zero; i.e, the total of
+ additions to the balance equals the total of subtractions from it.
+
+
+Abstract
+========
+
+This ZIP proposes an encoding for V6 Zcash transactions that is intended to
+reduce the impact of future changes to the Zcash transaction format on the
+Zcash ecosystem. It defines a new typecode-length-value encoding for a sequence
+of protocol bundles, and a "value balance" map that describes the effect of
+each bundle on the transparent transaction value pool for each asset. The
+entries of this map serve the same purpose as the Sapling and Orchard value
+balance fields have done in the past.
+
+
+Motivation
+==========
+
+In the past, Zcash network upgrades that changed the transaction format have
+resulted in substantial disruption for wallets and other third-party clients in
+the Zcash ecosystem. In order to continue functioning after a network upgrade,
+clients were required to upgrade their Zcash transaction parsers to read the
+new format, even if the context in which those parsers were being used didn't
+need or couldn't make use of newly added transaction data. An example of this
+is that transparent-only wallets were forced to update their parsers to
+understand the Sapling and Orchard parts of transactions, even if they would
+never read or act upon those parts. This has led on occasion to significant
+problems in the Zcash ecosystem, including situations where funds have been
+locked and rendered unspendable from transparent-only wallets.
+
+For some kinds of changes to consensus features, it's imperative that every
+wallet be aware of and be adapted to those changes, and in those cases making a
+major (breaking) transaction version update as we've done in the past is
+appropriate. For many new features, however, it is possible for a wallet to
+continue functioning correctly without having to fully understand a transaction
+using that feature.
+
+For example, if TZEs were to be added to the protocol, it wouild be possible
+for wallets to continue operating with transparent/Sapling/Orchard
+functionality, ignoring TZE parts. There is substantial precedent for this sort
+of behavior; transparent-only hardware wallets are currently still important in
+the Zcash ecosystem, and many wallets didn't begin interacting with Orchard
+transaction parts until quite a while after Orchard activation.
+
+After this change to transaction encoding, wallets and other third parties will
+not be required to update their transaction parsers in advance of a network
+upgrade for the introduction of many (and perhaps most) types of new protocol
+features. This will enable the Zcash ecosystem to make smaller and more
+incremental network upgrades without breaking existing wallets.
+
+
+Privacy Implications
+====================
+
+This change alters the encoding of transactions, but does not alter the
+information content of the transaction. As such, the only implication of this
+change is that the use of this transaction format acts as a 1-bit distinguisher
+that reveals that the wallet that generated the transaction has been updated to
+be aware of the new format. This information leakage is unavoidable for any
+transaction format change.
+
+In the future, this change may reduce the amount of information leakage, since
+transactions created using the proposed TLV format will include bundles only
+for those protocols for which the transaction modifies chain state. For example,
+if this transaction format change is deployed in NU7 and NU8 defines a bundle
+type for TZE components, it will not be possible for a chain observer to
+distinguish whether or not the wallet that produced an Orchard-only transaction
+is one that has been updated to understand the TZE component. Under prior
+practices for changing the transaction format, this would have been
+distinguishable.
+
+In summary, this proposal provides a net improvement in user privacy in
+addition to its other benefits.
+
+
+Requirements
+============
+
+* The transaction format can be parsed without any knowledge of any Zcash
+ payment protocols.
+* Movement of value into and out of the transparent value pools (the ZEC
+ transparent value pool, plus the transparent value pool for each ZSA asset)
+ can be understood with only partial knowledge of the Zcash payment protocols.
+* The information content of transactions should not change as part of
+ this ZIP. Other ZIPs activated along with this ZIP may however make
+ use of it in introducing such changes.
+* It must be possible for wallets to parse any transaction that is valid within
+ a version group that it understands, even if it doesn't have handling for or
+ understand all of the bundle types that are valid for that version group. In
+ such a situation, however, such a wallet must still be able to accurately
+ describe any transparent movement of funds effected by the transaction, and
+ alert the user if the transaction contains bundles that it does not
+ understand.
+* It must be possible for a wallet to correctly construct and sign transactions
+ for a given transaction version group that it understands, even if it doesn't
+ have handling for or understand all of the bundle types that are valid for
+ transactions in that version group.
+
+
+Non-requirements
+================
+
+
+Specification
+=============
+
+Protocol Bundles
+----------------
+
+This ZIP refines and codifies the concept of "protocol bundles" that emerged
+from the implementation of the ZIP 225 [#zip-0225]_ transaction format. It
+makes bundles first-class objects and defines a registry of bundle type
+identifiers. Within the period that a given transaction format version is used
+on the Zcash network, the semantics of the bundle associated with a given
+bundle type identifier are fixed.
+
+A **protocol bundle** is a self-contained component of a transaction that
+implements a specific piece of protocol functionality. Each bundle type
+defines:
+
+* What **effecting data** the bundle contains — the data that determines what
+ state changes the bundle produces (e.g., which notes are spent, which outputs
+ are created, which transparent UTXOs are consumed or produced).
+
+* What **authorizing data** the bundle contains — the proofs and signatures
+ that authorize the state changes specified by the effecting data.
+
+* How the bundle affects the **transparent transaction value pool** — whether
+ the bundle adds value to, removes value from, or has no effect on this
+ ephemeral pool that balances value flows within a transaction.
+
+Rationale for Effecting Data and Authorizing Data
+`````````````````````````````````````````````````
+
+.. raw:: html
+
+
+ Click to show/hide
+
+The separation of effecting data from authorizing data serves several purposes:
+
+1. **Transaction identifier stability**: The transaction identifier (txid) is
+ computed only from the effecting data. This means that the txid is
+ determined by *what* the transaction does, not by *how* it is authorized.
+ Third parties cannot change a transaction's identifier by modifying
+ signatures or proofs.
+
+2. **Efficient pruning**: Full nodes that have validated a transaction may
+ prune the authorizing data while retaining the effecting data. Since
+ authorizing data appears at the end of the encoded transaction, pruning
+ is simply truncation.
+
+3. **Partial validation**: A wallet that does not understand a particular
+ bundle type can still compute the transaction identifier by hashing the
+ effecting data opaquely, without needing to parse its internal structure.
+
+.. raw:: html
+
+
+
+The Transparent Transaction Value Pool
+``````````````````````````````````````
+
+The transparent transaction value pool is an ephemeral concept that exists only
+within the scope of processing a single transaction. It serves as a balancing
+mechanism through which value flows between bundles.
+
+Each bundle may contribute a **value pool delta** — a signed value indicating
+how much the bundle adds to or removes from the transparent transaction value
+pool for a given asset. A positive delta means the bundle is adding value to
+the pool (e.g., a shielded spend releasing value), while a negative delta means
+the bundle is consuming value from the pool (e.g., a shielded output absorbing
+value, or a transaction fee).
+
+For a valid non-coinbase transaction, the sum of all value pool deltas for each
+asset MUST equal zero. This ensures that value is neither created nor destroyed
+— it is only transferred between bundles within the transaction.
+
+For a coinbase transaction, the sum of value pool deltas for ZEC equals the
+negative of the block subsidy, reflecting that the block subsidy implicitly
+adds value to the transparent transaction value pool.
+
+Bundle Type Registration
+````````````````````````
+
+When a ZIP introduces a new bundle type, it MUST:
+
+1. Request allocation of a bundle type identifier in the registry defined
+ below. The identifier must be a non-negative integer.
+
+2. Specify whether entries for this bundle type are permitted in
+ ``mValuePoolDeltas`` (the value pool delta map).
+
+3. Specify whether entries for this bundle type are permitted in
+ ``mEffectBundles`` (the effecting data map).
+
+4. Specify whether entries for this bundle type are permitted in
+ ``mAuthBundles`` (the authorizing data map).
+
+5. If effecting data is permitted, define the encoding of that data.
+
+6. If authorizing data is permitted, define the encoding of that data.
+
+7. Define the digest algorithm for the bundle's contribution to the transaction
+ identifier, if effecting data is present.
+
+8. Define the digest algorithm for the bundle's contribution to the authorizing
+ data commitment, if authorizing data is present.
+
+A bundle type MUST NOT permit entries in ``mAuthBundles`` unless it also permits
+entries in ``mEffectBundles``. That is, authorizing data cannot exist without
+corresponding effecting data for a given bundle type.
+
+Once a bundle type identifier is assigned for a given transaction version, its
+semantics are fixed for the lifetime of that transaction version. A subsequent
+network upgrade may define a new transaction version that reassigns identifiers
+or changes bundle semantics, but within a single transaction version, bundle
+type identifiers have stable, unchanging meanings.
+
+V6 Transaction Bundle Type Registry
+```````````````````````````````````
+
+The following integers are registered as bundle type identifiers for the V6
+transaction format. All currently-defined IDs are encoded as single-byte
+``compactSize`` values where they appear in the transaction format.
+
+The ``mValuePoolDeltas`` column indicates whether or not an entry for this
+bundle type MAY appear in ``mValuePoolDeltas``. For rows where an ❌
+is present, the value pool delta for every pool is guaranteed to be zero, and
+so entries in ``mValuePoolDeltas`` MUST NOT be present.
+
+The ``mEffectBundles`` column indicates whether or not an entry for this bundle
+type MAY appear in ``mEffectBundles``. For rows where an ❌ is present, the
+bundle has no effecting data, and so an entry in ``mEffectBundles`` MUST NOT
+be present.
+
+The ``mAuthBundles`` column indicates whether or not an entry for this bundle
+type MAY appear in ``mAuthBundles``. For rows where an ❌ is present, the
+bundle has no authorizing data, and so an entry in ``mAuthBundles`` MUST NOT
+be present.
+
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| BundleType | ``mValuePoolDeltas`` | ``mEffectBundles`` | ``mAuthBundles`` | Defining ZIP | Bundle kind |
++============+======================+====================+==================+==============+==============================================+
+| 0 |✅ |✅ |✅ | This ZIP | Transparent |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| 1 | | | | | Reserved |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| 2 |✅ |✅ |✅ | This ZIP | Sapling |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| 3 |✅ |✅ |✅ | This ZIP | Orchard |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| 4 |✅ |❌ |❌ | ZIP 2002 | Transaction fee |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| 5 |✅ |❌ |❌ | ZIP 233 | ZIP 233 NSM field |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| 6 |❌ |✅ |✅ | ZIP 270 | Key rotation |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| 7 |✅ |✅ |✅ | TBD | Lockbox disbursement |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| |❌ |✅ |❌ | ZIP 231 | Memos |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| |✅ |✅ |✅ | ZIP 231 | Sapling-post-ZIP 231 |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| |✅ |✅ |✅ | ZIP 231 | Orchard-post-ZIP 231 |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| |✅ |✅ |✅ | ZIP 227 | ZSA Issuance |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+| |✅ |✅ |✅ | ZIP 226 | OrchardZSA |
++------------+----------------------+--------------------+------------------+--------------+----------------------------------------------+
+
+Additional bundle types MAY be added to this registry via modifications to this
+ZIP specified in other ZIPs. Such modifications MUST specify all of the
+information required by the `Bundle Type Registration`_ section above.
+
+Potential Future Bundle Types
+`````````````````````````````
+
+.. raw:: html
+
+
+ Click to show/hide
+
+The following entries are provided to illustrate how potential future upgrades
+might affect the bundle registry:
+
++------------+----------------------+--------------------+------------------+-------------------------------------------------------------+
+| BundleType | ``mValuePoolDeltas`` | ``mEffectBundles`` | ``mAuthBundles`` | Bundle kind |
++============+======================+====================+==================+=============================================================+
+| |✅ |✅ |✅ | TZEs |
++------------+----------------------+--------------------+------------------+-------------------------------------------------------------+
+| |✅ |✅ |✅ | Pool that only has a long-term storage protocol (PQ, very |
+| | | | | simple thus insulated from counterfeiting fears, can be |
+| | | | | used for payments but higher latency for that purpose) |
++------------+----------------------+--------------------+------------------+-------------------------------------------------------------+
+| |✅ |✅ |✅ | Tachyon |
++------------+----------------------+--------------------+------------------+-------------------------------------------------------------+
+| |✅ |✅ |❌ | Staking |
++------------+----------------------+--------------------+------------------+-------------------------------------------------------------+
+| |✅ |✅ |✅ | Unstaking (if it can't be combined with the Staking bundle) |
++------------+----------------------+--------------------+------------------+-------------------------------------------------------------+
+| |✅ |✅ |✅ | Post-quantum fast payment protocol |
++------------+----------------------+--------------------+------------------+-------------------------------------------------------------+
+
+.. raw:: html
+
+
+
+Transaction Format
+------------------
+
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==============================+================================================+=====================================================================+
+| **Common Transaction Fields** |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| 4 |``header`` |``uint32`` |Contains: |
+| | | | |
+| | | |* ``fOverwintered`` flag (bit 31, always set) |
+| | | |* ``version`` (bits 30 .. 0) – transaction version. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| 4 |``nVersionGroupId`` |``uint32`` |Version group ID (nonzero). |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| 4 |``nConsensusBranchId`` |``uint32`` |Consensus branch ID (nonzero). |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| 4 |``lock_time`` |``uint32`` |Unix-epoch UTC time or block height, encoded as in Bitcoin. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| 4 |``nExpiryHeight`` |``uint32`` |A block height in the range {1 .. 499999999} after which |
+| | | |the transaction will expire, or 0 to disable expiry. [#zip-0203]_ |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| **Transaction transparent value pool balance map** |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``nValuePoolDeltas`` |``compactSize`` |Number of entries in the ``mValuePoolDeltas`` map. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``mValuePoolDeltas`` |``ValuePoolDelta[nValuePoolDeltas]`` |A map describing the change to the transparent value pool produced by|
+| | | |each bundle. Only bundles that produces changes to the transparent |
+| | | |value balance will have corresponding entries in this map. For |
+| | | |bundles that have no data except for a value, such as the ZIP 233 |
+| | | |amount, no additional bundle data will be present in the ``Bundles`` |
+| | | |section. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| **Bundles** |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``nEffectBundles`` |``compactSize`` |Number of bundles in the transaction that have per-bundle data. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``mEffectBundles`` |``BundleData[nEffectBundles]`` |A map from bundle identifier to the effecting data of a bundle. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``nAuthBundles`` |``compactSize`` |Number of bundles in the transaction that have per-bundle data. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``mAuthBundles`` |``BundleData[nAuthBundles]`` |A map from bundle identifier to the authorizing data of a bundle. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+
+``mEffectBundles`` and ``mAuthBundles`` are interpreted as maps keyed by
+bundle type. The entries in each map MUST be in increasing order of key.
+Each map MUST NOT contain more than a single entry for a given key. For each
+key that exists in ``mAuthBundles``, a corresponding entry must exist in
+``mEffectBundles``.
+
+ValuePoolDelta
+--------------
+
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==============================+================================================+=====================================================================+
+| varies |``bundleType`` |``compactSize`` |An encoding of the bundle type identifier. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| 1 |``assetClass`` |``uint8`` |An asset class identifier. 0x00 for the ZEC asset, 0x01 for other |
+| | | |assets. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| one of {0, 64} |``assetUuid`` |``byte[0] or byte[64]`` |If `assetClass == 0`, the zero-length byte array, otherwise a byte |
+| | | |array containing a universally unique 64-byte identifier for the |
+| | | |asset. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| 8 |``value`` |``nonzero int64`` |The net change to the transparent transaction value pool for the |
+| | | |given asset, produced by the bundle with this bundle type identifier.|
+| | | |This value MUST be nonzero; if a ``ValuePoolDelta`` record would |
+| | | |have zero value, it MUST be elided from the encoding |
+| | | |of ``mValuePoolDeltas`` instead. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+
+``mValuePoolDeltas`` is interpreted as a map keyed by the tuple
+$(\mathsf{BundleType}, \mathsf{AssetUuid}).$ The map MUST NOT contain more than
+a single entry for a given key. Lookups in this map are denoted with the
+syntax $\mathsf{mValuePoolDeltas}[(\mathsf{BundleType}, \mathsf{AssetUuid})].$
+
+Let $\mathsf{AssetUuid}(\mathsf{d})$ be the asset indicated by the ``mValuePoolDeltas`` entry $\mathsf{d}.$
+
+.. math::
+
+ \mathsf{AssetUuid}(\mathsf{d}) =
+ \begin{cases}
+ \mathsf{Zec} & \text{if } \mathsf{d}.\mathsf{assetClass} = 0 \\
+ \mathsf{d}.\mathsf{assetUuid} & \text{if } \mathsf{d}.\mathsf{assetClass} = 1 \\
+ \bot & \text{otherwise}
+ \end{cases}
+
+BundleData
+----------
+
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==============================+================================================+=====================================================================+
+| varies |``bundleType`` |``compactSize`` |An encoding of the bundle type identifier. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``nBundleDataLen`` |``compactSize`` |The length of the ``vBundleData`` byte array. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+| varies |``vBundleData`` |``byte[nBundleDataLen]`` |The effecting or authorizing data for the bundle, dependent upon |
+| | | |whether the ``BundleData`` occurs in ``mEffectBundles`` or |
+| | | |``mAuthBundles``. |
++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
+
+
+Transparent Bundle
+------------------
+
+Transparent Effecting Data
+``````````````````````````
+
+The effecting data for the transparent bundle describes the transparent inputs
+being spent and the transparent outputs being created.
+
++-----------------------------+--------------------------+------------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+==========================================+=====================================================================+
+|``varies`` |``tx_in_count`` |``compactSize`` |Number of transparent inputs. |
++-----------------------------+--------------------------+------------------------------------------+---------------------------------------------------------------------+
+|``varies`` |``tx_in_effecting`` |``TransparentInputEffecting[tx_in_count]``|Effecting data for each transparent input. |
++-----------------------------+--------------------------+------------------------------------------+---------------------------------------------------------------------+
+|``varies`` |``tx_out_count`` |``compactSize`` |Number of transparent outputs. |
++-----------------------------+--------------------------+------------------------------------------+---------------------------------------------------------------------+
+|``varies`` |``tx_out`` |``TransparentOutput[tx_out_count]`` |Transparent outputs. |
++-----------------------------+--------------------------+------------------------------------------+---------------------------------------------------------------------+
+
+TransparentInputEffecting
+'''''''''''''''''''''''''
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``32`` |``prevout_hash`` |``byte[32]`` |The transaction ID of the output being spent. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``4`` |``prevout_index`` |``uint32`` |The index of the output being spent within that transaction. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``4`` |``nSequence`` |``uint32`` |Sequence number, encoded as in Bitcoin. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+TransparentOutput
+'''''''''''''''''
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``8`` |``value`` |``int64`` |The value of the output in zatoshi. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``varies`` |``scriptPubKeyLen`` |``compactSize`` |Length of the scriptPubKey. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``scriptPubKeyLen`` |``scriptPubKey`` |``byte[scriptPubKeyLen]`` |The script that must be satisfied to spend this output. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+Transparent Authorizing Data
+````````````````````````````
+
+The authorizing data for the transparent bundle contains the scripts that
+authorize spending of the referenced transparent inputs.
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``varies`` |``tx_in_auth`` |``TransparentInputAuth[tx_in_count]`` |Authorizing data for each transparent input. The number of entries |
+| | | |MUST equal ``tx_in_count`` from the effecting data. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+TransparentInputAuth
+''''''''''''''''''''
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``varies`` |``scriptSigLen`` |``compactSize`` |Length of the scriptSig. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``scriptSigLen`` |``scriptSig`` |``byte[scriptSigLen]`` |The script satisfying the conditions of the referenced output's |
+| | | |scriptPubKey. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+
+Sapling Bundle
+--------------
+
+Sapling Effecting Data
+``````````````````````
+
+The effecting data for the Sapling bundle describes the Sapling spends and
+outputs. Unlike the V5 transaction format defined in ZIP 225 [#zip-0225]_,
+the value balance is not included here; it appears in ``mValuePoolDeltas``
+instead.
+
++-----------------------------+--------------------------+-----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+=========================================+=====================================================================+
+|``varies`` |``nSpendsSapling`` |``compactSize`` |Number of Sapling Spend descriptions. |
++-----------------------------+--------------------------+-----------------------------------------+---------------------------------------------------------------------+
+|``96 * nSpendsSapling`` |``vSpendsSapling`` |``SaplingSpendEffecting[nSpendsSapling]``|Effecting data for each Sapling Spend. |
++-----------------------------+--------------------------+-----------------------------------------+---------------------------------------------------------------------+
+|``varies`` |``nOutputsSapling`` |``compactSize`` |Number of Sapling Output descriptions. |
++-----------------------------+--------------------------+-----------------------------------------+---------------------------------------------------------------------+
+|``756 * nOutputsSapling`` |``vOutputsSapling`` |``SaplingOutput[nOutputsSapling]`` |Sapling Output descriptions. |
++-----------------------------+--------------------------+-----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``anchorSapling`` |``byte[32]`` |A root of the Sapling note commitment tree at some block height |
+| | | |in the past. |
++-----------------------------+--------------------------+-----------------------------------------+---------------------------------------------------------------------+
+
+* The field ``anchorSapling`` is present if and only if $\mathtt{nSpendsSapling} > 0$.
+
+SaplingSpendEffecting
+'''''''''''''''''''''
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the input note. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``nullifier`` |``byte[32]`` |The nullifier of the input note. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``rk`` |``byte[32]`` |The randomized validating key for this Spend. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+SaplingOutput
+'''''''''''''
+
+This is identical to ``OutputDescriptionV5`` as defined in ZIP 225 [#zip-0225]_.
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the output note. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``cmu`` |``byte[32]`` |The :math:`u\!`-coordinate of the note commitment for the output |
+| | | |note. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``ephemeralKey`` |``byte[32]`` |An encoding of an ephemeral Jubjub public key. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``580`` |``encCiphertext`` |``byte[580]`` |The encrypted contents of the note plaintext. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``80`` |``outCiphertext`` |``byte[80]`` |The encrypted contents of the byte string created by concatenation |
+| | | |of the transmission key with the ephemeral secret key. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+Sapling Authorizing Data
+````````````````````````
+
+The authorizing data for the Sapling bundle contains the proofs and signatures
+that authorize the spends and validate the outputs.
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``192 * nSpendsSapling`` |``vSpendProofsSapling`` |``byte[192 * nSpendsSapling]`` |Encodings of the zk-SNARK proofs for each Sapling Spend. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``64 * nSpendsSapling`` |``vSpendAuthSigsSapling`` |``byte[64 * nSpendsSapling]`` |Authorizing signatures for each Sapling Spend. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``192 * nOutputsSapling`` |``vOutputProofsSapling`` |``byte[192 * nOutputsSapling]`` |Encodings of the zk-SNARK proofs for each Sapling Output. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``64`` |``bindingSigSapling`` |``byte[64]`` |A Sapling binding signature on the SIGHASH transaction hash. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+* The values of ``nSpendsSapling`` and ``nOutputsSapling`` are not re-encoded in
+ the authorizing data; they are taken from the corresponding effecting data.
+
+* The field ``bindingSigSapling`` is present if and only if
+ $\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0$.
+
+* The elements of ``vSpendProofsSapling`` and ``vSpendAuthSigsSapling`` have a
+ 1:1 correspondence to the elements of ``vSpendsSapling`` in the effecting data
+ and MUST be ordered such that the element at a given index corresponds to the
+ ``SaplingSpendEffecting`` at the same index.
+
+* The elements of ``vOutputProofsSapling`` have a 1:1 correspondence to the
+ elements of ``vOutputsSapling`` in the effecting data and MUST be ordered such
+ that the proof at a given index corresponds to the ``SaplingOutput`` at the
+ same index.
+
+
+Orchard Bundle
+--------------
+
+Orchard Effecting Data
+``````````````````````
+
+The effecting data for the Orchard bundle describes the Orchard actions. Unlike
+the V5 transaction format defined in ZIP 225 [#zip-0225]_, the value balance is
+not included here; it appears in ``mValuePoolDeltas`` instead.
+
++-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+===========================================+=====================================================================+
+|``varies`` |``nActionsOrchard`` |``compactSize`` |The number of Orchard Action descriptions. |
++-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+
+|``820 * nActionsOrchard`` |``vActionsOrchard`` |``OrchardActionEffecting[nActionsOrchard]``|Effecting data for each Orchard Action. |
++-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+
+|``1`` |``flagsOrchard`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: |
+| | | | |
+| | | |* ``enableSpendsOrchard`` |
+| | | |* ``enableOutputsOrchard`` |
+| | | |* The remaining bits are set to :math:`0\!`. |
++-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+
+|``32`` |``anchorOrchard`` |``byte[32]`` |A root of the Orchard note commitment tree at some block height |
+| | | |in the past. |
++-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+
+
+* The fields ``flagsOrchard`` and ``anchorOrchard`` are present if and only if
+ $\mathtt{nActionsOrchard} > 0$.
+
+* For coinbase transactions, the ``enableSpendsOrchard`` bit MUST be set to $0$.
+
+OrchardActionEffecting
+''''''''''''''''''''''
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the input note minus the |
+| | | |output note. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``nullifier`` |``byte[32]`` |The nullifier of the input note. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``rk`` |``byte[32]`` |The randomized validating key for this Action. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``cmx`` |``byte[32]`` |The :math:`x\!`-coordinate of the note commitment for the output |
+| | | |note. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``32`` |``ephemeralKey`` |``byte[32]`` |An encoding of an ephemeral Pallas public key. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``580`` |``encCiphertext`` |``byte[580]`` |The encrypted contents of the note plaintext. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``80`` |``outCiphertext`` |``byte[80]`` |The encrypted contents of the byte string created by concatenation |
+| | | |of the transmission key with the ephemeral secret key. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+Orchard Authorizing Data
+````````````````````````
+
+The authorizing data for the Orchard bundle contains the proofs and signatures
+that authorize the actions.
+
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+| Bytes | Name | Data Type | Description |
++=============================+==========================+========================================+=====================================================================+
+|``varies`` |``sizeProofsOrchard`` |``compactSize`` |Length in bytes of ``proofsOrchard``. Value is |
+| | | |:math:`2720 + 2272 \cdot \mathtt{nActionsOrchard}\!`. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``sizeProofsOrchard`` |``proofsOrchard`` |``byte[sizeProofsOrchard]`` |Encoding of aggregated zk-SNARK proofs for Orchard Actions. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``64 * nActionsOrchard`` |``vSpendAuthSigsOrchard`` |``byte[64 * nActionsOrchard]`` |Authorizing signatures for each Orchard Action. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+|``64`` |``bindingSigOrchard`` |``byte[64]`` |An Orchard binding signature on the SIGHASH transaction hash. |
++-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
+
+* The value of ``nActionsOrchard`` is not re-encoded in the authorizing data; it
+ is taken from the corresponding effecting data.
+
+* The fields ``sizeProofsOrchard``, ``proofsOrchard``, and ``bindingSigOrchard``
+ are present if and only if $\mathtt{nActionsOrchard} > 0$.
+
+* The proofs aggregated in ``proofsOrchard``, and the elements of
+ ``vSpendAuthSigsOrchard``, each have a 1:1 correspondence to the elements of
+ ``vActionsOrchard`` in the effecting data and MUST be ordered such that the
+ proof or signature at a given index corresponds to the
+ ``OrchardActionEffecting`` at the same index.
+
+
+Consensus Rules
+---------------
+
+This ZIP requires the following modifications to the consensus rules in the
+Zcash Protocol Specification.
+
+Let ``FeeBundleId`` be the identifier of the fee bundle. In V6 transactions,
+$\mathsf{FeeBundleId} = 4$ as defined in the table above.
+
+The following transaction validity rules are added:
+
+* The ``assetClass`` value for any entry in ``mValuePoolDeltas`` having
+ ``bundleType = FeeBundleId`` is 0 (fee amounts are denominated in ZEC
+ and no other asset.)
+
+* For coinbase transactions, the value of $\mathsf{mValuePoolDeltas}[(\mathsf{FeeBundleId}, \mathsf{Zec})]$
+ must be nonnegative. This represents the total transaction fees collected from
+ all other transactions in the block.
+
+* For non-coinbase transactions, the value of $\mathsf{mValuePoolDeltas}[(\mathsf{FeeBundleId}, \mathsf{Zec})]$
+ must be nonpositive. This represents the transaction fee paid by the
+ transaction (expressed as a negative value, since it is removed from the
+ transparent transaction value pool).
+
+* Within the scope of a block, the sum of the fee bundle values must equal 0.
+ That is, the fees collected by the coinbase transaction must equal the sum of
+ fees paid by all other transactions in the block.
+
+* Certain bundle types are mutually exclusive: a transaction MUST NOT contain
+ more than one bundle from each of the following sets:
+
+ * {Sapling, Sapling-post-ZIP-231}
+ * {Orchard, Orchard-post-ZIP-231, OrchardZSA}
+
+* For the coinbase transaction, the sum of value pool deltas in the ZEC asset
+ is equal to the negative of the block subsidy for that block; the block
+ subsidy adds an implicit input value to the transparent transaction value
+ pool that the coinbase outputs consume.
+
+ .. math::
+
+ \sum_{\mathsf{d} \in \mathsf{mValuePoolDeltas} | \mathsf{AssetUuid}(\mathsf{d}) = \mathsf{Zec}} \mathsf{d.value} = -\mathsf{BlockSubsidy}(\mathsf{height})
+
+ where $\mathsf{BlockSubsidy}$ is defined in § 7.8 'Block Subsidy and
+ Founders' Reward'. [#protocol-subsidies]_
+
+* For all non-coinbase transactions, the sum of value pool delta values in each
+ asset equals 0.
+
+ .. math::
+
+ \forall \mathsf{a}. \sum_{\mathsf{d} \in \mathsf{mValuePoolDeltas} | \mathsf{AssetUuid}(\mathsf{d}) = \mathsf{a}} \mathsf{d.value} = 0
+
+Digest Algorithms
+-----------------
+
+All digests are personalized BLAKE2b-256 hashes. In cases where no elements are
+available for hashing (for example, if there are no transparent transaction
+inputs), a personalized hash of the empty byte array will be used. The
+personalization string therefore provides domain separation for the hashes of
+even empty data fields.
+
+The notation ``BLAKE2b-256(personalization_string, [])`` is used to refer to
+hashes constructed in this manner.
+
+TxId Digest
+```````````
+
+A new transaction digest algorithm is defined that constructs the identifier for
+a V6 transaction from a tree of hashes. The overall structure of the hash is as
+follows::
+
+ txid_digest
+ ├── header_digest
+ ├── value_pool_deltas_digest
+ └── effects_bundles_digest
+ ├─ (bundle_type_id || transparent_effects_digest)
+ ├─ (bundle_type_id || sapling_effects_digest)
+ │ ├── sapling_spends_digest
+ │ │ ├── sapling_spends_compact_digest
+ │ │ └── sapling_spends_noncompact_digest
+ │ └── sapling_outputs_digest
+ │ ├── sapling_outputs_compact_digest
+ │ ├── sapling_outputs_memos_digest
+ │ └── sapling_outputs_noncompact_digest
+ ├─ (bundle_type_id || orchard_effects_digest)
+ │ ├── orchard_actions_compact_digest
+ │ ├── orchard_actions_memos_digest
+ │ └── orchard_actions_noncompact_digest
+ └─ (bundle_type_id || unknown_bundle_effects_digest) ...
+
+Each node written as ``snake_case`` in this tree is a BLAKE2b-256 hash of its
+children, initialized with a personalization string specific to that branch
+of the tree. Nodes that are not themselves digests are written in ``camelCase``.
+In the specification below, nodes of the tree are presented in depth-first order.
+
+txid_digest
+'''''''''''
+
+A BLAKE2b-256 hash of the following values::
+
+ T.1: header_digest (32-byte hash output)
+ T.2: value_pool_deltas_digest (32-byte hash output)
+ T.3: effects_bundles_digest (32-byte hash output)
+
+The personalization field of this hash is set to::
+
+ "ZcashTxHash_" || CONSENSUS_BRANCH_ID
+
+``ZcashTxHash_`` has 1 underscore character.
+
+As in ZIP 143 [#zip-0143]_, CONSENSUS_BRANCH_ID is the 4-byte little-endian
+encoding of the consensus branch ID for the epoch of the block containing the
+transaction.
+
+T.1: header_digest
+''''''''''''''''''
+
+A BLAKE2b-256 hash of the following values::
+
+ T.1a: version (4-byte little-endian version identifier including overwintered flag)
+ T.1b: version_group_id (4-byte little-endian version group identifier)
+ T.1c: consensus_branch_id (4-byte little-endian consensus branch id)
+ T.1d: lock_time (4-byte little-endian nLockTime value)
+ T.1e: expiry_height (4-byte little-endian block height)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdHeadersHash"
+
+T.2: value_pool_deltas_digest
+'''''''''''''''''''''''''''''
+
+A BLAKE2b-256 hash of the concatenated encodings of all entries in
+``mValuePoolDeltas``, in increasing order of ``(bundleType, assetClass, assetUuid)``.
+For each entry, the following values are concatenated::
+
+ T.2a: bundleType (compactSize encoding)
+ T.2b: assetClass (1 byte)
+ T.2c: assetUuid (0 or 64 bytes, depending on assetClass)
+ T.2d: value (8-byte signed little-endian)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdVPDeltaHash"
+
+In the case that the transaction has no value pool delta entries (which would
+only occur for transactions that have no effect on any value pool),
+``value_pool_deltas_digest`` is::
+
+ BLAKE2b-256("ZTxIdVPDeltaHash", [])
+
+T.3: effects_bundles_digest
+'''''''''''''''''''''''''''
+
+A BLAKE2b-256 hash of the concatenated tagged bundle effect digests for all
+bundles present in ``mEffectBundles``, in increasing order of ``bundleType``. For each
+bundle, the following values are concatenated::
+
+ T.3a: bundleType (compactSize encoding)
+ T.3b: bundle_effects_digest (32-byte hash output)
+
+where ``bundle_effects_digest`` is the root hash of the bundle's effecting data
+tree, as defined below for each known bundle type.
+
+The personalization field of this hash is set to::
+
+ "ZTxIdEffBndHash"
+
+In the case that the transaction has no effect bundles, ``effects_bundles_digest``
+is::
+
+ BLAKE2b-256("ZTxIdEffBndHash", [])
+
+For bundle types not recognized by a wallet, the wallet MUST be provided with the
+32-byte ``bundle_effects_digest`` value in order to compute the transaction
+identifier. This enables partial verification of transactions containing unknown
+bundle types.
+
+T.3.0: transparent_effects_digest
+.................................
+
+In the case that transparent inputs or outputs are present, the transparent
+effects digest is a BLAKE2b-256 hash of the following values::
+
+ T.3.0a: prevouts_digest (32-byte hash)
+ T.3.0b: sequence_digest (32-byte hash)
+ T.3.0c: outputs_digest (32-byte hash)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdTranspaHash"
+
+In the case that the transaction has no transparent components,
+``transparent_effects_digest`` is::
+
+ BLAKE2b-256("ZTxIdTranspaHash", [])
+
+T.3.0a: prevouts_digest
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the field encoding of all ``(prevout_hash, prevout_index)``
+pairs from the transparent effecting data.
+
+The personalization field of this hash is set to::
+
+ "ZTxIdPrevoutHash"
+
+In the case that the transaction has transparent outputs but no transparent
+inputs, ``prevouts_digest`` is::
+
+ BLAKE2b-256("ZTxIdPrevoutHash", [])
+
+T.3.0b: sequence_digest
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the 32-bit little-endian representation of all ``nSequence``
+field values from the transparent effecting data.
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSequencHash"
+
+In the case that the transaction has transparent outputs but no transparent
+inputs, ``sequence_digest`` is::
+
+ BLAKE2b-256("ZTxIdSequencHash", [])
+
+T.3.0c: outputs_digest
+~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the concatenated field encodings of all transparent
+outputs. The field encoding of each output consists of the encoded output
+``value`` (8-byte little endian) followed by the ``scriptPubKey`` byte array
+(with leading ``compactSize`` length).
+
+The personalization field of this hash is set to::
+
+ "ZTxIdOutputsHash"
+
+In the case that the transaction has transparent inputs but no transparent
+outputs, ``outputs_digest`` is::
+
+ BLAKE2b-256("ZTxIdOutputsHash", [])
+
+T.3.2: sapling_effects_digest
+.............................
+
+In the case that Sapling spends or outputs are present, the Sapling effects
+digest is a BLAKE2b-256 hash of the following values::
+
+ T.3.2a: sapling_spends_digest (32-byte hash)
+ T.3.2b: sapling_outputs_digest (32-byte hash)
+ T.3.2c: anchorSapling (32 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSaplingHash"
+
+Note that unlike ZIP 244, the value balance is not included here; it is committed
+via ``value_pool_deltas_digest`` instead.
+
+In the case that the transaction has no Sapling spends or outputs,
+``sapling_effects_digest`` is::
+
+ BLAKE2b-256("ZTxIdSaplingHash", [])
+
+T.3.2a: sapling_spends_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the case that Sapling spends are present, this digest is a BLAKE2b-256 hash
+of the following values::
+
+ T.3.2a.i: sapling_spends_compact_digest (32-byte hash)
+ T.3.2a.ii: sapling_spends_noncompact_digest (32-byte hash)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSSpendsHash"
+
+In the case that the transaction has Sapling outputs but no Sapling spends,
+``sapling_spends_digest`` is::
+
+ BLAKE2b-256("ZTxIdSSpendsHash", [])
+
+T.3.2a.i: sapling_spends_compact_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the field encoding of all ``nullifier`` field values
+of Sapling spends belonging to the transaction.
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSSpendCHash"
+
+T.3.2a.ii: sapling_spends_noncompact_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the non-nullifier information for all Sapling spends
+belonging to the transaction. For each spend, the following elements are
+included in the hash::
+
+ T.3.2a.ii.1: cv (32 bytes)
+ T.3.2a.ii.2: anchor (32 bytes)
+ T.3.2a.ii.3: rk (32 bytes)
+
+The anchor is hashed for *each* spend (even though it is shared in the encoding).
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSSpendNHash"
+
+T.3.2b: sapling_outputs_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the case that Sapling outputs are present, this digest is a BLAKE2b-256 hash
+of the following values::
+
+ T.3.2b.i: sapling_outputs_compact_digest (32-byte hash)
+ T.3.2b.ii: sapling_outputs_memos_digest (32-byte hash)
+ T.3.2b.iii: sapling_outputs_noncompact_digest (32-byte hash)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSOutputHash"
+
+In the case that the transaction has Sapling spends but no Sapling outputs,
+``sapling_outputs_digest`` is::
+
+ BLAKE2b-256("ZTxIdSOutputHash", [])
+
+T.3.2b.i: sapling_outputs_compact_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the subset of Sapling output information included in the
+ZIP 307 [#zip-0307]_ ``CompactBlock`` format for all Sapling outputs belonging
+to the transaction. For each output, the following elements are included::
+
+ T.3.2b.i.1: cmu (32 bytes)
+ T.3.2b.i.2: ephemeralKey (32 bytes)
+ T.3.2b.i.3: encCiphertext[..52] (first 52 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSOutC__Hash" (2 underscore characters)
+
+T.3.2b.ii: sapling_outputs_memos_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the memo field data for all Sapling outputs belonging to
+the transaction. For each output::
+
+ T.3.2b.ii.1: encCiphertext[52..564] (512 bytes, encrypted memo)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSOutM__Hash" (2 underscore characters)
+
+T.3.2b.iii: sapling_outputs_noncompact_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the remaining Sapling output information not included in
+the ``CompactBlock`` format. For each output::
+
+ T.3.2b.iii.1: cv (32 bytes)
+ T.3.2b.iii.2: encCiphertext[564..] (post-memo AEAD tag, 16 bytes)
+ T.3.2b.iii.3: outCiphertext (80 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdSOutN__Hash" (2 underscore characters)
+
+T.3.3: orchard_effects_digest
+.............................
+
+In the case that Orchard actions are present, the Orchard effects digest is a
+BLAKE2b-256 hash of the following values::
+
+ T.3.3a: orchard_actions_compact_digest (32-byte hash)
+ T.3.3b: orchard_actions_memos_digest (32-byte hash)
+ T.3.3c: orchard_actions_noncompact_digest (32-byte hash)
+ T.3.3d: flagsOrchard (1 byte)
+ T.3.3e: anchorOrchard (32 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdOrchardHash"
+
+Note that unlike ZIP 244, the value balance is not included here; it is committed
+via ``value_pool_deltas_digest`` instead.
+
+In the case that the transaction has no Orchard actions, ``orchard_effects_digest``
+is::
+
+ BLAKE2b-256("ZTxIdOrchardHash", [])
+
+T.3.3a: orchard_actions_compact_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the subset of Orchard action information intended for
+inclusion in the ``CompactBlock`` format. For each action::
+
+ T.3.3a.i: nullifier (32 bytes)
+ T.3.3a.ii: cmx (32 bytes)
+ T.3.3a.iii: ephemeralKey (32 bytes)
+ T.3.3a.iv: encCiphertext[..52] (first 52 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdOrcActCHash"
+
+T.3.3b: orchard_actions_memos_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the memo field data for all Orchard actions. For each
+action::
+
+ T.3.3b.i: encCiphertext[52..564] (512 bytes, encrypted memo)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdOrcActMHash"
+
+T.3.3c: orchard_actions_noncompact_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A BLAKE2b-256 hash of the remaining Orchard action information not intended for
+inclusion in the ``CompactBlock`` format. For each action::
+
+ T.3.3c.i: cv (32 bytes)
+ T.3.3c.ii: rk (32 bytes)
+ T.3.3c.iii: encCiphertext[564..] (post-memo AEAD tag, 16 bytes)
+ T.3.3c.iv: outCiphertext (80 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdOrcActNHash"
+
+Signature Digest
+````````````````
+
+A new per-input transaction digest algorithm is defined that constructs a hash
+that may be signed by a transaction creator to commit to the effects of the
+transaction. This follows closely the algorithm from ZIP 244 [#zip-0244]_.
+
+For transactions that have no transparent inputs, the signature digest is
+identical to the transaction identifier digest.
+
+For transactions with transparent inputs, the signature digest replaces
+``effects_bundles_digest`` with a ``signature_bundles_digest`` that incorporates
+``hash_type``-dependent transparent signing data::
+
+ signature_digest
+ ├── header_digest
+ ├── value_pool_deltas_digest
+ └── signature_bundles_digest
+
+signature_digest
+''''''''''''''''
+
+A BLAKE2b-256 hash of the following values::
+
+ S.1: header_digest (32-byte hash output)
+ S.2: value_pool_deltas_digest (32-byte hash output)
+ S.3: signature_bundles_digest (32-byte hash output)
+
+The personalization field of this hash is set to::
+
+ "ZcashTxHash_" || CONSENSUS_BRANCH_ID
+
+This value has the same personalization as the transaction identifier digest,
+so that what is being signed in the case that there are no transparent inputs
+is exactly the transaction id.
+
+S.3: signature_bundles_digest
+'''''''''''''''''''''''''''''
+
+If the transaction has no transparent inputs, ``signature_bundles_digest`` is
+identical to ``effects_bundles_digest``.
+
+Otherwise, ``signature_bundles_digest`` is constructed the same as
+``effects_bundles_digest``, except that ``transparent_effects_digest`` is
+replaced with ``transparent_sig_digest``.
+
+S.3.0: transparent_sig_digest
+.............................
+
+This digest is a BLAKE2b-256 hash of the following values::
+
+ S.3.0a: hash_type (1 byte)
+ S.3.0b: prevouts_sig_digest (32-byte hash)
+ S.3.0c: amounts_sig_digest (32-byte hash)
+ S.3.0d: scriptpubkeys_sig_digest (32-byte hash)
+ S.3.0e: sequence_sig_digest (32-byte hash)
+ S.3.0f: outputs_sig_digest (32-byte hash)
+ S.3.0g: txin_sig_digest (32-byte hash)
+
+The personalization field of this hash is set to::
+
+ "ZTxIdTranspaHash"
+
+S.3.0a: hash_type
+~~~~~~~~~~~~~~~~~
+
+An 8-bit unsigned value. The ``SIGHASH`` encodings from the legacy script system
+are used: one of ``SIGHASH_ALL`` (0x01), ``SIGHASH_NONE`` (0x02), or
+``SIGHASH_SINGLE`` (0x03), optionally combined with ``SIGHASH_ANYONECANPAY`` (0x80).
+
+The following restrictions apply:
+
+- Using any undefined ``hash_type`` (not 0x01, 0x02, 0x03, 0x81, 0x82, or 0x83)
+ causes validation failure.
+- Using ``SIGHASH_SINGLE`` without a corresponding output at the same index
+ causes validation failure.
+
+For signatures over Sapling Spends or Orchard Actions, ``hash_type`` is set to
+``SIGHASH_ALL`` (0x01).
+
+S.3.0b: prevouts_sig_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the ``SIGHASH_ANYONECANPAY`` flag is not set, identical to ``prevouts_digest``
+(T.3.0a).
+
+Otherwise::
+
+ BLAKE2b-256("ZTxIdPrevoutHash", [])
+
+S.3.0c: amounts_sig_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the ``SIGHASH_ANYONECANPAY`` flag is not set, a BLAKE2b-256 hash of the
+concatenation of the 8-byte signed little-endian representations of all ``value``
+fields for the coins spent by the transparent inputs to the transaction.
+
+The personalization field of this hash is set to::
+
+ "ZTxTrAmountsHash"
+
+If the ``SIGHASH_ANYONECANPAY`` flag is set::
+
+ BLAKE2b-256("ZTxTrAmountsHash", [])
+
+S.3.0d: scriptpubkeys_sig_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the ``SIGHASH_ANYONECANPAY`` flag is not set, a BLAKE2b-256 hash of the
+concatenation of the field encodings (each including a leading ``compactSize``)
+of all ``scriptPubKey`` fields for the coins spent by the transparent inputs.
+
+The personalization field of this hash is set to::
+
+ "ZTxTrScriptsHash"
+
+If the ``SIGHASH_ANYONECANPAY`` flag is set::
+
+ BLAKE2b-256("ZTxTrScriptsHash", [])
+
+S.3.0e: sequence_sig_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Identical to ``sequence_digest`` (T.3.0b) regardless of ``hash_type``.
+
+S.3.0f: outputs_sig_digest
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the sighash type is neither ``SIGHASH_SINGLE`` nor ``SIGHASH_NONE``, identical
+to ``outputs_digest`` (T.3.0c).
+
+If the sighash type is ``SIGHASH_SINGLE`` and a transparent output exists at the
+same index as the input being signed, a hash of that output's encoding.
+
+Otherwise::
+
+ BLAKE2b-256("ZTxIdOutputsHash", [])
+
+S.3.0g: txin_sig_digest
+~~~~~~~~~~~~~~~~~~~~~~~
+
+For signatures over a transparent input, a BLAKE2b-256 hash of::
+
+ S.3.0g.i: prevout (36 bytes: 32-byte hash + 4-byte index)
+ S.3.0g.ii: value (8-byte signed little-endian)
+ S.3.0g.iii: scriptPubKey (with compactSize length prefix)
+ S.3.0g.iv: nSequence (4-byte unsigned little-endian)
+
+The personalization field of this hash is set to::
+
+ "Zcash___TxInHash" (3 underscores)
+
+For signatures over a Sapling Spend or Orchard Action::
+
+ BLAKE2b-256("Zcash___TxInHash", [])
+
+Authorizing Data Commitment
+```````````````````````````
+
+A transaction digest algorithm is defined that constructs a digest committing to
+the authorizing data of a transaction. The overall structure is::
+
+ auth_digest
+ └── auth_bundles_digest
+ ├─ (bundle_type_id || transparent_auth_digest)
+ ├─ (bundle_type_id || sapling_auth_digest)
+ ├─ (bundle_type_id || orchard_auth_digest)
+ └─ (bundle_type_id || unknown_bundle_auth_digest) ...
+
+auth_digest
+'''''''''''
+
+A BLAKE2b-256 hash of the following value::
+
+ A.1: auth_bundles_digest (32-byte hash output)
+
+The personalization field of this hash is set to::
+
+ "ZTxAuthHash_" || CONSENSUS_BRANCH_ID
+
+For transaction versions before V6, a placeholder value consisting of 32 bytes
+of ``0xFF`` is used in place of the authorizing data commitment.
+
+A.1: auth_bundles_digest
+''''''''''''''''''''''''
+
+A BLAKE2b-256 hash of the concatenated tagged bundle auth digests for all
+bundles present in ``mAuthBundles``, in increasing order of ``bundleType``. For each
+bundle, the following values are concatenated::
+
+ A.1a: bundleType (compactSize encoding)
+ A.1b: bundle_auth_digest (32-byte hash output)
+
+The personalization field of this hash is set to::
+
+ "ZTxAuthBndHash"
+
+In the case that the transaction has no auth bundles, ``auth_bundles_digest`` is::
+
+ BLAKE2b-256("ZTxAuthBndHash", [])
+
+A.1.0: transparent_auth_digest
+..............................
+
+In the case that the transaction contains transparent inputs, this is a
+BLAKE2b-256 hash of the concatenated ``scriptSig`` values (each with leading
+``compactSize`` length) for all transparent inputs.
+
+The personalization field of this hash is set to::
+
+ "ZTxAuthTransHash"
+
+In the case that the transaction has no transparent inputs::
+
+ BLAKE2b-256("ZTxAuthTransHash", [])
+
+A.1.2: sapling_auth_digest
+..........................
+
+In the case that Sapling spends or outputs are present, this is a BLAKE2b-256
+hash of the following concatenated values::
+
+ A.1.2a: vSpendProofsSapling (192 bytes per spend)
+ A.1.2b: vSpendAuthSigsSapling (64 bytes per spend)
+ A.1.2c: vOutputProofsSapling (192 bytes per output)
+ A.1.2d: bindingSigSapling (64 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxAuthSapliHash"
+
+In the case that the transaction has no Sapling spends or outputs::
+
+ BLAKE2b-256("ZTxAuthSapliHash", [])
+
+A.1.3: orchard_auth_digest
+..........................
+
+In the case that Orchard actions are present, this is a BLAKE2b-256 hash of the
+following concatenated values::
+
+ A.1.3a: proofsOrchard (aggregated proofs)
+ A.1.3b: vSpendAuthSigsOrchard (64 bytes per action)
+ A.1.3c: bindingSigOrchard (64 bytes)
+
+The personalization field of this hash is set to::
+
+ "ZTxAuthOrchaHash"
+
+In the case that the transaction has no Orchard actions::
+
+ BLAKE2b-256("ZTxAuthOrchaHash", [])
+
+
+Rationale
+=========
+
+TODO: Document why we take the specific approach we do on what the format
+constrains vs what wallets are expected (required?) to notify users of (once we
+decide on the approach).
+
+Effecting data bundles and authorizing data bundles are stored separately in
+the transaction format so that the authorizing data may be pruned by
+straightforward truncation of the encoded representation of the transaction.
+
+
+Deployment
+==========
+
+
+Reference implementation
+========================
+
+
+Open issues
+===========
+
+Notes from design sessions
+==========================
+
+This section should be removed as soon as all the considerations described here
+are accounted for in ZIP.
+
+Wallets or consensus-dependent applications that send transactions, might do
+something wrong that compromises user funds or privacy if they do not take into
+account consensus changes in an upgrade; therefore, only a subset of consensus
+changes can be safely adapted to using this mechanism.
+
+In particular, consensus rules may change in such a way that a wallet doing
+what it has done in the past causes risk of loss of funds.
+
+An example of this was ZIP 212 [#zip-0212]_. In that case
+the existing mechanisms failed to prevent loss of funds because in practice,
+wallets updated the consensus branch ID without updating note encryption. We
+made the mistake of requiring wallets to change their behaviour for an existing
+transaction version. Except for certain cases involving severe security flaws,
+we should avoid doing that again.
+
+If a wallet needs to actively do something differently (for example,
+advertizing addresses in a new format or creating an output with a TZE
+precondition) in order to be affected by a new feature, then it is reasonably
+safe for it to ignore the feature as long as it can still parse transactions
+and, and create and sign transactions that don't make use of those features.
+
+It is okay that such a wallet might not be able to see funds that depend on new
+features, as long as they do not create such funds themselves.
+
+Loss of funds is unacceptable. Temporary inaccessibility of funds in certain
+circumstances can be okay -- provided that this potential inaccessiblity and
+the circumstances where it can occur is documented and an explicit design
+decision.
+
+Strawman
+--------
+
+Modify how we approach transaction format evolution, such that (after one more
+change to transaction encoding) it is possible for a wallet that has not
+adopted a parser for a given transaction format to continue to function after
+an *additive* change to the transaction format. Another way to state this is
+that we should make it possible to make "semver-compatible" transaction format
+changes.
+
+* @str4d: We could use a TLV approach where each "bundle" has a value balance.
+ The NSM burn amount field could be its own bundle, the explicit fee data
+ could be its own bundle and the consensus rule could be that all value
+ balances sum to zero.
+
+ * generically, you want a value balance vector, where you have zero or more
+ value balances moving between bundles in other assets.
+
+* @nuttycom: You could have pre-ZSA and post-ZSA Orchard bundles.
+
+Strawman II
+-----------
+
+Treat bundles as individually versioned.
+
+* Each bundle is registered with an ID relative to a tx version group ID.
+* The bundle ID encoding also has some flag bits indicating how it interacts
+ with the tx as a whole.
+* Transactions then have two "bundle maps":
+
+ * The first encodes how value moves between the different bundles.
+ * The second encodes data specific to a bundle (e.g. how value moves within a bundle)
+ * Bundles that don't have any data would just appear in the first map, and
+ bundles that don't produce or consume value would just appear in the
+ second map.
+* We can re-interpret various other facets of transactions as "bundles"
+
+ * Explicit fees are a bundle that never produces value
+ * NSM field similarly never produces value
+ * ZSA burns would be split into "value balance out of Orchard pool" and
+ "value balance being removed from ZSA issuance"
+ * See also the conversation we had about refactoring coinbase transactions.
+ TODO: Figure out how to integrate the two.
+* Privacy effect is minimal
+
+ * We already follow a bundle approach with a transparent transaction value
+ pool, for the turnstiles. This leans into it, while preserving the bundle
+ boundary within which we implement each privacy protocol.
+ * Some combinations of bundles would be permitted by the tx format that
+ were not previously permitted.
+
+ * However, we can still restrict which combinations of bundles can be
+ mined in the consensus rules.
+
+Sketch of the format:
+
+* Transaction version (like now)
+
+ * Version
+ * Version group ID
+
+* Transaction header
+
+ * Expiry height etc
+ * Likely need some kind of key-value map here to allow additional fields to
+ be added, or maybe version the header to allow evolution?
+
+* Transparent transaction value pool "traffic map"
+
+ * Option 1: BundleVersionID -> (valueBalance, AssetId -> valueBalance)
+
+ * Key: Bundle version ID
+ * Value:
+
+ * ZEC `valueBalance`
+ * CompactSize len(generalizedValueBalances)
+ * Zero or more generalized value balances
+
+ * `AssetId` (not `AssetBase` because those are
+ protocol-specific, and we want generalized value balances to
+ be understandable independently of protocol changes)
+ * `valueBalance`
+
+ * Option 2: (BundleVersionID, Option[AssetId]) -> valueBalance
+
+ * Key: Bundle version ID encoded as u8 || { Option[AssetId] }
+ * Value: `valueBalance`
+
+ * Option 3: BundleVersionID -> Option[AssetId] -> valueBalance
+
+ * Key: Bundle version ID
+ * Value:
+
+ * Map containing one or more generalized value balances
+
+ * { Option[AssetId] }
+ * `valueBalance`
+* Sequence of bundles (maybe with a length prefix?)
+
+ * Bundle version ID
+
+ * Maybe flag bits, either in the version ID or next to it, that
+ indicate how an opaquely-parsing wallet should interpret the bundle,
+ e.g.:
+
+ * A bit that says whether or not the bundle interacts with the
+ transparent transaction value pool (which memo bundles would not
+ have).
+
+ * Counterpoint: The traffic map already specifies whether a
+ given bundle *does* have an interaction with the transparent
+ tx value pool for this tx. This is different from whether
+ that kind of bundle *can* interact with the transparent tx
+ value pool, but it the latter needed?
+
+ * A bit that says whether the bundle has any other effect than what
+ is specified in the traffic map.
+
+ * Counterpoint: We should split apart effecting and authorizing
+ data in the encoding, and then a bundle must be assumed
+ effecting iff it has non-null effecting data.
+
+ * CompactSize len(effectingData)
+
+ * effectingData
+
+ * CompactSize len(authorizingData)
+
+ * authorizingData
+
+ * effectingData and authorizingData would be opaque to the initial
+ parser.
+ * Parsers that support parsing (tx_version, bundle_version) know how to
+ interpret its internals
+
+Questions
+---------
+
+* Is it okay for fee calculations to be opaque to wallet parsers, as long as
+ the fee amounts can be calculated in consensus?
+
+ * Yes:
+
+ * When receiving, all you care about is knowing the actual fee amount;
+ you see that in the fee bundle's value balance.
+ * When sending, you need to understand all bundles you are including,
+ and then you can calculate the fee.
+
+* Can wallets still compute the txid and wtxid of an arbitrary transaction?
+
+ * Yes, provided that effecting and authorizing data is separated. Then they
+ can hash the effecting data even without understanding it to compute the
+ txid, and they can hash the authorizing data even without understanding
+ it to compute the authorizing data commitment part of the wtxid (ZIP
+ 239 [#zip-0239]_).
+ * *However*, this reintroduces a more direct linkage between the [w]txid
+ computation and the transaction encoding. It's arguably fine, and
+ potentially simpler -- since the [w]txid computation need not change at
+ all for most protocol changes.
+ * If the hashing uses flat hashes over the effectingData and
+ authorizingData of each bundle (which it has to because the internal
+ structure is not known), then it might be more difficult to do Merkle
+ proofs over subsets of the data within a bundle. We haven't used that so
+ far; is it really needed?
+
+ * Should the authorizing data be entirely separate from the effecting data,
+ and encoded at the end of the transaction in a batch, so that pruning is
+ simply truncation?
+
+* The light wallet protocol will be updated to allow the client to specify the
+ set of bundle types that the client understands. In the case that this
+ information is provided, the light client server will then send the root
+ hashes for each bundle type that the client **does not** understand when
+ returning raw transaction data, so that the light client can correctly
+ recompute and validate the txid; also, the compact transactions can be pruned
+ to exclude bundles of bundle types. that the client will not understand.
+
+TODO
+====
+
+Rename ``assetDigest`` to ``assetUuid`` in ZIP 227
+
+
+References
+==========
+
+.. [#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 `_
+.. [#protocol] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1] or later `_
+.. [#protocol-blockchain] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.3: The Block Chain `_
+.. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.12: Mainnet and Testnet `_
+.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 7.8: Block Subsidy and Founders' Reward `_
+.. [#zip-0143] `ZIP 143: Transaction Signature Validation for Overwinter `_
+.. [#zip-0203] `ZIP 203: Transaction Expiry `_
+.. [#zip-0212] `ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext `_
+.. [#zip-0225] `ZIP 225: Version 5 Transaction Format `_
+.. [#zip-0239] `ZIP 239: Relay of Version 5 Transactions `_
+.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_
+.. [#zip-0307] `ZIP 307: Light Client Protocol for Payment Detection `_
+
diff --git a/zips/zip-2002.rst b/zips/zip-2002.rst
index 0abbda89..230744ad 100644
--- a/zips/zip-2002.rst
+++ b/zips/zip-2002.rst
@@ -32,10 +32,12 @@ The terms "Mainnet" and "Testnet" are to be interpreted as described in
Abstract
========
-This proposal adds an explicit ``fee`` field to the v6 transaction format.
-Instead of fees being implicit in the difference between the input value and
-output value of the transaction, all value transfers, including fee transfers to
-miners, will be explicit and committed to via the txid.
+This proposal makes the transaction fee explicit in the v6 transaction format,
+as an entry in the transparent transaction value pool balance map defined in
+ZIP 248 [#zip-0248]_. Instead of fees being implicit in the difference between
+the input value and output value of the transaction, all value transfers,
+including fee transfers to miners, will be explicit and committed to via the
+txid.
Motivation
@@ -68,53 +70,65 @@ needed to compute it.
Specification
=============
-Changes to ZIP 230 [#zip-0230]_
--------------------------------
+Bundle Type Registration
+------------------------
-The following field is appended to the Common Transaction Fields of the v6
-transaction format after ``nExpiryHeight`` [#zip-0230-transaction-format]_:
+This ZIP registers bundle type 4 ("Transaction fee") in the V6 transaction
+bundle type registry defined in ZIP 248 [#zip-0248]_.
-+-------+---------+------------+------------------------------------------------------+
-| Bytes | Name | Data Type | Description |
-+=======+=========+============+======================================================+
-| 8 | ``fee`` | ``uint64`` | The fee to be paid by this transaction, in zatoshis. |
-+-------+---------+------------+------------------------------------------------------+
++------------+----------------------+--------------------+------------------+
+| BundleType | ``mValuePoolDeltas`` | ``mEffectBundles`` | ``mAuthBundles`` |
++============+======================+====================+==================+
+| 4 |✅ |❌ |❌ |
++------------+----------------------+--------------------+------------------+
-Note: If both this ZIP and ZIP 233 are selected for inclusion in the same
-Network Upgrade, then the ordering of fields in the transaction format will
-be ``fee`` and then ``zip233Amount``.
+The fee bundle has no effecting data and no authorizing data. The transaction
+fee is represented solely as an entry in ``mValuePoolDeltas`` with
+``bundleType = 4`` and ``assetClass = 0`` (ZEC).
+
+For non-coinbase transactions, the ``value`` field of this entry MUST BE
+nonpositive, representing the fee being removed from the transparent
+transaction value pool. For coinbase transactions, the ``value`` field MUST BE
+nonnegative, representing the total fees collected from other transactions in
+the block being added to the ZEC transparent transaction value pool.
Changes to the Zcash Protocol Specification
-------------------------------------------
-In § 3.4 ‘Transactions and Treestates’ [#protocol-transactions]_ (last modified by
-ZIP 236 [#zip-0236]_), add the following consensus rule and note:
+Let $\mathsf{FeeBundleId} = 4.$
+
+Let $\mathsf{Zec}$ be the asset UUID for ZEC as defined in ZIP 248 [#zip-0248]_.
+
+In § 3.4 'Transactions and Treestates' [#protocol-transactions]_ (last modified by
+ZIP 236 [#zip-0236]_), add the following consensus rules:
- * [NU7 onward] For v6 and later transactions, the remaining value in the
- transparent transaction value pool, in zatoshis, MUST be equal to the value
- of the transaction’s ``fee`` field.
-
- Non-normative note: The effect of these rules is that the ``fee`` field of
- v6 and later coinbase transactions will always be zero.
+ * [NU7 onward] The ``assetClass`` for any entry in ``mValuePoolDeltas`` having
+ ``bundleType`` $= \mathsf{FeeBundleId}$ MUST be 0. That is, fee amounts MUST
+ be denominated in ZEC.
-In § 7.1 ‘Transaction Encoding and Consensus’ [#protocol-txnconsensus]_, add:
+ * [NU7 onward] For v6 and later non-coinbase transactions, the value of
+ $\mathsf{mValuePoolDeltas}[(\mathsf{FeeBundleId}, \mathsf{Zec})]$ MUST be
+ nonpositive. Its absolute value represents the transaction fee in zatoshis.
- [NU7 onward] ``fee`` MUST be in the range $\{ 0 .. \mathsf{MAX\_MONEY} \}$.
+ * [NU7 onward] For v6 and later coinbase transactions, the value of
+ $\mathsf{mValuePoolDeltas}[(\mathsf{FeeBundleId}, \mathsf{Zec})]$ MUST be
+ nonnegative. It represents the total transaction fees collected from all
+ other transactions in the block.
+In § 7.1 'Transaction Encoding and Consensus' [#protocol-txnconsensus]_, add:
-Modifications relative to ZIP 244 [#zip-0244]_
-----------------------------------------------
+ [NU7 onward] The absolute value of the fee bundle's value pool delta MUST
+ be in the range $\{ 0 .. \mathsf{MAX\_MONEY} \}$.
-Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm
-that applies to v6 transactions differs by appending the ``fee`` field to
-the Common Transaction Fields that are the input to the digest in
-T.1: header_digest [#zip-0244-header-digest]_::
- T.1f: fee (8-byte little-endian fee amount)
+Modifications to Digest Algorithms
+----------------------------------
-Note: If both this ZIP and ZIP 233 are selected for inclusion in the same
-Network Upgrade, then the ambiguity in ordering of the fields added by these
-ZIPs would need to be resolved.
+The fee amount is committed to the transaction identifier and signature
+digest via the ``value_pool_deltas_digest`` defined in ZIP 248 [#zip-0248]_.
+Since the fee bundle (bundle type 4) has no effecting data and no authorizing
+data, its only contribution to the transaction digest is through its entry
+in ``mValuePoolDeltas``.
Applicability
@@ -147,8 +161,5 @@ References
.. [#bitcointalk-fee-error] `Bitcoin Forum post by @Voiceeeeee, March 8, 2017. "PLEASE HELP.. I sent a transaction with a 2.5 BTC transaction fee" `_
.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_
.. [#zip-0230] `ZIP 230: Version 6 Transaction Format `_
-.. [#zip-0230-transaction-format] `ZIP 230: Version 6 Transaction Format — Specification: Transaction Format `_
.. [#zip-0236] `ZIP 236: Blocks should balance exactly `_
-.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_
-.. [#zip-0244-header-digest] `ZIP 244: Transaction Identifier Non-Malleability. Section T.1: Header Digest `_
-.. [#zip-0246] `ZIP 246: Digests for the Version 6 Transaction Format `_
+.. [#zip-0248] `ZIP 248: Extensible Transaction Format `_
diff --git a/zips/zip-2005.md b/zips/zip-2005.md
index 241e18af..0dd466d1 100644
--- a/zips/zip-2005.md
+++ b/zips/zip-2005.md
@@ -1,6 +1,6 @@
ZIP: 2005
- Title: Quantum Recoverability
+ Title: Orchard Quantum Recoverability
Owners: Daira-Emma Hopwood
Jack Grigg
Credits: Sean Bowe
@@ -25,7 +25,7 @@ The character § is used when referring to sections of the Zcash Protocol
Specification. [^protocol]
The terms "Mainnet" and "Testnet" are to be interpreted as described in
-§ 3.12 ‘Mainnet and Testnet’. [^protocol-networks]
+§ 3.12 ‘Mainnet and Testnet’. [^protocol-networks]
We use the convention followed in the protocol specification that an
$\underline{\mathsf{underlined}}$ variable indicates a byte sequence,
@@ -282,6 +282,17 @@ graph BT
# Specification
+## Usage with Zcash Shielded Assets
+
+This proposal has been designed to activate either at the same time as, or prior
+to any possible activation of ZSAs [^zip-0226] [^zip-0227].
+
+Whether or not ZSAs are deployed at the same time, the proposal anticipates that an
+$\mathsf{AssetBase}$ field will be added to note plaintexts with lead byte $\mathtt{0x03}$.
+This field will be set to the 32-byte constant
+$\mathsf{LEBS2OSP}_{\ell_{\mathbb{P}}}\big(\mathsf{repr}_{\mathbb{P}}(\mathcal{V}^{\mathsf{Orchard}})\kern-0.1em\big)$
+as long as ZSAs are not deployed.
+
## Usage with FROST
When generating Orchard keys for FROST, $\mathsf{ak}$ will be derived jointly
@@ -292,7 +303,7 @@ This ZIP further constrains FROST key generation for Orchard as follows:
participants MUST privately agree on a value $\mathsf{sk}$, and then use it
with $\mathsf{use\_qsk} = \mathsf{true}$ to derive $\mathsf{nk}$, $\mathsf{qsk}$,
$\mathsf{qk}$, and (using the $\mathsf{ak}$ output by the DKG protocol)
-$\mathsf{rivk\_ext}$, as specified in § 4.2.3 ‘Orchard Key Components’.
+$\mathsf{rivk\_ext}$, as specified in § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents].
```mermaid
graph BT
@@ -323,7 +334,7 @@ graph BT
The protocol MUST ensure that all participants obtain the same values for
$\mathsf{ak}$, $\mathsf{nk}$, and $\mathsf{rivk\_ext}$. (Provided that the
-participants have followed § 4.2.3, this implies that they have the same
+participants have followed § 4.2.3, this implies that they have the same
$\mathsf{qsk}$ and $\mathsf{qk}$, by collision resistance of $\mathsf{H^{qk}}$
and $\mathsf{H^{rivk\_ext}}$.)
@@ -424,10 +435,9 @@ wallet.
## Specification Updates
This is written as a set of changes to version 2025.6.2 of the protocol
-specification, and to the contents of ZIPs at the time of writing in
-October 2025 (as proposed for the NU6.1 upgrade). It will need to be merged
-with other changes for v6 transactions (memo bundles [^zip-0231] and
-ZSAs [^zip-0226] [^zip-0227]).
+specification, and to the contents of ZIPs as of February 2026. It will need
+to be merged with other potential changes for v6 transactions (memo bundles
+[^zip-0231] and ZSAs [^zip-0226] [^zip-0227]).
### Changes to the Protocol Specification
@@ -462,47 +472,39 @@ In the list of places where $\mathsf{PRF^{expand}}$ is used:
Replace
-> * [**NU5** onward] in § 4.2.3 ‘Orchard Key Components’, with inputs
-> $[\mathtt{0x06}]$, $[\mathtt{0x07}]$, $[\mathtt{0x08}]$, and with
-> first byte $\mathtt{0x82}$ (the last of these is also specified in
-> [[ZIP-32]](https://zips.z.cash/zip-0032));
-> * in the processes of sending (§ 4.7.2 ‘Sending Notes (Sapling)’ and
-> § 4.7.3 ‘Sending Notes (Orchard)’) and of receiving
-> (§ 4.20 ‘In-band secret distribution (Sapling and Orchard)’) notes,
-> for Sapling with inputs $[\mathtt{0x04}]$ and $[\mathtt{0x05}]$,
+> * [**NU5** onward] in § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents],
+> with inputs $[\mathtt{0x06}]$, $[\mathtt{0x07}]$, $[\mathtt{0x08}]$, and with
+> first byte $\mathtt{0x82}$;
+> * in the processes of sending (§ 4.7.2 ‘Sending Notes (Sapling)’ [^protocol-saplingsend]
+> and § 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]) and of receiving
+> (§ 4.20 ‘In-band secret distribution (Sapling and Orchard)’ [^protocol-saplingandorchardinband])
+> notes, for Sapling with inputs $[\mathtt{0x04}]$ and $[\mathtt{0x05}]$,
> and for Orchard $[t] || \underline{\text{ρ}}$ with
> $t \in \{ \mathtt{0x05}, \mathtt{0x04}, \mathtt{0x09} \}$;
with
-> * [**NU5** onward] in § 4.2.3 ‘Orchard Key Components’, with inputs
-> $[\mathtt{0x06}]$, $[\mathtt{0x07}]$, $[\mathtt{0x08}]$, with first
-> byte in $\{ \mathtt{0x0C}, \mathtt{0x0D} \}$ (also specified in
-> {{ reference to this ZIP }}), and with first byte $\mathtt{0x82}$
-> (also specified in [[ZIP-32]](https://zips.z.cash/zip-0032));
-> * in the processes of sending (§ 4.7.2 ‘Sending Notes (Sapling)’ and
-> § 4.7.3 ‘Sending Notes (Orchard)’) and of receiving
-> (§ 4.20 ‘In-band secret distribution (Sapling and Orchard)’) notes,
-> for Sapling with inputs $[\mathtt{0x04}]$ and $[\mathtt{0x05}]$,
+> * [**NU5** onward] in § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents],
+> with inputs $[\mathtt{0x06}]$, $[\mathtt{0x07}]$, $[\mathtt{0x08}]$, and with
+> first byte in $\{ \mathtt{0x0C}, \mathtt{0x0D}, \mathtt{0x82} \}$
+> ($\mathtt{0x0C}$ and $\mathtt{0x0D}$ are also specified in [ZIP 2005]);
+> * in the processes of sending (§ 4.7.2 ‘Sending Notes (Sapling)’ [^protocol-saplingsend]
+> and § 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]) and of receiving
+> (§ 4.20 ‘In-band secret distribution (Sapling and Orchard)’ [^protocol-saplingandorchardinband])
+> notes, for Sapling with inputs $[\mathtt{0x04}]$ and $[\mathtt{0x05}]$,
> and for Orchard with first byte in
> $\{ \mathtt{0x05}, \mathtt{0x04}, \mathtt{0x09}, \mathtt{0x0A}, \mathtt{0x0B} \}$
-> ($\mathtt{0x0A}$ and $\mathtt{0x0B}$ are also specified in
-> {{ reference to this ZIP }});
+> ($\mathtt{0x0A}$ and $\mathtt{0x0B}$ are also specified in [ZIP 2005]);
Add
-> * in {{ reference to this ZIP }}, with first byte in
+> * in [ZIP 2005], with first byte in
> $\{ \mathtt{0x0A}, \mathtt{0x0B}, \mathtt{0x0C}, \mathtt{0x0D} \}$.
#### § 4.2.3 ‘Orchard Key Components’
Add $\ell_{\mathsf{qsk}}$ and $\ell_{\mathsf{qk}}$ to the constants obtained
-from § 5.3 ‘Constants’.
-
-Insert after the definition of $\mathsf{ToScalar^{Orchard}}$:
-
-> Define $\mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}_{qk}}([\mathtt{0x0D}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak})$
-> $\hspace{23.9em} ||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))$.
+from § 5.3 ‘Constants’ [^protocol-constants].
Replace from "From this spending key" up to and including the line
"let $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$"
@@ -513,17 +515,17 @@ in the algorithm with:
> directly from $\mathsf{sk}$. However, this might not be the case for
> protocols that require distributed generation of shares of $\mathsf{ask}$,
> such as FROST's Distributed Key Generation [^zip-0312-key-generation]
-> (see {{ reference to the [Usage with FROST] section of this ZIP }} for
-> further discussion). To support this we define an alternative derivation
-> method using an additional "quantum spending key", $\mathsf{qsk}$, and
+> (see [[ZIP 2005, Usage with Frost]](#usagewithfrost) for further
+> discussion). To support this we define an alternative derivation method
+> using an additional "quantum spending key", $\mathsf{qsk}$, and
> "quantum intermediate key", $\mathsf{qk}$.
>
> There can also be advantages to not deriving $\mathsf{ask}$ directly from
> $\mathsf{sk}$ for hardware wallets, in order to separate the authority to
> make proofs for the Recovery Protocol from the spend authorization key
-> that is kept on the device (see {{ reference to the [Usage with hardware wallets]
-> section of this ZIP }}). The derivation from $\mathsf{qsk}$ can also be
-> used in that case.
+> that is kept on the device (see
+> [[ZIP 2005, Usage with hardware wallets]](#usagewithhardwarewallets)).
+> The derivation from $\mathsf{qsk}$ can also be used in that case.
>
> Let $\mathsf{use\_qsk} \;{\small ⦂}\; \mathbb{B}$ be a flag that is set
> to true when the derivation from $\mathsf{qsk}$ is used, or false if
@@ -538,6 +540,7 @@ in the algorithm with:
> * $\mathsf{H^{rivk}}(\mathsf{sk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x08}])\kern-0.1em\big)$
> * $\mathsf{H^{qsk}}(\mathsf{sk}) = \mathsf{truncate}_{32}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x0C}])\kern-0.1em\big)$
> * $\mathsf{H^{qk}}(\mathsf{qsk}) = \textsf{BLAKE2s\kern0.1em-256}(\texttt{“Zcash\_qk”}, \mathsf{qsk})$.
+> * $\mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{qk}}\big([\mathtt{0x0D}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$.
>
> $\mathsf{ask} \;{\small ⦂}\; \mathbb{F}^{*}_{r_{\mathbb{P}}}$,
> the Spend validating key $\mathsf{ak} \;{\small ⦂}\; \{ 1\,..\,q_{\mathbb{P}}-1 \}$,
@@ -573,24 +576,24 @@ Add the following notes:
> * If $\mathsf{ask}$, $\mathsf{ak}$, $\mathsf{nk}$, $\mathsf{rivk}$, and
> $\mathsf{rivk_{internal}}$ are not generated as specified in this
> section, then it may not be possible to recover the resulting notes as
-> specified in {{ reference to this ZIP }} in the event that attacks
-> using quantum computers become practical. In addition, to recover
-> notes it is necessary to retain, or be able to rederive the following
-> information.
-> * When $\mathsf{use\_qsk}$ is $\mathsf{false}$: the secret key $\mathsf{sk}$.
-> This will be the case when $\mathsf{sk}$ is generated according to
-> [[ZIP-32]](https://zips.z.cash/zip-0032), and the master seed *or*
-> any secret key and chain code above $\mathsf{sk}$ in the derivation
-> hierarchy is retained.
-> * When $\mathsf{use\_qsk}$ is $\mathsf{true}$: the combination of the
-> full viewing key $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$, the
-> quantum spending key $\mathsf{qsk}$, and the ability to make spend
-> authorization signatures with $\mathsf{ask}$.
+> specified in [ZIP 2005] in the event that attacks using quantum computers
+> become practical. In addition, to recover notes it is necessary to
+> retain, or be able to rederive the following information.
>
-> When the latter option is used, see {{ reference to the
-> [Usage with hardware wallets] section of this ZIP }} for
-> recommendations on the storage of, and access to $\mathsf{qsk}$
-> and $\mathsf{qk}$.
+> * When $\mathsf{use\_qsk}$ is $\mathsf{false}$: the secret key $\mathsf{sk}$.
+> This will be the case when $\mathsf{sk}$ is generated according to
+> [[ZIP-32]](https://zips.z.cash/zip-0032), and the master seed *or*
+> any secret key and chain code above $\mathsf{sk}$ in the derivation
+> hierarchy is retained.
+> * When $\mathsf{use\_qsk}$ is $\mathsf{true}$: the combination of the
+> full viewing key $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$, the
+> quantum spending key $\mathsf{qsk}$, and the ability to make spend
+> authorization signatures with $\mathsf{ask}$.
+>
+> When the latter option is used, see
+> [[ZIP 2005, Usage with hardware wallets]](#usagewithhardwarewallets)
+> for recommendations on the storage of, and access to $\mathsf{qsk}$
+> and $\mathsf{qk}$.
#### § 4.7.2 ‘Sending Notes (Sapling)’
@@ -611,31 +614,43 @@ Replace the lines deriving $\mathsf{rcm}$ and $\mathsf{esk}$ with
#### § 4.7.3 ‘Sending Notes (Orchard)’
-Add after the definition of $\mathsf{leadByte}$:
+If this proposal is to be deployed without ZSAs, add after the definition of
+$\mathsf{leadByte}$:
+
+> Let $\mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}}$ as defined in
+> § 5.4.8.3 ‘Homomorphic Pedersen commitments (Sapling and Orchard)’.
+
+If it is deployed at the same time as ZSAs, it is assumed that $\mathsf{AssetBase}$
+will have been defined by the ZSA-related changes to § 4.7.3.
-> Define $\mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star])\kern-0.1em\big) =$
+Add before "For each Action description":
+
+> Define $\mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, \mathsf{AssetBase}\kern0.05em\star)\kern-0.1em\big) =$
> $\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)$
>
> where $\mathsf{pre\_rcm} = \begin{cases}
> [\mathtt{0x05}] \,||\, \underline{\text{ρ}},&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x02} \\
> [\mathtt{0x0B}, \mathsf{leadByte}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \\
> \hphantom{[\mathtt{0x0B}, \mathsf{leadByte}]} \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ}) \\
-> \hphantom{[\mathtt{0x0B}, \mathsf{leadByte}]}\,[\,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{AssetBase}\kern0.08em\star)],&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x03}
+> \hphantom{[\mathtt{0x0B}, \mathsf{leadByte}]} \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{AssetBase}\kern0.05em\star),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x03}
> \end{cases}$
>
> Define $\mathsf{H^{esk,Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$.
>
> Define $\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, \mathsf{split\_flag}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathsf{split\_domain}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$.
> where $\mathsf{split\_domain} = \begin{cases}
-> \mathtt{0x09}&\text{if } \mathsf{split\_flag} = 0 \\
-> \mathtt{0x0A}&\text{if } \mathsf{split\_flag} = 1\text{.}
+> \mathtt{0x09},&\!\!\!\text{if } \mathsf{split\_flag} = 0 \\
+> \mathtt{0x0A},&\!\!\!\text{if } \mathsf{split\_flag} = 1\text{.}
> \end{cases}$
+If this proposal is to be deployed without ZSAs, replace $\mathsf{split\_domain}$ with
+$\mathtt{0x09}$ above and elide its definition.
+
Insert before the derivation of $\mathsf{esk}$:
> Let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$,
-> $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}) [$,
-> and $\mathsf{AssetBase}\kern0.08em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})]$.
+> $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$,
+> and $\mathsf{AssetBase}\kern0.05em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})$.
and use these in the inputs to $\mathsf{NoteCommit^{Orchard}}$.
@@ -644,7 +659,7 @@ with
> Derive $\mathsf{esk} = \mathsf{H^{esk,Orchard}_{rseed}}(\underline{\text{ρ}})$
-> Derive $\mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star]))$
+> Derive $\mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, \mathsf{AssetBase}\kern0.05em\star)\kern-0.1em\big)$
> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, \mathsf{split\_flag})$
@@ -653,7 +668,7 @@ with
Add
> Let $\mathsf{H^{rcm,Sapling}}$ be as defined in
-> § 4.7.2 ‘Sending Notes (Sapling)’.
+> § 4.7.2 ‘Sending Notes (Sapling)’.
Replace the line deriving $\mathsf{rcm}$ with
@@ -661,37 +676,52 @@ Replace the line deriving $\mathsf{rcm}$ with
#### § 4.8.3 ‘Dummy Notes (Orchard)’
+If this proposal is to be deployed without ZSAs, add after the definition of
+$\mathsf{leadByte}$:
+
+> Let $\mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}}$ as defined in
+> § 5.4.8.3 ‘Homomorphic Pedersen commitments (Sapling and Orchard)’.
+
Insert before "The spend-related fields ...":
> Let $\mathsf{H^{rcm,Orchard}}$ and $\mathsf{H^{\text{ψ},Orchard}}$ be
-> as defined in § 4.7.3 ‘Sending Notes (Orchard)’.
+> as defined in § 4.7.3 ‘Sending Notes (Orchard)’.
Replace the lines deriving $\mathsf{rcm}$ and $\text{ψ}$ with
> Let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$,
-> $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}) [$,
-> and $\mathsf{AssetBase}\kern0.08em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})]$.
+> $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$,
+> and $\mathsf{AssetBase}\kern0.05em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})$.
>
-> Derive $\mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star]))$
+> Derive $\mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, \mathsf{AssetBase}\kern0.05em\star)\kern-0.1em\big)$
>
> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, 0)$
and use $\mathsf{g}\star_{\mathsf{d}}$, $\mathsf{pk}\star_{\mathsf{d}}$,
-and $\mathsf{AssetBase}\kern0.08em\star$ in the inputs to
+and $\mathsf{AssetBase}\kern0.05em\star$ in the inputs to
$\mathsf{NoteCommit^{Orchard}}$.
#### § 4.20.2 and § 4.20.3 ‘Decryption using an Incoming/Full Viewing Key (Sapling and Orchard)’
-For both § 4.20.2 and § 4.20.3, add before the decryption procedure:
+If this proposal is to be deployed without ZSAs, add after the definition of
+$\mathsf{leadByte}$:
-> Let $\mathsf{H^{rcm,Sapling}}$ and $\mathsf{H^{\text{esk},Sapling}}$
-> be as defined in § 4.7.2 ‘Sending Notes (Sapling)’.
+> Let $\mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}}$ as defined in
+> § 5.4.8.3 ‘Homomorphic Pedersen commitments (Sapling and Orchard)’.
+
+If it is deployed at the same time as ZSAs, it is assumed that $\mathsf{AssetBase}$
+will have been defined by the ZSA-related changes to § 4.20.2 and § 4.20.3.
+
+For both § 4.20.2 and § 4.20.3, add before the decryption procedure:
+
+> Let $\mathsf{H^{rcm,Sapling}}$ and $\mathsf{H^{esk,Sapling}}$
+> be as defined in § 4.7.2 ‘Sending Notes (Sapling)’.
>
-> Let $\mathsf{H^{rcm,Orchard}}$, $\mathsf{H^{\text{esk},Orchard}}$,
+> Let $\mathsf{H^{rcm,Orchard}}$, $\mathsf{H^{esk,Orchard}}$,
> and $\mathsf{H^{\text{ψ},Orchard}}$ be as defined in
-> § 4.7.3 ‘Sending Notes (Orchard)’.
+> § 4.7.3 ‘Sending Notes (Orchard)’.
-For § 4.20.3, replace
+For § 4.20.3, replace
> $\hspace{1.0em}$ if $\mathsf{esk} \geq r_{\mathbb{G}}$ or $\mathsf{pk_d} = \bot$, return $\bot$
@@ -704,7 +734,7 @@ and in the note containing "However, this is technically redundant with the
later check that returns $\bot$ if $\mathsf{pk_d} \not\in \mathbb{J}^{(r)*}$",
delete the word "later".
-For both § 4.20.2 and § 4.20.3, replace
+For both § 4.20.2 and § 4.20.3, replace
> $\hspace{1.0em}$ for Sapling, let $\mathsf{pre\_rcm} = [4]$ and $\mathsf{pre\_esk} = [5]$
> $\hspace{1.0em}$ for Orchard, let $\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}$ from the same Action description $\!)$, $\mathsf{pre\_rcm} = [5] \,||\, \underline{\text{ρ}}$, and $\mathsf{pre\_esk} = [4] \,||\, \underline{\text{ρ}}$
@@ -713,17 +743,17 @@ with
> $\hspace{1.0em}$ let $\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}$ from the same Action description $\!)$
-For § 4.20.2, replace
+For § 4.20.2, replace
> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases}
> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\
-> \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})),&\!\!\!\text{otherwise}
+> \mathsf{ToScalar}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big),&\!\!\!\text{otherwise}
> \end{cases}$
> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$
> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$
> $\hspace{1.0em}$ [**Canopy** onward] if $\mathsf{leadByte} \neq \mathtt{0x01}$:
-> $\hspace{2.5em}$ $\mathsf{esk} = \mathsf{ToScalar^{protocol}}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_esk}))$
-> $\hspace{2.5em}$ if $\mathsf{repr}_{\mathbb{G}}(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})) \neq \mathtt{ephemeralKey}$, return $\bot$
+> $\hspace{2.5em}$ $\mathsf{esk} = \mathsf{ToScalar^{protocol}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_esk})\kern-0.1em\big)$
+> $\hspace{2.5em}$ if $\mathsf{repr}_{\mathbb{G}}\big(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})\kern-0.1em\big) \neq \mathtt{ephemeralKey}$, return $\bot$
>
> $\hspace{1.0em}$ let $\mathsf{pk_d} = \mathsf{KA.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})$
@@ -732,28 +762,28 @@ with
> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$
> $\hspace{1.0em}$ [**Canopy** onward] if $\mathsf{leadByte} \neq \mathtt{0x01}$:
> $\hspace{2.5em}$ let $\mathsf{esk} = \mathsf{H^{esk,protocol}_{rseed}}(\underline{\text{ρ}})$
-> $\hspace{2.5em}$ if $\mathsf{repr}_{\mathbb{G}}(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})) \neq \mathtt{ephemeralKey}$, return $\bot$
+> $\hspace{2.5em}$ if $\mathsf{repr}_{\mathbb{G}}\big(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})\kern-0.1em\big) \neq \mathtt{ephemeralKey}$, return $\bot$
>
> $\hspace{1.0em}$ let $\mathsf{pk_d} = \mathsf{KA.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})$
-> $\hspace{1.0em}$ let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}) [$, and $\mathsf{AssetBase}\kern0.08em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})]$
+> $\hspace{1.0em}$ let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$, and $\mathsf{AssetBase}\kern0.05em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})$
> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, 0)$ for Orchard or $\bot$ for Sapling
> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases}
> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\
-> \mathsf{H^{rcm,protocol}_{rseed}}(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star])),&\!\!\!\text{otherwise}
+> \mathsf{H^{rcm,protocol}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, \mathsf{AssetBase}\kern0.05em\star)\kern-0.1em\big),&\!\!\!\text{otherwise}
> \end{cases}$
> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$
The order of operations has to be altered because the derivation of
$\mathsf{rcm}$ can depend on $\mathsf{g_d}$ and $\mathsf{pk_d}$.
The definitions of $\mathsf{pre\_rcm}$ and $\mathsf{pre\_esk}$ are moved into
-§ 4.7.2 ‘Sending Notes (Sapling)’ and § 4.7.3 ‘Sending Notes (Orchard)’ which
+§ 4.7.2 ‘Sending Notes (Sapling)’ and § 4.7.3 ‘Sending Notes (Orchard)’ which
define $\mathsf{H^{rcm,protocol}}$.
-For § 4.20.3, replace
+For § 4.20.3, replace
> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases}
> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\
-> \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})),&\!\!\!\text{otherwise}
+> \mathsf{ToScalar}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big),&\!\!\!\text{otherwise}
> \end{cases}$
> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$
> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$ or $\mathsf{pk_d} \not\in \mathbb{J}^{(r)*}$ (see note below), return $\bot$
@@ -761,15 +791,15 @@ For § 4.20.3, replace
with
> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$
-> $\hspace{1.0em}$ let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}) [$, and $\mathsf{AssetBase}\kern0.08em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})]$
+> $\hspace{1.0em}$ let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$, and $\mathsf{AssetBase}\kern0.05em\star = \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})$
> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, 0)$ for Orchard or $\bot$ for Sapling
> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases}
> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\
-> \mathsf{H^{rcm,protocol}_{rseed}}(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star])),&\!\!\!\text{otherwise}
+> \mathsf{H^{rcm,protocol}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, \mathsf{AssetBase}\kern0.05em\star)\kern-0.1em\big),&\!\!\!\text{otherwise}
> \end{cases}$
> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$
-and delete "where $\text{ψ} = \mathsf{ToBase^{Orchard}}(\mathsf{PRF^{expand}_{rseed}}([9] \,||\, \underline{\text{ρ}}))$".
+and delete "where $\text{ψ} = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([9] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$".
#### § 5.3 ‘Constants’
@@ -788,12 +818,12 @@ in the diagram in section ‘Orchard internal key derivation’
> $\ast$ The derivations of $\mathsf{ask}$ and $\mathsf{rivk}$ shown in
> the diagram are not the only possibility. For further detail see
-> § 4.2.3 ‘Orchard Key Components’ in the protocol specification.
+> § 4.2.3 ‘Orchard Key Components’ in the protocol specification.
> However, if $\mathsf{ask}$, $\mathsf{ak}$, $\mathsf{nk}$, $\mathsf{rivk}$,
> and $\mathsf{rivk_{internal}}$ are not generated as in the diagram, then
> it may not be possible to recover the resulting notes as specified in
-> {{ reference to this ZIP }} in the event that attacks using quantum
-> computers become practical.
+> [ZIP 2005] in the event that attacks using quantum computers become
+> practical.
#### ZIP 212
@@ -802,13 +832,13 @@ Add a note before the Abstract:
This ZIP reflects the changes made to note encryption for the Canopy upgrade.
-It does not include subsequent changes in {{ reference to this ZIP }}.
+It does not include subsequent changes in [ZIP 2005].
#### ZIP 226
Add the following to the section [Note Structure and Commitment](https://zips.z.cash/zip-0226#note-structure-and-commitment):
-> When § 4.7.3 ‘Sending Notes (Orchard)’ or § 4.8.3 ‘Dummy Notes (Orchard)’
+> When § 4.7.3 ‘Sending Notes (Orchard)’ or § 4.8.3 ‘Dummy Notes (Orchard)’
> are invoked directly or indirectly in the computation of $\text{ρ}$ and
> $\text{ψ}$ for an OrchardZSA note, $\mathsf{leadByte}$ MUST be set to
> $\mathtt{0x03}$.
@@ -850,34 +880,36 @@ The proposed Recovery Protocol works, roughly speaking, by enforcing the
derivations given in the [Flow diagram for the Orchard and OrchardZSA protocols],
and we suggest having that diagram open in another window to refer to it.
-Import this definition from § 4.7.3 ‘Sending Notes (Orchard)’:
+Import this definition from § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents]:
-> Let $\mathsf{leadByte}$ be the note plaintext lead byte, chosen
-> according to § 3.2.1 ‘Note Plaintexts and Memo Fields’ with
-> $\mathsf{protocol} = \mathsf{Orchard}$.
->
-> Define $\mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star])\kern-0.1em\big) =$
-> $\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)$
+> Define $\mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{qk}}\big([\mathtt{0x0D}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$.
+
+Import this definition from ZIP 32 [^zip-0032-orchard-internal-key-derivation]:
+
+> $\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}_{rivk\_ext}}([\mathtt{0x83}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak})$
+> $\hspace{21.58em} ||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))$
+
+Import these definitions from § 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend], specialized to $\mathsf{leadByte} = \mathtt{0x03}$:
+
+> Define $\mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathsf{leadByte}, (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, \mathsf{AssetBase}\kern0.05em\star)\kern-0.1em\big) =$
+> $\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)$
>
> where $\mathsf{pre\_rcm} = \begin{cases}
-> [\mathtt{0x05}] \,||\, \underline{\text{ρ}},&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x02} \\
+> \sout{[\mathtt{0x05}] \,||\, \underline{\text{ρ}},}&\!\!\!\sout{\text{if } \mathsf{leadByte} = \mathtt{0x02}} \\
> [\mathtt{0x0B}, \mathsf{leadByte}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \\
> \hphantom{[\mathtt{0x0B}, \mathsf{leadByte}]} \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ}) \\
-> \hphantom{[\mathtt{0x0B}, \mathsf{leadByte}]}\,[\,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{AssetBase}\kern0.08em\star)],&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x03}\text{.} \\
+> \hphantom{[\mathtt{0x0B}, \mathsf{leadByte}]} \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{AssetBase}\kern0.05em\star),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x03}
+> \end{cases}$
+>
+> Define $\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, \mathsf{split\_flag}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathsf{split\_domain}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$.
+> where $\mathsf{split\_domain} = \begin{cases}
+> \mathtt{0x09},&\!\!\!\text{if } \mathsf{split\_flag} = 0 \\
+> \mathtt{0x0A},&\!\!\!\text{if } \mathsf{split\_flag} = 1\text{.}
> \end{cases}$
-Define:
+Import this definition from § 5.4.7.1 ‘Spend Authorization Signature (Sapling and Orchard)’ [^protocol-concretespendauthsig]:
-* $\mathsf{H}^{\text{ψ},\mathsf{Orchard}}_{\mathsf{r}\text{ψ}}(\underline{\text{ρ}}, \mathsf{split\_flag}) = \mathsf{ToBase^{Orchard}}(\mathsf{PRF}^{\mathsf{expand}}_{\mathsf{r}\text{ψ}}([\mathsf{split\_domain}] \,||\, \underline{\text{ρ}}))$
- where $\mathsf{split\_domain} = \begin{cases}
- \mathtt{0x09},&\!\!\!\text{if } \mathsf{split\_flag} = 0 \\
- \mathtt{0x0A},&\!\!\!\text{if } \mathsf{split\_flag} = 1\text{.}
- \end{cases}$
-* $\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}_{rivk\_ext}}([\mathtt{0x83}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak})$
- $\hspace{21.58em} ||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))$
-* $\mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}_{\rlap{qk}{\hphantom{rivk\_ext}}}}([\mathtt{0x84}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak})$
- $\hspace{21.58em} ||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))$
-* $\mathcal{G}^{\mathsf{Orchard}} = \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard”}, \texttt{“G”})$
+> Define $\mathcal{G}^{\mathsf{Orchard}} = \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard”}, \texttt{“G”})$.
A valid instance of a Recovery statement assures that given a primary input:
@@ -923,7 +955,7 @@ such that the following conditions hold:
$\begin{array}{l}
\{\;\, \mathsf{use\_qsk} \Rightarrow \big(\;\, \mathsf{rk} = \mathsf{SpendAuthSig^{Orchard}.RandomizePublic}(\alpha, \mathsf{ak}^{\mathbb{P}}) \\
\hspace{6.7em} \wedge\; \mathsf{SoK^{qsk}.Validate}\big((\mathsf{qk}), \mathsf{SigHash}, \sigma_{\mathsf{qsk}}\big) \\
-\hspace{6.7em} \wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_qk}(\mathsf{ak}, \mathsf{nk})\,\big) \\
+\hspace{6.7em} \wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})\,\big) \\
\wedge\; \text{not } \mathsf{use\_qsk} \Rightarrow \mathsf{SoK^{sk}.Validate}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}, \sigma_{\mathsf{sk}}\big) \\
\wedge\; \mathsf{rivk} = \begin{cases}
\mathsf{rivk\_ext}&\text{if } \mathsf{is\_rivk\_internal} = 0 \\
@@ -933,7 +965,7 @@ $\begin{array}{l}
\wedge\; \mathsf{ivk} \not\in \{0, \bot\} \\
\wedge\; \text{let } \mathsf{pk_d} = [\mathsf{ivk}]\, \mathsf{g_d} \\
\wedge\; \text{let } \text{ψ} = \mathsf{H}^{\text{ψ}}_{\mathsf{r}\text{ψ}}(\underline{\text{ρ}}, \mathsf{split\_flag}) \\
-\wedge\; \text{let } \mathsf{note\_repr} = \big(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star]\big) \\
+\wedge\; \text{let } \mathsf{note\_repr} = \big(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, {\mathsf{AssetBase}\kern0.05em\star}\big) \\
\wedge\; \text{let } \mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathtt{0x03}, \mathsf{note\_repr}\big) \\
\wedge\; \text{let } \mathsf{cm} = \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{note\_repr}) \\
\wedge\; \mathsf{cm} \neq \bot \\
@@ -1030,7 +1062,7 @@ Balance property.
We prefer to fix this without changing $\mathsf{NoteCommit^{Orchard}}$ itself.
Instead we change how $\mathsf{rcm}$ is computed to be a hash of $\mathsf{rseed}$ and
-$\mathsf{noterepr} = (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}[, \mathsf{AssetBase}\kern0.08em\star])$,
+$\mathsf{noterepr} = (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}, \mathsf{AssetBase}\kern0.05em\star)$,
as detailed in the [Specification] section.
Specifically, when $\mathsf{leadByte} = \mathtt{0x03}$ we have:
@@ -1204,14 +1236,14 @@ choose to attack either):
than to search for values of $\mathsf{sk}$ (possibly using a Grover search)
to find one that reproduces a given $\mathsf{ivk}$. Since $\mathsf{ivk}$
must be an $x$-coordinate of a Pallas curve point (see the note at the end of
- [§ 4.2.3 Orchard Key Components](https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents)),
+ [§ 4.2.3 Orchard Key Components](https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents)),
it can take on $(r_{\mathbb{P}}-1)/2$ values. So if there are $T$ targets
the success probability for each attempt in a classical search is
$2T/(r_{\mathbb{P}}-1)$, which is negligible provided that
$T \ll r_{\mathbb{P}}$. This is also infeasible for a quantum adversary
using a Grover search for reasonable values of $T$.
-* Case $\mathsf{use\_qsk} = 0$: This case is almost the same except that
+* Case $\mathsf{use\_qsk} = 1$: This case is almost the same except that
$\mathsf{ivk}$ is now an essentially random function of
$(\mathsf{nk}, \mathsf{ak}, \mathsf{qk})$. The success probability
in terms of $T$ is also the same as for $\mathsf{use\_qsk} = 0$.
@@ -1332,7 +1364,7 @@ As far as I'm aware, all existing Zcash wallets already derive
$(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ from a spending key
$\mathsf{sk}$ in the way specified for the
$\mathsf{use\_qsk} = \mathsf{false}$ case in
-[§ 4.2.3 Orchard Key Components](https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents).
+§ 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents].
FROST distributed key generation requires the $\mathsf{use\_qsk} = \mathsf{true}$ case.
There is no significant existing deployment of FROST, so we can
@@ -1341,7 +1373,7 @@ from the start.
The part of the protocol that is new is the different input for
$\mathsf{pre\_rcm}$. It would have been possible to use a separate
-pq-binding commitment, but $\mathsf{H^rcm}$ is already pq-binding and so
+pq-binding commitment, but $\mathsf{H^{rcm}}$ is already pq-binding and so
doing it this way involves fewer components. This also allows us to avoid
any security compromise and use 256-bit cryptovalues for both integrity
and randomization, which would otherwise have been difficult.
@@ -1375,10 +1407,22 @@ manipulate the note selection algorithm to some extent.
[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks)
+[^protocol-orchardkeycomponents]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.2.3: Orchard Key Components](protocol/protocol.pdf#orchardkeycomponents)
+
+[^protocol-saplingsend]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.2: Sending Notes (Sapling)](protocol/protocol.pdf#saplingsend)
+
+[^protocol-orchardsend]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.3: Sending Notes (Orchard)](protocol/protocol.pdf#orchardsend)
+
+[^protocol-saplingandorchardinband]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.20: In-band secret distribution (Sapling and Orchard)](protocol/protocol.pdf#saplingandorchardinband)
+
+[^protocol-constants]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants](protocol/protocol.pdf#constants)
+
[^protocol-concretesinsemillahash]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.1.9: Sinsemilla Hash Function](protocol/protocol.pdf#concretesinsemillahash)
[^protocol-sinsemillasecurity]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.1.9: Sinsemilla Hash Function — Security argument](protocol/protocol.pdf#sinsemillasecurity)
+[^protocol-concretespendauthsig]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.7.1: Spend Authorization Signature (Sapling and Orchard)](protocol/protocol.pdf#concretespendauthsig)
+
[^zip-0032-sapling-child-key-derivation]: [ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling child key derivation](zip-0032.rst#sapling-child-key-derivation)
[^zip-0032-sapling-internal-key-derivation]: [ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling internal key derivation](zip-0032.rst#sapling-internal-key-derivation)