Hyper BMMTV Costs

.

The purpose of this post is to understand the computational costs of committing to an \(\ell\) variate multi-linear polynomial using the inner product commitment scheme prescribed by (Bünz et al., 2019).

Note that (Bünz et al., 2019) only describes how to commit to a univariate polynomial or a bi-variate polynomial explicitly.
To commit to a multi-linear polynomial, we feed the univariate polynomial scheme as a blackbox to the reduction of knowledge technique described in Section 6 of (Zhao et al., 2024) (titled hyper-kzg).

Notation

Throughout this post we assume that use \(m \in \mathbb{N}\) is a power of 2. As the main content of this post is from (Bünz et al., 2019), when describing group operations, we stick with their conventions and use multiplicative notation.

Index Notation: Usually we index the \(i\)’th location of a vector \(\vec{a}\) with \(a_i\). Often, however, owing to the need for multi-indexing or other reasons, we will index vectors with script notation \(a^{(j)}\) instead. We understand this can be confusing, so to ease cognitive load, the reader is asked to remember that

  • When there are parentheses around \((i)\) then \(a^{(i)}\) is the \(i\)’th index of a vector \(\vec{a}\).

  • When there are NO parentheses around \(i\) then \(a^{i}\) is \(a\) raised to the power of \(i\).

The original manuscript by (Bünz et al., 2019) introduces a lot of non-standard notation. We feel that most of that notation is not needed to accurately describe the protocols. Therefore, in this post, we describe everything using standard notation accepted by the wider mathematics/TCS community, outside of crypto and snarks (at the cost of sometimes being a little bit more verbose). As we do not go into security proofs, we also abandon most of the formalism introduced in the preliminary sections of the original manuscript. We believe this approach simplifies the exposition significantly without compromising rigour or correctness.

Curves And Pairings

Let \(\textcolor{blue}{\mathtt{q}}\) be some prime. We highlight this in blue and write in a different font to distinguish it from univariate polynomial \(q\) which is used later in the post to verify if the commitment keys are propelry structured.

Throughout this post, and the posts hyper-linked here, we will assume the pairing \(e: \mathbb{G}_1\times \mathbb{G}_2\rightarrow \mathbb{G}_T\) is constructed from some elliptic curve \(E/\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\).

  • \(\mathbb{G}_1\) is an order \(\textcolor{blue}{\mathtt{q}}\) subgroup of \(E(\mathbb{F}_{\textcolor{blue}{\mathtt{q}}})\).
  • \(\mathbb{G}_1\) is an order \(\textcolor{blue}{\mathtt{q}}\) subgroup of \(E(\mathbb{F}_{\textcolor{blue}{\mathtt{q}}^d})\) for some \(d > 1\).
  • \(\mathbb{G}_T\) is an order \(\textcolor{blue}{\mathtt{q}}\) multiplicative subgroup of the finite field \(\mathbb{F}_{\textcolor{blue}{\mathtt{q}}^d}\)

Background

To fully make sense of the commitment scheme, we need to understand 4 sub-components

  1. The KZG commitment scheme: You can ignore the section on batching, as that’s not critical for understanding inner product arguments.
  2. We introduce the “inner product” or “multi-exponentiation” argument, which is the main contribution of (Bünz et al., 2019). Using KZG and the inner product argument, we show how to commit to a bivariate polynomial. This is the new stuff!.
  3. Finally, we show how to commit to a univariate polynomial using bi-variate commitment scheme
  4. Now that we have a univariate commitment scheme, we can commit to multi-linear polynomials using univariate commitments using the black box reduction of knowledge scheme from (Zhao et al., 2024).

Bi-variate Polynomials

We are given a bi-variate polynomial \(f \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}[X, Y]\)

\[ \begin{align} f(X, Y) &= \sum_{i=0}^{m-1} f_i(Y)X^{i} \tag{i} \end{align} \] where for all \(i \in \{0, \ldots, m-1\}\), \(f_i \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}[Y]\) is a univariate polynomial with degree at most \(\ell -1\) i.e \(f_i(Y) = f_{(i, 0)}Y^0 + \ldots + f_{(i, \ell-1)}Y^{\ell-1}\) where \(f_{i,j} \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\) for all \(j \in \{0, \ldots, \ell-1\}\)

Trusted Setup

Let \(g \in \mathbb{G}_1\) and \(h \in \mathbb{G}_2\) be group generators.

Things that the prover is given

  • \(\vec{w} = [w_j]_{j=0}^{\ell-1} = \left[ g^{\alpha^i} \right]_{i=0}^{\ell - 1} \in \mathbb{G}_1^m\), where \(\alpha \xleftarrow[]{\$}\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\) is toxic waste of the trusted setup.

  • \(\vec{u} = \left[u_i\right]^{2m-2}_{i=0} = \left[h^{\beta^{i}}\right]^{2m-2}_{i=0} \in \mathbb{G}_2^{2m-2}\) where \(\beta \xleftarrow[]{\$}\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\) is also toxic waste of the trusted setup.

Things that the verifier is given: Just the two group elements that will be needed to open KZG proofs using keys in \(\mathbb{G}_1\) and \(\mathbb{G}_2\)

  • \(w_1 = g^{\alpha}\)
  • \(u_1 = h^{\beta}\)

How To Commit

Prover \(\rightarrow\) Verifier: \(T \in \mathbb{G}_T\) as the commitment to \(f\)

To commit to \(f\)

For all \(i \in \{0, \ldots, m-1\}\) we commit to each univariate polynomial \(f_{i} \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}[Y]\) using the KZG commitment scheme with commitment key \(\vec{w} \in \mathbb{G}_1^m\). Let \(A_i \in \mathbb{G}_1\) denote this commitment. i.e.

\[ \begin{align} A_i &= \prod_{j=0}^{\ell -1} w_j^{f_{(i,j)}} = \prod_{j=0}^{\ell -1} \Big(g^{\alpha^j}\Big)^{f_{(i,j)}} = g^{\sum_{j=0}^{\ell-1}f_{i,j}\alpha^j} \end{align} \]

The commitment key for the pairing commitment is \(\vec{v}\) which is the vector constructed from the even indices of \(\vec{u}\) in the trusted setup i.e. \(\vec{v} = \left[ u_{2i} \right]_{i=0}^{m-1} = \left[ h^{\beta^{2i}} \right]_{i=0}^{m-1}\).

Then we compute a pairing commitment under \(\vec{v}\) using the KZG commitments as witness. The final commitment \(T \in \mathbb{G}_T\) \[T = \prod_{i=0}^{m-1} e(A_j, v_j)\]

How To Open

The verifier asks the prover to open \(f\) at points \((z_x, z_y) \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\times \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\). As a response the prover

Prover \(\rightarrow\) Verifier: \(\pi = (U, \pi_1, \pi_2)\) this is opening proof and \(\nu\) is the evaluation

1. Commit To A Partial Evaluation

Remember \(\textcolor{red}{f_{i,j}}\) is the \(j\)’th coefficient of univariate polynomial \(f_i(Y) = f_{(i, 0)}Y^0 + \ldots \textcolor{red}{f_{(i, j)}} + \ldots + f_{(i, \ell-1)}Y^{\ell-1}\)

Recall that \[A_i = \prod_{j=0}^{\ell -1} w_j^{f_{i,j}}\] are KZG commitments to the univariate polynomials \(f_i \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}[Y]\) and \(\vec{w}\) is as defined in the trusted setup section.

The prover computes \(U = \prod_{i=0}^{m-1} A_i^{(z_x)^i} \in \mathbb{G}_1\). Observe that \(U\) is a KZG commitment to the univariate polynomial \(f(z_x, Y) = \sum_{j=0}^{\ell-1} \Big(\sum_{i=0}^{m-1} f_{i, j}(z_x)^i\Big)Y^j\) (see here for the derivation), which is a partial opening of \(f\).

2. Inner Product Proof

Next the prover provides a proof \(\pi_1\) that \(U\) is the inner product of the opening of \(T\) under commitment key \(\vec{v}\) and the public vector \(\vec{z_x} = \left[z_x^{i}\right]_{i=0}^{m-1}\).

Here we use the term inner product, as that’s what the original authors do, but to be explicit, we mean \(\langle\vec{A}, \vec{z}_x\rangle = \prod_{i=0}^{m-1} A_i^{(z_x)^i}\), where \(\vec{A}\) is the opening of \(T\) under commitment key \(\vec{v}\).

First we fully describe the remainder of the opening proof. Then we discuss what \(\pi_1\) looks like in detail. This is the contribution of (Bünz et al., 2019). So we will dive deep into this in a subsequent section. Everything else about the opening proof we already know how to do.

3. The Full Evaluation Proof

Given commitment \(U\) to \(f(z_x, Y)\), the prover provides a KZG evaluation proof \(\pi_2\) that \(\nu = f(z_x, z_y)\) and that it knows an opening \(f(z_x, Y)\) of the KZG commitment \(U\).

We know how to compute KZG commitments, and open KZG commitments, and understand well the costs of those two. We do not go over them in this post. For the remainder, we focus on the prover cost of generating \(\pi_1\).

To pass verification both \(\pi_1\) and \(\pi_2\) must pass the verifier tests.

Inner Product Proof

A quick reminder, the prover is giving a proof \(\pi_1\) that \(U \in \mathbb{G}_1\) is the inner product of the opening of \(T \in \mathbb{G}_T\) under commitment key \(\vec{v} \in \mathbb{G}_2^m\) and the public vector \(\vec{z_x} = \left[z_x^{i}\right]_{i=0}^{m-1}\).

The provers witness is \(\vec{A} = A_0, \ldots, A_{m-1} \in \mathbb{G}_1^m\).

Define \(\vec{b} = (b_0, \ldots, b_{m-1}) = (z_x^0, \ldots, z_x^{m-1})\in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}^m\). This is common knowledge to the prover and the verifier, as the verifier picks \(z_x \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\).

Def:

Opening Proof For Inner Product Argument

Initialise \(\vec{A}^{(0)} = \vec{A},\quad \vec{b}^{(0)} = \vec{b},\quad \vec{v}^{(0)} = \vec{v}\) where \(\vec{v}\) is the commitment key used for pairing commitments by the prover (see How To Commit)

If \(m=1\) then we simply return

\[\pi_1 = \left(\vec{A}^{(0)},\vec{b}^{(0)}\right), \vec{v}^{(0)}, \{ \}\]


FOR LOOP STARTS

For \(j \in 1..{\log_2 m}\)

  • The prover computes1 commitments \(C_{L^{(j)}} \in \mathbb{G}_T\times \mathbb{G}_1\) and \(C_{R^{(j)}} \in \mathbb{G}_T\times \mathbb{G}_1\) where

\[ C_{L^{(j)}} := \prod_{i=0}^{m/2^{j}-1}e\left(A^{(j-1)}_{\left(\frac{m}{2^{j}}+i\right)}, v^{(j-1)}_{i}\right), \quad\prod_{i=0}^{m/2^{j}-1}\left(A^{{(j-1)}}_{\left(\frac{m}{2^{j}}+i\right)}\right)^{b_i^{{(j-1)}}} \]

\[ C_{R^{(j)}} := \prod_{i=0}^{m/2^{j}-1}e\left(A^{(j-1)}_{i}, v^{(j-1)}_{\left(\frac{m}{2^{j}}+i\right)}\right), \quad \prod_{i=0}^{m/2^{j}-1}\left(A^{(j-1)}_{i}\right)^{b^{(j-1)}_{\left(\frac{m}{2^{j}}+i\right)}} \]

  • It sends \(C_{L^{(j)}}, C_{R^{(j)}}\) to the verifier.

  • Verifier sends the prover a challenge \(r_j\xleftarrow[]{\$}\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\). Then it folds the witness, public vector of exponents and commitment key to half the size using the verifiers challenge \(r_j \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\)

\[\vec{A}^{(j)} = \left[A_i^{(j-1)} \left(A^{(j-1)}_{m/2^{j}+i}\right)^{r_j} \right]_{i=0}^{\frac{m}{2^{j}}-1}\] \[\vec{b}^{(j)} = \left[b^{(j-1)}_i + \left(b^{(j-1)}_{m/2^{j}+i}\right){r_j^{-1}} \right]_{i=0}^{\frac{m}{2^{j}}-1}\]

\[\vec{v}^{(j)} = \left[v^{(j-1)}_i \left(v^{(j-1)}_{m/2^{j}+i}\right)^{r_j^{-1}} \right]_{i=0}^{\frac{m}{2^{j}}-1}\]

FOR LOOP ENDS


After the for loop ends we output as the proof \(\pi_1\) \[ \pi_1 := \left\{ \begin{aligned} & A^{(\log m)} \in \mathbb{G}_1\\[10pt] & v^{(\log m)} \in \mathbb{G}_2\\[10pt] & \left[ C_{R^{(j)}}, C_{L^{(j)}}\right]_{j=1}^{\log m} \in \mathbb{G}_T^{2\log m} \\[10pt] &\ \text{KZG evaluation proof for $q$ at challenge $z \xleftarrow[]{\$}\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}$} \in \mathbb{G}_2 \end{aligned} \right\} \]

See below for details about \(q\). The cost of this is 1 KZG opening over \(\mathbb{G}_2\) – and the degree of the \(q\) is at most \(2m-2\),

A Note About Optimising Communication and defining \(q\)

In a naive implementation the prover sends as part of the proof the intermediate commitment keys \(\vec{v}^{(1)}, \ldots, \vec{v}^{(\ell -1)}\) to the verifier. But notice that in the above description of the proof, we claim that the prover only sends only \(\vec{v}^{(\log m)}\) to the verifier.

This is done to reduce verification time. To be more specific, once the verifier receives \(\vec{v}^{(j)}\) it must use \(\vec{v}^{(j-1)}\) and \(r_j\) to check if the prover constructed \(\vec{v}^{(j)}\) correctly. This causes the verifiers work to be linear in \(m\).

With a little bit of algebra it is not too hard to see that \(\vec{v}^{(\log m)}\) is actually a KZG commitment to the polynomial \(q(x) = \prod_{i=1}^{\log m}(1 + r^{-1}_{(\log m-i+1)}x^{2i})\). That is after all \(\log m\) folding operations the final value of the folded commitment key is

\[\vec{v}^{(\log m)} = h^{q(\beta)}= h^{\prod_{i=1}^{\log m}(1 + r^{-1}_{(\log m-i+1)}\beta^{2i})} \in \mathbb{G}_2\]

Now instead of the prover sending over all the intermediate keys, and asking the verifier to check if \(\vec{v}^{(j)}\) was properly constructed from \(\vec{v}^{(j-1)}\), it just sends the final shortened commitment key.

To check the prover did the intermediate calculations correctly, it suffices for the prover give a KZG evaluation proof for \(q\) evaluated at a random challenge point \(z \xleftarrow[]{\$}\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\), to check if the prover folded correctly.

Lookout for this KZG opening in the verification

How To Verify An Inner Product Proof

We have \(\vec{b} = (b_0, \ldots, b_{m-1}) = (1, z_x , \ldots z_x^{m-1})\). Given \(T = \prod_{i=0}^{m-1}e(A_i, v_i)\), the verifier wants to use the proof \(\pi_1\) defined above to verify that opening of \(T\) is \((A_0, \ldots, A_{m-1}) \in \mathbb{G}_1^m\) such that \(U=\prod_{i=0}^{m-1} A_i^{b_i}\)

The verifier also possesses all the challenges \(r_1, \ldots, r_{\log m}\) it had sent the prover during the proof. In practice, we fiat-shamir these to remove interaction.

The verifier performs a sequence of checks:

  1. Check commitment collapsing: Define \(T^{(0)}, U^{(0)} = (T, U)\) where \(T\) and \(U\) are the original pairing commitment to \(f\) and the KZG commitment to \(f(z_x, Y)\) respectively.

\[ \begin{align} \forall j \in 1, \ldots \ell \qquad & T^{(j)} = C_{L^{j}}^{r_j}T^{(j-1)}C_{R^{j}}^{r_j^{-1}} \\[10pt] & U^{(j)} = C_{L^{j}_1}^{r_j}\cdot U^{(j-1)}\cdot C_{R^{j}_1}^{r_j^{-1}} \end{align} \]

  1. Compute the foldings of \(\vec{b}\): If the prover folds all the \(b_i\)’s correctly, then the final check boils down to \[b' = \prod_{i=1}^{\log m}(1 + r_i {b}^{j})\]

  2. Check folding for commitment keys

    To check that all commitment keys \(\vec{v}^{(1)}, \ldots, \vec{v}^{(\log m -1)}\) were folded correctly, given \(\vec{v}^{(\log m)}\) the prover asks for a KZG opening proof to evaluate \(q\) at \(z \xleftarrow[]{\$}\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\), where \(q(x) = \prod_{i=1}^{\log m}(1 + r^{-1}_{(\log m-i+1)}x^{2i})\)

  3. Finally check \[T^{(j)} \quad \textcolor{red}{\overset{?}{=}}\quad e(\pi_1.A^{(\log m)}, \pi_1.v^{\log m})\]

and

\[U^{(j)} \quad \textcolor{red}{\overset{?}{=}}\quad \left(\pi_1.A^{(\log m)}\right)^{b^{' }}\]

where \(b'\) was computed in step 2.

How To Commit To A Univariate Polynomial

Now we are given \(f \in \mathbb{F}_{\textcolor{blue}{\mathtt{q}}}[X]\) with degree \(d\). We select \(\ell, m\) of roughly equal size such that \(\ell m =d\).

Just make sure \(m\) is a power of 2.

Let \(f(X) = f_0 + f_1X + \ldots + f_{d}x^d\). Now we chunk the coefficients of \(f\) into a \(m\) sets of size \(\ell\), that is

\(f_i(Y) = \sum_{j=0}^{\ell -1} f_{i\ell + j}Y^j\), and \(p(X,Y) = \sum_{i=0}^{m} f_i(Y)X^{i}\).

This implies that \(p(X^\ell, X) = f(X)\).

See worked out example below

Example

Let \(f(X) = f_0 + \ldots + f_7x^7\). Let \(m=4\) and \(\ell = 2\)

\[ \begin{align} f_0(Y) &= f_0 + f_1Y \\[10pt] f_1(Y) &= f_2 + f_3Y \\[10pt] f_2(Y) &= f_4 + f_5Y \\[10pt] f_3(Y) &= f_6 + f_7Y \\[10pt] \end{align} \]

Let \[p(X, Y) = \sum_{i=0}^m f_i(Y)X^i\]

Easy to see that \(p(X^2, X) = f(X)\)

To commit to \(f\) we commit to bivariate polynomial \(p\). To evaluate \(f\) at \(z\) we evaluate \(p\) at \((z^\ell, z)\).

Full Accounting For Prover Costs For Multi-variate Polynomial

To fully understand this accounting please make sure you’ve read this article.

We want to commit to a \(\log d\) variable multi-linear polynomial \(f\). To commit we compute the univariate encoding of \(f\) and we pick \(m\) which is a power of 2 and \(\ell \in \mathbb{N}\) such that \(\ell m = d\). Then we represent \(f\) with the bivariate polynomial \(p^{(0)}\) as described above. Typically \(\ell, m \in O\left(\sqrt{d}\right)\).

Cost Of Committing to \(p^{(0)}\)

To commit to \(p\) where \(X\) variables have degree at most \(m \in O\left(\sqrt{d}\right)\) and \(Y\) variables have degree at most \(\ell \in O\left(\sqrt{d}\right)\).

  • \(m\) KZG commitments for polynomials with degree at most \(\ell-1\) to get \(A_0, \ldots, A_{m-1}\). This is \(m\) MSMs with where each MSM uses at most \(\ell\) \(\mathbb{G}_1\) elements.

  • \(m\) Pairing operations + \(m\) \(\mathbb{G}_T\) multiplications

Next we discuss the cost of opening a polynomial

The cost of opening \(f\) at \((z_1, \ldots, z_{\log d})\) leads to the prover constructing \(\log d\) univariate polynomials \(p^{(1)}, \ldots, p^{(\log d)}\) with number of coefficients \(d/2, d/4, \ldots, 1\) and committing to these polynomials \(\{C_{p^{(i)}}\}_{i=1}^{\log d}\)

To commit to each univariate polynomial, set \(m_i\ell_i = d/2^{i}\),

This is \(m_i\) MSMs each with \(\ell_i\) \(\mathbb{G}_1\) elements.

Then \(m_i\) pairing operations followed by \(m_i\) \(\mathbb{G}_T\) multiplications as described above.

Next the prover will have open the above \(p^{(1)}, \ldots, p^{(\log d)}\) at \(r\) and \(-r\) and open \(p^{(0)}, \ldots, p^{(\log d -1)}\) at \(r^2\).

As the above commitment scheme is also homomorphic, the prover constructs a single polynomial \(B\) using the verifiers challenge \(z_r \xleftarrow[]{\$}\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\).

\[B(X) = p^{(0)}(X) + z_r p^{(1)}(X) + z_r^2 p^{(2)}(X) + \ldots + (z_r)^{\log d} p^{(\log d)}(X)\]

This is not an issue for the verifier as it can construct a commitment for \(B\) from \(\{C_{p^{(i)}}\}_{i=0}^{\log d}\) (using homomorphism)

\(B\) has \(d\) coefficients, and setting \(m\ell = d\) we once again get \(m, \ell \in O\left(\sqrt{d}\right)\)

So we have to open at 3 locations – where the cost of evaluating one is given by

Cost Of Opening The Evaluation Of 1 Bivariate Polynomial At One Location

  • 1 KZG commitment which is 1 MSM with \(m\) \(\mathbb{G}_1\) elements to get \(U\).

  • 1 KZG opening for commitment \(U\). This MSM uses \(m-1\) \(\mathbb{G}_1\) elements and the cost of finding the quotient polynomial \(\frac{f(z_x, Y) - f(z_x, z_y)}{Y - z_y}\)

  • 1 KZG opening for a \(v^{(\log m)}\) is commitment to the quotient polynomial \(\frac{q(X) - q(z)}{X - z}\). This includes the cost of computing the quotient polynomial using Horners rule, and one MSM using at most \(2m-1\) \(\mathbb{G}_2\) elements to commit to the quotient.

  • \(A^{(\log m)}\) requires \(m\) \(\mathbb{G}_1\) multiplications and exponentiations.

  • \(b^{(\log m)}\) requires \(m\) \(\mathbb{F}_{\textcolor{blue}{\mathtt{q}}}\) multiplications and additions.

  • \(v^{(\log m)}\) requires \(m\) \(\mathbb{G}_2\) multiplications and exponentiations.

  • The commitments take \(2m\) pairing operations and \(2m\) \(\mathbb{G}_T\) multiplications.

References

Bünz, B., Maller, M., Mishra, P., Tyagi, N., Vesely, P., 2019. Proofs for inner pairing products and applications.
Zhao, J., Setty, S., Cui, W., Zaverucha, G., 2024. MicroNova: Folding-based arguments with efficient (on-chain) verification.

  1. You can read this as a compressed version of \(T\) and \(U\) using only half the witness and public vector. That is, we split \(\vec{A}, \vec{v}, \vec{b}\) down the middle into left and right halves. For the first commitment, denoted with \(L\) we use the right half of \(\vec{A}\) but the left halves of \(\vec{b}\) and \(\vec{v}\). For the second commitment we use the left half of \(\vec{A}\) and the right halves of \(\vec{v}\) and \(\vec{b}\).↩︎