7#include <gtest/gtest.h>
35 for (
auto& poly : full_polynomials.get_precomputed()) {
40 for (
auto& poly : full_polynomials.get_witness()) {
45 for (
auto& poly : full_polynomials.get_shifted()) {
51 constexpr size_t gate_start = UseRowDisablingPolynomial<Flavor> ? NUM_DISABLED_ROWS_IN_SUMCHECK : 1;
54 if (circuit_size > gate_start) {
55 full_polynomials.w_l.at(gate_start) =
FF(1);
56 full_polynomials.w_r.at(gate_start) =
FF(1);
57 full_polynomials.w_o.at(gate_start) =
FF(2);
58 full_polynomials.q_l.at(gate_start) =
FF(1);
59 full_polynomials.q_r.at(gate_start) =
FF(1);
60 full_polynomials.q_o.at(gate_start) =
FF(-1);
61 full_polynomials.q_arith.at(gate_start) =
FF(1);
65 if (circuit_size > gate_start + 1) {
66 full_polynomials.w_l.at(gate_start + 1) =
FF(2);
67 full_polynomials.w_r.at(gate_start + 1) =
FF(2);
68 full_polynomials.w_o.at(gate_start + 1) =
FF(4);
69 full_polynomials.q_m.at(gate_start + 1) =
FF(1);
70 full_polynomials.q_o.at(gate_start + 1) =
FF(-1);
71 full_polynomials.q_arith.at(gate_start + 1) =
FF(1);
77 for (
size_t i = 1; i < NUM_DISABLED_ROWS_IN_SUMCHECK; ++i) {
88 full_polynomials.set_shifted();
90 return full_polynomials;
93template <
typename Flavor>
class SumcheckTests :
public ::testing::Test {
105 for (
auto& coeff : poly.coeffs()) {
114 for (
auto [full_poly, input_poly] :
zip_view(full_polynomials.get_all(), input_polynomials)) {
115 full_poly = input_poly.share();
117 return full_polynomials;
120 void test_polynomial_normalization()
123 const size_t multivariate_d(3);
124 const size_t multivariate_n(1 << multivariate_d);
129 for (
auto& poly : random_polynomials) {
130 poly = random_poly(multivariate_n);
132 auto full_polynomials = construct_ultra_full_polynomials(random_polynomials);
134 auto transcript = Flavor::Transcript::test_prover_init_empty();
136 FF alpha = transcript->template get_challenge<FF>(
"Sumcheck:alpha");
138 std::vector<FF> gate_challenges(multivariate_d);
139 for (
size_t idx = 0; idx < multivariate_d; idx++) {
140 gate_challenges[idx] =
141 transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
145 multivariate_n, full_polynomials, transcript, alpha, gate_challenges, {}, multivariate_d);
147 auto output = sumcheck.
prove();
149 FF u_0 = output.challenge[0];
150 FF u_1 = output.challenge[1];
151 FF u_2 = output.challenge[2];
163 std::vector<FF> u_challenge = { u_0, u_1, u_2 };
164 for (
auto [full_poly, claimed_eval] :
165 zip_view(full_polynomials.get_all(), output.claimed_evaluations.get_all())) {
167 auto v_expected = poly.evaluate_mle(u_challenge);
168 EXPECT_EQ(v_expected, claimed_eval);
175 const size_t multivariate_d = UseRowDisablingPolynomial<Flavor> ? 4 : 2;
176 const size_t multivariate_n(1 << multivariate_d);
181 for (
auto& poly : random_polynomials) {
182 poly = random_poly(multivariate_n);
184 auto full_polynomials = construct_ultra_full_polynomials(random_polynomials);
186 auto transcript = Flavor::Transcript::test_prover_init_empty();
188 FF alpha = transcript->template get_challenge<FF>(
"Sumcheck:alpha");
190 auto gate_challenges =
191 transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", CONST_PROOF_SIZE_LOG_N);
194 multivariate_n, full_polynomials, transcript, alpha, gate_challenges, {}, CONST_PROOF_SIZE_LOG_N);
200 ZKData zk_sumcheck_data = ZKData(CONST_PROOF_SIZE_LOG_N, transcript);
201 output = sumcheck.
prove(zk_sumcheck_data);
203 output = sumcheck.
prove();
205 FF u_0 = output.challenge[0];
206 FF u_1 = output.challenge[1];
207 std::vector<FF> expected_values;
208 for (
auto& polynomial_ptr : full_polynomials.get_all()) {
209 auto& polynomial = polynomial_ptr;
211 FF expected_lo = polynomial[0] * (
FF(1) - u_0) + polynomial[1] * u_0;
212 expected_lo *= (
FF(1) - u_1);
213 FF expected_hi = polynomial[2] * (
FF(1) - u_0) + polynomial[3] * u_0;
215 expected_values.emplace_back(expected_lo + expected_hi);
218 for (
auto [eval, expected] :
zip_view(output.claimed_evaluations.get_all(), expected_values)) {
224 void test_prover_verifier_flow()
226 const size_t multivariate_d = UseRowDisablingPolynomial<Flavor> ? 4 : 3;
227 const size_t multivariate_n(1 << multivariate_d);
229 const size_t virtual_log_n = 6;
231 auto full_polynomials = create_satisfiable_trace<Flavor>(multivariate_n);
235 auto prover_transcript = Flavor::Transcript::test_prover_init_empty();
236 FF prover_alpha = prover_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
238 std::vector<FF> prover_gate_challenges(virtual_log_n);
239 prover_gate_challenges =
240 prover_transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", virtual_log_n);
246 prover_gate_challenges,
252 ZKData zk_sumcheck_data = ZKData(virtual_log_n, prover_transcript);
253 output = sumcheck_prover.prove(zk_sumcheck_data);
255 output = sumcheck_prover.prove();
258 auto verifier_transcript = Flavor::Transcript::test_verifier_init_empty(prover_transcript);
260 FF verifier_alpha = verifier_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
264 std::vector<FF> verifier_gate_challenges(virtual_log_n);
265 verifier_gate_challenges =
266 verifier_transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", virtual_log_n);
268 auto verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_gate_challenges);
270 auto verified = verifier_output.verified;
272 EXPECT_EQ(verified,
true);
275 void test_failure_prover_verifier_flow()
277 const size_t multivariate_d = UseRowDisablingPolynomial<Flavor> ? 4 : 3;
278 const size_t multivariate_n(1 << multivariate_d);
281 auto full_polynomials = create_satisfiable_trace<Flavor>(multivariate_n);
284 constexpr size_t gate_row = UseRowDisablingPolynomial<Flavor> ? NUM_DISABLED_ROWS_IN_SUMCHECK : 1;
285 full_polynomials.w_l.at(gate_row) =
FF(0);
289 auto prover_transcript = Flavor::Transcript::test_prover_init_empty();
290 FF prover_alpha = prover_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
292 auto prover_gate_challenges =
293 prover_transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", multivariate_d);
299 prover_gate_challenges,
306 ZKData zk_sumcheck_data = ZKData(multivariate_d, prover_transcript);
307 output = sumcheck_prover.prove(zk_sumcheck_data);
309 output = sumcheck_prover.prove();
312 auto verifier_transcript = Flavor::Transcript::test_verifier_init_empty(prover_transcript);
314 FF verifier_alpha = verifier_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
318 std::vector<FF> verifier_gate_challenges(multivariate_d);
319 for (
size_t idx = 0; idx < multivariate_d; idx++) {
320 verifier_gate_challenges[idx] =
321 verifier_transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
324 auto verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_gate_challenges);
326 auto verified = verifier_output.verified;
328 EXPECT_EQ(verified,
false);
341TYPED_TEST(SumcheckTests, PolynomialNormalization)
343 if constexpr (!TypeParam::HasZK) {
344 this->test_polynomial_normalization();
346 GTEST_SKIP() <<
"Skipping test for ZK-enabled flavors";
355TYPED_TEST(SumcheckTests, ProverAndVerifierSimple)
357 this->test_prover_verifier_flow();
360TYPED_TEST(SumcheckTests, ProverAndVerifierSimpleFailure)
362 this->test_failure_prover_verifier_flow();
A container for the prover polynomials.
static constexpr bool HasZK
typename Curve::ScalarField FF
static constexpr size_t NUM_ALL_ENTITIES
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
static Polynomial shiftable(size_t virtual_size, bool masked=false)
Utility to create a shiftable polynomial of given virtual size.
The implementation of the sumcheck Prover for statements of the form for multilinear polynomials .
SumcheckOutput< Flavor > prove()
Non-ZK version: Compute round univariate, place it in transcript, compute challenge,...
A flexible, minimal test flavor for sumcheck testing.
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
typename ECCVMFlavor::ProverPolynomials ProverPolynomials
testing::Types< UltraFlavor, UltraKeccakFlavor, MegaFlavor > FlavorTypes
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
SumcheckTestFlavor_< curve::BN254, true, true > SumcheckTestFlavorZK
Zero-knowledge variant.
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
SumcheckTestFlavor_< curve::BN254, false, true > SumcheckTestFlavor
Base test flavor (BN254, non-ZK, short monomials)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
Container for parameters used by the grand product (permutation, lookup) Honk relations.
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
This structure is created to contain various polynomials and constants required by ZK Sumcheck.
static field random_element(numeric::RNG *engine=nullptr) noexcept
Minimal test flavors for sumcheck testing without UltraFlavor dependencies.