21#include <gtest/gtest.h>
35 vk.ordered_extra_range_constraints_numerator =
36 proving_key->commitment_key.commit(proving_key->polynomials.ordered_extra_range_constraints_numerator);
47 for (
const auto&
fr : frs) {
48 elements.push_back(
fr);
83 constexpr size_t frs_per_G = FrCodec::calc_num_fields<Flavor::Commitment>();
88 manifest.
add_entry(0,
"Gemini:masking_poly_comm", frs_per_G);
92 std::vector<std::string> wire_labels = {
93 "CONCATENATED_RANGE_CONSTRAINTS_0",
"CONCATENATED_RANGE_CONSTRAINTS_1",
94 "CONCATENATED_RANGE_CONSTRAINTS_2",
"CONCATENATED_RANGE_CONSTRAINTS_3",
95 "CONCATENATED_NON_RANGE",
96 "ORDERED_RANGE_CONSTRAINTS_0",
"ORDERED_RANGE_CONSTRAINTS_1",
97 "ORDERED_RANGE_CONSTRAINTS_2",
"ORDERED_RANGE_CONSTRAINTS_3",
98 "ORDERED_RANGE_CONSTRAINTS_4",
101 for (
const auto& label : wire_labels) {
109 manifest.
add_entry(1,
"Z_PERM", frs_per_G);
114 manifest.
add_entry(2,
"Libra:concatenation_commitment", frs_per_G);
120 for (
size_t i = 0; i < LOG_MINI; ++i) {
131 for (
size_t i = LOG_MINI + 1; i < NUM_SUMCHECK_ROUNDS; ++i) {
138 const size_t eval_round = 3 + NUM_SUMCHECK_ROUNDS;
140 manifest.
add_entry(eval_round,
"Libra:claimed_evaluation", 1);
141 manifest.
add_entry(eval_round,
"Libra:grand_sum_commitment", frs_per_G);
142 manifest.
add_entry(eval_round,
"Libra:quotient_commitment", frs_per_G);
146 const size_t gemini_fold_round = eval_round + 1;
147 for (
size_t i = 1; i < NUM_SUMCHECK_ROUNDS; ++i) {
153 const size_t gemini_eval_round = gemini_fold_round + 1;
154 for (
size_t i = 1; i <= NUM_SUMCHECK_ROUNDS; ++i) {
158 manifest.
add_entry(gemini_eval_round,
"Libra:concatenation_eval", 1);
159 manifest.
add_entry(gemini_eval_round,
"Libra:shifted_grand_sum_eval", 1);
160 manifest.
add_entry(gemini_eval_round,
"Libra:grand_sum_eval", 1);
161 manifest.
add_entry(gemini_eval_round,
"Libra:quotient_eval", 1);
165 const size_t shplonk_round = gemini_eval_round + 1;
166 manifest.
add_entry(shplonk_round,
"Shplonk:Q", frs_per_G);
170 const size_t kzg_round = shplonk_round + 1;
171 manifest.
add_entry(kzg_round,
"KZG:W", frs_per_G);
177 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue,
size_t count = 1)
179 for (
size_t i = 0; i < count; i++) {
180 op_queue->random_op_ultra_only();
184 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue,
size_t count = 100)
189 for (
size_t i = 0; i < count; i++) {
190 op_queue->add_accumulate(P1);
191 op_queue->mul_accumulate(P2, z);
193 op_queue->eq_and_reset();
198 const Fq& evaluation_challenge_x,
199 const size_t circuit_size_parameter = 500)
204 op_queue->construct_zk_columns();
209 op_queue->merge_fixed_append(op_queue->get_append_offset());
211 return CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
215 const Fq& evaluation_challenge_x,
216 const Fq& batching_challenge_v)
221 auto initial_transcript = prover_transcript->export_proof();
225 verifier_transcript->template receive_from_prover<Fq>(
"init");
236 op_queue_commitments[0] =
237 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
238 op_queue_commitments[1] =
239 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
240 op_queue_commitments[2] =
241 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
242 op_queue_commitments[3] =
243 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
246 uint256_t accumulated_result = prover.get_accumulated_result();
251 evaluation_challenge_x,
252 batching_challenge_v,
254 op_queue_commitments);
258 return result.
pairing_points.check() && result.reduction_succeeded;
262 const Fq& evaluation_challenge_x,
263 const Fq& batching_challenge_v)
267 auto initial_transcript = prover_transcript->export_proof();
270 verifier_transcript->template receive_from_prover<Fq>(
"init");
278 op_queue_commitments[0] =
279 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
280 op_queue_commitments[1] =
281 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
282 op_queue_commitments[2] =
283 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
284 op_queue_commitments[3] =
285 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
289 evaluation_challenge_x,
290 batching_challenge_v,
291 prover.get_accumulated_result(),
292 op_queue_commitments);
295 return result.
pairing_points.check() && result.reduction_succeeded;
298 template <
typename FullRelation,
typename ShortRelation>
301 const FF& scaling_factor)
304 for (
auto [extended_edge, short_edge] :
zip_view(extended_edges.get_all(), in.get_all())) {
305 extended_edge = short_edge.template extend_to<TranslatorFlavor::MAX_PARTIAL_RELATION_LENGTH>();
308 typename FullRelation::SumcheckTupleOfUnivariatesOverSubrelations full_accumulators{};
309 typename ShortRelation::SumcheckTupleOfUnivariatesOverSubrelations short_accumulators{};
310 FullRelation::accumulate(full_accumulators, extended_edges, params, scaling_factor);
311 ShortRelation::accumulate(short_accumulators, in, params, scaling_factor);
313 EXPECT_EQ(short_accumulators, full_accumulators);
320 for (
auto& edge : result.get_all()) {
348 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
353 prover_transcript->export_proof();
375 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
378 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
379 EXPECT_TRUE(verified);
384 const auto run_test = [&](
bool random_inputs) {
386 const auto input = get_short_edge_input(random_inputs);
390 expect_short_relation_matches_full_edges<TranslatorPermutationRelation<FF>,
392 expect_short_relation_matches_full_edges<TranslatorDeltaRangeConstraintRelation<FF>,
394 input, params, scaling_factor);
395 expect_short_relation_matches_full_edges<TranslatorOpcodeConstraintRelation<FF>,
397 input, params, scaling_factor);
398 expect_short_relation_matches_full_edges<TranslatorAccumulatorTransferRelation<FF>,
400 input, params, scaling_factor);
401 expect_short_relation_matches_full_edges<TranslatorDecompositionRelation<FF>,
403 input, params, scaling_factor);
404 expect_short_relation_matches_full_edges<TranslatorNonNativeFieldRelation<FF>,
406 input, params, scaling_factor);
407 expect_short_relation_matches_full_edges<TranslatorZeroConstraintsRelation<FF>,
409 input, params, scaling_factor);
423 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
426 EXPECT_TRUE(prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v));
427 EXPECT_TRUE(prove_and_verify_short_monomial(circuit_builder, evaluation_challenge_x, batching_challenge_v));
445 op_queue->no_op_ultra_only();
447 add_mixed_ops(op_queue, 100);
449 auto circuit_builder =
CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue,
true };
452 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
453 EXPECT_TRUE(verified);
470 prover_transcript->export_proof();
478 auto compare_computed_vk_against_fixed = [&](
size_t circuit_size_parameter) {
480 generate_test_circuit(batching_challenge_v, evaluation_challenge_x, circuit_size_parameter);
484 auto labels = TranslatorFlavor::VerificationKey::get_labels();
487 for (
auto [vk_commitment, fixed_commitment] :
zip_view(computed_vk.get_all(), fixed_vk.get_all())) {
488 if (vk_commitment != fixed_commitment) {
490 info(
"Commitment(uint256_t(\"0x", vk_commitment.x,
"\"),");
491 info(
" uint256_t(\"0x", vk_commitment.y,
"\")),");
493 EXPECT_EQ(vk_commitment, fixed_commitment) <<
"Mismatch at label: " << labels[
index];
497 EXPECT_EQ(computed_vk, fixed_vk);
501 const size_t circuit_size_parameter_1 = 1 << 2;
502 const size_t circuit_size_parameter_2 = 1 << 3;
504 compare_computed_vk_against_fixed(circuit_size_parameter_1);
505 compare_computed_vk_against_fixed(circuit_size_parameter_2);
510 if (computed_hash != hardcoded_hash) {
511 info(
"VK hash mismatch! Update TranslatorHardcodedVKAndHash::vk_hash() with:");
512 info(
"0x", computed_hash);
514 EXPECT_EQ(computed_hash, hardcoded_hash) <<
"Hardcoded VK hash does not match computed hash";
529 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
541 verifier_transcript->enable_manifest();
544 uint256_t accumulated_result = prover.get_accumulated_result();
548 op_queue_commitments[0] = proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
549 op_queue_commitments[1] =
550 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
551 op_queue_commitments[2] =
552 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
553 op_queue_commitments[3] =
554 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
559 evaluation_challenge_x,
560 batching_challenge_v,
562 op_queue_commitments);
568 auto expected_manifest = build_expected_translator_manifest();
569 auto verifier_manifest = verifier_transcript->get_manifest();
571 EXPECT_EQ(verifier_manifest, expected_manifest);
599 for (
auto& e : evals.get_all()) {
607 for (
auto& e : evals.get_minicircuit_wires()) {
608 EXPECT_TRUE(covered.insert(&e).second) <<
"minicircuit wire overlaps with a previous entity";
610 EXPECT_EQ(covered.size(), Flavor::NUM_MINICIRCUIT_WIRES);
612 for (
auto& e : evals.get_minicircuit_wires_shifted()) {
613 EXPECT_TRUE(covered.insert(&e).second) <<
"minicircuit wire shift overlaps with a previous entity";
615 EXPECT_EQ(covered.size(), 2 * Flavor::NUM_MINICIRCUIT_WIRES);
617 for (
auto& e : evals.get_full_circuit_entities()) {
618 EXPECT_TRUE(covered.insert(&e).second) <<
"full-circuit entity overlaps with a previous entity";
620 EXPECT_EQ(covered.size(), 2 * Flavor::NUM_MINICIRCUIT_WIRES + Flavor::NUM_FULL_CIRCUIT_EVALUATIONS);
623 for (
auto& e : evals.get_concatenated()) {
624 EXPECT_TRUE(covered.insert(&e).second) <<
"concatenated poly overlaps with a previous entity";
626 EXPECT_EQ(covered.size(),
627 2 * Flavor::NUM_MINICIRCUIT_WIRES + Flavor::NUM_FULL_CIRCUIT_EVALUATIONS +
628 Flavor::NUM_CONCATENATED_POLYS);
632 EXPECT_EQ(remaining, Flavor::NUM_COMPUTABLE_PRECOMPUTED);
635 for (
auto& e : evals.get_all()) {
636 if (covered.find(&e) == covered.end()) {
641 EXPECT_EQ(remaining, 0UL);
662 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
667 auto pcs_unshifted = pk->proving_key->polynomials.get_pcs_unshifted();
668 auto pcs_to_be_shifted = pk->proving_key->polynomials.get_pcs_to_be_shifted();
671 const auto&
ck = pk->proving_key->commitment_key;
672 std::vector<Commitment> unshifted_comms;
673 for (
auto& poly : pcs_unshifted) {
674 unshifted_comms.push_back(
ck.commit(poly));
676 std::vector<Commitment> shifted_comms;
677 for (
auto& poly : pcs_to_be_shifted) {
678 shifted_comms.push_back(
ck.commit(poly));
682 std::vector<Commitment> commitments;
683 commitments.push_back(Commitment::one());
684 commitments.insert(commitments.end(), unshifted_comms.begin(), unshifted_comms.end());
685 commitments.insert(commitments.end(), shifted_comms.begin(), shifted_comms.end());
692 auto check_range = [&](
const auto& range,
const std::string& label) {
693 for (
size_t i = 0; i < range.count; i++) {
694 EXPECT_EQ(commitments[range.original_start +
offset + i], commitments[range.duplicate_start +
offset + i])
695 << label <<
" commitment mismatch at index " << i;
699 check_range(repeated.first,
"Range 1");
700 check_range(repeated.second,
"Range 2");
710 for (
auto& v : mid) {
716 for (
auto& v : full_circuit) {
721 std::vector<FF> challenge(Flavor::CONST_TRANSLATOR_LOG_N);
722 for (
auto& u : challenge) {
728 Flavor::set_minicircuit_evaluations(evals, mid);
729 Flavor::complete_full_circuit_evaluations(evals, full_circuit,
std::span<const FF>(challenge));
732 auto all = evals.get_all();
734 EXPECT_NE(all[i],
FF(0)) <<
"Entity " << i <<
" was not populated by verifier methods";
static bool prove_and_verify(const CircuitBuilder &circuit_builder, const Fq &evaluation_challenge_x, const Fq &batching_challenge_v)
static TranslatorShortMonomialFlavor::ProverUnivariates< 2 > get_short_edge_input(bool random_inputs)
static void add_random_ops(std::shared_ptr< bb::ECCOpQueue > &op_queue, size_t count=1)
Flavor::Commitment Commitment
static void expect_short_relation_matches_full_edges(const TranslatorShortMonomialFlavor::ProverUnivariates< 2 > &in, const RelationParameters< FF > ¶ms, const FF &scaling_factor)
static CircuitBuilder generate_test_circuit(const Fq &batching_challenge_v, const Fq &evaluation_challenge_x, const size_t circuit_size_parameter=500)
static void SetUpTestSuite()
static void add_mixed_ops(std::shared_ptr< bb::ECCOpQueue > &op_queue, size_t count=100)
static TranscriptManifest build_expected_translator_manifest()
Build the expected transcript manifest for Translator verification.
static bool prove_and_verify_short_monomial(const CircuitBuilder &circuit_builder, const Fq &evaluation_challenge_x, const Fq &batching_challenge_v)
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
Manages ECC operations for the Goblin proving system.
A base class labelling all entities (for instance, all of the polynomials used by the prover during s...
static constexpr bool HasZK
typename Curve::ScalarField FF
static constexpr size_t NUM_ALL_ENTITIES
typename G1::affine_element Commitment
bb::CommitmentKey< Curve > CommitmentKey
static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS
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.
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
void add_entry(size_t round, const std::string &element_label, size_t element_size)
void add_challenge(size_t round, const std::string &label)
Add a single challenge label to the manifest for the given round.
TranslatorCircuitBuilder creates a circuit that evaluates the correctness of the evaluation of EccOpQ...
static constexpr size_t NUM_RANDOM_OPS_END
static constexpr size_t NUM_RANDOM_OPS_START
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
A base class labelling all entities (for instance, all of the polynomials used by the prover during s...
static constexpr size_t NUM_FULL_CIRCUIT_EVALUATIONS
BaseTranscript< Codec, HashFunction > Transcript
static constexpr size_t CONST_TRANSLATOR_LOG_N
static constexpr size_t PROOF_LENGTH
TranslatorCircuitBuilder CircuitBuilder
Curve::AffineElement Commitment
static constexpr size_t NUM_MINICIRCUIT_EVALUATIONS
static constexpr size_t LOG_MINI_CIRCUIT_SIZE
HonkProof construct_proof()
Translator verifier class that verifies the proof of the Translator circuit.
ReductionResult reduce_to_pairing_check()
Reduce the translator proof to a pairing check.
A univariate polynomial represented by its values on {0, 1,..., domain_end - 1}.
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
static affine_element random_element(numeric::RNG *engine=nullptr) noexcept
Samples a random point on the curve.
group_elements::affine_element< Fq, Fr, Params > affine_element
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.
field< Bn254FqParams > fq
TEST_F(IPATest, ChallengesAreZero)
field< Bn254FrParams > fr
CommitmentKey< Curve > ck
VerifierCommitmentKey< Curve > vk
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.
static RelationParameters get_random()
static std::vector< Commitment > get_all()
PairingPoints pairing_points
static field random_element(numeric::RNG *engine=nullptr) noexcept
TranslatorFlavor::VerificationKey create_vk_from_proving_key(const std::shared_ptr< TranslatorFlavor::ProvingKey > &proving_key)
TranslatorFlavor::FF compute_translator_vk_hash()