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 if (circuit_size > 1) {
52 full_polynomials.w_l.at(1) =
FF(1);
53 full_polynomials.w_r.at(1) =
FF(1);
54 full_polynomials.w_o.at(1) =
FF(2);
55 full_polynomials.q_l.at(1) =
FF(1);
56 full_polynomials.q_r.at(1) =
FF(1);
57 full_polynomials.q_o.at(1) =
FF(-1);
58 full_polynomials.q_arith.at(1) =
FF(1);
62 if (circuit_size > 2) {
63 full_polynomials.w_l.at(2) =
FF(2);
64 full_polynomials.w_r.at(2) =
FF(2);
65 full_polynomials.w_o.at(2) =
FF(4);
66 full_polynomials.q_m.at(2) =
FF(1);
67 full_polynomials.q_o.at(2) =
FF(-1);
68 full_polynomials.q_arith.at(2) =
FF(1);
74 constexpr size_t NUM_DISABLED_ROWS = 3;
75 if (circuit_size > NUM_DISABLED_ROWS) {
76 for (
size_t i = circuit_size - NUM_DISABLED_ROWS; i < circuit_size; ++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::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);
174 const size_t multivariate_d(2);
175 const size_t multivariate_n(1 << multivariate_d);
180 for (
auto& poly : random_polynomials) {
181 poly = random_poly(multivariate_n);
183 auto full_polynomials = construct_ultra_full_polynomials(random_polynomials);
185 auto transcript = Flavor::Transcript::prover_init_empty();
187 FF alpha = transcript->template get_challenge<FF>(
"Sumcheck:alpha");
189 std::vector<FF> gate_challenges(multivariate_d);
190 for (
size_t idx = 0; idx < gate_challenges.size(); idx++) {
191 gate_challenges[idx] =
192 transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
196 multivariate_n, full_polynomials, transcript, alpha, gate_challenges, {}, CONST_PROOF_SIZE_LOG_N);
201 ZKData zk_sumcheck_data = ZKData(multivariate_d, transcript);
202 output = sumcheck.
prove(zk_sumcheck_data);
204 output = sumcheck.
prove();
206 FF u_0 = output.challenge[0];
207 FF u_1 = output.challenge[1];
208 std::vector<FF> expected_values;
209 for (
auto& polynomial_ptr : full_polynomials.get_all()) {
210 auto& polynomial = polynomial_ptr;
212 FF expected_lo = polynomial[0] * (
FF(1) - u_0) + polynomial[1] * u_0;
213 expected_lo *= (
FF(1) - u_1);
214 FF expected_hi = polynomial[2] * (
FF(1) - u_0) + polynomial[3] * u_0;
216 expected_values.emplace_back(expected_lo + expected_hi);
219 for (
auto [eval, expected] :
zip_view(output.claimed_evaluations.get_all(), expected_values)) {
225 void test_prover_verifier_flow()
227 const size_t multivariate_d(3);
228 const size_t multivariate_n(1 << multivariate_d);
230 const size_t virtual_log_n = 6;
232 auto full_polynomials = create_satisfiable_trace<Flavor>(multivariate_n);
236 auto prover_transcript = Flavor::Transcript::prover_init_empty();
237 FF prover_alpha = prover_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
239 std::vector<FF> prover_gate_challenges(virtual_log_n);
240 prover_gate_challenges =
241 prover_transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", virtual_log_n);
247 prover_gate_challenges,
253 ZKData zk_sumcheck_data = ZKData(multivariate_d, prover_transcript);
254 output = sumcheck_prover.prove(zk_sumcheck_data);
256 output = sumcheck_prover.prove();
259 auto verifier_transcript = Flavor::Transcript::verifier_init_empty(prover_transcript);
261 FF verifier_alpha = verifier_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
265 std::vector<FF> verifier_gate_challenges(virtual_log_n);
266 verifier_gate_challenges =
267 verifier_transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", virtual_log_n);
269 std::vector<FF> padding_indicator_array(virtual_log_n, 1);
271 for (
size_t idx = 0; idx < virtual_log_n; idx++) {
272 padding_indicator_array[idx] = (idx < multivariate_d) ?
FF{ 1 } :
FF{ 0 };
276 auto verifier_output =
277 sumcheck_verifier.verify(relation_parameters, verifier_gate_challenges, padding_indicator_array);
279 auto verified = verifier_output.verified;
281 EXPECT_EQ(verified,
true);
284 void test_failure_prover_verifier_flow()
288 const size_t multivariate_d(3);
289 const size_t multivariate_n(1 << multivariate_d);
292 auto full_polynomials = create_satisfiable_trace<Flavor>(multivariate_n);
298 full_polynomials.w_l.at(1) =
FF(0);
302 auto prover_transcript = Flavor::Transcript::prover_init_empty();
303 FF prover_alpha = prover_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
305 auto prover_gate_challenges =
306 prover_transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", multivariate_d);
312 prover_gate_challenges,
319 ZKData zk_sumcheck_data = ZKData(multivariate_d, prover_transcript);
320 output = sumcheck_prover.prove(zk_sumcheck_data);
322 output = sumcheck_prover.prove();
325 auto verifier_transcript = Flavor::Transcript::verifier_init_empty(prover_transcript);
327 FF verifier_alpha = verifier_transcript->template get_challenge<FF>(
"Sumcheck:alpha");
331 std::vector<FF> verifier_gate_challenges(multivariate_d);
332 for (
size_t idx = 0; idx < multivariate_d; idx++) {
333 verifier_gate_challenges[idx] =
334 verifier_transcript->template get_challenge<FF>(
"Sumcheck:gate_challenge_" +
std::to_string(idx));
337 std::vector<FF> padding_indicator_array(multivariate_d);
338 std::ranges::fill(padding_indicator_array,
FF{ 1 });
339 auto verifier_output =
340 sumcheck_verifier.verify(relation_parameters, verifier_gate_challenges, padding_indicator_array);
342 auto verified = verifier_output.verified;
344 EXPECT_EQ(verified,
false);
357TYPED_TEST(SumcheckTests, PolynomialNormalization)
359 if constexpr (!TypeParam::HasZK) {
360 this->test_polynomial_normalization();
362 GTEST_SKIP() <<
"Skipping test for ZK-enabled flavors";
371TYPED_TEST(SumcheckTests, ProverAndVerifierSimple)
373 this->test_prover_verifier_flow();
376TYPED_TEST(SumcheckTests, ProverAndVerifierSimpleFailure)
378 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)
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
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.