Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
test_class.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
8
14#include "gtest/gtest.h"
15#include <vector>
16
17namespace acir_format {
18
19using namespace bb;
20using namespace bb::stdlib;
21
33
37inline Acir::FunctionInput witness_to_function_input(uint32_t witness_index)
38{
39 return Acir::FunctionInput{ .value =
40 Acir::FunctionInput::Witness{ .value = Acir::Witness{ .value = witness_index } } };
41}
42
50{
52 .mul_terms = {},
53 .linear_combinations = {},
54 .q_c = bb::fr::zero().to_buffer(),
55 };
56
57 if (input.is_constant) {
58 expr.q_c = input.value.to_buffer();
59 } else {
60 // Linear term with coefficient 1
61 expr.linear_combinations.push_back(
62 std::make_tuple(bb::fr::one().to_buffer(), Acir::Witness{ .value = input.index }));
63 }
64
65 return expr;
66}
67
75{
76 bb::fr value = (access_type == AccessType::Write) ? bb::fr::one() : bb::fr::zero();
77 return Acir::Expression{
78 .mul_terms = {},
79 .linear_combinations = {},
80 .q_c = value.to_buffer(),
81 };
82}
83
88{
89 return Acir::MemOp{
93 };
94}
95
100{
101 switch (type) {
102 case BlockType::ROM:
103 case BlockType::RAM:
104 // ROM and RAM both map to Memory in ACIR
106 case BlockType::CallData: {
107 uint32_t id = (calldata_id == CallDataType::Primary) ? 0 : 1;
109 }
112 default:
113 throw_or_abort("Unknown BlockType");
114 }
115}
116
128inline std::vector<Acir::Opcode> block_constraint_to_acir_opcodes(const BlockConstraint& constraint,
129 uint32_t block_id = 0)
130{
131 std::vector<Acir::Opcode> opcodes;
132
133 // Create the MemoryInit opcode
134 std::vector<Acir::Witness> init_witnesses;
135 init_witnesses.reserve(constraint.init.size());
136 for (const auto& init_val : constraint.init) {
137 init_witnesses.push_back(Acir::Witness{ .value = init_val });
138 }
139
141 .block_id = Acir::BlockId{ .value = block_id },
142 .init = std::move(init_witnesses),
143 .block_type = block_type_to_acir_block_type(constraint.type, constraint.calldata_id),
144 };
145 opcodes.push_back(Acir::Opcode{ .value = mem_init });
146
147 // Create MemoryOp opcodes for each operation in the trace
148 for (const auto& mem_op : constraint.trace) {
149 Acir::Opcode::MemoryOp acir_mem_op{
150 .block_id = Acir::BlockId{ .value = block_id },
151 .op = mem_op_to_acir_mem_op(mem_op),
152 };
153 opcodes.push_back(Acir::Opcode{ .value = acir_mem_op });
154 }
155
156 return opcodes;
157}
158
164{
165 // Add multiplication term if both a and b are not constants
166 if (mul_quad.a != bb::stdlib::IS_CONSTANT && mul_quad.b != bb::stdlib::IS_CONSTANT &&
167 !mul_quad.mul_scaling.is_zero()) {
168 expr.mul_terms.push_back(std::make_tuple(mul_quad.mul_scaling.to_buffer(),
169 Acir::Witness{ .value = mul_quad.a },
170 Acir::Witness{ .value = mul_quad.b }));
171 }
172
173 // Add linear terms for each non-constant witness with non-zero scaling
174 if (mul_quad.a != bb::stdlib::IS_CONSTANT && !mul_quad.a_scaling.is_zero()) {
175 expr.linear_combinations.push_back(
176 std::make_tuple(mul_quad.a_scaling.to_buffer(), Acir::Witness{ .value = mul_quad.a }));
177 }
178 if (mul_quad.b != bb::stdlib::IS_CONSTANT && !mul_quad.b_scaling.is_zero()) {
179 expr.linear_combinations.push_back(
180 std::make_tuple(mul_quad.b_scaling.to_buffer(), Acir::Witness{ .value = mul_quad.b }));
181 }
182 if (mul_quad.c != bb::stdlib::IS_CONSTANT && !mul_quad.c_scaling.is_zero()) {
183 expr.linear_combinations.push_back(
184 std::make_tuple(mul_quad.c_scaling.to_buffer(), Acir::Witness{ .value = mul_quad.c }));
185 }
186 if (mul_quad.d != bb::stdlib::IS_CONSTANT && !mul_quad.d_scaling.is_zero()) {
187 expr.linear_combinations.push_back(
188 std::make_tuple(mul_quad.d_scaling.to_buffer(), Acir::Witness{ .value = mul_quad.d }));
189 }
190}
191
203template <typename ConstraintType> std::vector<Acir::Opcode> constraint_to_acir_opcode(const ConstraintType& constraint)
204{
206 // LogicConstraint maps to either AND or XOR BlackBoxFuncCall
207 if (constraint.is_xor_gate) {
208 return { Acir::Opcode{
212 .rhs = witness_or_constant_to_function_input(constraint.b),
213 .num_bits = constraint.num_bits,
214 .output = Acir::Witness{ .value = constraint.result },
215 } } } } };
216 }
217 return { Acir::Opcode{
221 .rhs = witness_or_constant_to_function_input(constraint.b),
222 .num_bits = constraint.num_bits,
223 .output = Acir::Witness{ .value = constraint.result },
224 } } } } };
226 return { Acir::Opcode{
229 .input = witness_to_function_input(constraint.witness),
230 .num_bits = constraint.num_bits,
231 } } } } };
233 std::vector<Acir::FunctionInput> inputs;
234 for (const auto& input : constraint.inputs) {
236 }
238 for (size_t i = 0; i < 16; ++i) {
239 (*iv)[i] = witness_or_constant_to_function_input(constraint.iv[i]);
240 }
242 for (size_t i = 0; i < 16; ++i) {
243 (*key)[i] = witness_or_constant_to_function_input(constraint.key[i]);
244 }
245 std::vector<Acir::Witness> outputs;
246 for (const auto& out : constraint.outputs) {
247 outputs.push_back(Acir::Witness{ .value = out });
248 }
252 .iv = iv,
253 .key = key,
254 .outputs = std::move(outputs),
255 } } } } };
258 for (size_t i = 0; i < 16; ++i) {
259 (*inputs)[i] = witness_or_constant_to_function_input(constraint.inputs[i]);
260 }
262 for (size_t i = 0; i < 8; ++i) {
263 (*hash_values)[i] = witness_or_constant_to_function_input(constraint.hash_values[i]);
264 }
266 for (size_t i = 0; i < 8; ++i) {
267 (*outputs)[i] = Acir::Witness{ .value = constraint.result[i] };
268 }
271 .inputs = inputs,
272 .hash_values = hash_values,
273 .outputs = outputs,
274 } } } } };
277 for (size_t i = 0; i < 32; ++i) {
278 (*hashed_message)[i] = witness_to_function_input(constraint.hashed_message[i]);
279 }
281 for (size_t i = 0; i < 64; ++i) {
282 (*signature)[i] = witness_to_function_input(constraint.signature[i]);
283 }
285 for (size_t i = 0; i < 32; ++i) {
286 (*public_key_x)[i] = witness_to_function_input(constraint.pub_x_indices[i]);
287 }
289 for (size_t i = 0; i < 32; ++i) {
290 (*public_key_y)[i] = witness_to_function_input(constraint.pub_y_indices[i]);
291 }
292 auto predicate = witness_or_constant_to_function_input(constraint.predicate);
293 if (constraint.type == bb::CurveType::SECP256K1) {
294 return { Acir::Opcode{
297 .public_key_x = public_key_x,
298 .public_key_y = public_key_y,
299 .signature = signature,
300 .hashed_message = hashed_message,
301 .predicate = predicate,
302 .output = Acir::Witness{ .value = constraint.result },
303 } } } } };
304 }
305 return { Acir::Opcode{
308 .public_key_x = public_key_x,
309 .public_key_y = public_key_y,
310 .signature = signature,
311 .hashed_message = hashed_message,
312 .predicate = predicate,
313 .output = Acir::Witness{ .value = constraint.result },
314 } } } } };
316 std::vector<Acir::FunctionInput> inputs;
317 for (const auto& input : constraint.inputs) {
318 inputs.push_back(witness_or_constant_to_function_input(input.blackbox_input));
319 }
321 for (size_t i = 0; i < 32; ++i) {
322 (*outputs)[i] = Acir::Witness{ .value = constraint.result[i] };
323 }
327 .outputs = outputs,
328 } } } } };
330 std::vector<Acir::FunctionInput> inputs;
331 for (const auto& input : constraint.inputs) {
332 inputs.push_back(witness_or_constant_to_function_input(input.blackbox_input));
333 }
335 for (size_t i = 0; i < 32; ++i) {
336 (*outputs)[i] = Acir::Witness{ .value = constraint.result[i] };
337 }
341 .outputs = outputs,
342 } } } } };
343 } else if constexpr (std::is_same_v<ConstraintType, Keccakf1600>) {
345 for (size_t i = 0; i < 25; ++i) {
346 (*inputs)[i] = witness_or_constant_to_function_input(constraint.state[i]);
347 }
349 for (size_t i = 0; i < 25; ++i) {
350 (*outputs)[i] = Acir::Witness{ .value = constraint.result[i] };
351 }
354 .inputs = inputs,
355 .outputs = outputs,
356 } } } } };
358 std::vector<Acir::FunctionInput> inputs;
359 for (const auto& input : constraint.state) {
361 }
362 std::vector<Acir::Witness> outputs;
363 for (const auto& out : constraint.result) {
364 outputs.push_back(Acir::Witness{ .value = out });
365 }
366 return { Acir::Opcode{
370 .outputs = std::move(outputs),
371 } } } } };
373 std::vector<Acir::FunctionInput> points;
374 for (const auto& pt : constraint.points) {
375 points.push_back(witness_or_constant_to_function_input(pt));
376 }
377 std::vector<Acir::FunctionInput> scalars;
378 for (const auto& sc : constraint.scalars) {
379 scalars.push_back(witness_or_constant_to_function_input(sc));
380 }
382 (*outputs)[0] = Acir::Witness{ .value = constraint.out_point_x };
383 (*outputs)[1] = Acir::Witness{ .value = constraint.out_point_y };
384 (*outputs)[2] = Acir::Witness{ .value = constraint.out_point_is_infinite };
388 .points = std::move(points),
389 .scalars = std::move(scalars),
390 .predicate = witness_or_constant_to_function_input(constraint.predicate),
391 .outputs = outputs,
392 } } } } };
393 } else if constexpr (std::is_same_v<ConstraintType, EcAdd>) {
395 (*input1)[0] = witness_or_constant_to_function_input(constraint.input1_x);
396 (*input1)[1] = witness_or_constant_to_function_input(constraint.input1_y);
397 (*input1)[2] = witness_or_constant_to_function_input(constraint.input1_infinite);
399 (*input2)[0] = witness_or_constant_to_function_input(constraint.input2_x);
400 (*input2)[1] = witness_or_constant_to_function_input(constraint.input2_y);
401 (*input2)[2] = witness_or_constant_to_function_input(constraint.input2_infinite);
403 (*outputs)[0] = Acir::Witness{ .value = constraint.result_x };
404 (*outputs)[1] = Acir::Witness{ .value = constraint.result_y };
405 (*outputs)[2] = Acir::Witness{ .value = constraint.result_infinite };
409 .input1 = input1,
410 .input2 = input2,
411 .predicate = witness_or_constant_to_function_input(constraint.predicate),
412 .outputs = outputs,
413 } } } } };
415 std::vector<Acir::FunctionInput> verification_key;
416 for (const auto& key_idx : constraint.key) {
417 verification_key.push_back(witness_to_function_input(key_idx));
418 }
419 std::vector<Acir::FunctionInput> proof;
420 for (const auto& proof_idx : constraint.proof) {
421 proof.push_back(witness_to_function_input(proof_idx));
422 }
423 std::vector<Acir::FunctionInput> public_inputs;
424 for (const auto& pub_input_idx : constraint.public_inputs) {
425 public_inputs.push_back(witness_to_function_input(pub_input_idx));
426 }
430 .verification_key = std::move(verification_key),
431 .proof = std::move(proof),
432 .public_inputs = std::move(public_inputs),
433 .key_hash = witness_to_function_input(constraint.key_hash),
434 .proof_type = constraint.proof_type,
435 .predicate = witness_or_constant_to_function_input(constraint.predicate),
436 } } } } };
438 return block_constraint_to_acir_opcodes(constraint);
440 // Convert a single mul_quad_ to an AssertZero opcode
441 Acir::Expression expr{
442 .mul_terms = {},
443 .linear_combinations = {},
444 .q_c = constraint.const_scaling.to_buffer(),
445 };
446
447 add_terms_to_expression(expr, constraint);
448
449 return { Acir::Opcode{ .value = Acir::Opcode::AssertZero{ .value = expr } } };
451 // Convert a vector of mul_quad_ (big_quad_constraints) to an AssertZero opcode
452 Acir::Expression expr{
453 .mul_terms = {},
454 .linear_combinations = {},
455 .q_c = constraint[0].const_scaling.to_buffer(),
456 };
457
458 for (const auto& mul_quad : constraint) {
459 add_terms_to_expression(expr, mul_quad);
460 }
461
462 return { Acir::Opcode{ .value = Acir::Opcode::AssertZero{ .value = expr } } };
463 } else {
464 throw_or_abort("Unsupported constraint type");
465 }
466}
467
477inline Acir::Circuit build_acir_circuit(const std::vector<Acir::Opcode>& opcodes, uint32_t max_witness_index)
478{
479 return Acir::Circuit{
480 .function_name = "test_circuit",
481 .current_witness_index = max_witness_index,
482 .opcodes = opcodes,
483 .private_parameters = {},
484 .public_parameters = Acir::PublicInputs{ .value = {} },
485 .return_values = Acir::PublicInputs{ .value = {} },
486 .assert_messages = {},
487 };
488}
489
502template <typename ConstraintType>
503AcirFormat constraint_to_acir_format(const ConstraintType& constraint, uint32_t varnum)
504{
505 std::vector<Acir::Opcode> opcodes = constraint_to_acir_opcode(constraint);
506 Acir::Circuit circuit = build_acir_circuit(opcodes, varnum);
507 return circuit_serde_to_acir_format(circuit);
508}
509
521template <typename T>
522concept TestBase = requires {
523 // Required type aliases
524 typename T::Builder;
525 typename T::AcirConstraint;
526 typename T::InvalidWitness;
527 typename T::InvalidWitness::Target;
528
529 // Ensure InvalidWitness::Target is enum
531
532 // Ensure that InvalidWitness::Target has a None value
533 { T::InvalidWitness::Target::None };
534
535 // InvalidWitness must provide static methods for test iteration
536 { T::InvalidWitness::get_all() } -> std::same_as<std::vector<typename T::InvalidWitness::Target>>;
537 { T::InvalidWitness::get_labels() } -> std::same_as<std::vector<std::string>>;
538
539 // Required constraint manipulation methods (can be static or non-static)
540 requires requires(T& instance,
541 typename T::AcirConstraint& constraint,
542 WitnessVector& witness_values,
543 const typename T::InvalidWitness::Target& invalid_witness_target) {
548 { instance.generate_constraints(constraint, witness_values) } -> std::same_as<void>;
549
554 { instance.invalidate_witness(constraint, witness_values, invalid_witness_target) } -> std::same_as<void>;
555 };
556};
557
558template <TestBase Base> class TestClass {
559 public:
560 using Builder = Base::Builder;
561 using AcirConstraint = Base::AcirConstraint;
562 using InvalidWitness = Base::InvalidWitness;
563 using InvalidWitnessTarget = Base::InvalidWitness::Target;
564
569 const InvalidWitnessTarget& invalid_witness_target = InvalidWitnessTarget::None)
570 {
571 AcirConstraint constraint;
572 WitnessVector witness_values;
573
574 // Create an instance to allow for non-static methods
575 Base base_instance;
576 base_instance.generate_constraints(constraint, witness_values);
577 base_instance.invalidate_witness(constraint, witness_values, invalid_witness_target);
578
579 return { constraint, witness_values };
580 }
581
597 {
598 auto [constraint, witness_values] = generate_constraints(invalid_witness_target);
599
600 // Use the full ACIR flow: constraint -> Acir::Opcode -> Acir::Circuit -> circuit_serde_to_acir_format
601 AcirFormat constraint_system = constraint_to_acir_format(
602 constraint, /*max_witness_index=*/static_cast<uint32_t>(witness_values.size()) - 1);
603
604 AcirProgram program{ constraint_system, witness_values };
605 auto builder = create_circuit<Builder>(program);
606
607 return { CircuitChecker::check(builder), builder.failed(), builder.err() };
608 }
609
618 template <typename Flavor> static size_t test_vk_independence()
619 {
622
623 size_t num_gates = 0;
624
625 // Generate the constraint system
626 auto [constraint, witness_values] = generate_constraints();
627
628 // Use the full ACIR flow: constraint -> Acir::Opcode -> Acir::Circuit -> circuit_serde_to_acir_format
629 AcirFormat constraint_system = constraint_to_acir_format(
630 constraint, /*max_witness_index=*/static_cast<uint32_t>(witness_values.size()) - 1);
631
632 // Construct the vks
633 std::shared_ptr<VerificationKey> vk_from_witness;
634 {
635 AcirProgram program{ constraint_system, witness_values };
636 auto builder = create_circuit<Builder>(program);
637 num_gates = builder.get_num_finalized_gates_inefficient();
638
639 auto prover_instance = std::make_shared<ProverInstance>(builder);
640 vk_from_witness = std::make_shared<VerificationKey>(prover_instance->get_precomputed());
641
642 // Validate the builder
643 EXPECT_TRUE(CircuitChecker::check(builder));
644 }
645
646 std::shared_ptr<VerificationKey> vk_from_constraint;
647 {
648 AcirProgram program{ constraint_system, /*witness=*/{} };
649 auto builder = create_circuit<Builder>(program);
650 auto prover_instance = std::make_shared<ProverInstance>(builder);
651 vk_from_constraint = std::make_shared<VerificationKey>(prover_instance->get_precomputed());
652 }
653
654 EXPECT_EQ(*vk_from_witness, *vk_from_constraint) << "Mismatch in the vks";
655
656 return num_gates;
657 }
658
664 static std::vector<std::string> test_tampering()
665 {
666 std::vector<std::string> error_msgs;
667 for (auto [target, label] : zip_view(InvalidWitness::get_all(), InvalidWitness::get_labels())) {
668 auto [circuit_checker_result, builder_failed, builder_err] = test_constraints(target);
669 error_msgs.emplace_back(builder_err);
670
671 if (target != InvalidWitness::Target::None) {
672 bool circuit_check_failed = !circuit_checker_result;
673 bool assert_eq_error_present = (builder_err.find("assert_eq") != std::string::npos);
674 EXPECT_TRUE(circuit_check_failed || assert_eq_error_present)
675 << "Circuit checker succeeded unexpectedly and no assert_eq failure for invalid witness target " +
676 label;
677 EXPECT_TRUE(builder_failed) << "Builder succeeded for invalid witness target " + label;
678 } else {
679 EXPECT_TRUE(circuit_checker_result)
680 << "Circuit checker failed unexpectedly for invalid witness target " + label;
681 EXPECT_FALSE(builder_failed) << "Builder failed unexpectedly for invalid witness target " + label;
682 }
683 }
684
685 return error_msgs;
686 }
687};
688
689} // namespace acir_format
std::shared_ptr< Napi::ThreadSafeFunction > instance
static std::vector< std::string > test_tampering()
Test all invalid witness targets.
static size_t test_vk_independence()
Test vk generation is independent of the witness values supplied.
static std::pair< AcirConstraint, WitnessVector > generate_constraints(const InvalidWitnessTarget &invalid_witness_target=InvalidWitnessTarget::None)
Generate constraints and witness values based on the invalidation target.
static std::tuple< bool, bool, std::string > test_constraints(const InvalidWitnessTarget &invalid_witness_target)
General purpose testing function. It generates the test based on the predicate and invalidation targe...
Base::AcirConstraint AcirConstraint
Base::InvalidWitness InvalidWitness
Base::InvalidWitness::Target InvalidWitnessTarget
The verification key is responsible for storing the commitments to the precomputed (non-witnessk) pol...
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
Concept defining the requirements for the Base template parameter of TestClass.
AluTraceBuilder builder
Definition alu.test.cpp:124
AvmProvingInputs inputs
UltraKeccakFlavor::VerificationKey VerificationKey
AcirFormat circuit_serde_to_acir_format(Acir::Circuit const &circuit)
Convert an Acir::Circuit into an AcirFormat by processing all the opcodes.
Acir::BlockType block_type_to_acir_block_type(BlockType type, CallDataType calldata_id)
Convert an acir_format::BlockType to an Acir::BlockType.
std::vector< Acir::Opcode > block_constraint_to_acir_opcodes(const BlockConstraint &constraint, uint32_t block_id=0)
Convert a BlockConstraint to a vector of Acir::Opcodes.
AcirFormat constraint_to_acir_format(const ConstraintType &constraint, uint32_t varnum)
Convert an AcirConstraint to AcirFormat by going through the full ACIR serde flow.
std::vector< bb::fr > WitnessVector
Acir::Expression access_type_to_expression(AccessType access_type)
Convert an AccessType to an Acir::Expression representing the operation type.
std::vector< Acir::Opcode > constraint_to_acir_opcode(const ConstraintType &constraint)
Convert a constraint to a vector of Acir::Opcodes.
Acir::Circuit build_acir_circuit(const std::vector< Acir::Opcode > &opcodes, uint32_t max_witness_index)
Build an Acir::Circuit from opcodes and witness count.
Acir::FunctionInput witness_or_constant_to_function_input(const WitnessOrConstant< bb::fr > &input)
Convert a WitnessOrConstant back to an Acir::FunctionInput.
Acir::FunctionInput witness_to_function_input(uint32_t witness_index)
Convert a witness index to an Acir::FunctionInput (witness variant).
Acir::MemOp mem_op_to_acir_mem_op(const MemOp &mem_op)
Convert an acir_format::MemOp to an Acir::MemOp.
void add_terms_to_expression(Acir::Expression &expr, const mul_quad_< bb::fr > &mul_quad)
Add terms for a mul_quad_ gate to an Acir::Expression.
Acir::Expression witness_or_constant_to_expression(const WitnessOrConstant< bb::fr > &input)
Convert a WitnessOrConstant to an Acir::Expression.
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
@ SECP256K1
Definition types.hpp:10
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::vector< uint8_t > to_buffer(T const &value)
std::vector< Acir::FunctionInput > inputs
Definition acir.hpp:3055
Acir::FunctionInput lhs
Definition acir.hpp:3095
std::vector< Acir::FunctionInput > inputs
Definition acir.hpp:3207
std::vector< Acir::FunctionInput > inputs
Definition acir.hpp:3239
std::shared_ptr< std::array< Acir::FunctionInput, 32 > > public_key_x
Definition acir.hpp:3271
std::shared_ptr< std::array< Acir::FunctionInput, 32 > > public_key_x
Definition acir.hpp:3319
std::shared_ptr< std::array< Acir::FunctionInput, 3 > > input1
Definition acir.hpp:3407
std::shared_ptr< std::array< Acir::FunctionInput, 25 > > inputs
Definition acir.hpp:3447
std::vector< Acir::FunctionInput > points
Definition acir.hpp:3367
std::vector< Acir::FunctionInput > inputs
Definition acir.hpp:3527
Acir::FunctionInput input
Definition acir.hpp:3175
std::vector< Acir::FunctionInput > verification_key
Definition acir.hpp:3479
std::shared_ptr< std::array< Acir::FunctionInput, 16 > > inputs
Definition acir.hpp:3559
Acir::FunctionInput lhs
Definition acir.hpp:3135
std::variant< AES128Encrypt, AND, XOR, RANGE, Blake2s, Blake3, EcdsaSecp256k1, EcdsaSecp256r1, MultiScalarMul, EmbeddedCurveAdd, Keccakf1600, RecursiveAggregation, Poseidon2Permutation, Sha256Compression > value
Definition acir.hpp:3608
uint32_t value
Definition acir.hpp:3861
std::variant< Memory, CallData, ReturnData > value
Definition acir.hpp:3920
std::string function_name
Definition acir.hpp:5009
std::vector< std::tuple< std::vector< uint8_t >, Acir::Witness > > linear_combinations
Definition acir.hpp:4006
std::vector< std::tuple< std::vector< uint8_t >, Acir::Witness, Acir::Witness > > mul_terms
Definition acir.hpp:4005
std::vector< uint8_t > value
Definition acir.hpp:2929
std::variant< Constant, Witness > value
Definition acir.hpp:2968
Acir::Expression operation
Definition acir.hpp:4327
Acir::Expression value
Definition acir.hpp:4365
Acir::BlackBoxFuncCall value
Definition acir.hpp:4385
Acir::BlockId block_id
Definition acir.hpp:4437
Acir::BlockId block_id
Definition acir.hpp:4405
std::variant< AssertZero, BlackBoxFuncCall, MemoryOp, MemoryInit, BrilligCall, Call > value
Definition acir.hpp:4552
std::vector< Acir::Witness > value
Definition acir.hpp:4989
uint32_t value
Definition acir.hpp:2907
Struct holding the data required to add memory constraints to a circuit.
std::vector< uint32_t > init
Memory operation. Index and value store the index of the memory location, and value is the value to b...
WitnessOrConstant< bb::fr > index
WitnessOrConstant< bb::fr > value
static constexpr field one()
BB_INLINE constexpr bool is_zero() const noexcept
BB_INLINE std::vector< uint8_t > to_buffer() const
static constexpr field zero()
void throw_or_abort(std::string const &err)