11#include <gtest/gtest.h>
25 for (
auto [polynomial, commitment] :
zip_view(proving_key->polynomials.get_precomputed(),
vk.get_all())) {
26 commitment = proving_key->commitment_key.commit(polynomial);
38 for (
const auto&
fr : frs) {
39 elements.push_back(
fr);
74 constexpr size_t frs_per_G = FrCodec::calc_num_fields<Flavor::Commitment>();
75 constexpr size_t NUM_SUMCHECK_ROUNDS = 17;
79 manifest.
add_entry(0,
"Gemini:masking_poly_comm", frs_per_G);
83 std::vector<std::string> wire_labels = {
84 "P_X_LOW_LIMBS",
"P_X_HIGH_LIMBS",
"P_Y_LOW_LIMBS",
"P_Y_HIGH_LIMBS",
85 "Z_LOw_LIMBS",
"Z_HIGH_LIMBS",
86 "ACCUMULATORS_BINARY_LIMBS_0",
"ACCUMULATORS_BINARY_LIMBS_1",
87 "ACCUMULATORS_BINARY_LIMBS_2",
"ACCUMULATORS_BINARY_LIMBS_3",
88 "QUOTIENT_LOW_BINARY_LIMBS",
"QUOTIENT_HIGH_BINARY_LIMBS",
89 "RELATION_WIDE_LIMBS",
90 "P_X_LOW_LIMBS_RANGE_CONSTRAINT_0",
"P_X_LOW_LIMBS_RANGE_CONSTRAINT_1",
91 "P_X_LOW_LIMBS_RANGE_CONSTRAINT_2",
"P_X_LOW_LIMBS_RANGE_CONSTRAINT_3",
92 "P_X_LOW_LIMBS_RANGE_CONSTRAINT_4",
"P_X_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
93 "P_X_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"P_X_HIGH_LIMBS_RANGE_CONSTRAINT_1",
94 "P_X_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"P_X_HIGH_LIMBS_RANGE_CONSTRAINT_3",
95 "P_X_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"P_X_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
96 "P_Y_LOW_LIMBS_RANGE_CONSTRAINT_0",
"P_Y_LOW_LIMBS_RANGE_CONSTRAINT_1",
97 "P_Y_LOW_LIMBS_RANGE_CONSTRAINT_2",
"P_Y_LOW_LIMBS_RANGE_CONSTRAINT_3",
98 "P_Y_LOW_LIMBS_RANGE_CONSTRAINT_4",
"P_Y_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
99 "P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_1",
100 "P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_3",
101 "P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
102 "Z_LOW_LIMBS_RANGE_CONSTRAINT_0",
"Z_LOW_LIMBS_RANGE_CONSTRAINT_1",
103 "Z_LOW_LIMBS_RANGE_CONSTRAINT_2",
"Z_LOW_LIMBS_RANGE_CONSTRAINT_3",
104 "Z_LOW_LIMBS_RANGE_CONSTRAINT_4",
"Z_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
105 "Z_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"Z_HIGH_LIMBS_RANGE_CONSTRAINT_1",
106 "Z_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"Z_HIGH_LIMBS_RANGE_CONSTRAINT_3",
107 "Z_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"Z_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
108 "ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_0",
"ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_1",
109 "ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_2",
"ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_3",
110 "ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_4",
"ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
111 "ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_1",
112 "ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_3",
113 "ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
114 "QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_0",
"QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_1",
115 "QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_2",
"QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_3",
116 "QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_4",
"QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
117 "QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_1",
118 "QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_3",
119 "QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
120 "RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_0",
"RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_1",
121 "RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_2",
"RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_3",
122 "ORDERED_RANGE_CONSTRAINTS_0",
"ORDERED_RANGE_CONSTRAINTS_1",
123 "ORDERED_RANGE_CONSTRAINTS_2",
"ORDERED_RANGE_CONSTRAINTS_3",
124 "ORDERED_RANGE_CONSTRAINTS_4",
127 for (
const auto& label : wire_labels) {
136 manifest.
add_entry(2,
"Z_PERM", frs_per_G);
140 for (
size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
145 manifest.
add_entry(20,
"Libra:concatenation_commitment", frs_per_G);
150 for (
size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
156 manifest.
add_entry(38,
"Sumcheck:evaluations", 188);
157 manifest.
add_entry(38,
"Libra:claimed_evaluation", 1);
158 manifest.
add_entry(38,
"Libra:grand_sum_commitment", frs_per_G);
159 manifest.
add_entry(38,
"Libra:quotient_commitment", frs_per_G);
163 for (
size_t i = 1; i <= 16; ++i) {
169 for (
size_t i = 1; i <= 17; ++i) {
172 manifest.
add_entry(40,
"Gemini:P_pos", 1);
173 manifest.
add_entry(40,
"Gemini:P_neg", 1);
174 manifest.
add_entry(40,
"Libra:concatenation_eval", 1);
175 manifest.
add_entry(40,
"Libra:shifted_grand_sum_eval", 1);
176 manifest.
add_entry(40,
"Libra:grand_sum_eval", 1);
177 manifest.
add_entry(40,
"Libra:quotient_eval", 1);
181 manifest.
add_entry(41,
"Shplonk:Q", frs_per_G);
185 manifest.
add_entry(42,
"KZG:W", frs_per_G);
192 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue,
size_t count = 1)
194 for (
size_t i = 0; i < count; i++) {
195 op_queue->random_op_ultra_only();
199 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue,
size_t count = 100)
204 for (
size_t i = 0; i < count; i++) {
205 op_queue->add_accumulate(P1);
206 op_queue->mul_accumulate(P2, z);
208 op_queue->eq_and_reset();
213 const Fq& evaluation_challenge_x,
214 const size_t circuit_size_parameter = 500)
219 op_queue->no_op_ultra_only();
227 return CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
231 const Fq& evaluation_challenge_x,
232 const Fq& batching_challenge_v)
237 auto initial_transcript = prover_transcript->export_proof();
241 verifier_transcript->template receive_from_prover<Fq>(
"init");
252 op_queue_commitments[0] =
253 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
254 op_queue_commitments[1] =
255 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
256 op_queue_commitments[2] =
257 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
258 op_queue_commitments[3] =
259 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
262 uint256_t accumulated_result = prover.get_accumulated_result();
267 evaluation_challenge_x,
268 batching_challenge_v,
270 op_queue_commitments);
274 return result.
pairing_points.check() && result.reduction_succeeded;
293 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
298 prover_transcript->export_proof();
320 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
323 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
324 EXPECT_TRUE(verified);
341 op_queue->no_op_ultra_only();
343 add_mixed_ops(op_queue, 100);
345 auto circuit_builder =
CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue,
true };
348 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
349 EXPECT_TRUE(verified);
366 prover_transcript->export_proof();
374 auto compare_computed_vk_against_fixed = [&](
size_t circuit_size_parameter) {
376 generate_test_circuit(batching_challenge_v, evaluation_challenge_x, circuit_size_parameter);
380 auto labels = TranslatorFlavor::VerificationKey::get_labels();
382 for (
auto [vk_commitment, fixed_commitment] :
zip_view(computed_vk.get_all(), fixed_vk.get_all())) {
383 EXPECT_EQ(vk_commitment, fixed_commitment)
384 <<
"Mismatch between computed vk_commitment and fixed_commitment at label: " << labels[
index];
388 EXPECT_EQ(computed_vk, fixed_vk);
392 const size_t circuit_size_parameter_1 = 1 << 2;
393 const size_t circuit_size_parameter_2 = 1 << 3;
395 compare_computed_vk_against_fixed(circuit_size_parameter_1);
396 compare_computed_vk_against_fixed(circuit_size_parameter_2);
401 if (computed_hash != hardcoded_hash) {
402 info(
"VK hash mismatch! Update TranslatorHardcodedVKAndHash::vk_hash() with:");
403 info(
"0x", computed_hash);
405 EXPECT_EQ(computed_hash, hardcoded_hash) <<
"Hardcoded VK hash does not match computed hash";
420 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
432 verifier_transcript->enable_manifest();
435 uint256_t accumulated_result = prover.get_accumulated_result();
439 op_queue_commitments[0] = proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
440 op_queue_commitments[1] =
441 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
442 op_queue_commitments[2] =
443 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
444 op_queue_commitments[3] =
445 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
450 evaluation_challenge_x,
451 batching_challenge_v,
453 op_queue_commitments);
459 auto expected_manifest = build_expected_translator_manifest();
460 auto verifier_manifest = verifier_transcript->get_manifest();
462 EXPECT_EQ(verifier_manifest, expected_manifest);
static bool prove_and_verify(const CircuitBuilder &circuit_builder, const Fq &evaluation_challenge_x, const Fq &batching_challenge_v)
static void add_random_ops(std::shared_ptr< bb::ECCOpQueue > &op_queue, size_t count=1)
Flavor::Commitment Commitment
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.
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.
static const size_t OP_QUEUE_SIZE
Simple verification key class for fixed-size circuits (ECCVM, Translator).
static std::vector< fr > serialize_to_fields(const T &val)
Conversion from transcript values to bb::frs.
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.
BaseTranscript< Codec, HashFunction > Transcript
TranslatorCircuitBuilder CircuitBuilder
Curve::AffineElement Commitment
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS
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.
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
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
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()