diff --git a/README.rst b/README.rst index 929608d08..18edc0e01 100644 --- a/README.rst +++ b/README.rst @@ -131,6 +131,7 @@ Released ZIPs 252 Deployment of the NU5 Network Upgrade Final 253 Deployment of the NU6 Network Upgrade Final 255 Deployment of the NU6.1 Network Upgrade Proposed + 257 Deployment of the Orchard Temporary Vulnerability Mitigation and NU6.2 Network Upgrade Proposed 271 Dev Fund Extension and One-Time Disbursement Proposed 300 Cross-chain Atomic Transactions Proposed 301 Zcash Stratum Protocol Active @@ -144,7 +145,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 + 2005 Ironwood Quantum Recoverability Proposed Draft ZIPs @@ -184,6 +185,7 @@ written. 240 Standard Transaction Rules Reserved zips#648 245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft zips#384 246 Digests for the Version 6 Transaction Format Draft + 258 Deployment of the NU6.3 Network Upgrade Draft 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 @@ -234,6 +236,7 @@ be deleted. draft-ecc-authenticated-reply-addrs Authenticated Reply Addresses zips#1230 draft-ecc-onchain-accountable-voting On-chain Accountable Voting draft-str4d-orchard-balance-proof Air drops, Proof-of-Balance, and Stake-weighted Polling zips#1229 + draft-zodl-valargroup-ironwood-txformat Version 6 Transaction Format Withdrawn, Rejected, or Obsolete ZIPs @@ -333,6 +336,8 @@ Index of ZIPs 253 Deployment of the NU6 Network Upgrade Final 254 Deployment of the NU7 Network Upgrade (Withdrawn) Withdrawn 255 Deployment of the NU6.1 Network Upgrade Proposed + 257 Deployment of the Orchard Temporary Vulnerability Mitigation and NU6.2 Network Upgrade Proposed + 258 Deployment of the NU6.3 Network Upgrade Draft 260 Extending Block Messages with Additional Authentication Data Reserved 270 Key Rotation for Tracked Signing Keys Reserved 271 Dev Fund Extension and One-Time Disbursement Proposed @@ -389,7 +394,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 Orchard Quantum Recoverability Proposed + 2005 Ironwood 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/render.sh b/render.sh index e499e0990..4ff61157c 100755 --- a/render.sh +++ b/render.sh @@ -59,7 +59,13 @@ cat <( # Not actually MathJax. KaTeX is compatible if we use the right headers. pandoc --mathjax --from=markdown --to=html "${inputfile}" --output="${outputfile}.temp" else - multimarkdown ${inputfile} -o "${outputfile}.temp" + cat "${inputfile}" \ + | sed 's|[\][$]|💲|g; + s|[$]\([.,:;!?-][^ $]\)|💲\1|g; + s|[$]\([.,:;!?-]\)|\\kern-0.05em\\textsf{\\small \1}$|g; + s|[$]—|\\kern-0.3em$ —|g; + s|💲|$|g' \ + | multimarkdown -o "${outputfile}.temp" fi # Both pandoc and multimarkdown just output the HTML body. diff --git a/static/assets/fonts/OFL.txt b/static/assets/fonts/OFL.txt new file mode 100644 index 000000000..2478ae502 --- /dev/null +++ b/static/assets/fonts/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2010 The Raleway Project Authors (impallari@gmail.com), with Reserved Font Name "Raleway". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/static/assets/fonts/Raleway-Italic-VariableFont_wght.ttf b/static/assets/fonts/Raleway-Italic-VariableFont_wght.ttf new file mode 100644 index 000000000..64f5882c7 Binary files /dev/null and b/static/assets/fonts/Raleway-Italic-VariableFont_wght.ttf differ diff --git a/static/assets/fonts/Raleway-VariableFont_wght.ttf b/static/assets/fonts/Raleway-VariableFont_wght.ttf new file mode 100644 index 000000000..8aa222662 Binary files /dev/null and b/static/assets/fonts/Raleway-VariableFont_wght.ttf differ diff --git a/static/css/style.css b/static/css/style.css index 8ffef858c..5ed7f237d 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -307,6 +307,20 @@ div.warning + p { font-style: normal; } +@font-face { + font-family: raleway; + src: url('../assets/fonts/Raleway-VariableFont_wght.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: ralewayitalic; + src: url('../assets/fonts/Raleway-Italic-VariableFont_wght.ttf') format('truetype'); + font-weight: normal; + font-style: italic; +} + body, body > section { margin: 0 auto; padding: 1.5rem 0 3rem; @@ -461,7 +475,16 @@ pre { } .katex { - font-size: 1.21em; + font-size: 1.2em; +} + +/* Render \textit{...} inside KaTeX in the body font, so slanted identifiers + in math (e.g. pool names such as IronwoodPool) match the slanted look of + Markdown emphasis *foo* in surrounding text. */ +.katex .textit { + font-family: 'ralewayitalic', Arial, 'Helvetica Neue', Helvetica, sans-serif; + font-style: italic; + font-size: 0.92em; } div.math { @@ -569,6 +592,12 @@ a.footnote-ref sup, a.footnote sup { } /* }}} md-specific */ +em { + font-family: 'ralewayitalic',Arial,Helvetica Neue,Helvetica,sans-serif; + font-weight: 720; + font-stretch: 85%; +} + strong, b { font-family: 'robotomedium',Arial,Helvetica Neue,Helvetica,sans-serif; font-weight: normal; diff --git a/zips/draft-zodl-valargroup-ironwood-txformat.md b/zips/draft-zodl-valargroup-ironwood-txformat.md new file mode 100644 index 000000000..8506741e1 --- /dev/null +++ b/zips/draft-zodl-valargroup-ironwood-txformat.md @@ -0,0 +1,582 @@ + ZIP: XXX + Title: Version 6 Transaction Format + Owners: Daira-Emma Hopwood + ‹other ZODL / Valar Group authors› + Status: Draft + Category: Consensus + Created: 2026-06-13 + License: MIT + Discussions-To: ‹https://github.com/zcash/zips/issues/XXXX› + + +# 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 term "network upgrade" in this document is to be interpreted as described in +ZIP 200. [^zip-0200] + +The character § is used when referring to sections of the Zcash Protocol +Specification. [^protocol] + +The terms "Mainnet" and "Testnet" are to be interpreted as described in § 3.12 +‘Mainnet and Testnet’. [^protocol-networks] + +The term "Recovery Protocol" is to be interpreted as described in [^zip-2005]. + +The terms below are to be interpreted as follows: + +Orchard protocol (or Orchard shielded protocol) +: The shared cryptographic design that supports the *Orchard pool* and the + *Ironwood pool*, including the Pallas and Vesta curves, the Sinsemilla hash, the Action + circuit (as modified by [^draft-zodl-valargroup-action-circuit-update]), the + note, note commitment, nullifier, and key constructions, and the note encryption + (as modified by [^zip-2005]) used for these two pools. + +*Orchard pool* (or Orchard shielded pool) +: The value pool, with its own note commitment tree, anchor, and chain value pool + balance, that was introduced by ZIP 224 [^zip-0224]. + +*Ironwood pool* (or Ironwood shielded pool) +: A new value pool of the Orchard protocol, introduced by this ZIP, with its own note + commitment tree, anchor, and chain value pool balance, distinct from the + *Orchard pool*. + + +# Abstract + +This ZIP defines version 6 of the Zcash transaction format, to be activated at NU6.3 +[^zip-0258]. + +NU6.3 [^draft-zodl-valargroup-deploy-nu6.3] introduces the Ironwood shielded pool, an +Orchard-protocol successor to the *Orchard pool*, that ensures quantum recoverability +[^zip-2005] and has supply integrity supported from the start by formal verification +efforts [^zcash-ironwood]. + +This requires a new transaction version that can hold an **Ironwood component**: +a second Orchard-protocol shielded component that commits to, and spends from, the +Ironwood shielded pool, rather than the *Orchard pool*. The Ironwood component reuses +the Orchard Action encoding and proof system unchanged. This ZIP defines the +corresponding txid, signature-hash, and block-commitment changes. + +The addition of the *Ironwood pool* does not change address structures or encodings. +At the protocol level, Orchard spending-key and viewing-key material grants authority +to spend or view notes in both the *Orchard* and *Ironwood pools*. However, NU6.3 enforces +that outputs to the *Orchard pool* are sent to an Orchard-protocol-level address for +which the transaction creator can authorize spends. The intent is that transfers +between users will automatically create notes in the *Ironwood pool*. The address +restriction discourages economic activity between users within the *Orchard pool*, and +encourages faster migration to the *Ironwood pool*. + +This ZIP specifies only the transaction format and its associated hashing. The Action +circuit changes needed to restrict address usage within the *Orchard pool* are specified +in [^draft-zodl-valargroup-action-circuit-update], and implications for wallets are +discussed in [^draft-zodl-valargroup-ironwood-migration]. Activation parameters are +specified in the NU6.3 deployment ZIP [^draft-zodl-valargroup-deploy-nu6.3]. + + +# Motivation + +The main purpose of the NU6.3 network upgrade is to bolster confidence in Zcash's supply +integrity, after the discovery and remediation of the Orchard soundness vulnerability +described in [^zip-0257]. The turnstile mechanism [^zip-0209] ensures that the overall +ZEC supply is bounded. However, since a substantial portion of ZEC was in the +*Orchard pool* at the time this vulnerability was remediated, it is necessary to take +further steps to ensure confidence in the supply by migrating funds to a new pool. + +All funds in the *Ironwood pool* will be **quantum-recoverable** [^zip-2005]. +The existing Zcash shielded protocols are dependent on the hardness of finding +discrete logarithms; an adversary who can do so (via quantum computers or otherwise) +would be able to steal or forge funds. In the event of needing to disable these +protocols in order to prevent such attacks, it will be possible to use a Recovery +Protocol to recover funds from the *Ironwood pool*. This Recovery Protocol is expected +to remain secure against discrete-log-breaking and quantum adversaries. This change +does not by itself make Zcash secure against attacks using quantum computers, but is +a necessary and substantial step toward that goal. + +Recovery would not be possible for funds still in the *Sprout*, *Sapling*, or +*Orchard pools*; all such funds would be inaccessible after their respective +protocols are disabled. They should be migrated to the *Ironwood pool* in +order to take advantage of this change. + +The version 6 transaction format also changes the authorization structure for all +supported shielded pools (*Sapling*, *Orchard*, and *Ironwood*) so that anchors are +considered to be authorizing data rather than effecting data. This allows a transaction +to be pre-authorized and its proofs computed independently after choosing an anchor, +and also improves opportunities for parallelism in transaction creation. + + +# Privacy Implications + +The turnstile mechanism reveals the amounts in each transaction that cross between pools, +including the amounts migrated into the *Ironwood pool*. This is considered in full detail +in [^draft-zodl-valargroup-ironwood-migration]. + +There is no reason to believe that the soundness vulnerability described in [^zip-0257] +could have led to any compromise of key material associated with existing addresses. +Independent of the soundness bug, we recommend address rotation for quantum privacy +implications discussed in [^zip-2005]. + + +# Requirements + +Changes relative to v5 transactions should be minimized. + +The version 6 transaction format must be able to carry an *Ironwood-pool* component in +addition to transparent-pool, *Sapling-pool*, and *Orchard-pool* components similar to +those in a version 5 transaction. + +The Ironwood component must reuse the Orchard Action design and component encoding, so +that implementation is shared between them to the maximum extent possible. + +The transaction identifier, signature hash, and authorizing-data commitment must +commit to the *Ironwood-pool* component when it is present, using personalizations +distinct from those used for the *Orchard-pool* component. + +The changes to the authorization structure must support pre-authorizing transactions +using spending key material, and later updating the anchor and proofs (for all +supported shielded pools). + +Personalizations for nodes in the digest tree must be changed when what is hashed at +that node changes. + +The `flags` fields in the *Orchard-pool* and *Ironwood-pool* components must support +encoding an indication of whether outputs to the *Orchard pool* are required to use +a protocol-level address for which the transaction creator can authorize spends. + +The one known Orchard-supporting hardware wallet, Keystone, must continue to be able to +sign v5 tx format Orchard -> Transparent unshielding transactions, without firmware update. + +# Non-requirements + +This ZIP does not define the Action circuit update for NU6.3 or its `disableCrossAddress` +constraint (see [^draft-zodl-valargroup-action-circuit-update]), the activation height +or consensus branch ID (see [^draft-zodl-valargroup-deploy-nu6.3]), or wallet behaviour associated with migration +to Ironwood (see [^draft-zodl-valargroup-ironwood-migration]). + +The v6 transaction format need not support ZSAs, the `zip233Amount` field, the explicit +`fee` field, or per-transparent-input sighash information that appeared in the withdrawn +ZIP 230 [^zip-0230], or those features and other extensibility affordances planned for +ZIP 248 [^zip-0248]. + +The value 6 for the transaction version number need not avoid collisions with the +withdrawn ZIP 230 or with the current draft of ZIP 248. + + +# Specification + +## Transaction Format + +A version 6 transaction is encoded as follows. Fields up to and including the Orchard +component are as in the version 5 format [^zip-0225], except as noted; the Ironwood component +is new. + +| Note | Bytes | Name | Data Type | Description +| ---- | ------------------------------- | ------------------------ | -------------------------------------- | ----------- +| **Common Transaction Fields (unchanged from v5)** ||||| +| | $4$ | `header` | `uint32` | Contains the `fOverwintered` flag (bit 31, always set) and `version` (bits 30 .. 0), which MUST be `6`. +| | $4$ | `nVersionGroupId` | `uint32` | Version group ID (nonzero); the version 6 value fixed in [^draft-zodl-valargroup-deploy-nu6.3]. +| | $4$ | `nConsensusBranchId` | `uint32` | Consensus branch ID; MUST be the NU6.3 branch ID [^draft-zodl-valargroup-deploy-nu6.3]. +| | $4$ | `lock_time` | `uint32` | Unix-epoch UTC time or block height, encoded as in Bitcoin. +| | $4$ | `nExpiryHeight` | `uint32` | A block height in {1 .. 499999999} after which the transaction will expire, or 0 to disable expiry. [^zip-0203] +| **Transparent Transaction Fields (unchanged from v5)** ||||| +| | `varies` | `tx_in_count` | `compactSize` | Number of transparent inputs in `tx_in`. +| | `varies` | `tx_in` | `tx_in` | Transparent inputs, encoded as in Bitcoin. +| | `varies` | `tx_out_count` | `compactSize` | Number of transparent outputs in `tx_out`. +| | `varies` | `tx_out` | `tx_out` | Transparent outputs, encoded as in Bitcoin. +| **Sapling Transaction Fields (unchanged from v5)** ||||| +| | `varies` | `nSpendsSapling` | `compactSize` | Number of Sapling Spend descriptions in `vSpendsSapling`. +| | $96\,\cdot$ `nSpendsSapling` | `vSpendsSapling` | `SpendDescriptionV5[nSpendsSapling]` | Sapling Spend descriptions, encoded per § 7.3 ‘Spend Description Encoding and Consensus’. +| | `varies` | `nOutputsSapling` | `compactSize` | Number of Sapling Output descriptions in `vOutputsSapling`. +| | $756\,\cdot$ `nOutputsSapling` | `vOutputsSapling` | `OutputDescriptionV5[nOutputsSapling]` | Sapling Output descriptions, encoded per § 7.4 ‘Output Description Encoding and Consensus’. +| † | $8$ | `valueBalanceSapling` | `int64` | The net value of Sapling Spends minus Outputs. +| ‡ | $32$ | `anchorSapling` | `byte[32]` | A root of the Sapling note commitment tree at some block height in the past. +| | $192\,\cdot$ `nSpendsSapling` | `vSpendProofsSapling` | `byte[192 * nSpendsSapling]` | Encodings of the zk-SNARK proofs for each Sapling Spend. +| | $64\,\cdot$ `nSpendsSapling` | `vSpendAuthSigsSapling` | `byte[64 * nSpendsSapling]` | Authorizing signatures for each Sapling Spend. +| | $192\,\cdot$ `nOutputsSapling` | `vOutputProofsSapling` | `byte[192 * nOutputsSapling]` | Encodings of the zk-SNARK proofs for each Sapling Output. +| † | $64$ | `bindingSigSapling` | `byte[64]` | A Sapling binding signature on the SIGHASH transaction hash. +| **Orchard Transaction Fields** ||||| +| | `varies` | `nActionsOrchard` | `compactSize` | The number of Orchard Action descriptions in `vActionsOrchard`. +| | $820\,\cdot$ `nActionsOrchard` | `vActionsOrchard` | `OrchardAction[nActionsOrchard]` | A sequence of Orchard Action descriptions, encoded per § 7.5 ‘Action Description Encoding and Consensus’. +| § | $1$ | `flagsOrchard` | `byte` | An 8-bit value representing a set of flags. From LSB to MSB: `enableSpends`, `enableOutputs`, `enableCrossAddress` (new at NU6.3); the remaining bits MUST be 0. +| § | $8$ | `valueBalanceOrchard` | `int64` | The net value of Orchard spends minus outputs. +| § | $32$ | `anchorOrchard` | `byte[32]` | A root of the Orchard note commitment tree at some block height in the past. +| § | `varies` | `sizeProofsOrchard` | `compactSize` | Length in bytes of `proofsOrchard`. Value is `2720 + 2272 * nActionsOrchard`. +| § | `sizeProofsOrchard` | `proofsOrchard` | `byte[sizeProofsOrchard]` | Encoding of aggregated zk-SNARK proofs for Orchard Actions. +| | $64\,\cdot$ `nActionsOrchard` | `vSpendAuthSigsOrchard` | `byte[64 * nActionsOrchard]` | Authorizing signatures for each Orchard Action. +| § | $64$ | `bindingSigOrchard` | `byte[64]` | An Orchard binding signature on the SIGHASH transaction hash. +| **Ironwood Transaction Fields (new)** ||||| +| | `varies` | `nActionsIronwood` | `compactSize` | The number of Ironwood Action descriptions in `vActionsIronwood`. +| | $820\,\cdot$ `nActionsIronwood` | `vActionsIronwood` | `OrchardAction[nActionsIronwood]` | A sequence of Ironwood Action descriptions, using the same encoding as Orchard Actions (§ 7.5). +| ◊ | $1$ | `flagsIronwood` | `byte` | The same layout as `flagsOrchard`, including `enableCrossAddress` at bit 2; the remaining bits MUST be 0. +| ◊ | $8$ | `valueBalanceIronwood` | `int64` | The net value of Ironwood spends minus outputs. +| ◊ | $32$ | `anchorIronwood` | `byte[32]` | A root of the **Ironwood** note commitment tree at some block height in the past. +| ◊ | `varies` | `sizeProofsIronwood` | `compactSize` | Length in bytes of `proofsIronwood`. Value is `2720 + 2272 * nActionsIronwood`. +| ◊ | `sizeProofsIronwood` | `proofsIronwood` | `byte[sizeProofsIronwood]` | Encoding of aggregated zk-SNARK proofs for Ironwood Actions. +| | $64\,\cdot$ `nActionsIronwood` | `vSpendAuthSigsIronwood` | `byte[64 * nActionsIronwood]` | Authorizing signatures for each Ironwood Action. +| ◊ | $64$ | `bindingSigIronwood` | `byte[64]` | An Ironwood binding signature on the SIGHASH transaction hash. + +Fields marked in the Note column are conditionally present: + +| Note | Description +| ---- | ----------- +| † | `valueBalanceSapling` and `bindingSigSapling` are present if and only if `nSpendsSapling + nOutputsSapling > 0`. If `valueBalanceSapling` is not present, it is taken to be 0. +| ‡ | `anchorSapling` is present if and only if `nSpendsSapling > 0`. +| § | `flagsOrchard`, `valueBalanceOrchard`, `anchorOrchard`, `sizeProofsOrchard`, `proofsOrchard`, and `bindingSigOrchard` are present if and only if `nActionsOrchard > 0`. If `valueBalanceOrchard` is not present, it is taken to be 0. +| ◊ | `flagsIronwood`, `valueBalanceIronwood`, `anchorIronwood`, `sizeProofsIronwood`, `proofsIronwood`, and `bindingSigIronwood` are present if and only if `nActionsIronwood > 0`. If `valueBalanceIronwood` is not present, it is taken to be 0. + +The encoding of the transparent and Sapling fields is unchanged from version 5 +[^zip-0225]. Ironwood Action descriptions use the same `OrchardAction` encoding as +Orchard Action descriptions. Every *Ironwood-pool* output note uses the quantum-recoverable +note plaintext format (lead byte `0x03`) defined in ZIP 2005 [^zip-2005]; no *Orchard-pool* +output note uses that format. This is the only note-level distinction between the two pools. + +Two `flagsOrchard` bits have been renamed relative to version 5: `enableSpendsOrchard` → +`enableSpends` and `enableOutputsOrchard` → `enableOutputs`. In version 6 these bits +—together with `enableCrossAddress`— are defined with the same meaning in both `flagsOrchard` +and `flagsIronwood`, so the previous `...Orchard` suffix would be misleading. + +## Consensus Rules + +* `nVersionGroupId` MUST equal the version 6 version group ID, and `nConsensusBranchId` + MUST equal the NU6.3 consensus branch ID, both defined in [^draft-zodl-valargroup-deploy-nu6.3]. + +* The proofs in `proofsOrchard` and the signatures in `vSpendAuthSigsOrchard` each + correspond 1:1 to the elements of `vActionsOrchard`, in the same order; likewise the + proofs in `proofsIronwood` and the signatures in `vSpendAuthSigsIronwood` to the + elements of `vActionsIronwood`. (Conditional presence of fields is given in the format + table above.) + +* In each of `flagsOrchard` and `flagsIronwood`: + * Bits 3..7 inclusive MUST be 0. + * The semantics of the `enableSpends` and `enableOutputs` bits are as in ZIP 224 [^zip-0224]. + * The `enableCrossAddress` bit is specified in [^draft-zodl-valargroup-action-circuit-update]. + Before NU6.3 this bit of `flagsOrchard` was reserved as 0 in v5 transactions. + +* For coinbase transactions, + * The `enableSpends` bit of `flagsIronwood` MUST be 0. + +* The `anchorOrchard` field refers to the Orchard note commitment tree, and the + `anchorIronwood` field to the Ironwood note commitment tree. The *Orchard* and + *Ironwood pools* have separate, independent note commitment trees and nullifier sets. + +Version 4, version 5, and version 6 transactions are all valid from NU6.3 activation onward; +this ZIP defines only the version 6 format (the version 4 and version 5 formats are +unchanged). The NU6.3 consensus rules on Orchard actions apply regardless of transaction +version. In particular, the Orchard-protocol cross-address restriction is enforced for every +*Orchard-pool* Action mined from NU6.3 onward [^draft-zodl-valargroup-action-circuit-update], +so that it cannot be bypassed by using a version 5 transaction. + +See [^draft-zodl-valargroup-deploy-nu6.3] for additional consensus requirements that apply +to **all** transactions from NU6.3 onward, regardless of transaction version. (Briefly and +non-normatively, these are that coinbase transactions must have an empty Orchard component; +that the `enableCrossAddress` bit of `flagsOrchard` must be 0; and that +$\mathsf{v}^{\textit{OrchardPoolBalance}}$ must be nonnegative.) + +## Transaction Identifiers, Signature Hashing, and Block Commitments + +Version 6 transaction identifiers (txids), authorizing-data commitments ("auth digests"), +and signature hashes are computed as in ZIP 244 [^zip-0244], with two changes: an +**Ironwood component digest** is added, and for version 6 the Sapling, Orchard and Ironwood anchors +move from effecting data to authorizing data. The version 5 algorithm is unchanged. + +### Ironwood component digest + +Relative to the txid digest for v5 transactions [^zip-0244-txiddigest], the version 6 +txid digest adds an Ironwood component digest as the last child, after the Orchard component +digest: + + txid_digest_v6 = BLAKE2b-256("ZcashTxHash_" || consensusBranchId, + header_digest || transparent_digest || sapling_digest_v6 || + orchard_digest_v6 || ironwood_digest_v6) + +Relative to the auth digest for v5 transactions [^zip-0244-authorizingdatacommitment], the +version 6 auth digest adds an Ironwood auth digest as the last child, after the Orchard one: + + auth_digest_v6 = BLAKE2b-256("ZTxAuthHash_" || consensusBranchId, + transparent_auth_digest || sapling_auth_digest_v6 || + orchard_auth_digest_v6 || ironwood_auth_digest_v6) + +### Anchor commitment (version 6) + +In version 5, the Sapling anchor (encoded redundantly as `anchor` in each +`sapling_spends_noncompact_digest`) and the Orchard anchor (`anchorOrchard` in `orchard_digest`) +are part of the **effecting data**: they are committed to in `txid_digest`, while the Sapling and +Orchard auth digests commit only to proofs and signatures [^zip-0244-authorizingdatacommitment]. + +In version 6, for Sapling, Orchard, and Ironwood components, the anchor is instead part of the +**authorizing data**. Relative to ZIP 244, for version 6 transactions: + +- `sapling_spends_noncompact_digest_v6`, `orchard_digest_v6`, and `ironwood_digest_v6` omit the anchor. +- `sapling_auth_digest_v6`, `orchard_auth_digest_v6`, and `ironwood_auth_digest_v6` additionally commit + to `anchorSapling`, `anchorOrchard`, or `anchorIronwood` respectively, after the existing fields. + +This lets the anchor be updated (re-anchored to a more recent note commitment tree root) without +changing the transaction ID, while the proofs still bind to the specific anchor used. + +`ironwood_digest_v6` and `ironwood_auth_digest_v6` are computed with *the same structure* as +`orchard_digest_v6` and `orchard_auth_digest_v6`, but with Ironwood-specific 16-byte BLAKE2b-256 +personalizations at each node. Also, distinct personalizations are used for Sapling and Orchard nodes +where what is directly hashed has been affected as a result of moving the anchor commitments to auth +data, as follows: + +| Node | v5 personalization | v6 personalization | Comment for v6 | +|:--------------------------------------- | ------------------ | ------------------ | ------------------------- | +| $\hspace{22em}$ **Sapling** |||| +| `sapling_digest[_v6]` | `ZTxIdSaplingHash` | `ZTxIdSaplingHash` | not changed directly | +| `sapling_spends_digest` | `ZTxIdSSpendsHash` | `ZTxIdSSpendsHash` | unchanged | +| `sapling_spends_compact_digest` | `ZTxIdSSpendCHash` | `ZTxIdSSpendCHash` | unchanged | +| `sapling_spends_noncompact_digest[_v6]` | `ZTxIdSSpendNHash` | `ZTxIdSSpendNH_v6` | omits `anchor` | +| `sapling_auth_digest[_v6]` | `ZTxAuthSapliHash` | `ZTxAuthSapliH_v6` | includes `anchorSapling` | +| $\hspace{22em}$ **Orchard** |||| +| `orchard_digest[_v6]` | `ZTxIdOrchardHash` | `ZTxIdOrchardH_v6` | omits `anchorOrchard` | +| `orchard_actions_compact_digest` | `ZTxIdOrcActCHash` | `ZTxIdOrcActCHash` | unchanged | +| `orchard_actions_memos_digest` | `ZTxIdOrcActMHash` | `ZTxIdOrcActMHash` | unchanged | +| `orchard_actions_noncompact_digest` | `ZTxIdOrcActNHash` | `ZTxIdOrcActNHash` | unchanged | +| `orchard_auth_digest[_v6]` | `ZTxAuthOrchaHash` | `ZTxAuthOrchaH_v6` | includes `anchorOrchard` | +| $\hspace{22em}$ **Ironwood** |||| +| `ironwood_digest_v6` | n/a | `ZTxIdIronwd_H_v6` | omits `anchorIronwood` | +| `ironwood_actions_compact_digest_v6` | n/a | `ZTxIdIrnActCH_v6` | | +| `ironwood_actions_memos_digest_v6` | n/a | `ZTxIdIrnActMH_v6` | | +| `ironwood_actions_noncompact_digest_v6` | n/a | `ZTxIdIrnActNH_v6` | | +| `ironwood_auth_digest_v6` | n/a | `ZTxAuthIrnwdH_v6` | includes `anchorIronwood` | + +As in the case of Sapling and Orchard, when a version 6 transaction has no Ironwood actions, +`ironwood_digest_v6` and `ironwood_auth_digest_v6` are the hashes of empty input under the component +and auth personalizations respectively, i.e. `BLAKE2b-256("ZTxIdIronwd_H_v6", [])` and +`BLAKE2b-256("ZTxAuthIrnwdH_v6", [])`, which are distinct from the Orchard empty-component digests. + +### Summary of the resulting digest structure + +Below, `(*)` indicates a node that is directly changed relative to v5, and `(+)` indicates a node +that is added relative to v5. + +The txid digest structure becomes: + + txid_digest_v6 + ├── header_digest + ├── transparent_digest + │   ├── prevouts_digest + │   ├── sequence_digest + │   └── outputs_digest + ├── sapling_digest_v6 + │   ├── sapling_spends_digest_v6 + │   │   ├── sapling_spends_compact_digest + │   │   └── sapling_spends_noncompact_digest_v6 (*) + │   │ ├── cv + │   │ └── rk + │   ├── sapling_outputs_digest + │   │   ├── sapling_outputs_compact_digest + │   │   ├── sapling_outputs_memos_digest + │   │   └── sapling_outputs_noncompact_digest + │   └── valueBalance + ├── orchard_digest_v6 (*) + │   ├── orchard_actions_compact_digest + │   ├── orchard_actions_memos_digest + │   ├── orchard_actions_noncompact_digest + │   ├── flagsOrchard + │   └── valueBalanceOrchard + └── ironwood_digest_v6 (+) +    ├── ironwood_actions_compact_digest_v6 +    ├── ironwood_actions_memos_digest_v6 +    ├── ironwood_actions_noncompact_digest_v6 +    ├── flagsIronwood +    └── valueBalanceIronwood + +The auth digest structure becomes: + + auth_digest_v6 + ├── transparent_scripts_digest + ├── sapling_auth_digest_v6 (*) + │   ├── vSpendProofsSapling + │ ├── vSpendAuthSigsSapling + │ ├── vOutputProofsSapling + │ ├── bindingSigSapling + │ └── anchorSapling (+) + ├── orchard_auth_digest_v6 (*) + │ ├── proofsOrchard + │ ├── vSpendAuthSigsOrchard + │ ├── bindingSigOrchard + │ └── anchorOrchard (+) + └── ironwood_auth_digest_v6 (+) + ├── proofsIronwood + ├── vSpendAuthSigsIronwood + ├── bindingSigIronwood + └── anchorIronwood + +Note that the nodes under each of `sapling_digest_v6`, `orchard_digest_v6`, `ironwood_digest_v6`, +and their `auth_digest`s are present only if the corresponding component is non-empty. + +### Block commitments + +The `hashAuthDataRoot` component of `hashBlockCommitments` [^zip-0244] incorporates the version 6 auth +digest — which now includes the Ironwood auth digest, and (per the change above) the anchors — with +no further structural change. + + +## Changes to ZIP 221 + +The history tree that commits to chain history [^zip-0221] gains Ironwood metadata, exactly +as it gained Orchard metadata at NU5. The new fields are computed and aggregated identically +to the corresponding `...Orchard...` fields. + +In the "Tree Node specification" section, after field 14 `nOrchardTxCount`, add: + +> 15. [NU6.3 onward] `hashEarliestIronwoodRoot` +> +> Leaf node +> Calculated as the note commitment root of the final Ironwood treestate +> (similar to `hashEarliestOrchardRoot`). +> +> Internal or root node +> Inherited from the left child. +> +> Serialized as `char[32]`. +> +> 16. [NU6.3 onward] `hashLatestIronwoodRoot` +> +> Leaf node +> Calculated as the note commitment root of the final Ironwood treestate +> (similar to `hashLatestOrchardRoot`). +> +> Internal or root node +> Inherited from the right child. +> +> Serialized as `char[32]`. +> +> 17. [NU6.3 onward] `nIronwoodTxCount` +> +> Leaf node +> The number of transactions in the leaf block where `vActionsIronwood` +> is non-empty. +> +> Internal or root node +> The sum of the `nIronwoodTxCount` field of both children. +> +> Serialized as `CompactSize uint`. + +Replace + +> The fields marked "[NU5 onward]" are omitted before NU5 activation [^zip-0252]. +> +> Each node, when serialized, is between 147 and 171 bytes long (between 212 and 244 bytes +> after NU5 activation). [...] + +with + +> The fields marked "[NU5 onward]" are omitted before NU5 activation [^zip-0252]. The fields +> marked "[NU6.3 onward]" are omitted before NU6.3 activation. +> +> Each node, when serialized, is between 147 and 171 bytes long (between 212 and 244 bytes +> after NU5 activation, and between 277 and 317 bytes after NU6.3 activation). [...] + +The pseudocode node structure and `serialize` / `make_leaf` / `make_parent` functions are +extended with `hashEarliestIronwoodRoot`, `hashLatestIronwoodRoot`, and `nIronwoodTxCount` +in the same way the "# NU5 only" Orchard fields were added (present iff NU6.3 has activated; +the roots inherited from the left/right child and the count summed, in internal nodes). + +`hashChainHistoryRoot` continues to be the BLAKE2b-256 digest of the serialized root node; +its value changes at NU6.3 only through the added node fields. The `hashBlockCommitments` +header field [^zip-0244] is unaffected beyond this. + +# Rationale + +The main purpose of the NU6.3 network upgrade is to bolster confidence in Zcash's supply +integrity, after the discovery and remediation of the Orchard soundness vulnerability +described in [^zip-0257]. + +The urgency of this motivation called for an accelerated timeline, which necessitated +a high bar for feature inclusion. Therefore, even fairly straightforward improvements +(such as [^zip-2002], which had been "queued" for inclusion in the next transaction format +update), were omitted from this upgrade. + +## Reuse of the Orchard protocol with minimal changes + +Carrying the *Ironwood pool* as a second Orchard-protocol component, rather than defining a +new shielded protocol, keeps the transaction-format and implementation surface small: +the Action encoding, proving system, authorization, and note encryption (modulo the new +note plaintext format defined by [^zip-2005]) are inherited unchanged. The pools are +distinguished by their note commitment trees, nullifier sets, value pool +balances, and component position, not by separate circuits. + +## Separate state + +Giving the *Ironwood pool* its own note commitment tree, anchor, and nullifier set creates +a state boundary from the *Orchard pool*, so that their chain value pool balance can be +accounted for independently. + +## `enableCrossAddress` polarity + +This flag is encoded in the enabled sense (`1` = cross-address transfers enabled, the +normal case for *Ironwood-pool* actions; 0 = action outputs restricted to use the same +protocol-level address as the action's spend), with bit 2 reserved as 0 before NU6.3. +This is backward-compatible: an *Orchard-pool* spend after NU6.3 requires the restricted +state, which is bit 2 = 0 — exactly the value that signers treating bit 2 as a +reserved-zero bit already produce. The in-circuit constraint and the equivalent +internal `disableCrossAddress` instance value are discussed in +[^draft-zodl-valargroup-action-circuit-update]. + + +# Deployment + +This transaction format is deployed at NU6.3. Activation heights, the version 6 version +group ID, and the NU6.3 consensus branch ID are specified in [^draft-zodl-valargroup-deploy-nu6.3]. + + +# Acknowledgements + +We thank the developers of Penumbra [^penumbra] for demonstrating the advantages of +treating the note commitment tree anchor as authorizing data rather than effecting data. + + +# 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 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-chainvalue]: [Zcash Protocol Specification, Version 2025.6.3 [NU6.1] or later. Section 4.17: Chain Value Pool Balances](protocol/protocol.pdf#chainvaluepoolbalances) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0203]: [ZIP 203: Transaction Expiry](zip-0203.rst) + +[^zip-0209]: [ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances](zip-0209.rst) + +[^zip-0221]: [ZIP 221: FlyClient - Consensus-Layer Changes](zip-0221.rst) + +[^zip-0224]: [ZIP 224: Orchard Shielded Protocol](zip-0224.rst) + +[^zip-0225]: [ZIP 225: Version 5 Transaction Format](zip-0225.rst) + +[^zip-0230]: [ZIP 230: Withdrawn Version 6 Transaction Format](zip-0230.rst) + +[^zip-0244]: [ZIP 244: Transaction Identifier Non-Malleability](zip-0244.rst) + +[^zip-0244-txiddigest]: [ZIP 244: Transaction Identifier Non-Malleability — TxId Digest](zip-0244.rst#txid-digest) + +[^zip-0244-authorizingdatacommitment]: [ZIP 244: Transaction Identifier Non-Malleability — Authorizing Data Commitment](zip-0244.rst#authorizing-data-commitment) + +[^zip-0252]: [ZIP 252: Deployment of the NU5 Network Upgrade](zip-0252.rst) + +[^zip-2005]: [ZIP 2005: Ironwood Quantum Recoverability](zip-2005.md) + +[^draft-zodl-valargroup-action-circuit-update]: [NU6.3 Updates to the Orchard-protocol Action Circuit (draft)](draft-zodl-valargroup-action-circuit-update.md) + +[^zip-0248]: ZIP 248: Extensible Transaction Format (unmerged; PR at ) + +[^zip-0257]: [ZIP 257: Deployment of the Orchard Temporary Vulnerability Mitigation and NU6.2 Network Upgrade](zip-0257.md) + +[^zip-2002]: [ZIP 2002: Explicit Fees](zip-2002.rst) + +[^draft-zodl-valargroup-deploy-nu6.3]: [Deployment of the NU6.3 Network Upgrade (draft)](draft-zodl-valargroup-deploy-nu6.3.md) + +[^draft-zodl-valargroup-ironwood-migration]: [Wallet Considerations for NU6.3 and Migration to the Ironwood Pool (draft)](draft-zodl-valargroup-ironwood-migration.md) + +[^zcash-ironwood]: [GitHub repository zcash/ironwood: Formal Verification of the Zcash Protocol and Documentation for the Ironwood Pool](https://github.com/zcash/ironwood) + +[^penumbra]: [The Penumbra Protocol](https://protocol.penumbra.zone/main/index.html) diff --git a/zips/zip-0258.md b/zips/zip-0258.md new file mode 100644 index 000000000..304528ddd --- /dev/null +++ b/zips/zip-0258.md @@ -0,0 +1,186 @@ + + ZIP: 258 + Title: Deployment of the NU6.3 Network Upgrade + Owners: Daira-Emma Hopwood + Status: Draft + Category: Consensus / Network + Created: 2026-06-19 + License: MIT + Discussions-To: + + +# Terminology + +The key words "MUST", "MUST NOT", and "SHOULD" in this document are to be interpreted as +described in BCP 14 [^BCP14] when, and only when, they appear in all capitals. + +The term "network upgrade" in this document is to be interpreted as described in +ZIP 200. [^zip-0200] + +The character § is used when referring to sections of the Zcash Protocol +Specification. [^protocol] + +The terms "Mainnet" and "Testnet" are to be interpreted as described in § 3.12 +‘Mainnet and Testnet’. [^protocol-networks] + +The terms "Orchard protocol", "*Orchard pool*", "*Ironwood pool*", "*Orchard-pool* Action", and +"version 6 transaction" are to be interpreted as described in +[^draft-zodl-valargroup-ironwood-txformat]. + + +# Abstract + +This proposal defines the deployment of the NU6.3 network upgrade, which introduces the +Ironwood shielded pool. The consensus changes for NU6.3 are specified across the version 6 +transaction format [^draft-zodl-valargroup-ironwood-txformat], the Orchard Action circuit +update [^draft-zodl-valargroup-action-circuit-update], ZIP 2005 [^zip-2005], and this ZIP, +which fixes the activation parameters and the consensus rules that gate on NU6.3 activation +regardless of transaction version. + + +# Specification + +## NU6.3 deployment + +The primary sources of information about NU6.3 consensus protocol changes are: + +* The Zcash Protocol Specification [^protocol]. +* ZIP 200: Network Upgrade Mechanism [^zip-0200]. +* The version 6 transaction format [^draft-zodl-valargroup-ironwood-txformat], the Orchard + Action circuit update [^draft-zodl-valargroup-action-circuit-update], and ZIP 2005 + [^zip-2005]. + +The network handshake and peer management mechanisms defined in ZIP 201 [^zip-0201] also +apply to this upgrade. + +The following network upgrade constants [^zip-0200] are defined for the NU6.3 upgrade: + +CONSENSUS_BRANCH_ID +: 0x37A5165B + +ACTIVATION_HEIGHT (NU6.3) +: Testnet: TBD +: Mainnet: TBD + +MIN_NETWORK_PROTOCOL_VERSION (NU6.3) +: Testnet: TBD +: Mainnet: TBD + +The version group ID for version 6 transactions [^draft-zodl-valargroup-ironwood-txformat] is: + +TX_VERSION_GROUP_ID (v6) +: TBD + +For each network (Testnet and Mainnet), nodes compatible with NU6.3 activation on that +network MUST advertise a network protocol version that is greater than or equal to the +MIN_NETWORK_PROTOCOL_VERSION (NU6.3) for that activation. + +## Consensus rules from NU6.3 activation + +The following consensus rules apply to every transaction in a block mined at a height greater +than or equal to the NU6.3 ACTIVATION_HEIGHT, regardless of its transaction version. They +ensure that, after NU6.3, the *Orchard pool* can only be spent from (not added to), and that +cross-address transfers within the *Orchard pool* are disabled, so that newly created shielded +value is directed into the *Ironwood pool*. + +* A coinbase transaction MUST NOT contain any *Orchard-pool* Actions; that is, its Orchard + component MUST be empty. + +* Every *Orchard-pool* Action MUST be created with cross-address transfers disabled (the + `enableCrossAddress` bit set as 0). This restriction is enforced by the Action circuit + verifying key, which is selected by block height + [^draft-zodl-valargroup-action-circuit-update], so it applies to *Orchard-pool* Actions in + version 5 transactions as well as version 6. + +* No new value may enter the *Orchard pool*: for every transaction, + $\mathsf{v}^{\textit{OrchardPoolBalance}} \geq 0$ (so the encoded `valueBalanceOrchard` is + nonnegative). Value may still leave the *Orchard pool*, including across the turnstile into the + *Ironwood pool*. + +## Changes to ZIP 209 + +ZIP 209 [^zip-0209] is extended to track an Ironwood chain value pool balance and to require +it, like the other shielded pool balances, not to become negative. + +[TODO take account of changes that should be (but are not currently) made in ZIP 256. +The check for each pool is now that the chain value pool balance stays within [0, MAX_MONEY].] + +In the Terminology section, after the paragraph + +> The "Orchard chain value pool balance" for a given block chain is the negation of the sum +> of all `valueBalanceOrchard` fields for transactions in the block chain. (Before NU5 has +> activated, the Orchard chain value pool balance is zero.) + +add + +> The "Ironwood chain value pool balance" for a given block chain is the negation of the sum +> of all `valueBalanceIronwood` fields for transactions in the block chain. (Before NU6.3 +> has activated, the Ironwood chain value pool balance is zero.) + +In the Specification section, replace + +> If any of the "Sprout chain value pool balance", "Sapling chain value pool balance", or +> "Orchard chain value pool balance" would become negative in the block chain created as a +> result of accepting a block, then all nodes MUST reject the block as invalid. + +with + +> If any of the "Sprout chain value pool balance", "Sapling chain value pool balance", +> "Orchard chain value pool balance", or "Ironwood chain value pool balance" would become +> negative in the block chain created as a result of accepting a block, then all nodes MUST +> reject the block as invalid. + +## Changes to the Protocol Specification + +Changes corresponding to the [ZIP 209 changes above](#changestozip209) are required in +§ 4.17 ‘Chain Value Pool Balances’ [^protocol-chainvalue] to define an Ironwood chain value +pool balance alongside those for the existing Sprout, Sapling, and *Orchard pools*. These +mirror the changes above and are not spelled out here. + +## ZIP 2005 activation + +ZIP 2005 [^zip-2005] activates at NU6.3: its $\mathsf{ZIP2005ActivationHeight}$ (also referenced +by § 3.2.1 ‘Note Plaintexts and Memo Fields’) is the NU6.3 ACTIVATION_HEIGHT for each network. +From that height, every *Ironwood-pool* output note uses the quantum-recoverable note plaintext +format (lead byte `0x03`) defined in ZIP 2005. + +## Implementation support + +It is proposed that `zcashd` will not implement the consensus changes for NU6.3. `zebra` is +therefore expected to be the only full-validator implementation able to follow the consensus +Zcash block chain from NU6.3 activation onward. + + +# Backward compatibility + +Prior to the network upgrade activating on each network, NU6.3 and pre-NU6.3 nodes are +compatible and can connect to each other. However, NU6.3 nodes will have a preference for +connecting to other NU6.3 nodes, so pre-NU6.3 nodes will gradually be disconnected in the run +up to activation. + +Once the network upgrades, even though pre-NU6.3 nodes can still accept the numerically larger +protocol version used by NU6.3 as being valid, NU6.3 nodes will always disconnect peers using +lower protocol versions. + + +# 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 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-chainvalue]: [Zcash Protocol Specification, Version 2025.6.3 [NU6.1] or later. Section 4.17: Chain Value Pool Balances](protocol/protocol.pdf#chainvaluepoolbalances) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0201]: [ZIP 201: Network Peer Management for Overwinter](zip-0201.rst) + +[^zip-0209]: [ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances](zip-0209.rst) + +[^zip-2005]: [ZIP 2005: Ironwood Quantum Recoverability](zip-2005.md) + +[^draft-zodl-valargroup-ironwood-txformat]: [Version 6 Transaction Format (draft)](draft-zodl-valargroup-ironwood-txformat.md) + +[^draft-zodl-valargroup-action-circuit-update]: [NU6.2 and NU6.3 updates to the Orchard Circuit (draft)](draft-zodl-valargroup-action-circuit-update.md) diff --git a/zips/zip-2005.md b/zips/zip-2005.md index ce0250e76..25688852c 100644 --- a/zips/zip-2005.md +++ b/zips/zip-2005.md @@ -1,6 +1,6 @@ ZIP: 2005 - Title: Orchard Quantum Recoverability + Title: Ironwood Quantum Recoverability Owners: Daira-Emma Hopwood Jack Grigg Credits: Sean Bowe @@ -37,7 +37,7 @@ 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 +number of ways of choosing $n$ items from a set of $k$, which is equal to $\frac{k!}{n!(k-n)!}$ for $0 \leq n \leq k$. For brevity, in the discussion sections of this ZIP we abbreviate @@ -47,42 +47,46 @@ $\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]. - -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 terms "*Ironwood pool*" and "*Orchard pool*" are to be interpreted as +described in [^draft-zodl-valargroup-ironwood-txformat]. Following the +convention in the protocol specification, we use *slanted text* to refer +to pool names, in order to more clearly distinguish them from shielded +protocols. 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. +initially deployed, these are necessarily *Ironwood-pool* 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. -This ZIP describes the Recovery Protocol in outline but not in detail: -many of its design decisions are intentionally left open. +that would allow recovery of funds held in recoverable *Ironwood-pool* notes. +This ZIP describes the Recovery Protocol in outline but not in detail: many +of its design decisions are intentionally left open. The Recovery Protocol +would also allow recovering notes created according to the ZSA extension to +the Orchard protocol [^zip-0226] [^zip-0227] if that were deployed. # Abstract -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 -from stealing or forging funds, this change would make it possible to use -a Recovery Protocol to recover existing Orchard funds. This Recovery Protocol -is expected to remain secure against discrete-log-breaking and quantum -adversaries. - -If the Orchard[ZSA] protocol needed to be disabled for this reason, the -Sapling protocol would need to be disabled as well, which would make all -Sapling funds inaccessible. Sapling funds should be migrated to Orchard in +This ZIP proposes a change to the construction of notes, to be deployed for the +*Ironwood pool* [^draft-zodl-valargroup-ironwood-txformat], 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. + +The existing Zcash shielded protocols are dependent on the hardness of finding +discrete logarithms; an adversary who can do so (via quantum computers or otherwise) +would be able to steal or forge funds. In the event of needing to disable these +protocols in order to prevent such attacks, it will be possible to use a Recovery +Protocol to recover funds from the *Ironwood pool*. This Recovery Protocol is expected +to remain secure against discrete-log-breaking and quantum adversaries. This change +does not by itself make Zcash secure against attacks using quantum computers, but is +a necessary and substantial step toward that goal. + +Recovery would not be possible for funds still in the *Sprout*, *Sapling*, or +*Orchard pools*; all such funds would be inaccessible after their respective +protocols are disabled. They should be migrated to the *Ironwood pool* in order to take advantage of this change. @@ -103,25 +107,25 @@ it would still be possible for a quantum or discrete-log-breaking adversary to forge and spend notes that are not actually in the commitment tree — thus breaking the Balance property. -This ZIP proposes a small change to the way Orchard[ZSA] notes are derived. -If this change is made in advance of quantum computers becoming viable, -then users' Orchard[ZSA] funds could remain safe and recoverable after a -post-quantum transition. This would not require any change to the Orchard -or proposed OrchardZSA *circuits* for the time being, and would not require -deciding on the particular proof system or note commitment tree hash used -in the future protocol. - -Recovering Orchard[ZSA] funds after the post-quantum transition would -involve checking a more expensive and complicated statement in zero -knowledge, but it is expected that this will be entirely practical for the -intended usage of recovering funds into another shielded pool. The current -privacy properties of Orchard would be retained against pre-quantum -adversaries, and also against post-quantum adversaries without knowledge -of the notes' addresses. [^pq-zcash] - -To reduce overall protocol complexity and analysis effort, we do *not* -propose a similar change for Sapling. Instead, Sapling funds can be -migrated to Orchard in order to make them quantum-recoverable. (Note +This ZIP proposes a small change to the way Orchard-protocol notes are derived, +that would apply to all notes in the new *Ironwood pool*. If this change is made +well in advance of quantum computers becoming viable, it would provide time for +users to move their funds to the *Ironwood pool*, keeping them safe and recoverable +after a subsequent post-quantum transition. This would not require any change to +the Orchard-protocol (or proposed OrchardZSA-protocol) **circuits** for the time +being, and would not require deciding on the particular proof system or note +commitment tree hash used in the future protocol. + +Recovering these funds after the post-quantum transition would involve checking +a more expensive and complicated statement in zero knowledge, but it is expected +that this will be entirely practical for the intended usage of recovering funds +into another shielded pool. The current privacy properties of the Orchard +protocol would be retained against pre-quantum adversaries, and also against +post-quantum adversaries without knowledge of the notes' addresses. [^pq-zcash] + +To reduce overall protocol complexity and analysis effort, we do **not** +propose a similar change for Sapling. Instead, Sapling funds can be migrated +to the *Ironwood pool* in order to make them quantum-recoverable. (Note that this analysis effort needs to include the child and internal key derivations defined in ZIP 32, which differ significantly between Sapling [^zip-0032-sapling-child-key-derivation] [^zip-0032-sapling-internal-key-derivation] @@ -145,6 +149,8 @@ and/or ZSAs [^zip-0226]. both. * The proposed scheme should not require regeneration of existing non-multisignature keys or addresses. +* It should be possible for wallets to identify what subset of a user's + funds have been made recoverable. * The changes made to the pre-quantum protocol should not cause a significant regression in performance, applicability, or security against any given adversary class, or require significant re-analysis @@ -162,7 +168,7 @@ and/or ZSAs [^zip-0226]. # Non-requirements * It is not required to address discrete-log-breaking or quantum - attacks on *privacy* with this proposal, as long as it does not + attacks on **privacy** with this proposal, as long as it does not cause any regression in privacy properties. * It is not required to add support for the Recovery Protocol to consensus rules now. @@ -177,9 +183,10 @@ and/or ZSAs [^zip-0226]. This subsection and the flow diagram below are non-normative. -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 +This proposal defines a new note plaintext format to be used for +recoverable notes (that is, those in the *Ironwood pool*), 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 @@ -188,13 +195,13 @@ 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 +function $\mathsf{Commit^{ivk}}$ that is used to derive Orchard-protocol 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 +* For existing Orchard-protocol 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. @@ -207,12 +214,10 @@ oracles, depending on which key material the user holds: $\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 +Both branches (and both cases $\mathsf{rivk} \in \{ \mathsf{rivk\_ext}, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \}$) 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}$ +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 @@ -221,7 +226,7 @@ hardware-wallet use cases are described in ## Flow diagram for the Orchard protocol -This diagram shows, approximately, the derivation of Orchard keys, +This diagram shows, approximately, the derivation of Orchard-protocol keys, addresses, notes, note commitments, and nullifiers. All of the flow diagrams in this ZIP omit type conversions between curve points, field elements, byte sequences, and bit sequences, and so are not sufficiently @@ -252,7 +257,7 @@ of additional inputs to derivation functions or alternative derivations. 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 +for $\mathsf{leadByte} = \mathtt{0x02}$ the existing Orchard-protocol 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. @@ -318,7 +323,7 @@ graph BT 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 +*Ironwood-pool* 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. @@ -328,11 +333,11 @@ recoverable notes as an ongoing process. ## Usage with FROST -When generating Orchard keys for FROST, $\mathsf{ak}$ will be derived jointly +When generating Orchard-protocol keys for FROST, $\mathsf{ak}$ will be derived jointly from the participants' shares of $\mathsf{ask}$ according to the FROST Distributed Key Generation (DKG) protocol. -This ZIP further constrains FROST key generation for Orchard as follows: +This ZIP further constrains FROST key generation for the Orchard procotol 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) @@ -385,7 +390,7 @@ 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 +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 @@ -399,10 +404,10 @@ FROST keys be transferred into that protocol's shielded pool. The same $\mathsf{use\_qsk}$ option can help to improve the efficiency of 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 +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 @@ -445,7 +450,7 @@ 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 -$$\mathsf{c_{link}} = \mathsf{LinkCommit}_r(\mathsf{H^{qk}}(\mathsf{qsk}), \mathsf{sighash}).$$ +$$\mathsf{c_{link}} = \mathsf{LinkCommit}_r(\mathsf{H^{qk}}(\mathsf{qsk}), \mathsf{sighash})\textsf{\small .}$$ 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. @@ -461,7 +466,7 @@ no information is leaked about which $\mathsf{qk}$ is being used. 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) +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}$: @@ -493,7 +498,7 @@ 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}$ + Pallas curve.** The variants differ only in **how** $\mathsf{qsk}$ is obtained: @@ -546,7 +551,7 @@ 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 as of May 2026. +specification, and to the contents of ZIPs as of June 2026. ### Changes to the Protocol Specification @@ -563,52 +568,32 @@ Replace the paragraph with -> Let the constant $\mathsf{ZIP2005ActivationHeight}$ be as defined in -> [[ZIP 2005, Deployment]](#deployment). +> Let $\mathsf{pool} \;{\small ⦂}\; \{ \textit{SaplingPool}, \textit{OrchardPool}, \textit{IronwoodPool}\, \}$ +> be the chain value pool of the note. > -> Define $\mathsf{allowedLeadBytes^{protocol}}(\mathsf{height}, \mathsf{txVersion}) =$ +> Define $\mathsf{allowedLeadBytes^{pool}}(\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{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{0x02} \},&\!\!\!\text{if } \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod} \leq \mathsf{height} \text{ and } \mathsf{pool} \neq \textit{IronwoodPool} \\ > \{ \mathtt{0x03} \},&\!\!\!\text{otherwise.} > \end{cases}$ -Replace +Replace the non-normative note: -> Senders SHOULD choose the highest note plaintext lead byte allowed under this -> condition. +> * 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. 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. +> not currently depend on $\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}$. +> * For *Ironwood-pool* note plaintexts, the only allowed lead byte value is +> $\mathtt{0x03}$. #### § 4.1.2 ‘Pseudo Random Functions’ @@ -1189,10 +1174,10 @@ $\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, the note commitment for $\mathsf{notetuple}$ is -$$[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}.$$ +$$[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}\textsf{\small .}$$ 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 +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 instantiated using BLAKE2b, a conventional hash function not related to the Pallas curve. @@ -1247,7 +1232,7 @@ We're not finished yet because we also have to prove that the nullifier is computed deterministically for a given note. All of the inputs to $\mathsf{DeriveNullifier}$ are things we committed to -in the protocol so far *except* $\mathsf{nk}$. By the same argument used +in the protocol so far **except** $\mathsf{nk}$. By the same argument used pre-quantumly, there is only one $\mathsf{ivk}$ for a given $(\mathsf{g_d}, \mathsf{pk_d})$. So in order to just use the existing protocol for this part, we would need to prove that there is only one @@ -1376,7 +1361,7 @@ $\begin{array}{l} \wedge\; \mathsf{ivk} \not\in \{0, \bot\} \end{array}$ -where $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}).$ +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 @@ -1433,19 +1418,19 @@ $\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3\, q_{\math *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),$$ +\mathsf{Extract}_{\mathbb{P}}\big(M' + [\mathsf{rivk}]\, \mathcal{S}\big)\textsf{\small ,}$$ where $\mathcal{S}$ is the rivk-randomization base -$$\mathcal{S} := \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard-CommitIvk-r”}, \texttt{“”}),$$ +$$\mathcal{S} := \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard-CommitIvk-r”}, \texttt{“”})\textsf{\small ,}$$ 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).$$ +\mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\mathsf{nk})\big)\textsf{\small .}$$ 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).$$ +\mathsf{Extract}_{\mathbb{P}}\big([h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk}]\, \mathcal{S}\big)\textsf{\small .}$$ Domain separation in the protocol's BLAKE2b instantiations ensures $h$ does not query $\mathsf{H^{rivk\_ext}}$, $\mathsf{H^{rivk\_legacy}}$, @@ -1455,7 +1440,7 @@ $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}}}.$$ +$$h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk} \equiv \pm\big(h(\mathsf{ak}', \mathsf{nk}') + \mathsf{rivk}'\big) \pmod{r_{\mathbb{P}}}\textsf{\small .}$$ 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 @@ -1545,7 +1530,7 @@ 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}}}.$$ +$$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3 q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2 r_{\mathbb{P}}}\textsf{\small .}$$ ## Security argument for Spendability @@ -1584,7 +1569,7 @@ $$\mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) := Also recall from [Repairing note commitments] that we have $$\mathsf{cm} = [\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) - + \mathsf{f}(\mathsf{rseed}, \mathsf{noterepr})]\, \mathcal{R}.$$ + + \mathsf{f}(\mathsf{rseed}, \mathsf{noterepr})]\, \mathcal{R}\textsf{\small .}$$ Let $K_{\kern-.08em\mathcal{R}}$ denote the discrete logarithm of $\mathcal{K}$ with respect to $\mathcal{R}$. This is well-defined and @@ -1602,7 +1587,7 @@ $$\mathsf{Extract}_{\mathbb{P}}\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).$$ + \Big)\textsf{\small .}$$ We model $\mathsf{H^{rcm}}$ as a random oracle with output uniform on $\mathbb{F}_{r_{\mathbb{P}}}$. The functions $\mathsf{f}$, @@ -1695,7 +1680,7 @@ satisfying: 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}}),$$ + = \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})\textsf{\small ,}$$ taken over the random oracle's responses and any internal randomness of $\mathcal{A}$. @@ -1704,7 +1689,7 @@ 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 +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 @@ -1730,7 +1715,7 @@ 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}}},$$ +\pmod{r_{\mathbb{P}}}\textsf{\small ,}$$ where $\mathsf{rseed}, \text{ρ}, \text{ψ}$ are fields of $\mathsf{notetuple}$ and $\mathsf{PRF^{nf}_{nk}}(\text{ρ})$ is determined by $\mathsf{notetuple}$ via the @@ -1760,10 +1745,10 @@ 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}}}.$$ +$$\Pr[\text{win} \mid \neg\,\text{break}] \leq \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}}\textsf{\small .}$$ 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}}).$$ +$$\Pr[\text{win}] \leq \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})\textsf{\small .}$$ This completes the classical-ROM proof. The [key-binding theorem](#thm-key-binding-rom) bounds @@ -1783,8 +1768,8 @@ 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 +**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 @@ -1795,7 +1780,7 @@ 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* +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 @@ -1812,7 +1797,7 @@ 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. -By the argument in [^Bernstein2009], the best known *generic* quantum +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 @@ -1833,7 +1818,7 @@ 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 +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. @@ -1863,15 +1848,15 @@ 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).$ +* $\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 +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. @@ -1901,15 +1886,15 @@ 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 +* break Balance for the *Sapling pool* or *Orchard pool* by forging value-commitment openings or binding signatures; -* break Balance for the Sprout, Sapling, or Orchard pools by forging Groth16 or +* 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 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 +* break Spend authentication for the *Sapling pool* or *Orchard pool* 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 @@ -1931,11 +1916,11 @@ Segwit is not relevant to Zcash. 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, +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, +**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. @@ -1959,7 +1944,7 @@ 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 +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 @@ -1982,26 +1967,26 @@ 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. +ability to spend the funds afterward. The window between the activation +height of this ZIP 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. +notes, even though we cannot decrypt them: the recoverable notes are exactly the +*Ironwood-pool* notes, so their commitments are exactly those in the +*Ironwood pool*'s note commitment tree [^draft-zodl-valargroup-ironwood-txformat]. -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. +We can likewise identify the precise set of nullifiers for recoverable notes: +they are exactly the *Ironwood-pool* nullifiers, which form a nullifier set +separate from that of the *Orchard pool* [^draft-zodl-valargroup-ironwood-txformat]. -On the other hand, within the Recovery Statement we know that the note being -spent is recoverable. +Within the Recovery Statement we also know that the note being spent is +recoverable. # Deployment -Let $\mathsf{ZIP2005ActivationHeight}$ be {{TBD}}. +The activation height of this ZIP is the NU6.3 ACTIVATION_HEIGHT +[^draft-zodl-valargroup-deploy-nu6.3]. 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 @@ -2022,21 +2007,25 @@ and randomization, which would otherwise have been difficult. 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), +1. Deploy this change prior to the next network upgrade. This would + optimize the time to deployment if there were a significant time + before the next upgrade. 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 (NU6.3), 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. +The second option has been chosen. (The first had been the plan, until +the Orchard circuit soundness vulnerability was discovered.) Deploying at +an upgrade makes the set of recoverable notes easy to identify (they are +exactly the *Ironwood-pool* notes), and it strengthens the case for +migrating funds out of the *Orchard pool*: a migrating user gains both +quantum recoverability and the improvement in supply-integrity confidence +that NU6.3 provides. -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. +This change is enforced from NU6.3: every *Ironwood-pool* output note is a +recoverable note, and no *Orchard-pool* output note is +[^draft-zodl-valargroup-ironwood-txformat]. When a compliant wallet receives an Orchard note with lead byte $\mathtt{0x02}$, the associated funds are not recoverable and need to be @@ -2097,8 +2086,6 @@ manipulate the note selection algorithm to some extent. [^zip-0231]: [ZIP 231: Memo Bundles](zip-0231.md) -[^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) @@ -2142,3 +2129,7 @@ manipulate the note selection algorithm to some extent. [^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) + +[^draft-zodl-valargroup-ironwood-txformat]: [Version 6 Transaction Format (draft)](draft-zodl-valargroup-ironwood-txformat.md) + +[^draft-zodl-valargroup-deploy-nu6.3]: [Deployment of the NU6.3 Network Upgrade (draft)](draft-zodl-valargroup-deploy-nu6.3.md)