Varun Thakore

Variants of KZG: Part IV, Multilinear Commitments with Gemini

This is Part IV of a five-part series on different variations of the KZG protocol. The original appeared on the ZK Security blog.


In Part II and Part III, we studied PST and Zeromorph, which construct multilinear polynomial commitment schemes based on the multilinear quotient identity. In this post, we explore a different route based on split-and-fold techniques. Similar techniques are also used in FRI, Bulletproofs and Sumcheck. Building on ideas from the previous posts in this series, we will study Gemini.

Notation. We continue to use the notation from Part III. We write F[X0,…,Xn−1]⪯1\mathbb{F}[X_0,\ldots,X_{n-1}]^{\preceq 1} for the set of nn-variate multilinear polynomials and F[X]<d\mathbb{F}[X]^{ < d} for the set of univariate polynomials of degree at most d−1d-1. Univariate polynomials are denoted with a hat, while multilinear polynomials are denoted without a hat. We write u⃗=(u0,…,un−1)\vec u=(u_0,\ldots,u_{n-1}) for a point in Fn\mathbb F^n and Um\mathcal U_m for the univariatization map on mm-variate multilinear polynomials.

We will now study the split-and-fold techniques used in Gemini.

Splitting and Folding Multilinear Polynomials#

Consider an nn-variate multilinear polynomial f(X0,…,Xn−1)f(X_0,\ldots,X_{n-1}). Suppose we want to prove

f(u0,…,un−1)=v. f(u_0,\ldots,u_{n-1})=v.

Gemini reduces this multilinear evaluation claim by partially evaluating one variable at a time. The verifier checks consistency between consecutive partial evaluations using a univariate identity, which we derive next.

Define the ii-th partial evaluation f(i)f^{(i)} by fixing the first ii variables:

f(i)(Xi,…,Xn−1)=f(u0,…,ui−1,Xi,…,Xn−1). f^{(i)}(X_i,\ldots,X_{n-1}) = f(u_0,\ldots,u_{i-1},X_i,\ldots,X_{n-1}).

Here, f(i)f^{(i)} is multilinear in Xi,…,Xn−1X_i,\ldots,X_{n-1} and independent of X0,…,Xi−1X_0,\ldots,X_{i-1}.

Thus,

f(0)(X0,…,Xn−1)=f(X0,…,Xn−1)andf(n)=f(u0,…,un−1)=v. f^{(0)}(X_0,\ldots,X_{n-1}) = f(X_0,\ldots,X_{n-1}) \quad \text{and} \quad f^{(n)} = f(u_0,\ldots,u_{n-1}) = v.

At step ii, f(i)f^{(i)} is obtained from f(i−1)f^{(i-1)} by setting Xi−1=ui−1X_{i-1}=u_{i-1}. Since f(i−1)f^{(i-1)} is linear in Xi−1X_{i-1}, it is determined by its evaluations at Xi−1=0X_{i-1}=0 and Xi−1=1X_{i-1}=1. Therefore,

f(i−1)(Xi−1,Xi,…,Xn−1)=(1−Xi−1)⋅f(i−1)(0,Xi,…,Xn−1)+Xi−1⋅f(i−1)(1,Xi,…,Xn−1). \begin{aligned} f^{(i-1)}(X_{i-1},X_i,\ldots,X_{n-1}) ={}&(1-X_{i-1}) \cdot f^{(i-1)}(0,X_i,\ldots,X_{n-1})\\ &+X_{i-1} \cdot f^{(i-1)}(1,X_i,\ldots,X_{n-1}). \end{aligned}

Setting Xi−1=ui−1X_{i-1}=u_{i-1} gives the next partial evaluation:

f(i)(Xi,…,Xn−1)=f(i−1)(ui−1,Xi,…,Xn−1)=(1−ui−1)⋅f(i−1)(0,Xi,…,Xn−1)+ui−1⋅f(i−1)(1,Xi,…,Xn−1). \begin{aligned} f^{(i)}(X_i,\ldots,X_{n-1}) ={}&f^{(i-1)}(u_{i-1},X_i,\ldots,X_{n-1})\\ ={}&(1-u_{i-1}) \cdot f^{(i-1)}(0,X_i,\ldots,X_{n-1})\\ &+u_{i-1} \cdot f^{(i-1)}(1,X_i,\ldots,X_{n-1}). \end{aligned}

We refer to the two restrictions of f(i−1)f^{(i-1)} obtained by setting Xi−1X_{i-1} to 00 and 11 as its even and odd parts, respectively:

feven(i−1)(Xi,…,Xn−1):=f(i−1)(0,Xi,…,Xn−1),fodd(i−1)(Xi,…,Xn−1):=f(i−1)(1,Xi,…,Xn−1). \begin{aligned} f^{(i-1)}_{\mathrm{even}}(X_i,\ldots,X_{n-1}) &:=f^{(i-1)}(0,X_i,\ldots,X_{n-1}),\\ f^{(i-1)}_{\mathrm{odd}}(X_i,\ldots,X_{n-1}) &:=f^{(i-1)}(1,X_i,\ldots,X_{n-1}). \end{aligned}

Equivalently, when f(i−1)f^{(i-1)} is represented by its evaluations over the remaining Boolean hypercube, feven(i−1)f^{(i-1)}_{\mathrm{even}} consists of its even-indexed evaluations and fodd(i−1)f^{(i-1)}_{\mathrm{odd}} consists of its odd-indexed evaluations. The even indices correspond to Xi−1=0X_{i-1}=0, while the odd indices correspond to Xi−1=1X_{i-1}=1. Using this notation, the next partial evaluation is

f(i)(Xi,…,Xn−1)=(1−ui−1)⋅feven(i−1)(Xi,…,Xn−1)+ui−1⋅fodd(i−1)(Xi,…,Xn−1) f^{(i)}(X_i,\ldots,X_{n-1}) = (1-u_{i-1}) \cdot f^{(i-1)}_{\mathrm{even}}(X_i,\ldots,X_{n-1}) + u_{i-1} \cdot f^{(i-1)}_{\mathrm{odd}}(X_i,\ldots,X_{n-1})

Note

Each partial-evaluation step first splits the previous evaluations into their even and odd parts and then folds these parts using the current evaluation point ui−1u_{i-1} to obtain the next partial evaluation. This is why the technique is called split-and-fold.

The identity above is still between multivariate polynomials, whereas Gemini uses univariate KZG commitments. To express the folding identity in a form that can be committed using univariate KZG, we apply the univariatization map from Part III.

Since the univariatization map Un−i\mathcal U_{n-i} is linear, we get:

Un−i(f(i))=(1−ui−1)⋅Un−i(feven(i−1))+ui−1⋅Un−i(fodd(i−1)) \mathcal U_{n-i}\left(f^{(i)}\right) = (1-u_{i-1}) \cdot \mathcal U_{n-i}\left(f^{(i-1)}_{\mathrm{even}}\right) + u_{i-1} \cdot \mathcal U_{n-i}\left(f^{(i-1)}_{\mathrm{odd}}\right) f^(i)(X)=(1−ui−1)⋅f^even(i−1)(X)+ui−1⋅f^odd(i−1)(X)(1) \hat f^{(i)}(X) = (1-u_{i-1}) \cdot \hat f^{(i-1)}_{\mathrm{even}}(X) + u_{i-1} \cdot \hat f^{(i-1)}_{\mathrm{odd}}(X) \tag{1}

where:

  • f^(i)(X)=Un−i(f(i))\hat f^{(i)}(X)=\mathcal U_{n-i}\left(f^{(i)}\right) is the univariate polynomial whose coefficients are the evaluations of f(i)f^{(i)} over the remaining Boolean hypercube {0,1}n−i\{0,1\}^{n-i};
  • f^even(i−1)(X)=Un−i(feven(i−1))\hat f^{(i-1)}_{\mathrm{even}}(X)=\mathcal U_{n-i}\left(f^{(i-1)}_{\mathrm{even}}\right) is the univariate polynomial whose coefficients are the even-indexed evaluations of f(i−1)f^{(i-1)}, corresponding to Xi−1=0X_{i-1}=0;
  • f^odd(i−1)(X)=Un−i(fodd(i−1))\hat f^{(i-1)}_{\mathrm{odd}}(X)=\mathcal U_{n-i}\left(f^{(i-1)}_{\mathrm{odd}}\right) is the univariate polynomial whose coefficients are the odd-indexed evaluations of f(i−1)f^{(i-1)}, corresponding to Xi−1=1X_{i-1}=1.

This is exactly the univariate form of the multilinear partial-evaluation identity. The only remaining issue is that the prover does not commit to f^even(i−1)\hat f^{(i-1)}_{\mathrm{even}} and f^odd(i−1)\hat f^{(i-1)}_{\mathrm{odd}}. The prover only commits to the univariatization of the full previous partial evaluation f^(i−1)(X)\hat f^{(i-1)}(X). Therefore, we will now express f^even(i−1)\hat f^{(i-1)}_{\mathrm{even}} and f^odd(i−1)\hat f^{(i-1)}_{\mathrm{odd}} in terms of f^(i−1)(X)\hat f^{(i-1)}(X) and substitute them into equation (1)(1).

By definition, the coefficients of f^(i−1)(X)\hat f^{(i-1)}(X) are all the evaluations of f(i−1)f^{(i-1)}, with the even- and odd-indexed evaluations appearing alternately. Suppose

f^even(i−1)(X)=e0+e1X+e2X2+⋯ \hat f^{(i-1)}_{\mathrm{even}}(X)=e_0+e_1X+e_2X^2+\cdots

and

f^odd(i−1)(X)=o0+o1X+o2X2+⋯ . \hat f^{(i-1)}_{\mathrm{odd}}(X)=o_0+o_1X+o_2X^2+\cdots.

Then the coefficients of the full univariate polynomial are interleaved as

f^(i−1)(X)=e0+o0X+e1X2+o1X3+e2X4+o2X5+⋯ . \hat f^{(i-1)}(X) =e_0+o_0X+e_1X^2+o_1X^3+e_2X^4+o_2X^5+\cdots.

Substituting X2X^2 into f^even(i−1)\hat f^{(i-1)}_{\mathrm{even}} places its coefficients at the even powers of XX. Similarly, substituting X2X^2 into f^odd(i−1)\hat f^{(i-1)}_{\mathrm{odd}} and multiplying by XX places its coefficients at the odd powers. Therefore, these polynomials are related by

f^(i−1)(X)=f^even(i−1)(X2)+X⋅f^odd(i−1)(X2). \hat f^{(i-1)}(X) = \hat f^{(i-1)}_{\mathrm{even}}(X^2) + X \cdot \hat f^{(i-1)}_{\mathrm{odd}}(X^2).

Replacing XX by −X-X in the above relation gives

f^(i−1)(−X)=f^even(i−1)(X2)−X⋅f^odd(i−1)(X2). \hat f^{(i-1)}(-X) = \hat f^{(i-1)}_{\mathrm{even}}(X^2) - X \cdot \hat f^{(i-1)}_{\mathrm{odd}}(X^2).

Adding and subtracting the relations at XX and −X-X gives

f^even(i−1)(X2)=f^(i−1)(X)+f^(i−1)(−X)2, \hat f^{(i-1)}_{\mathrm{even}}(X^2) = \frac{ \hat f^{(i-1)}(X)+\hat f^{(i-1)}(-X) }{2},

and

f^odd(i−1)(X2)=f^(i−1)(X)−f^(i−1)(−X)2X. \hat f^{(i-1)}_{\mathrm{odd}}(X^2) = \frac{ \hat f^{(i-1)}(X)-\hat f^{(i-1)}(-X) }{2X}.

Evaluating the univariate fold identity in equation (1)(1) at X2X^2 gives

f^(i)(X2)=(1−ui−1)⋅f^even(i−1)(X2)+ui−1⋅f^odd(i−1)(X2). \hat f^{(i)}(X^2) = (1-u_{i-1}) \cdot \hat f^{(i-1)}_{\mathrm{even}}(X^2) + u_{i-1} \cdot \hat f^{(i-1)}_{\mathrm{odd}}(X^2).

Substituting the even and odd parts into this equation gives the following identity for X≠0X\neq0:

f^(i)(X2)=(1−ui−1)f^(i−1)(X)+f^(i−1)(−X)2+ui−1f^(i−1)(X)−f^(i−1)(−X)2X. \hat f^{(i)}(X^2) = (1-u_{i-1}) \frac{ \hat f^{(i-1)}(X)+\hat f^{(i-1)}(-X) }{2} + u_{i-1} \frac{ \hat f^{(i-1)}(X)-\hat f^{(i-1)}(-X) }{2X}.

After the prover commits to the intermediate polynomials, the verifier samples a random nonzero point r∈F∗r\in\mathbb F^* and checks the following identity for every i∈{1,…,n}i\in\{1,\ldots,n\}, using the claimed evaluations at rr, −r-r, and r2r^2:

f^(i)(r2)=?(1−ui−1)f^(i−1)(r)+f^(i−1)(−r)2+ui−1f^(i−1)(r)−f^(i−1)(−r)2r. \hat f^{(i)}(r^2) \stackrel{?}{=} (1-u_{i-1}) \frac{ \hat f^{(i-1)}(r)+\hat f^{(i-1)}(-r) }{2} + u_{i-1} \frac{ \hat f^{(i-1)}(r)-\hat f^{(i-1)}(-r) }{2r}.

Note

The construction presented here is HyperKZG, a variant of Gemini. Gemini represents multilinear polynomials in coefficient form, whereas HyperKZG works directly in point-evaluation form. This is often more practical because a witness in a SNARK protocol is typically encoded as evaluations over the Boolean hypercube.

Using Gemini with this representation requires the prover to convert the evaluations over the Boolean hypercube into the coefficients of the multilinear polynomial using an FFT. This takes O(Nlog⁡N)O(N\log N) time, where N=2nN=2^n. HyperKZG avoids this conversion by working directly with the point-evaluation representation.

We will now look at the final construction of the opening protocol.

End-To-End Protocol#

The public inputs are the commitment CC to f^(0)=Un(f)\hat f^{(0)}=\mathcal U_n(f), the evaluation point u⃗=(u0,…,un−1)\vec u=(u_0,\ldots,u_{n-1}) and the claimed evaluation vv. The prover’s witness is the multilinear polynomial ff. The complete end-to-end protocol is as follows:

  1. Compute and commit to the intermediate folds. The prover sets f(0)=ff^{(0)}=f and, for every i∈{1,…,n}i\in\{1,\ldots,n\}, computes

    f(i)(Xi,…,Xn−1)=(1−ui−1)⋅feven(i−1)(Xi,…,Xn−1)+ui−1⋅fodd(i−1)(Xi,…,Xn−1). \begin{aligned} f^{(i)}(X_i,\ldots,X_{n-1}) ={}&(1-u_{i-1}) \cdot f^{(i-1)}_{\mathrm{even}}(X_i,\ldots,X_{n-1})\\ &+u_{i-1} \cdot f^{(i-1)}_{\mathrm{odd}}(X_i,\ldots,X_{n-1}). \end{aligned}

    For every i∈{1,…,n−1}i\in\{1,\ldots,n-1\}, it computes the univariate encoding

    f^(i)(X)=Un−i(f(i))(X) \hat f^{(i)}(X)=\mathcal U_{n-i}\left(f^{(i)}\right)(X)

    and sends its univariate KZG commitment

    Ci=KZG.Com⁡(f^(i))=[f^(i)(τ)]1 C_i=\operatorname{KZG.Com}(\hat f^{(i)}) =\left[\hat f^{(i)}(\tau)\right]_1

    to the verifier. No commitment to f^(n)\hat f^{(n)} is needed because f^(n)=v\hat f^{(n)}=v is the constant claimed evaluation. We write C0=CC_0=C for the original univariate KZG commitment.

  2. Sample the evaluation challenge. After receiving all the intermediate commitments, the verifier samples a random nonzero challenge r←$F∗ r\xleftarrow{\raisebox{0pt}{\textdollar}}\mathbb F^* and sends it to the prover.

  3. Evaluate the folded polynomials and prove the openings. For every i∈{1,…,n}i\in\{1,\ldots,n\}, the prover computes

    a(i)=f^(i)(r2), a^{(i)}=\hat f^{(i)}(r^2),

    where f^(n)(X)=v\hat f^{(n)}(X)=v. For every i∈{0,…,n−1}i\in\{0,\ldots,n-1\}, it also computes

    b+(i)=f^(i)(r)andb−(i)=f^(i)(−r). b_+^{(i)}=\hat f^{(i)}(r) \qquad\text{and}\qquad b_-^{(i)}=\hat f^{(i)}(-r).

    The prover sends all these claimed evaluations to the verifier. Along with them, it sends a batched univariate KZG opening proof for the claims

    f^(i)(r)=b+(i)andf^(i)(−r)=b−(i),i∈{0,…,n−1}, \hat f^{(i)}(r)=b_+^{(i)} \qquad\text{and}\qquad \hat f^{(i)}(-r)=b_-^{(i)}, \qquad i\in\{0,\ldots,n-1\},

    and

    f^(i)(r2)=a(i),i∈{1,…,n−1}. \hat f^{(i)}(r^2)=a^{(i)}, \qquad i\in\{1,\ldots,n-1\}.

    These claims are combined using the batched univariate KZG opening protocol from Part I.

  4. Check the folding relations. For every i∈{1,…,n}i\in\{1,\ldots,n\}, the verifier checks

    a(i)=?(1−ui−1)b+(i−1)+b−(i−1)2+ui−1b+(i−1)−b−(i−1)2r. a^{(i)} \stackrel{?}{=} (1-u_{i-1})\frac{b_+^{(i-1)}+b_-^{(i-1)}}{2} +u_{i-1}\frac{b_+^{(i-1)}-b_-^{(i-1)}}{2r}.

    It also checks that the batched KZG opening proof is valid and that the final fold equals the claimed multilinear evaluation:

    a(n)=?v. a^{(n)}\stackrel{?}{=}v.

Each accepted folding relation connects the evaluation of one intermediate polynomial to evaluations of the preceding polynomial. The final check a(n)=va^{(n)}=v therefore links the original commitment CC to the claimed evaluation f(u⃗)=vf(\vec u)=v. We now look at the efficiency of the protocol.

Complexity of the Protocol#

For an nn-variate multilinear polynomial with 2n2^n coefficients, the major costs of the opening protocol are as follows:

  • Proof Size: The prover sends n−1n-1 intermediate commitments, O(n)O(n) claimed evaluations and a constant-size batched KZG opening proof. Assuming each group element is encoded by a constant number of field elements, the total proof size is O(n)O(n) field elements.

  • Prover Cost: The sizes of the intermediate folds form the geometric series 2n−1+2n−2+⋯+1=O(2n)2^{n-1}+2^{n-2}+\cdots+1=O(2^n). Therefore, computing the folds and the batched opening proof requires O(2n)O(2^n) field operations. Committing to the intermediate folds and computing the batched KZG proof requires O(2n)O(2^n) group scalar multiplications in total.

  • Verifier Cost: Checking the nn folding relations requires O(n)O(n) field operations. To verify the batched KZG opening, the verifier forms a linear combination of the original commitment and the n−1n-1 intermediate commitments. This is an MSM of size nn, requiring O(n)O(n) group scalar multiplications. The final KZG check uses two pairing terms.

Equivalently, the opening costs can be summarized as follows:

ComponentCost
Proof sizeO(n)O(n) field elements
Prover workO(2n)O(2^n) field operations, O(2n)O(2^n) group scalar mults
Verifier workO(n)O(n) field operations, O(n)O(n) group scalar mults, two pairing terms

Conclusion#

Gemini reduces a multilinear evaluation claim by partially evaluating one variable at a time. The prover commits to every intermediate fold, giving linear prover work and an opening proof whose size grows linearly with the number of variables.

In the next part, we will study how Mercury folds multiple variables at once and reduces this opening proof to constant size.