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);
73 constexpr size_t frs_per_G = FrCodec::calc_num_fields<Flavor::Commitment>();
74 constexpr size_t NUM_SUMCHECK_ROUNDS = 17;
78 manifest.
add_entry(0,
"Gemini:masking_poly_comm", frs_per_G);
82 std::vector<std::string> wire_labels = {
83 "P_X_LOW_LIMBS",
"P_X_HIGH_LIMBS",
"P_Y_LOW_LIMBS",
"P_Y_HIGH_LIMBS",
84 "Z_LOw_LIMBS",
"Z_HIGH_LIMBS",
85 "ACCUMULATORS_BINARY_LIMBS_0",
"ACCUMULATORS_BINARY_LIMBS_1",
86 "ACCUMULATORS_BINARY_LIMBS_2",
"ACCUMULATORS_BINARY_LIMBS_3",
87 "QUOTIENT_LOW_BINARY_LIMBS",
"QUOTIENT_HIGH_BINARY_LIMBS",
88 "RELATION_WIDE_LIMBS",
89 "P_X_LOW_LIMBS_RANGE_CONSTRAINT_0",
"P_X_LOW_LIMBS_RANGE_CONSTRAINT_1",
90 "P_X_LOW_LIMBS_RANGE_CONSTRAINT_2",
"P_X_LOW_LIMBS_RANGE_CONSTRAINT_3",
91 "P_X_LOW_LIMBS_RANGE_CONSTRAINT_4",
"P_X_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
92 "P_X_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"P_X_HIGH_LIMBS_RANGE_CONSTRAINT_1",
93 "P_X_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"P_X_HIGH_LIMBS_RANGE_CONSTRAINT_3",
94 "P_X_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"P_X_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
95 "P_Y_LOW_LIMBS_RANGE_CONSTRAINT_0",
"P_Y_LOW_LIMBS_RANGE_CONSTRAINT_1",
96 "P_Y_LOW_LIMBS_RANGE_CONSTRAINT_2",
"P_Y_LOW_LIMBS_RANGE_CONSTRAINT_3",
97 "P_Y_LOW_LIMBS_RANGE_CONSTRAINT_4",
"P_Y_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
98 "P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_1",
99 "P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_3",
100 "P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
101 "Z_LOW_LIMBS_RANGE_CONSTRAINT_0",
"Z_LOW_LIMBS_RANGE_CONSTRAINT_1",
102 "Z_LOW_LIMBS_RANGE_CONSTRAINT_2",
"Z_LOW_LIMBS_RANGE_CONSTRAINT_3",
103 "Z_LOW_LIMBS_RANGE_CONSTRAINT_4",
"Z_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
104 "Z_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"Z_HIGH_LIMBS_RANGE_CONSTRAINT_1",
105 "Z_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"Z_HIGH_LIMBS_RANGE_CONSTRAINT_3",
106 "Z_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"Z_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
107 "ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_0",
"ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_1",
108 "ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_2",
"ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_3",
109 "ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_4",
"ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
110 "ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_1",
111 "ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_3",
112 "ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"ACCUMULATOR_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
113 "QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_0",
"QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_1",
114 "QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_2",
"QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_3",
115 "QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_4",
"QUOTIENT_LOW_LIMBS_RANGE_CONSTRAINT_TAIL",
116 "QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_0",
"QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_1",
117 "QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_2",
"QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_3",
118 "QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_4",
"QUOTIENT_HIGH_LIMBS_RANGE_CONSTRAINT_TAIL",
119 "RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_0",
"RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_1",
120 "RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_2",
"RELATION_WIDE_LIMBS_RANGE_CONSTRAINT_3",
121 "ORDERED_RANGE_CONSTRAINTS_0",
"ORDERED_RANGE_CONSTRAINTS_1",
122 "ORDERED_RANGE_CONSTRAINTS_2",
"ORDERED_RANGE_CONSTRAINTS_3",
123 "ORDERED_RANGE_CONSTRAINTS_4",
126 for (
const auto& label : wire_labels) {
134 manifest.
add_entry(1,
"Z_PERM", frs_per_G);
136 for (
size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
141 manifest.
add_entry(2,
"Libra:concatenation_commitment", frs_per_G);
146 for (
size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
152 manifest.
add_entry(20,
"Sumcheck:evaluations", 188);
153 manifest.
add_entry(20,
"Libra:claimed_evaluation", 1);
154 manifest.
add_entry(20,
"Libra:grand_sum_commitment", frs_per_G);
155 manifest.
add_entry(20,
"Libra:quotient_commitment", frs_per_G);
159 for (
size_t i = 1; i <= 16; ++i) {
165 for (
size_t i = 1; i <= 17; ++i) {
168 manifest.
add_entry(22,
"Gemini:P_pos", 1);
169 manifest.
add_entry(22,
"Gemini:P_neg", 1);
170 manifest.
add_entry(22,
"Libra:concatenation_eval", 1);
171 manifest.
add_entry(22,
"Libra:shifted_grand_sum_eval", 1);
172 manifest.
add_entry(22,
"Libra:grand_sum_eval", 1);
173 manifest.
add_entry(22,
"Libra:quotient_eval", 1);
177 manifest.
add_entry(23,
"Shplonk:Q", frs_per_G);
181 manifest.
add_entry(24,
"KZG:W", frs_per_G);
188 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue,
size_t count = 1)
190 for (
size_t i = 0; i < count; i++) {
191 op_queue->random_op_ultra_only();
195 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue,
size_t count = 100)
200 for (
size_t i = 0; i < count; i++) {
201 op_queue->add_accumulate(P1);
202 op_queue->mul_accumulate(P2, z);
204 op_queue->eq_and_reset();
209 const Fq& evaluation_challenge_x,
210 const size_t circuit_size_parameter = 500)
215 op_queue->no_op_ultra_only();
223 return CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
227 const Fq& evaluation_challenge_x,
228 const Fq& batching_challenge_v)
233 auto initial_transcript = prover_transcript->export_proof();
237 verifier_transcript->template receive_from_prover<Fq>(
"init");
248 op_queue_commitments[0] =
249 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
250 op_queue_commitments[1] =
251 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
252 op_queue_commitments[2] =
253 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
254 op_queue_commitments[3] =
255 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
258 uint256_t accumulated_result = prover.get_accumulated_result();
263 evaluation_challenge_x,
264 batching_challenge_v,
266 op_queue_commitments);
270 return result.
pairing_points.check() && result.reduction_succeeded;
289 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
294 prover_transcript->export_proof();
316 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
319 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
320 EXPECT_TRUE(verified);
337 op_queue->no_op_ultra_only();
339 add_mixed_ops(op_queue, 100);
341 auto circuit_builder =
CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue,
true };
344 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
345 EXPECT_TRUE(verified);
362 prover_transcript->export_proof();
370 auto compare_computed_vk_against_fixed = [&](
size_t circuit_size_parameter) {
372 generate_test_circuit(batching_challenge_v, evaluation_challenge_x, circuit_size_parameter);
376 auto labels = TranslatorFlavor::VerificationKey::get_labels();
378 for (
auto [vk_commitment, fixed_commitment] :
zip_view(computed_vk.get_all(), fixed_vk.get_all())) {
379 EXPECT_EQ(vk_commitment, fixed_commitment)
380 <<
"Mismatch between computed vk_commitment and fixed_commitment at label: " << labels[
index];
384 EXPECT_EQ(computed_vk, fixed_vk);
388 const size_t circuit_size_parameter_1 = 1 << 2;
389 const size_t circuit_size_parameter_2 = 1 << 3;
391 compare_computed_vk_against_fixed(circuit_size_parameter_1);
392 compare_computed_vk_against_fixed(circuit_size_parameter_2);
397 if (computed_hash != hardcoded_hash) {
398 info(
"VK hash mismatch! Update TranslatorHardcodedVKAndHash::vk_hash() with:");
399 info(
"0x", computed_hash);
401 EXPECT_EQ(computed_hash, hardcoded_hash) <<
"Hardcoded VK hash does not match computed hash";
416 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
428 verifier_transcript->enable_manifest();
431 uint256_t accumulated_result = prover.get_accumulated_result();
435 op_queue_commitments[0] = proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
436 op_queue_commitments[1] =
437 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
438 op_queue_commitments[2] =
439 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
440 op_queue_commitments[3] =
441 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
446 evaluation_challenge_x,
447 batching_challenge_v,
449 op_queue_commitments);
455 auto expected_manifest = build_expected_translator_manifest();
456 auto verifier_manifest = verifier_transcript->get_manifest();
458 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
static constexpr size_t PROOF_LENGTH
TranslatorCircuitBuilder CircuitBuilder
Curve::AffineElement Commitment
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()