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
72 {
73 TranscriptManifest manifest;
74 constexpr size_t frs_per_G = FrCodec::calc_num_fields<Flavor::Commitment>();
75 constexpr size_t NUM_SUMCHECK_ROUNDS = 17; // CONST_TRANSLATOR_LOG_N + 2
76
77 // Round 0: vk_hash, Gemini masking, wire commitments
78 manifest.add_entry(0, "vk_hash", 1);
79 manifest.add_entry(0, "Gemini:masking_poly_comm", frs_per_G);
80
81 // Wire commitments (82 total, in order from the manifest dump)
82 // clang-format off
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",
125 };
126 // clang-format on
127 for (const auto& label : wire_labels) {
128 manifest.add_entry(0, label, frs_per_G);
129 }
130 manifest.add_challenge(0, "beta");
131
132 // Round 1: gamma challenge (no entries)
133 manifest.add_challenge(1, "gamma");
134
135 // Round 2: Z_PERM -> Sumcheck:alpha
136 manifest.add_entry(2, "Z_PERM", frs_per_G);
137 manifest.add_challenge(2, "Sumcheck:alpha");
138
139 // Rounds 3-19: Gate challenges (17 rounds)
140 for (size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
141 manifest.add_challenge(3 + i, "Sumcheck:gate_challenge_" + std::to_string(i));
142 }
143
144 // Round 20: Libra concatenation commitment + Sum -> Libra:Challenge
145 manifest.add_entry(20, "Libra:concatenation_commitment", frs_per_G);
146 manifest.add_entry(20, "Libra:Sum", 1);
147 manifest.add_challenge(20, "Libra:Challenge");
148
149 // Rounds 21-37: Sumcheck univariates (17 rounds)
150 for (size_t i = 0; i < NUM_SUMCHECK_ROUNDS; ++i) {
151 manifest.add_entry(21 + i, "Sumcheck:univariate_" + std::to_string(i), 9);
152 manifest.add_challenge(21 + i, "Sumcheck:u_" + std::to_string(i));
153 }
154
155 // Round 38: Sumcheck evaluations + Libra commitments -> rho
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);
160 manifest.add_challenge(38, "rho");
161
162 // Round 39: Gemini fold commitments -> Gemini:r
163 for (size_t i = 1; i <= 16; ++i) {
164 manifest.add_entry(39, "Gemini:FOLD_" + std::to_string(i), frs_per_G);
165 }
166 manifest.add_challenge(39, "Gemini:r");
167
168 // Round 40: Gemini evaluations + Libra evals -> Shplonk:nu
169 for (size_t i = 1; i <= 17; ++i) {
170 manifest.add_entry(40, "Gemini:a_" + std::to_string(i), 1);
171 }
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);
178 manifest.add_challenge(40, "Shplonk:nu");
179
180 // Round 41: Shplonk:Q -> Shplonk:z
181 manifest.add_entry(41, "Shplonk:Q", frs_per_G);
182 manifest.add_challenge(41, "Shplonk:z");
183
184 // Round 42: KZG:W -> KZG:masking_challenge
185 manifest.add_entry(42, "KZG:W", frs_per_G);
186 manifest.add_challenge(42, "KZG:masking_challenge");
187
188 return manifest;
189 }
190
191 // Helper function to add no-ops
192 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 1)
193 {
194 for (size_t i = 0; i < count; i++) {
195 op_queue->random_op_ultra_only();
196 }
197 }
198
199 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 100)
200 {
201 auto P1 = G1::random_element();
202 auto P2 = G1::random_element();
203 auto z = Fr::random_element();
204 for (size_t i = 0; i < count; i++) {
205 op_queue->add_accumulate(P1);
206 op_queue->mul_accumulate(P2, z);
207 }
208 op_queue->eq_and_reset();
209 }
210
211 // Construct a test circuit based on some random operations
212 static CircuitBuilder generate_test_circuit(const Fq& batching_challenge_v,
213 const Fq& evaluation_challenge_x,
214 const size_t circuit_size_parameter = 500)
215 {
216
217 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
218 auto op_queue = std::make_shared<bb::ECCOpQueue>();
219 op_queue->no_op_ultra_only();
221 add_mixed_ops(op_queue, circuit_size_parameter / 2);
222 op_queue->merge();
223 add_mixed_ops(op_queue, circuit_size_parameter / 2);
225 op_queue->merge(MergeSettings::APPEND, ECCOpQueue::OP_QUEUE_SIZE - op_queue->get_current_subtable_size());
226
227 return CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
228 }
229
230 static bool prove_and_verify(const CircuitBuilder& circuit_builder,
231 const Fq& evaluation_challenge_x,
232 const Fq& batching_challenge_v)
233 {
234 // Setup prover transcript
235 auto prover_transcript = std::make_shared<Transcript>();
236 prover_transcript->send_to_verifier("init", Fq::random_element());
237 auto initial_transcript = prover_transcript->export_proof();
238
239 // Setup verifier transcript
240 auto verifier_transcript = std::make_shared<Transcript>(initial_transcript);
241 verifier_transcript->template receive_from_prover<Fq>("init");
242
243 // Create proving key and prover
244 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
245 TranslatorProver prover{ proving_key, prover_transcript };
246
247 // Generate proof
248 auto proof = prover.construct_proof();
249
250 // Commit to op queue wires
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);
260
261 // Get accumulated_result from the prover
262 uint256_t accumulated_result = prover.get_accumulated_result();
263
264 // Create verifier
265 TranslatorVerifier verifier(verifier_transcript,
266 proof,
267 evaluation_challenge_x,
268 batching_challenge_v,
269 accumulated_result,
270 op_queue_commitments);
271
272 // Verify proof: get reduction result and check all components
273 auto result = verifier.reduce_to_pairing_check();
274 return result.pairing_points.check() && result.reduction_succeeded;
275 }
276};
277
285TEST_F(TranslatorTests, ProofLengthCheck)
286{
287 using Fq = fq;
288
289 Fq batching_challenge_v = Fq::random_element();
290 Fq evaluation_challenge_x = Fq::random_element();
291
292 // Generate a circuit and its verification key (computed at runtime from the proving key)
293 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
294
295 // Setup prover transcript
296 auto prover_transcript = std::make_shared<Transcript>();
297 prover_transcript->send_to_verifier("init", Fq::random_element());
298 prover_transcript->export_proof();
299 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
300 TranslatorProver prover{ proving_key, prover_transcript };
301
302 // Generate proof
303 auto proof = prover.construct_proof();
304
306}
307
313{
314 using Fq = fq;
315
316 Fq batching_challenge_v = Fq::random_element();
317 Fq evaluation_challenge_x = Fq::random_element();
318
319 // Generate a circuit without no-ops
320 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
321
322 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
323 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
324 EXPECT_TRUE(verified);
325}
326
333{
334 using Fq = fq;
335
336 Fq batching_challenge_v = Fq::random_element();
337 Fq evaluation_challenge_x = Fq::random_element();
338
339 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
340 auto op_queue = std::make_shared<bb::ECCOpQueue>();
341 op_queue->no_op_ultra_only();
342 add_random_ops(op_queue, CircuitBuilder::NUM_RANDOM_OPS_START);
343 add_mixed_ops(op_queue, 100);
344 op_queue->merge();
345 auto circuit_builder = CircuitBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue, /*avm_mode=*/true };
346
347 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
348 bool verified = prove_and_verify(circuit_builder, evaluation_challenge_x, batching_challenge_v);
349 EXPECT_TRUE(verified);
350}
351
361{
362 using Fq = fq;
363
364 auto prover_transcript = std::make_shared<Transcript>();
365 prover_transcript->send_to_verifier("init", Fq::random_element());
366 prover_transcript->export_proof();
367 Fq batching_challenge_v = Fq::random_element();
368 Fq evaluation_challenge_x = Fq::random_element();
369
370 // Generate the default fixed VK
372
373 // Lambda for manually computing a verification key for a given circuit and comparing it to the fixed VK
374 auto compare_computed_vk_against_fixed = [&](size_t circuit_size_parameter) {
375 CircuitBuilder circuit_builder =
376 generate_test_circuit(batching_challenge_v, evaluation_challenge_x, circuit_size_parameter);
377 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
378 TranslatorProver prover{ proving_key, prover_transcript };
379 TranslatorFlavor::VerificationKey computed_vk = create_vk_from_proving_key(proving_key->proving_key);
380 auto labels = TranslatorFlavor::VerificationKey::get_labels();
381 size_t index = 0;
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];
385 ++index;
386 }
387
388 EXPECT_EQ(computed_vk, fixed_vk);
389 };
390
391 // Check consistency of the fixed VK with the computed VK for some different circuit sizes
392 const size_t circuit_size_parameter_1 = 1 << 2;
393 const size_t circuit_size_parameter_2 = 1 << 3;
394
395 compare_computed_vk_against_fixed(circuit_size_parameter_1);
396 compare_computed_vk_against_fixed(circuit_size_parameter_2);
397
398 // Verify that the hardcoded VK hash matches the computed hash
399 auto computed_hash = compute_translator_vk_hash();
400 auto hardcoded_hash = TranslatorHardcodedVKAndHash::vk_hash();
401 if (computed_hash != hardcoded_hash) {
402 info("VK hash mismatch! Update TranslatorHardcodedVKAndHash::vk_hash() with:");
403 info("0x", computed_hash);
404 }
405 EXPECT_EQ(computed_hash, hardcoded_hash) << "Hardcoded VK hash does not match computed hash";
406}
407
413TEST_F(TranslatorTests, TranscriptPinned)
414{
415 using Fq = fq;
416
417 Fq batching_challenge_v = Fq::random_element();
418 Fq evaluation_challenge_x = Fq::random_element();
419
420 CircuitBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
421
422 // Create proving key and prover
423 auto prover_transcript = std::make_shared<Transcript>();
424 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
425 TranslatorProver prover{ proving_key, prover_transcript };
426
427 // Generate proof
428 auto proof = prover.construct_proof();
429
430 // Setup verifier transcript with manifest tracking
431 auto verifier_transcript = std::make_shared<Transcript>(proof);
432 verifier_transcript->enable_manifest();
433
434 // Get accumulated_result from the prover
435 uint256_t accumulated_result = prover.get_accumulated_result();
436
437 // Commit to op queue wires
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);
446
447 // Create verifier with all required inputs
448 TranslatorVerifier verifier(verifier_transcript,
449 proof,
450 evaluation_challenge_x,
451 batching_challenge_v,
452 accumulated_result,
453 op_queue_commitments);
454
455 // Run verification - just reduce to pairing check to exercise the transcript
456 [[maybe_unused]] auto result = verifier.reduce_to_pairing_check();
457
458 // Compare verifier manifest against hardcoded expected structure
459 auto expected_manifest = build_expected_translator_manifest();
460 auto verifier_manifest = verifier_transcript->get_manifest();
461
462 EXPECT_EQ(verifier_manifest, expected_manifest);
463}
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
TranslatorCircuitBuilder CircuitBuilder
Curve::ScalarField FF
Curve::AffineElement Commitment
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS
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:190
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()