Zcash Bug

The Zcash Orchard Counterfeiting Vulnerability and the Redefinition of Cybersecurity by AI

What Happened and Why It Matters#

Taylor Hornby, with significant help from Opus 4.8, found a Zcash bug that had not been identified by "the world's best cryptographers" for more than four years, shortly after the latest LLM was released.1 The impact of this bug may have been limited, exploitation of this bug was unlikely, an emergency mitigation/fix was implemented, and a tentative resolution has been proposed2; however, cybersecurity roles are being substantially changed and redefined by LLMs. This incident can serve as a starting point for thinking about the future shape of cybersecurity roles in the AI era.

Taylor Hornby:  

  • A former security engineer at the Electric Coin Company
  • An independent security researcher contracted by Shielded Labs 3

Taylor's report4

How Orchard Shielded Transactions Work#

Alice has 5 ZEC now, and she sends 3 ZEC to Bob.

0. Alice’s Starting Point: Keys, Address, and Old Note#

Alice's key material (payment address and keys):

  • ak_A
  • nk_A: nullifier key
  • rivk_A From this, she can derive the incoming viewing key (a private key used to view the transaction note):
  • ivk_A = commitivk_{rivk_A}(ExtractP(ak_A), nk_A)

5

Alice's old address:

  • g_d_A_old
  • ivk_A
  • pk_d_A_old = [ivk_A]*g_d_A_old

Alice's old (Orchard) note:

  • d_A_old
  • pk_d_A_old
  • v_A_old: 500,000,000 zatoshi
  • ρ_A_old
  • ψ_A_old
  • rcm_A_old

Note Commitment: g_d_A_old = DiversifyHash(d_A_old) cm_old = NoteCommit{rcm_A_old}(g_d_A_old, pk_d_old, v_A_old, ρ_A_old, ψ_A_old) *The note commitment uses a Sinsemilla commitment

cm_old would be stored in the Note Commitment Tree. *Preventing double-spends is not the job of the commitment tree.

The Merkle root of the note commitment tree uniquely identifies a note commitment tree state, and this root is stored in a transaction and maintained by full nodes.

5

Nullifiers (Preventing double-spends): The nullifier for a note, denoted nf, is a value unique to the note that is used to prevent double-spending. The nullifier for an Orchard note is derived from the ρ and ψ values, the recipient’s nullifier deriving key nk, and the note commitment.

nf = DeriveNullifier{nk}(ρ, ψ, cm)

1. Creating the New Output Notes#

  • Alice knows Bob's address (d_B, pk_d_B)

Alice creates new notes:

  • N_B_new: new note for Bob

    • d_B
    • pk_d_B
    • v_B: 300,000,000 zatoshi
    • ρ_B
    • ψ_B
    • rcm_B
  • N_A_new: new note for Alice (change)

    • d_A
    • pk_d_A
    • v_A: 500,000,000 - 300,000,000 - fee
    • ρ_A
    • ψ_A
    • rcm_A

Conceptually:

  • Alice's old note: 5 ZEC
  • outputs:
    • Bob: 3 ZEC
    • Alice: 2 ZEC - fee
    • fee

No one on-chain sees the note contents directly. The protocol discloses note commitments, value commitments, and ciphertexts, while the actual note contents stay hidden.

cv: value commitment cmx: note commitment anchor: Merkle root

6

2. Creating Proofs with Circuit Constraints#

  1. Old note commitment integrity NoteCommit{rcm_A_old}(g_d_A_old, pk_d_old, v_A_old, ρ_A_old, ψ_A_old) ∈ {cm_A_old, ⊥}

  2. Merkle path validity cm_A_old is included in the note commitment tree under the given anchor I know an old note whose commitment is in the Orchard tree with the root anchor

  3. Value commitment integrity cv_net = ValueCommit{rcv}(v_old - v_new)

  4. Nullifier integrity nf_old is correctly derived from Alice's note and Alice's nullifier key material

  5. Spend authority rk is a randomized version of Alice's spend authorization key

  6. Address integrity pk_d_A_old corresponds to Alice's incoming viewing key / address key material pk_d_A_old = [ivk_A] * g_d_A_old

3. Broadcasting the Transaction#

After Alice assembles the transaction with her signatures, she submits the encoded transaction to the P2P network.

4. How the Network Verifies the Transaction#

Some full nodes receive it and may validate it before relaying it. Miners validate transactions before including them. A block is mined containing Alice's transaction. Other full nodes validate the block and every transaction in it. If valid, the block can become part of the best valid chain.

5. Receiving Funds Without Public Disclosure#

Bob’s wallet can detect and decrypt the incoming note using ivk_B.

The Bug: A Broken Binding in Scalar Multiplication#

There was a bug in a Halo 2 scalar-multiplication gadget, specifically the halo2_gadgets elliptic-curve scalar-multiplication gadget used by the Orchard Action circuit. In a normal Orchard spend proof, the prover must satisfy the diversified address integrity relation pk_d_old = [ivk] * g_d_old, which binds the old note’s diversified address to the key material used to derive ivk and the nullifier key nk. The bug was not simply that g_d_old itself was unconstrained; rather, the scalar multiplication gadget could be made to accept a multiplication against a free base different from the real base. This broke the binding between the committed old note and the nullifier deriving key, allowing a malicious prover to use different nk values for the same committed note and produce different nullifiers via nf = DeriveNullifier_nk(rho, psi, cm).

Since full nodes only reject repeated nullifiers, different nullifiers for the same note could appear as different spends, enabling double-spending or counterfeiting within the Orchard shielded pool.

The bug could have allowed "unlimited, undetectable counterfeit ZEC". However, Zcash's turnstile /chain value pool accounting would constrain exits from public shielded pool. 7
"Consensus rule: If the 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." 5

Was the Vulnerability Exploited?#

Taylor’s report states that Opus 4.8 only barely managed to find the bug, and that the PoC took about six hours, while Opus 4.7 could not find it unless guided. It also says the Opus 4.8 window of exposure was 4 days and 10 hours, which was likely short enough to make exploitation by attackers using the latest model unlikely. However, the bug’s more-than-four-year exposure window is still worth considering.

8

Also, based on the public shielded-pool supply data, there was no obvious large discontinuity or visible cross-pool anomaly around the disclosure period. This suggests that no large-scale, publicly visible extraction occurred. However, this does not rule out Orchard-internal counterfeiting or gradual/small-scale exploitation.

AI Is Redefining Cybersecurity Work#

Opus 4.7 could not find the bug unless given vulnerability-specific information, like "audit the variable base scalar mul gadget for any missing constrains that could lead to an inflation bug or double-spending attack against Zcash." Even Opus 4.8 struggled to find the bug; it found it in 25% of the test runs. Moreover, implementing the attack PoC took about six hours with AI, which could be reduced with faster modes such as /fast.

AI helped find a bug/vulnerability that humans had not found for more than four years. It is unclear whether we should call this AI-centered or human-centered cybersecurity, but either way, AI is now playing an essential role in cybersecurity work, and the workflow is changing.

In the past, cybersecurity work was mainly led by people with specialized knowledge, experience, and skills. From here, AI will amplify that dynamic. AI can find bugs even with relatively general guidance, as Opus 4.8 did in this case. However, malicious actors or white-hat hackers with specialized knowledge, like Taylor, may be able to guide AI more effectively and find such vulnerabilities earlier, as Taylor’s Opus 4.7 test suggests.

4

Footnotes#

  1. https://shieldedlabs.net/the-orchard-counterfeiting-vulnerability

  2. https://forum.zcashcommunity.com/t/ironwood-verifying-the-soundness-of-zcash-s-circulating-supply/56044

  3. https://forum.zcashcommunity.com/t/orchard-vulnerability-successfully-remediated/55976

  4. https://drive.google.com/file/d/1SVK41y-ip3Vw9eB69E9QRy-Qn3idTOwV/view 2

  5. https://zips.z.cash/protocol/protocol.pdf 2 3

  6. https://mainnet.zcashexplorer.app/transactions/92a05c92e557bb107bc9facccc265abfedd401a23f166222da8ff4887e77b457/raw

  7. https://forum.zcashcommunity.com/t/the-orchard-counterfeiting-vulnerability-and-next-steps

  8. https://blockworks.com/analytics/zcash/zcash-overview/zcash-shielded-supply-2