When designing the zkvm circuit, because of many custom gates determined, there are a lot of binary selectors are introduced. Taking the (field) division gate as an example, we plan to design a gate to verify that the relationship
Between the two elements, there is an equal relationship. Therefore, we have the following Trace table:
Step | … | … | |||||||
---|---|---|---|---|---|---|---|---|---|
… | … | … | … | … | |||||
k | 0 | 0 | 1 | 0 | x | y | q | //division | |
… | … | … | … | … |
Define the polynomial
To ensure that the relationship above can be satisfied in the corresponding row, a selector is needed to make the corresponding division to constrain the verification. Therefore, we have introduced a new column
From the example above, we can see that when we define a new customized gate, a selector column
For the prover needs to conduct commitments to all polynomials during the proof generation, overmuch selector polynomials introduced will increase the workload of the prover and the verifier. Therefore, it is necessary to optimize the selector number while the following two conditions must be satisfied:
In "Plonky2: Fast Recursive Arguments with PLONK and FRI"(https://github.com/mir-protocol/plonky2/blob/main/plonky2/plonky2.pdf), there is an optimization method "Binary-Tree Based Selector", which reduces the number of the select polynomial to
To understand it easier, let's take a simple example (for specific algorithm, please refer to Selector combining - The halo2 Book)
Step | |||||||||
---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 0 | //add | ||||
1 | 0 | 1 | 0 | 0 | //division | ||||
2 | 0 | 0 | 1 | 0 | //cube | ||||
3 | 0 | 0 | 0 | 1 | //sqrt |
We can see that we have set 4 selector columns for 4 kinds of customized gates, which are not what we want just like the aforementioned. Therefore, this will increase the workload of the prover and the verifier. Here we define a new column
If we define a set
Step | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 0 | 1 | //add | ||||
1 | 0 | 1 | 0 | 0 | 2 | //division | ||||
2 | 0 | 0 | 1 | 0 | 3 | //cube | ||||
3 | 0 | 0 | 0 | 1 | 4 | //sqrt |
Here, define a new selector polynomial form based on column
For example, for the constraint:
The above formula can be expanded into:
Set
Then, the true value figure is obtained:
x | ||
---|---|---|
0 | 1 | 1 |
1 | 0 | 0 |
2 | 0 | 0 |
3 | 0 | 0 |
It can be seen that it does the same thing as the original selector. Therefore, for constraints
We can rewrite the constrains into:
For the constraints above, we only need to conduct commitment to the polynomial
So far, we have achieved the two points mentioned above:
Of course, there are limitations to the constrained Degree in the protocol, so the selector number participating in the combine is bounded, that is, the number of the single combined selector depends on the boundary value of the Degree and max_degree of the constraint polynomial
For more handling cases and algorithm details, please refer to Selector combining - The halo2 Book.