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)