an executable simulator

The third algorithm.

Production zero-knowledge code ships Prove and Verify. The third algorithm, Simulate, is what makes a proof zero-knowledge in the first place, and is almost never implemented outside of security proofs. Here is one for Halo 2's inner-product argument and for the production Zcash Orchard Action proof, in the browser.

halo2_proofs 0.3 orchard 0.14 Pasta curves ~3 s per Orchard proof (rayon, 32 threads) Zcash protocol spec ↗

A zero-knowledge proof system has three algorithms. Most engineers can name two. The third lives in the security proof: given only the public statement, the simulator constructs an accepting transcript that the verifier cannot distinguish from a real prover's. Its existence is what guarantees the real prover's transcript leaks nothing about the witness.

The four sections below build the argument up from the inner-product argument that underlies Halo 2, through the multipoint reduction and a single gate, to the production Orchard Action circuit. Each section is a separate page; each page is reproducible from the seed in its URL hash.

I.
Foundations
Three algorithms, not two. Witness-indistinguishability versus zero-knowledge. The statement to be proved. The simulator's algebraic move.
II.
Halo 2
The strict ROM-programmable Simulate construction on Halo 2's inner-product argument, isolated on a single multiplication gate. Three runs through halo2_proofs show acceptance under the programmable transcript and rejection under Blake2b.
III.
Orchard
The simulator on the production Zcash Orchard Action circuit. 4992-byte proofs, full Bundle<Authorized>, soundness check, signature verification, byte-level reproducibility.
IV.
Reference
Proof anatomy. Comparison to other SNARK families. Why a mainnet node still rejects this. Glossary, FAQ, references, and how to run the whole thing yourself.

What it is, what it isn't

It is a working Simulate algorithm for two ZK relations: Halo 2's inner-product argument run through a small multiplication-gate circuit (Page II), and the production Orchard Action relation as deployed in Zcash (Page III). Both pages run the same construction — uniform witness sampling combined with a programmable Fiat-Shamir transcript — that satisfies the textbook zero-knowledge definition in the random-oracle model for any multi-witness relation. The Orchard path drives upstream orchard::circuit::Proof::create and Proof::verify directly, against the same proving and verifying keys a mainnet node builds.

It is not a production prover. It is not Zcash. It does not let you spend ZEC. A consensus node would reject these proofs for reasons that have nothing to do with cryptography: the anchor is uniformly random, the spent note doesn't exist on chain, the sighash isn't bound to a real transaction. The Orchard page spells out the five reasons.

How to read this

Linear reading from Foundations onward is the intended path. Each experiment exposes its seed in the URL hash; the same seed reproduces byte-identical output. The Orchard simulator on Page III takes around three seconds per proof on a modern desktop with the parallel WASM build; if you only want to see one running proof, that is the page to visit.