Multipoint opening argument

Consider the commitments to polynomials . Let's say that and were queried at the point , while and were queried at both points and . (Here, is the primitive root of unity in the multiplicative subgroup over which we constructed the polynomials).

We can group the commitments in terms of the sets of points at which they were queried:

The multipoint opening optimisation proceeds as such:

  1. Sample random , at which we evaluate .

  2. The prover provides evaluations of each polynomial at each point of interest:

  3. Sample random , to keep linearly independent.

  4. Accumulate polynomials and their corresponding evaluations according to the point set at which they were queried: q_polys: q_eval_sets:

            [
                [a(x_3) + x_4 b(x_3)],
                [
                    c(x_3) + x_4 d(x_3),
                    c(\omega x_3) + x_4 d(\omega x_3)
                ]
            ]
    

    NB: q_eval_sets is a vector of sets of evaluations, where the outer vector goes over the point sets, and the inner vector goes over the points in each set.

  5. Interpolate each set of values in q_eval_sets: r_polys:

  6. Construct f_polys which check the correctness of q_polys: f_polys

    If , then should be a polynomial. If and then should be a polynomial.

  7. Sample random to keep the f_polys linearly independent.

  8. Construct .

  9. Sample random , at which we evaluate :

  10. Sample random to keep and q_polys linearly independent.

  11. Construct final_poly, which is the polynomial we commit to in the inner product argument.