3#include <gtest/gtest.h>
41 for (
auto [polynomial, commitment] :
zip_view(proving_key->polynomials.get_precomputed(),
vk.get_all())) {
42 commitment = proving_key->commitment_key.commit(polynomial);
54 for (
const auto&
fr : frs) {
55 elements.push_back(
fr);
88 op_queue->add_accumulate(
a);
89 op_queue->mul_accumulate(
a, x);
90 op_queue->mul_accumulate(
b, x);
91 op_queue->mul_accumulate(
b, y);
92 op_queue->add_accumulate(
a);
93 op_queue->mul_accumulate(
b, x);
94 op_queue->eq_and_reset();
95 op_queue->add_accumulate(c);
96 op_queue->mul_accumulate(
a, x);
97 op_queue->mul_accumulate(
b, x);
98 op_queue->eq_and_reset();
99 op_queue->mul_accumulate(
a, x);
100 op_queue->mul_accumulate(
b, x);
101 op_queue->mul_accumulate(c, x);
103 add_hiding_op_for_test(op_queue);
119 for (
auto i = 0; i < 8; i++) {
121 op_queue->mul_accumulate(Curve::Group::affine_point_at_infinity, x);
124 for (
auto i = 0; i < 8; i++) {
126 op_queue->mul_accumulate(g, 0);
130 add_hiding_op_for_test(op_queue);
138 std::vector<FF>& gate_challenges)
144 const FF beta_sqr = beta * beta;
145 const FF beta_quartic = beta_sqr * beta_sqr;
146 relation_parameters.
gamma = gamma;
147 relation_parameters.
beta = beta;
148 relation_parameters.
beta_sqr = beta_sqr;
149 relation_parameters.
beta_cube = beta_sqr * beta;
151 auto first_term_tag = beta_quartic;
153 (gamma + beta_sqr + beta_sqr + first_term_tag) *
154 (gamma + beta_sqr + beta_sqr + beta_sqr + first_term_tag);
159 compute_logderivative_inverse<FF, ECCVMFlavor::LookupRelation, ECCVMFlavor::ProverPolynomials, true>(
161 compute_grand_products<ECCVMFlavor>(pk->polynomials, relation_parameters);
164 for (
size_t idx = 0; idx < CONST_ECCVM_LOG_N; idx++) {
178 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
189 ASSERT_TRUE(ipa_verified && eccvm_result.reduction_succeeded);
197 EXPECT_THROW(op_queue->get_eccvm_ops(), std::runtime_error);
204 add_hiding_op_for_test(op_queue);
212 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
223 ASSERT_TRUE(ipa_verified && eccvm_result.reduction_succeeded);
235 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
245 ASSERT_TRUE(ipa_verified && eccvm_result.reduction_succeeded);
259 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
269 ASSERT_TRUE(ipa_verified && eccvm_result.reduction_succeeded);
278 for (
auto& edge : result.get_all()) {
290template <
typename ShortRelation>
293 const FF& scaling_factor)
295 typename ShortRelation::SumcheckTupleOfUnivariatesOverSubrelations accumulators{};
296 ShortRelation::accumulate(accumulators, in, params, scaling_factor);
303template <
size_t Offset,
typename FullTuple,
typename ShortTuple,
size_t... Js>
308 constexpr size_t full_idx = Offset + Js;
309 constexpr size_t full_length = std::tuple_element_t<full_idx, FullTuple>::LENGTH;
316template <
size_t Offset,
typename FullTuple>
void compare_short_blocks(
const FullTuple&)
319 "short relations must cover exactly the legacy relation's subrelations");
325template <
size_t Offset,
typename FullTuple,
typename ShortHead,
typename... ShortTail>
326void compare_short_blocks(
const FullTuple& full_acc,
const ShortHead& head,
const ShortTail&... tail)
330 compare_short_blocks<Offset + head_size>(full_acc, tail...);
333template <
typename FullRelation,
typename... ShortRelations>
336 const FF& scaling_factor)
339 for (
auto [extended_edge, short_edge] :
zip_view(extended_edges.get_all(), in.get_all())) {
340 extended_edge = short_edge.template extend_to<ECCVMFlavor::MAX_PARTIAL_RELATION_LENGTH>();
343 typename FullRelation::SumcheckTupleOfUnivariatesOverSubrelations full_acc{};
344 FullRelation::accumulate(full_acc, extended_edges, params, scaling_factor);
346 compare_short_blocks<0>(full_acc, accumulate_short_relation<ShortRelations>(in, params, scaling_factor)...);
356 const auto run_test = [&](
bool random_inputs) {
357 const auto input = get_short_edge_input(random_inputs);
361 expect_short_relations_match_full_edges<ECCVMTranscriptRelation<FF>,
364 input, params, scaling_factor);
365 expect_short_relations_match_full_edges<ECCVMPointTableRelation<FF>,
369 input, params, scaling_factor);
370 expect_short_relations_match_full_edges<ECCVMMSMRelation<FF>,
376 input, params, scaling_factor);
378 input, params, scaling_factor);
379 expect_short_relations_match_full_edges<ECCVMBoolsRelation<FF>,
398 op_queue->eq_and_reset();
400 add_hiding_op_for_test(op_queue);
408 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
418 ASSERT_TRUE(ipa_verified && eccvm_result.reduction_succeeded);
448 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
458 ASSERT_TRUE(ipa_verified && eccvm_result.reduction_succeeded);
465 builder.op_queue->add_erroneous_equality_op_for_testing();
474 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
484 ASSERT_FALSE(ipa_verified && eccvm_result.reduction_succeeded);
496 std::vector<FF> gate_challenges(CONST_ECCVM_LOG_N);
521 ZKData zk_sumcheck_data = ZKData(CONST_ECCVM_LOG_N, prover_transcript);
522 auto prover_output = sumcheck_prover.
prove(zk_sumcheck_data);
532 for (
size_t idx = 0; idx < CONST_ECCVM_LOG_N; idx++) {
533 FF true_eval_at_the_challenge = prover_output.round_univariates[idx].evaluate(prover_output.challenge[idx]);
535 EXPECT_TRUE(true_eval_at_the_challenge == verifier_eval_at_the_challenge);
539 FF prover_target_sum = zk_sumcheck_data.libra_challenge * zk_sumcheck_data.libra_total_sum;
544 EXPECT_TRUE(verifier_output.
verified);
568 auto generators = Curve::Group::derive_generators(
"base_infinity_regression", 2);
569 G1 a = generators[0];
570 G1 b = generators[1];
575 G1 honest_result =
a * x +
b * y;
576 G1 forged_result =
a * x;
577 ASSERT_NE(honest_result, forged_result) <<
"Need b*y != 0 for a meaningful attack";
583 op_queue->mul_accumulate(
a, x);
584 op_queue->mul_accumulate(Curve::Group::affine_point_at_infinity, y);
585 op_queue->eq_and_reset();
587 add_hiding_op_for_test(op_queue);
596 auto& polys = prover.
key->polynomials;
597 const size_t num_rows = polys.get_polynomial_size();
598 size_t forged_row = 0;
599 for (
size_t i = 0; i < num_rows; i++) {
600 if (polys.transcript_op[i] ==
FF(4) && polys.transcript_base_infinity[i] ==
FF(1)) {
605 ASSERT_GT(forged_row,
size_t(0)) <<
"Could not find infinity mul row";
610 auto b_affine = Curve::Group::affine_element(
b);
611 polys.transcript_Px.at(forged_row) = b_affine.x;
612 polys.transcript_Py.at(forged_row) = b_affine.y;
619 PCS::compute_opening_proof(prover.
key->commitment_key, opening_claim, ipa_transcript);
631 bool proof_verified = ipa_verified && eccvm_result.reduction_succeeded;
633 EXPECT_FALSE(proof_verified)
634 <<
"REGRESSION: Forged ECCVM proof must NOT verify after base_infinity coordinate constraints";
659 const auto& labels = bb::ECCVMFlavor::VerificationKey::get_labels();
661 for (
auto [vk_commitment, fixed_commitment] :
zip_view(vk_computed_by_prover.get_all(), fixed_vk.get_all())) {
662 EXPECT_EQ(vk_commitment, fixed_commitment)
663 <<
"Mismatch between vk_commitment and fixed_commitment at label: " << labels[
index];
668 EXPECT_EQ(fixed_vk, vk_computed_by_prover);
673 if (computed_hash != hardcoded_hash) {
674 info(
"VK hash mismatch! Update ECCVMHardcodedVKAndHash::vk_hash() with:");
675 info(
"0x", computed_hash);
677 EXPECT_EQ(computed_hash, hardcoded_hash) <<
"Hardcoded VK hash does not match computed hash";
691 auto check_masked = [](
const auto& poly,
const std::string& label) {
692 bool has_masking =
false;
693 for (
size_t j = 0; j < NUM_MASKED_ROWS; j++) {
694 has_masking |= !poly[NUM_ZERO_ROWS + j].is_zero();
696 EXPECT_TRUE(has_masking) << label <<
" should be masked but has all zeros in masking region";
700 for (
auto [poly, label] :
zip_view(polynomials.get_wires(), labels.get_wires())) {
701 check_masked(poly, label);
703 check_masked(polynomials.z_perm,
"z_perm");
704 check_masked(polynomials.lookup_inverses,
"lookup_inverses");
720 auto unshifted = pk->polynomials.get_unshifted();
721 auto to_be_shifted = pk->polynomials.get_to_be_shifted();
724 ASSERT_EQ(to_be_shifted.size(), repeated.first.count);
727 const auto&
ck = pk->commitment_key;
729 commitments.push_back(ECCVMFlavor::Commitment::one());
730 for (
auto& poly : unshifted) {
731 commitments.push_back(
ck.commit(poly));
733 for (
auto& poly : to_be_shifted) {
734 commitments.push_back(
ck.commit(poly));
739 for (
size_t i = 0; i < repeated.first.count; i++) {
740 EXPECT_EQ(commitments[repeated.first.original_start +
offset + i],
741 commitments[repeated.first.duplicate_start +
offset + i])
742 <<
"REPEATED_COMMITMENTS commitment mismatch at index " << i;
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
static constexpr bool HasZK
typename Curve::ScalarField FF
typename Curve::BaseField BF
static constexpr size_t PROOF_LENGTH
bb::CommitmentKey< Curve > CommitmentKey
static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS
BaseTranscript< Codec, HashFunction > Transcript
static constexpr size_t TRACE_OFFSET
static std::vector< Commitment > get_all()
std::pair< Proof, OpeningClaim > construct_proof()
std::shared_ptr< ProvingKey > key
Unified ECCVM verifier class for both native and recursive verification.
ReductionResult reduce_to_ipa_opening()
Reduce the ECCVM proof to an IPA opening claim.
Simple verification key class for fixed-size circuits (ECCVM, Translator, AVM).
static std::vector< fr > serialize_to_fields(const T &val)
Conversion from transcript values to bb::frs.
IPA (inner product argument) commitment scheme class.
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 .
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 .
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...
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
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()
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.
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)
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TEST_F(IPATest, ChallengesAreZero)
CommitmentKey< Curve > ck
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Container for parameters used by the grand product (permutation, lookup) Honk relations.
T eccvm_set_permutation_delta
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