Batch opening scheme - BDFG 21

DoHoon Kim·2025년 4월 23일

halo2

목록 보기
3/4

In this post, we will review the batch opening scheme used in halo2 library. The paper for this scheme is introduced in the paper.

In this protocol, the prover and the verifier has access to SRS of the group elements from the groups that support the non-degenerate bilinear pairing.

Algebraic Group Model

The batch opening scheme is proven to be secure(has perfect completeness and knowledge soundness) in Algebraic Group Model. In algebraic group model, the adversary A\mathcal{A} for the protocol, is assumed to be algebraic adversary. This means that whenever A\mathcal{A} outputs an element AGiA \in \mathbb{G}_i for i=1,2i = 1, 2, it also outputs the vector vFkv \in \mathbb{F}^k such that A=v,SRSiA = \langle v, SRS_i \rangle.

Now, let's see the definition of knowledge soundness in algebraic group model.

A protocol P\mathcal{P} between the prover P\mathbf{P} and the verifier V\mathbf{V} for a relation R\mathcal{R} has knowledge soundness in algebraic group model, if there exists an efficient E\mathbf{E} such that the probability of any algebraic adversary A\mathcal{A} winning the following game is negligible.

  1. A\mathcal{A} chooses input xx and plays the role of P\mathbf{P} with input xx.
  2. E\mathbf{E} given access to all of A\mathcal{A}’s messages during the protocol (including the coefficients of the linear combinations) outputs ω\omega.
  3. A\mathcal{A} wins if
    (a) V\mathbf{V} accepts at the end of the protocol, and
    (b) (x,ω)R(x, \omega) \notin \mathcal{R}

Extractor is an idealized object used for proving knowledge soundness, not implemented in the real-world case. In short, if the protocol has knowledge soundness in algebraic group model, there must be only two cases: the transcript is accepting and (x,ω)R(x, \omega) \in \mathcal{R}, or, the transcript is not accepting and (x,ω)R(x, \omega) \notin \mathcal{R}.

The rationality behind this definition is because, in the case of transcript is accepting and (x,ω)R(x, \omega) \notin \mathcal{R}, the extractor can solve discrete logarithm problem and break Q-DLOG assumption. We will visit this in the future post.

Batch opening scheme

Opening scheme

Let the initial setup is given as following.

  • T={z1,,zt}FT = \{ z_1, \dots, z_t \} \subset \mathbb{F} and S1,,SkTS_1, \dots, S_k \subset T.
  • cm1,,cmkcm_1, \dots, cm_k are the commitments to the polynomials f1,,fkf_1, \dots, f_k.
  • {riF<Si[X]}i[k]\{r_i \in \mathbb{F}_{\lt |S_i|} [X]\}_{i \in [k]} such that ri(z)=fi(z)r_i(z) = f_i(z) for each i[k],zSii \in [k], z \in S_i.

SiS_i is the opening set for each polynomial fif_i, and T=i=1kSiT = \cup_{i=1}^k S_i. rir_i is the polynomial that opens to fif_i in SiS_i.

Let's visit the following claims.

Fix subsets STFS \subset T \subset \mathbb{F}, and a polynomial gF<d[X]g \in \mathbb{F}_{\lt d}[X]. Then ZS(X)Z_S(X) divides g(X)g(X) if and only if ZT(X)Z_T(X) divides ZT\Sg(X)Z_{T \backslash S} \cdot g(X).

Fix F1,,FkF<n[X]F_1, \dots, F_k \in \mathbb{F}_{\lt n}[X]. Fix ZF<n[X]Z \in \mathbb{F}_{\lt n}[X] that decomposes to distinct linear factors over F\mathbb{F}. Suppose that for some i[k]i \in [k], Z∤  FiZ \not| \;F_i. Then, except with the probability k/Fk / |\mathbb{F}| over uniform γF\gamma \in \mathbb{F}, ZZ does not divide i=1kγi1Fi\sum_{i=1}^k \gamma^{i - 1} \cdot F_i.

Using this claim, let's visit batch opening scheme.

  • V\mathbf{V} sends random γF\gamma \in \mathbb{F}.
  • P\mathbf{P} computes the polynomial
    f(X):=i[k]γi1ZT\Si(X)(fi(X)ri(X))f(X) := \sum_{i \in [k]} \gamma^{i-1} \cdot Z_{T \backslash S_i}(X) \cdot (f_i(X) - r_i(X))

and h(X)=f(X)/ZT(X)h(X) = f(X) / Z_T(X). Sends W=[h(X)]1W = [h(X)]_1.

  • V\mathbf{V} sends random zFz \in \mathbb{F}.
  • P\mathbf{P} computes the polynomial
    L(X):=fz(X)ZT(z)h(X)L(X) := f_z(X) - Z_T(z) \cdot h(X)

where

fz(X):=i[k]γi1ZT\Si(z)(fi(X)ri(z))f_z(X) := \sum_{i \in [k]} \gamma^{i-1} \cdot Z_{T \backslash S_i}(z) \cdot (f_i(X) - r_i(z))

and L(X)Xz\frac{L(X)}{X - z}. Sends W:=[L(X)Xz]1W' := [\frac{L(X)}{X - z}]_1.

  • V\mathbf{V} computes
F:=i[k]γi1ZT\Si(z)(cmi[ri(z)]1)ZT(z)WF := \sum_{i \in [k]} \gamma^{i-1} \cdot Z_{T \backslash S_i}(z) \cdot (cm_i - [r_i(z)]_1) - Z_T(z) \cdot W

and checks

e(F,[1]2)=e(W,[xz]2)e(F, [1]_2) = e(W', [x - z]_2)

Proof of knowledge soundness

Let's prove the knowledge soundness of the protocol. First, algebraic adversary A\mathcal{A} chooses the group elements cm1,,cmkcm_1, \dots, cm_k and plays the role of P\mathbf{P}. There is an efficient AGM-extractor that has access to A\mathcal{A}'s choice of coefficients in F\mathbb{F} to make cm1,,cmkcm_1, \dots, cm_k. Let's say

cmi=j=0d1aij[xj]1cm_i = \sum_{j=0}^{d-1} a_{ij} [x^j]_1

.

AGM-extractor outputs the polynomials fi(X)=j=0d1aijXjf_i(X) = \sum_{j=0}^{d-1} a_{ij} X^{j}.
A\mathcal{A} now participate as P\mathbf{P}. After V\mathbf{V} sends random γF\gamma \in \mathbb{F}, A\mathcal{A} computes the polynomial

f(X):=i[k]γi1ZT\Si(X)(fi(X)ri(X))f(X) := \sum_{i \in [k]} \gamma^{i-1} \cdot Z_{T \backslash S_i}(X) \cdot (f_i(X) - r_i(X))

Suppose that there exists some i[k]i^* \in [k] such that ZSi(X)∤  (fi(X)ri(X))Z_{S_{i^*}}(X) \not| \;(f_{i^*}(X) - r_{i^*}(X)). Then, by the claims we saw, f(X)f(X) is not divisible by ZT(X)Z_T(X) except with the probability k/Fk / |\mathbb{F}| over uniform γF\gamma \in \mathbb{F}. Suppose that γF\gamma \in \mathbb{F} is not in that form, and A\mathcal{A} computes W:=[H(x)]1W := [H(x)]_1 for arbitrary H(X)H(X).

V\mathbf{V} sends random zFz \in \mathbb{F} and A\mathcal{A} computes L(X):=fz(X)ZT(z)H(X)L(X) := f_z(X) - Z_T(z) \cdot H(X). L(z)=0L(z) = 0 except with the negligible probability over uniform zFz \in \mathbb{F}. Suppose that zz is not in that form, and A\mathcal{A} computes W:=[H(x)]1W' := [H'(x)]_1 for arbitrary H(X)H'(X).

Let's show that the final pairing check passes with negligible probability to prove the knowledge soundness. Since the pairing check is the randomized test of fz(X)ZT(z)H(X)=H(X)(Xz)f_z(X) - Z_T(z) \cdot H(X) = H'(X) \cdot (X - z), and this pairing check satisfies only if fz(X)ZT(z)H(X)f_z(X) - Z_T(z) \cdot H(X) is divisible by XzX - z, fz(z)=ZT(z)H(z)f_z(z) = Z_T(z) \cdot H(z). However, this holds except with negligible probability. Thus the pairing check passes with negligible probability, thereby proving the knowledge soundness.

Implementation

There is a implementation of this batch opening scheme inside halo2. It would be worthy to review the implementation and get some deeper understanding.

The structs we first encounter is the following: RotationSet and IntermediateSets.

#[derive(Debug, Clone, PartialEq)]
struct RotationSet<F: Field, T: PartialEq + Clone> {
    commitments: Vec<Commitment<F, T>>,
    points: Vec<F>,
}

#[derive(Debug, PartialEq)]
struct IntermediateSets<F: Field, Q: Query<F>> {
    rotation_sets: Vec<RotationSet<F, Q::Commitment>>,
    super_point_set: BTreeSet<F>,
}

IntermediateSets has two fields, rotation_sets and super_point_set. These struct holds the information about all the evaluation points TT(super_point_set), and rotation_sets is the sets of the polynomials that will be opened in the same opening set SiS_i. Inside RotationSet, there are the polynomial commitments that will be opened against the same opening set(commitments), and the opening points(points).

There are additional two intermediate types, CommitmentExtension and RotationSetExtension.

struct CommitmentExtension<'a, C: CurveAffine> {
    commitment: Commitment<C::Scalar, PolynomialPointer<'a, C>>,
    low_degree_equivalent: Polynomial<C::Scalar, Coeff>,
}

struct RotationSetExtension<'a, C: CurveAffine> {
    commitments: Vec<CommitmentExtension<'a, C>>,
    points: Vec<C::Scalar>,
}

CommitmentExtension groups the polynomial commitment fif_i (commitment) and evaluation polynomial on the opening set rir_i (low_degree_equivalent). RotationSetExtension is the same with RotationSet except that commitments field is replaced with the vector of CommitmentExtension type.

create_proof

After having this in mind, let's look into create_proof function.

There is additional challenge y sampled by the verifier in the actual protocol, to random linearly combine the polynomials in the same RotationSet.

let intermediate_sets = construct_intermediate_sets(queries);
let (rotation_sets, super_point_set) = (
    intermediate_sets.rotation_sets,
    intermediate_sets.super_point_set,
);

let rotation_sets: Vec<RotationSetExtension<E::G1Affine>> = rotation_sets
    .into_par_iter()
    .map(|rotation_set| {
        let commitments: Vec<CommitmentExtension<E::G1Affine>> = rotation_set
            .commitments
            .as_slice()
            .into_par_iter()
            .map(|commitment_data| commitment_data.extend(&rotation_set.points))
            .collect();
        rotation_set.extend(commitments)
    })
    .collect();

First, the prover builds rotation_sets and super_point_set from the queries. It extends each rotation set by extending the commitments of fijf_{i_j} polynomials with rijr_{i_j} polynomials.

  • Computing W=[h(X)]1W = [h(X)]_1
let v: ChallengeV<_> = transcript.squeeze_challenge_scalar();

#[allow(clippy::needless_collect)]
let quotient_polynomials = rotation_sets
    .as_slice()
    .into_par_iter()
    .map(quotient_contribution)
    .collect::<Vec<_>>();

let h_x: Polynomial<E::Fr, Coeff> = quotient_polynomials
    .into_iter()
    .zip(powers(*v))
    .map(|(poly, power_of_v)| poly * power_of_v)
    .reduce(|acc, poly| acc + &poly)
    .unwrap();

let h = self.params.commit(&h_x, Blind::default()).to_affine();
transcript.write_point(h)?;

verify_proof

For the rotation set S={x1,,xn}S = \{x_1, \dots, x_{n}\}, suppose that we are given polynomial evaluations on the set as z1,,znz_1, \dots, z_{n}. Verifier should construct the polynomial by Lagrange interpolation, thus Lagrange basis polynomials should be computed in EVM verifier side for each rotation set.

Both halo2 Rust verifier and EVM verifier utilizes memory-efficient algorithm to compute Lagrange basis polynomials using elementary algebra trick.

The constructed polynomial would have the form

f(X)=j=1nzjk=1,kjnXxkxjxkf(X) = \sum_{j=1}^{n} z_j \cdot \prod_{k=1, k \neq j}^{n} \frac{X-x_k}{x_j-x_k}

Lagrange basis polynomials refer to k=1,kjnXxkxjxk\prod_{k=1, k \neq j}^{n} \frac{X-x_k}{x_j-x_k} for each jj. What we want to compute is the coefficient form of Lagrange basis polynomial. We will denote the coefficient form of the polynomial as the row vector [c0,,cn2][c_0, \dots, c_{n-2}]. The algorithm proceeds inductively on nn.

Suppose that j=1j=1 and we are trying to compute k=2n(Xxk)\prod_{k=2}^{n} (X-x_k). Since k=2n(Xxk)=(Xxn)k=2n1(Xxk)\prod_{k=2}^{n} (X-x_k) = (X-x_{n}) * \prod_{k=2}^{n-1} (X-x_k), the coefficient of Xi,1inX^i, 1 \le i \le n can be computed as (coefficient of  Xi1  of  k=2n1(Xxk))+(xn)(coefficient of  Xi  of  k=2n1(Xxk))(\text{coefficient of} \;X^{i-1} \;\text{of} \;\prod_{k=2}^{n-1} (X-x_k)) + (-x_{n}) * (\text{coefficient of} \;X^i \;\text{of} \;\prod_{k=2}^{n-1} (X-x_k)). The constant coefficient is i=2n(xi)\prod_{i=2}^{n}(-x_i).

Let [c0,,cn3][c_0, \dots, c_{n-3}] be the coefficient vector of k=2n1(Xxk)\prod_{k=2}^{n-1} (X-x_k) and [c0,,cn2][c_0', \dots, c_{n-2}'] be the coefficient vector of k=2n(Xxk)\prod_{k=2}^{n} (X-x_k). Then,

[c0c1c2cn3][c0c1cn4cn3][c0c1c2cn3cn2]\begin{bmatrix} c_0 & c_1 & c_2 & \dots & c_{n-3} \end{bmatrix} \\ \qquad \qquad \quad \begin{bmatrix} c_0 & c_1 & \dots & c_{n-4} & c_{n-3} \end{bmatrix} \\ \qquad \quad \begin{bmatrix} c_0' & c_1' & c_2' & \dots & c_{n-3}' & c_{n-2}' \end{bmatrix}

Each coefficient (third row) can be obtained by (xn)(first row)+(second row)(-x_{n}) \cdot (\text{first row}) + (\text{second row}).

profile
Researcher & Developer

0개의 댓글