9#include <gtest/gtest.h>
14template <
typename Flavor>
class SumcheckTests :
public ::testing::Test {
27 for (
auto& coeff : poly.coeffs()) {
28 coeff = FF::random_element();
36 for (
auto [full_poly, input_poly] :
zip_view(full_polynomials.get_all(), input_polynomials)) {
37 full_poly = input_poly.share();
39 return full_polynomials;
42 void test_polynomial_normalization()
45 const size_t multivariate_d(3);
46 const size_t multivariate_n(1 << multivariate_d);
51 for (
auto& poly : random_polynomials) {
52 poly = random_poly(multivariate_n);
54 auto full_polynomials = construct_ultra_full_polynomials(random_polynomials);
56 auto transcript = Flavor::Transcript::prover_init_empty();
58 SubrelationSeparators alpha;
59 for (
size_t idx = 0; idx < alpha.size(); idx++) {
60 alpha[idx] = transcript->template get_challenge<FF>(
"Sumcheck:alpha_" +
std::to_string(idx));
63 std::vector<FF> gate_challenges(multivariate_d);
64 for (
size_t idx = 0; idx < multivariate_d; idx++) {
65 gate_challenges[idx] =
66 transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
70 multivariate_n, full_polynomials, transcript, alpha, gate_challenges, {}, multivariate_d);
72 auto output = sumcheck.
prove();
74 FF u_0 = output.challenge[0];
75 FF u_1 = output.challenge[1];
76 FF u_2 = output.challenge[2];
90 FF l_0 = (one - u_0) * (one - u_1) * (one - u_2);
91 FF l_1 = (u_0) * (one - u_1) * (one - u_2);
92 FF l_2 = (one - u_0) * (u_1) * (one - u_2);
93 FF l_3 = (u_0) * (u_1) * (one - u_2);
94 FF l_4 = (one - u_0) * (one - u_1) * (u_2);
95 FF l_5 = (u_0) * (one - u_1) * (u_2);
96 FF l_6 = (one - u_0) * (u_1) * (u_2);
97 FF l_7 = (u_0) * (u_1) * (u_2);
99 FF hand_computed_value;
100 for (
auto [full_poly, partial_eval_poly] :
101 zip_view(full_polynomials.get_all(), sumcheck.partially_evaluated_polynomials.get_all())) {
103 hand_computed_value = l_0 * full_poly[0] + l_1 * full_poly[1] + l_2 * full_poly[2] + l_3 * full_poly[3] +
104 l_4 * full_poly[4] + l_5 * full_poly[5] + l_6 * full_poly[6] + l_7 * full_poly[7];
105 EXPECT_EQ(hand_computed_value, partial_eval_poly[0]);
110 std::vector<FF> u_challenge = { u_0, u_1, u_2 };
111 for (
auto [full_poly, claimed_eval] :
112 zip_view(full_polynomials.get_all(), output.claimed_evaluations.get_all())) {
114 auto v_expected = poly.evaluate_mle(u_challenge);
115 EXPECT_EQ(v_expected, claimed_eval);
121 const size_t multivariate_d(2);
122 const size_t multivariate_n(1 << multivariate_d);
127 for (
auto& poly : random_polynomials) {
128 poly = random_poly(multivariate_n);
130 auto full_polynomials = construct_ultra_full_polynomials(random_polynomials);
132 auto transcript = Flavor::Transcript::prover_init_empty();
134 SubrelationSeparators alpha;
135 for (
size_t idx = 0; idx < alpha.size(); idx++) {
136 alpha[idx] = transcript->template get_challenge<FF>(
"Sumcheck:alpha_" +
std::to_string(idx));
139 std::vector<FF> gate_challenges(multivariate_d);
140 for (
size_t idx = 0; idx < gate_challenges.size(); idx++) {
141 gate_challenges[idx] =
142 transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
146 multivariate_n, full_polynomials, transcript, alpha, gate_challenges, {}, CONST_PROOF_SIZE_LOG_N);
151 ZKData zk_sumcheck_data = ZKData(multivariate_d, transcript);
152 output = sumcheck.
prove(zk_sumcheck_data);
154 output = sumcheck.
prove();
156 FF u_0 = output.challenge[0];
157 FF u_1 = output.challenge[1];
158 std::vector<FF> expected_values;
159 for (
auto& polynomial_ptr : full_polynomials.get_all()) {
160 auto& polynomial = polynomial_ptr;
162 FF expected_lo = polynomial[0] * (
FF(1) - u_0) + polynomial[1] * u_0;
163 expected_lo *= (
FF(1) - u_1);
164 FF expected_hi = polynomial[2] * (
FF(1) - u_0) + polynomial[3] * u_0;
166 expected_values.emplace_back(expected_lo + expected_hi);
169 for (
auto [eval, expected] :
zip_view(output.claimed_evaluations.get_all(), expected_values)) {
175 void test_prover_verifier_flow()
177 const size_t multivariate_d(3);
178 const size_t multivariate_n(1 << multivariate_d);
180 const size_t virtual_log_n = 6;
184 for (
auto& poly : zero_polynomials) {
187 auto full_polynomials = construct_ultra_full_polynomials(zero_polynomials);
206 w_l[7] = FF::random_element();
207 w_r[6] = FF::random_element();
208 w_4[6] = FF::random_element();
209 auto z_1 = FF::random_element();
210 auto z_2 = FF::random_element();
211 auto r = FF::random_element();
245 .
beta = FF::random_element(),
246 .gamma = FF::random_element(),
247 .public_input_delta = FF::one(),
249 auto prover_transcript = Flavor::Transcript::prover_init_empty();
250 SubrelationSeparators prover_alpha{ 1 };
251 for (
size_t idx = 1; idx < prover_alpha.size(); idx++) {
252 prover_alpha[idx] = prover_transcript->template get_challenge<FF>(
"Sumcheck:alpha_" +
std::to_string(idx));
255 std::vector<FF> prover_gate_challenges(virtual_log_n);
256 for (
size_t idx = 0; idx < virtual_log_n; idx++) {
257 prover_gate_challenges[idx] =
258 prover_transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
265 prover_gate_challenges,
271 ZKData zk_sumcheck_data = ZKData(multivariate_d, prover_transcript);
272 output = sumcheck_prover.prove(zk_sumcheck_data);
274 output = sumcheck_prover.prove();
277 auto verifier_transcript = Flavor::Transcript::verifier_init_empty(prover_transcript);
279 SubrelationSeparators verifier_alpha{ 1 };
280 for (
size_t idx = 1; idx < verifier_alpha.size(); idx++) {
281 verifier_alpha[idx] =
282 verifier_transcript->template get_challenge<FF>(
"Sumcheck:alpha_" +
std::to_string(idx));
286 std::vector<FF> verifier_gate_challenges(virtual_log_n);
287 for (
size_t idx = 0; idx < virtual_log_n; idx++) {
288 verifier_gate_challenges[idx] =
289 verifier_transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
292 std::vector<FF> padding_indicator_array(virtual_log_n, 1);
294 for (
size_t idx = 0; idx < virtual_log_n; idx++) {
295 padding_indicator_array[idx] = (idx < multivariate_d) ?
FF{ 1 } :
FF{ 0 };
299 auto verifier_output =
300 sumcheck_verifier.verify(relation_parameters, verifier_gate_challenges, padding_indicator_array);
302 auto verified = verifier_output.verified;
304 EXPECT_EQ(verified,
true);
307 void test_failure_prover_verifier_flow()
311 const size_t multivariate_d(3);
312 const size_t multivariate_n(1 << multivariate_d);
317 for (
auto& poly : zero_polynomials) {
320 auto full_polynomials = construct_ultra_full_polynomials(zero_polynomials);
326 w_l = { 0, 0, 2, 0 };
351 .
beta = FF::random_element(),
352 .gamma = FF::random_element(),
353 .public_input_delta = FF::one(),
355 auto prover_transcript = Flavor::Transcript::prover_init_empty();
356 SubrelationSeparators prover_alpha;
357 for (
size_t idx = 0; idx < prover_alpha.size(); idx++) {
358 prover_alpha[idx] = prover_transcript->template get_challenge<FF>(
"Sumcheck:alpha_" +
std::to_string(idx));
360 std::vector<FF> prover_gate_challenges(multivariate_d);
361 for (
size_t idx = 0; idx < multivariate_d; idx++) {
362 prover_gate_challenges[idx] =
363 prover_transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
370 prover_gate_challenges,
377 ZKData zk_sumcheck_data = ZKData(multivariate_d, prover_transcript);
378 output = sumcheck_prover.prove(zk_sumcheck_data);
380 output = sumcheck_prover.prove();
383 auto verifier_transcript = Flavor::Transcript::verifier_init_empty(prover_transcript);
385 SubrelationSeparators verifier_alpha;
386 for (
size_t idx = 0; idx < verifier_alpha.size(); idx++) {
387 verifier_alpha[idx] =
388 verifier_transcript->template get_challenge<FF>(
"Sumcheck:alpha_" +
std::to_string(idx));
392 std::vector<FF> verifier_gate_challenges(multivariate_d);
393 for (
size_t idx = 0; idx < multivariate_d; idx++) {
394 verifier_gate_challenges[idx] =
395 verifier_transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
398 std::vector<FF> padding_indicator_array(multivariate_d);
399 std::ranges::fill(padding_indicator_array,
FF{ 1 });
400 auto verifier_output =
401 sumcheck_verifier.verify(relation_parameters, verifier_gate_challenges, padding_indicator_array);
403 auto verified = verifier_output.verified;
405 EXPECT_EQ(verified,
false);
414#ifdef STARKNET_GARAGA_FLAVORS
416 UltraStarknetZKFlavor,
423TYPED_TEST(SumcheckTests, PolynomialNormalization)
426 this->test_polynomial_normalization();
428 GTEST_SKIP() <<
"Skipping test for ZK-enabled flavors";
437TYPED_TEST(SumcheckTests, ProverAndVerifierSimple)
439 this->test_prover_verifier_flow();
442TYPED_TEST(SumcheckTests, ProverAndVerifierSimpleFailure)
444 this->test_failure_prover_verifier_flow();
A container for the prover polynomials.
std::array< FF, NUM_SUBRELATIONS - 1 > SubrelationSeparators
static constexpr size_t NUM_ALL_ENTITIES
static constexpr bool HasZK
Child class of MegaFlavor that runs with ZK Sumcheck. See more in Sumcheck Outline.
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
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,...
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Child class of UltraFlavor that runs with ZK Sumcheck.
typename ECCVMFlavor::ProverPolynomials ProverPolynomials
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(ShpleminiTest, TestSettings)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
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.