The Orchard Action relation is the production target. A valid Action witness is a tuple (SpendingKey, Note, MerklePath, OutputNote, α, rcv) satisfying the on-chain constraints: the spent note's commitment must be in the Merkle tree at the claimed anchor, the nullifier must equal ExtractP([PRFnfOrchardnk(ρ) + ψ]·KOrchard + cm), the value commitment must be a Pedersen commitment to (spend − output) with trapdoor rcv, and so on. The Zcash protocol specification documents the full relation in section 4.18.4 ("Action Statement (Orchard)").

The simulator below samples a uniformly random valid witness, builds the production orchard::circuit::Circuit from it, runs halo2_proofs::plonk::create_proof, and presents the resulting 4992 bytes to the production orchard::circuit::Proof::verify. The verifier accepts. A small downstream patch on the upstream orchard crate exposes six read-only accessors (ProvingKey::{inner,params}, VerifyingKey::{inner,params}, Instance::to_halo2_instance, SigningMetadata::{alpha,is_dummy}) so the same path can also run with a programmable Fiat-Shamir transcript; otherwise nothing in orchard or halo2_proofs is modified.

Run it

First click pays for the proving-key build (around six seconds on a desktop, more in the browser, cached afterward). Each proof from then on takes roughly three seconds on the parallel WASM build, or thirty seconds on the single-threaded build. The seed is exposed in the URL hash so the run is reproducible.

WASM loading…

What would happen on mainnet

Every cryptographic check on this page passes. A consensus node would still reject the transaction for non-cryptographic reasons:

  1. The anchor is uniformly random; mainnet nodes check it against historical roots of the on-chain Orchard note-commitment tree.
  2. Even with a matching anchor, the spent note's commitment is not in any real block. The Merkle path proves membership in a tree the spent note was never in.
  3. If the bundle were submitted alongside transparent or Sapling components, the cross-bundle value balance check would fail unless those components were constructed to net to (spend_orchard − output_orchard − fee). An Orchard-only transaction (as this simulator builds) doesn't hit this constraint internally, but a real wallet rarely sends one.
  4. The 32-byte sighash here is uniformly random. In production it is derived from the entire v5 transaction body per ZIP 244. A node deriving the sighash from the actual submitted body computes a different value, and every signature in the bundle fails to verify against it.

The simulator therefore demonstrates the Simulate algorithm without breaking any soundness property. It cannot be used to forge a spend the network would accept.