freecoding.school100% FREE · NO SIGNUP
Proof PeaksISSUE #19 of 38

plonk · universal setup · custom gates

ZeekaVSThe Collision
Zeeka saysPLONK uses one universal trusted setup for all circuits and adds custom gates plus a permutation argument for copy constraints — flexibility Groth16 lacks.

PLONK fixed Groth16's biggest annoyance: instead of a fresh ceremony per circuit, one universal setup serves them all. It also adds custom gates (encode complex operations in one gate) and uses a permutation argument to enforce copy constraints — the rule that the same wire value appears in multiple places.

The permutation argument reduces to a multiset-equality check: prove one vector of wire values is a permutation of another via a grand product that telescopes to 1 when the wiring is consistent. The demo runs that exact check, showing a genuine permutation passes while a single altered wire breaks the equality. PLONK's lineage (Halo2, plonky2) powers much of today's ZK.

Power-ups you unlock

The Collision attacks — common mistakes

Boss battleUse a permutation argument to prove one wire vector is a permutation of another, and show a single altered wire breaks the equality.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
// PLONK's core gadget: a permutation (multiset-equality) argument.
// ∏(β − a_i) == ∏(β − b_i)  iff  b is a permutation of a.  copy-constraints reduce to this.
const F=97, mod=(n)=>((n%F)+F)%F;
const prod=(arr,beta)=> arr.reduce((acc,x)=> mod(acc*mod(beta - x)), 1);
const a=[5, 9, 2, 7];
const b=[2, 7, 5, 9];                               // a permutation of a (consistent wiring)
const bad=[2, 7, 5, 8];                             // one wire altered (broken copy)
const beta=11;
document.getElementById('o').textContent = [
  'a   = [' + a.join(', ') + ']',
  'b   = [' + b.join(', ') + ']  → ∏(β−a)=' + prod(a,beta) + '  ∏(β−b)=' + prod(b,beta) + '  equal? ' + (prod(a,beta)===prod(b,beta)),
  'bad = [' + bad.join(', ') + ']  → ∏(β−bad)=' + prod(bad,beta) + '  equal? ' + (prod(a,beta)===prod(bad,beta)),
  'custom gates + this check = PLONK; one universal setup serves all circuits'
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Groth16 · The Compact SnarkLookup Arguments · Plookup · Logup ›