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 // Overwrite fixed commitments with computed commitments from the proving key
25 for (auto [polynomial, commitment] : zip_view(proving_key->polynomials.get_precomputed(), vk.get_all())) {
26 commitment = proving_key->commitment_key.commit(polynomial);
27 }
28 return vk;
29}
30
31// Compute VK hash from fixed commitments (for test verification that vk_hash() is correct)
33{
35 // Serialize commitments using the Codec
36 for (const auto& commitment : TranslatorHardcodedVKAndHash::get_all()) {
38 for (const auto& fr : frs) {
39 elements.push_back(fr);
40 }
41 }
43}
44
45class TranslatorTests : public ::testing::Test {
47 using Fr = fr;
48 using Fq = fq;
50 using FF = Flavor::FF;
52
53 protected:
55
71 {
72 TranscriptManifest manifest;
73 constexpr size_t frs_per_G = FrCodec::calc_num_fields<Flavor::Commitment>();
74 constexpr size_t NUM_SUMCHECK_ROUNDS = 17; // CONST_TRANSLATOR_LOG_N + 2
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 (82 total, in order from the manifest dump)
81 // clang-format off
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",
124 };
125 // clang-format on
126 for (const auto& label : wire_labels) {
127 manifest.add_entry(0, label, frs_per_G);
128 }
129 // beta and gamma are consecutive challenges (no data between), so both in round 0
130 manifest.add_challenge(0, "beta");
131 manifest.add_challenge(0, "gamma");
132
133 // Round 1: Z_PERM -> Sumcheck:alpha + all gate challenges (same round, no data between them)
134 manifest.add_entry(1, "Z_PERM", frs_per_G);
135 manifest.add_challenge(1, "Sumcheck:alpha");
136 for (size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
137 manifest.add_challenge(1, "Sumcheck:gate_challenge_" + std::to_string(i));
138 }
139
140 // Round 2: Libra concatenation commitment + Sum -> Libra:Challenge
141 manifest.add_entry(2, "Libra:concatenation_commitment", frs_per_G);
142 manifest.add_entry(2, "Libra:Sum", 1);
143 manifest.add_challenge(2, "Libra:Challenge");
144
145 // Rounds 3-19: Sumcheck univariates (17 rounds)
146 for (size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
147 manifest.add_entry(3 + i, "Sumcheck:univariate_" + std::to_string(i), 9);
148 manifest.add_challenge(3 + i, "Sumcheck:u_" + std::to_string(i));
149 }
150
151 // Round 20: Sumcheck evaluations + Libra commitments -> rho
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);
156 manifest.add_challenge(20, "rho");
157
158 // Round 21: Gemini fold commitments -> Gemini:r
159 for (size_t i = 1; i <= 16; ++i) {
160 manifest.add_entry(21, "Gemini:FOLD_" + std::to_string(i), frs_per_G);
161 }
162 manifest.add_challenge(21, "Gemini:r");
163
164 // Round 22: Gemini evaluations + Libra evals -> Shplonk:nu
165 for (size_t i = 1; i <= 17; ++i) {
166 manifest.add_entry(22, "Gemini:a_" + std::to_string(i), 1);
167 }
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);
174 manifest.add_challenge(22, "Shplonk:nu");
175
176 // Round 23: Shplonk:Q -> Shplonk:z
177 manifest.add_entry(23, "Shplonk:Q", frs_per_G);
178 manifest.add_challenge(23, "Shplonk:z");
179
180 // Round 24: KZG:W -> KZG:masking_challenge
181 manifest.add_entry(24, "KZG:W", frs_per_G);
182 manifest.add_challenge(24, "KZG:masking_challenge");
183
184 return manifest;
185 }
186
187 // Helper function to add no-ops
188 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 1)
189 {
190 for (size_t i = 0; i < count; i++) {
191 op_queue->random_op_ultra_only();
192 }
193 }
194
195 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 100)
196 {
197 auto P1 = G1::random_element();
198 auto P2 = G1::random_element();
199 auto z = Fr::random_element();
200 for (size_t i = 0; i < count; i++) {
201 op_queue->add_accumulate(P1);
202 op_queue->mul_accumulate(P2, z);
203 }
204 op_queue->eq_and_reset();
205 }
206
207 // Construct a test circuit based on some random operations
208 static CircuitBuilder generate_test_circuit(const Fq& batching_challenge_v,
209 const Fq& evaluation_challenge_x,
210 const size_t circuit_size_parameter = 500)
211 {
212
213 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
214 auto op_queue = std::make_shared<bb::ECCOpQueue>();
215 op_queue->no_op_ultra_only();
217 add_mixed_ops(op_queue, circuit_size_parameter / 2);
218 op_queue->merge();
219 add_mixed_ops(op_queue, circuit_size_parameter / 2);
221 op_queue->merge(MergeSettings::APPEND, ECCOpQueue::OP_QUEUE_SIZE - op_queue->get_current_subtable_size());
222
223 return CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
224 }
225
226 static bool prove_and_verify(const CircuitBuilder& circuit_builder,
227 const Fq& evaluation_challenge_x,
228 const Fq& batching_challenge_v)
229 {
230 // Setup prover transcript
231 auto prover_transcript = std::make_shared<Transcript>();
232 prover_transcript->send_to_verifier("init", Fq::random_element());
233 auto initial_transcript = prover_transcript->export_proof();
234
235 // Setup verifier transcript
236 auto verifier_transcript = std::make_shared<Transcript>(initial_transcript);
237 verifier_transcript->template receive_from_prover<Fq>("init");
238
239 // Create proving key and prover
240 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
241 TranslatorProver prover{ proving_key, prover_transcript };
242
243 // Generate proof
244 auto proof = prover.construct_proof();
245
246 // Commit to op queue wires
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);
256
257 // Get accumulated_result from the prover
258 uint256_t accumulated_result = prover.get_accumulated_result();
259
260 // Create verifier
261 TranslatorVerifier verifier(verifier_transcript,
262 proof,
263 evaluation_challenge_x,
264 batching_challenge_v,
265 accumulated_result,
266 op_queue_commitments);
267
268 // Verify proof: get reduction result and check all components
269 auto result = verifier.reduce_to_pairing_check();
270 return result.pairing_points.check() && result.reduction_succeeded;
271 }
272};
273
281TEST_F(TranslatorTests, ProofLengthCheck)
282{
283 using Fq = fq;
284
285 Fq batching_challenge_v = Fq::random_element();
286 Fq evaluation_challenge_x = Fq::random_element();
287
288 // Generate a circuit and its verification key (computed at runtime from the proving key)
289 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
290
291 // Setup prover transcript
292 auto prover_transcript = std::make_shared<Transcript>();
293 prover_transcript->send_to_verifier("init", Fq::random_element());
294 prover_transcript->export_proof();
295 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
296 TranslatorProver prover{ proving_key, prover_transcript };
297
298 // Generate proof
299 auto proof = prover.construct_proof();
300
301 EXPECT_EQ(proof.size(), TranslatorFlavor::PROOF_LENGTH);
302}
303
309{
310 using Fq = fq;
311
312 Fq batching_challenge_v = Fq::random_element();
313 Fq evaluation_challenge_x = Fq::random_element();
314
315 // Generate a circuit without no-ops
316 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
317
318 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
319 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
320 EXPECT_TRUE(verified);
321}
322
329{
330 using Fq = fq;
331
332 Fq batching_challenge_v = Fq::random_element();
333 Fq evaluation_challenge_x = Fq::random_element();
334
335 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
336 auto op_queue = std::make_shared<bb::ECCOpQueue>();
337 op_queue->no_op_ultra_only();
338 add_random_ops(op_queue, CircuitBuilder::NUM_RANDOM_OPS_START);
339 add_mixed_ops(op_queue, 100);
340 op_queue->merge();
341 auto circuit_builder = CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue, /*avm_mode=*/true };
342
343 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
344 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
345 EXPECT_TRUE(verified);
346}
347
357{
358 using Fq = fq;
359
360 auto prover_transcript = std::make_shared<Transcript>();
361 prover_transcript->send_to_verifier("init", Fq::random_element());
362 prover_transcript->export_proof();
363 Fq batching_challenge_v = Fq::random_element();
364 Fq evaluation_challenge_x = Fq::random_element();
365
366 // Generate the default fixed VK
368
369 // Lambda for manually computing a verification key for a given circuit and comparing it to the fixed VK
370 auto compare_computed_vk_against_fixed = [&](size_t circuit_size_parameter) {
371 CircuitBuilder circuit_builder =
372 generate_test_circuit(batching_challenge_v, evaluation_challenge_x, circuit_size_parameter);
373 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
374 TranslatorProver prover{ proving_key, prover_transcript };
375 TranslatorFlavor::VerificationKey computed_vk = create_vk_from_proving_key(proving_key->proving_key);
376 auto labels = TranslatorFlavor::VerificationKey::get_labels();
377 size_t index = 0;
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];
381 ++index;
382 }
383
384 EXPECT_EQ(computed_vk, fixed_vk);
385 };
386
387 // Check consistency of the fixed VK with the computed VK for some different circuit sizes
388 const size_t circuit_size_parameter_1 = 1 << 2;
389 const size_t circuit_size_parameter_2 = 1 << 3;
390
391 compare_computed_vk_against_fixed(circuit_size_parameter_1);
392 compare_computed_vk_against_fixed(circuit_size_parameter_2);
393
394 // Verify that the hardcoded VK hash matches the computed hash
395 auto computed_hash = compute_translator_vk_hash();
396 auto hardcoded_hash = TranslatorHardcodedVKAndHash::vk_hash();
397 if (computed_hash != hardcoded_hash) {
398 info("VK hash mismatch! Update TranslatorHardcodedVKAndHash::vk_hash() with:");
399 info("0x", computed_hash);
400 }
401 EXPECT_EQ(computed_hash, hardcoded_hash) << "Hardcoded VK hash does not match computed hash";
402}
403
409TEST_F(TranslatorTests, TranscriptPinned)
410{
411 using Fq = fq;
412
413 Fq batching_challenge_v = Fq::random_element();
414 Fq evaluation_challenge_x = Fq::random_element();
415
416 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
417
418 // Create proving key and prover
419 auto prover_transcript = std::make_shared<Transcript>();
420 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
421 TranslatorProver prover{ proving_key, prover_transcript };
422
423 // Generate proof
424 auto proof = prover.construct_proof();
425
426 // Setup verifier transcript with manifest tracking
427 auto verifier_transcript = std::make_shared<Transcript>(proof);
428 verifier_transcript->enable_manifest();
429
430 // Get accumulated_result from the prover
431 uint256_t accumulated_result = prover.get_accumulated_result();
432
433 // Commit to op queue wires
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);
442
443 // Create verifier with all required inputs
444 TranslatorVerifier verifier(verifier_transcript,
445 proof,
446 evaluation_challenge_x,
447 batching_challenge_v,
448 accumulated_result,
449 op_queue_commitments);
450
451 // Run verification - just reduce to pairing check to exercise the transcript
452 [[maybe_unused]] auto result = verifier.reduce_to_pairing_check();
453
454 // Compare verifier manifest against hardcoded expected structure
455 auto expected_manifest = build_expected_translator_manifest();
456 auto verifier_manifest = verifier_transcript->get_manifest();
457
458 EXPECT_EQ(verifier_manifest, expected_manifest);
459}
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).
Definition flavor.hpp:136
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.
BaseTranscript< Codec, HashFunction > Transcript
static constexpr size_t PROOF_LENGTH
TranslatorCircuitBuilder CircuitBuilder
Curve::ScalarField FF
Curve::AffineElement Commitment
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:212
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:169
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()