ZIP: 257
Title: Deployment of the Orchard Temporary Vulnerability Mitigation and NU6.2 Network Upgrade
Owners: Daira-Emma Hopwood <[email protected]>
Status: Final
Category: Consensus / Network
Created: 2026-06-09
License: MIT
Discussions-To: <https://github.com/zcash/zips/issues/1293>
The key words “MUST” and “MUST NOT” in this document are to be interpreted as described in BCP 14 1 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. 2
The character § is used when referring to sections of the Zcash Protocol Specification. 3
The terms “Mainnet” and “Testnet” are to be interpreted as described in § 3.12 ‘Mainnet and Testnet’. 4
This ZIP retrospectively documents the deployment of the Orchard temporary vulnerability mitigation, and the NU6.2 network upgrade.
On 2026–05–29, security researcher Taylor Hornby, who had been tasked with an AI-assisted security audit of the Orchard shielded protocol, reported a soundness vulnerability in the Orchard Action circuit implementation. Details of the vulnerability are described in Taylor’s work log 5 and in GHSA-ww9q-8r59-xv46. 6
This vulnerability could have allowed balance violation and theft of funds. Therefore, it was imperative to immediately disable use of Orchard, until a corrected Orchard Action circuit could be deployed in the NU6.2 network upgrade. (Disabling the vulnerable circuit and enabling the new one at the same time was ruled out due to the risk of revealing the vulnerability before it had been mitigated, and in order to close the vulnerability window more quickly, while the fix was still being prepared and reviewed.)
Consensus rule: From block height 3363426 (Mainnet) or 4048500 (Testnet) onward, until the activation of NU6.2 on each network, v5 and later transactions MUST NOT contain any Orchard Action descriptions, i.e. \(\mathsf{nActionsOrchard} = 0\kern-0.05em\textsf{.}\)
The Mainnet mitigation was deployed as an emergency hotfix in zcashd v6.12.5 and zebra v4.5.3. 7 8 These releases did not have the “until the activation of NU6.2” restriction; i.e. they disabled Orchard until deployment of the subsequent releases. Note that zcashd v6.12.4 also deployed other security fixes described in ZIP 256 9.
zcashd v6.12.4 had used a Mainnet activation height of 3363366, 60 blocks earlier. Some mining pools failed to upgrade in time, so the activation was re-attempted successfully at the height given above.
These emergency hotfixes enabled the soft fork on Mainnet only, leaving the Testnet mitigation height unset. On Testnet, the soft fork instead took effect through zcashd v6.20.0 and zebra v5.0.0, which set the Testnet mitigation height to 4048500 and added support for NU6.2. Those releases had been published before Testnet reached height 4048500. The disabling of Orchard, and the subsequent re-enabling at NU6.2 (height 4052000), therefore occurred on Testnet as an ordinary scheduled activation rather than an emergency response.
The NU6.2 network upgrade re-enables the Orchard shielded protocol, with two consensus changes relative to the original Orchard rules:
The Orchard Action circuit’s variable-base scalar multiplication gadget is corrected, fixing the soundness vulnerability. This changes the Orchard verifying key. Pre-NU6.2 Action proofs verify only under the historical (insecure) verifying key, and NU6.2-onward proofs only under the corrected one. The fix was published in halo2_gadgets v0.5.0 10 and orchard v0.14.0. 11
From the activation of NU6.2, an Orchard Action proof MUST have the canonical length for the corrected circuit. Before NU6.2, this length was not enforced as a consensus rule. 8
From the activation of NU6.2, the temporary mitigation no longer applies. Transactions containing Orchard Action descriptions MUST again be accepted, with proofs subject to verification under the corrected circuit and the canonical-length rule. NU6.2 was deployed in zcashd v6.20.0 and zebra v5.0.0.
The primary sources of information about NU6.2 consensus protocol changes are the Zcash Protocol Specification 3 and this ZIP.
The network handshake and peer management mechanisms defined in ZIP 201 12 also apply to this upgrade.
The following network upgrade constants 2 are defined for the NU6.2 upgrade:
0x5437F330170150170150For each network (Testnet and Mainnet), nodes compatible with NU6.2 activation on that network MUST advertise a network protocol version that is greater than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU6.2) for that activation.
The changes below to the Zcash Protocol Specification correspond to the two NU6.2 consensus changes described above. They are relative to version 2026.6.4 of the specification 13, and are applied in version 2026.7.0 3.
Add a consensus rule to § 7.1.2 ‘Transaction Consensus Rules’ 14:
[Pre-NU6.2] From block height 3363426 (Mainnet) or 4048500 (Testnet) onward, until the activation of NU6.2 on each network, if \(\mathsf{effectiveVersion} \geq 5\) then the transaction MUST NOT contain any Orchard Action descriptions, i.e. \(\mathsf{nActionsOrchard} = 0\kern-0.05em\textsf{.}\)
The correction to the Orchard Action circuit changes the Orchard Action verifying key after NU6.2 activation.
In § 4.1.13 ‘Zero-Knowledge Proving System’ 15, replace the sentence
We also omit subscripts on \(\mathsf{ZKAction.Prove}\) and \(\mathsf{ZKAction.Verify}\kern-0.05em\textsf{.}\)
with
Subscripts are not omitted on \(\mathsf{ZKAction.Prove}\) and \(\mathsf{ZKAction.Verify}\kern-0.05em\textsf{,}\) since more than one version of the \(\mathsf{Orchard}\) circuit has been deployed.
In § 4.6 ‘Action Descriptions’ 16:
Before “An Action description comprises”, add:
Let \(\mathsf{vk}\) be the halo2 verifying key identified by the Orchard circuit version, as specified in the consensus rules below.
Replace the last consensus rule with the following three rules:
- [NU5 to NU6.1 inclusive, pre NU6.2] \(\mathsf{vk}\) MUST be the key identified by \(\texttt{OrchardCircuitVersion::InsecurePreNU6\_2}\kern-0.05em\textsf{.}\)
- [NU6.2 onward] \(\mathsf{vk}\) MUST be the key identified by \(\texttt{OrchardCircuitVersion::FixedPostNU6\_2}\kern-0.05em\textsf{.}\)
- The proof \(\pi\) MUST be valid for verifying key \(\mathsf{vk}\) given a primary input \((\mathsf{cv}, \mathsf{rt}^{\textit{OrchardPool}}, \mathsf{nf}, \mathsf{rk}, \mathsf{cm}_x, \mathsf{enableSpends}, \mathsf{enableOutputs})\) — i.e. \(\mathsf{ZKAction.Verify_{vk}}\big(\kern-0.1em(\mathsf{cv}, \mathsf{rt}^{\textit{OrchardPool}}, \mathsf{nf}, \mathsf{rk}, \mathsf{cm}_x, \mathsf{enableSpends}, \mathsf{enableOutputs}), \pi\big) = 1\kern-0.05em\textsf{.}\)
In § 4.18.4 ‘Action Statement (\(\mathsf{Orchard}\kern-0.15em\) )’ 17, add a vulnerability disclosure (styled similarly to the one for \(\mathsf{BCTV14}\) in § 5.4.10.1):
Vulnerability disclosure: The pre-NU6.2 Orchard Action circuit had a soundness bug in its variable-base scalar multiplication gadget 6, which could have allowed balance violation. The bug is in the circuit implementation only; the Action statement specified above is as intended. The corrected circuit deployed at NU6.2 has a different verifying key, so pre-NU6.2 Action proofs verify only under the insecure pre-NU6.2 key, and NU6.2-onward proofs only under the corrected one. The two circuits differ only in the additional copy constraints added to ensure soundness 18. The consensus rule specifying which key is used for verification is in § 4.6 ‘Action Descriptions’.
Add a consensus rule in § 7.5 ‘Action Description Encoding and Consensus’ 19:
- [NU6.2 onward] The \(\mathtt{proofsOrchard}\) field MUST have the canonical length of \(2720 + 2272 \cdot \mathtt{nActionsOrchard}\) bytes.
Add a non-normative note:
- Before NU6.2, the length of the \(\mathtt{proofsOrchard}\) field was not enforced as a consensus rule. The canonical length is determined by the circuit, and is the same for the pre-NU6.2 and post-NU6.2 circuits. See § 5.4.10.3 ‘Encoding of \(\mathsf{Halo\;2}\) Proofs’ 20, where a \(\mathsf{Halo\;2}\) proof is encoded as the proof byte sequence itself.
Prior to the network upgrade activating on each network, NU6.2 and pre-NU6.2 nodes are compatible and can connect to each other. However, NU6.2 nodes will have a preference for connecting to other NU6.2 nodes, so pre-NU6.2 nodes will be disconnected in the run up to activation. (In practice, this was limited by the fix only initially being distributed to a subset of nodes before the activation, due to time constraints.)
Once the network upgrades, even though pre-NU6.2 nodes can still accept the numerically larger protocol version used by NU6.2 as being valid, NU6.2 nodes will always disconnect peers using lower protocol versions.
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” ↩︎
Zcash Protocol Specification, Version 2026.7.0 [NU6.2] or later. Section 3.12: Mainnet and Testnet ↩︎
Taylor Hornby — work log for the Orchard counterfeiting vulnerability ↩︎
GitHub Security Advisory ww9q-8r59-xv46: Missing copy constraint in halo2_gadgets variable-base scalar multiplication allows under-constrained base, breaking Orchard Action circuit soundness ↩︎
GitHub Security Advisory ghc3-g8w4-whf9: Urgent zcashd hotfixes v6.12.4 and v6.20.0 ↩︎
GitHub Security Advisory jfw5-j458-pfv6: Zebra vulnerability remediation for the soundness flaw in the pre-NU6.2 Orchard Action circuit ↩︎
ZIP 256: Deployment of Consensus Bug Fixes Between NU6.1 and NU6.2 ↩︎
Zcash Protocol Specification, Version 2026.6.4 [NU6.1]. Section 7.1.2: Transaction Consensus Rules ↩︎
Zcash Protocol Specification, Version 2026.6.4 [NU6.1]. Section 4.1.13: Zero-Knowledge Proving System ↩︎
Zcash Protocol Specification, Version 2026.6.4 [NU6.1]. Section 4.6: Action Descriptions ↩︎
Zcash Protocol Specification, Version 2026.6.4 [NU6.1]. Section 4.18.4: Action Statement (\(\mathsf{Orchard}\kern-0.15em\) ) ↩︎
zcash/halo2 PR 888, commit d8e48ef. halo2_gadgets: Anchor variable-base scalar-mul incomplete-addition base ↩︎
Zcash Protocol Specification, Version 2026.6.4 [NU6.1]. Section 7.5: Action Description Encoding and Consensus ↩︎
Zcash Protocol Specification, Version 2026.6.4 [NU6.1]. Section 5.4.10.3: Encoding of \(\mathsf{Halo\;2}\) Proofs ↩︎