This repo implements a gkr-based proving system aiming to prove relations that can be represented by layered arithmetic circuit.
The major part of the code lies in the 'include' folder, including the definition of field, circuit, transcript, gkr protocol, and polynomial commitment. Details follow:
-
include/field. This contains the definition of fields. For now we mainly use M31, a prime field with$p=2^{31}-1$ being a mersenne prime. Any field implements theinclude/field/basefield.hppshould work well with the remaining part of the protocol. -
include/LinearGKR. This is the major part of the protocol where we implement the sumcheck and the gkr protocol. -
include/poly_commit. Here we implements several polynomial commitment scheme including kzg, fri and orion, these PC schemes are mainly used to commit the input of a layered arithmetic circuit to reduce the proof size and the verifier's computation cost. -
include/fiat_shamir. This is where we define the transcript used to perform fiat-shamir transformation in order to achieve non-interactivity.
The details can be found in the Libra paper. We give a short description here, presuming the readers are already familiar with the basic GKR protocol.
Given a layered arithmetic circuit
$$ \tilde{v}_{i+1}(z) = \sum_x\sum_y \tilde{mul}(z, x ,y)\cdot \tilde{v}_i(x)\tilde{v}_i(y)+ \tilde{add}(z, x)\tilde{v}_i(x) $$ .
Given
-
$v(z)$ evaluates into the value of the$z^{th}$ gate. -
$mul(z, x, y) = 1$ if there is a multiplication gate that connects the$z^{th}$ gate at the output layer to the$x^{th}$ and$y^{th}$ gate in the input layer, and it is 0 otherwise. -
$add(z, x) = 1$ if there is a addition gate that connects the$z^{th}$ gate at the output layer to the$x^{th}$ gate in the input layer. Note that an addition gate may have more than one input, and in this case,$add(z, x_1)=1, add(z, x_2)=1...add(z, x_n)=1$ for all$x_1, x_2...x_n$ .
~ refers to the multi-linear extension.
In order for the prover to efficiently compute the sumcheck for this function, we divide it into two phases.
We perform the sumcheck on variable
$f_1(x) = \sum_x \tilde{g}(x) \cdot \tilde{v}(x)$ .
where
We perform sumcheck on variable
$f_2(y) = \tilde{v}(rx) \cdot \sum_y h(y) $ .
where
In gkr reduction, a random value
-
include/LinearGKR/gkr.hppprovides the interface for gkr prover and verifier, and defines the structure of the proof. -
include/LinearGKR/scratch_pad.hpppre-allocates some memory to avoid extensive memory allocation and copy in the executaion of the protocol. -
include/LinearGKR/sumcheck_helper.hppprovides the helper function for the prover.- Note that
$f_1$ and$f_2$ are both the in the form of production of two multi-linear functions, so we use a class SumcheckMultiLinearProdHelper to facilitate the computation. This class, when taking the evaluation of the two multi-linear functions at prepare(), can output the required low-degree polynomials in the process of sumcheck. The interface is named poly_eval_at(). Whenever the verifier sends a challenge, it can take it using receive_challenge(), and do some computation internally to help produce the next low degree polynomial. - SumcheckGKRHelper computes the evaluations required by SumcheckMultiLinearProdHelper, and instantiates two of the instances.
- Note that
-
include/LinearGKR/sumcheck_common.hppprovides a function that will be used by both the prover and the verifier, i.e. evaluates$\tilde{eq}(r, a)$ at some specific random vector$r$ and all the possible$a$ from$0$ to$2^{r.size()} - 1$ . The returned value shoud have size$2^{r.size()}$ . -
include/LinearGKR/sumcheck_verifier_utilscontains two functions.-
degree_2_eval evaluates a degree-2 polynomial at some value
$x$ , the degree-2 polynomial is defined by its evaluation at$0, 1, 2$ as given in vals. -
eval_sparse_circuit_connect_poly evaluates
$add$ or$mul$ at some specific point$rx$ ,$ry$ and$rz$ . Since we have two claims, we actually compute$\alpha\cdot add(rz_1, rx) + \beta\cdot add(rz_2, rx)$ , and it is similar in the case of$mul$ .
-
-
include/LinearGKR/sumcheck.hppis where the sumcheck actually take place. It is relatively simple since all the complexity has gone to the utility files.
We offer several choices of polynomial commitment to be used to commit the input layer of the circuit including kzg, fri, Orion. In general, they should have setup, commit, open, verify interfaces.