Skip to main content

ZK Examples

Example: PLONK

There are various options of what kind of front-end to use to design a ZK circuit. The PLONK system is one such way. We will describe it below, and it will be a good way of preparing us for the full PLONKish arithmetization used in halo2, which is what Axiom uses in production.

A PLONK circuit consists of a table/matrix with the following fixed columns and nearly arbitrary number of rows:


where the numbers in the columns qL,,qOq_L, \dotsc, q_O are fixed once and for all at compile time. Meanwhile the numbers in columns a,b,ca, b, c are called witnesses and specified by the prover each time a new proof is generated. What makes the circuit meaningful, and not a random collection of numbers, is that for each row ii, the following equation is guaranteed to hold:

qLa+qRb+qMab+qC=qOcq_L \cdot a + q_R \cdot b + q_M \cdot a \cdot b + q_C = q_O \cdot c

Since the qq columns are fixed once and for all, specifying these numbers allows you to "mold" the circuit to constrain the witnesses a,b,ca, b, c to perform certain computations.

For example, if you want to add ai+bi=cia_i + b_i = c_i in row ii, put:


To multiply aibi=cia_i \cdot b_i = c_i in row ii, put:


To force aia_i to be a known constant CC, put:


Note that bi,cib_i, c_i can be any numbers and it doesn't matter.

So far, we can use the above to do single line computations. There is one more ingredient: one can also specify once and for all that certain predetermined cells in the table above are always equal. For example, for some i0i_0, we must have c_ i_0 = a_ i_0 + 1. This now allows us to carry results of previous computations into new computations, "chaining" to create longer computations.


To summarize, creating a ZK proof involves the following steps:

Once and for all, specify the circuit itself:

  • Specify all cells in columns qL,qR,,qOq_L, q_R, \dotsc, q_O.
  • Specify any equality constraints between cells.
  • The verifier receives the above information in a compressed form.
  • The prover holds onto a copy of the above information itself.

To submit a proof:

  • Do the computation itself, i.e., generate the witnesses ai,bi,cia_i, b_i, c_i.


While circuit design involves just filling out a table using some front end, to actually create a proof there is a backend that takes the PLONK table above and does a bunch of computations involving polynomial commitment schemes. This part is largely independent of the circuit design, but different backends lead to different performance characteristics, which become important to understand for production use cases.