33 using Ts::operator()...;
38 BB_ASSERT_EQ(
buffer.size(), 32U,
"acir_format::from_buffer_with_bound_checks: buffer size must be 32 bytes.");
46 .
index = e.value.value,
53 .
index = bb::stdlib::IS_CONSTANT,
65 "acir_format::get_witness_from_function_input: input must be a Witness variant. An error here means "
66 "there was a serialization error.");
73 if (witness_idx != stdlib::IS_CONSTANT) {
81 for (
const auto& mul_term : expr.
mul_terms) {
100 auto update_max_witness_index_from_witness = [&](
const Acir::Witness& witness) {
109 update_max_witness_index_from_function_input(bb_arg.lhs);
110 update_max_witness_index_from_function_input(bb_arg.rhs);
111 update_max_witness_index_from_witness(bb_arg.output);
114 update_max_witness_index_from_function_input(bb_arg.lhs);
115 update_max_witness_index_from_function_input(bb_arg.rhs);
116 update_max_witness_index_from_witness(bb_arg.output);
119 update_max_witness_index_from_function_input(bb_arg.input);
122 for (
const auto& input : bb_arg.inputs) {
123 update_max_witness_index_from_function_input(input);
125 for (
const auto& input : *bb_arg.iv) {
126 update_max_witness_index_from_function_input(input);
128 for (
const auto& input : *bb_arg.key) {
129 update_max_witness_index_from_function_input(input);
131 for (
const auto& output : bb_arg.outputs) {
132 update_max_witness_index_from_witness(output);
136 for (
const auto& input : *bb_arg.inputs) {
137 update_max_witness_index_from_function_input(input);
139 for (
const auto& input : *bb_arg.hash_values) {
140 update_max_witness_index_from_function_input(input);
142 for (
const auto& output : *bb_arg.outputs) {
143 update_max_witness_index_from_witness(output);
147 for (
const auto& input : bb_arg.inputs) {
148 update_max_witness_index_from_function_input(input);
150 for (
const auto& output : *bb_arg.outputs) {
151 update_max_witness_index_from_witness(output);
155 for (
const auto& input : bb_arg.inputs) {
156 update_max_witness_index_from_function_input(input);
158 for (
const auto& output : *bb_arg.outputs) {
159 update_max_witness_index_from_witness(output);
163 for (
const auto& input : *bb_arg.public_key_x) {
164 update_max_witness_index_from_function_input(input);
166 for (
const auto& input : *bb_arg.public_key_y) {
167 update_max_witness_index_from_function_input(input);
169 for (
const auto& input : *bb_arg.signature) {
170 update_max_witness_index_from_function_input(input);
172 for (
const auto& input : *bb_arg.hashed_message) {
173 update_max_witness_index_from_function_input(input);
175 update_max_witness_index_from_function_input(bb_arg.predicate);
176 update_max_witness_index_from_witness(bb_arg.output);
179 for (
const auto& input : *bb_arg.public_key_x) {
180 update_max_witness_index_from_function_input(input);
182 for (
const auto& input : *bb_arg.public_key_y) {
183 update_max_witness_index_from_function_input(input);
185 for (
const auto& input : *bb_arg.signature) {
186 update_max_witness_index_from_function_input(input);
188 for (
const auto& input : *bb_arg.hashed_message) {
189 update_max_witness_index_from_function_input(input);
191 update_max_witness_index_from_function_input(bb_arg.predicate);
192 update_max_witness_index_from_witness(bb_arg.output);
195 for (
const auto& input : bb_arg.points) {
196 update_max_witness_index_from_function_input(input);
198 for (
const auto& input : bb_arg.scalars) {
199 update_max_witness_index_from_function_input(input);
201 update_max_witness_index_from_function_input(bb_arg.predicate);
202 for (
const auto& output : *bb_arg.outputs) {
203 update_max_witness_index_from_witness(output);
207 for (
const auto& input : *bb_arg.input1) {
208 update_max_witness_index_from_function_input(input);
210 for (
const auto& input : *bb_arg.input2) {
211 update_max_witness_index_from_function_input(input);
213 update_max_witness_index_from_function_input(bb_arg.predicate);
214 for (
const auto& output : *bb_arg.outputs) {
215 update_max_witness_index_from_witness(output);
219 for (
const auto& input : *bb_arg.inputs) {
220 update_max_witness_index_from_function_input(input);
222 for (
const auto& output : *bb_arg.outputs) {
223 update_max_witness_index_from_witness(output);
227 for (
const auto& input : bb_arg.verification_key) {
228 update_max_witness_index_from_function_input(input);
230 for (
const auto& input : bb_arg.proof) {
231 update_max_witness_index_from_function_input(input);
233 for (
const auto& input : bb_arg.public_inputs) {
234 update_max_witness_index_from_function_input(input);
236 update_max_witness_index_from_function_input(bb_arg.key_hash);
237 update_max_witness_index_from_function_input(bb_arg.predicate);
240 for (
const auto& input : bb_arg.inputs) {
241 update_max_witness_index_from_function_input(input);
243 for (
const auto& output : bb_arg.outputs) {
244 update_max_witness_index_from_witness(output);
250 for (
const auto&
init : arg.init) {
251 update_max_witness_index_from_witness(
init);
260 for (
const auto& input : arg.inputs) {
266 for (
const auto& expr : e.value) {
276 for (
const auto& output : arg.outputs) {
279 update_max_witness_index_from_witness(e.value);
282 for (
const auto& witness : e.value) {
283 update_max_witness_index_from_witness(witness);
292 bb::assert_failure(
"acir_format::update_max_witness_index_from_opcode: Call opcode is not supported.");
303 BB_ASSERT(!
buf.empty(),
"deserialize_msgpack_compact: buffer is empty");
306 const uint8_t FORMAT_MSGPACK = 2;
307 const uint8_t FORMAT_MSGPACK_COMPACT = 3;
308 uint8_t format_u8 =
buf[0];
309 BB_ASSERT(format_u8 == FORMAT_MSGPACK || format_u8 == FORMAT_MSGPACK_COMPACT,
310 "deserialize_msgpack_compact: expected msgpack format marker (2 or 3), got " +
std::to_string(format_u8));
313 const char*
buffer = &
reinterpret_cast<const char*
>(
buf.data())[1];
314 size_t size =
buf.size() - 1;
316 auto oh = msgpack::unpack(
buffer, size);
320 BB_ASSERT(o.type == msgpack::type::ARRAY,
321 "deserialize_msgpack_compact: expected ARRAY type, got " +
std::to_string(o.type));
323 return decode_msgpack(o);
329 circuit.
opcodes.size(), UINT32_MAX,
"acir_format::circuit_serde_to_acir_format: too many opcodes in circuit.");
336 update_max_witness_index(e.value, af);
341 update_max_witness_index(e.value, af);
351 for (
size_t i = 0; i < circuit.
opcodes.size(); ++i) {
352 const auto& gate = circuit.
opcodes[i];
360 uint32_t block_id = arg.block_id.value;
361 block_id_to_block_constraint[block_id] = { block, { i } };
364 auto block = block_id_to_block_constraint.find(arg.block_id.value);
365 if (block == block_id_to_block_constraint.end()) {
366 bb::assert_failure(
"acir_format::circuit_serde_to_acir_format: unitialized MemoryOp.");
369 block->second.second.push_back(i);
373 bb::assert_failure(
"acir_format::circuit_serde_to_acir_format: Call opcode is not supported.");
379 for (
const auto& [_, block] : block_id_to_block_constraint) {
390 auto program = deserialize_msgpack_compact<Acir::ProgramWithoutBrillig>(
396 o.convert(program_wob);
397 }
catch (
const msgpack::type_error&) {
400 "acir_format::circuit_buf_to_acir_format: failed to convert msgpack data to Program");
404 BB_ASSERT_EQ(program.functions.size(), 1U,
"circuit_buf_to_acir_format: expected single function in ACIR program");
412 auto witness_stack = deserialize_msgpack_compact<Witnesses::WitnessStack>(
std::move(
buf), [](
auto o) {
415 o.convert(witness_stack);
416 }
catch (
const msgpack::type_error&) {
419 "acir_format::witness_buf_to_witness_vector: failed to convert msgpack data to WitnessStack");
421 return witness_stack;
425 "acir_format::witness_buf_to_witness_vector: expected single WitnessMap in WitnessStack");
436 for (
size_t index = 0;
const auto& e : witness_map.
value) {
442 while (
index < e.first.value) {
450 return witness_vector;
461 idx, bb::stdlib::IS_CONSTANT,
"Attempting to override a non-constant witness index in mul_quad_ gate");
462 idx = linear_terms.begin()->first;
463 scaling += linear_terms.begin()->second;
464 linear_terms.erase(idx);
472 SIZE_MAX - linear_terms.size(),
473 "split_into_mul_quad_gates: overflow when reserving space for mul_quad_ gates.");
474 result.reserve(arg.
mul_terms.size() + linear_terms.size());
477 for (
const auto& mul_term : arg.
mul_terms) {
481 .c = bb::stdlib::IS_CONSTANT,
482 .d = bb::stdlib::IS_CONSTANT,
492 auto& mul_quad = result.back();
493 if (linear_terms.contains(mul_quad.a)) {
494 mul_quad.a_scaling += linear_terms.at(mul_quad.a);
495 linear_terms.erase(mul_quad.a);
497 if (linear_terms.contains(mul_quad.b)) {
499 mul_quad.b_scaling += linear_terms.at(mul_quad.b);
500 linear_terms.erase(mul_quad.b);
505 bool is_first_gate =
true;
506 for (
auto& mul_quad : result) {
507 if (!linear_terms.empty()) {
508 add_linear_term_and_erase(mul_quad.c, mul_quad.c_scaling, linear_terms);
514 if (!linear_terms.empty()) {
515 add_linear_term_and_erase(mul_quad.d, mul_quad.d_scaling, linear_terms);
517 is_first_gate =
false;
522 while (!linear_terms.empty()) {
525 .
a = bb::stdlib::IS_CONSTANT,
526 .b = bb::stdlib::IS_CONSTANT,
527 .c = bb::stdlib::IS_CONSTANT,
528 .d = bb::stdlib::IS_CONSTANT,
536 if (!linear_terms.empty()) {
537 add_linear_term_and_erase(mul_quad.
a, mul_quad.
a_scaling, linear_terms);
539 if (!linear_terms.empty()) {
540 add_linear_term_and_erase(mul_quad.
b, mul_quad.
b_scaling, linear_terms);
542 if (!linear_terms.empty()) {
543 add_linear_term_and_erase(mul_quad.
c, mul_quad.
c_scaling, linear_terms);
548 if (!linear_terms.empty()) {
549 add_linear_term_and_erase(mul_quad.
d, mul_quad.
d_scaling, linear_terms);
551 is_first_gate =
false;
554 result.emplace_back(mul_quad);
558 "split_into_mul_quad_gates: resulted in zero gates. This means that there is an expression with no "
559 "multiplication terms and no linear terms.");
560 result.shrink_to_fit();
569 return ((gate.mul_scaling ==
fr(0)) && (gate.a_scaling ==
fr(0)) && (gate.b_scaling ==
fr(0)) &&
570 (gate.c_scaling ==
fr(0)) && (gate.d_scaling ==
fr(0)) && (gate.const_scaling ==
fr(0)));
577 if (is_single_gate) {
578 BB_ASSERT_EQ(mul_quads.size(), 1U,
"acir_format::assert_zero_to_quad_constraints: expected a single gate.");
579 auto mul_quad = mul_quads[0];
586 "acir_format::assert_zero_to_quad_constraints: expected multiple gates but found one.");
591 for (
auto const& mul_quad : mul_quads) {
593 "acir_format::assert_zero_to_quad_constraints: produced an arithmetic zero gate.");
602 auto to_witness = [](
const Acir::Witness& e) {
return e.value; };
610 .result = to_witness(arg.output),
611 .num_bits = arg.num_bits,
612 .is_xor_gate =
false,
620 .result = to_witness(arg.output),
621 .num_bits = arg.num_bits,
629 .num_bits = arg.num_bits,
645 .hash_values =
transform::map(*arg.hash_values, to_witness_or_constant),
667 .hashed_message =
transform::map(*arg.hashed_message, to_witness_from_input),
668 .signature =
transform::map(*arg.signature, to_witness_from_input),
669 .pub_x_indices =
transform::map(*arg.public_key_x, to_witness_from_input),
670 .pub_y_indices =
transform::map(*arg.public_key_y, to_witness_from_input),
672 .result = to_witness(arg.output),
679 .hashed_message =
transform::map(*arg.hashed_message, to_witness_from_input),
680 .signature =
transform::map(*arg.signature, to_witness_from_input),
681 .pub_x_indices =
transform::map(*arg.public_key_x, to_witness_from_input),
682 .pub_y_indices =
transform::map(*arg.public_key_y, to_witness_from_input),
684 .result = to_witness(arg.output),
693 .out_point_x = to_witness((*arg.outputs)[0]),
694 .out_point_y = to_witness((*arg.outputs)[1]),
695 .out_point_is_infinite = to_witness((*arg.outputs)[2]),
708 .result_x = to_witness((*arg.outputs)[0]),
709 .result_y = to_witness((*arg.outputs)[1]),
710 .result_infinite = to_witness((*arg.outputs)[2]),
723 if (predicate.is_constant && predicate.value.is_zero()) {
730 .public_inputs =
transform::map(arg.public_inputs, to_witness_from_input),
732 .proof_type = arg.proof_type,
733 .predicate = predicate,
737 switch (c.proof_type) {
762 "acir_format::handle_black_box_fun_call: Invalid PROOF_TYPE in RecursionConstraint.");
786 for (
const auto&
init : mem_init.
init) {
787 block.init.push_back(
init.value);
794 BB_ASSERT(calldata_id == 0 || calldata_id == 1,
"acir_format::handle_memory_init: Unsupported calldata id");
808 auto acir_expression_to_witness_or_constant = [](
const Acir::Expression& expr) {
811 BB_ASSERT(expr.mul_terms.empty(),
"MemoryOp should not have multiplication terms");
812 BB_ASSERT_LTE(expr.linear_combinations.size(), 1U,
"MemoryOp should have at most one linear term");
814 const fr a_scaling = expr.linear_combinations.size() == 1
819 bool is_witness = a_scaling ==
fr::one() && constant_term ==
fr::zero();
820 bool is_constant = a_scaling ==
fr::zero();
821 BB_ASSERT(is_witness || is_constant,
"MemoryOp expression must be a witness or a constant");
824 .
index = is_witness ?
std::get<1>(expr.linear_combinations[0]).value : bb::stdlib::IS_CONSTANT,
825 .value = is_constant ? constant_term :
fr::zero(),
826 .is_constant = is_constant,
832 BB_ASSERT(expr.mul_terms.empty(),
"MemoryOp expression should not have multiplication terms");
833 BB_ASSERT(expr.linear_combinations.empty(),
"MemoryOp expression should not have linear terms");
838 "MemoryOp expression should be either zero or one");
857 block.
trace.push_back(acir_mem_op);
862 static constexpr size_t NUM_WIRES = 4;
865 if (linear_terms.size() > NUM_WIRES) {
888 size_t num_witnesses_to_be_put_in_wires = 2 + linear_terms.size();
893 bool lhs_is_distinct_from_linear_terms = !linear_terms.contains(witness_idx_lhs);
894 bool rhs_is_distinct_from_linear_terms = !linear_terms.contains(witness_idx_rhs);
896 if (witness_idx_lhs != witness_idx_rhs) {
897 num_witnesses_to_be_put_in_wires -= lhs_is_distinct_from_linear_terms ? 0U : 1U;
898 num_witnesses_to_be_put_in_wires -= rhs_is_distinct_from_linear_terms ? 0U : 1U;
900 num_witnesses_to_be_put_in_wires -= lhs_is_distinct_from_linear_terms ? 0U : 1U;
903 return num_witnesses_to_be_put_in_wires <= NUM_WIRES;
906 return linear_terms.size() <= NUM_WIRES;
914 uint32_t witness_idx =
std::get<1>(linear_term).value;
915 if (linear_terms.contains(witness_idx)) {
916 linear_terms[witness_idx] += selector_value;
918 linear_terms[witness_idx] = selector_value;
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GT(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define BB_ASSERT_LTE(left, right,...)
#define BB_ASSERT_LT(left, right,...)
std::unique_ptr< uint8_t[]> buffer
Entry point for Barretenberg command-line interface.
field< Bn254FrParams > fr
void assert_failure(std::string const &err)
C join(std::initializer_list< C > to_join)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
std::variant< AES128Encrypt, AND, XOR, RANGE, Blake2s, Blake3, EcdsaSecp256k1, EcdsaSecp256r1, MultiScalarMul, EmbeddedCurveAdd, Keccakf1600, RecursiveAggregation, Poseidon2Permutation, Sha256Compression > value
std::variant< Memory, CallData, ReturnData > value
Acir::PublicInputs return_values
std::vector< Acir::Opcode > opcodes
Acir::PublicInputs public_parameters
std::vector< std::tuple< std::vector< uint8_t >, Acir::Witness > > linear_combinations
std::vector< uint8_t > q_c
std::vector< std::tuple< std::vector< uint8_t >, Acir::Witness, Acir::Witness > > mul_terms
Acir::Expression operation
Acir::BlackBoxFuncCall value
std::vector< Acir::Witness > init
Acir::BlockType block_type
std::variant< AssertZero, BlackBoxFuncCall, MemoryOp, MemoryInit, BrilligCall, Call > value
std::map< Witnesses::Witness, std::vector< uint8_t > > value
static constexpr field one()
static field random_element(numeric::RNG *engine=nullptr) noexcept
static field serialize_from_buffer(const uint8_t *buffer)
static constexpr field zero()