Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
eccvm.test.cpp
Go to the documentation of this file.
1#include <cstddef>
2#include <cstdint>
3#include <gtest/gtest.h>
4#include <vector>
5
28
29using namespace bb;
36
37// Test helper: Create a VK by committing to proving key polynomials (for comparing with fixed VK)
39{
41 // Overwrite fixed commitments with computed commitments from the proving key
42 for (auto [polynomial, commitment] : zip_view(proving_key->polynomials.get_precomputed(), vk.get_all())) {
43 commitment = proving_key->commitment_key.commit(polynomial);
44 }
45 return vk;
46}
47
48// Compute VK hash from fixed commitments (for test verification that vk_hash() is correct)
50{
52 // Serialize commitments using the Codec
53 for (const auto& commitment : ECCVMHardcodedVKAndHash::get_all()) {
54 auto frs = ECCVMFlavor::Codec::serialize_to_fields(commitment);
55 for (const auto& fr : frs) {
56 elements.push_back(fr);
57 }
58 }
59 return ECCVMFlavor::HashFunction::hash(elements);
60}
61
62class ECCVMTests : public ::testing::Test {
63 protected:
64 void SetUp() override
65 {
67 static const bool grumpkin_srs_initialized = []() {
69 return true;
70 }();
71 static_cast<void>(grumpkin_srs_initialized);
72 };
73};
74namespace {
76} // namespace
77
85{
86 using Curve = curve::BN254;
87 using G1 = Curve::Element;
88 using Fr = Curve::ScalarField;
89
91 G1 a = G1::random_element(engine);
92 G1 b = G1::random_element(engine);
93 G1 c = G1::random_element(engine);
96
97 op_queue->add_accumulate(a);
98 op_queue->mul_accumulate(a, x);
99 op_queue->mul_accumulate(b, x);
100 op_queue->mul_accumulate(b, y);
101 op_queue->add_accumulate(a);
102 op_queue->mul_accumulate(b, x);
103 op_queue->eq_and_reset();
104 op_queue->add_accumulate(c);
105 op_queue->mul_accumulate(a, x);
106 op_queue->mul_accumulate(b, x);
107 op_queue->eq_and_reset();
108 op_queue->mul_accumulate(a, x);
109 op_queue->mul_accumulate(b, x);
110 op_queue->mul_accumulate(c, x);
111 op_queue->merge();
112 add_hiding_op_for_test(op_queue);
113 ECCVMCircuitBuilder builder{ op_queue };
114 return builder;
115}
116
117// returns a CircuitBuilder consisting of mul_add ops of the following form: either 0*g, for a group element, or
118// x * e, where x is a scalar and e is the identity element of the group.
119ECCVMCircuitBuilder generate_zero_circuit([[maybe_unused]] numeric::RNG* engine = nullptr, bool zero_scalars = 1)
120{
121 using Curve = curve::BN254;
122 using G1 = Curve::Element;
123 using Fr = Curve::ScalarField;
124
126
127 if (!zero_scalars) {
128 for (auto i = 0; i < 8; i++) {
130 op_queue->mul_accumulate(Curve::Group::affine_point_at_infinity, x);
131 }
132 } else {
133 for (auto i = 0; i < 8; i++) {
134 G1 g = G1::random_element(engine);
135 op_queue->mul_accumulate(g, 0);
136 }
137 }
138 op_queue->merge();
139 add_hiding_op_for_test(op_queue);
140
141 ECCVMCircuitBuilder builder{ op_queue };
142 return builder;
143}
144
147 std::vector<FF>& gate_challenges)
148{
149 // Prepare the inputs for the sumcheck prover:
150 // Compute and add beta to relation parameters
151 const FF beta = FF::random_element();
152 const FF gamma = FF::random_element();
153 const FF beta_sqr = beta * beta;
154 const FF beta_quartic = beta_sqr * beta_sqr;
155 relation_parameters.gamma = gamma;
156 relation_parameters.beta = beta;
157 relation_parameters.beta_sqr = beta_sqr;
158 relation_parameters.beta_cube = beta_sqr * beta;
159 relation_parameters.beta_quartic = beta_quartic;
160 auto first_term_tag = beta_quartic; // FIRST_TERM_TAG (= 1) * beta_quartic
161 relation_parameters.eccvm_set_permutation_delta = (gamma + first_term_tag) * (gamma + beta_sqr + first_term_tag) *
162 (gamma + beta_sqr + beta_sqr + first_term_tag) *
163 (gamma + beta_sqr + beta_sqr + beta_sqr + first_term_tag);
164 relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert();
165
166 // Compute z_perm and inverse polynomial for our logarithmic-derivative lookup method
167 // Skip the disabled head region to preserve masking values
168 compute_logderivative_inverse<FF, ECCVMFlavor::LookupRelation, ECCVMFlavor::ProverPolynomials, true>(
169 pk->polynomials, relation_parameters, ECCVMFlavor::TRACE_OFFSET);
170 compute_grand_products<ECCVMFlavor>(pk->polynomials, relation_parameters);
171
172 // Generate gate challenges
173 for (size_t idx = 0; idx < CONST_ECCVM_LOG_N; idx++) {
174 gate_challenges[idx] = FF::random_element();
175 }
176}
177TEST_F(ECCVMTests, ZeroesCoefficients)
178{
180
181 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
182 ECCVMProver prover(builder, prover_transcript);
183 auto proof = prover.construct_proof();
184
185 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
186 ECCVMVerifier verifier(verifier_transcript, proof);
187 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
188
189 ASSERT_TRUE(eccvm_result.reduction_succeeded);
190}
191
192// Calling get_eccvm_ops without a hiding op should throw
193TEST_F(ECCVMTests, MissingHidingOpThrows)
194{
196 // get_eccvm_ops() requires a hiding op to have been set; throws "Hiding op must be set before calling
197 // get_eccvm_ops()"
198 EXPECT_THROW(op_queue->get_eccvm_ops(), std::runtime_error);
199}
200
201// Note that `NullOpQueue` is somewhat misleading, as we add a hiding operation.
202TEST_F(ECCVMTests, NullOpQUeue)
203{
205 add_hiding_op_for_test(op_queue);
206 ECCVMCircuitBuilder builder{ op_queue };
207 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
208 ECCVMProver prover(builder, prover_transcript);
209 auto proof = prover.construct_proof();
210
211 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
212 ECCVMVerifier verifier(verifier_transcript, proof);
213 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
214
215 ASSERT_TRUE(eccvm_result.reduction_succeeded);
216}
217
218TEST_F(ECCVMTests, PointAtInfinity)
219{
221
222 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
223 ECCVMProver prover(builder, prover_transcript);
224 auto proof = prover.construct_proof();
225
226 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
227 ECCVMVerifier verifier(verifier_transcript, proof);
228 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
229
230 ASSERT_TRUE(eccvm_result.reduction_succeeded);
231}
232
233TEST_F(ECCVMTests, ShortMonomialProverVerifies)
234{
236
237 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
238 ECCVMProver prover(builder, prover_transcript);
239 auto proof = prover.construct_proof();
240
241 EXPECT_EQ(proof.size(), ECCVMFlavor::PROOF_LENGTH);
242
243 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
244 ECCVMVerifier verifier(verifier_transcript, proof);
245 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
246
247 // The TripleIPA opening is produced inside construct_proof and carried on prover.ipa_proof; discharge it
248 // against the reconstructed claim.
249 auto ipa_verifier_transcript = std::make_shared<Transcript>(prover.ipa_proof);
251 bool ipa_verified =
252 ECCVMVerifier::TripleIPA::reduce_verify(ipa_vk, eccvm_result.triple_ipa_claim, ipa_verifier_transcript);
253
254 ASSERT_TRUE(ipa_verified && eccvm_result.reduction_succeeded);
255}
256
257namespace {
258// Build a length-2 edge input (one ProverUnivariate per entity), mirroring the translator equivalence test.
259ECCVMFlavor::ProverUnivariates<2> get_short_edge_input(bool random_inputs)
260{
262 FF value = 0;
263 for (auto& edge : result.get_all()) {
264 if (random_inputs) {
266 } else {
267 value += 1;
268 edge = bb::Univariate<FF, 2>({ value, value + 1 });
269 value += 1;
270 }
271 }
272 return result;
273}
274
275template <typename ShortRelation>
276auto accumulate_short_relation(const ECCVMFlavor::ProverUnivariates<2>& in,
277 const RelationParameters<FF>& params,
278 const FF& scaling_factor)
279{
280 typename ShortRelation::SumcheckTupleOfUnivariatesOverSubrelations accumulators{};
281 ShortRelation::accumulate(accumulators, in, params, scaling_factor);
282 return accumulators;
283}
284
285// Compare one short relation's subrelations against the full relation's subrelations starting at `Offset`. ECCVM
286// legacy relations over-provision every subrelation to a uniform length while the short relations declare the true
287// (smaller) per-subrelation degree, so each short subrelation is extended up to the legacy length before comparison.
288template <size_t Offset, typename FullTuple, typename ShortTuple, size_t... Js>
289void compare_subrelation_block(const FullTuple& full_acc, const ShortTuple& short_acc, std::index_sequence<Js...>)
290{
291 (
292 [&] {
293 constexpr size_t full_idx = Offset + Js;
294 constexpr size_t full_length = std::tuple_element_t<full_idx, FullTuple>::LENGTH;
295 EXPECT_EQ(std::get<Js>(short_acc).template extend_to<full_length>(), std::get<full_idx>(full_acc));
296 }(),
297 ...);
298}
299
300// Base case: every legacy subrelation must have been covered by exactly one short subrelation.
301template <size_t Offset, typename FullTuple> void compare_short_blocks(const FullTuple&)
302{
303 static_assert(Offset == std::tuple_size_v<FullTuple>,
304 "short relations must cover exactly the legacy relation's subrelations");
305}
306
307// Walk the short relations in flavor order, matching each against the corresponding contiguous slice of the full
308// relation's subrelations. Index-aligned equality also confirms the split short relations reproduce the legacy
309// global subrelation ordering (and hence the alpha batching).
310template <size_t Offset, typename FullTuple, typename ShortHead, typename... ShortTail>
311void compare_short_blocks(const FullTuple& full_acc, const ShortHead& head, const ShortTail&... tail)
312{
313 constexpr size_t head_size = std::tuple_size_v<ShortHead>;
314 compare_subrelation_block<Offset>(full_acc, head, std::make_index_sequence<head_size>{});
315 compare_short_blocks<Offset + head_size>(full_acc, tail...);
316}
317
318template <typename FullRelation, typename... ShortRelations>
319void expect_short_relations_match_full_edges(const ECCVMFlavor::ProverUnivariates<2>& in,
320 const RelationParameters<FF>& params,
321 const FF& scaling_factor)
322{
323 ECCVMFlavor::ExtendedEdges extended_edges;
324 for (auto [extended_edge, short_edge] : zip_view(extended_edges.get_all(), in.get_all())) {
325 extended_edge = short_edge.template extend_to<ECCVMFlavor::MAX_PARTIAL_RELATION_LENGTH>();
326 }
327
328 typename FullRelation::SumcheckTupleOfUnivariatesOverSubrelations full_acc{};
329 FullRelation::accumulate(full_acc, extended_edges, params, scaling_factor);
330
331 compare_short_blocks<0>(full_acc, accumulate_short_relation<ShortRelations>(in, params, scaling_factor)...);
332}
333} // namespace
334
335// Each ECCVM short relation (some of which split a single legacy relation across several short relations) must
336// produce, edge-for-edge, the same per-subrelation contributions as its legacy counterpart. This is the soundness
337// guard for the prover-only short path: the legacy verifier (native and recursive) only ever evaluates the full
338// relations, so a divergence here would make the short-prover's proof unverifiable.
339TEST_F(ECCVMTests, ShortMonomialRelationsMatchFullEdgeRelations)
340{
341 const auto run_test = [&](bool random_inputs) {
342 const auto input = get_short_edge_input(random_inputs);
343 const auto params = RelationParameters<FF>::get_random();
344 const FF scaling_factor = random_inputs ? FF::random_element() : FF(7);
345
346 expect_short_relations_match_full_edges<ECCVMTranscriptRelation<FF>,
349 input, params, scaling_factor);
350 expect_short_relations_match_full_edges<ECCVMPointTableRelation<FF>,
352 ECCVMPointTableShortRelation<FF>>(input, params, scaling_factor);
353 expect_short_relations_match_full_edges<ECCVMWnafRelation<FF>, ECCVMWnafShortRelation<FF>>(
354 input, params, scaling_factor);
355 expect_short_relations_match_full_edges<ECCVMMSMRelation<FF>,
359 ECCVMMSMShortRelation<FF>>(input, params, scaling_factor);
360 expect_short_relations_match_full_edges<ECCVMSetRelation<FF>, ECCVMSetShortRelation<FF>>(
361 input, params, scaling_factor);
362 expect_short_relations_match_full_edges<ECCVMLookupRelation<FF>, ECCVMLookupShortRelation<FF>>(
363 input, params, scaling_factor);
364 expect_short_relations_match_full_edges<ECCVMBoolsRelation<FF>,
366 ECCVMBoolsMsmShortRelation<FF>>(input, params, scaling_factor);
367 };
368
369 run_test(/*random_inputs=*/false);
370 run_test(/*random_inputs=*/true);
371}
372
373TEST_F(ECCVMTests, ScalarEdgeCase)
374{
375 using Curve = curve::BN254;
376 using G1 = Curve::Element;
377 using Fr = Curve::ScalarField;
378
380 G1 a = G1::one();
381
382 op_queue->mul_accumulate(a, Fr(uint256_t(1) << 128));
383 op_queue->eq_and_reset();
384 op_queue->merge();
385 add_hiding_op_for_test(op_queue);
386 ECCVMCircuitBuilder builder{ op_queue };
387
388 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
389 ECCVMProver prover(builder, prover_transcript);
390 auto proof = prover.construct_proof();
391
392 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
393 ECCVMVerifier verifier(verifier_transcript, proof);
394 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
395
396 ASSERT_TRUE(eccvm_result.reduction_succeeded);
397}
405TEST_F(ECCVMTests, ProofLengthCheck)
406{
408
409 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
410 ECCVMProver prover(builder, prover_transcript);
411 auto proof = prover.construct_proof();
412 EXPECT_EQ(proof.size(), ECCVMFlavor::PROOF_LENGTH);
413}
414
415TEST_F(ECCVMTests, BaseCaseFixedSize)
416{
417 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
418 ECCVMProver prover = [&]() {
420 return ECCVMProver(builder, prover_transcript);
421 }();
422
423 auto proof = prover.construct_proof();
424
425 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
426 ECCVMVerifier verifier(verifier_transcript, proof);
427 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
428
429 ASSERT_TRUE(eccvm_result.reduction_succeeded);
430}
431
432TEST_F(ECCVMTests, EqFailsFixedSize)
433{
435 // Tamper with the eq op such that the expected value is incorect
436 builder.op_queue->add_erroneous_equality_op_for_testing();
437 builder.op_queue->merge();
438
439 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
440 ECCVMProver prover(builder, prover_transcript);
441
442 auto proof = prover.construct_proof();
443
444 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
445 ECCVMVerifier verifier(verifier_transcript, proof);
446 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
447
448 ASSERT_FALSE(eccvm_result.reduction_succeeded);
449}
450
451TEST_F(ECCVMTests, CommittedSumcheck)
452{
453 using Flavor = ECCVMFlavor;
454 using ProvingKey = ECCVMFlavor::ProvingKey;
455 using FF = ECCVMFlavor::FF;
457 using ZKData = ZKSumcheckData<Flavor>;
458
459 bb::RelationParameters<FF> relation_parameters;
460 std::vector<FF> gate_challenges(CONST_ECCVM_LOG_N);
461
463 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
464 ECCVMProver prover(builder, prover_transcript);
466
467 // Prepare the inputs for the sumcheck prover:
468 // Compute and add beta to relation parameters
469 const FF alpha = FF::random_element();
470 complete_proving_key_for_test(relation_parameters, pk, gate_challenges);
471
472 // Clear the transcript
473 prover_transcript = std::make_shared<Transcript>();
474
475 // Run Sumcheck on the ECCVM Prover polynomials
477 SumcheckProver sumcheck_prover(pk->circuit_size,
478 pk->polynomials,
479 prover_transcript,
480 alpha,
481 gate_challenges,
482 relation_parameters,
483 CONST_ECCVM_LOG_N);
484
485 ZKData zk_sumcheck_data = ZKData(CONST_ECCVM_LOG_N, prover_transcript);
486 auto prover_output = sumcheck_prover.prove(zk_sumcheck_data);
487
488 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>(prover_transcript->export_proof());
489
490 // Execute Sumcheck Verifier
491 SumcheckVerifier<Flavor> sumcheck_verifier(verifier_transcript, alpha, CONST_ECCVM_LOG_N);
492 SumcheckOutput<ECCVMFlavor> verifier_output = sumcheck_verifier.verify(relation_parameters, gate_challenges);
493
494 // Evaluate prover's round univariates at corresponding challenges and compare them with the claimed evaluations
495 // computed by the verifier
496 for (size_t idx = 0; idx < CONST_ECCVM_LOG_N; idx++) {
497 FF true_eval_at_the_challenge = prover_output.round_univariates[idx].evaluate(prover_output.challenge[idx]);
498 FF verifier_eval_at_the_challenge = verifier_output.round_univariate_evaluations[idx][2];
499 EXPECT_TRUE(true_eval_at_the_challenge == verifier_eval_at_the_challenge);
500 }
501
502 // Check that the first sumcheck univariate is consistent with the claimed ZK Sumchek Sum
503 FF prover_target_sum = zk_sumcheck_data.libra_challenge * zk_sumcheck_data.libra_total_sum;
504
505 EXPECT_TRUE(prover_target_sum == verifier_output.round_univariate_evaluations[0][0] +
506 verifier_output.round_univariate_evaluations[0][1]);
507
508 EXPECT_TRUE(verifier_output.verified);
509}
510
526TEST_F(ECCVMTests, BaseInfinityForgedCoordinatesRejected)
527{
528 using Curve = curve::BN254;
529 using G1 = Curve::Element;
530 using Fr = Curve::ScalarField;
531
532 auto generators = Curve::Group::derive_generators("base_infinity_regression", 2);
533 G1 a = generators[0];
534 G1 b = generators[1]; // the point the attacker tries to smuggle in
537
538 // Honest vs forged results
539 G1 honest_result = a * x + b * y;
540 G1 forged_result = a * x;
541 ASSERT_NE(honest_result, forged_result) << "Need b*y != 0 for a meaningful attack";
542
543 // Build the circuit: mul(a, x), mul(infinity, y), eq_and_reset()
544 // The op queue honestly computes a*x + infinity*y = a*x. Eq point = a*x.
545 // The builder sets base_infinity=1 at the second mul row.
547 op_queue->mul_accumulate(a, x);
548 op_queue->mul_accumulate(Curve::Group::affine_point_at_infinity, y);
549 op_queue->eq_and_reset();
550 op_queue->merge();
551 add_hiding_op_for_test(op_queue);
552
553 ECCVMCircuitBuilder builder{ op_queue };
554
555 // Create prover (polynomials are built in the constructor)
556 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
557 ECCVMProver prover(builder, prover_transcript);
558
559 // Find the mul row with base_infinity=1
560 auto& polys = prover.key->polynomials;
561 const size_t num_rows = polys.get_polynomial_size();
562 size_t forged_row = 0;
563 for (size_t i = 0; i < num_rows; i++) {
564 if (polys.transcript_op[i] == FF(4) && polys.transcript_base_infinity[i] == FF(1)) {
565 forged_row = i;
566 break;
567 }
568 }
569 ASSERT_GT(forged_row, size_t(0)) << "Could not find infinity mul row";
570
571 // Replace transcript_Px/Py with valid on-curve point b.
572 // After this, the committed transcript says: mul(a,x), mul(b,y), eq(a*x)
573 // Honest result = a*x + b*y, but the proof will claim a*x.
574 auto b_affine = Curve::Group::affine_element(b);
575 polys.transcript_Px.at(forged_row) = b_affine.x;
576 polys.transcript_Py.at(forged_row) = b_affine.y;
577
578 // Generate proof from modified polynomials
579 auto proof = prover.construct_proof();
580
581 // Verify the ECCVM proof
582 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
583 ECCVMVerifier verifier(verifier_transcript, proof);
584 auto eccvm_result = verifier.reduce_to_triple_ipa_claim();
585
586 bool proof_verified = eccvm_result.reduction_succeeded;
587
588 EXPECT_FALSE(proof_verified)
589 << "REGRESSION: Forged ECCVM proof must NOT verify after base_infinity coordinate constraints";
590}
591
599{
600 // Generate a circuit and its verification key (computed at runtime from the proving key)
602 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
603 ECCVMProver prover(builder, prover_transcript);
604 auto proof = prover.construct_proof();
605
606 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
607 ECCVMVerifier verifier(verifier_transcript, proof);
608
609 // Generate the default fixed VK
611 // Generate a VK from PK
612 ECCVMFlavor::VerificationKey vk_computed_by_prover = create_vk_from_proving_key(prover.key);
613
614 const auto& labels = bb::ECCVMFlavor::VerificationKey::get_labels();
615 size_t index = 0;
616 for (auto [vk_commitment, fixed_commitment] : zip_view(vk_computed_by_prover.get_all(), fixed_vk.get_all())) {
617 EXPECT_EQ(vk_commitment, fixed_commitment)
618 << "Mismatch between vk_commitment and fixed_commitment at label: " << labels[index];
619 ++index;
620 }
621
622 // Check that the fixed VK is equal to the generated VK
623 EXPECT_EQ(fixed_vk, vk_computed_by_prover);
624
625 // Verify that the hardcoded VK hash matches the computed hash
626 auto computed_hash = compute_eccvm_vk_hash();
627 auto hardcoded_hash = ECCVMHardcodedVKAndHash::vk_hash();
628 if (computed_hash != hardcoded_hash) {
629 info("VK hash mismatch! Update ECCVMHardcodedVKAndHash::vk_hash() with:");
630 info("0x", computed_hash);
631 }
632 EXPECT_EQ(computed_hash, hardcoded_hash) << "Hardcoded VK hash does not match computed hash";
633}
634
640TEST_F(ECCVMTests, WitnessPolynomialsMasked)
641{
644
645 // Every witness polynomial should have at least one non-zero masking value
646 auto check_masked = [](const auto& poly, const std::string& label) {
647 bool has_masking = false;
648 for (size_t j = 0; j < NUM_MASKED_ROWS; j++) {
649 has_masking |= !poly[NUM_ZERO_ROWS + j].is_zero();
650 }
651 EXPECT_TRUE(has_masking) << label << " should be masked but has all zeros in masking region";
652 };
653
655 for (auto [poly, label] : zip_view(polynomials.get_wires(), labels.get_wires())) {
656 check_masked(poly, label);
657 }
658 check_masked(polynomials.z_perm, "z_perm");
659 check_masked(polynomials.lookup_inverses, "lookup_inverses");
660}
void SetUp() override
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
A base class labelling all entities (for instance, all of the polynomials used by the prover during s...
A container for commitment labels.
A container for the prover polynomials.
The proving key is responsible for storing the polynomials used by the prover.
static constexpr size_t ECCVM_FIXED_SIZE
typename Curve::ScalarField FF
typename Curve::BaseField BF
static constexpr size_t PROOF_LENGTH
BaseTranscript< Codec, HashFunction > Transcript
static constexpr size_t TRACE_OFFSET
static std::vector< Commitment > get_all()
std::shared_ptr< ProvingKey > key
Unified ECCVM verifier class for both native and recursive verification.
ReductionResult reduce_to_triple_ipa_claim()
Reduce the ECCVM proof to a compact TripleIPA verifier claim.
Simple verification key class for fixed-size circuits (ECCVM, Translator, AVM).
Definition flavor.hpp:104
static std::vector< fr > serialize_to_fields(const T &val)
Conversion from transcript values to bb::frs.
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:87
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
The implementation of the sumcheck Prover for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:304
SumcheckOutput< Flavor > prove()
Non-ZK version: Compute round univariate, place it in transcript, compute challenge,...
Definition sumcheck.hpp:398
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:802
SumcheckOutput< Flavor > verify(const bb::RelationParameters< FF > &relation_parameters, const std::vector< FF > &gate_challenges)
The Sumcheck verification method. First it extracts round univariate, checks sum (the sumcheck univar...
Definition sumcheck.hpp:859
A univariate polynomial represented by its values on {0, 1,..., domain_end - 1}.
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
typename Group::element Element
Definition grumpkin.hpp:63
#define info(...)
Definition log.hpp:93
AluTraceBuilder builder
Definition alu.test.cpp:124
FF a
FF b
std::string label
void complete_proving_key_for_test(bb::RelationParameters< FF > &relation_parameters, std::shared_ptr< PK > &pk, std::vector< FF > &gate_challenges)
ECCVMFlavor::VerificationKey create_vk_from_proving_key(const std::shared_ptr< PK > &proving_key)
ECCVMFlavor::BF compute_eccvm_vk_hash()
ECCVMFlavor::FF FF
ECCVMCircuitBuilder generate_zero_circuit(numeric::RNG *engine=nullptr, bool zero_scalars=1)
ECCVMCircuitBuilder generate_circuit(numeric::RNG *engine=nullptr)
Adds operations in BN254 to the op_queue and then constructs and ECCVM circuit from the op_queue.
numeric::RNG & engine
void add_hiding_op_for_test(const std::shared_ptr< ECCOpQueue > &op_queue)
Set a hiding op on the op_queue for testing.
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:245
std::filesystem::path bb_crs_path()
std::vector< grumpkin::g1::affine_element > generate_grumpkin_srs(size_t num_points)
Generates a monomial basis Grumpkin SRS on-the-fly.
void init_file_crs_factory(const std::filesystem::path &path)
void init_grumpkin_mem_crs_factory(std::vector< curve::Grumpkin::AffineElement > const &points)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:160
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::AffineElement G1
Container for parameters used by the grand product (permutation, lookup) Honk relations.
static RelationParameters get_random()
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
std::vector< std::array< FF, 3 > > round_univariate_evaluations
This structure is created to contain various polynomials and constants required by ZK Sumcheck.
static field random_element(numeric::RNG *engine=nullptr) noexcept
VectorField result