diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index b32f858d5..aa1f935c0 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -27,9 +27,9 @@ jobs: steps: - name: Generate app token id: app-token - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: - app-id: ${{ secrets.APP_ID }} + client-id: ${{ secrets.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} - name: Checkout repository @@ -78,7 +78,7 @@ jobs: default_author: github_actions - name: Upload artifact - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: 'rendered' diff --git a/.github/workflows/render.yml b/.github/workflows/render.yml index 10546138e..ca936488b 100644 --- a/.github/workflows/render.yml +++ b/.github/workflows/render.yml @@ -19,11 +19,11 @@ jobs: if [ -e base_ref ]; then exit 1; fi - name: Install Nix - uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21 + uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22 - name: Restore Nix store cache id: nix-cache - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: /tmp/nix-closure key: nix-devshell-${{ runner.os }}-${{ hashFiles('flake.lock', 'flake.nix') }} diff --git a/.github/workflows/report_updatecheck.yml b/.github/workflows/report_updatecheck.yml index 60b3a6d2d..b03435115 100644 --- a/.github/workflows/report_updatecheck.yml +++ b/.github/workflows/report_updatecheck.yml @@ -12,7 +12,7 @@ jobs: post_status: runs-on: ubuntu-latest steps: - - uses: actions/github-script@v8 + - uses: actions/github-script@v9 with: script: | const runId = context.payload.workflow_run.id; @@ -27,7 +27,7 @@ jobs: run_id: runId, }); - if (artifacts.data.artifacts.some(a => a.name === 'neutral-signal') { + if (artifacts.data.artifacts.some(a => a.name === 'neutral-signal')) { conclusion = 'neutral'; title = 'Dependencies are correct but not up-to-date'; } else { diff --git a/README.rst b/README.rst index f26255a5c..7a7b373e9 100644 --- a/README.rst +++ b/README.rst @@ -62,6 +62,7 @@ NU7 Candidate ZIPs The following ZIPs are under consideration for deployment in NU7: +- `ZIP 218: 25-second Block Target Spacing `__ - `ZIP 226: Transfer and Burn of Zcash Shielded Assets `__ - `ZIP 227: Issuance of Zcash Shielded Assets `__ - `ZIP 230: Version 6 Transaction Format `__ @@ -134,7 +135,7 @@ Released ZIPs 300 Cross-chain Atomic Transactions Proposed 301 Zcash Stratum Protocol Active 308 Sprout to Sapling Migration Active - 316 Unified Addresses and Unified Viewing Keys [Revision 0] Active, [Revision 1] Proposed + 316 Unified Addresses and Unified Viewing Keys [Revision 0] Active, [Revision 1] Withdrawn, [Revision 2] Draft 317 Proportional Transfer Fee Mechanism Active 320 Defining an Address Type to which funds can only be sent from Transparent Addresses Active 321 Payment Request URIs Active @@ -143,6 +144,7 @@ Released ZIPs 1015 Block Subsidy Allocation for Non-Direct Development Funding Final 1016 Community and Coinholder Funding Model Proposed 2001 Lockbox Funding Streams Final + 2005 Orchard Quantum Recoverability Proposed Draft ZIPs @@ -169,12 +171,12 @@ written. 129 Zcash Transparent Multisig Setup Reserved zips#1060 204 Zcash P2P Network Protocol Draft zips#352 217 Aggregate Signatures Reserved zips#1137 + 218 25-second Block Target Spacing Draft https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577 219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved zips#428 222 Transparent Zcash Extensions Draft zips#1231 226 Transfer and Burn of Zcash Shielded Assets Draft zips#618 227 Issuance of Zcash Shielded Assets Draft zips#618 228 Asset Swaps for Zcash Shielded Assets Reserved zips#776 - 230 Version 6 Transaction Format Draft zips#686 231 Memo Bundles Draft zips#627 233 Network Sustainability Mechanism: Removing Funds From Circulation Draft zips#922 234 Network Sustainability Mechanism: Issuance Smoothing Draft zips#923 @@ -185,7 +187,6 @@ written. 260 Extending Block Messages with Additional Authentication Data Reserved zips#522 270 Key Rotation for Tracked Signing Keys Reserved zips#1047 302 Standardized Memo Field Format Draft zips#366 - 303 Sprout Payment Disclosure Reserved 304 Sapling Address Signatures Draft zips#345 305 Best Practices for Hardware Wallets supporting Sapling Reserved zips#346 306 Security Considerations for Anchor Selection Reserved zips#351 @@ -196,7 +197,6 @@ written. 312 FROST for Spend Authorization Multisignatures Draft zips#382 314 Privacy upgrades to the Zcash light client protocol Reserved zips#434 315 Best Practices for Wallet Implementations Draft zips#447 - 318 Associated Payload Encryption Reserved zips#633 319 Options for Shielded Pool Retirement Reserved zips#635 322 Generic Signed Message Format Reserved zips#429 323 Specification of getblocktemplate for Zcash Reserved zips#405 @@ -212,7 +212,6 @@ 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 guide-markdown {Something Short and To the Point} Draft guide {Something Short and To the Point} Draft template {Template for new ZIPs} Draft @@ -248,7 +247,9 @@ Withdrawn, Rejected, or Obsolete ZIPs ZIP Title Status 210 Sapling Anchor Deduplication within Transactions Withdrawn 220 Zcash Shielded Assets Withdrawn + 230 Withdrawn Version 6 Transaction Format Withdrawn 254 Deployment of the NU7 Network Upgrade (Withdrawn) Withdrawn + 303 Sprout Payment Disclosure Withdrawn 313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete 1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete 1002 Opt-in Donation Feature Obsolete @@ -304,6 +305,7 @@ Index of ZIPs 215 Explicitly Defining and Modifying Ed25519 Validation Rules Final 216 Require Canonical Jubjub Point Encodings Final 217 Aggregate Signatures Reserved + 218 25-second Block Target Spacing Draft 219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved 220 Zcash Shielded Assets Withdrawn 221 FlyClient - Consensus-Layer Changes Final @@ -313,7 +315,7 @@ Index of ZIPs 226 Transfer and Burn of Zcash Shielded Assets Draft 227 Issuance of Zcash Shielded Assets Draft 228 Asset Swaps for Zcash Shielded Assets Reserved - 230 Version 6 Transaction Format Draft + 230 Withdrawn Version 6 Transaction Format Withdrawn 231 Memo Bundles Draft 233 Network Sustainability Mechanism: Removing Funds From Circulation Draft 234 Network Sustainability Mechanism: Issuance Smoothing Draft @@ -337,7 +339,7 @@ Index of ZIPs 300 Cross-chain Atomic Transactions Proposed 301 Zcash Stratum Protocol Active 302 Standardized Memo Field Format Draft - 303 Sprout Payment Disclosure Reserved + 303 Sprout Payment Disclosure Withdrawn 304 Sapling Address Signatures Draft 305 Best Practices for Hardware Wallets supporting Sapling Reserved 306 Security Considerations for Anchor Selection Reserved @@ -350,9 +352,8 @@ Index of ZIPs 313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete 314 Privacy upgrades to the Zcash light client protocol Reserved 315 Best Practices for Wallet Implementations Draft - 316 Unified Addresses and Unified Viewing Keys [Revision 0] Active, [Revision 1] Proposed + 316 Unified Addresses and Unified Viewing Keys [Revision 0] Active, [Revision 1] Withdrawn, [Revision 2] Draft 317 Proportional Transfer Fee Mechanism Active - 318 Associated Payload Encryption Reserved 319 Options for Shielded Pool Retirement Reserved 320 Defining an Address Type to which funds can only be sent from Transparent Addresses Active 321 Payment Request URIs Active @@ -388,7 +389,7 @@ 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 Proposed guide-markdown {Something Short and To the Point} Draft guide {Something Short and To the Point} Draft template {Template for new ZIPs} Draft diff --git a/README.template b/README.template index 111eb1a22..4f078629e 100644 --- a/README.template +++ b/README.template @@ -62,6 +62,7 @@ NU7 Candidate ZIPs The following ZIPs are under consideration for deployment in NU7: +- `ZIP 218: 25-second Block Target Spacing `__ - `ZIP 226: Transfer and Burn of Zcash Shielded Assets `__ - `ZIP 227: Issuance of Zcash Shielded Assets `__ - `ZIP 230: Version 6 Transaction Format `__ diff --git a/flake.nix b/flake.nix index 14035b348..146a1f09c 100644 --- a/flake.nix +++ b/flake.nix @@ -63,40 +63,67 @@ # Tests require additional fixtures not included in the PyPI tarball doCheck = false; }; + + buildInputs = [ + # Core dependencies for render.sh + rst2html5 # rst2html5 2.0.1 (PyPI) + pkgs.python3Packages.pygments # syntax highlighting for code blocks + pkgs.pandoc # pandoc markdown renderer + mmd # multimarkdown renderer (zcash fork) + pkgs.perl # perl for text processing + + # Build system dependencies + pkgs.gnumake # make command for building + pkgs.git # required by Makefile for safe.directory + + # LaTeX dependencies for protocol PDF generation + (pkgs.texlive.combine { inherit (pkgs.texlive) scheme-full; }) + + # Python dependencies for links_and_dests.py + pkgs.python3 + pkgs.python3Packages.beautifulsoup4 + pkgs.python3Packages.html5lib + pkgs.python3Packages.certifi + + # Standard utilities (usually available, but ensuring they're present) + pkgs.coreutils + pkgs.bash + pkgs.gnused + pkgs.gnugrep + pkgs.diffutils + pkgs.findutils + ]; + + all = pkgs.stdenv.mkDerivation { + pname = "zcash-zips-rendered-all"; + version = "0.0.1"; + src = ./.; + + inherit buildInputs; + + buildPhase = '' + # Subprocess for bash set flags scope, especially -x so that we + # don't see very verbose nix cleanup traces on errors: + ( + set -efuxo pipefail + # Ewww... looks like `kpathsea` mutates the user's home. + # Create a fake home dir inside the buildir: + fake_home='./messy-fake-home' + mkdir "$fake_home" + HOME="$fake_home" make all + ) + ''; + }; in { + packages = { + inherit all; + + default = all; + }; + devShells.default = pkgs.mkShell { - buildInputs = [ - # Core dependencies for render.sh - rst2html5 # rst2html5 2.0.1 (PyPI) - pkgs.python3Packages.pygments # syntax highlighting for code blocks - pkgs.pandoc # pandoc markdown renderer - mmd # multimarkdown renderer (zcash fork) - pkgs.perl # perl for text processing - - # Build system dependencies - pkgs.gnumake # make command for building - pkgs.git # required by Makefile for safe.directory - - # LaTeX dependencies for protocol PDF generation - (pkgs.texlive.combine { - inherit (pkgs.texlive) scheme-full; - }) - - # Python dependencies for links_and_dests.py - pkgs.python3 - pkgs.python3Packages.beautifulsoup4 - pkgs.python3Packages.html5lib - pkgs.python3Packages.certifi - - # Standard utilities (usually available, but ensuring they're present) - pkgs.coreutils - pkgs.bash - pkgs.gnused - pkgs.gnugrep - pkgs.diffutils - pkgs.findutils - ]; + inherit buildInputs; shellHook = '' echo "ZIP documentation rendering environment" diff --git a/protocol/protocol.tex b/protocol/protocol.tex index 80b64a816..76371e474 100644 --- a/protocol/protocol.tex +++ b/protocol/protocol.tex @@ -882,10 +882,11 @@ \newcommand{\primeOrderCurve}{\term{prime-order curve}} \newcommand{\primeOrderCurves}{\terms{prime-order curve}} \newcommand{\hashToCurve}{\term{hash-to-curve}} -\newcommand{\xDiscreteLogarithmProblem}{\term{Discrete Logarithm Problem}} -\newcommand{\xDiscreteLogarithm}{\termandindex{Discrete Logarithm}{Discrete Logarithm Problem}} -\newcommand{\xDecisionalDiffieHellmanProblem}{\term{Decisional Diffie--Hellman Problem}} -\newcommand{\xDecisionalDiffieHellman}{\termandindex{Decisional Diffie--Hellman}{Decisional Diffie--Hellman Problem}} +\newcommand{\discreteLogarithm}{\term{discrete logarithm}} +\newcommand{\DiscreteLogarithmProblem}{\term{Discrete Logarithm Problem}} +\newcommand{\DiscreteLogarithmIndependence}{\term{Discrete Logarithm Independence}} +\newcommand{\DecisionalDiffieHellmanProblem}{\term{Decisional Diffie--Hellman Problem}} +\newcommand{\DecisionalDiffieHellmanAssumption}{\termandindex{Decisional Diffie--Hellman assumption}{Decisional Diffie--Hellman Problem}} \newcommand{\partitioningOracleAttack}{\term{partitioning oracle attack}} \newcommand{\partitioningOracleAttacks}{\terms{partitioning oracle attack}} \newcommand{\sideChannel}{\term{side-channel}} @@ -1690,6 +1691,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}} @@ -3701,13 +3703,14 @@ \vspace{1ex} \defining{\xTransparentInputs} to a \transaction insert value into a \defining{\transparentTxValuePool} associated with the \transaction, and \defining{\transparentOutputs} remove value from this pool. + The effect of \Sprout \joinSplitTransfers\sapling{,\notnufive{ and} \Sapling \spendTransfers and \outputTransfers}\nufive{, and \Orchard \actionTransfers} on the \transparentTxValuePool are specified in \crossref{sproutbalance}\sapling{,\notnufive{ and} \crossref{saplingbalance}}\nufive{, and \crossref{orchardbalance}} respectively. As in \Bitcoin, the remaining value in the \transparentTxValuePool of a non-coinbase \transaction -is available to miners as a fee. That is, the sum of those values for non-coinbase \transactions +is available to miners as a \defining{\transactionFee}. That is, the sum of those values for non-coinbase \transactions in each \block is treated as an implicit input to the \transparentTxValuePool balance of the \block's \coinbaseTransaction (in addition to the implicit input created by issuance). @@ -4256,8 +4259,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 +4271,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} @@ -4970,15 +4972,15 @@ a sequence of \emph{distinct} inputs $m_{\alln} \typecolon \typeexp{\SubgroupGHashInput}{n}$ and a sequence of nonzero $x_{\alln} \typecolon \typeexp{\GFstar{\ParamG{r}}}{n}$ such that $\ssum{i = 1}{n}\!\Big(\scalarmult{x_i}{\SubgroupGHash{\URS}(m_i)}\Big) = \ZeroG{}$. - \item Under the \xDiscreteLogarithm assumption on $\SubgroupG{}$, a \randomOracle almost surely satisfies - Discrete Logarithm Independence. Discrete Logarithm Independence implies \collisionResistance\!, - since a collision $(m_1, m_2)$ for $\SubgroupGHash{\URS}$ trivially gives a - discrete logarithm relation with $x_1 = 1$ and $x_2 = -1$. + \item Assuming hardness of the \DiscreteLogarithmProblem on $\SubgroupG{}$, a \randomOracle almost + surely satisfies \DiscreteLogarithmIndependence. \DiscreteLogarithmIndependence implies + \collisionResistance\!, since a collision $(m_1, m_2)$ for $\SubgroupGHash{\URS}$ trivially + gives a \discreteLogarithm relation with $x_1 = 1$ and $x_2 = -1$. \item $\GroupJHash{}$ is used in \crossref{concretediversifyhash} to instantiate $\DiversifyHash{Sapling}$. We do not know how to prove the Unlinkability property defined in that section in the standard model, but in a model where $\GroupJHash{}$ (restricted to inputs for which it does not return $\bot$) is taken as a \randomOracle, - it is implied by the \xDecisionalDiffieHellman assumption on $\SubgroupJ$\nufive{, + it is implied by the \DecisionalDiffieHellmanAssumption on $\SubgroupJ$\nufive{, and similarly for $\GroupPHash$}. \item $\URS$ is a \defining{\uniformRandomString}; we chose it verifiably at random (see \crossref{beacon}), after fixing the concrete group hash algorithm to be used. @@ -5354,53 +5356,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 +5448,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 +5456,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 +5582,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 +5752,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 +5782,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 +5830,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 +5852,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 +5864,7 @@ } %nufive -\vspace{-3ex} +\vspace{-2.5ex} \lsubsection{Sending Notes}{send} \vspace{-1ex} @@ -5869,15 +5877,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 +5911,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 +5929,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 @@ -6404,7 +6413,7 @@ $\ZeroP$. Allowing the validity check to pass in that case models the fact that incomplete addition is used to implement Sinsemilla in the circuit. As proven in \theoremref{thmsinsemillaex}, a $\bot$ output from $\SinsemillaHash$ yields a - nontrivial discrete logarithm relation. Since we assume finding such a relation to be + nontrivial \discreteLogarithm relation. Since we assume finding such a relation to be infeasible, we can argue that it is safe to allow an adversary to create a proof that passes the Merkle validity check in such a case. } %nufive @@ -6679,7 +6688,7 @@ We now explain why this works. \vspace{1ex} -A \saplingBindingSignature proves knowledge of the discrete logarithm $\BindingPrivate{Sapling}$ +A \saplingBindingSignature proves knowledge of the \discreteLogarithm $\BindingPrivate{Sapling}$ of $\BindingPublic{Sapling}$ with respect to $\ValueCommitRandBase{Sapling}$. That is, $\BindingPublic{Sapling} = \scalarmult{\BindingPrivate{Sapling}}{\ValueCommitRandBase{Sapling}}$. So the value $0$ and randomness $\BindingPrivate{Sapling}$ is an opening of the \xPedersenCommitment @@ -6714,7 +6723,7 @@ Suppose that $\vSum = \vBad \neq 0 \pmod{\ParamJ{r}}$. Then $\BindingPublic{Sapling} = \ValueCommit{Sapling}{\BindingPrivate{Sapling}}(\vBad)$. -If the adversary were able to find the discrete logarithm of this $\BindingPublic{Sapling}$ +If the adversary were able to find the \discreteLogarithm of this $\BindingPublic{Sapling}$ with respect to $\ValueCommitRandBase{Sapling}$, say ${\BindingPrivate{}}'$ (as needed to create a valid \saplingBindingSignature), then $(\vBad, \BindingPrivate{Sapling})$ and $(0, {\BindingPrivate{}}')$ would be distinct openings of $\BindingPublic{Sapling}$ to different @@ -6873,7 +6882,7 @@ value commitments, and a different bound on the net value sum $\vSum$. \vspace{1ex} -An \orchardBindingSignature proves knowledge of the discrete logarithm $\BindingPrivate{Orchard}$ +An \orchardBindingSignature proves knowledge of the \discreteLogarithm $\BindingPrivate{Orchard}$ of $\BindingPublic{Orchard}$ with respect to $\ValueCommitRandBase{Orchard}$. That is, $\BindingPublic{Orchard} = \scalarmult{\BindingPrivate{Orchard}}{\ValueCommitRandBase{Orchard}}$. So the value $0$ and randomness $\BindingPrivate{Orchard}$ is an opening of the \xPedersenCommitment @@ -6904,7 +6913,7 @@ Suppose that $\vSum = \vBad \neq 0 \pmod{\ParamJ{r}}$. Then $\BindingPublic{Orchard} = \ValueCommit{Orchard}{\BindingPrivate{Orchard}}(\vBad)$. -If the adversary were able to find the discrete logarithm of this $\BindingPublic{Orchard}$ +If the adversary were able to find the \discreteLogarithm of this $\BindingPublic{Orchard}$ with respect to $\ValueCommitRandBase{Orchard}$, say ${\BindingPrivate{}}'$ (as needed to create a valid \orchardBindingSignature), then $(\vBad, \BindingPrivate{Orchard})$ and $(0, {\BindingPrivate{}}')$ would be distinct openings of $\BindingPublic{Orchard}$ to different @@ -7682,7 +7691,7 @@ assumed to allow them to control the output. (The formal output of $\SinsemillaHashToPoint$ is $\bot$ in such a case, while the output computed by the circuit would be nondeterministic.) But as proven in \theoremref{thmsinsemillaex}, these exceptional cases allow immediately - finding a nontrivial discrete logarithm relation. If the \xDiscreteLogarithmProblem is hard on the + finding a nontrivial \discreteLogarithm relation. If the \DiscreteLogarithmProblem is hard on the \pallasCurve, then finding such a case is infeasible. \end{nnotes} } %nufive @@ -8891,8 +8900,8 @@ \item Suppose that $\GroupJHash{}$ (restricted to inputs for which it does not return $\bot$) is modelled as a \randomOracle from \diversifiers to points of order $\ParamJ{r}$ on the \jubjubCurve. In this model, Unlinkability - of $\DiversifyHash{Sapling}$ holds under the \xDecisionalDiffieHellman assumption on the - \primeOrderSubgroup of points on the \jubjubCurve. + of $\DiversifyHash{Sapling}$ holds under the \DecisionalDiffieHellmanAssumption + on the \primeOrderSubgroup of points on the \jubjubCurve. To prove this, consider the ElGamal encryption scheme \cite{ElGamal1985} on this \primeOrderSubgroup, restricted to encrypting plaintexts encoded @@ -8911,11 +8920,10 @@ of the candidate \diversifiedPaymentAddresses.) So if ElGamal is \keyPrivate, then $\DiversifyHash{Sapling}$ is Unlinkable under the same conditions. - \cite[Appendix A]{BBDP2001} gives a security proof for \keyPrivacy - (both \nh{IK-CPA} and \nh{IK-CCA}) of ElGamal under the \xDecisionalDiffieHellman - assumption on the relevant group. (In fact the proof needed is the - ``small modification'' described in the last paragraph in which the generator - is chosen at random for each key.) + \cite[Appendix A]{BBDP2001} gives a security proof for \keyPrivacy (both \nh{IK-CPA} + and \nh{IK-CCA}) of ElGamal under the \DecisionalDiffieHellmanAssumption on the + relevant group. (In fact the proof needed is the ``small modification'' described in + the last paragraph in which the generator is chosen at random for each key.) \item It is assumed (also for the security of other uses of the group hash, such as Pedersen hashes and commitments) that the discrete @@ -8969,7 +8977,7 @@ $\PedersenHash$ is an algebraic \hashFunction with \collisionResistance (for fixed input length) derived from assumed hardness of the -\xDiscreteLogarithmProblem on the \jubjubCurve. +\DiscreteLogarithmProblem on the \jubjubCurve. It is based on the work of David Chaum, Ivan Damgård, Jeroen van de Graaf, Jurgen Bos, George Purdy, Eugène van Heijst and Birgit Pfitzmann in \cite{CDvdG1987}, \cite{BCP1988} and \cite{CvHP1991}, @@ -9146,7 +9154,7 @@ \vspace{-2ex} \defining{$\SinsemillaHash$} is an algebraic \hashFunction with \collisionResistance (for fixed input length) derived from assumed hardness -of the \xDiscreteLogarithmProblem. It is designed by Sean Bowe and \nh{Daira-Emma} Hopwood. +of the \DiscreteLogarithmProblem. It is designed by Sean Bowe and \nh{Daira-Emma} Hopwood. The motivation for introducing a new discrete-logarithm-based hash function (rather than using $\PedersenHash$) is to make efficient use of the lookups available in recent proof systems including \HaloTwo. @@ -9266,7 +9274,7 @@ \vspace{-2.5ex} We show a correspondence between Sinsemilla and a vector Pedersen hash, which allows using the security argument from \cite{BGG1995} to show that collision-resistance can be tightly reduced -to the \xDiscreteLogarithmProblem in $\mathbb{P}$. +to the \DiscreteLogarithmProblem in $\mathbb{P}$. \vspace{1ex} Define $\delta(a, b) = \begin{cases} @@ -9300,7 +9308,7 @@ Let $D \typecolon \byteseqs$ be a personalization input, and let $\ell \typecolon \range{0}{k \mult c}$. Finding a collision $M, M' \typecolon \bitseq{\ell}$ with $M \neq M'$ such that $\SinsemillaHashToPoint(D, M) = \SinsemillaHashToPoint(D, M') \neq \bot$ efficiently yields a nontrivial -discrete logarithm relation, and similarly for $\SinsemillaHash(D, M) = \SinsemillaHash(D, M') \neq \bot$. +\discreteLogarithm relation, and similarly for $\SinsemillaHash(D, M) = \SinsemillaHash(D, M') \neq \bot$. \end{theorem} \begin{proof} @@ -9321,9 +9329,9 @@ The fixed offset does not affect \collisionResistance in this context. (See below for why it cannot be eliminated for $\SinsemillaHash$, or when using incomplete addition.) \theoremref{thmsinsemillaex} will prove that a $\bot$ output from $\SinsemillaHashToPoint$ -yields a nontrivial discrete log relation. It follows that the \collisionResistance of +yields a nontrivial \discreteLogarithm relation. It follows that the \collisionResistance of $\SinsemillaHashToPoint$ can be tightly reduced, via the proof in \cite[Appendix A]{BGG1995}, -to the \xDiscreteLogarithmProblem over $\GroupP$. +to the \DiscreteLogarithmProblem over $\GroupP$. Note that \cite{BGG1995} requires for their main scheme that the scalars are nonzero, which is not necessarily the case in our context. However, their proof in Appendix A does not depend @@ -9335,7 +9343,7 @@ Now we consider $\SinsemillaHash$. We want to prove that, for given $D$, if we can find two distinct messages $M$ and $M'$ such that $\ExtractPbot\smash{\big(\SinsemillaHashToPoint(D, M)\kern-0.1em\big)} = \ExtractPbot\smash{\big(\SinsemillaHashToPoint(D, M')\kern-0.1em\big)} \neq \bot$ then we can efficiently -extract a discrete logarithm. +extract a \discreteLogarithm. The inputs to $\ExtractPbot$ are not $\bot$, therefore they are in $\GroupP$. $\ExtractPbot$ maps $P, Q \in \GroupP$ to the same output if and only if $P = \pm Q$. @@ -9351,12 +9359,12 @@ \vspace{1ex} Because $2^{n+1} \leq \ParamP{r}-1$, the coefficients $\!\!\pmod{\ParamP{r}}$ are not all zero, and therefore -this is a nontrivial discrete logarithm relation between independent bases. +this is a nontrivial \discreteLogarithm relation between independent bases. \end{proof} \begin{nnotes} - \item \cite[Lemma 3]{JT2020} proves a tight reduction from finding a nontrivial discrete logarithm - relation in a \primeOrderGroup to solving the \xDiscreteLogarithmProblem in that group. + \item \cite[Lemma 3]{JT2020} proves a tight reduction from finding a nontrivial \discreteLogarithm + relation in a \primeOrderGroup to solving the \DiscreteLogarithmProblem in that group. \item The above theorem easily extends to the case where additional scalar multiplication terms with independent bases may be added to the $\SinsemillaHashToPoint$ output before applying $\ExtractPbot$. This is needed to show security of the $\SinsemillaShortCommitAlg$ \commitmentScheme defined in @@ -9370,7 +9378,7 @@ \introsection \theoremlabel{thmsinsemillaex} -\begin{theorem}[A $\bot$ output from $\SinsemillaHashToPoint$ yields a nontrivial discrete log relation]\end{theorem} +\begin{theorem}[$\SinsemillaHashToPoint(\ldots) = \bot$ yields a nontrivial \discreteLogarithm relation]\end{theorem} \begin{proof} For convenience of reference, we repeat the algorithm for $\SinsemillaHashToPoint$ in terms @@ -9401,7 +9409,7 @@ \vspace{-0.5ex} $\Acc_i$ has a representation $\scalarmult{2^i}{\SinsemillaGenInit(D)} + \ssum{j=0}{2^k - 1} \,\scalarmult{X_{i,j+1}}{\SinsemillaGenBase(j)}$ for some $X_i \typecolon \typeexp{\binaryrange{i}}{2^j}$. -So given $m$ that results in an exceptional case, the nontrivial discrete logarithm relation +So given $m$ that results in an exceptional case, the nontrivial \discreteLogarithm relation $\scalarmult{\alpha \mult 2^i}{\SinsemillaGenInit(D)} + \Big(\ssum{j=0}{\smash{2^k - 1}} \,\scalarmult{\alpha \mult X_{i,j+1}}{\SinsemillaGenBase(j)}\kern-0.15em\Big) + \SinsemillaGenBase(m_i) = \ZeroP$ is easily computable from $m$. The coefficients in this representation do not overflow since $X_{i,j+1} < 2^i$ for all $i \in \range{1}{n}$ and $j \in \binaryrange{k}$; and @@ -9409,10 +9417,10 @@ \end{proof} \vspace{-0.5ex} -Similarly, a $\bot$ output from $\SinsemillaHash$ yields a nontrivial discrete logarithm relation, +Similarly, a $\bot$ output from $\SinsemillaHash$ yields a nontrivial \discreteLogarithm relation, because $\ExtractPbot$ only returns $\bot$ when its input is $\bot$. -Since by assumption it is hard to find a nontrivial discrete logarithm relation, +Since by assumption it is hard to find a nontrivial \discreteLogarithm relation, we can argue that it is safe to use incomplete additions when computing Sinsemilla inside a circuit. } %nufive @@ -9491,7 +9499,7 @@ against a potential discrete-log-breaking adversary. Given the weak assumption that the $\PoseidonHash$ sponge produces output that preserves sufficient entropy from the inputs $\NullifierKey$ and $\NoteUniqueRand$, this nullifier - construction would still be secure under a \xDecisionalDiffieHellman assumption + construction would still be secure under a \DecisionalDiffieHellmanAssumption on the \Pallas curve, even if the $\Poseidon$-based PRF were distinguishable from an ideal PRF. \item The constant $2^{65}$ comes from \cite[section 4.2]{GKRRS2019}: @@ -10464,7 +10472,7 @@ \vspace{-2ex} \securityrequirement{ \nufive{Each instantiation of} $\BindingSig{}$ must be a \nh{SUF-CMA-secure} \keyMonomorphicSignatureScheme -as defined in \crossref{abstractsigmono}. A signature must prove knowledge of the discrete logarithm of +as defined in \crossref{abstractsigmono}. A signature must prove knowledge of the \discreteLogarithm of the \validatingKey with respect to the base $\ValueCommitRandBase{Sapling}$\nufive{ or $\ValueCommitRandBase{Orchard}$}. } %securityrequirement @@ -10724,7 +10732,7 @@ \vspace{1ex} The probability of $\SinsemillaHashToPoint$ returning $\bot$ is insignificant -(and would yield a nontrivial discrete logarithm relation). +(and would yield a nontrivial \discreteLogarithm relation). The \binding property of $\SinsemillaCommitAlg$ follows from \collisionResistance of $\SinsemillaHashToPoint$ proven in \theoremref{thmsinsemillacr}, given that $\GroupPHash\Of{D \bconcat \ascii{-r}, \ascii{}}$ is independent of any of the bases @@ -10803,7 +10811,7 @@ $\NoteCommitAlg{Orchard}$ in this specification, the implementation in the \actionCircuit constrains the result to an unspecified set of values when an input results in an exceptional case for any incomplete addition. If this - occurs then it yields a nontrivial discrete logarithm relation for the + occurs then it yields a nontrivial \discreteLogarithm relation for the \pallasCurve, as proven in \theoremref{thmsinsemillaex}. We can therefore assume that it is infeasible to find such inputs with nonnegligible probability. \item There are also no points in $\GroupP$ with \affineSW $x$-coordinate @@ -14775,7 +14783,7 @@ \crossref{rhoandnullifiers}). Resistance to Faerie Gold attacks, on the other hand, depends entirely on hardness -of the \xDiscreteLogarithmProblem. The $\NoteUniqueRand$ value of a \note created +of the \DiscreteLogarithmProblem. The $\NoteUniqueRand$ value of a \note created in a given \actionTransfer is obtained from the \nullifier of the \note spent in that \actionTransfer; this ensures (without any cryptographic assumption) that all $\NoteUniqueRand$ values of \notes added to the \noteCommitmentTree are unique. @@ -14784,7 +14792,7 @@ that \commitmentScheme ensures that \Orchard \nullifiers will be unique. (Specifically, this is a Sinsemilla commitment with an additional term having base $\NullifierBaseOrchard$, truncated to its $x$-coordinate. The $x$-coordinate truncation cannot harm -\collisionResistance because, assuming hardness of the \xDiscreteLogarithmProblem +\collisionResistance because, assuming hardness of the \DiscreteLogarithmProblem on the \pallasCurve, \crossref{sinsemillasecurity} covers the case where the additional term is added.) Roadblock attacks are not possible because $\NoteUniqueRand$ does not repeat for \notes in the \noteCommitmentTree, and by a corresponding argument @@ -14863,7 +14871,7 @@ These commitments are statistically \hiding, and so ``everlasting anonymity'' is supported for \SaplingAndOrchard notes under the same conditions as in \Zerocash (by the protocol, not necessarily by \zcashd). Note that -\diversifiedPaymentAddresses can be linked if the \xDecisionalDiffieHellmanProblem +\diversifiedPaymentAddresses can be linked if the \DecisionalDiffieHellmanProblem on the \jubjubCurve\nufive{ or the \pallasCurve} can be broken. } %saplingonward @@ -15688,7 +15696,7 @@ \crossref{inbandrationale}:\!\! \begin{itemize} \item The argument for decryption with an \incomingViewingKey does not need to - depend on the \xDecisionalDiffieHellmanProblem, since $\DiversifiedTransmitBase$ + depend on the \DecisionalDiffieHellmanProblem, since $\DiversifiedTransmitBase$ is committed to by the \noteCommitment as well as $\DiversifiedTransmitPublic$. \item It is necessary to say that the \noteCommitment is always checked for a successful decryption. @@ -15997,8 +16005,8 @@ \item Clarify the distinction between \Orchard \incomingViewingKeys and $\KA{Orchard}$ \privateKeys. \item Add a note in \crossref{concretesinsemillahash} that \cite[Lemma 3]{JT2020} proves - a tight reduction from finding a nontrivial discrete logarithm relation to the - \xDiscreteLogarithmProblem. + a tight reduction from finding a nontrivial \discreteLogarithm relation to the + \DiscreteLogarithmProblem. } %nufive \sapling{ \item Add a note to \crossref{merklepath} clarifying the encoding of $\rt{Sapling}$ @@ -16033,8 +16041,8 @@ a non-null $\prevoutField$ field. \item Caveat how the result of \cite{GG2015} applies to analysis of $\PRFnf{Orchard}{}$ in \crossref{concreteprfs}. - \item Unlinkability of \diversifiedPaymentAddresses depends on the \xDecisionalDiffieHellmanProblem, - not the \xDiscreteLogarithmProblem. + \item Unlinkability of \diversifiedPaymentAddresses depends on the \DecisionalDiffieHellmanProblem, + not the \DiscreteLogarithmProblem. \item Add a paragraph to \crossref{truncation} covering \Orchard. \item Clarify the definition of $\pad$ in \crossref{concretesinsemillahash} by disambiguating $\Mpieces$ from $\Mpadded$. @@ -18521,7 +18529,7 @@ The specification of the \xPedersenHashes used in \Sapling is given in \crossref{concretepedersenhash}. It is based on the scheme from \cite[section 5.2]{CvHP1991} --for which a tighter security reduction to -the \xDiscreteLogarithmProblem was given in \cite{BGG1995}-- but tailored +the \DiscreteLogarithmProblem was given in \cite{BGG1995}-- but tailored to allow several optimizations in the circuit implementation. \xPedersenHashes are the single most commonly used primitive in the diff --git a/render.sh b/render.sh index 045e9e7b5..e499e0990 100755 --- a/render.sh +++ b/render.sh @@ -5,9 +5,9 @@ set -euo pipefail -if ! ( ( [ "x$1" = "x--rst" ] || [ "x$1" = "x--pandoc" ] || [ "x$1" = "x--mmd" ] ) && [ $# -eq 3 ] ); then +if ! ( [ $# -eq 3 ] && ( [ "x$1" = "x--rst" ] || [ "x$1" = "x--pandoc" ] || [ "x$1" = "x--mmd" ] ) ); then cat - < +Usage: render.sh --rst|--pandoc|--mmd <inputfile> <htmlfile> --rst render reStructuredText using rst2html5 --pandoc render Markdown using pandoc diff --git a/static/css/style.css b/static/css/style.css index 51d038e56..8ffef858c 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -422,6 +422,21 @@ li ol { margin-top: 0.25ex; } +/* +Default nested-ordered-list numbering for Markdown ZIPs (which have no way +to set `<ol type="...">` from source): ordered list levels are numeric, then +alphabetic, then lower-roman (e.g. 1. a. i.). The `:not([type])` qualifier +preserves explicit type attributes emitted by the RST renderer or inline HTML, +which can be semantically significant. +*/ +li ol:not([type]) { + list-style-type: lower-alpha; +} + +li ol:not([type]) li ol:not([type]) { + list-style-type: lower-roman; +} + li ul { margin-top: 0.25ex; } diff --git a/zips/zip-0000.rst b/zips/zip-0000.rst index efbe05be1..ae511b942 100644 --- a/zips/zip-0000.rst +++ b/zips/zip-0000.rst @@ -8,6 +8,9 @@ Arya <arya@zfnd.org> Kris Nuttycombe <kris@nutty.land> Sam H. Smith <sam@shieldedlabs.net> + Sean Bowe <sean@bowe.tech> + Tal Derei <tal@bowe.tech> + Dev Ojha <dev@valargroup.dev> Original-Authors: Josh Cincinnati George Tankersley Deirdre Connolly @@ -190,6 +193,8 @@ The current ZIP Editors are: capacities. * Arya, associated with the Zcash Foundation. * Mark Henderson and Sam H. Smith, associated with Shielded Labs. +* Sean Bowe and Tal Derei, associated with Project Tachyon. +* Dev Ojha, associated with Valar Group. All can be reached at zips@z.cash. The current design of the ZIP Process dictates that there are always at least two ZIP Editors, including at least @@ -199,8 +204,9 @@ ZIP Editors MUST declare any potential or perceived conflict of interest they have relating to their responsibilities as ZIP Editors. Daira-Emma Hopwood declares a conflict of interest in acting as a ZIP Editor -and as Head of Research and Assurance at Znewco, Inc., and will endeavour -to minimize the downsides of that confluence of roles as far as possible. +and as Head of Research and Assurance at Zcash Open Development Lab, and +will endeavour to minimize the downsides of that confluence of roles as far +as possible. In particular, ze commits to stepping down from the ZIP Editor role after the deployment of Zcash Shielded Assets, assuming ze is still in a management role at a company primarily involved with the development of diff --git a/zips/zip-0032.rst b/zips/zip-0032.rst index 8fba1d59b..7360d1f1b 100644 --- a/zips/zip-0032.rst +++ b/zips/zip-0032.rst @@ -518,7 +518,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 @@ -545,8 +545,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 @@ -555,18 +555,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 @@ -942,4 +948,5 @@ References .. [#zip-0000] `ZIP 0: ZIP Process <zip-0000.rst>`_ .. [#zip-0315-wallet-seeds] `ZIP 315: Best Practices for Wallet Implementations — Specification: Wallet seeds <zip-0315.rst#wallet-seeds>`_ .. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys <zip-0316.rst>`_ +.. [#zip-0316-usage-of-outgoing-viewing-keys] `ZIP 316: Unified Addresses and Unified Viewing Keys — Usage of Outgoing Viewing Keys <zip-0316.rst#usage-of-outgoing-viewing-keys>`_ .. [#zip-2005] `ZIP 2005: Orchard Quantum Recoverability <zip-2005.md>`_ diff --git a/zips/zip-0213.rst b/zips/zip-0213.rst index e4a3b6e19..181427d96 100644 --- a/zips/zip-0213.rst +++ b/zips/zip-0213.rst @@ -130,9 +130,9 @@ be shielded immediately. Enforcing coinbase maturity at the consensus level for Sapling outputs would incur significant complexity in the consensus rules, because it would require special-casing coinbase note commitments in the Sapling commitment tree. The standard recommendation when -spending a note is to select an anchor 10 blocks back from the current chain tip, which -acts as a de-facto 10-block maturity on all notes, coinbase included. This might be -proposed as a consensus rule in future. +spending a note is to select an anchor 3 blocks back from the current chain tip (see ZIP +315 [#zip-0315-anchor-selection]_), which acts as a de-facto 3-block maturity on all notes, coinbase +included. This might be proposed as a consensus rule in future. There is another reason for shielded coinbase maturity being unnecessary: shielded coinbase outputs have the same effect on economic activity as regular shielded outputs. @@ -205,3 +205,4 @@ References .. [#zip-0207] `ZIP 207: Funding Streams <zip-0207.rst>`_ .. [#zip-0250] `ZIP 250: Deployment of the Heartwood Network Upgrade <zip-0250.rst>`_ .. [#zip-0252] `ZIP 252: Deployment of the NU5 Network Upgrade <zip-0252.rst>`_ +.. [#zip-0315-anchor-selection] `ZIP 315: Best Practices for Wallet Implementations — Anchor selection <zip-0315.rst#anchor-selection>`_ diff --git a/zips/zip-0218.md b/zips/zip-0218.md new file mode 100644 index 000000000..7bb50f1de --- /dev/null +++ b/zips/zip-0218.md @@ -0,0 +1,758 @@ + + ZIP: 218 + Title: 25-second Block Target Spacing + Owners: Dev Ojha <dev@valargroup.dev> + Evan Forbes <evan@valargroup.dev> + Status: Draft + Category: Consensus + Created: 2026-03-13 + License: MIT + Discussions-To: <https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577> + + +# Terminology + +The key words "MUST", "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 terms "block chain", "consensus rule change", "consensus branch", +and "network upgrade" are to be interpreted as defined in ZIP 200. +[^zip-0200] + +The term "block target spacing" means the time interval between blocks +targeted by the difficulty adjustment algorithm in a given consensus +branch. It is normally measured in seconds. (This is also sometimes +called the "target block time", but "block target spacing" is the term +used in the Zcash Protocol Specification [^protocol-diffadjustment].) + +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] + + +# Abstract + +This proposal specifies a change in the block target spacing from 75 +seconds to 25 seconds in NU7, and introduces per-pool action limits for +the Sapling and Orchard shielded protocols. + +This solves three problems. +- Significantly improves the UX for actors who need 1 or 2 conf's. (Near Intents, small payments) The user-latency goes down 3x. +- Increases consensus bandwidth, which amplifies the scaling impact of a future shielded pool which does not require shielded sync. +- Introduces action limits. These provide limits of the number of actions that can go into a block. There is a global limit across all pools, and per pool limits. It is configured to more than double the Orchard TPS (2.9 → 6.6 TPS), while lowering the impact a DoS attacker can impose on wallets; for example, maximum shielded sync bandwidth for light clients is reduced by 37% (271 → 169 MB/day). + +The action limits significantly decrease the number of Sprout and Sapling pool +outputs available per block, to lower the maximum shielded sync burden under +attempted DoS. + +The emission schedule of mined ZEC will be the same in terms of ZEC/day, +but this requires the emission per block to be adjusted +to take account of the changed block target spacing. + +# Motivation + +The motivations for decreasing the block target spacing are: + +- **Reduced transaction latency.** Currently, users must wait + 75 seconds on average for even a single confirmation, regardless + of network utilization. This creates friction for point-of-sale + payments, exchange deposits, and cross-chain bridge operations. A + 25-second target spacing reduces the expected wait for a first + confirmation to 25 seconds on average. + +- **Greater throughput.** With 3× as many blocks per day and the same + 2 MB block size limit, we will have allocated higher consensus bandwidth + capacity. Short term, when paired with the action limits, we will more than + double the Orchard TPS for 2-action transactions. Longer term, when we get a + shielded pool with no shielded sync burden, we will have 3x higher throughput. + +The throughput goal on its own could be achieved via a block size increase. +However the goal of this proposal is foremost to improve the transaction +latency. + +This proposal is complementary to, and does not compete with, finality +mechanisms such as Crosslink [^crosslink]. Faster block times improve the +responsiveness of the base layer regardless of whether an additional finality +gadget is also deployed. Rollback-risk analysis depends on the threat model. +For models that bound an attacker by a fixed fraction of total hash power, +reducing the block target spacing can reduce confirmation latency by nearly the +same factor, provided that block validation and propagation remain small +relative to the target spacing. Given that is maintained here, this proposal is +expected to improve confirmation latency by slightly less than 3x for users +applying the same rollback-risk tolerance as today. See [#slowfastblocks]_ for +analysis under several attack models. + +Economic rollback models give a different result. For recipients who wait until +the block rewards built on top of their payment exceed the payment value, then +shorter block times significantly reduce the variance of their waiting time, +while the mean stays roughly the same. Recall that proof of work block times +have high very high variance, so variance reduction is a substantial benefit. +This ZIP does not argue for clients reducing confirmation counts, but it does +expect many users to see a lower expected time until receipt under confirmation +policies comparable to those they use today. + +## Security + +Scaling and block time reductions in Zcash impose three security costs, one on +full nodes and miners' ability to verify blocks, a second on clients for +shielded sync, and a third on the whole network for the uncle rate and fork +rate. Action limits are introduced in this ZIP to limit the block processing +costs, and client shielded sync costs. The proposed parameterization lowers the +worst case for shielded sync and node processing times relative to today, while +yielding far higher Orchard TPS. We benchmark [block verification](#block-processing-time), and the uncle-rate post-proposal +on networks more distributed than mainnet at maximum load is far lower than +ETH-PoW was, leading to conclusion that it is safe. + +Today the worst-case DoS attack can induce 271 MB of wallet sync download to +clients per day, and 4.8M trial decryptions per day [^syncsimulator]. This is d +one with max utilizing Sapling transactions, with few inputs and many outputs. +The worst-cast DOS for node verification time is done with many Sapling inputs, +and a single transparent output, totalling 5600 Sapling inputs and ZKP's. This +takes 3.2s on a modern AMD laptop CPU with 4 pinned threads. Meanwhile regular userflow +has far lower costs on the network, than the DOS model. + +We propose introducing global action limits and per-pool action limits as follows: + +- A maximum of 330 actions per block across all pools + +- A maximum of 330 Orchard actions per block + +- A maximum of 300 Sapling inputs + outputs. (Total inputs + outputs <= 300) + +- A maximum of 25 Sprout JoinSplits per block. + +With these limits, the worst case client load becomes 169 MB bandwidth and 2.3M +trial decrypts per day. This is a 37% improvement in worst case wallet sync +bandwidth despite 3x more blocks. This yields a 2x in Orchard TPS, and keeps +Sapling TPS at a higher level than today's Orchard TPS. We expand on these derivations in [] + +However, every wallet does have to download every compact block header, which +is 90 bytes. This leads to an extra 200kb of wallet bandwidth per day in +exchange for the improved UX. + +The reduced Sapling and Sprout per-block limits are justified by the +current distribution of shielded funds across pools. As of May 2026: + +| Pool | Balance | Share of shielded supply | +|------|---------|--------------------------| +| Orchard | 4,534,914 ZEC | 87.9% | +| Sapling | 597,910 ZEC | 11.6% | +| Sprout | 25,409 ZEC | 0.5% | + +The vast majority of shielded activity is already in Orchard, and this +trend is expected to continue. The Sapling and Sprout limits are set +generously relative to their current usage while substantially reducing +their potential for DoS. + +## Stale block rate + +The stale rate is the percentage of blocks that get orphaned, which relates to +mining centralization risk, block propagation delay, and block verification +times. Today the stale rate is 0.4%, but this may be lower than what pure block +propagation delay may imply due to hashpower centralization in mining pools. + +At 25-second block target spacing, the theoretical stale block rate is +approximately 3.26%, derived from measured Zcash network propagation +delays. A devnet experiment with 99 geographically-distributed Zebra +nodes producing 2MB blocks at 25-second target spacing measured a stale +block rate of 4.86% and a fork rate of 0.37%. Both observed figures are +below the 5.4% safety threshold set by Ethereum's historical proof-of-work +stale rate. [^forum-proposal] The only modification required to achieve +these rates was tuning TCP configuration (more details in the linked +footnote). The devnet's node distribution was significantly more +decentralized than today's mainnet, so these figures represent a +near worst-case scenario. [^devnet-blocktime-test] + + +## Block processing time + +A prerequisite for reducing the target block spacing is that block validation +and propagation must remain small relative to the target spacing. The per-pool +propagation remain small relative to the target spacing. The per-pool +action limits introduced by this proposal ensure that worst-case +*per-block* processing time is lower than today's. The fact that there +are three times as many blocks in unit time does mean that the *overall* +worst-case proportion of time taken for processing, and the worst cost of +sync after a given time offline for full nodes will increase. We accept this +trade-off. These computational limits parallelize well. The max bandwidth requirement from the chain is 655kbps, so syncing with 10mbps bandwidth still has a 15x advantage factor over full blocks on mainnet. + +**Current worst case:** A full 2 MB block today can contain up to ~617 +Orchard actions or ~2,090 Sapling outputs, with no per-pool limits. A fully +packed Orchard block requires verifying all action proofs and spend +authorization signatures for those ~617 actions. + +**Proposed worst case:** With the action limits, a block contains at +most 330 actions across pools. There is separately, limits per pool. We propose per-pool limits of: + +- 330 Orchard actions +- 300 Sapling inputs+outputs. +- 25 Sprout JoinSplits. + +This means the new worst case block processing time, if Orchard dominant, +would be 14% of today's worst case, and Sapling's would be +less than one tenth. The per-block verification work is therefore substantially reduced. + +**Batch verification.** Orchard transaction verification benefits from +batch validation, where proof and signature verification is amortized +across multiple transactions. In Zebra, Orchard +transactions are batch-verified in groups of up to 64 transactions +(each worst case being a single action). Zebra has performed batch +verification during live network syncing since version 3.0.0. With the +action limits, a worst-case block's Orchard bundle can be fully +batch-verified in a small number of batches. + +**Measured timing.** We benchmarked worst-case block verification with +Zebra on a modern AMD laptop CPU with 4 pinned threads.[^verification-benchmark] +The figures report wall-clock time for verifying the zero-knowledge proofs +and signatures in a single block, without any mempool pre-verification. + +| Case | Block composition | Mean ± stddev | +|------|-------------------|---------------| +| Full Orchard limit (proposed) | 330 Orchard actions | 432.11 ± 11.03 ms | +| Full Sapling limit (proposed) | 300 Sapling spends, 0 outputs | 271.51 ± 5.03 ms | +| Today's Orchard worst case | ~617 actions in dense multi-action txs in a 2 MB block | 769.85 ± 16.18 ms | +| Today's Sapling worst case | ~5,600 spends in dense multi-spend txs in a 2 MB block | 3,174.90 ± 144.04 ms | + +- **Full Orchard limit (proposed)** — binding post-NU7 verification worst case. +- **Full Sapling limit (proposed)** — verification worst case is all-spends; the bandwidth worst case (all-outputs) is in [Rationale](#rationale). +- **Today's Orchard worst case** — dense multi-action (single-action would understate the byte bound). +- **Today's Sapling worst case** — analogous, dense multi-spend. + +When transactions have already been pre-verified upon +entering the mempool, which is the typical case for a node that has +been online, block validation reduces to checking signatures and +state updates, which is even cheaper. + + +# Specification + +The changes described in this section are to be made in the Zcash +Protocol Specification [^protocol], relative to the specification as of +the activation of this proposal. + +## Consensus changes + +### Block target spacing + +In § 2 'Notation', add $\mathsf{NU7ActivationHeight}$ +and $\mathsf{PostNU7PoWTargetSpacing}$ to the list of +integer constants. + +In § 5.3 'Constants', define: + +$$\mathsf{PostNU7PoWTargetSpacing} := 25 \text{ seconds}$$ + +For a given network (production or test), define +$\mathsf{NU7ActivationHeight}$ as the height at which +this network upgrade activates on that network, as specified in a +separate deployment ZIP. + +Define: + +$$\mathsf{NU7PoWTargetSpacingRatio} := \mathsf{PostBlossomPoWTargetSpacing} \;/\; \mathsf{PostNU7PoWTargetSpacing} = 3$$ + +Define $\mathsf{IsNU7Activated}(\mathsf{height})$ to +return true if +$\mathsf{height} \geq \mathsf{NU7ActivationHeight}$, +otherwise false. + +In § 7.7.3 'Difficulty adjustment', redefine $\mathsf{PoWTargetSpacing}$ +as: + +$$ +\mathsf{PoWTargetSpacing}(\mathsf{height}) := + \begin{cases} + \mathsf{PreBlossomPoWTargetSpacing}, &\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\\\ + \mathsf{PostBlossomPoWTargetSpacing}, &\text{if } \mathsf{IsBlossomActivated}(\mathsf{height}) \text{ and not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\ + \mathsf{PostNU7PoWTargetSpacing} &\text{otherwise} + \end{cases} +$$ + +### Averaging window [averaging-window] + +In § 2 'Notation', add $\mathsf{PostNU7PoWAveragingWindow}$ to the +list of integer constants. + +In § 5.3 'Constants', define: + +$$\mathsf{PostNU7PoWAveragingWindow} := 102$$ + +In § 7.7.3 'Difficulty adjustment', redefine +$\mathsf{PoWAveragingWindow}$ as a height-dependent function: + +$$ +\mathsf{PoWAveragingWindow}(\mathsf{height}) := + \begin{cases} + 17, &\text{if not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\ + \mathsf{PostNU7PoWAveragingWindow} &\text{otherwise} + \end{cases} +$$ + +All other references to $\mathsf{PoWAveragingWindow}$ in +§ 7.7.3 'Difficulty adjustment' that previously took the constant +value 17 are reinterpreted as +$\mathsf{PoWAveragingWindow}(\mathsf{height})$ for the height of the +block under consideration. This includes the size of the averaging +window used to compute the average target threshold and the average +block timespan. + +### Halving interval and block subsidy + +Define: + +$$\mathsf{PostNU7HalvingInterval} := \lfloor \mathsf{PostBlossomHalvingInterval} \cdot \mathsf{NU7PoWTargetSpacingRatio} \rfloor = 5{,}040{,}000$$ + +Redefine the $\mathsf{Halving}$ function as: + +$$ +\mathsf{Halving}(\mathsf{height}) := + \begin{cases} + \left\lfloor \dfrac{\mathsf{height} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} \right\rfloor, + &\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\\\[1.5ex] + \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} + + \dfrac{\mathsf{height} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}} \right\rfloor, + &\text{if } \mathsf{IsBlossomActivated}(\mathsf{height}) \text{ and not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\[1.5ex] + \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} + + \dfrac{\mathsf{NU7ActivationHeight} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}} + + \dfrac{\mathsf{height} - \mathsf{NU7ActivationHeight}}{\mathsf{PostNU7HalvingInterval}} \right\rfloor, + &\text{otherwise} + \end{cases} +$$ + +Redefine $\mathsf{BlockSubsidy}$ to add a case for post-activation +heights. The prior Blossom case in § 7.8 'Calculation of Block Subsidy +and Founders' Reward', currently written as "otherwise", must be +amended to "if $\mathsf{IsBlossomActivated}(\mathsf{height})$ and not +$\mathsf{IsNU7Activated}(\mathsf{height})$": + +$$ +\mathsf{BlockSubsidy}(\mathsf{height}) := + \begin{cases} + \ldots &\text{(prior cases, with the Blossom case amended as above)} \\\\[1ex] + \mathsf{floor}\left(\dfrac{\mathsf{MaxBlockSubsidy}}{\mathsf{BlossomPoWTargetSpacingRatio} \cdot \mathsf{NU7PoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})}}\right), + &\text{if } \mathsf{IsNU7Activated}(\mathsf{height}) + \end{cases} +$$ + +This divides the per-block subsidy by an additional factor of 3 relative +to the post-Blossom subsidy, so that the total issuance per unit of wall +clock time remains the same. + +Note: the current post-Blossom block subsidy of 1.5625 ZEC does not +divide evenly by 3. The post-NU7 subsidy is +$\mathsf{floor}(156250000 / 6) = 26041666$ zatoshi (0.26041666 ZEC), +losing approximately 0.33 zatoshi per block to rounding. Over a full +halving interval of 5,040,000 blocks this amounts to less than 0.017 ZEC +of total underpaid issuance, a negligible amount. Should ZIP 234 be accepted, +the difference will eventually be reissued. + +### Shielded pool action limits + +Define the following constants in § 5.3 'Constants': + +$$\mathsf{GlobalShieldedBudget} := 330$$ +$$\mathsf{OrchardBlockActionLimit} := 330$$ +$$\mathsf{SaplingBlockIOLimit} := 300$$ +$$\mathsf{SproutBlockJoinSplitLimit} := 25$$ + +For each block at height $\mathsf{height}$ where +$\mathsf{IsNU7Activated}(\mathsf{height})$, the following limits MUST +be satisfied: + +**Per-pool limits:** + +- The total number of Orchard actions across all transactions in the + block MUST NOT exceed $\mathsf{OrchardBlockActionLimit}$. That is, + $\sum_{\mathit{tx} \in \mathit{block}} \mathit{nActionsOrchard}(\mathit{tx}) \leq 330$. + +- The total number of Sapling inputs and outputs across all + transactions in the block MUST NOT exceed + $\mathsf{SaplingBlockIOLimit}$. That is, + $\sum_{\mathit{tx} \in \mathit{block}} (\mathit{nSpendsSapling}(\mathit{tx}) + \mathit{nOutputsSapling}(\mathit{tx})) \leq 300$. + +- The total number of Sprout JoinSplits across all transactions in + the block MUST NOT exceed $\mathsf{SproutBlockJoinSplitLimit}$. That + is, + $\sum_{\mathit{tx} \in \mathit{block}} \mathit{nJoinSplit}(\mathit{tx}) \leq 25$. + +**Global shielded budget:** + +In addition to the per-pool limits, the total shielded cost across all +pools in a block MUST NOT exceed $\mathsf{GlobalShieldedBudget}$. The +shielded cost of a block is defined as: + +$$\sum_{\mathit{tx}} \mathit{nActionsOrchard}(\mathit{tx}) \;+\; \sum_{\mathit{tx}} (\mathit{nSpendsSapling}(\mathit{tx}) + \mathit{nOutputsSapling}(\mathit{tx})) \;+\; 2 \times \sum_{\mathit{tx}} \mathit{nJoinSplit}(\mathit{tx}) \;\leq\; 330$$ + +where the factor of 2 for Sprout JoinSplits reflects that each +JoinSplit produces 2 shielded outputs. + +This global budget ensures that the worst-case shielded sync bandwidth +per block is bounded regardless of which combination of pools is used. + +These limits do not apply to the transparent components of +transactions. The overall 2 MB block size limit continues to apply as +before. + +#### Rationale: Compact sync bandwidth per action + +The limits above are chosen to bound the worst-case bandwidth that +lightweight wallets must download for shielded sync. The compact +representation used for syncing has the following per-note costs: + +**Orchard:** 148 bytes per action, consisting of: + +| Field | Size | +|-------|------| +| cmx (note commitment) | 32 bytes | +| nullifier | 32 bytes | +| ephemeral public key | 32 bytes | +| truncated note plaintext | 52 bytes | +| **Total** | **148 bytes** | + +**Sapling:** 32 bytes per spend (input) and 116 bytes per output, +consisting of: + +| Field | Size | +|-------|------| +| *Per spend:* nullifier | 32 bytes | +| *Per output:* cmu (note commitment) | 32 bytes | +| *Per output:* ephemeral public key | 32 bytes | +| *Per output:* truncated note plaintext | 52 bytes | +| **Per spend total** | **32 bytes** | +| **Per output total** | **116 bytes** | + +With these limits, the worst-case compact sync bandwidth per block is: + +- **Orchard:** $330 \times 148 = 48{,}840$ bytes +- **Sapling:** at most $300 \times 116 = 34{,}800$ bytes (all-output + pathological case) + +Due to the global shielded budget, these cannot stack: a block that +uses 330 Orchard actions has zero budget remaining for Sapling or +Sprout. The worst-case compact sync bandwidth per block is therefore +always bounded by the Orchard case at 48,840 bytes. + +See the [Rationale](#rationale) section for the full daily bandwidth +analysis. + +## Effect on difficulty adjustment + +As with the Blossom activation [^zip-0208], the difficulty adjustment +parameter $\mathsf{PoWMedianBlockSpan}$ refers to a number of blocks +and does not change at activation. The change in the effective value +of $\mathsf{PoWTargetSpacing}$ will cause the block spacing to adjust +to the new target at the normal rate for a difficulty adjustment. See +[Difficulty averaging window](#difficulty-averaging-window) in the +Rationale for analysis of the $\mathsf{PoWAveragingWindow}$ change. + +It is likely that the difficulty adjustment for the first few blocks +after activation will be limited by $\mathsf{PoWMaxAdjustDown}$. This +is not anticipated to cause any problem. + +## Minimum difficulty blocks on Testnet + +On Testnet, the minimum-difficulty block threshold defined in ZIP 205 +[^zip-0205] and modified by ZIP 208 [^zip-0208] continues to use +$6 \cdot \mathsf{PoWTargetSpacing}(\mathsf{height})$ seconds. +After activation, this threshold becomes $6 \times 25 = 150$ seconds. + +## Non-consensus node behaviour + +### Default expiry delta + +When not overridden by the `-txexpirydelta` option, node +implementations that create transactions use a default expiry delta. +The current default of 40 blocks (approximately 50 minutes at 75-second +spacing) SHOULD change to +$\mathsf{NU7PoWTargetSpacingRatio} \times 40 = 120$ +blocks after activation, to maintain the approximate expiry time of +50 minutes. + +If the `-txexpirydelta` option is set, then the set value SHOULD be +used both before and after activation. + +### Block-count-based constants + +The following constants, measured in number of blocks, were reviewed. +Implementations SHOULD scale by $\mathsf{NU7PoWTargetSpacingRatio}$ +those constants that represent a time duration (marked "Scale by 3" +below), and SHOULD NOT scale those whose semantics are intrinsically +measured in blocks (marked "No change"): + +| Constant | Current | Post-activation | Notes | +|---------------------------------------------|---------|-----------------|-------| +| `COINBASE_MATURITY` | 100 | 100 | No change; | +| `MAX_REORG_LENGTH` | 99 | 600 | Scale by 6; decoupled from `COINBASE_MATURITY` | +| `TX_EXPIRING_SOON_THRESHOLD` | 3 | 3 | No change; | +| `MAX_BLOCKS_IN_TRANSIT_PER_PEER` | 16 | 48 | Scale by 3 | +| `BLOCK_DOWNLOAD_WINDOW` | 1024 | 3072 | Scale by 3 | +| `MIN_BLOCKS_TO_KEEP` | 288 | 864 | Scale by 3; keep 6 hours worth of blocks | +| `NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD` | 1728 | 1728 | No change; | + +This proposal is fundamentally about decreasing the target +spacing, which makes the wall-clock margin shorter for any given +`MAX_REORG_LENGTH`. Zebra's `MAX_REORG_LENGTH` is currently 99, set +just below `COINBASE_MATURITY` (= 100) by Bitcoin-inherited +convention. At Zcash's launch 150-second spacing it covered about +4.2 hours, at the current 75-second spacing about 125 minutes, and +at NU7's proposed 25-second spacing only about 42 minutes. + +Recent incidents show consensus splits can persist beyond tens of minutes: +for example, Litecoin's April 2026 MWEB incident produced a +13-block invalid chain that was later reorged out, with a ~3-hour +recovery window per the postmortem [^litecoin-mweb-incident]. The +optimal long-term value for `MAX_REORG_LENGTH` likely needs to +change further in the future, but that is out of scope here. +Raising it to 600 blocks restores the ~4.2-hour wall-clock window +it provided at Zcash's launch 150-second target spacing, while +`COINBASE_MATURITY` remains 100. This is more conservative than the +~125-minute window at today's 75-second spacing. Given the incident +above and that the launch 150-second-spacing value predates this +line of evidence, restoring the launch wall-clock margin is the +safer choice. + +This deliberately means that a supported reorg may invalidate a +mature coinbase output. That case is already a valid consequence +of deep PoW reorgs in the abstract protocol model. + +### Anchor selection depth + +ZIP 315 [^zip-0315], recommends selecting an anchor 3 blocks back from +the chain tip when constructing shielded transactions. The recommended +anchor depth SHOULD remain at 3 blocks after activation, reducing the average +wall-clock anchor delay from ~3.75 minutes to ~1.25 minutes. This +follows the same precedent set by the Blossom upgrade (ZIP 208 +[^zip-0208]), which did not update the anchor depth and therefore halved delay. + +| Parameter | Current | Post-activation | Notes | +|-----------|---------|-----------------|-------| +| Recommended anchor depth | 3 blocks (~3.75 min) | 3 blocks (~1.25 min) | No change; follows Blossom precedent | + +The increased likelihood of forking due to block time reduction should not be +concerning here. For an issue to occur when anchor depth is 3 blocks back, you +must have a 4 block re-org. In the many years of Ethereum PoW, a 4 block re-org +has never been observed [^lovejoy-reorg]. So we are not practically at risk of +inherent randomness causing a re-org. In other POW chains, re-orgs of 4+ +blocks resulted from a consensus split of some form, including the recent +Litecoin attack, or an attack from a surge in hashpower. +Anchor height depth is not intended to protect against those two vectors. + +# Rationale + +## Shielded sync bandwidth analysis + +The per-pool block space limits are chosen so that the worst-case daily +bandwidth for lightweight wallet syncing does not increase relative to +the current protocol. This section presents the analysis. + +### Parameters + +| Parameter | Value | +|-----------|-------| +| Block size limit | 2,000,000 bytes | +| Block target spacing | 25 seconds | +| Blocks per day | $ 86{,}400 / 25 = 3{,}456$ | +| Compact block header size | ~90 bytes | + +**Orchard pool:** + +| Parameter | Value | +|-----------|-------| +| $\mathsf{OrchardBlockActionLimit}$ | 330 actions | +| Compact sync bandwidth per action | 148 bytes | +| Compact bandwidth per block | $330 \times 148 = 48{,}840$ bytes | + +**Sapling pool:** + +| Parameter | Value | +|-----------|-------| +| $\mathsf{SaplingBlockIOLimit}$ | 300 (inputs + outputs) | +| Compact sync bandwidth per spend | 32 bytes | +| Compact sync bandwidth per output | 116 bytes | +| Compact bandwidth per block (worst case, all outputs) | $300 \times 116 = 34{,}800$ bytes | + +### Daily bandwidth comparison + +| Metric | Current (75s, no pool limits) | Proposed (25s, action limits) | +|--------|-------------------------------|-------------------------------| +| Blocks per day | 1,152 | 3,456 | +| Max Orchard actions/block | ~617 (block-size limited) | 330 | +| Max Sapling IOs/block | ~2,140 (block-size limited) | 300 | +| Orchard compact BW/day | ~105.2 MB | 168.79 MB | +| Sapling compact BW/day | ~270.38 MB | 120.27 MB | +| Compact block headers/day | ~0.10 MB | 0.31 MB | +| **Worst-case total BW/day** | **~270.5 MB** | **169.10 MB** | +| Worst-case trial decrypts/day | ~4.8M | ~2.3M | + +The worst-case compact sync bandwidth is **169.10 MB/day**, a reduction +of **37%** from today's worst case of approximately 270.5 MB/day. This +is despite a 3× increase in block frequency and overall throughput +capacity. + +The binding constraint is Orchard at 330 actions per block: +$330 \times 148 \times 3{,}456 + 90 \times 3{,}456 = 169.10\text{ MB/day}$. + +The trial decryption count also decreases significantly, since the +per-block action limits more than offset the 3× increase in block count. + +Note that the trial decrypt count is 2× the number of shielded +outputs/actions, because wallets must attempt decryption with both the +internal and external incoming viewing keys (IVKs). The internal IVK +detects change outputs sent back to the wallet, while the external IVK +detects incoming payments. In principle, wallets could avoid trial decrypts +with their IVK assuming other sync trade-offs are taken, but current Sapling and +Orchard wallets always attempt both. + +### Normal transaction throughput + +For standard 2-action Orchard transactions, the action limit of 330 +allows $\lfloor 330 / 2 \rfloor = 165$ transactions per block, giving: + +$$\mathsf{orchard\_tps} = 165 \;/\; 25 = 6.6 \text{ TPS}$$ + +For comparison, the current protocol (75s blocks, block-size limited) +supports approximately 2.9 TPS for 2-action Orchard transactions. This +is a **2.3× increase** in normal Orchard throughput. + +**Sapling throughput.** For standard Sapling transactions (2 spends + 2 +outputs = 4 IOs), the limit of 300 IOs allows $\lfloor 300 / 4 \rfloor += 75$ transactions per block, giving $75 / 25 = 3.0$ TPS. Even with +the reduced Sapling limit, the post-NU7 Sapling TPS (3.0) still +exceeds the current pre-NU7 Orchard TPS (2.9). + +### Fee incentives and DoS resistance + +A concern with per-pool limits is that a DoS attacker could fill +the Sapling or Sprout budget to crowd out Orchard transactions (or vice +versa). The global shielded budget prevents this from being worse than +filling any single pool, but it is worth examining whether fee +incentives create an asymmetry. + +Under ZIP 317 [^zip-0317], the conventional fee is based on *logical +actions*: each Sapling output or spend counts as one logical action, and +each Orchard action counts as one logical action. The marginal fee per +logical action is the same regardless of pool. Therefore, an attacker +gains no fee advantage by spamming Sapling instead of Orchard (or vice +versa). The cost per unit of shielded budget consumed is identical. + +Furthermore, because the global shielded budget is shared, filling +the Sapling budget necessarily reduces the Orchard budget by the same +amount. An attacker who spends their entire budget on Sapling spam at +300 IOs leaves only 30 Orchard actions available in that block. But +this attack is no cheaper than filling 330 Orchard actions directly, +since the per-action fee is the same. The global budget ensures that +the total shielded sync cost per block is bounded to 330 units +regardless of the attacker's pool choice. + +The Orchard per-pool cap of 330 also guarantees that legitimate Orchard +transactions always have access to the full Orchard budget when Sapling +and Sprout are not used, which is the expected common case going +forward. + + +## Difficulty averaging window [difficulty-averaging-window] + +This proposal increases $\mathsf{PoWAveragingWindow}$ from 17 to 102 +at NU7 activation (specified in +[Averaging window](#averaging-window) under Consensus changes), so +that the wall-clock smoothing window is +$102 \times 25 = 17 \times 150 = 2{,}550$ seconds — the same +wall-clock window the value $\mathsf{PoWAveragingWindow} = 17$ was +originally chosen to provide at Zcash's launch target spacing of +150 s. At today's 75 s spacing the same value covers only 1,275 s, +and at NU7's proposed 25 s spacing it would cover only 425 s. + +The motivations are: + +1. To preserve the wall-clock duration over which difficulty is + smoothed, so that NU7 does not amplify difficulty-manipulation + attacks like the one recently observed on Litecoin + [^litecoin-mweb-incident]. +2. As an additional improvement over keeping + $\mathsf{PoWAveragingWindow} = 17$, to reduce the standard + deviation of block-spacing averages over short rolling windows. + +Under a Zebra difficulty-adjustment simulator +[^daa-recovery-benchmark] with a stable hash rate and with +$\mathsf{PoWAveragingWindow} = 17$ unchanged across the transition, +the expected block spacing recovers to within 5% of the new 25 s +target within 62 blocks of NU7 activation: + +| Expected spacing | Blocks after activation | Wall-clock | +|-----------------------|-------------------------|------------| +| 75 s (pre-NU7 target) | — | — | +| 56.8 s (activation) | 0 | — | +| $\leq 30$ s | 30 | \~21 min | +| $\leq 26.25$ s | 62 | \~36 min | + +Setting $\mathsf{PoWAveragingWindow} = 102$ is expected to require +roughly 6× as many blocks to cross each threshold, which is the +same wall-clock duration as recovery would have taken at Zcash's +launch 150 s spacing with $\mathsf{PoWAveragingWindow} = 17$. + +For a real-world reference point, the Blossom upgrade [^zip-0208] +made a 2× target-spacing reduction (150 s → 75 s) with +$\mathsf{PoWAveragingWindow}$ unchanged; mainnet block spacing +(20-block rolling average) reached approximately 74 s at height +653,664 — 64 blocks after activation. + +Two geographically-distributed devnets of 99 Zebra nodes across 14 +regions (1 vCPU per node), one at $\mathsf{PoWAveragingWindow} = 17$ +and one at 51, confirmed a \~1-second reduction in the standard +deviation of 5- and 10-block rolling-average block spacings. The +variance reduction is expected to be somewhat larger at +$\mathsf{PoWAveragingWindow} = 102$. + + +# Deployment + +This proposal is intended to be deployed as part of NU7, should tokenholder polling and developer consensus agree on it. A separate ZIP will specify the deployment details including +activation heights and consensus branch IDs. + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.3 or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.3. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-constants]: [Zcash Protocol Specification, Version 2025.6.3. Section 5.3: Constants](protocol/protocol.pdf#constants) + +[^protocol-diffadjustment]: [Zcash Protocol Specification, Version 2025.6.3. Section 7.7.3: Difficulty adjustment](protocol/protocol.pdf#diffadjustment) + +[^protocol-txnencoding]: [Zcash Protocol Specification, Version 2025.6.3. Section 7.1: Transaction Encoding and Consensus](protocol/protocol.pdf#txnencoding) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0205]: [ZIP 205: Deployment of the Sapling Network Upgrade](zip-0205.rst) + +[^zip-0206]: [ZIP 206: Deployment of the Blossom Network Upgrade](zip-0206.rst) + +[^zip-0208]: [ZIP 208: Shorter Block Target Spacing](zip-0208.rst) + +[^zip-0315]: [ZIP 315: Best Practices for Wallet Implementations](zip-0315.rst) + +[^zip-0317]: [ZIP 317: Proportional Transfer Fee Mechanism](zip-0317.rst) + +[^crosslink]: [Crosslink — a Zcash Finality Protocol](https://electric-coin-company.github.io/zcash-crosslink/) + +[^slowfastblocks]: [On Slow and Fast Block Times](https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/) + +[^syncsimulator]: [Shielded Sync Simulator](https://nu7syncsimulator.valargroup.dev/) + +[^lovejoy-reorg]: [Lovejoy, James P. (2020). *An Empirical Analysis of Chain Reorganizations and Double-Spend Attacks on Proof-of-Work Cryptocurrencies.* M.Eng. thesis, Massachusetts Institute of Technology, Department of Electrical Engineering and Computer Science.](https://static1.squarespace.com/static/6675a0d5fc9e317c60db9b37/t/66eb3560532516773c4f7ece/1726690657755/LovejoyJamesP-meng-eecs-2020+%281%29.pdf) + +[^forum-proposal]: [Forum: Proposal — Lower Zcash Block Target Spacing to 25s](https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577) + +[^devnet-blocktime-test]: [Forum: Zcash Block Time Reduction Appears Safe for NU7 w/ Zebra-only Devnet](https://forum.zcashcommunity.com/t/zcash-block-time-reduction-appears-safe-for-nu7-w-zebra-only-devnet/55586) + +[^verification-benchmark]: [Zebra worst-case block verification benchmark (`worst_case_tx_verification.rs`)](https://github.com/valargroup/zebra/blob/evan/benchmark-worst-case-block-verification/zebra-consensus/benches/worst_case_tx_verification.rs) + +[^daa-recovery-benchmark]: [Zebra difficulty-adjustment recovery simulator: `benchmark_hash_rate_shock_daa_configurations` in `zebra-state/src/service/check/difficulty.rs`](https://github.com/valargroup/zebra/blob/evan/benchmark-worst-case-block-verification/zebra-state/src/service/check/difficulty.rs#L555). The 3× target-spacing transition is exercised by [`simulate_three_x_target_spacing_reduction`](https://github.com/valargroup/zebra/blob/evan/benchmark-worst-case-block-verification/zebra-state/src/service/check/difficulty.rs#L397) in the same file. + +[^litecoin-mweb-incident]: [Litecoin MWEB Security Incident Postmortem](https://litecoin.com/news/litecoin-mweb-security-incident-postmortem) diff --git a/zips/zip-0226.rst b/zips/zip-0226.rst index 4b42c0057..4c35334a8 100644 --- a/zips/zip-0226.rst +++ b/zips/zip-0226.rst @@ -42,6 +42,8 @@ Abstract This ZIP (ZIP 226) proposes the Orchard Zcash Shielded Assets (OrchardZSA) protocol, in conjunction with ZIP 227 [#zip-0227]_. The OrchardZSA protocol is an extension of the Orchard protocol that enables the issuance, transfer and burn of custom Assets on the Zcash chain. The issuance of such Assets is defined in ZIP 227 [#zip-0227]_, while the transfer and burn of such Assets is defined in this ZIP (ZIP 226). While the proposed OrchardZSA protocol is a modification to the Orchard protocol, it has been designed with adaptation to possible future shielded protocols in mind. +This ZIP is defined relative to the Zcash protocol with the changes specified in ZIP 2005 [#zip-2005]_ applied. ZIP 2005 (Orchard Quantum Recoverability) is expected to deploy before any ZSA activation; the references in this document to $\mathsf{H^{rcm,Orchard}}$, $\mathsf{H^{\text{ψ},Orchard}}$, recoverable note plaintexts, and related constructs are to be interpreted as defined by ZIP 2005's modifications to the protocol specification. + Motivation ========== @@ -157,6 +159,8 @@ The nullifier is generated in the same manner as in the Orchard protocol §4.16 The OrchardZSA note plaintext also includes the Asset Base $\mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]}$ in addition to the components in the Orchard note plaintext [#protocol-notept]_. The explicit encoding of the note plaintext is provided in ZIP 230 [#zip-0230-orchard-note-plaintext]_. +When § 4.7.3 'Sending Notes (Orchard)' [#protocol-orchardsend]_ or § 4.8.3 'Dummy Notes (Orchard)' [#protocol-orcharddummynotes]_ are invoked directly or indirectly in the computation of $\text{ρ}$ and $\text{ψ}$ for an OrchardZSA note, $\mathsf{leadByte}$ MUST be set to {{ZSALEADBYTE}}. + The explicit order of addition of the note commitments to the note commitment tree is specified in ZIP 227 [#zip-0227-note-commitment-order]_. Rationale for Note Commitment @@ -290,7 +294,7 @@ For Split Notes, the nullifier is generated as follows: .. math:: \mathsf{nf_{old}} = \mathsf{Extract}_{\mathbb{P}} ([(\mathsf{PRF^{nfOrchard}_{nk}} (\text{ρ}^{\mathsf{old}}) + \text{ψ}^{\mathsf{nf}}) \bmod q_{\mathbb{P}}]\,\mathcal{K}^\mathsf{Orchard} + \mathsf{cm^{old}} + \mathcal{L}^\mathsf{Orchard}) -where $\text{ψ}^{\mathsf{nf}}$ is sampled uniformly at random on $\mathbb{F}_{q_{\mathbb{P}}}$, $\mathcal{K}^{\mathsf{Orchard}}$ is the Orchard Nullifier Base as defined in §4.16 ‘Computing ρ values and Nullifiers’ [#protocol-rhoandnullifiers]_, and $\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard”}, \texttt{“L”})$. +where $\text{ψ}^{\mathsf{nf}}$ is computed as $\mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed\_nf}}([\mathtt{0x0A}] \,||\, \underline{\text{ρ}^{\mathsf{old}}})\kern-0.1em\big)$ for $\mathsf{rseed\_nf}$ sampled uniformly at random on $\mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[32]}$, $\mathcal{K}^{\mathsf{Orchard}}$ is the Orchard Nullifier Base as defined in §4.16 ‘Computing ρ values and Nullifiers’ [#protocol-rhoandnullifiers]_, and $\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard”}, \texttt{“L”})$. The first-byte domain separator $\mathtt{0x0A}$ for $\mathsf{PRF^{expand}}$ is reserved by ZIP 2005 [#zip-2005]_ for this use. Rationale for Split Notes ````````````````````````` @@ -388,11 +392,9 @@ The following requirements on wallets are specified and motivated in ZIP 230 ZEC asset. For other consequences see ZIP 230. * *All* wallets should be ready to receive funds in outputs of v6 transactions as soon - as ZSAs activate — in particular to support decrypting note plaintexts with lead-byte - $\mathtt{0x03}$ [#zip-0230-note-plaintexts]_. The consequence of not doing so would - be that funds sent to Orchard addresses of a wallet without this support could be - temporarily inaccessible, until the wallet is upgraded to fully support v6 and to - rescan outputs since v6 activation. + as ZSAs activate. The consequence of not doing so would be that funds sent to Orchard + addresses of a wallet without this support could be 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]_ ------------------------------------------------------ @@ -459,11 +461,12 @@ References .. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability <zip-0244.rst>`_ .. [#zip-0246] `ZIP 246: Digests for the Version 6 Transaction Format <zip-0246.rst>`_ .. [#zip-0307] `ZIP 307: Light Client Protocol for Payment Detection <zip-0307.rst>`_ -.. [#zip-2005] `ZIP 2005: Quantum Recoverability <zip-2005.md>`_ +.. [#zip-2005] `ZIP 2005: Orchard Quantum Recoverability <zip-2005.md>`_ .. [#protocol] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later. <protocol/protocol.pdf>`_ .. [#protocol-notes] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.2: Notes <protocol/protocol.pdf#notes>`_ .. [#protocol-actions] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.7: Action Transfers and their Descriptions <protocol/protocol.pdf#actions>`_ .. [#protocol-abstractcommit] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.1.8: Commitment <protocol/protocol.pdf#abstractcommit>`_ +.. [#protocol-orchardsend] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.3: Sending Notes (Orchard) <protocol/protocol.pdf#orchardsend>`_ .. [#protocol-orcharddummynotes] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.8.3: Dummy Notes (Orchard) <protocol/protocol.pdf#orcharddummynotes>`_ .. [#protocol-orchardbalance] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.14: Balance and Binding Signature (Orchard) <protocol/protocol.pdf#orchardbalance>`_ .. [#protocol-rhoandnullifiers] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.16: Computing ρ values and Nullifiers <protocol/protocol.pdf#rhoandnullifiers>`_ diff --git a/zips/zip-0230.rst b/zips/zip-0230.rst index 7ad1dcf3a..e5c016b1e 100644 --- a/zips/zip-0230.rst +++ b/zips/zip-0230.rst @@ -1,7 +1,7 @@ :: ZIP: 230 - Title: Version 6 Transaction Format + Title: Withdrawn Version 6 Transaction Format Owners: Daira-Emma Hopwood <daira@jacaranda.org> Jack Grigg <thestr4d@gmail.com> Sean Bowe <ewillbefull@gmail.com> @@ -11,7 +11,7 @@ Original-Authors: Greg Pfeil Deirdre Connolly Credits: Ying Tong Lai - Status: Draft + Status: Withdrawn Category: Consensus Created: 2023-04-18 License: MIT @@ -35,6 +35,15 @@ The character § is used when referring to sections of the Zcash Protocol Specif Abstract ======== +.. warning:: + This ZIP has been obsoleted by ZIP 248 [#zip-0248]_, and will not be deployed. Transaction + version number 6 is now defined by ZIP 248. + + Occurrences of the note plaintext lead byte constant it introduced (originally $\mathtt{0x03}$) + have been changed to "{{LEADBYTE}}", to clarify that this ZIP does not reserve that lead byte + value, and to avoid confusion with the different specification of lead byte $\mathtt{0x03}$ in + ZIP 2005 [#zip-2005]_. + This proposal defines a new Zcash peer-to-peer transaction format, which supports the changes being deployed in Network Upgrade 7 [#draft-arya-deploy-nu7]_. It follows the same design pattern as the v5 transaction format [#zip-0225]_. @@ -46,7 +55,7 @@ Motivation The OrchardZSA protocol requires serialized data elements that are distinct from any previous Zcash transaction. Since ZIP 244 was activated in NU5, the v5 and later serialized transaction formats are not consensus-critical. -Thus, this ZIP defines format that can easily accommodate future extensions, +Thus, this ZIP defines a format that can easily accommodate future extensions, where elements or a given pool are kept separate. @@ -487,11 +496,11 @@ An issuance note description, ``IssueNoteDescription`` contains the following fi Note Plaintexts --------------- -New note plaintext formats using lead byte $\mathtt{0x03}$ are introduced for +New note plaintext formats using lead byte {{LEADBYTE}} are introduced for Sapling and Orchard, in order to support memo bundles and (for Orchard) ZSAs and quantum recoverability. -The $\mathsf{leadByte}$ MUST be $\mathtt{0x03}$ for all note plaintexts in v6 +The $\mathsf{leadByte}$ MUST be {{LEADBYTE}} for all note plaintexts in v6 transactions. Sapling Note Plaintext @@ -546,8 +555,8 @@ The encodings of $\mathsf{d}$, $\mathsf{v}$, and $\mathsf{rseed}$ remain unchang Non-normative note: The *use* of the $\mathsf{rseed}$ in Orchard note decryption changes, but its type and encoding do not. -Rationale for requiring the lead byte to be 0x03 in v6 -`````````````````````````````````````````````````````` +Rationale for requiring the lead byte to be {{LEADBYTE}} in v6 +`````````````````````````````````````````````````````````````` It was decided to synchronize the changes to note encryption required for quantum recoverability, ZSA support, and memo bundles with a change to the @@ -632,7 +641,7 @@ Support for receiving funds in v6 transactions Zcash wallets MUST support parsing and processing v6 transactions by the time they are allowed on the network (scheduled for NU7 activation). This includes -detecting and decrypting lead-byte $\mathtt{0x03}$ note plaintexts and memo +detecting and decrypting lead-byte {{LEADBYTE}} note plaintexts and memo bundles. The necessary changes to note decryption are specified in ZIP 231 [#zip-0231]_, @@ -648,7 +657,7 @@ once that support is added. Rationale for being ready to receive v6 transactions at their activation ```````````````````````````````````````````````````````````````````````` -Note plaintexts with lead byte $\mathtt{0x03}$, which are required for Orchard +Note plaintexts with lead byte {{LEADBYTE}}, which are required for Orchard notes in v6 transactions, can be sent to any Orchard address. These notes use a different computation of $\mathsf{rcm}$ and $\text{ψ}$ from @@ -660,7 +669,7 @@ attempting to non-conformantly use the note decryption algorithm for lead byte $\mathtt{0x02}$ would compute a different note commitment $\mathsf{cm}_x$ and would reject the note. -If wallets do not support v6 transactions and lead-byte $\mathtt{0x03}$ note +If wallets do not support v6 transactions and lead-byte {{LEADBYTE}} note decryption immediately, then funds may be sent to them that they cannot receive. This affects both the existing Orchard functionality, and receiving non-native ZSA assets. @@ -720,5 +729,5 @@ References .. [#zip-0301] `ZIP 301: Zcash Stratum Protocol <zip-0301.rst>`_ .. [#zip-2002-motivation] `ZIP 231: Explicit Fees — Motivation <zip-2002.rst#motivation>`_ .. [#zip-2005] `ZIP 2005: Quantum Recoverability <zip-2005.md>`_ -.. [#zip-2005-security-analysis] `ZIP 2005: Quantum Recoverability — Security Analysis <zip-2005.md#security-analysis>`_ +.. [#zip-2005-security-analysis] `ZIP 2005: Quantum Recoverability — Security Analysis <zip-2005.md#securityanalysis>`_ .. [#draft-arya-deploy-nu7] `draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade <draft-arya-deploy-nu7.md>`_ diff --git a/zips/zip-0231.md b/zips/zip-0231.md index 45c8e4a0a..f5b05b61f 100644 --- a/zips/zip-0231.md +++ b/zips/zip-0231.md @@ -487,7 +487,7 @@ In § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ [^protocol-notepten > > $\begin{array}{|c|c|c|c|c|} \hline \raisebox{0.6ex}{\mathstrut} \text{8-bit } \mathsf{leadByte} & \text{88-bit } \mathsf{d} & \text{64-bit } \mathsf{v} & \text{256-bit } \mathsf{rseed} & \text{32-byte } \mathsf{K^{memo}} \\\hline \end{array}$ > - > * A byte 0x03, indicating this version of the encoding of a v6-onward + > * A byte {{MBLEADBYTE}}, indicating this version of the encoding of a v6-onward > Sapling or Orchard note plaintext. > * 11 bytes specifying $\mathsf{d}$. > * 8 bytes specifying $\mathsf{v}$. @@ -583,6 +583,11 @@ synchronization. TBD +## Note plaintext lead byte assignment + +The lead byte to be used for this proposal, denoted as {{MBLEADBYTE}} above, has +not yet been assigned. + # Rationale diff --git a/zips/zip-0303.rst b/zips/zip-0303.rst index 54e439e80..85f17c416 100644 --- a/zips/zip-0303.rst +++ b/zips/zip-0303.rst @@ -4,6 +4,6 @@ Title: Sprout Payment Disclosure Owners: Deirdre Connolly <deirdre@zfnd.org> Original-Authors: Simon Liu - Status: Reserved + Status: Withdrawn Category: Standards / RPC / Wallet Pull-Request: <https://github.com/zcash/zips/pull/119> diff --git a/zips/zip-0316.rst b/zips/zip-0316.rst index c9c0e4d4b..7e7058f4c 100644 --- a/zips/zip-0316.rst +++ b/zips/zip-0316.rst @@ -321,22 +321,24 @@ Revisions * Revision 0: The initial version of this specification. -.. _`Revision 1` (Withdrawn): +.. _`Revision 1`: -* Revision 1 proposed a variant of this specification similar to that specified - for `Revision 2`_ addresses having the `tu` Human-Readable Part. It faced - [opposition from the community](https://forum.zcashcommunity.com/t/unified-addresses-composition/51024/7) +* Revision 1 (Withdrawn): Revision 1 proposed a variant of this specification + similar to that specified for `Revision 2`_ addresses having the ``tu`` + Human-Readable Part. It faced `opposition from the community + <https://forum.zcashcommunity.com/t/unified-addresses-composition/51024/7>`_ due to it being difficult to discern the privacy implications of sharing an address as that specified, and has been withdrawn. See - https://github.com/zcash/zips/blob/4acf32ac6db409d93041c463880dad6df83875e1/zips/zip-0316.rst - for the specification that was proposed. + `the previously proposed specification + <https://github.com/zcash/zips/blob/4acf32ac6db409d93041c463880dad6df83875e1/zips/zip-0316.rst>`_ + for details. .. _`Revision 2`: * Revision 2: This version adds support for `MUST-understand Typecodes`_ and `Address Expiration Metadata`_. It introduces two new variants of Unified - Addresses; `zu` addresses, which are prohibited from containing transparent - receivers, and `tu` addresses, which allow transparent receivers to be + Addresses; ``zu`` addresses, which are prohibited from containing transparent + receivers, and ``tu`` addresses, which allow transparent receivers to be augmented with metadata items. For Unified Viewing Keys, this version adopts ``uvf`` and ``uvi`` encoding prefixes for Unified Full Viewing Keys and Unified Incoming Viewing Keys respectively, drops the restriction that a UVK @@ -680,16 +682,14 @@ representation of viewing keys for P2SH addresses, which is an important use case with the advent of ZIP 48 [#zip-0048]_. In addition, transparent-only viewing keys can use Metadata Items to represent expiration heights/dates as described in `Address Expiration Metadata`_ that is useful in the generation of -`tu`-prefixed addresses. +``tu``-prefixed addresses. .. raw:: html </details> -.. _`Rationale for removing Transparent Receivers from zu Unified Addresses`: - -Rationale for removing Transparent Receivers from `zu` Unified Addresses -'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +Rationale for removing Transparent Receivers from ``zu`` Unified Addresses +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' .. raw:: html @@ -701,7 +701,7 @@ way for a user to visually distinguish a Unified Address that allowed the receipt of transparent funds from one that did not; Transparent addresses do not provide any privacy protection, and including them in UAs created a risk that Senders would fall back to transparent transfers even when the Recipient -supports shielded protocols. Historically, the `z` address prefix indicated +supports shielded protocols. Historically, the ``z`` address prefix indicated to the user that no element of the recipient address would cause information about the recipient to be leaked on-chain by transfers to that address. `Revision 2`_ restores this property. @@ -942,8 +942,6 @@ set this bound more tightly; a common expiry delta used by many wallets is 40 blocks from the current chain tip, as suggested in ZIP 203 [#zip-0203-default-expiry]_. -.. _`Typecode Registry`: - Typecode Registry ----------------- diff --git a/zips/zip-0318.rst b/zips/zip-0318.rst deleted file mode 100644 index 1081e4d3e..000000000 --- a/zips/zip-0318.rst +++ /dev/null @@ -1,11 +0,0 @@ -:: - - ZIP: 318 - Title: Associated Payload Encryption - Owners: Kris Nuttycombe <kris@nutty.land> - Daira-Emma Hopwood <daira@jacaranda.org> - Status: Reserved - Category: Standards Track - Created: 2022-09-19 - License: MIT - Discussions-To: <https://github.com/zcash/zips/issues/633> diff --git a/zips/zip-0416.rst b/zips/zip-0416.rst index eb15749bc..1f5a067b3 100644 --- a/zips/zip-0416.rst +++ b/zips/zip-0416.rst @@ -1,10 +1,10 @@ :: ZIP: 416 - Title: Support for Unified Addresses in zcashd + Title: Spending Key Derivation in the `zcashd` wallet Owners: Daira-Emma Hopwood <daira@jacaranda.org> Jack Grigg <thestr4d@gmail.com> Kris Nuttycombe <kris@nutty.land> Status: Reserved Category: RPC / Wallet - Discussions-To: <https://github.com/zcash/zips/issues/503> + Discussions-To: <https://github.com/zcash/zips/issues/1175> diff --git a/zips/zip-2005.md b/zips/zip-2005.md index 241e18af1..ce0250e76 100644 --- a/zips/zip-2005.md +++ b/zips/zip-2005.md @@ -1,15 +1,19 @@ ZIP: 2005 - Title: Quantum Recoverability + Title: Orchard Quantum Recoverability Owners: Daira-Emma Hopwood <daira@jacaranda.org> Jack Grigg <thestr4d@gmail.com> Credits: Sean Bowe - Status: Draft + Dev Ojha + Kris Nuttycombe + Status: Proposed Category: Consensus Created: 2025-03-31 License: MIT Discussions-To: <https://github.com/zcash/zips/issues/1135> Pull-Request: <https://github.com/zcash/zips/pull/1126> + <https://github.com/zcash/zips/pull/1184> + <https://github.com/zcash/zips/pull/1275> # Terminology @@ -25,13 +29,24 @@ 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, and a variable suffixed with $\star$ indicates a bit-sequence encoding of an elliptic curve point. +The notation ${k \choose n}$ denotes the binomial coefficient — the +number of ways of choosing $n$ items from a set of $k$, equal to +$\frac{k!}{n!(k-n)!}$ for $0 \leq n \leq k$. + +For brevity, in the discussion sections of this ZIP we abbreviate +$\mathsf{H^{rcm,Orchard}}$ as $\mathsf{H^{rcm}}$, +$\mathsf{PRF^{nfOrchard}}$ as $\mathsf{PRF^{nf}}$, +$\mathcal{K}^{\mathsf{Orchard}}$ as $\mathcal{K}$, +and similarly for other Orchard-specific hash function names. The changes +to the protocol specification and to other ZIPs use the full forms. + The term "Zcash Shielded Assets" or "ZSAs" refers to the extension to the Orchard shielded protocol described in ZIPs 226 and 227 [^zip-0226] [^zip-0227]. @@ -39,8 +54,9 @@ The term "Orchard[ZSA]" in this document refers to the Orchard shielded protocol before the deployment of ZSAs, and to the OrchardZSA shielded protocol after the deployment of ZSAs. -The term "recoverable Orchard[ZSA] note" refers to an Orchard or OrchardZSA -note that was created according to this proposal. +The terms "recoverable note" and "recoverable note plaintext" refer to a +note or note plaintext that was created according to this proposal. As +initially deployed, these are necessarily Orchard notes or note plaintexts. The term "Recovery Protocol" refers to a potential new shielded protocol that would allow recovery of funds held in recoverable Orchard[ZSA] notes. @@ -50,12 +66,12 @@ many of its design decisions are intentionally left open. # Abstract -This ZIP proposes a change to the construction of Orchard[ZSA] notes -starting with v6 transactions, designed to improve Zcash's long-term -resilience against a significant potential threat to its security from -quantum computers. It does not by itself make the protocol secure against -quantum adversaries, but is intended to support a smoother transition to -future versions of Zcash designed to be so. +This ZIP proposes a change to the construction of Orchard[ZSA] notes, +designed to improve Zcash's long-term resilience against a significant +potential threat to its security from quantum computers. It does not +by itself make the protocol secure against quantum adversaries, but is +intended to support a smoother transition to future versions of Zcash +designed to be so. Specifically, if it were necessary to disable the current Orchard[ZSA] shielded protocol in order to prevent a discrete-log-breaking adversary @@ -112,8 +128,8 @@ Sapling [^zip-0032-sapling-child-key-derivation] [^zip-0032-sapling-internal-key and Orchard [^zip-0032-orchard-child-key-derivation] [^zip-0032-orchard-internal-key-derivation].) This proposal is implementable at low risk, and required changes to existing -libraries and wallets are small. It can be folded into other changes -necessary to implement ZSAs [^zip-0226] and Memo Bundles [^zip-0231]. +libraries and wallets are small. It is compatible with Memo Bundles [^zip-0231] +and/or ZSAs [^zip-0226]. # Requirements @@ -124,9 +140,9 @@ necessary to implement ZSAs [^zip-0226] and Memo Bundles [^zip-0231]. discrete-log-breaking and quantum adversaries. * No particular choice of post-quantum proving system or commitment tree hash should be assumed for that alternate protocol. -* The proposed scheme should be fully compatible with FROST - multisignatures [^zip-0312], hardware wallets, and the combination - of both. +* The proposed scheme should be fully compatible with FROST threshold + multisignatures [^zip-0312], hardware wallets, and the combination of + both. * The proposed scheme should not require regeneration of existing non-multisignature keys or addresses. * The changes made to the pre-quantum protocol should not cause a @@ -134,10 +150,8 @@ necessary to implement ZSAs [^zip-0226] and Memo Bundles [^zip-0231]. against any given adversary class, or require significant re-analysis of that protocol's pre-quantum security. * The Recovery Protocol should ensure no loss of security against - pre-quantum adversaries — including when FROST multisignatures and/or - hardware wallets are used. (This is motivated by the fact that there - is likely to be a period during which quantum attacks may be possible - but very difficult.) + pre-quantum adversaries — including when FROST threshold multisignatures + and/or hardware wallets are used. * Recovery of funds from hardware wallets that support this protocol should not require exposing the pre-quantum spend authorizing key $\mathsf{ask}$ to theft. @@ -163,31 +177,49 @@ necessary to implement ZSAs [^zip-0226] and Memo Bundles [^zip-0231]. This subsection and the flow diagram below are non-normative. -In order to support ZSAs [^zip-0226] [^zip-0227] and memo bundles -[^zip-0231], v6 transactions require in any case a new note plaintext -format, with lead byte $\mathtt{0x03}.$ This gives us an opportunity -to change the way that the $\mathsf{pre\_rcm}$ value is computed for -this new format, by including all of the note fields in $\mathsf{pre\_rcm}$. -The resulting $\mathsf{rcm}$ is essentially a random function of the -note fields — this allows us to argue that the overall commitment -scheme is post-quantum binding, as long as the new derivation of -$\mathsf{rcm}$ is checked in the Recovery Protocol. +This proposal defines a new note plaintext format for Orchard notes, +with lead byte $\mathtt{0x03}.$ The $\mathsf{pre\_rcm}$ value is computed +differently for this new format, by including all of the note fields in +$\mathsf{pre\_rcm}$. This means that an adversary constrained to treat +the PRF used to derive $\mathsf{rcm}$ from $\mathsf{pre\_rcm}$ as a +random oracle, could not vary any note field without producing a +different $\mathsf{rcm}$. This lets us argue that the overall +commitment scheme is post-quantum binding, as long as the new +derivation of $\mathsf{rcm}$ is checked in the Recovery Protocol. Essentially the same technique also needs to be applied to the function $\mathsf{Commit^{ivk}}$ that is used to derive Orchard -incoming viewing keys. In order to support existing keys, we have -the Recovery Protocol check the derivations of $\mathsf{nk}$, -$\mathsf{ak}$, and $\mathsf{rivk}$ from the secret key $\mathsf{sk}$. - -Since this derivation of (at least) $\mathsf{ak}$ from $\mathsf{sk}$ -cannot be used in the case of FROST key generation, we also provide an -alternative way to derive $\mathsf{rivk}$ which is to be used in that -case. This alternative derivation, using a new "quantum spending key" -$\mathsf{qsk}$ and "quantum intermediate key" $\mathsf{qk}$, also -supports more efficient use of hardware wallets in the Recovery Protocol. -It is described in sections [Usage with FROST] and [Usage with Hardware Wallets]. - -## Flow diagram for the Orchard and OrchardZSA protocols +incoming viewing keys. The randomness $\mathsf{rivk}$ in +$\mathsf{Commit^{ivk}}$ is derived directly or indirectly from +$\mathsf{rivk\_ext}$, which is in turn derived from one of two random +oracles, depending on which key material the user holds: + +* For existing Orchard keys, $\mathsf{rivk\_ext}$ is derived from + the secret key $\mathsf{sk}$ via $\mathsf{H^{rivk\_legacy}}(\mathsf{sk})$, + with $\mathsf{ak}$ and $\mathsf{nk}$ also derived from $\mathsf{sk}$. + The Recovery Protocol checks all three derivations. +* For keys generated via FROST distributed key generation, or for + hardware wallets where exporting $\mathsf{sk}$ is undesirable, an + alternative "quantum spending key" $\mathsf{qsk}$ and "quantum + intermediate key" $\mathsf{qk}$ are used, with + $\mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})$. + The Recovery Protocol checks this derivation together with a + $\mathsf{SoK^{qsk}}$ proof of knowledge of $\mathsf{qsk}$ such that + $\mathsf{H^{qk}}(\mathsf{qsk}) = \mathsf{qk}$. + +Both branches (and both cases +$\mathsf{rivk} \in \big\{ \mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \big\}$) +are covered uniformly by the +[Security argument for key binding](#securityargumentforkeybinding): +each binds the keys $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ — and, +when in use, $\mathsf{qk}$ — to the incoming-viewing key $\mathsf{ivk}$ +post-quantumly, up to a small advantage against collision-finding in +the random oracles used for $\mathsf{rivk}$ derivation. The FROST and +hardware-wallet use cases are described in +[Usage with FROST](#usagewithfrost) and +[Usage with hardware wallets](#usagewithhardwarewallets). + +## Flow diagram for the Orchard protocol This diagram shows, approximately, the derivation of Orchard keys, addresses, notes, note commitments, and nullifiers. All of the flow @@ -217,8 +249,13 @@ graph BT The bold lines are changes introduced by this ZIP, which all take the form of additional inputs to derivation functions or alternative derivations. -The derivations shown in the box labelled "Potential recovery circuit" are, -roughly speaking, those enforced by the [Proposed Recovery Protocol]. +The derivations shown in the box labelled [Proposed Recovery Statement](#proposedrecoverystatement) +are, roughly speaking, those enforced by the section of that name. The +diagram shows the recoverable-note case ($\mathsf{leadByte} = \mathtt{0x03}$); +for $\mathsf{leadByte} = \mathtt{0x02}$ the existing Orchard derivation +$\mathsf{rcm} = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$ +applies, and the additional fields feeding into $\mathsf{pre\_rcm}$ +are absent. ```mermaid graph BT @@ -231,7 +268,7 @@ graph BT classDef spacer opacity:0; PostQC:::circuit - subgraph PostQC[<div style="margin:1.1em;font-size:20px"><b>Potential recovery circuit</b></div>] + subgraph PostQC[<div style="margin:1.1em;font-size:20px"><b>Proposed Recovery Statement</b></div>] direction BT rivk_ext([rivk_ext]) --> Hrivk_int[H<sup>rivk_int</sup>]:::func ak([ak]) --> Hrivk_int[H<sup>rivk_int</sup>]:::func @@ -244,14 +281,9 @@ graph BT Commitivk ---> ivk([ivk]) gd ---> ivkmul[[ivk]g<sub>d</sub> ]:::func ivk --> ivkmul - split_flag([split_flag]) --> Hpsi - rsplit([rsplit]) -->|split_flag| rpsi{{rψ}} - rsplit ~~~ split_flag - rseed -->|¬split_flag| rpsi - rpsi --> Hpsi[H<sup>ψ</sup>]:::func + rseed --> Hpsi[H<sup>ψ</sup>]:::func rho --> Hpsi - leadByte([leadByte]) ==> pre_rcm - v([v, AssetBase]) ===> pre_rcm([pre_rcm]) + v([#8239;v#8239;]) ==> pre_rcm([pre_rcm]) pkd ====> pre_rcm gd ==> pre_rcm psi ===> pre_rcm @@ -264,8 +296,8 @@ graph BT Hpsi --> psi([#8239;ψ#8239;]) gd --> NoteCommit:::func pkd --> NoteCommit - v --> NoteCommit psi --> NoteCommit + v --> NoteCommit rcm --> NoteCommit rho --> NoteCommit cm --> DeriveNullifier:::func @@ -282,6 +314,18 @@ graph BT # Specification +## Proactive movement of funds to recoverable notes + +Once this proposal is deployed, wallets SHOULD move all of the funds they +control (including transparent, Sprout, and Sapling funds) into recoverable +Orchard notes as soon as practically possible. This does not depend on support +from other wallets for receiving recoverable notes, because wallet-internal +addresses can be used. + +Non-recoverable funds may be received after existing funds have been made +recoverable. Wallets SHOULD therefore treat the movement of funds to +recoverable notes as an ongoing process. + ## Usage with FROST When generating Orchard keys for FROST, $\mathsf{ak}$ will be derived jointly @@ -292,7 +336,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 +367,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}}$.) @@ -335,33 +379,31 @@ and when the current Orchard protocol is disabled. The Recovery Protocol will still require a RedDSA signature verifiable by the Spend validating key $\mathsf{ak}$, in addition to knowledge of -$\mathsf{qsk}$. Although RedDSA is not secure in the long term against a -quantum or discrete-log-breaking adversary, the most likely eventuality is -that attacks against it will be difficult for some years after the current -Orchard protocol is disabled. During this period, checking this RedDSA -signature in the Recovery Protocol will ensure that spend authorization by -a $t$-of-$n$ threshold of participants continues to be needed against -classical adversaries. This retains the usual advantage of FROST that the -parties can sign using their shares *without* reconstructing the Spend -authorizing key $\mathsf{ask}$. Coalitions of fewer than $t$ of the -participants will be unable to authorize spends as long as they do not -have access to a sufficiently powerful quantum computer. +$\mathsf{qsk}$. RedDSA is not secure in the long term against a quantum +or discrete-log-breaking adversary. However, during any period in which +the adversary cannot find discrete logarithms on the Pallas curve, +checking this RedDSA signature will ensure that spend authorization +continues to require a $t$-of-$n$ threshold of participants. +An important advantage of FROST —that the parties can sign using their +shares *without* reconstructing $\mathsf{ask}$, the Spend authorizing +key— is retained. Note that a quantum adversary may be able to steal the funds with only -access to $\mathsf{qsk}$, which is held by every participant. Therefore, -it is RECOMMENDED that as soon as a fully post-quantum protocol that -supports multisignatures is available, all funds held under FROST keys -be transferred into that protocol's shielded pool. +access to $\mathsf{qsk}$, which is held by every participant (see below +for more detail on [Key storage options](#keystorageoptionsandanalysis)). +Therefore, it is RECOMMENDED that as soon as a fully post-quantum protocol +that supports threshold multisignatures is available, all funds held under +FROST keys be transferred into that protocol's shielded pool. ## Usage with hardware wallets The same $\mathsf{use\_qsk}$ option can help to improve the efficiency of -using the Recovery Protocol with hardware wallets. If the keys -$\mathsf{rivk\_ext},$ $\mathsf{nk},$ and $\mathsf{ak}$ are generated from -$\mathsf{sk},$ then the circuit for the Recovery Protocol will need to -prove their correct derivation using $\mathsf{H^{rivk\_legacy}},$ -$\mathsf{H^{nk}},$ $\mathsf{H^{ask}},$ and $\mathsf{DerivePublic}$ as -shown in the $\mathsf{SoK^{sk}}$ box of the diagram below. +using the [Recovery Protocol](#proposedrecoveryprotocol) with hardware +wallets. If the keys $\mathsf{rivk\_ext},$ $\mathsf{nk},$ and $\mathsf{ak}$ +are generated from $\mathsf{sk},$ then the circuit for the Recovery Protocol +will need to prove their correct derivation using $\mathsf{H^{rivk\_legacy}},$ +$\mathsf{H^{nk}},$ $\mathsf{H^{ask}},$ and $\mathsf{DerivePublic}$ as shown +in the $\mathsf{SoK^{sk}}$ box of the diagram below. ```mermaid graph BT @@ -396,38 +438,115 @@ graph BT rivk_legacy([rivk_legacy]) -->|¬use_qsk| rivk_ext ``` +<a id="linking-commitments"></a> When $\mathsf{use\_qsk}$ is used, on the other hand, it is possible for -the Recovery Protocol to support spend authorization using a much smaller -circuit that only uses $\mathsf{H^{qk}}$ and a commitment scheme. -For example, for some hiding and collapse binding commitment -$c = \mathsf{LinkCommit}_r(\mathsf{qk}, \mathsf{sighash}),$ +the Recovery Protocol to support spend authorization using a simpler +statement that only uses $\mathsf{H^{qk}}$ and a commitment scheme. +For example, for some hiding and collapse-binding commitment +$$\mathsf{c_{link}} = \mathsf{LinkCommit}_r(\mathsf{qk}, \mathsf{sighash})$$ the hardware wallet could prove knowledge of $(\mathsf{qsk}, r)$ such that -$c = \mathsf{LinkCommit}_r(\mathsf{H^{qk}}(\mathsf{qsk}), \mathsf{sighash}).$ -This circuit is relatively small and it might be feasible to do the proof in -quite constrained hardware. - -The host wallet would be given $\mathsf{nk},$ $\mathsf{ak},$ and $\mathsf{qk}$ -for use in the main Recovery circuit (discussed later). The commitment $c$ would -be a public input opened to $(\mathsf{qk}, \mathsf{sighash})$ in that circuit, -ensuring that the hardware wallet has authorized the spend for the correct key. -Because $\mathsf{LinkCommit}$ is hiding and the proofs are zero knowledge, no -information is leaked about which $\mathsf{qk}$ is being used. - -Alternatively, if the hardware wallet is unable to support making proofs at -all, it could be updated to permit exporting $\mathsf{qsk}$. This is less -secure against a quantum adversary that is able to obtain $\mathsf{qsk}$, but -it allows the funds to be transferred to another key or protocol. A quantum -adversary would have to break RedDSA in order to steal funds even if it were -to obtain $\mathsf{qsk}$, since $\mathsf{ask}$ would remain on the hardware -wallet. +$$\mathsf{c_{link}} = \mathsf{LinkCommit}_r(\mathsf{H^{qk}}(\mathsf{qsk}), \mathsf{sighash}).$$ +This statement, labelled as $\mathsf{SoK^{qsk}}$ in the diagram, can be +implemented in a much smaller circuit, so it might be feasible to do the +proof in quite constrained hardware. + +The commitment $\mathsf{c_{link}}$ would be a public input opened to +$(\mathsf{qk}, \mathsf{sighash})$ in the [Recovery Statement](#proposedrecoverystatement), +ensuring that the hardware wallet has authorized the spend for the correct +key. Because $\mathsf{LinkCommit}$ is hiding and the proofs are zero knowledge, +no information is leaked about which $\mathsf{qk}$ is being used. + +### Key storage options and analysis + +By *host wallet*, we mean the device that builds the spend transaction and +produces the rest of the Recovery Statement proof. In a multi-signer FROST +setup, this would be the Coordinator [^zip-0312-threat-model]. The host wallet +is given $\mathsf{nk},$ $\mathsf{ak},$ and (assuming $\mathsf{use\_qsk}$ is true) +$\mathsf{qk}$, for use in the Recovery Statement. Then two options are possible +for storage of $\mathsf{qsk}$: + +**Option A** — The $\mathsf{SoK^{qsk}}$ proof is produced inside the hardware +wallet, and $\mathsf{qsk}$ is retained there. + +**Option B** — Alternatively, if the hardware wallet is unable to support +proving $\mathsf{SoK^{qsk}}$, it could be updated to permit exporting +$\mathsf{qsk}$ to the host wallet, and the $\mathsf{SoK^{qsk}}$ proof would be +produced there. + +In either option, $\mathsf{ask}$ would remain on the hardware wallet which +would continue to produce RedDSA spend authorization signatures (or perform +its part of the FROST multi-signing protocol). + +#### Threat model + +The [Recovery Statement](#proposedrecoverystatement) is assumed below to +require both of: + +* an $\mathsf{SoK^{qsk}}$ proof verifying knowledge of $\mathsf{qsk}$ + such that $\mathsf{H^{qk}}(\mathsf{qsk}) = \mathsf{qk}$ for the + spent note's $\mathsf{qk}$; and +* a RedDSA signature on $\mathsf{ak}$, which under FROST is + constructed by cooperation of $t$-of-$n$ hardware-wallet signers, + each contributing using its share of $\mathsf{ask}$. + +Under this assumed structure, with FROST + hardware-wallet deployment, +spend authorization is broken only by either: + +1. **$\mathsf{qsk}$ possession + finding discrete logarithms on the + Pallas curve.** The variants differ only in *how* $\mathsf{qsk}$ + is obtained: + + <!-- rendered as a., b., c. --> + 1. the adversary is an authorized FROST signer — they hold a copy + of $\mathsf{qsk}$ by construction; + 2. $\mathsf{qsk}$ is extracted from a hardware wallet, defeating + Option A by a physical-device or side-channel attack; + 3. $\mathsf{qsk}$ is obtained after export to the host wallet, by + compromising the host wallet or intercepting it during export. + +2. **Breaking a primitive or scheme.** RedDSA, FROST, the DKG, or the + proving system has a cryptographic weakness or implementation flaw. + +#### Choosing between Options A and B + +Option A is preferred where the target hardware wallet is capable of +proving $\mathsf{SoK^{qsk}}$ on-device. Option B is a fallback for +cases where it cannot — for instance, due to memory or secure-element +constraints, uncertainty about the proof system that will be chosen +and what will be tractable on small devices, or the device having been +obsoleted before firmware support could be added. + +Under Option A, the host wallet holds only the full viewing key +($\mathsf{ak}$, $\mathsf{nk}$) —which the pre-Quantum-Recoverability +protocol already entrusted to it— plus $\mathsf{qk}$. The $\mathsf{qsk}$ +attack surface is then 1.a. or 1.b. only. + +Option B additionally places $\mathsf{qsk}$ on the host wallet, admitting +case 1.c. as well. This has the disadvantage that host-wallet compromise +is a substantially larger attack surface than hardware-wallet extraction. +However, even with $\mathsf{qsk}$ in hand, an adversary would still need +to break RedDSA or find discrete logarithms on the Pallas curve to steal +funds. + +Note: with ZIP 32 hierarchical derivation, $\mathsf{qsk}$ need not be +backed up separately from the seed phrase. When $\mathsf{use\_qsk}$ is +true, $\mathsf{qsk} = \mathsf{H^{qsk}}(\mathsf{sk})$ where $\mathsf{sk}$ +is the HD-derived spending key, and so $\mathsf{qsk}$ can be re-derived +from the seed phrase (with or without SLIP 39 Shamir backup [^slip-0039]). +A deployment that does not use ZIP 32 is responsible for the security of +its own backup arrangements. + +## Usage with other proposals requiring note plaintext format changes + +This proposal was originally designed to be deployed alongside ZSAs [^zip-0226] +[^zip-0227] and memo bundles [^zip-0231], which also defined a new note +plaintext format. Since this proposal now defines lead byte $\mathtt{0x03}$, +those proposals will need to use a new lead byte value or values. ## 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 May 2026. ### Changes to the Protocol Specification @@ -444,17 +563,52 @@ Replace the paragraph with +> Let the constant $\mathsf{ZIP2005ActivationHeight}$ be as defined in +> [[ZIP 2005, Deployment]](#deployment). +> > Define $\mathsf{allowedLeadBytes^{protocol}}(\mathsf{height}, \mathsf{txVersion}) =$ > $\hspace{2em} \begin{cases} > \{ \mathtt{0x01} \},&\!\!\!\text{if } \mathsf{height} < \mathsf{CanopyActivationHeight} \\ > \{ \mathtt{0x01}, \mathtt{0x02} \},&\!\!\!\text{if } \mathsf{CanopyActivationHeight} \leq \mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod} \\ -> \{ \mathtt{0x02} \},&\!\!\!\text{if } \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod} \leq \mathsf{height} \text{ and } \mathsf{txVersion} < 6 \\ +> \{ \mathtt{0x02} \},&\!\!\!\text{if } \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod} \leq \mathsf{height} \text{ and } \\ +> &\;\; (\mathsf{height} < \mathsf{ZIP2005ActivationHeight} \text{ or } \mathsf{protocol} \neq \mathsf{Orchard}) \\ +> \{ \mathtt{0x02}, \mathtt{0x03} \},&\!\!\!\text{if } \mathsf{ZIP2005ActivationHeight} \leq \mathsf{height} \text{ and } \mathsf{protocol} = \mathsf{Orchard} \text{ and } \mathsf{txVersion} < 6 \\ > \{ \mathtt{0x03} \},&\!\!\!\text{otherwise.} > \end{cases}$ -and delete "or $\mathsf{txVersion}$" from "It is intentional that the -definition of $\mathsf{allowedLeadBytes}$ does not currently depend on -$\mathsf{protocol}$ or $\mathsf{txVersion}$." +Replace + +> Senders SHOULD choose the highest note plaintext lead byte allowed under this +> condition. + +with + +> $\mathsf{ZIP2005ActivationHeight}$ specifies the first block height at which +> recoverable note plaintexts with lead byte $\mathtt{0x03}$ are allowed to +> occur in Orchard outputs. Orchard note plaintexts sent to *wallet-internal* +> addresses SHOULD use lead byte $\mathtt{0x03}$ starting from this height. +> Orchard note plaintexts in v5 transactions sent to *external* addresses +> SHOULD use lead byte $\mathtt{0x02}$ until wallet support for receiving note +> plaintexts with lead byte $\mathtt{0x03}$ is widespread in the Zcash ecosystem. +> +> In other cases, senders of non-dummy note plaintexts SHOULD choose the +> highest note plaintext lead byte allowed according to $\mathsf{allowedLeadBytes}.$ +> For dummy note plaintexts, any of the allowed lead bytes MAY be used (it does +> not matter which). + +Delete the non-normative note: + +> * It is intentional that the definition of $\mathsf{allowedLeadBytes}$ does +> not currently depend on $\mathsf{protocol}$ or $\mathsf{txVersion}.$ It +> might do so in future. + +Add the non-normative note: + +> * For Orchard note plaintexts sent in v6 transactions [^zip-0248], the only +> allowed lead byte value is $\mathtt{0x03}.$ + +It is assumed for these changes that v6 transactions will not activate before +$\mathsf{ZIP2005ActivationHeight}$. #### § 4.1.2 ‘Pseudo Random Functions’ @@ -462,47 +616,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,31 +659,32 @@ 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 -> $\mathsf{ask}$ is derived directly from $\mathsf{sk}$. (In cases where -> it is desired for the generation of key components to match versions of -> this specification prior to {{ fill in version }}, $\mathsf{use\_qsk}$ -> needs to be set to false.) +> Let $\mathsf{use\_qsk} \;{\small ⦂}\; \mathbb{B}$ be a flag indicating +> whether $\mathsf{qsk}$ and $\mathsf{qk}$ are generated and used in the +> derivation of $\mathsf{rivk}$. (In cases where it is desired for the +> generation of key components to match versions of this specification +> prior to {{ fill in version }}, $\mathsf{use\_qsk}$ needs to be set to +> false.) > > Define: > * $\mathsf{H^{ask}}(\mathsf{sk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x06}])\kern-0.1em\big)$ > * $\mathsf{H^{nk}}(\mathsf{sk}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x07}])\kern-0.1em\big)$ > * $\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^{qk}}(\mathsf{qsk}) = \mathsf{BLAKE3.derive\_key}(\texttt{“Zcash ZIP 2005 qk-derivation v1”}, \mathsf{qsk}, 32)$ [^BLAKE3]. +> * $\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 \}$, @@ -552,9 +699,9 @@ in the algorithm with: > > $\hspace{1.0em}$ let $\mathsf{nk} = \mathsf{H^{nk}}(\mathsf{sk})$ <br> > $\hspace{1.0em}$ if $\mathsf{use\_qsk}$: <br> -> $\hspace{2.5em}$ generate $\mathsf{ask} \;{\small ⦂}\; \mathbb{F}^{*}_{r_{\mathbb{P}}}$ and corresponding $\mathsf{SpendAuthSig^{Orchard}}$ public key $\mathsf{ak}^{\mathbb{P}} \;{\small ⦂}\; \mathbb{P}^*$ <br> -> $\hspace{3.5em}$ using any suitably secure method that ensures the last bit of $\mathsf{repr}_{\mathbb{P}}(\mathsf{ak}_{\mathbb{P}})$ is $0$. <br> -> $\hspace{2.5em}$ let $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}_{\mathbb{P}})$ <br> +> $\hspace{2.5em}$ obtain a $\mathsf{SpendAuthSig^{Orchard}}$ public key $\mathsf{ak}^{\mathbb{P}} \;{\small ⦂}\; \mathbb{P}^*$ by any suitably secure <br> +> $\hspace{3.5em}$ method that ensures the last bit of $\mathsf{repr}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$ is $0$ (see below). <br> +> $\hspace{2.5em}$ let $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$ <br> > $\hspace{2.5em}$ let $\mathsf{qsk} = \mathsf{H^{qsk}}(\mathsf{sk})$ <br> > $\hspace{2.5em}$ let $\mathsf{qk} = \mathsf{H^{qk}}(\mathsf{qsk})$ <br> > $\hspace{2.5em}$ let $\mathsf{rivk} = \mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk})$ <br> @@ -568,74 +715,76 @@ in the algorithm with: > $\hspace{2.5em}$ let $\mathsf{qsk} = \mathsf{qk} = \bot$ (there are no quantum spending/intermediate keys in this case) <br> > $\hspace{2.5em}$ let $\mathsf{rivk} = \mathsf{H^{rivk}}(\mathsf{sk})$ +Add before "As explained in § 3.1": + +> When $\mathsf{use\_qsk}$ is true, possible methods of generating +> $\mathsf{ak}^{\mathbb{P}}$ include direct generation of an Orchard Spend +> authorizing key $\mathsf{ask} \;{\small ⦂}\; \mathbb{F}^{*}_{r_{\mathbb{P}}}$ followed by +> $\mathsf{ak}^{\mathbb{P}} = \mathsf{SpendAuthSig^{Orchard}.DerivePublic}(\mathsf{ask})$, +> or FROST distributed key generation [^zip-0312-key-generation] in which the +> corresponding spend-authorization material is $t$-of-$n$ shared among the +> participants. + 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}$. +> $\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 +> [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 $\mathsf{sk}$, and also to know whether $\mathsf{use\_qsk}$ +> was used to derive the $\mathsf{ivk}$ and addresses. When FROST is being +> used, it is also necessary to retain the group verifying key $\mathsf{ak}$ +> and (collectively among the signers) the key material needed to make +> spend authorization signatures that can be verified using $\mathsf{ak}$. > -> 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}$. +> See [[ZIP 2005, Key storage options and analysis]](#keystorageoptionsandanalysis) +> for further discussion of storage requirements for $\mathsf{sk}$ and +> $\mathsf{qsk}$. #### § 4.7.2 ‘Sending Notes (Sapling)’ Add after the definition of $\mathsf{leadByte}$: -> Define $\mathsf{H^{rcm,Sapling}_{rseed}}(\_, \_) = \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}])\kern-0.1em\big)$ +> Define $\mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}) = \begin{cases} +> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\ +> \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}])\kern-0.1em\big),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x02} +> \end{cases}$ > -> Define $\mathsf{H^{esk,Sapling}_{rseed}}(\_, \_) = \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}])\kern-0.1em\big)$. +> Define $\mathsf{H^{esk,Sapling}_{rseed}}(\_) = \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}])\kern-0.1em\big)$. > -> ($\mathsf{H^{rcm,Sapling}}$ and $\mathsf{H^{esk,Sapling}}$ intentionally -> take arguments that are unused.) +> ($\mathsf{H^{esk,Sapling}}$ intentionally takes an argument that is unused.) Replace the lines deriving $\mathsf{rcm}$ and $\mathsf{esk}$ with -> Derive $\mathsf{rcm} = \mathsf{H^{rcm,Sapling}_{rseed}}(\bot, \bot)$ +> Derive $\mathsf{rcm} = \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte})$ > -> Derive $\mathsf{esk} = \mathsf{H^{esk,Sapling}_{rseed}}(\bot, \bot)$ +> Derive $\mathsf{esk} = \mathsf{H^{esk,Sapling}_{rseed}}(\bot)$ #### § 4.7.3 ‘Sending Notes (Orchard)’ -Add after the definition of $\mathsf{leadByte}$: +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.08em\star])\kern-0.1em\big) =$ +> Define $\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) =$ > $\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} +> where $\mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ})$. +> +> Define $\mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) = \begin{cases} +> \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}] \,||\, \underline{\text{ρ}})\kern-0.1em\big),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x02} \\ +> \mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\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{.} -> \end{cases}$ +> Define $\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x09}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$. + +The first-byte domain separator $\mathtt{0x0A}$ for $\mathsf{PRF^{expand}}$ is reserved by this ZIP for use by split notes in ZIP 226 [^zip-0226-split-notes]. 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})]$. +> and $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$. and use these in the inputs to $\mathsf{NoteCommit^{Orchard}}$. @@ -644,54 +793,56 @@ 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{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ})$ -> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, \mathsf{split\_flag})$ +> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ #### § 4.8.2 ‘Dummy Notes (Sapling)’ Add -> Let $\mathsf{H^{rcm,Sapling}}$ be as defined in -> § 4.7.2 ‘Sending Notes (Sapling)’. +> Let $\mathsf{Derive\_rcm^{Sapling}}$ be as defined in +> § 4.7.2 ‘Sending Notes (Sapling)’. Replace the line deriving $\mathsf{rcm}$ with -> Derive $\mathsf{rcm} = \mathsf{H^{rcm,Sapling}_{rseed}}(\bot, \bot)$ +> Derive $\mathsf{rcm} = \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte})$ #### § 4.8.3 ‘Dummy Notes (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)’. +> Let $\mathsf{Derive\_rcm^{Orchard}}$ and $\mathsf{H^{\text{ψ},Orchard}}$ be +> 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})]$. +> and $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$. > -> 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{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ})$ > -> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, 0)$ +> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ and use $\mathsf{g}\star_{\mathsf{d}}$, $\mathsf{pk}\star_{\mathsf{d}}$, -and $\mathsf{AssetBase}\kern0.08em\star$ in the inputs to -$\mathsf{NoteCommit^{Orchard}}$. +in the inputs to $\mathsf{NoteCommit^{Orchard}}$. + +Per § 3.2.1, use $\mathsf{leadByte} = \mathtt{0x03}$ starting from +$\mathsf{ZIP2005ActivationHeight}$. The choice is operationally irrelevant +for dummy notes, since their plaintexts cannot be decrypted. #### § 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: +For both § 4.20.2 and § 4.20.3, add before the decryption procedure: -> Let $\mathsf{H^{rcm,Sapling}}$ and $\mathsf{H^{\text{esk},Sapling}}$ -> be as defined in § 4.7.2 ‘Sending Notes (Sapling)’. +> Let $\mathsf{Derive\_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{Derive\_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 +855,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]$ <br> > $\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 +864,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}$ <br> > $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$ <br> > $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$ <br> > $\hspace{1.0em}$ [**Canopy** onward] if $\mathsf{leadByte} \neq \mathtt{0x01}$: <br> -> $\hspace{2.5em}$ $\mathsf{esk} = \mathsf{ToScalar^{protocol}}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_esk}))$ <br> -> $\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)$ <br> +> $\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 +883,28 @@ with > $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$ <br> > $\hspace{1.0em}$ [**Canopy** onward] if $\mathsf{leadByte} \neq \mathtt{0x01}$: <br> > $\hspace{2.5em}$ let $\mathsf{esk} = \mathsf{H^{esk,protocol}_{rseed}}(\underline{\text{ρ}})$ <br> -> $\hspace{2.5em}$ if $\mathsf{repr}_{\mathbb{G}}(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})) \neq \mathtt{ephemeralKey}$, return $\bot$ <br> +> $\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$ <br> > > $\hspace{1.0em}$ let $\mathsf{pk_d} = \mathsf{KA.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})$ <br> -> $\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})]$ <br> -> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, 0)$ for Orchard or $\bot$ for Sapling <br> +> $\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})$ <br> +> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ for Orchard or $\bot$ for Sapling <br> > $\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{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Sapling} \\ +> \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Orchard} > \end{cases}$ <br> > $\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 -define $\mathsf{H^{rcm,protocol}}$. +The definitions of $\mathsf{pre\_rcm}$ and $\mathsf{pre\_esk}$ are moved or inlined +into § 4.7.2 ‘Sending Notes (Sapling)’ and § 4.7.3 ‘Sending Notes (Orchard)’ which +define $\mathsf{Derive\_rcm^{\{Sapling,Orchard\}}}$ and $\mathsf{H^{esk,\{Sapling,Orchard\}}}$. -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}$ <br> > $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$ <br> > $\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 +912,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$ <br> -> $\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})]$ <br> -> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}, 0)$ for Orchard or $\bot$ for Sapling <br> +> $\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})$ <br> +> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ for Orchard or $\bot$ for Sapling <br> > $\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{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Sapling} \\ +> \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Orchard} > \end{cases}$ <br> > $\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 +939,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 +> 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,28 +953,7 @@ Add a note before the Abstract: <div class="note"></div> This ZIP reflects the changes made to note encryption for the Canopy upgrade. -It does not include subsequent changes in {{ reference to this ZIP }}. - -#### 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)’ -> are invoked directly or indirectly in the computation of $\text{ρ}$ and -> $\text{ψ}$ for an OrchardZSA note, $\mathsf{leadByte}$ MUST be set to -> $\mathtt{0x03}$. - -In section [Split Notes](https://zips.z.cash/zip-0226#split-notes), change: - -> where $\text{ψ}^{\mathsf{nf}}$ is sampled uniformly at random on -> $\mathbb{F}_{q_{\mathbb{P}}}$, ... - -to - -> where $\text{ψ}^{\mathsf{nf}}$ is computed as -> $\mathsf{H^{\text{ψ},Orchard}_{rseed\_nf}}(\underline{\text{ρ}}, 1) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed\_nf}}([\mathtt{0x0A}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$ -> for $\mathsf{rseed\_nf}$ sampled uniformly at random on $\mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[32]}$, ... - +It does not include subsequent changes in [ZIP 2005]. # Rationale @@ -847,39 +977,33 @@ changes to be adopted now are likely to be sufficient to securely support a Recovery Protocol. 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. +derivations given in the [Flow diagram for the Orchard protocol], and we +suggest having that diagram open in another window to refer to it. + +### Proposed Recovery Statement + +Import this definition from § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents]: -Import this definition from § 4.7.3 ‘Sending Notes (Orchard)’: +> 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)$. -> 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}$. +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}}\big(\mathsf{PRF^{expand}_{rivk\_ext}}\big([\mathtt{0x83}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$ + +Import these definitions from § 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]: + +> Define $\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) =$ +> $\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)$ > -> 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)$ +> where $\mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ})$. > -> 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}\text{.} \\ -> \end{cases}$ +> Define $\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x09}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$. -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{ρ}}))$ <br> - 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: +A valid instance of a Recovery Statement assures that given a primary input: $\begin{array}{rl} \hspace{4.1em} ( \mathsf{rt^{Orchard}} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,q_{\mathbb{P}}-1 \}, \\ @@ -891,18 +1015,16 @@ $\begin{array}{rl} the prover knows an auxiliary input: $\begin{array}{rl} - \hspace{4em} ( \mathsf{use\_qsk} \!\!\!\!&{\small ⦂}\; \mathbb{B}, \\ - \mathsf{is\_internal\_rivk} \!\!\!\!&{\small ⦂}\; \mathbb{B}, \\ - \mathsf{path} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,q_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{Orchard}}]}, \\ + \hspace{4em} ( \mathsf{path} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,q_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{Orchard}}]}, \\ \mathsf{pos} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,2^{\mathsf{MerkleDepth^{Orchard}}}-1 \}, \\ K \!\!\!\!&{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{sk}}]}, \\ \mathsf{\alpha} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ \mathsf{ak}^{\mathbb{P}} \!\!\!\!&{\small ⦂}\; \mathbb{P}^*, \\ \mathsf{nk} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}}, \\ - \mathsf{qk} \!\!\!\!&{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qk}}/8]}, \\ - \sigma_{\mathsf{qsk}} \!\!\!\!&{\small ⦂}\; \mathsf{SoK^{qsk}}\big((\mathsf{qk}), \mathsf{SigHash}\big), \\ + \mathsf{rivk\_ext} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ \mathsf{rivk} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ - \sigma_{\mathsf{sk}} \!\!\!\!&{\small ⦂}\; \mathsf{SoK^{sk}}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}\big), \\ + (\mathsf{qk}, \sigma_{\mathsf{qsk}}) \!\!\!\!&{\small ⦂}\; \big(\mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qk}}/8]} \times \mathsf{SoK^{qsk}}\big((\mathsf{qk}), \mathsf{SigHash}\big)\big) \cup \{(\bot, \bot)\}, \\ + \sigma_{\mathsf{sk}} \!\!\!\!&{\small ⦂}\; \mathsf{SoK^{sk}}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}\big) \cup \{\bot\}, \\ \mathsf{rseed} \!\!\!\!&{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[32]}, \\ \mathsf{g_d} \!\!\!\!&{\small ⦂}\; \mathbb{P}^*, \\ \mathsf{v} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,2^{\ell_{\mathsf{value}}}-1 \}, \\ @@ -912,75 +1034,83 @@ $\begin{array}{rl} where $\begin{array}{rll} - \hspace{1em}\mathsf{SoK^{qsk}.Statement} \!\!\!\!&=\, \big\{\,\mathsf{qsk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qsk}}/8]} &\!\!\!\!|\;\, \mathsf{qk} = \mathsf{H^{qk}}(\mathsf{qsk})\,\big\} \\ - \hspace{1em}\mathsf{SoK^{sk}.Statement} \!\!\!\!&=\, \big\{\,\mathsf{sk} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{sk}}]} &\!\!\!\!|\;\, \mathsf{ak}^{\mathbb{P}} = [\mathsf{H^{ask}}(\mathsf{sk})]\, \mathcal{G}^{\mathsf{Orchard}} \\ - && \;\wedge\; \mathsf{nk} = \mathsf{H^{nk}} \\ - && \;\wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk})\,\big\} + \hspace{1em}\mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) = + \big(&\!\!\!\! \mathsf{ak}^{\mathbb{P}} = [\mathsf{H^{ask}}(\mathsf{sk})]\, \mathcal{G}^{\mathsf{Orchard}} \\ + &\!\!\!\! \wedge\; \mathsf{nk} = \mathsf{H^{nk}}(\mathsf{sk}) \\ + &\!\!\!\! \wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk}) \,\big) +\end{array}$ + +and + +$\begin{array}{rll} + \hspace{1em}\mathsf{SoK^{qsk}.Statement} \!\!\!&=\, \big\{\,\mathsf{qsk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qsk}}/8]} &\!\!\!\!|\;\, \mathsf{qk} = \mathsf{H^{qk}}(\mathsf{qsk}) \,\big\} \\ + \hspace{1em}\mathsf{SoK^{sk}.Statement} \!\!\!&=\, \big\{\,\mathsf{sk} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{sk}}]} &\!\!\!\!|\;\, \mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) \,\big\} \end{array}$ 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) \\ -\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 \\ -\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk})&\text{if } \mathsf{is\_rivk\_internal} = 1 \end{cases} \\ -\wedge\; \mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}) \\ -\wedge\; \text{let } \mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) \\ -\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{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 \\ -\wedge\; \text{let } \mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}(\mathsf{cm}) \\ -\wedge\; \text{let } \mathsf{leaf} = \mathsf{MerkleCRH}(\mathsf{cm}_x, \text{ρ}) \\ -\wedge\; \mathsf{path} \text{ is a path to } \mathsf{leaf} \text{ in the rehashed commitment tree} \\ -\wedge\; \mathsf{nf} = \mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) \\ +\{\;\, \mathsf{rk} = \mathsf{SpendAuthSig^{Orchard}.RandomizePublic}(\alpha, \mathsf{ak}^{\mathbb{P}}) \vphantom{\big(}\\ +\wedge\; \mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}) \vphantom{\Big(}\\ +\wedge\; \big((\mathsf{qk}, \sigma_{\mathsf{qsk}}) = (\bot, \bot)\big) \neq \big(\sigma_{\mathsf{sk}} = \bot\big) \vphantom{\big(}\\ +\wedge\; (\mathsf{qk}, \sigma_{\mathsf{qsk}}) \neq (\bot, \bot) \Rightarrow \big(\, \mathsf{SoK^{qsk}.Validate}\big((\mathsf{qk}), \mathsf{SigHash}, \sigma_{\mathsf{qsk}}\big) \kern0.05em\wedge\, \mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})\kern0.05em\big) \vphantom{\Big(}\\ +\wedge\; \sigma_{\mathsf{sk}} \neq \bot \Rightarrow \mathsf{SoK^{sk}.Validate}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}, \sigma_{\mathsf{sk}}\big) \vphantom{\big(}\\ +\wedge\; \mathsf{rivk} \in \big\{\, \mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \,\big\} \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) \vphantom{\big(}\\ +\wedge\; \mathsf{ivk} \not\in \{0, \bot\} \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{pk_d} = [\mathsf{ivk}]\, \mathsf{g_d} \vphantom{\big(}\\ +\wedge\; \text{let } \text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{noterepr} = \big(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \underline{\text{ρ}}, \text{ψ}\big) \vphantom{\big(}\\ +\wedge\; \text{let } \mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathtt{0x03}, \mathsf{noterepr}\big) \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{cm} = \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{noterepr}) \vphantom{\big(}\\ +\wedge\; \mathsf{cm} \neq \bot \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}(\mathsf{cm}) \vphantom{\big(}\\ +\wedge\; \text{let } \mathsf{leaf} = \mathsf{MerkleCRH}(\mathsf{cm}_x, \text{ρ}) \vphantom{\Big(}\\ +\wedge\; \mathsf{path} \text{ is a path to } \mathsf{leaf} \text{ in the rehashed commitment tree} \vphantom{\big(}\\ +\wedge\; \mathsf{nf} = \mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) \vphantom{\Big(}\\ \} \end{array}$ and $\mathsf{nf}$ is the revealed nullifier. -TODO: finish extending this to ZSAs. We need to add $\text{ψ}^{\mathsf{nf}}$, -and enforce $\mathsf{rseed\_nf} = \mathsf{rseed\_old}$ only if this is a -non-split note. - (We don't need to check the derivation of $\mathsf{g_d}$ from $\mathsf{d}$.) ### Cost -Note that in the "$\mathsf{use\_qsk}$" case, two BLAKE2b compressions -are required to compute $\mathsf{rivk\_ext}$, and in the -"not $\mathsf{use\_qsk}$" cases, three BLAKE2b compressions in total -are required to compute $\mathsf{H^{ask}}$, $\mathsf{H^{nk}}$, and -$\mathsf{H^{rivk\_legacy}}$. Since these cases are mutually exclusive, -it is possible to multiplex the same three compression function instances. -So, supporting "$\mathsf{use\_qsk}$" in addition to -"not $\mathsf{use\_qsk}$" costs very little extra. +Note that in the "$\mathsf{use\_qsk}$" case, one BLAKE2b compression is required +to compute $\mathsf{rivk\_ext}$ (provided $\ell_{\mathsf{qk}} \leq 504$ bits, so +that the input $\mathsf{qk} \,||\, [\mathtt{0x0D}] \,||\, \mathsf{ak} \,||\, \mathsf{nk}$ +fits in a single 128-byte BLAKE2b block), and in the "not $\mathsf{use\_qsk}$" +case, three BLAKE2b compressions in total are required to compute $\mathsf{H^{ask}}$, +$\mathsf{H^{nk}}$, and $\mathsf{H^{rivk\_legacy}}$. Since these cases are mutually +exclusive, it is possible to multiplex the same three compression function instances. +So, supporting "$\mathsf{use\_qsk}$" in addition to "not $\mathsf{use\_qsk}$" costs +very little extra. All of the operations below need to be implemented with complete additions, -even if they are incomplete in the current Orchard[ZSA] circuit. - -* 9 BLAKE2b-512 compressions: - * 3 to compute $\mathsf{rivk\_ext}$ - * 2 to compute $\mathsf{H^{rivk\_int}}$ - * 2 to compute $\mathsf{H^{\text{ψ}}}$ - * 2 to compute $\mathsf{H^{rcm}}$ - * we could potentially save these two by using Poseidon to implement $\mathsf{H^{rcm}}$, but it seems not worth it. -* 1 use of $\mathsf{H^{qk}}$ +even if they are incomplete in the current Orchard[ZSA] statement/circuit. + +In $\mathsf{SoK^{sk}}$ and the main circuit: +* 7 BLAKE2b-512 compressions: + * 3 multiplexed between $\mathsf{H^{rivk\_ext}}$ when $\mathsf{use\_qsk}$ is true (1 compression), + and $\mathsf{H^{ask}}$ + $\mathsf{H^{nk}}$ + $\mathsf{H^{rivk\_legacy}}$ when $\mathsf{use\_qsk}$ is false (3 compressions) + * 1 to compute $\mathsf{H^{rivk\_int}}$ + * 1 to compute $\mathsf{H^{\text{ψ}}}$ + * 2 to compute $\mathsf{H^{rcm}}$ * 1 use of $\mathsf{Commit^{ivk}}$ ($\mathsf{SinsemillaShortCommit}$) -* 1 use of $\mathsf{NoteCommit^{Orchard}}$ ($\mathsf{SinsemillaCommit}$) +* 1 use of $\mathsf{NoteCommit}$ ($\mathsf{SinsemillaCommit}$) * 1 full-width fixed-base Pallas scalar multiplication, $[\mathsf{ask}]\, \mathcal{G}^{\mathsf{Orchard}}$ * 1 full-width variable-base Pallas scalar multiplication, $[\mathsf{ivk}]\, \mathsf{g_d}$ * 1 Merkle tree path check * 1 additional use of $\mathsf{MerkleCRH}$ to compute $\mathsf{leaf}$. -The expensive parts of this are the 9 BLAKE2b compressions. +In $\mathsf{SoK^{qsk}}$: +* 1 BLAKE3 compression for $\mathsf{H^{qk}}$ (with the $\mathsf{derive\_key}$ context key precomputed as a constant) + +plus, potentially, [linking commitments](#linking-commitments) between +the circuits. + +The expensive parts of this are the 7 BLAKE2b compressions. ## Security analysis @@ -993,9 +1123,9 @@ post-quantum knowledge-sound. ### Repairing the note commitment Merkle tree -$\mathsf{MerkleCRH^{Orchard}}$ is instantiated using +$\mathsf{MerkleCRH}$ is instantiated using $\mathsf{SinsimillaHash}$ [^protocol-concretesinsemillahash]. -Its collision resistance depends on the discrete log relation problem +Its collision resistance depends on the Discrete Logarithm Relation Problem on the Pallas curve [^protocol-sinsemillasecurity], and so it is not post-quantum collision-resistant or collapsing. However, because the note commitment tree is public, it is possible to re-hash all of its leaves to @@ -1004,63 +1134,71 @@ Suppose this has been done. > The post-quantum security of Merkle trees —considered as position-binding > vector commitments which is the property required by Zcash [^zcash-security]— -> is proven under reasonable assumptions in [^CMSZ2021] and [^CDDGS2025]. +> is proven under reasonable assumptions in [^CMSZ2021], [^GM2022], and +> [^CDDGS2025]. Note: when we rehash the commitment tree, we could include both $\text{ρ}$ and $\mathsf{cm}_x$ for each note (i.e. what is currently the leaf layer becomes $\mathsf{MerkleCRH}(\text{ρ}, \mathsf{cm}_x)$ where $\mathsf{MerkleCRH}$ -is pq-collision-resistant). This change might not be necessary; it just -removes potential complications due to duplicate commitments for the same -note. +is collapsing). This change might not be necessary; it just removes potential +complications due to duplicate commitments for the same note. ### Attacks against binding of note commitments -We still face the problem that $\mathsf{NoteCommit^{Orchard}}$ is not -binding against a discrete-log-breaking adversary: given the discrete log -relations between bases, we can easily write a linear equation in the -scalar field with multiple solutions of the inputs for a given commitment. +We still face the problem that $\mathsf{NoteCommit}$ is not +binding against a discrete-log-breaking adversary: given the discrete +logarithm relations between bases, we can easily write a linear equation +in the scalar field with multiple solutions of the inputs for a given +commitment. This allows an adversary to find two distinct notes corresponding to -openings of $\mathsf{NoteCommit^{Orchard}}$ on the same commitment. +openings of $\mathsf{NoteCommit}$ on the same commitment. They create one note as an output and spend the other note — which may have a greater value, or a value in a different ZSA asset, breaking the Balance property. ### Repairing note commitments -We prefer to fix this without changing $\mathsf{NoteCommit^{Orchard}}$ itself. +We prefer to fix this without changing $\mathsf{NoteCommit}$ 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{ψ})$, as detailed in the [Specification] section. Specifically, when $\mathsf{leadByte} = \mathtt{0x03}$ we have: -$\mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr}) = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm}))$ +$\hspace{2em}\mathsf{rcm} = \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) = \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm}))$ -$\text{where } \mathsf{pre\_rcm} = [\mathtt{0x0B}, \mathsf{leadByte}] \,||\, \mathsf{encode}(\mathsf{noterepr})$ +$\text{where } \mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{encode}(\mathsf{noterepr})$ -Then we view the output of -$\mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{noterepr})$ +### Informal security argument for binding of note commitments + +For the formal versions of these arguments and their adaptation to the +post-quantum setting, see the [key-binding](#thm-key-binding-rom) and +[Spendability](#thm-spendability-collide) theorems below, and +[§ Adaptation to the quantum setting](#adaptationtothequantumsetting). + +We can view the output of $\mathsf{NoteCommit_{rcm}}$ for +$\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$ as the point addition of a randomization term -$[\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr})]\, \mathcal{R}$, -and some other function of $\mathsf{rseed}$, $\mathsf{leadByte}$, and -$\mathsf{noterepr}$. +$[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr})]\, \mathcal{R}$, +and some other function of $\mathsf{notetuple}$. Without loss of generality, we can write that function as -$[f(\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr})]\, \mathcal{R}$, +$[\mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}$, by expanding each of the Sinemilla bases $\mathcal{C}_j = \mathcal{Q}(D) \text{ or } \mathcal{S}(j)$ used by [$\mathsf{HashToSinsimillaPoint}$](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillahash) as $\mathcal{C}_j = [c_j]\, \mathcal{R}$ for some $c_j$. That is, -$$\mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{noterepr}) = [\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr}) + f(\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr})]\, \mathcal{R}.$$ +the note commitment for $\mathsf{notetuple}$ is +$$[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}.$$ -First we informally argue security in the classical ROM. We will model -$\mathsf{H^{rcm}}$ as a random oracle independent of $f$ with uniform -output on $\mathbb{F}_{r_{\mathbb{P}}}$. This is reasonable because +We will model $\mathsf{H^{rcm}}$ as a random oracle independent of $\mathsf{f}$ with +uniform output on $\mathbb{F}_{r_{\mathbb{P}}}.$ This is reasonable because $\mathsf{H^{rcm}}$ cannot depend on any of the $c_j$, and in any case it is -likely to be a conventional hash function not related to the Pallas curve. +instantiated using BLAKE2b, a conventional hash function not related to the +Pallas curve. -> The fact that $\mathsf{NoteCommit^{Orchard}}$ has -> $\text{ψ} = \mathsf{H}^{\text{ψ}}(\mathsf{rseed}, \text{ρ})$ as an +> The fact that $\mathsf{NoteCommit}$ has +> $\text{ψ} = \mathsf{H}^{\text{ψ}}_{\mathsf{rseed}}(\text{ρ})$ as an > input does not affect the analysis provided that $\mathsf{H^{rcm}}$ and > $\mathsf{H}^{\text{ψ}}$ can be treated as independent. In practice both > are defined in terms of $\mathsf{PRF^{expand}}$, but with strict domain @@ -1068,115 +1206,42 @@ likely to be a conventional hash function not related to the Pallas curve. > as BLAKE2b-512 can be modelled as a random oracle. Note that since the > input to $\mathsf{H^{rcm}}$ needs more than one BLAKE2b input block, we > require that a HAIFA sponge can be modelled as a random oracle which is -> justified by [^ACMT2025]. +> justified by [^ACMT2025]. It is possible that there could be +> better-than-generic quantum attacks against BLAKE2b-512, but none have +> been published to our knowledge. In practice, we consider it reasonable to +> assume that BLAKE2b-512 has the properties needed for $\mathsf{H^{rcm}}$ +> to be collapsing. Taking the 512-bit BLAKE2b output modulo +> $r_{\mathbb{P}} \approx 2^{254}$ cannot introduce a problem. For each $\mathsf{H^{rcm}}$ oracle query the adversary chooses -$\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr}$ +$\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$ and obtains a "random" -$\mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr})$, -such that the distribution of -$\mathsf{rcm} + [f(\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr})]\, \mathcal{R}$ -is computationally indistinguishable from the uniform distribution on -$\mathbb{F}_{r_\mathbb{P}}$. -Therefore $\mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}([\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr}) + f(\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr})]\, \mathcal{R})$ -is computationally indistinguishable from an output of -$\mathsf{Extract}_{\mathbb{P}}$ applied to uniformly distributed -Pallas curve points. The number of such outputs is -$(\mathbb{F}_{r_\mathbb{P}} + 1)/2$ (one for each possible -$x$-coordinate of Pallas curve points, plus one for the zero point -$\mathcal{O}_{\mathbb{P}}$ which is mapped to $0$). +$\mathsf{rcm} = \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr})$. + +We have $\mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}([\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R})$. + +Over all Pallas curve points $P$, the number of outputs of +$\mathsf{Extract}_{\mathbb{P}}(P)$ is $(\mathbb{F}_{r_\mathbb{P}} + 1)/2 \approx 2^{253}$ — +one for each possible $x$-coordinate of Pallas curve points, plus one for the +zero point $\mathcal{O}_{\mathbb{P}}$ which is mapped to $0$. > Only one point maps to $0$, as opposed to two points mapping to every > other possible output of $\mathsf{Extract}_{\mathbb{P}}$, but that has > negligible effect. -The number of queries needed to find a collision therefore follows a -distribution negligibly far from that expected for a collision attack on -an ideal hash function mapping from the input domain to a set of size -$(\mathbb{F}_{r_\mathbb{P}} + 1)/2 \approx 2^{253}$. - -In order to adapt this argument to the quantum setting, we need to consider -*collapsing* hash functions as defined in [^Unruh2015] [^Unruh2016]. - -TODO: $\mathsf{Extract}_{\mathbb{P}}$ is not collapsing. -Is $\mathsf{Extract}_{\mathbb{P}}([\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr}) + f(\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr})]\, \mathcal{R})$ collapsing? - -By the argument in [^Bernstein2009], the best known *generic* quantum -attack on a hash function is simply the classical attack of [^vOW1999]. -(In particular, the Brassard–Høyer–Tapp algorithm [^BHT1997] is entirely -unimplementable for a 253-bit output size: to achieve the claimed speed-up, -it would require running Grover's algorithm with a quantum circuit that -does random accesses to a $2^{92.3}$-bit quantum memory.) Therefore, an -output size of 253 bits does not exclude a hash function from being -post-quantum collision-resistant. It is possible that there could be -better-than-generic quantum attacks against BLAKE2b, but none have been -published to our knowledge. In practice, we consider it reasonable to -assume that BLAKE2b-512 has the properties needed for $\mathsf{H^{rcm}}$ -to be post-quantum collision-resistant. - -TODO: discuss [^CBHSU2017] (sponge security), [^Unruh2015] [^Unruh2016] -(collapse-binding property). - -The above security argument means that provided we also check the uses of -$\mathsf{H^{rcm}}$ and $\mathsf{H}^{\text{ψ}}$ in the post-quantum recovery -circuit, Orchard note commitments can be considered binding on all of the -note fields. - -Note that the argument associated with -[Theorem 5.4.4](https://zips.z.cash/protocol/protocol.pdf#thmsinsemillaex) -in the protocol specification ("A $\bot$ output from -$\mathsf{SinsemillaHashToPoint}$ yields a nontrivial discrete log relation." -and "Since by assumption it is hard to find a nontrivial discrete logarithm -relation, we can argue that it is safe to use incomplete additions when -computing Sinsemilla inside a circuit.") is not applicable when it is -necessary to defend against a discrete-log-breaking or quantum adversary. -Therefore, the post-quantum recovery circuit will need to use complete -curve additions to implement Sinsemilla. - -### Attacks against binding of ivk - -The security of Orchard against double-spending also depends on the binding -property of $\mathsf{Commit^{ivk}}$. Informally, the security argument is -that there is only one value of $\mathsf{ivk}$ corresponding to a given -$(\mathsf{g_d}, \mathsf{pk_d})$ (which are committed to by the note -commitment), and so this binds $\mathsf{nk}$ and $\mathsf{ak}$ to the -correct values for the committed note. - -If the binding property of $\mathsf{Commit^{ivk}}$ fails, then so do -the security arguments for the Balance and Spend Authorization properties, -because we can no longer infer that $\mathsf{nk}$ and $\mathsf{ak}$ are the -correct values. - -Fortunately, the Orchard protocol specified $\mathsf{rivk}$ to be -derived from $\mathsf{sk}$. - -(There is a complication in that $\mathsf{rivk}$ is derived differently -for an "internal IVK".) - -We use essentially the same fix as for $\mathsf{NoteCommit^{Orchard}}$, -with $\mathsf{rivk}$ in place of $\mathsf{rcm}$. - -There is a complication: contrary to the situation with note commitments, -addresses may be used over the long term and it may not be feasible or -desirable to switch to new addresses. - -## Informal Security Argument - -The argument is that if $\mathsf{H^{rcm}}$ and $\mathsf{H^{\text{φ}}}$ are -random oracles, $\mathsf{rcm}$ is an unpredictable function of the note fields. -There are two values of $\mathsf{cm}$ that match $\mathsf{cm}_x$ in their -$x$-coordinate. Because the output of $\mathsf{NoteCommit^{Orchard}}$ is of -the form $\mathsf{cm} = F(\mathsf{note}) + [\mathsf{rcm}]\, \mathcal{R}$, -for any given note we have exactly two values of $\mathsf{rcm}$ that will -pass the commitment check. +There are two values of $\mathsf{cm}$ that match $\mathsf{cm}_x$ in their $x$-coordinate. +Because the output of $\mathsf{NoteCommit_{rcm}}$ for $\mathsf{notetuple}$ is +of the form $\mathsf{cm} = [\mathsf{f}(\mathsf{notetuple}) + \mathsf{rcm}]\, \mathcal{R}$, +for any given note we have exactly two values of $\mathsf{rcm}$ that will pass +the commitment check. Suppose there are $N$ legitimate notes in the tree. The adversary is trying -to find (possibly using a Grover search) a note that will pass the commitment -check without actually being a note in the tree. The success probability for -each attempt in a classical search is $2N/r_{\mathbb{P}}$ where $r_{\mathbb{P}}$ -is the order of the Pallas curve, and that is negligible because -$N \leq 2^{32} \ll r_{\mathbb{P}}$. This is also infeasible for a quantum -adversary using a Grover search. +to find a note that will pass the commitment check without actually being a +note in the tree. As argued above, the distribution of $\mathsf{rcm}$ is +indistinguishable from uniform-random on $\mathbb{F}_{r_\mathbb{P}}$. The +success probability for each attempt in a classical search is therefore +$2N/r_{\mathbb{P}}$ where $r_{\mathbb{P}}$ is the order of the Pallas curve, +and that is negligible because $N \leq 2^{32} \ll r_{\mathbb{P}}$. We're not finished yet because we also have to prove that the nullifier is computed deterministically for a given note. @@ -1191,176 +1256,793 @@ $\mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ivk}$. Unfortunately that's not true; $\mathsf{Commit^{ivk}}$ is instantiated by $\mathsf{SinsemillaShortCommit}$ which is not post-quantum binding. -There are two cases depending on $\mathsf{use\_qsk}$ (the adversary can -choose to attack either): +There are two cases depending on which witness branch the adversary +uses (they can choose to attack either, or both simultaneously): -* Case $\mathsf{use\_qsk} = 0$: The spender must prove knowledge of +* Case $\mathsf{sk} \neq \bot$: The spender must prove knowledge of $\mathsf{sk}$, and that $\mathsf{ak}$, $\mathsf{nk}$, and $\mathsf{rivk}$ are derived correctly from $\mathsf{sk}$. This works because the - derivations use post-quantum hashes (and $\mathsf{ask} \rightarrow \mathsf{ak}$ - is deterministic). <br> + derivations use post-quantum hashes (and $\mathsf{ask} \mapsto \mathsf{ak}$ + is deterministic). <br> In particular, $\mathsf{ivk}$ is an essentially random function of $\mathsf{sk}$, and so we expect that an adversary has no better attack - than to search for values of $\mathsf{sk}$ (possibly using a Grover search) + than to search for values of $\mathsf{sk}$ 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$. + $T \ll r_{\mathbb{P}}$. -* Case $\mathsf{use\_qsk} = 0$: This case is almost the same except that +* Case $\mathsf{qk} \neq \bot$: 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$. + in terms of $T$ is also the same as for the $\mathsf{sk} \neq \bot$ + case. + +The above security argument means that provided we also check the uses of +$\mathsf{H^{rcm}}$ and $\mathsf{H}^{\text{ψ}}$ in the post-quantum +[Recovery Statement](#proposedrecoverystatement), Orchard note commitments +can be considered binding on the note tuple +$(\mathsf{rseed}, \mathsf{noterepr})$. + +Note that the argument associated with +[Theorem 5.4.4](https://zips.z.cash/protocol/protocol.pdf#thmsinsemillaex) +in the protocol specification ("$\mathsf{SinsemillaHashToPoint}(\ldots) = \bot$ +yields a nontrivial discrete logarithm relation." and +"Since by assumption it is hard to find a nontrivial discrete logarithm +relation, we can argue that it is safe to use incomplete additions when +computing Sinsemilla inside a circuit.") is not applicable when it is +necessary to defend against a discrete-log-breaking or quantum adversary. +Therefore, the post-quantum [Recovery Statement](#proposedrecoverystatement) +will need to use complete curve additions to implement Sinsemilla. + +### Security argument for key binding + +The security of Orchard against several attacks depends on cryptographic +keys being bound to a recoverable note's $\mathsf{ivk}$. Different +Orchard properties need different components of the key witness pinned: + +* **Nullifier-binding** (used by the Balance argument and by the + [Spendability argument](#securityargumentforspendability) below + — the latter via the + [$\mathsf{PRF^{nf}}$-pinning lemma](#lemma-prf-nf-pinning)): + $\mathsf{nk}$ uniquely determined by $\mathsf{ivk}$. +* **Spend Authorization**: $\mathsf{ak}$ (up to $y$-sign of + $\mathsf{ak}^{\mathbb{P}}$) uniquely determined by $\mathsf{ivk}$; + and $\mathsf{qk}$ uniquely determined by $\mathsf{ivk}$ when + $\mathsf{qk} \neq \bot$ (i.e., when $\mathsf{use\_qsk} = \mathsf{true}$). + +The formal key-binding condition stated below covers both of these +uniformly: a key-binding break is a pair of distinct witnesses sharing +the same $\mathsf{ivk}$, where each witness carries the full key tuple +— $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ plus whichever of +$\mathsf{qk}$ or $\mathsf{sk}$ is in use. If key binding fails, the +Balance, Spendability, and Spend Authorization arguments each lose +their corresponding pinning step. + +Relative to the situation with note commitments where it was reasonable +to only obtain quantum recoverability for newly output Orchard notes, +there is a complication. Addresses may be used over the long term and +it may not be desirable to switch to new addresses, or to avoid funds +being sent to old ones. Fortunately, the Orchard protocol specified each +of $\mathsf{ak}$, $\mathsf{nk}$, and $\mathsf{rivk}$ to be derived from +$\mathsf{sk}$ via $\mathsf{PRF^{expand}}$, which is assumed collapsing. +($\mathsf{rivk}$ is derived differently for an "internal IVK", but that +is also via $\mathsf{PRF^{expand}}$.) + +Classically, the binding of $\mathsf{Commit^{ivk}}$ —instantiated via +Sinsemilla— fails against a discrete-log-breaking adversary, similarly +to $\mathsf{NoteCommit}$. We use essentially the same fix as for +$\mathsf{NoteCommit}$, with the $\mathsf{rivk}$-derivation hashes +playing the role of $\mathsf{H^{rcm}}$. The Recovery Statement checks +the derivation of $\mathsf{rivk}$: + +* When $\mathsf{qk} \neq \bot$, + $\mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})$. +* When $\mathsf{sk} \neq \bot$, + $\mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk})$, with + $\mathsf{ak}$ and $\mathsf{nk}$ also derived from $\mathsf{sk}$ via + $\mathsf{H^{ask}}$ and $\mathsf{H^{nk}}$. + +Exactly one of $\mathsf{qk}$ and $\mathsf{sk}$ is non-$\bot$ per +witness; this is equivalent to case-splitting by $\mathsf{use\_qsk}$. + +In either case, $\mathsf{rivk}$ is then either $\mathsf{rivk\_ext}$ +directly (external IVK) or +$\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk})$ (internal +IVK). All of these hashes are modelled as independent random oracles for +the key-binding argument. + +As in the [Recovery Statement](#proposedrecoverystatement), we have: + +$\begin{array}{rll} + \hspace{1em}\mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) = + \big(&\!\!\!\! \mathsf{ak}^{\mathbb{P}} = [\mathsf{H^{ask}}(\mathsf{sk})]\, \mathcal{G}^{\mathsf{Orchard}} \\ + &\!\!\!\! \wedge\; \mathsf{nk} = \mathsf{H^{nk}}(\mathsf{sk}) \\ + &\!\!\!\! \wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk}) \,\big) +\end{array}$ + +Let the key-binding condition on a witness +$w = (\mathsf{ivk}, \mathsf{qk}, \mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}, \mathsf{rivk})$ be: + +$\begin{array}{l} +\;\;\; (\mathsf{sk} = \bot) \neq (\mathsf{qk} = \bot) \\ +\wedge\; \mathsf{qk} \neq \bot \Rightarrow \big(\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk}) \,\big) \\ +\wedge\; \mathsf{sk} \neq \bot \Rightarrow \mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) \\ +\wedge\; \mathsf{rivk} \in \big\{\, \mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \,\big\} \\ +\wedge\; \mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) \\ +\wedge\; \mathsf{ivk} \not\in \{0, \bot\} +\end{array}$ + +where $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}).$ + +The predicate intentionally does not constrain the $y$-sign of +$\mathsf{ak}^{\mathbb{P}}$. This is consistent with Orchard's design +choice to use $\mathsf{ak}$ as a single $\mathbb{F}_{q_{\mathbb{P}}}$ +element (the $x$-coordinate $\mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$), +which avoids point-decompression in places that consume $\mathsf{ak}$, +in exchange for a factor-of-2 reduction in concrete binding security. +Accordingly, the break event below identifies witnesses up to the +$y$-sign of $\mathsf{ak}^{\mathbb{P}}$. + +The flags $\mathsf{use\_qsk}$ and $\mathsf{is\_internal\_rivk}$ that +appear in the protocol diagram do not appear in this witness — nor in +the formal Recovery Statement above. Their roles are absorbed into the +witness's structural form: + +* $\mathsf{use\_qsk}$ is encoded in + $(\mathsf{sk} = \bot) \neq (\mathsf{qk} = \bot)$: exactly one of + $\mathsf{sk}$ and $\mathsf{qk}$ is non-$\bot$, and the branch-specific + constraints apply to whichever is present. +* $\mathsf{is\_internal\_rivk}$ is encoded in + $\mathsf{rivk} \in \big\{\mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk})\big\}$: + both $\mathsf{rivk}$ derivations are admitted simultaneously. + +This formulation is strictly stronger than a flag-conditioned one: a +key-binding break can have $w_1$ and $w_2$ in different branches across +either flag (e.g., $w_1$ with $\mathsf{qk} \neq \bot$ and $w_2$ with +$\mathsf{sk} \neq \bot$, or $w_1$ with external $\mathsf{rivk}$ and +$w_2$ with internal $\mathsf{rivk}$), provided both produce the same +$\mathsf{ivk}$. A flag-based formulation would forbid only same-branch +breaks. + +A **key-binding break** is a pair of witnesses $(w_1, w_2)$ with +shared $\mathsf{ivk}$ satisfying the key-binding condition, whose +$(\mathsf{qk}, \mathsf{sk}, \mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ +projections differ — i.e., $w_1$ and $w_2$ differ in some component +other than the $y$-sign of $\mathsf{ak}^{\mathbb{P}}$. + +The random oracles used in the key-binding condition are $\mathsf{H^{rivk\_ext}}$, +$\mathsf{H^{rivk\_legacy}}$, $\mathsf{H^{rivk\_int}}$, $\mathsf{H^{ask}}$, and +$\mathsf{H^{nk}}$. + +Let $\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ +be the probability, over $\mathcal{A}$'s randomness and at most $q_{\mathsf{kb}}$ +queries in total to these random oracles, that $\mathcal{A}$ outputs a +key-binding break. + +**Theorem (key-binding, classical ROM).** <a id="thm-key-binding-rom"></a> +Let $\mathcal{A}$ be a classical adversary making at most $q_{\mathsf{kb}}$ +total queries to the random oracles used in the key-binding condition. Then +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3\, q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2\, r_{\mathbb{P}}}$. + +**Proof sketch.** + +*Algebraic setup.* +By § 5.4.1.10 “Sinsemilla commitments”, +$$\mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) = +\mathsf{Extract}_{\mathbb{P}}\big(M' + [\mathsf{rivk}]\, \mathcal{S}\big),$$ +where $\mathcal{S}$ is the rivk-randomization base +$$\mathcal{S} := \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard-CommitIvk-r”}, \texttt{“”}),$$ +and +$$M' := \mathsf{SinsemillaHashToPoint}\big(\texttt{“z.cash:Orchard-CommitIvk-M”},\; +\mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\mathsf{ak}) \,\Vert\, +\mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\mathsf{nk})\big).$$ +By expanding the Sinsemilla bases used inside $\mathsf{SinsemillaHashToPoint}$ +as scalar multiples of $\mathcal{S}$, without loss of generality we have +$M' = [h(\mathsf{ak}, \mathsf{nk})]\, \mathcal{S}$ for a Pedersen-like +deterministic scalar hash $h$, so +$$\mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) = +\mathsf{Extract}_{\mathbb{P}}\big([h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk}]\, \mathcal{S}\big).$$ +Domain separation in +the protocol's BLAKE2b instantiations ensures $h$ does not query +$\mathsf{H^{rivk\_ext}}$, $\mathsf{H^{rivk\_legacy}}$, +$\mathsf{H^{rivk\_int}}$, $\mathsf{H^{ask}}$, or $\mathsf{H^{nk}}$: +$h$ depends only on fixed Sinsemilla bases and on $(\mathsf{ak}, \mathsf{nk})$. + +By the same $y^2 = Y(x)$ argument used in the Spendability proof +(using § 5.4.9.7 for the $\mathsf{Extract}_{\mathbb{P}}$-style +$x$-coordinate convention), a key-binding break implies +$$h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk} \equiv \pm\big(h(\mathsf{ak}', \mathsf{nk}') + \mathsf{rivk}'\big) \pmod{r_{\mathbb{P}}}.$$ +Define $\mathsf{G}(w) := h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk} \pmod{r_{\mathbb{P}}}$ +for a witness $w$, and let $G_i := \mathsf{G}(w_i)$ for $i \in \{1, 2\}$. +The break condition is +$G_1 \equiv \pm G_2 \pmod{r_{\mathbb{P}}}$. + +*Final-random-oracle structure.* +For each witness $w_i$ satisfying the key-binding condition, +$\mathsf{rivk}_i$ is the output of a *final random oracle* +$O_i \in \{\mathsf{H^{rivk\_ext}}, \mathsf{H^{rivk\_legacy}}, \mathsf{H^{rivk\_int}}\}$ +at a *final input* $x_i$, determined by the witness's branch and +IVK choice: + +* qk-branch, external IVK: $O_i = \mathsf{H^{rivk\_ext}}$, + $x_i = (\mathsf{qk}_i, \mathsf{ak}_i, \mathsf{nk}_i)$. +* sk-branch, external IVK: $O_i = \mathsf{H^{rivk\_legacy}}$, + $x_i = \mathsf{sk}_i$. +* qk-branch, internal IVK: $O_i = \mathsf{H^{rivk\_int}}$, + $x_i = (\mathsf{rivk\_ext}_i, \mathsf{ak}_i, \mathsf{nk}_i)$ where + $\mathsf{rivk\_ext}_i = \mathsf{H^{rivk\_ext}_{qk_i}}(\mathsf{ak}_i, \mathsf{nk}_i)$. +* sk-branch, internal IVK: $O_i = \mathsf{H^{rivk\_int}}$, + $x_i = (\mathsf{rivk\_ext}_i, \mathsf{ak}_i, \mathsf{nk}_i)$ where + $\mathsf{rivk\_ext}_i = \mathsf{H^{rivk\_legacy}}(\mathsf{sk}_i)$. + +In each case +$G_i = h(\mathsf{ak}_i, \mathsf{nk}_i) + O_i(x_i) \pmod{r_{\mathbb{P}}}$, +with the deterministic shift $h$ independent of $O_i$'s responses +(by non-querying). + +*Independence claim per pair.* +For distinct witnesses $w_1, w_2$ both satisfying the key-binding +condition, $G_1$ and $G_2$ are independent uniform on +$\mathbb{F}_{r_{\mathbb{P}}}$, except for a residual event of +probability at most $1/r_{\mathbb{P}}$ per pair (accounting for +upstream-RO collisions in the both-internal sub-case). By case on +$(O_1, O_2)$: + +**$O_1 \neq O_2$.** The two random oracles are domain-separated +(independent BLAKE2b instantiations), so $O_1$'s outputs are +independent of $O_2$'s outputs. Each $G_i$ is uniform on +$\mathbb{F}_{r_{\mathbb{P}}}$ marginally; the pair is independent. + +**$O_1 = O_2 \in \{\mathsf{H^{rivk\_ext}}, \mathsf{H^{rivk\_legacy}}\}$.** +Both witnesses are in the same branch and external IVK. If +$x_1 = x_2$, the predicate's functional determinations +($\mathsf{rivk\_ext}_i$ from $x_i$; $\mathsf{rivk}_i = \mathsf{rivk\_ext}_i$; +$\mathsf{ivk}_i = \mathsf{Commit^{ivk}}(\mathsf{ak}_i, \mathsf{nk}_i, \mathsf{rivk}_i)$; +in the sk-branch additionally $\mathsf{ak}_i, \mathsf{nk}_i$ from +$\mathsf{sk}_i$ via $\mathsf{H^{ask}}, \mathsf{H^{nk}}$) force the +witnesses to coincide on all fields constrained by the key-binding +condition, contradicting distinctness. Hence WLOG $x_1 \neq x_2$, so +the two RO outputs at $x_1, x_2$ are independent uniform. + +**$O_1 = O_2 = \mathsf{H^{rivk\_int}}$.** Both witnesses are +internal IVK. If $x_1 = x_2$ as $\mathsf{H^{rivk\_int}}$ inputs, then +$\mathsf{rivk}_1 = \mathsf{rivk}_2$ and $\mathsf{ivk}_1 = \mathsf{ivk}_2$. +Sub-cases on the upstream branches: + +* same upstream branch (qk×qk or sk×sk): + $\mathsf{rivk\_ext}_1 = \mathsf{rivk\_ext}_2$ either forces upstream + input coincidence (and hence witness coincidence on all constrained + fields, contradicting distinctness) or requires an upstream-RO + collision — probability at most $1/r_{\mathbb{P}}$ per pair of + upstream queries. +* cross upstream branch (qk×sk): + $\mathsf{rivk\_ext}_1 = \mathsf{rivk\_ext}_2$ requires a cross-RO + collision between $\mathsf{H^{rivk\_ext}}$ and + $\mathsf{H^{rivk\_legacy}}$, which by domain separation is + probability at most $1/r_{\mathbb{P}}$ per pair of upstream queries. + +In every sub-case the residual $x_1 = x_2$ event has probability at +most $1/r_{\mathbb{P}}$ per pair. Conditional on $x_1 \neq x_2$, +$\mathsf{H^{rivk\_int}}$'s outputs at $x_1, x_2$ are independent +uniform. + +*Bounding the break probability.* +For any pair of distinct witnesses, the break condition +$G_1 \equiv \pm G_2 \pmod{r_{\mathbb{P}}}$ holds with probability +at most $2/r_{\mathbb{P}}$ when $G_1, G_2$ are independent uniform +(one per sign), plus at most $1/r_{\mathbb{P}}$ residual for +upstream collisions in the both-internal sub-case — total at most +$3/r_{\mathbb{P}}$ per pair. + +Treating the five rivk-derivation random oracles +($\mathsf{H^{rivk\_ext}}$, $\mathsf{H^{rivk\_legacy}}$, +$\mathsf{H^{rivk\_int}}$, $\mathsf{H^{ask}}$, $\mathsf{H^{nk}}$) as a +single combined uniform random oracle on the joint query domain (each +RO contributes its outputs independently of the others), and +union-bounding over the at most ${q_{\mathsf{kb}} \choose 2}$ pairs +of distinct witnesses, +$$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3 q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2 r_{\mathbb{P}}}.$$ + ## Security argument for Spendability DeriveNullifier is based on a Pedersen hash. In the current Orchard protocol, the property that it is infeasible to find two distinct -Orchard notes with the same nullifier (including possible nullfiers -of split OrchardZSA notes), depends on the collision-resistance of +Orchard notes with the same nullifier (including possible nullifiers +of split OrchardZSA notes), depends on the collision resistance of that hash, which would not hold against a discrete-log-breaking adversary. Does this mean it is possible to break Spendability for the given -Recovery circuit? As it turns out, no, but the argument is somewhat +Recovery Statement? As it turns out, no, but the argument is somewhat involved. -TODO: this argument is too handwavy and depends on the ROM; it needs -further work for a quantum adversary. Also it is incomplete because -it does not consider split notes. - -Since each function in the Recovery circuit is deterministic, the +Since each function in the Recovery Statement is deterministic, the free variables that the adversary can control are the sources of the -derivation digraph within that circuit and either $\mathsf{SoK^{sk}}$ -or $\mathsf{SoK^{qk}}$. That is, the adversary can control: - -* $(\text{ρ}, \mathsf{g_d}, \mathsf{split\_flag}, \mathsf{rseed}, \mathsf{rsplit}, \mathsf{is\_internal\_rivk}, \mathsf{use\_qsk})$ and - * $\mathsf{sk}$, when $\mathsf{use\_qsk} = \mathsf{false}$; - * $(\mathsf{nk}, \mathsf{ak}, \mathsf{qsk})$, when $\mathsf{use\_qsk} = \mathsf{true}$. - -As we argued earlier in section [Repairing note commitments], -$\mathsf{rcm}$ binds $\mathsf{rseed}$ and $\mathsf{pre\_rcm}$, and all -of the other inputs to $\mathsf{NoteCommit}$ are also included in -$\mathsf{pre\_rcm}$. Therefore, given the independence assumption between -$\mathsf{H^{rcm}}$ and $f$ described earlier, $\mathsf{cm}$ binds all -of the values in the Recovery circuit that the adversary can control. - -We can then analyze $\mathsf{DeriveNullifier}$ in essentially the same -way we analyzed $\mathsf{NoteCommit}$. - -First consider $\mathsf{split\_flag} = \mathsf{false}$. - -Recall that $\mathsf{DeriveNullifier}$ is defined in -§ 4.16 ‘Computing ρ values and Nullifiers’ as: - -$$\mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) = \mathsf{Extract}_{\mathbb{P}}\big(\big[\mathsf{PRF^{nfOrchard}_{nk}}(\text{ρ}) + \text{ψ}) \bmod q_{\mathbb{P}}\big]\, \mathcal{K}^{\mathsf{Orchard}} + \mathsf{cm}\big)$$ +derivation digraph within that statement and either $\mathsf{SoK^{sk}}$ +or $\mathsf{SoK^{qk}}$. That is, the adversary can control all of +$$(\text{ρ}, \mathsf{g_d}, \mathsf{rseed}, \mathsf{sk}, \mathsf{nk}, \mathsf{ak}, \mathsf{qk}, \mathsf{qsk}, \mathsf{rivk})$$ +subject to $(\mathsf{sk} = \bot) \neq (\mathsf{qk} = \bot)$. The +choice between external and internal IVK is encoded in +$\mathsf{rivk}$'s value (either $\mathsf{rivk\_ext}$ or +$\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk})$). + +We analyze $\mathsf{DeriveNullifier}$ as a function of these +controllable inputs. Recall that $\mathsf{DeriveNullifier}$ is defined +in § 4.16 ‘Computing ρ values and Nullifiers’ as: + +$$\mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) := + \mathsf{Extract}_{\mathbb{P}}\Big( + \big[(\mathsf{PRF^{nf}_{nk}}(\text{ρ}) + \text{ψ}) \bmod q_{\mathbb{P}}\big]\, \mathcal{K} + + \mathsf{cm} + \Big)$$ Also recall from [Repairing note commitments] that we have -$$\mathsf{cm} = [\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr}) + f(\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr})]\, \mathcal{R}.$$ - -When $\mathsf{split\_flag} = \mathsf{false}$, $\text{ψ}$ is determined -by $\mathsf{rseed}$. The nullifier corresponding to -$(\mathsf{nk}, \text{ρ}, \mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr})$ is -then -$$\mathsf{Extract}_{\mathbb{P}}\big([\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{noterepr}) + f(\mathsf{rseed}, \mathsf{leadByte}, \mathsf{noterepr}) + g(\mathsf{nk}, \text{ρ}, \mathsf{rseed})]\, \mathcal{R}\big)$$ - -for some $g$ depending on the discrete logarithm of $\mathcal{K}^{\mathsf{Orchard}}$ wrt $\mathcal{R}$. - -The intuition is that an adversary cannot vary any of the inputs it controls without causing an -unpredictable change to both $\mathsf{cm}$ and $\mathsf{nf}$. This is because every such input -goes through a function that can be modelled as a random oracle on the way to deriving -$\mathsf{cm}$ and $\mathsf{nf}$: - -* $\text{ρ}$ goes through $\mathsf{H}^{\text{ψ}}$ to derive $\text{ψ}$, and through - $\mathsf{PRF^{nfOrchard}_{nk}}$ which is instantiated as Poseidon to derive $\mathsf{nf}$; -* $\mathsf{g_d}$ goes through $\mathsf{H^{rcm}}$; -* because $\mathsf{g_d} \mapsto \mathsf{pk_d} = [\mathsf{ivk}]\, \mathsf{g_d}$ is 1-1, any - change to $\mathsf{ivk}$ for a given $\mathsf{g_d}$ results in a change to $\mathsf{pk_d}$, - which goes through $\mathsf{H^{rcm}}$; -* when $\mathsf{split\_flag} = \mathsf{false}$, $\mathsf{rseed}$ goes through $\mathsf{H}^{\text{ψ}}$ - and then $\mathsf{H^{rcm}}$; -* $\mathsf{use\_qsk}$ only has two possible values, and therefore can't increase the adversary's - advantage by more than a factor of $2$ provided that both alternatives are otherwise secure; -* when $\mathsf{use\_qsk} = \mathsf{false}$: - * $\mathsf{sk}$ goes through $\mathsf{H^{rivk\_legacy}}$; - * $\mathsf{nk}$ goes through $\mathsf{H^{nk}}$; - * $\mathsf{ak}$ goes through $\mathsf{H^{ask}}$; -* when $\mathsf{use\_qsk} = \mathsf{true}$: - * $\mathsf{qsk}$ goes through $\mathsf{H^{qk}}$ and $\mathsf{H^{rivk\_ext}}$; - * $\mathsf{nk}$ goes through $\mathsf{H^{rivk\_ext}}$; - * $\mathsf{ak}$ goes through $\mathsf{H^{rivk\_ext}}$; - -Note that while $f$ and $g$ are individually random oracles on their inputs, their -sum modulo $q_{\mathbb{P}}$ could potentially be subject to a meet-in-the-middle attack. -This might be possible if the inputs that the adversary can control could be split so -that some affect only $\mathsf{H^{rcm,Orchard}}$ and $f$, and others affect only $g$. -(Note that $\mathsf{H^{rcm,Orchard}}$ and $f$ have the same inputs and are each random -oracles on all of their inputs.) But $\mathsf{noterepr}$ includes $\text{ρ}$, and we have -already established that $\mathsf{nk}$ cannot be varied without affecting $\mathsf{pk_d}$. -So with a little work we can see that such splitting is not possible. - -TODO $\mathsf{split\_flag} = \mathsf{true}$. - -An adversary could also attempt to cause a collision in $\mathsf{nf}$ by causing a -collision on $\mathsf{Extract}_{\mathbb{P}}$, but this is also not feasible if -$\mathsf{H^{rcm,Orchard}}$ can be modelled as a random oracle. - -## Effects of discrete-log-breaking attacks before the switch to the Recovery Protocol +$$\mathsf{cm} = [\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + + \mathsf{f}(\mathsf{rseed}, \mathsf{noterepr})]\, \mathcal{R}.$$ + +Let $K_{\kern-.08em\mathcal{R}}$ denote the discrete logarithm of +$\mathcal{K}$ with respect to $\mathcal{R}$. This is well-defined and +nonzero: $\mathcal{R}$ generates the prime-order Pallas group, so any +non-identity Pallas point has a unique nonzero discrete logarithm with +respect to it; and $\mathcal{K}$ is non-identity by construction. + +Recall that $\text{ψ}$ is determined by $\mathsf{rseed}$ via +$\text{ψ} = \mathsf{H}^{\text{ψ}}_{\mathsf{rseed}}(\text{ρ})$. +The nullifier corresponding to +$(\mathsf{nk}, \text{ρ}, \mathsf{rseed}, \mathsf{noterepr})$ +is then +$$\mathsf{Extract}_{\mathbb{P}}\Big( + \big[ + \big((\mathsf{PRF^{nf}_{nk}}(\text{ρ}) + \text{ψ}) \bmod q_{\mathbb{P}}\big) \cdot K_{\kern-.08em\mathcal{R}} + + \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{rseed}, \mathsf{noterepr}) + \big]\, \mathcal{R} + \Big).$$ + +We model $\mathsf{H^{rcm}}$ as a random oracle with output uniform on +$\mathbb{F}_{r_{\mathbb{P}}}$. The functions $\mathsf{f}$, +$\mathsf{H}^{\text{ψ}}$, and $\mathsf{PRF^{nf}}$ are deterministic +functions of $\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$ +that **do not query $\mathsf{H^{rcm}}$**: $\mathsf{f}(\mathsf{notetuple})$ +is the Sinsemilla-base lift; $\mathsf{H}^{\text{ψ}}$ and $\mathsf{PRF^{nf}}$ are +conventional hash functions. + +> The non-querying constraint rules out trivializing instantiations such +> as $\mathsf{f}({\small •}) = -\mathsf{H^{rcm}}({\small •})$. +> In the concrete protocol, it reflects that $\mathsf{f}$ depends only on +> fixed Sinsemilla bases; and that the hashes $\mathsf{H}^{\text{ψ}}$, +> $\mathsf{PRF^{nf}}$, and $\mathsf{H^{rcm}}$ use distinct domain +> separators, so can be considered unrelated to each other. + +A key-binding break is as defined above in the +[Security argument for key binding](#securityargumentforkeybinding). + +Let $\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ +be the probability, over $\mathcal{A}$'s randomness and at most +$q_{\mathsf{kb}}$ queries to the random oracles used in the +key-binding argument, that $\mathcal{A}$ outputs a key-binding break. +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ is +bounded separately by that argument; the bound below is unconditional, +but is only useful to the extent that +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ is +small. + +We give a reduction-based argument that any classical adversary +$\mathcal{A}$ in the Random Oracle Model attempting to find two valid +[Recovery Statement](#proposedrecoverystatement) witnesses with distinct +note tuples that have colliding nullifiers, succeeds with probability at most +$\frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$, +where $q_{\mathsf{rcm}}$ is the number of queries $\mathcal{A}$ makes +to $\mathsf{H^{rcm}}$, and $q_{\mathsf{kb}}$ is as defined above. +The bound depends only on $q_{\mathsf{rcm}}$ and on +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$, +not on running time. + +The components $\mathsf{rseed}, \mathsf{noterepr}$ +are fields of $\mathsf{notetuple}$ by definition; and $\text{ρ}$, +$\mathsf{g_d}$, $\mathsf{pk_d}$, and $\text{ψ}$ are fields of +$\mathsf{noterepr}$, hence of $\mathsf{notetuple}$. + +**$\mathsf{ivk}$-pinning lemma.** <a id="lemma-ivk-pinning"></a> +For any valid Recovery Statement witness $w$ with +$\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$, +the value $\mathsf{ivk} = \log_{\mathsf{g_d}}(\mathsf{pk_d})$ is +well-defined, since $\mathsf{g_d} \neq \mathcal{O}_{\mathbb{P}}$ on the +prime-order Pallas curve and +$\mathsf{ivk} \in [0, q_{\mathbb{P}}) \subseteq [0, r_{\mathbb{P}})$; +$\mathsf{ivk}$ is therefore uniquely determined by $\mathsf{notetuple}$. + +**$\mathsf{PRF^{nf}}$-pinning lemma.** <a id="lemma-prf-nf-pinning"></a> +Suppose $\mathcal{A}$'s output $(w_1, w_2)$ does not contain a +key-binding break. Then for each $i \in \{1, 2\}$, +$\mathsf{PRF^{nf}_{\mathsf{nk}_i}}(\text{ρ}_i)$ is uniquely determined +by $\mathsf{notetuple}_i$: by the conditioning, +$(\mathsf{ak}_i, \mathsf{nk}_i, \mathsf{rivk}_i)$ is the only opening of +$\mathsf{ivk}_i$ appearing in $\mathcal{A}$'s output, so $\mathsf{nk}_i$ +is a function of $\mathsf{ivk}_i$, which is in turn a function of +$\mathsf{notetuple}_i$ by the $\mathsf{ivk}$-pinning lemma; and +$\text{ρ}_i$ is a field of $\mathsf{notetuple}_i$. + +The argument here covers nullifier-binding — it argues that $\mathsf{nf}$ +binds the note tuple $(\mathsf{rseed}, \mathsf{noterepr})$ +under $\mathsf{H^{rcm}}$ modelled as a random oracle +and the [key-binding theorem](#thm-key-binding-rom). + +**Theorem (distinct-notetuple Spendability, classical ROM).** <a id="thm-spendability"></a> +Let $\mathcal{A}$ be a classical adversary with oracle access to +$\mathsf{H^{rcm}}$ having output uniform on $\mathbb{F}_{r_{\mathbb{P}}}$, +making at most $q_{\mathsf{rcm}}$ oracle queries. The *Spendability-collision* +game has $\mathcal{A}$ output two Recovery Statement witnesses $w_1, w_2$ +satisfying: + +<a id="thm-spendability-validity"></a>**Validity of witnesses** +: both witnesses satisfy the + [Proposed Recovery Statement](#proposedrecoverystatement). + +<a id="thm-spendability-distinct"></a>**Distinct note tuples** +: the $\mathsf{H^{rcm}}$-input tuples + $\mathsf{notetuple}_i := (\mathsf{rseed}_i, \mathsf{noterepr}_i)$ + satisfy $\mathsf{notetuple}_1 \neq \mathsf{notetuple}_2$. + +<a id="thm-spendability-collide"></a>**Colliding nullifiers** +: $\mathsf{nf}_1 = \mathsf{nf}_2$. + +Then $\mathcal{A}$ wins this game with probability at most +$$\Big({\textstyle{q_{\mathsf{rcm}}} \atop \textstyle{2}}\Big) \cdot \frac{2}{r_{\mathbb{P}}} + + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) + = \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}),$$ +taken over the random oracle's responses and any internal randomness of +$\mathcal{A}$. + +This bound is essentially tight against classical generic adversaries. +Maurer [^Maurer2002] (Section 2, p. 5) establishes a matching upper +bound of ${k \choose 2}/N$ on the success probability of any +classical algorithm in finding a collision against a random oracle with +an $N$-element output space using $k$ queries. Maurer's bound applies +to the *equality* event $F_i = F_j$; our win condition allows +$F_i = \pm F_j$ (two winning configurations per pair instead of one). +Applying Maurer with $N = r_{\mathbb{P}}$ (the $\mathsf{H^{rcm}}$ +output space) gives ${q_{\mathsf{rcm}} \choose 2}/r_{\mathbb{P}}$ for +the equality event; doubling for the sign relaxation gives our +$\frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}}$ bound. +Classical parallel collision search [^Bernstein2009] (top of p. 8) +achieves the equality-event regime up to a constant factor; the same +adversaries achieve a constant fraction of the doubled bound for the +$\pm$-equivalence event. + +**Proof sketch.** +$\mathcal{A}$ makes at most $q_{\mathsf{rcm}}$ queries to +$\mathsf{H^{rcm}}$ before outputting $(w_1, w_2)$ satisfying +[**Validity of witnesses**](#thm-spendability-validity), +[**Distinct note tuples**](#thm-spendability-distinct), and +[**Colliding nullifiers**](#thm-spendability-collide). The probability +that $(w_1, w_2)$ contains a key-binding break is at most +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$; condition on +the complement. + +*Algebraic setup.* +Under this conditioning, define +$$\mathsf{F}(\mathsf{notetuple}) := \mathsf{H^{rcm}}(\mathsf{notetuple}) + +\mathsf{f}(\mathsf{notetuple}) + \big((\mathsf{PRF^{nf}_{nk}}(\text{ρ}) + +\text{ψ}) \bmod q_{\mathbb{P}}\big) \cdot K_{\kern-.08em\mathcal{R}} +\pmod{r_{\mathbb{P}}},$$ +where $\mathsf{rseed}, \text{ρ}, \text{ψ}$ are fields of +$\mathsf{notetuple}$ and $\mathsf{PRF^{nf}_{nk}}(\text{ρ})$ is +determined by $\mathsf{notetuple}$ via the +[$\mathsf{PRF^{nf}}$-pinning lemma](#lemma-prf-nf-pinning), and let +$F_i := \mathsf{F}(\mathsf{notetuple}_i)$ for $i \in \{1, 2\}$. + +$\mathsf{Extract}_{\mathbb{P}}$ (§ 5.4.9.7 'Coordinate Extractor for +Pallas' [^protocol-concreteextractorpallas]) is the $x$-coordinate of +its argument for non-identity points, with the identity mapping to $0$. +Since Pallas has the form $y^2 = Y(x)$ and no Pallas point has +$x$-coordinate $0$, the collision $\mathsf{nf}_1 = \mathsf{nf}_2$ +holds iff $F_1 \equiv \pm F_2 \pmod{r_{\mathbb{P}}}$. + +*Independence claim per pair.* +By [**Distinct note tuples**](#thm-spendability-distinct), +$\mathsf{notetuple}_1 \neq \mathsf{notetuple}_2$, so the +$\mathsf{H^{rcm}}$ outputs at $\mathsf{notetuple}_1, \mathsf{notetuple}_2$ +are independent uniform on $\mathbb{F}_{r_{\mathbb{P}}}$. The +deterministic shifts ($\mathsf{f}$ and the $\mathsf{PRF^{nf}}$ +contribution scaled by $K_{\kern-.08em\mathcal{R}}$) do not query +$\mathsf{H^{rcm}}$, so they are independent of its responses. Hence +$F_1$ and $F_2$ are independent uniform on $\mathbb{F}_{r_{\mathbb{P}}}$. + +*Bounding the win probability.* +The win condition $F_1 \equiv \pm F_2$ is a linear constraint on a +pair of independent uniform variables, satisfied with probability at +most $2/r_{\mathbb{P}}$ (one per sign). Union-bounding over the at +most ${q_{\mathsf{rcm}} \choose 2}$ pairs of distinct +$\mathsf{H^{rcm}}$ queries: +$$\Pr[\text{win} \mid \neg\,\text{break}] \leq \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}}.$$ +Decomposing on whether a key-binding break occurs and applying +$\Pr[\text{win}] \leq \Pr[\text{win} \mid \neg\,\text{break}] + \Pr[\text{break}]$: +$$\Pr[\text{win}] \leq \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}).$$ +This completes the classical-ROM proof. + +The [key-binding theorem](#thm-key-binding-rom) bounds +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3\, q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2\, r_{\mathbb{P}}}$. +Substituting, an adversary $\mathcal{A}$ that makes at most +$q_{\mathsf{rcm}}$ queries to $\mathsf{H^{rcm}}$ and at most +$q_{\mathsf{kb}}$ queries to the key-binding random oracles +wins the Spendability-collision game with probability at most +$\frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} \;+\; \frac{3\, q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2\, r_{\mathbb{P}}}$. + +For the post-quantum lift of this bound and of the +[key-binding bound](#thm-key-binding-rom) above, see the next section. + +## Adaptation to the quantum setting + +The classical-ROM proofs above (for [key binding](#thm-key-binding-rom) +and [Spendability](#thm-spendability-collide)) rely on +$\mathsf{H^{rcm}}$ and the various $\mathsf{rivk}$-derivation hashes +being collision-resistant. The natural quantum analog is called the +*collapsing* property, introduced by Unruh [^Unruh2015] [^Unruh2016]. +It says that even a quantum adversary holding a *superposition* over +several preimages of a fixed output cannot tell —by any subsequent +measurement— which preimage it now has. This is the right property +for our reductions. Each proof above splits cases based on which oracle +query produced the colliding output; that case analysis works the same +classically and quantumly only if the underlying hash "collapses" the +adversary's superposition to a single classical preimage. + +Subsequent work has analyzed whether standard hash-function +constructions inherit collapsing from their compression function. Unruh +[^Unruh2016] proved this for Merkle–Damgård (with a padding +restriction); Czajkowski et al. [^CBHSU2017] for the *sponge* +construction (the absorb-then-squeeze paradigm used by SHA-3 / Keccak), +with [^ACMT2025] strengthening the sponge result via the related notion +of quantum indifferentiability. Fehr [^Fehr2018] gave a unified +algebraic framework that recovers these results and proves the +collapsing property of HAIFA, a Merkle–Damgård variant with a +per-iteration salt and counter. Gunsing and Mennink [^GM2022] extended +this kind of analysis to tree-hash constructions, relevant for the +Recovery Protocol's note-commitment tree. + +BLAKE2b uses HAIFA, so by Fehr's theorem modelling $\mathsf{H^{rcm}}$ +as collapsing reduces to modelling BLAKE2b's compression function as +collapsing. The "iv-preimage resistance" side condition Fehr's theorem +requires for arbitrary-length inputs is automatically satisfied if the +compression function is modelled as a random oracle — which is also +the modelling assumption underlying the classical-ROM analyses above. -TBD: explain that such attacks can break Balance and Spendability, including -Spendability for transactions after switching to the Recovery Protocol. +By the argument in [^Bernstein2009], the best known *generic* quantum +attack on a hash function is simply the classical attack of [^vOW1999]. +(In particular, the Brassard–Høyer–Tapp algorithm [^BHT1997] is +entirely unimplementable for a 253-bit output size: to achieve the +claimed speed-up, it would require running Grover's algorithm with a +quantum circuit that does random accesses to a $2^{92.3}$-bit quantum +memory.) Therefore, an output size of 253 bits does not exclude a hash +function from being collapsing. + +$\mathsf{Extract}_{\mathbb{P}}$ does not interfere with the QROM lift: +it is a deterministic 2-to-1 map on non-identity Pallas points (sending +$P$ and $-P$ to the same $x$-coordinate) and does not query +$\mathsf{H^{rcm}}$ or any other random oracle, so it composes with the +underlying random oracle the same way classically and quantumly. The +factor of 2 from the 2-to-1 reduction is already absorbed into the +break-probability bound (each $\mathsf{cm}_x$ has exactly two valid +$\mathsf{cm}$ values, hence exactly two valid $\mathsf{rcm}$ values, as +stated in the Spendability proof above). + +This factor-of-2 absorption relies on the +[fibres](https://en.wikipedia.org/wiki/Fiber_%28mathematics%29) $\{P, -P\}$ +of $\mathsf{Extract}_{\mathbb{P}}$ forming a *uniform* partition of the +non-identity points of $\mathbb{P}$ — the free $\mathbb{Z}/2$ negation action +gives every fibre for non-identity points exactly size 2 — which is what lets +birthday-style bounds substitute $r_{\mathbb{P}} \to r_{\mathbb{P}}/2$ cleanly. +A non-uniform mapping would not admit such a substitution. + +### QROM lift of the security arguments + +The classical-ROM reductions for both +[Spendability](#thm-spendability-collide) and +[key binding](#thm-key-binding-rom) satisfy the standard conditions for +a "clean" lift to the quantum random-oracle model: + +* *Straight-line.* Neither reduction rewinds the adversary or measures + intermediate state; both inspect the adversary's classical output and + bound the probability over the random oracles' randomness. + Rewinding-based QROM techniques [^CMSZ2021] [^CDDGS2025] are therefore + not needed. +* *No adaptive reprogramming.* Both reductions treat their random + oracles as fixed random functions throughout; neither reprograms + responses to adversary-queried inputs. + +**Concrete QROM bounds.** By Zhandry's compressed-oracle technique +[^Zhandry2018] (see also [^CFHL2021] for a classical-style derivation), +the classical $q^2 / N$ collision probability +transfers to $O(q^3 / N)$ in QROM: an adversary making at most $q$ +quantum queries to a random oracle with output space of size $N$ +finds a collision with probability $O(q^3 / N)$. Applied to our +reductions: + +* $\varepsilon^{\mathsf{QROM}}_{\mathsf{Spendability}} \leq O\!\left(q_{\mathsf{rcm}}^3 / r_{\mathbb{P}}\right) + \varepsilon^{\mathsf{QROM}}_{\mathsf{kb}}.$ +* $\varepsilon^{\mathsf{QROM}}_{\mathsf{kb}} \leq O\!\left(q_{\mathsf{kb}}^3 / r_{\mathbb{P}}\right).$ + +These are worst-case theoretical bounds. An adversary that saturates +them would need to mount a BHT-style attack, which is unimplementable +for a 253-bit output (as discussed above, the BHT algorithm would +require a quantum circuit randomly accessing a $2^{92.3}$-bit quantum +memory). In practice the achievable bound remains close to the +classical $q^2 / r_{\mathbb{P}}$, since the best *known* generic +quantum attack is the classical attack of [^vOW1999] — Bernstein +[^Bernstein2009] is careful to flag this as best-known rather than +provably best. + +For the parameters relevant to Zcash ($q_{\mathsf{rcm}}, +q_{\mathsf{kb}} \ll 2^{60}$ and $r_{\mathbb{P}} \approx 2^{254}$), +the $O(q^3 / r_{\mathbb{P}})$ worst-case bound is at most +$\sim 2^{-74}$, while the practically achievable +$O(q^2 / r_{\mathbb{P}})$ bound stays closer to $\sim 2^{-134}$. -Note that we can identify the precise set of note commitments for -recoverable (lead byte $\mathtt{0x03}$) Orchard notes, since they are -the commitments for Orchard outputs of v6 transactions. -However, we cannot identify the precise set of nullifiers for -recoverable notes: an Orchard action in a v6 transaction could be -spending either a recoverable or non-recoverable note, and their -nullifier sets are indistinguishable. +## Effects of discrete-log-breaking attacks before the switch to the Recovery Protocol -On the other hand, within the recovery circuit we know that the -note being spent is recoverable. +A practical discrete-log-breaking attack —either by a sufficiently large quantum +computer running Shor's algorithm, or a major advance in classical cryptanalysis +of the discrete logarithm or Diffie–Hellman problems— would compromise the +cryptographic primitives underlying Zcash's shielded protocols. + +Note and value commitments in Orchard[ZSA] and Sapling are Pedersen-style and +lose binding; the proof systems used in the shielded protocols (Halo 2 over +Vesta in Orchard[ZSA], Groth16 over BLS12-381 in Sapling or Sprout) lose +soundness; and the RedDSA binding and spend authorization signatures in +Orchard[ZSA] and Sapling can be forged. Sprout's note commitments are +SHA-256-based and survive a discrete log break, but the broken proof system is +sufficient to forge JoinSplit statements, and the Ed25519 spend authorization +and JoinSplit signatures can be forged. In addition, the ECDSA signatures used +for transparent spend authentication can be forged. + +The combined effect is severe. An adversary can: + +* break Balance for the Sapling or Orchard pools by forging value-commitment + openings or binding signatures; +* break Balance for the Sprout, Sapling, or Orchard pools by forging Groth16 or + Halo 2 proofs of balanced transactions; +* break Spend authentication (i.e. steal funds, independently of a Balance break) + for the Sprout, Sapling, or Orchard pools by forging alternative note witnesses + for any commitment on chain, or by forging Groth16 or Halo 2 proofs of valid + spends; +* break Spend authentication for the Sapling or Orchard pools by forging RedJubjub + or RedPallas spend authorization signatures, or for the transparent pool by + forging ECDSA-over-secp256k1 signatures used in scripts; +* break Spendability via roadblock or Faerie Gold attacks, preventing users from + spending their own funds; +* break Privacy of note plaintexts by finding the $\mathsf{ivk}$ for a known + Sapling or Orchard address, or the $\mathsf{sk_{enc}}$ for a known Sprout + address, or by breaking the Diffie–Hellman-based note encryption (again only + for a known recipient address). + +Attacks on transparent spend authentication are not addressed by this proposal. +[^Google2025] discusses these attacks in the context of Bitcoin. For Zcash, we +should note that P2PK and legacy P2MS (non-P2SH) scripts have never been +supported by Zcash wallets, but Zcash is vulnerable to "on-spend" attacks in a +similar way to Bitcoin, with the additional consideration that some Zcash +wallets might be more likely to reuse transparent addresses. The discussion of +Segwit is not relevant to Zcash. + +## Effects of discrete-log-breaking attacks after the switch to the Recovery Protocol + +We assume for this section that the legacy Orchard, OrchardZSA (if deployed), +Sapling, and Sprout protocols will be switched off. Any remaining funds in +the Sapling and Sprout pools, as well as funds in non-recoverable Orchard notes, +would be rendered permanently unspendable. + +The Balance, Spend authentication, and Spendability attacks are possible only +*before* the switch to the Recovery Protocol — that is, while legacy Orchard, +Sapling, and (if ZIP 2003 is not deployed first [^zip-2003]) Sprout spends are +still accepted by the consensus rules. + +If a balance violation occurred in any pool before its protocol was switched +off, it would not necessarily be detected. The only constraint on such attacks +is the ZIP 209 turnstile mechanism [^zip-0209]. If there were evidence of +balance violation having occurred, confidence in Zcash as a whole could +potentially be undermined despite the turnstile constraints (especially if the +violation was in the largest pool, currently Orchard). Therefore, it will be +essential to ensure that the pre-quantum protocols are switched off well in +advance of the potential availability of cryptographically relevant quantum +computers. + +If the transparent protocol is not switched off, then the situation with respect +to transparent spend authentication is unchanged. Balance for the transparent +protocol cannot be violated directly by a discrete-log break (but funds created +by a balance violation in a shielded pool can be moved into the transparent pool +up to that shielded pool's turnstile limit). + +The changes made by ZIP 2005 are only intended to address Balance preservation, +Spend authentication, and Spendability for recoverable Orchard[ZSA] notes. The +situation with respect to Privacy is unchanged for any pool. + +In particular, the note encryption for Orchard[ZSA], Sapling, and Sprout pools +is subject to "Harvest Now, Decrypt Later" attacks: that is, a +discrete-log-breaking attack can be performed as long as an adversary has both +the ciphertext (which is published on the block chain) and the recipient +address. Other protocol changes are under consideration to mitigate this risk +for future transfers. + +Due to the zero-knowledge property, Groth16 and Halo 2 proofs do not leak +further information relevant to Privacy when addresses are unknown. The same is +true of Sapling or Orchard[ZSA] spend authentication signatures, due to key +rerandomization. + +## Attacks addressed by the Recovery Protocol + +The Recovery Statement's $\mathsf{BindKeys}$ constraint pins the key witness via +$\mathsf{PRF^{expand}}$ (modelled as collapsing), not via discrete-log hardness. +So (if no mistakes are made in the design or instantiation), fresh Balance, +Spend authentication, or Spendability attacks against the Recovery Protocol +should require breaking post-quantum binding rather than just discrete logs. +Funds in recoverable Orchard notes can therefore be spent through the Recovery +Protocol after the switch. However, if the adversary attacked either +Spendability (e.g. via a roadblock attack) or Spend authorization before the +switch to the Recovery Protocol, then it could affect the legitimate holder's +ability to spend the funds afterward. The window between +$\mathsf{ZIP2005ActivationHeight}$ and the switch is the critical exposure +period for recoverable Orchard funds. + +Note that we can precisely identify the set of note commitments for recoverable +Orchard notes in v6 transactions, even if we cannot decrypt them, since only +recoverable notes are allowed in that case. However, Orchard notes in v5 +transactions after $\mathsf{ZIP2005ActivationHeight}$ could be either +recoverable or not. + +We cannot identify the precise set of nullifiers for recoverable notes: an +Orchard action in a v6 transaction could be spending either a recoverable or +non-recoverable note, and their nullifier sets are indistinguishable. + +On the other hand, within the Recovery Statement we know that the note being +spent is recoverable. # Deployment -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). +Let $\mathsf{ZIP2005ActivationHeight}$ be {{TBD}}. + +As far as the author of this ZIP is 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’ [^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 -[write this into ZIP 312](https://github.com/zcash/zips/pull/883/files) +[write this into ZIP 312](https://github.com/zcash/zips/pull/895/files) 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. -It is suggested to deploy this change with v6 transactions. That is, -every Orchard output of a v6-onward transaction will be a pq-recoverable -note. This implies that when the pre-quantum protocol is turned off, -v5 and earlier outputs will no longer be spendable. Since v6 already -changes the note encryption in order to support memo bundles and ZSAs, -this approach to deployment reduces the risk of the kind of difficulties -that occurred with [ZIP 212](https://zips.z.cash/zip-0212), where some -wallets were following the old protocol after the Canopy upgrade and -sending non-conformant note plaintexts. - -When a compliant wallet receives an Orchard note in a v5 or earlier -transaction, the associated funds are not pq-recoverable and need to be -spent to v6 in order to make them so. - -Note: if we prioritize spending non-pq-recoverable notes, it is +Two options were considered for deployment: + +1. Deploy this change prior to the next network upgrade. This optimizes + time-to-deployment. An activation height is still needed, in order to + identify a height from which wallets must re-scan if they are missing + recoverable notes due to late deployment. +2. Deploy this change at the same time as the next network upgrade (NU7), + at the same time as v6 transactions. + +With either option, it is proposed to enforce this change with v6 transactions. +That is, every Orchard output of a v6-onward transaction will be a recoverable +note. + +This ZIP currently reflects the first option. The risk of some wallets +not having deployed support for receiving the new note plaintext format +is mitigated by initially only using that format for note plaintexts sent +to wallet-internal addresses. + +When a compliant wallet receives an Orchard note with lead byte +$\mathtt{0x02}$, the associated funds are not recoverable and need to be +spent to a recoverable note in order to make them so. + +Note: if we prioritize spending non-recoverable notes, it is conceivable that an adversary could exploit this to improve [arity leakage attacks](https://github.com/zcash/zcash/issues/4332). On the other hand, adversaries can already choose note values to @@ -1375,10 +2057,24 @@ 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) + +[^protocol-concreteextractorpallas]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.9.7: Coordinate Extractor for Pallas](protocol/protocol.pdf#concreteextractorpallas) + [^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) @@ -1387,38 +2083,62 @@ manipulate the note selection algorithm to some extent. [^zip-0032-orchard-internal-key-derivation]: [ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard internal key derivation](zip-0032.rst#orchard-internal-key-derivation) +[^slip-0039]: [SLIP-0039: Shamir's Secret-Sharing for Mnemonic Codes](https://github.com/satoshilabs/slips/blob/master/slip-0039.md) + [^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) +[^zip-0209]: [ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances](zip-0209.rst) + [^zip-0226]: [ZIP 226: Transfer and Burn of Zcash Shielded Assets](zip-0226.rst) +[^zip-0226-split-notes]: [ZIP 226: Transfer and Burn of Zcash Shielded Assets — Split Notes](zip-0226.rst#split-notes) + [^zip-0227]: [ZIP 227: Issuance of Zcash Shielded Assets](zip-0227.rst) -[^zip-0230]: [ZIP 230: Version 6 Transaction Format](zip-0230.rst) +[^zip-0231]: [ZIP 231: Memo Bundles](zip-0231.md) -[^zip-0231]: [ZIP 231: Memo Bundles](zip-0231.rst) +[^zip-0248]: [ZIP 248: Extensible Transaction Format (PR: zcash/zips#1156)](https://github.com/zcash/zips/pull/1156) [^zip-0312]: [ZIP 312: FROST for Spend Authorization Multisignatures](zip-0312.rst) [^zip-0312-key-generation]: [ZIP 312: FROST for Spend Authorization Multisignatures — Key Generation](zip-0312.rst#key-generation) +[^zip-0312-threat-model]: [ZIP 312: FROST for Spend Authorization Multisignatures — Threat Model](zip-0312.rst#threat-model) + +[^zip-2003]: [ZIP 2003: Disallow version 4 transactions](zip-2003.rst) + [^zcash-security]: Understanding Zcash Security ([video](https://www.youtube.com/watch?v=f6UToqiIdeY), [slides](https://raw.githubusercontent.com/daira/zcash-security/main/zcash-security.pdf)). Presentation by Daira-Emma Hopwood at Zcon3. [^pq-zcash]: Post-Quantum Zcash ([video](https://www.youtube.com/watch?v=T2B5f297d-Y), [slides](https://docs.google.com/presentation/d/1BHBiSOEO5zt40KWBbRXVMGIIuAcT2hfPWZQ3pT_8tm8/edit?slide=id.g335164f3026_0_113#slide=id.g335164f3026_0_113)). Presentation by Daira-Emma Hopwood at ZconVI. -[^BHT1997]: [Quantum Algorithm for the Collision Problem. Gilles Brassard, Peter Høyer, and Alain Tapp.](https://arxiv.org/abs/quant-ph/9705002) +[^BHT1997]: [Quantum Algorithm for the Collision Problem. Gilles Brassard, Peter Høyer, and Alain Tapp.](https://arxiv.org/abs/quant-ph/9705002) Also published in LATIN 1998, LNCS vol. 1380, pp. 163–169. [^vOW1999]: [Parallel collision search with cryptanalytic applications. Paul C. van Oorschot and Michael Wiener.](https://link.springer.com/article/10.1007/PL00003816) -[^Bernstein2009]: [Cost analysis of hash collisions: Will quantum computers make SHARCS obsolete? Daniel J. Bernstein.](https://cr.yp.to/hash/collisioncost-20090517.pdf) +[^Bernstein2009]: [Cost analysis of hash collisions: Will quantum computers make SHARCS obsolete? Daniel J. Bernstein.](https://cr.yp.to/hash/collisioncost-20090517.pdf) Presented at SHARCS 2009. + +[^BLAKE3]: [BLAKE3: One Function, Fast Everywhere. Jack O'Connor, Jean-Philippe Aumasson, Samuel Neves, and Zooko Wilcox, 2020.](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf) See § 2.1.2 for the `derive_key` mode. + +[^Maurer2002]: [Indistinguishability of Random Systems. Ueli Maurer.](https://crypto.ethz.ch/publications/files/Maurer02.pdf) Also published in Advances in Cryptology — EUROCRYPT 2002, LNCS vol. 2332, pp. 110–132. + +[^Unruh2015]: [Computationally binding quantum commitments. Dominique Unruh.](https://eprint.iacr.org/2015/361) Also published in EUROCRYPT 2016, LNCS vol. 9666. -[^Unruh2015]: [Computationally binding quantum commitments. Dominique Unruh.](https://eprint.iacr.org/2015/361) +[^Unruh2016]: [Collapse-binding quantum commitments without random oracles. Dominique Unruh.](https://eprint.iacr.org/2016/508) Also published in ASIACRYPT 2016, LNCS vol. 10032. -[^Unruh2016]: [Collapse-binding quantum commitments without random oracles. Dominique Unruh.](https://eprint.iacr.org/2016/508) +[^CBHSU2017]: [Post-quantum security of the sponge construction. Jan Czajkowski, Leon Groot Bruinderink, Andreas Hülsing, Christian Schaffner, and Dominique Unruh.](https://eprint.iacr.org/2017/771) Also published in PQCrypto 2018, LNCS vol. 10786. -[^CBHSU2017]: [Post-quantum security of the sponge construction. Jan Czajkowski, Leon Groot Bruinderink, Andreas Hülsing, Christian Schaffner, and Dominique Unruh.](https://eprint.iacr.org/2017/771) +[^Fehr2018]: [Classical Proofs for the Quantum Collapsing Property of Classical Hash Functions. Serge Fehr.](https://eprint.iacr.org/2018/887) Also published in TCC 2018, LNCS vol. 11240, pp. 315–338. -[^CMSZ2021]: [Post-Quantum Succinct Arguments: Breaking the Quantum Rewinding Barrier. Alessandro Chiesa, Fermi Ma, Nicholas Spooner, and Mark Zhandr.](https://eprint.iacr.org/2021/334) +[^Zhandry2018]: [How to Record Quantum Queries, and Applications to Quantum Indifferentiability. Mark Zhandry.](https://eprint.iacr.org/2018/276) Also published in CRYPTO 2019, LNCS vol. 11693. + +[^CFHL2021]: [On the Compressed-Oracle Technique, and Post-Quantum Security of Proofs of Sequential Work. Kai-Min Chung, Serge Fehr, Yu-Hsuan Huang, and Tai-Ning Liao.](https://eprint.iacr.org/2020/1305). Also published in EUROCRYPT 2021, LNCS vol. 12826. + +[^CMSZ2021]: [Post-Quantum Succinct Arguments: Breaking the Quantum Rewinding Barrier. Alessandro Chiesa, Fermi Ma, Nicholas Spooner, and Mark Zhandr.](https://eprint.iacr.org/2021/334) Also published in FOCS 2021. + +[^GM2022]: [Collapseability of Tree Hashes. Aldo Gunsing and Bart Mennink.](https://eprint.iacr.org/2022/248) Also published in PQCrypto 2020, LNCS vol. 12100, pp. 524–544. [^CDDGS2025]: [Quantum Rewinding for IOP-Based Succinct Arguments. Alessandro Chiesa, Marcel Dall'Agnol, Zijing Di, Ziyi Guan, and Nicholas Spooner.](https://eprint.iacr.org/2025/947) [^ACMT2025]: [The Sponge is Quantum Indifferentiable. Gorjan Alagic, Joseph Carolan, Christian Majenz, and Saliha Tokat.](https://eprint.iacr.org/2025/731) + +[^Google2025]: [Securing Elliptic Curve Cryptocurrencies against Quantum Vulnerabilities: Resource Estimates and Mitigations. Ryan Babbush, Adam Zalcman, Craig Gidney, Michael Broughton, Tanuj Khattar, Hartmut Neven, Thiago Bergamaschi, Justin Drake, and Dan Boneh](https://quantumai.google/static/site-assets/downloads/cryptocurrency-whitepaper.pdf)