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
162 const size_t kzg_round = shplonk_round + 1;
163 manifest.add_entry(kzg_round, "KZG:W", frs_per_G);
164
165 return manifest;
166 }
167
168 // Helper function to add no-ops
169 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 1)
170 {
171 for (size_t i = 0; i < count; i++) {
172 op_queue->random_op_ultra_only();
173 }
174 }
175
176 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 100)
177 {
178 auto P1 = G1::random_element();
179 auto P2 = G1::random_element();
180 auto z = Fr::random_element();
181 for (size_t i = 0; i < count; i++) {
182 op_queue->add_accumulate(P1);
183 op_queue->mul_accumulate(P2, z);
184 }
185 op_queue->eq_and_reset();
186 }
187
188 // Construct a test circuit based on some random operations
189 static CircuitBuilder generate_test_circuit(const Fq& batching_challenge_v,
190 const Fq& evaluation_challenge_x,
191 const size_t circuit_size_parameter = 500)
192 {
193
194 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
195 auto op_queue = std::make_shared<bb::ECCOpQueue>();
196 op_queue->no_op_ultra_only();
198 add_mixed_ops(op_queue, circuit_size_parameter / 2);
199 op_queue->merge();
200 add_mixed_ops(op_queue, circuit_size_parameter / 2);
202 op_queue->merge(MergeSettings::APPEND, ECCOpQueue::OP_QUEUE_SIZE - op_queue->get_current_subtable_size());
203
204 return CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
205 }
206
207 static bool prove_and_verify(const CircuitBuilder& circuit_builder,
208 const Fq& evaluation_challenge_x,
209 const Fq& batching_challenge_v)
210 {
211 // Setup prover transcript
212 auto prover_transcript = std::make_shared<Transcript>();
213 prover_transcript->send_to_verifier("init", Fq::random_element());
214 auto initial_transcript = prover_transcript->export_proof();
215
216 // Setup verifier transcript
217 auto verifier_transcript = std::make_shared<Transcript>(initial_transcript);
218 verifier_transcript->template receive_from_prover<Fq>("init");
219
220 // Create proving key and prover
221 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
222 TranslatorProver prover{ proving_key, prover_transcript };
223
224 // Generate proof
225 auto proof = prover.construct_proof();
226
227 // Commit to op queue wires
229 op_queue_commitments[0] =
230 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
231 op_queue_commitments[1] =
232 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
233 op_queue_commitments[2] =
234 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
235 op_queue_commitments[3] =
236 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
237
238 // Get accumulated_result from the prover
239 uint256_t accumulated_result = prover.get_accumulated_result();
240
241 // Create verifier
242 TranslatorVerifier verifier(verifier_transcript,
243 proof,
244 evaluation_challenge_x,
245 batching_challenge_v,
246 accumulated_result,
247 op_queue_commitments);
248
249 // Verify proof: get reduction result and check all components
250 auto result = verifier.reduce_to_pairing_check();
251 return result.pairing_points.check() && result.reduction_succeeded;
252 }
253};
254
262TEST_F(TranslatorTests, ProofLengthCheck)
263{
264 using Fq = fq;
265
266 Fq batching_challenge_v = Fq::random_element();
267 Fq evaluation_challenge_x = Fq::random_element();
268
269 // Generate a circuit and its verification key (computed at runtime from the proving key)
270 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
271
272 // Setup prover transcript
273 auto prover_transcript = std::make_shared<Transcript>();
274 prover_transcript->send_to_verifier("init", Fq::random_element());
275 prover_transcript->export_proof();
276 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
277 TranslatorProver prover{ proving_key, prover_transcript };
278
279 // Generate proof
280 auto proof = prover.construct_proof();
281
282 EXPECT_EQ(proof.size(), TranslatorFlavor::PROOF_LENGTH);
283}
284
290{
291 using Fq = fq;
292
293 Fq batching_challenge_v = Fq::random_element();
294 Fq evaluation_challenge_x = Fq::random_element();
295
296 // Generate a circuit without no-ops
297 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
298
299 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
300 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
301 EXPECT_TRUE(verified);
302}
303
310{
311 using Fq = fq;
312
313 Fq batching_challenge_v = Fq::random_element();
314 Fq evaluation_challenge_x = Fq::random_element();
315
316 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
317 auto op_queue = std::make_shared<bb::ECCOpQueue>();
318 op_queue->no_op_ultra_only();
319 add_random_ops(op_queue, CircuitBuilder::NUM_RANDOM_OPS_START);
320 add_mixed_ops(op_queue, 100);
321 op_queue->merge();
322 auto circuit_builder = CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue, /*avm_mode=*/true };
323
324 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
325 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
326 EXPECT_TRUE(verified);
327}
328
338{
339 using Fq = fq;
340
341 auto prover_transcript = std::make_shared<Transcript>();
342 prover_transcript->send_to_verifier("init", Fq::random_element());
343 prover_transcript->export_proof();
344 Fq batching_challenge_v = Fq::random_element();
345 Fq evaluation_challenge_x = Fq::random_element();
346
347 // Generate the default fixed VK
349
350 // Lambda for manually computing a verification key for a given circuit and comparing it to the fixed VK
351 auto compare_computed_vk_against_fixed = [&](size_t circuit_size_parameter) {
352 CircuitBuilder circuit_builder =
353 generate_test_circuit(batching_challenge_v, evaluation_challenge_x, circuit_size_parameter);
354 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
355 TranslatorProver prover{ proving_key, prover_transcript };
356 TranslatorFlavor::VerificationKey computed_vk = create_vk_from_proving_key(proving_key->proving_key);
357 auto labels = TranslatorFlavor::VerificationKey::get_labels();
358
359 size_t index = 0;
360 for (auto [vk_commitment, fixed_commitment] : zip_view(computed_vk.get_all(), fixed_vk.get_all())) {
361 if (vk_commitment != fixed_commitment) {
362 info("// ", labels[index]);
363 info("Commitment(uint256_t(\"0x", vk_commitment.x, "\"),");
364 info(" uint256_t(\"0x", vk_commitment.y, "\")),");
365 }
366 EXPECT_EQ(vk_commitment, fixed_commitment) << "Mismatch at label: " << labels[index];
367 ++index;
368 }
369
370 EXPECT_EQ(computed_vk, fixed_vk);
371 };
372
373 // Check consistency of the fixed VK with the computed VK for some different circuit sizes
374 const size_t circuit_size_parameter_1 = 1 << 2;
375 const size_t circuit_size_parameter_2 = 1 << 3;
376
377 compare_computed_vk_against_fixed(circuit_size_parameter_1);
378 compare_computed_vk_against_fixed(circuit_size_parameter_2);
379
380 // Verify that the hardcoded VK hash matches the computed hash
381 auto computed_hash = compute_translator_vk_hash();
382 auto hardcoded_hash = TranslatorHardcodedVKAndHash::vk_hash();
383 if (computed_hash != hardcoded_hash) {
384 info("VK hash mismatch! Update TranslatorHardcodedVKAndHash::vk_hash() with:");
385 info("0x", computed_hash);
386 }
387 EXPECT_EQ(computed_hash, hardcoded_hash) << "Hardcoded VK hash does not match computed hash";
388}
389
395TEST_F(TranslatorTests, TranscriptPinned)
396{
397 using Fq = fq;
398
399 Fq batching_challenge_v = Fq::random_element();
400 Fq evaluation_challenge_x = Fq::random_element();
401
402 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
403
404 // Create proving key and prover
405 auto prover_transcript = std::make_shared<Transcript>();
406 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
407 TranslatorProver prover{ proving_key, prover_transcript };
408
409 // Generate proof
410 auto proof = prover.construct_proof();
411
412 // Setup verifier transcript with manifest tracking
413 auto verifier_transcript = std::make_shared<Transcript>(proof);
414 verifier_transcript->enable_manifest();
415
416 // Get accumulated_result from the prover
417 uint256_t accumulated_result = prover.get_accumulated_result();
418
419 // Commit to op queue wires
421 op_queue_commitments[0] = proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.op);
422 op_queue_commitments[1] =
423 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_lo_y_hi);
424 op_queue_commitments[2] =
425 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.x_hi_z_1);
426 op_queue_commitments[3] =
427 proving_key->proving_key->commitment_key.commit(proving_key->proving_key->polynomials.y_lo_z_2);
428
429 // Create verifier with all required inputs
430 TranslatorVerifier verifier(verifier_transcript,
431 proof,
432 evaluation_challenge_x,
433 batching_challenge_v,
434 accumulated_result,
435 op_queue_commitments);
436
437 // Run verification - just reduce to pairing check to exercise the transcript
438 [[maybe_unused]] auto result = verifier.reduce_to_pairing_check();
439
440 // Compare verifier manifest against hardcoded expected structure
441 auto expected_manifest = build_expected_translator_manifest();
442 auto verifier_manifest = verifier_transcript->get_manifest();
443
444 EXPECT_EQ(verifier_manifest, expected_manifest);
445}
446
463TEST_F(TranslatorTests, EvaluationPartition)
464{
465 using Flavor = TranslatorFlavor;
466 using FF = Flavor::FF;
467
468 // Fill all entities with distinct values (entity index as value)
470 {
471 size_t idx = 0;
472 for (auto& e : evals.get_all()) {
473 e = FF(idx++);
474 }
475 }
476
477 // Collect addresses of all entities touched by each getter
478 std::set<FF*> covered;
479
480 for (auto& e : evals.get_minicircuit_wires()) {
481 EXPECT_TRUE(covered.insert(&e).second) << "minicircuit wire overlaps with a previous entity";
482 }
483 EXPECT_EQ(covered.size(), Flavor::NUM_MINICIRCUIT_WIRES);
484
485 for (auto& e : evals.get_minicircuit_wires_shifted()) {
486 EXPECT_TRUE(covered.insert(&e).second) << "minicircuit wire shift overlaps with a previous entity";
487 }
488 EXPECT_EQ(covered.size(), 2 * Flavor::NUM_MINICIRCUIT_WIRES);
489
490 for (auto& e : evals.get_full_circuit_entities()) {
491 EXPECT_TRUE(covered.insert(&e).second) << "full-circuit entity overlaps with a previous entity";
492 }
493 EXPECT_EQ(covered.size(), 2 * Flavor::NUM_MINICIRCUIT_WIRES + Flavor::NUM_FULL_CIRCUIT_EVALUATIONS);
494
495 // Concat polys are reconstructed (not sent in proof), but still in AllEntities
496 for (auto& e : evals.get_concatenated()) {
497 EXPECT_TRUE(covered.insert(&e).second) << "concatenated poly overlaps with a previous entity";
498 }
499 EXPECT_EQ(covered.size(),
500 2 * Flavor::NUM_MINICIRCUIT_WIRES + Flavor::NUM_FULL_CIRCUIT_EVALUATIONS +
501 Flavor::NUM_CONCATENATED_POLYS);
502
503 // The computable precomputed selectors are the remaining entities
504 size_t remaining = Flavor::NUM_ALL_ENTITIES - covered.size();
505 EXPECT_EQ(remaining, Flavor::NUM_COMPUTABLE_PRECOMPUTED);
506
507 // Verify the remaining entities are exactly the computable precomputed ones
508 for (auto& e : evals.get_all()) {
509 if (covered.find(&e) == covered.end()) {
510 // This entity must be one of the 12 computable precomputed selectors
511 remaining--;
512 }
513 }
514 EXPECT_EQ(remaining, 0UL);
515}
516
522TEST_F(TranslatorTests, VerifierPopulatesAllEntities)
523{
524 using Flavor = TranslatorFlavor;
525 using FF = Flavor::FF;
526
527 // Prepare random minicircuit evaluations (154 values)
529 for (auto& v : mid) {
530 v = FF::random_element(&engine);
531 }
532
533 // Prepare random full-circuit evaluations (26 values)
535 for (auto& v : full_circuit) {
536 v = FF::random_element(&engine);
537 }
538
539 // Random challenge (computable precomputed selectors depend on this)
540 std::vector<FF> challenge(Flavor::CONST_TRANSLATOR_LOG_N);
541 for (auto& u : challenge) {
542 u = FF::random_element(&engine);
543 }
544
545 // Verifier reconstruction: start from zero, populate via the two verifier methods
547 Flavor::set_minicircuit_evaluations(evals, mid);
548 Flavor::complete_full_circuit_evaluations(evals, full_circuit, std::span<const FF>(challenge));
549
550 // Every entity should now be nonzero (probability of a random FF being zero is negligible)
551 auto all = evals.get_all();
552 for (size_t i = 0; i < Flavor::NUM_ALL_ENTITIES; i++) {
553 EXPECT_NE(all[i], FF(0)) << "Entity " << i << " was not populated by verifier methods";
554 }
555}
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:153
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:155
field< Bn254FrParams > fr
Definition fr.hpp:155
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()