# Details of custom gate

Hi all, I heard a lot of custom gates in plonk, but can’t find anything about what it is, how it does, and any related projects that use it. I would be every thankful if someone could point that out.

In “vanilla Plonk”, the prover convinces the verifier that this constraint vanishes on H:

(q_L)_i \, x_{a_i} + (q_R)_i \, x_{b_i} + (q_O)_i \, x_{c_i} + (q_M)_i \, (x_{a_i} \, x_{b_i}) + (q_C)_i = 0.

The idea of custom gates is just to generalize this. As a basic example, if we wanted to evaluate MiMC more efficiently, we could add a cubic term:

(q_L)_i \, x_{a_i} + (q_R)_i \, x_{b_i} + (q_O)_i \, x_{c_i} + (q_M)_i \, x_{a_i} \, x_{b_i} + (q_{L3})_i \, x_{a_i}^3 + (q_C)_i = 0.

We could then make the i’th gate a cube gate by setting (q_{L3})_i = 1, (q_O)_i = -1, and the rest 0.

We can also use more than three wires, more than one constraint, constraints on more than one row, etc. With such generalizations, it can end up looking more like an AIR instance (as in the STARK paper) than a circuit.

As an example, Dmitry Khovratovich wrote up an adaptation of Plonk tailored to Poseidon. We also have various examples of custom gates in plonky.

2 Likes

So ‘custom gate’ is a feature that comes from original PLONK, not turbo-plonk?

I found some Zac Williamson’s speak on Zero Knowledge, I quote:

PLONK’s strength is these things we call custom gates. It’s basically you can define your own custom bit arithmetic operations. I guess you can call them mini gadgets. That are extremely efficient to evaluate inside a PLONK circuit. So you can do things like do elliptical curve point addition in a gate. You can do things like efficient Poseidon hashes, Pedersen hashes. You can do parts of a SHA-256 hash. You can do things like 8-bit logical XOR operations. All these like explicit instructions which are needed for real world circuits, but they’re all quite custom.

So Zac’s `'define your own custom bit arithmetic operations'` is what you mean setting different selectors with 1, -1 and 0?

And what’re the meanings of do `'parts of a SHA-256 hash'` and others, how to do that?

Happy to help

My understanding is that TurboPLONK is just a name for “PLONK with the addition of custom gates”.

I would think of setting selectors to 1 or 0 as enabling or disabling a certain gate. Like with (q_{L3})_i = 1, (q_O)_i = -1, and the rest zero, our constraint just becomes x_{c_i} = x_{a_i}^3. I.e. the i’th gate’s output wire must equal the cube of its left input wire.

I think what Zac was getting at was just that we could also add custom gates for binary functions. If we wanted an xor gate for example, we could add a term

(q_\oplus)_i \, (x_{a_i} + x_{b_i} - x_{a_i} x_{b_i}),

leveraging the fact that P \oplus Q = (P \lor Q) \land \lnot(P \land Q). Then we could make the i’th gate an xor gate by setting (q_\oplus)_i = 1 and (q_O)_i = -1, which simplifies our constraint to

x_{c_i} = x_{a_i} + x_{b_i} - x_{a_i} x_{b_i}.

(I’m assuming the inputs are already known to be in \{0, 1\}. If not, we can enforce that with a couple extra constraints.)

1 Like

Thank you for your help, I really learned a lot.

One more thing, here:

You mean this, right?
(q_⊕)_i({x_a}_i+{x_b}_i−{x_a}_i{x_b}_i) + (q_O)_i {x_c}_i = 0

Hm, that would work if we wanted a circuit with just xor gates. I was thinking of adding an xor gate as an extra option, while still keeping the “standard” terms/gates to support additions, multiplications, etc. So I was thinking we would keep all the usual terms like (q_O)_i \, x_{c_i}, and add (q_\oplus)_i \, (x_{a_i} + x_{b_i} - x_{a_i} x_{b_i}) as an extra term.

1 Like

Hey…
turbo-plonk is indeed sometimes used informally to mean “plonk with custom gates”
but see here for an attempt to formalize it : https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf

and a more recent attempt to get the terminology in order, and connect it to STARKWARE’s airs:

1 Like