The circuit is small on purpose. MulCircuit asserts a single multiplication gate qmul · (a · b − c) = 0 on three advice columns and one instance column carrying c. There are no lookups, no rotations beyond the current row, and one selector. The witness is the pair (a, b); the public statement is the single scalar c. The relation R = { ((a, b), c) : a · b = c } admits every nonzero a as half of a valid witness, so the witness set is parameterised by a single field element. This multi-witness structure is what lets the WI simulator on the next slide work without forcing any value.

All three runs below pass through the same upstream prover and verifier. The only thing the simulator changes is which transcript implementation create_proof drives, and which witness it samples along the way.

Run it

Keygen runs once. After that, each click takes well under a second on a desktop. The two seeds are exposed in the URL hash; same pair, same byte-identical output.

WASM loading…

What this shows

Three runs of the same circuit, three different transcripts, one upstream prover and verifier. The acceptance pattern determines what each run proves:

RunWitnessTranscriptBlake2b verifyProgrammable verify
honest real (sampled) Blake2bWrite accept n/a
WI simulator different sample Blake2bWrite accept n/a
ZK simulator different sample ProgrammableHalo2Write reject accept

The WI simulator's acceptance under Blake2b proves witness-indistinguishability: the verifier had to accept the proof of a different witness, with the same public statement, indistinguishably. The ZK simulator's pattern (acceptance under programmable, rejection under Blake2b) proves zero-knowledge in the random-oracle model: the simulator constructed an accepting transcript using only the public statement and the programmability power of the abstract oracle, with no leakage back to the witness.

Page III, Orchard, lifts both ideas to the production Action circuit. Same WI sampling argument, same programmable transcript trick, vastly larger circuit.

The Zcash protocol specification defines the concrete Halo 2 instantiation in §5.4.10.3 and the Pasta curves (Pallas and Vesta) in §5.4.9.6.