Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
translator.test.cpp
Go to the documentation of this file.
10
11#include <gtest/gtest.h>
12using namespace bb;
13
17static auto& engine = numeric::get_debug_randomness();
18
19// Test helper: Create a VK by committing to proving key polynomials (for comparing with fixed VK)
22{
24 // Only ordered_extra_range_constraints_numerator needs a VK commitment (the only non-computable precomputed)
25 vk.ordered_extra_range_constraints_numerator =
26 proving_key->commitment_key.commit(proving_key->polynomials.ordered_extra_range_constraints_numerator);
27 return vk;
28}
29
30// Compute VK hash from fixed commitments (for test verification that vk_hash() is correct)
32{
34 // Serialize commitments using the Codec
35 for (const auto& commitment : TranslatorHardcodedVKAndHash::get_all()) {
37 for (const auto& fr : frs) {
38 elements.push_back(fr);
39 }
40 }
42}
43
44class TranslatorTests : public ::testing::Test {
46 using Fr = fr;
47 using Fq = fq;
49 using FF = Flavor::FF;
51
52 protected:
54
71 {
72 TranscriptManifest manifest;
73 constexpr size_t frs_per_G = FrCodec::calc_num_fields<Flavor::Commitment>();
74 constexpr size_t NUM_SUMCHECK_ROUNDS = Flavor::CONST_TRANSLATOR_LOG_N;
75
76 // Round 0: vk_hash, Gemini masking, wire commitments
77 manifest.add_entry(0, "vk_hash", 1);
78 manifest.add_entry(0, "Gemini:masking_poly_comm", frs_per_G);
79
80 // Wire commitments (10 total: 5 concatenated + 5 ordered)
81 // clang-format off
82 std::vector<std::string> wire_labels = {
83 "CONCATENATED_RANGE_CONSTRAINTS_0", "CONCATENATED_RANGE_CONSTRAINTS_1",
84 "CONCATENATED_RANGE_CONSTRAINTS_2", "CONCATENATED_RANGE_CONSTRAINTS_3",
85 "CONCATENATED_NON_RANGE",
86 "ORDERED_RANGE_CONSTRAINTS_0", "ORDERED_RANGE_CONSTRAINTS_1",
87 "ORDERED_RANGE_CONSTRAINTS_2", "ORDERED_RANGE_CONSTRAINTS_3",
88 "ORDERED_RANGE_CONSTRAINTS_4",
89 };
90 // clang-format on
91 for (const auto& label : wire_labels) {
92 manifest.add_entry(0, label, frs_per_G);
93 }
94 // beta and gamma are consecutive challenges (no data between), so both in round 0
95 manifest.add_challenge(0, "beta");
96 manifest.add_challenge(0, "gamma");
97
98 // Round 1: Z_PERM -> Sumcheck:alpha + all gate challenges (same round, no data between them)
99 manifest.add_entry(1, "Z_PERM", frs_per_G);
100 manifest.add_challenge(1, "Sumcheck:alpha");
101 for (size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
102 manifest.add_challenge(1, "Sumcheck:gate_challenge_" + std::to_string(i));
103 }
104
105 // Round 2: Libra concatenation commitment + Sum -> Libra:Challenge
106 manifest.add_entry(2, "Libra:concatenation_commitment", frs_per_G);
107 manifest.add_entry(2, "Libra:Sum", 1);
108 manifest.add_challenge(2, "Libra:Challenge");
109
110 // Rounds 3-15: Sumcheck univariates for mini-circuit rounds 0..12
111 constexpr size_t LOG_MINI = Flavor::LOG_MINI_CIRCUIT_SIZE;
112 for (size_t i = 0; i < LOG_MINI; ++i) {
113 manifest.add_entry(3 + i, "Sumcheck:univariate_" + std::to_string(i), 9);
114 manifest.add_challenge(3 + i, "Sumcheck:u_" + std::to_string(i));
115 }
116
117 // Round 16: 154 minicircuit wire evaluations sent mid-sumcheck, then univariate_13
118 manifest.add_entry(3 + LOG_MINI, "Sumcheck:minicircuit_evaluations", Flavor::NUM_MINICIRCUIT_EVALUATIONS);
119 manifest.add_entry(3 + LOG_MINI, "Sumcheck:univariate_" + std::to_string(LOG_MINI), 9);
120 manifest.add_challenge(3 + LOG_MINI, "Sumcheck:u_" + std::to_string(LOG_MINI));
121
122 // Rounds 17-19: remaining sumcheck rounds 14..16
123 for (size_t i = LOG_MINI + 1; i < NUM_SUMCHECK_ROUNDS; ++i) {
124 manifest.add_entry(3 + i, "Sumcheck:univariate_" + std::to_string(i), 9);
125 manifest.add_challenge(3 + i, "Sumcheck:u_" + std::to_string(i));
126 }
127
128 // Sumcheck full-circuit evaluations (computable precomputed + minicircuit wires excluded) + Libra commitments
129 // -> rho
130 const size_t eval_round = 3 + NUM_SUMCHECK_ROUNDS;
131 manifest.add_entry(eval_round, "Sumcheck:evaluations", Flavor::NUM_FULL_CIRCUIT_EVALUATIONS);
132 manifest.add_entry(eval_round, "Libra:claimed_evaluation", 1);
133 manifest.add_entry(eval_round, "Libra:grand_sum_commitment", frs_per_G);
134 manifest.add_entry(eval_round, "Libra:quotient_commitment", frs_per_G);
135 manifest.add_challenge(eval_round, "rho");
136
137 // Gemini fold commitments -> Gemini:r
138 const size_t gemini_fold_round = eval_round + 1;
139 for (size_t i = 1; i < NUM_SUMCHECK_ROUNDS; ++i) {
140 manifest.add_entry(gemini_fold_round, "Gemini:FOLD_" + std::to_string(i), frs_per_G);
141 }
142 manifest.add_challenge(gemini_fold_round, "Gemini:r");
143
144 // Gemini evaluations + Libra evals -> Shplonk:nu
145 const size_t gemini_eval_round = gemini_fold_round + 1;
146 for (size_t i = 1; i <= NUM_SUMCHECK_ROUNDS; ++i) {
147 manifest.add_entry(gemini_eval_round, "Gemini:a_" + std::to_string(i), 1);
148 }
149 // No more Gemini:P_pos / Gemini:P_neg (interleaving replaced by concatenation)
150 manifest.add_entry(gemini_eval_round, "Libra:concatenation_eval", 1);
151 manifest.add_entry(gemini_eval_round, "Libra:shifted_grand_sum_eval", 1);
152 manifest.add_entry(gemini_eval_round, "Libra:grand_sum_eval", 1);
153 manifest.add_entry(gemini_eval_round, "Libra:quotient_eval", 1);
154 manifest.add_challenge(gemini_eval_round, "Shplonk:nu");
155
156 // Shplonk:Q -> Shplonk:z
157 const size_t shplonk_round = gemini_eval_round + 1;
158 manifest.add_entry(shplonk_round, "Shplonk:Q", frs_per_G);
159 manifest.add_challenge(shplonk_round, "Shplonk:z");
160
161 // KZG:W -> KZG:masking_challenge
162 const size_t kzg_round = shplonk_round + 1;
163 manifest.add_entry(kzg_round, "KZG:W", frs_per_G);
164 manifest.add_challenge(kzg_round, "KZG:masking_challenge");
165
166 return manifest;
167 }
168
169 // Helper function to add no-ops
170 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 1)
171 {
172 for (size_t i = 0; i < count; i++) {
173 op_queue->random_op_ultra_only();
174 }
175 }
176
177 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 100)
178 {
179 auto P1 = G1::random_element();
180 auto P2 = G1::random_element();
181 auto z = Fr::random_element();
182 for (size_t i = 0; i < count; i++) {
183 op_queue->add_accumulate(P1);
184 op_queue->mul_accumulate(P2, z);
185 }
186 op_queue->eq_and_reset();
187 }
188
189 // Construct a test circuit based on some random operations
190 static CircuitBuilder generate_test_circuit(const Fq& batching_challenge_v,
191 const Fq& evaluation_challenge_x,
192 const size_t circuit_size_parameter = 500)
193 {
194
195 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
196 auto op_queue = std::make_shared<bb::ECCOpQueue>();
197 op_queue->no_op_ultra_only();
199 add_mixed_ops(op_queue, circuit_size_parameter / 2);
200 op_queue->merge();
201 add_mixed_ops(op_queue, circuit_size_parameter / 2);
203 op_queue->merge(MergeSettings::APPEND, ECCOpQueue::OP_QUEUE_SIZE - op_queue->get_current_subtable_size());
204
205 return CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
206 }
207
208 static bool prove_and_verify(const CircuitBuilder& circuit_builder,
209 const Fq& evaluation_challenge_x,
210 const Fq& batching_challenge_v)
211 {
212 // Setup prover transcript
213 auto prover_transcript = std::make_shared<Transcript>();
214 prover_transcript->send_to_verifier("init", Fq::random_element());
215 auto initial_transcript = prover_transcript->export_proof();
216
217 // Setup verifier transcript
218 auto verifier_transcript = std::make_shared<Transcript>(initial_transcript);
219 verifier_transcript->template receive_from_prover<Fq>("init");
220
221 // Create proving key and prover
222 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
223 TranslatorProver prover{ proving_key, prover_transcript };
224
225 // Generate proof
226 auto proof = prover.construct_proof();
227
228 // Commit to op queue wires
230 op_queue_commitments[0] =
231 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
232 op_queue_commitments[1] =
233 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
234 op_queue_commitments[2] =
235 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
236 op_queue_commitments[3] =
237 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
238
239 // Get accumulated_result from the prover
240 uint256_t accumulated_result = prover.get_accumulated_result();
241
242 // Create verifier
243 TranslatorVerifier verifier(verifier_transcript,
244 proof,
245 evaluation_challenge_x,
246 batching_challenge_v,
247 accumulated_result,
248 op_queue_commitments);
249
250 // Verify proof: get reduction result and check all components
251 auto result = verifier.reduce_to_pairing_check();
252 return result.pairing_points.check() && result.reduction_succeeded;
253 }
254};
255
263TEST_F(TranslatorTests, ProofLengthCheck)
264{
265 using Fq = fq;
266
267 Fq batching_challenge_v = Fq::random_element();
268 Fq evaluation_challenge_x = Fq::random_element();
269
270 // Generate a circuit and its verification key (computed at runtime from the proving key)
271 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
272
273 // Setup prover transcript
274 auto prover_transcript = std::make_shared<Transcript>();
275 prover_transcript->send_to_verifier("init", Fq::random_element());
276 prover_transcript->export_proof();
277 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
278 TranslatorProver prover{ proving_key, prover_transcript };
279
280 // Generate proof
281 auto proof = prover.construct_proof();
282
283 EXPECT_EQ(proof.size(), TranslatorFlavor::PROOF_LENGTH);
284}
285
291{
292 using Fq = fq;
293
294 Fq batching_challenge_v = Fq::random_element();
295 Fq evaluation_challenge_x = Fq::random_element();
296
297 // Generate a circuit without no-ops
298 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
299
300 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
301 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
302 EXPECT_TRUE(verified);
303}
304
311{
312 using Fq = fq;
313
314 Fq batching_challenge_v = Fq::random_element();
315 Fq evaluation_challenge_x = Fq::random_element();
316
317 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
318 auto op_queue = std::make_shared<bb::ECCOpQueue>();
319 op_queue->no_op_ultra_only();
320 add_random_ops(op_queue, CircuitBuilder::NUM_RANDOM_OPS_START);
321 add_mixed_ops(op_queue, 100);
322 op_queue->merge();
323 auto circuit_builder = CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue, /*avm_mode=*/true };
324
325 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
326 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
327 EXPECT_TRUE(verified);
328}
329
339{
340 using Fq = fq;
341
342 auto prover_transcript = std::make_shared<Transcript>();
343 prover_transcript->send_to_verifier("init", Fq::random_element());
344 prover_transcript->export_proof();
345 Fq batching_challenge_v = Fq::random_element();
346 Fq evaluation_challenge_x = Fq::random_element();
347
348 // Generate the default fixed VK
350
351 // Lambda for manually computing a verification key for a given circuit and comparing it to the fixed VK
352 auto compare_computed_vk_against_fixed = [&](size_t circuit_size_parameter) {
353 CircuitBuilder circuit_builder =
354 generate_test_circuit(batching_challenge_v, evaluation_challenge_x, circuit_size_parameter);
355 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
356 TranslatorProver prover{ proving_key, prover_transcript };
357 TranslatorFlavor::VerificationKey computed_vk = create_vk_from_proving_key(proving_key->proving_key);
358 auto labels = TranslatorFlavor::VerificationKey::get_labels();
359
360 size_t index = 0;
361 for (auto [vk_commitment, fixed_commitment] : zip_view(computed_vk.get_all(), fixed_vk.get_all())) {
362 if (vk_commitment != fixed_commitment) {
363 info("// ", labels[index]);
364 info("Commitment(uint256_t(\"0x", vk_commitment.x, "\"),");
365 info(" uint256_t(\"0x", vk_commitment.y, "\")),");
366 }
367 EXPECT_EQ(vk_commitment, fixed_commitment) << "Mismatch at label: " << labels[index];
368 ++index;
369 }
370
371 EXPECT_EQ(computed_vk, fixed_vk);
372 };
373
374 // Check consistency of the fixed VK with the computed VK for some different circuit sizes
375 const size_t circuit_size_parameter_1 = 1 << 2;
376 const size_t circuit_size_parameter_2 = 1 << 3;
377
378 compare_computed_vk_against_fixed(circuit_size_parameter_1);
379 compare_computed_vk_against_fixed(circuit_size_parameter_2);
380
381 // Verify that the hardcoded VK hash matches the computed hash
382 auto computed_hash = compute_translator_vk_hash();
383 auto hardcoded_hash = TranslatorHardcodedVKAndHash::vk_hash();
384 if (computed_hash != hardcoded_hash) {
385 info("VK hash mismatch! Update TranslatorHardcodedVKAndHash::vk_hash() with:");
386 info("0x", computed_hash);
387 }
388 EXPECT_EQ(computed_hash, hardcoded_hash) << "Hardcoded VK hash does not match computed hash";
389}
390
396TEST_F(TranslatorTests, TranscriptPinned)
397{
398 using Fq = fq;
399
400 Fq batching_challenge_v = Fq::random_element();
401 Fq evaluation_challenge_x = Fq::random_element();
402
403 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
404
405 // Create proving key and prover
406 auto prover_transcript = std::make_shared<Transcript>();
407 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
408 TranslatorProver prover{ proving_key, prover_transcript };
409
410 // Generate proof
411 auto proof = prover.construct_proof();
412
413 // Setup verifier transcript with manifest tracking
414 auto verifier_transcript = std::make_shared<Transcript>(proof);
415 verifier_transcript->enable_manifest();
416
417 // Get accumulated_result from the prover
418 uint256_t accumulated_result = prover.get_accumulated_result();
419
420 // Commit to op queue wires
422 op_queue_commitments[0] = proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
423 op_queue_commitments[1] =
424 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
425 op_queue_commitments[2] =
426 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
427 op_queue_commitments[3] =
428 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
429
430 // Create verifier with all required inputs
431 TranslatorVerifier verifier(verifier_transcript,
432 proof,
433 evaluation_challenge_x,
434 batching_challenge_v,
435 accumulated_result,
436 op_queue_commitments);
437
438 // Run verification - just reduce to pairing check to exercise the transcript
439 [[maybe_unused]] auto result = verifier.reduce_to_pairing_check();
440
441 // Compare verifier manifest against hardcoded expected structure
442 auto expected_manifest = build_expected_translator_manifest();
443 auto verifier_manifest = verifier_transcript->get_manifest();
444
445 EXPECT_EQ(verifier_manifest, expected_manifest);
446}
447
464TEST_F(TranslatorTests, EvaluationPartition)
465{
466 using Flavor = TranslatorFlavor;
467 using FF = Flavor::FF;
468
469 // Fill all entities with distinct values (entity index as value)
471 {
472 size_t idx = 0;
473 for (auto& e : evals.get_all()) {
474 e = FF(idx++);
475 }
476 }
477
478 // Collect addresses of all entities touched by each getter
479 std::set<FF*> covered;
480
481 for (auto& e : evals.get_minicircuit_wires()) {
482 EXPECT_TRUE(covered.insert(&e).second) << "minicircuit wire overlaps with a previous entity";
483 }
484 EXPECT_EQ(covered.size(), Flavor::NUM_MINICIRCUIT_WIRES);
485
486 for (auto& e : evals.get_minicircuit_wires_shifted()) {
487 EXPECT_TRUE(covered.insert(&e).second) << "minicircuit wire shift overlaps with a previous entity";
488 }
489 EXPECT_EQ(covered.size(), 2 * Flavor::NUM_MINICIRCUIT_WIRES);
490
491 for (auto& e : evals.get_full_circuit_entities()) {
492 EXPECT_TRUE(covered.insert(&e).second) << "full-circuit entity overlaps with a previous entity";
493 }
494 EXPECT_EQ(covered.size(), 2 * Flavor::NUM_MINICIRCUIT_WIRES + Flavor::NUM_FULL_CIRCUIT_EVALUATIONS);
495
496 // Concat polys are reconstructed (not sent in proof), but still in AllEntities
497 for (auto& e : evals.get_concatenated()) {
498 EXPECT_TRUE(covered.insert(&e).second) << "concatenated poly overlaps with a previous entity";
499 }
500 EXPECT_EQ(covered.size(),
501 2 * Flavor::NUM_MINICIRCUIT_WIRES + Flavor::NUM_FULL_CIRCUIT_EVALUATIONS +
502 Flavor::NUM_CONCATENATED_POLYS);
503
504 // The computable precomputed selectors are the remaining entities
505 size_t remaining = Flavor::NUM_ALL_ENTITIES - covered.size();
506 EXPECT_EQ(remaining, Flavor::NUM_COMPUTABLE_PRECOMPUTED);
507
508 // Verify the remaining entities are exactly the computable precomputed ones
509 for (auto& e : evals.get_all()) {
510 if (covered.find(&e) == covered.end()) {
511 // This entity must be one of the 12 computable precomputed selectors
512 remaining--;
513 }
514 }
515 EXPECT_EQ(remaining, 0UL);
516}
517
523TEST_F(TranslatorTests, VerifierPopulatesAllEntities)
524{
525 using Flavor = TranslatorFlavor;
526 using FF = Flavor::FF;
527
528 // Prepare random minicircuit evaluations (154 values)
530 for (auto& v : mid) {
531 v = FF::random_element(&engine);
532 }
533
534 // Prepare random full-circuit evaluations (26 values)
536 for (auto& v : full_circuit) {
537 v = FF::random_element(&engine);
538 }
539
540 // Random challenge (computable precomputed selectors depend on this)
541 std::vector<FF> challenge(Flavor::CONST_TRANSLATOR_LOG_N);
542 for (auto& u : challenge) {
543 u = FF::random_element(&engine);
544 }
545
546 // Verifier reconstruction: start from zero, populate via the two verifier methods
548 Flavor::set_minicircuit_evaluations(evals, mid);
549 Flavor::complete_full_circuit_evaluations(evals, full_circuit, std::span<const FF>(challenge));
550
551 // Every entity should now be nonzero (probability of a random FF being zero is negligible)
552 auto all = evals.get_all();
553 for (size_t i = 0; i < Flavor::NUM_ALL_ENTITIES; i++) {
554 EXPECT_NE(all[i], FF(0)) << "Entity " << i << " was not populated by verifier methods";
555 }
556}
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
A base class labelling all entities (for instance, all of the polynomials used by the prover during s...
typename Curve::ScalarField FF
static constexpr size_t NUM_ALL_ENTITIES
Simple verification key class for fixed-size circuits (ECCVM, Translator, AVM).
Definition flavor.hpp:101
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 bool check(const Builder &circuit)
Check the witness satisifies the circuit.
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::ScalarField FF
Curve::AffineElement Commitment
static constexpr size_t NUM_MINICIRCUIT_EVALUATIONS
static constexpr size_t LOG_MINI_CIRCUIT_SIZE
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
Definition group.hpp:42
#define info(...)
Definition log.hpp:93
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:217
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
field< Bn254FqParams > fq
Definition fq.hpp:170
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:142
field< Bn254FrParams > fr
Definition fr.hpp:174
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
static std::vector< Commitment > get_all()
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()