39 .
index = e.value.value,
45 .
index = bb::stdlib::IS_CONSTANT,
50 bb::assert_failure(
"acir_format::parse_input: unrecognized Acir::FunctionInput variant. An error here "
51 "means there was a serialization error.");
61 "acir_format::get_witness_from_function_input: input must be a Witness variant. An error here means "
62 "there was a serialization error.");
69 if (witness_idx != stdlib::IS_CONSTANT) {
77 for (
const auto& mul_term : expr.
mul_terms) {
96 auto update_max_witness_index_from_witness = [&](
const Acir::Witness& witness) {
111 update_max_witness_index_from_function_input(bb_arg.lhs);
112 update_max_witness_index_from_function_input(bb_arg.rhs);
113 update_max_witness_index_from_witness(bb_arg.output);
115 update_max_witness_index_from_function_input(bb_arg.input);
117 for (
const auto& input : bb_arg.inputs) {
118 update_max_witness_index_from_function_input(input);
120 for (
const auto& input : *bb_arg.iv) {
121 update_max_witness_index_from_function_input(input);
123 for (
const auto& input : *bb_arg.key) {
124 update_max_witness_index_from_function_input(input);
126 for (
const auto& output : bb_arg.outputs) {
127 update_max_witness_index_from_witness(output);
130 for (
const auto& input : *bb_arg.inputs) {
131 update_max_witness_index_from_function_input(input);
133 for (
const auto& input : *bb_arg.hash_values) {
134 update_max_witness_index_from_function_input(input);
136 for (
const auto& output : *bb_arg.outputs) {
137 update_max_witness_index_from_witness(output);
141 for (
const auto& input : bb_arg.inputs) {
142 update_max_witness_index_from_function_input(input);
144 for (
const auto& output : *bb_arg.outputs) {
145 update_max_witness_index_from_witness(output);
149 for (
const auto& input : *bb_arg.public_key_x) {
150 update_max_witness_index_from_function_input(input);
152 for (
const auto& input : *bb_arg.public_key_y) {
153 update_max_witness_index_from_function_input(input);
155 for (
const auto& input : *bb_arg.signature) {
156 update_max_witness_index_from_function_input(input);
158 for (
const auto& input : *bb_arg.hashed_message) {
159 update_max_witness_index_from_function_input(input);
161 update_max_witness_index_from_function_input(bb_arg.predicate);
162 update_max_witness_index_from_witness(bb_arg.output);
164 for (
const auto& input : bb_arg.points) {
165 update_max_witness_index_from_function_input(input);
167 for (
const auto& input : bb_arg.scalars) {
168 update_max_witness_index_from_function_input(input);
170 update_max_witness_index_from_function_input(bb_arg.predicate);
171 for (
const auto& output : *bb_arg.outputs) {
172 update_max_witness_index_from_witness(output);
175 for (
const auto& input : *bb_arg.input1) {
176 update_max_witness_index_from_function_input(input);
178 for (
const auto& input : *bb_arg.input2) {
179 update_max_witness_index_from_function_input(input);
181 update_max_witness_index_from_function_input(bb_arg.predicate);
182 for (
const auto& output : *bb_arg.outputs) {
183 update_max_witness_index_from_witness(output);
186 for (
const auto& input : *bb_arg.inputs) {
187 update_max_witness_index_from_function_input(input);
189 for (
const auto& output : *bb_arg.outputs) {
190 update_max_witness_index_from_witness(output);
193 for (
const auto& input : bb_arg.verification_key) {
194 update_max_witness_index_from_function_input(input);
196 for (
const auto& input : bb_arg.proof) {
197 update_max_witness_index_from_function_input(input);
199 for (
const auto& input : bb_arg.public_inputs) {
200 update_max_witness_index_from_function_input(input);
202 update_max_witness_index_from_function_input(bb_arg.key_hash);
203 update_max_witness_index_from_function_input(bb_arg.predicate);
205 for (
const auto& input : bb_arg.inputs) {
206 update_max_witness_index_from_function_input(input);
208 for (
const auto& output : bb_arg.outputs) {
209 update_max_witness_index_from_witness(output);
215 for (
const auto&
init : arg.init) {
216 update_max_witness_index_from_witness(
init);
224 for (
const auto& input : arg.inputs) {
231 for (
const auto& expr : e.value) {
240 for (
const auto& output : arg.outputs) {
245 update_max_witness_index_from_witness(e.value);
247 for (
const auto& witness : e.value) {
248 update_max_witness_index_from_witness(witness);
255 if (arg.predicate.has_value()) {
259 bb::assert_failure(
"acir_format::update_max_witness_index_from_opcode: Unrecognized opcode.");
269 std::function<T(msgpack::object
const&)> decode_msgpack,
270 std::function<T(std::vector<uint8_t>)> decode_bincode)
288 const uint8_t FORMAT_MSGPACK = 2;
289 const uint8_t FORMAT_MSGPACK_COMPACT = 3;
291 if (
format == FORMAT_MSGPACK ||
format == FORMAT_MSGPACK_COMPACT) {
293 const char*
buffer = &
reinterpret_cast<const char*
>(
buf.data())[1];
294 size_t size =
buf.size() - 1;
295 msgpack::null_visitor probe;
296 if (msgpack::parse(
buffer, size, probe)) {
297 auto oh = msgpack::unpack(
buffer, size);
303 if (o.type == msgpack::type::MAP || o.type == msgpack::type::ARRAY) {
304 return decode_msgpack(o);
323 update_max_witness_index(e.value, af);
328 update_max_witness_index(e.value, af);
338 for (
size_t i = 0; i < circuit.
opcodes.size(); ++i) {
339 const auto& gate = circuit.
opcodes[i];
350 uint32_t block_id = arg.block_id.value;
351 block_id_to_block_constraint[block_id] = { block, { i } };
353 auto block = block_id_to_block_constraint.find(arg.block_id.value);
354 if (block == block_id_to_block_constraint.end()) {
355 bb::assert_failure(
"acir_format::circuit_serder_to_acir_format: unitialized MemoryOp.");
358 block->second.second.push_back(i);
362 bb::assert_failure(
"acir_format::circuit_serde_to_acir_format: Unrecognized Acir Opcode. An error "
363 "here means there was a serialization error.");
369 for (
const auto& [_, block] : block_id_to_block_constraint) {
380 auto program = deserialize_any_format<Acir::Program>(
388 o.convert(program_wob);
390 }
catch (
const msgpack::type_error&) {
393 "acir_format::circuit_buf_to_acir_format: failed to convert msgpack data to Program");
398 BB_ASSERT_EQ(program.functions.size(), 1U,
"circuit_buf_to_acir_format: expected single function in ACIR program");
406 auto witness_stack = deserialize_any_format<Witnesses::WitnessStack>(
411 o.convert(witness_stack);
412 }
catch (
const msgpack::type_error&) {
415 "acir_format::witness_buf_to_witness_vector: failed to convert msgpack data to WitnessStack");
417 return witness_stack;
422 "acir_format::witness_buf_to_witness_vector: expected single WitnessMap in WitnessStack");
433 for (
size_t index = 0;
const auto& e : witness_map.
value) {
437 while (
index < e.first.value) {
438 witness_vector.emplace_back(0);
445 return witness_vector;
456 idx, bb::stdlib::IS_CONSTANT,
"Attempting to override a non-constant witness index in mul_quad_ gate");
457 idx = linear_terms.begin()->first;
458 scaling += linear_terms.begin()->second;
459 linear_terms.erase(idx);
466 result.reserve(arg.
mul_terms.size() + linear_terms.size());
469 for (
const auto& mul_term : arg.
mul_terms) {
473 .c = bb::stdlib::IS_CONSTANT,
474 .d = bb::stdlib::IS_CONSTANT,
484 auto& mul_quad = result.back();
485 if (linear_terms.contains(mul_quad.a)) {
486 mul_quad.a_scaling += linear_terms.at(mul_quad.a);
487 linear_terms.erase(mul_quad.a);
489 if (linear_terms.contains(mul_quad.b)) {
491 mul_quad.b_scaling += linear_terms.at(mul_quad.b);
492 linear_terms.erase(mul_quad.b);
497 bool is_first_gate =
true;
498 for (
auto& mul_quad : result) {
499 if (!linear_terms.empty()) {
500 add_linear_term_and_erase(mul_quad.c, mul_quad.c_scaling, linear_terms);
506 if (!linear_terms.empty()) {
507 add_linear_term_and_erase(mul_quad.d, mul_quad.d_scaling, linear_terms);
509 is_first_gate =
false;
514 while (!linear_terms.empty()) {
517 .
a = bb::stdlib::IS_CONSTANT,
518 .b = bb::stdlib::IS_CONSTANT,
519 .c = bb::stdlib::IS_CONSTANT,
520 .d = bb::stdlib::IS_CONSTANT,
528 if (!linear_terms.empty()) {
529 add_linear_term_and_erase(mul_quad.
a, mul_quad.
a_scaling, linear_terms);
531 if (!linear_terms.empty()) {
532 add_linear_term_and_erase(mul_quad.
b, mul_quad.
b_scaling, linear_terms);
534 if (!linear_terms.empty()) {
535 add_linear_term_and_erase(mul_quad.
c, mul_quad.
c_scaling, linear_terms);
540 if (!linear_terms.empty()) {
541 add_linear_term_and_erase(mul_quad.
d, mul_quad.
d_scaling, linear_terms);
543 is_first_gate =
false;
546 result.emplace_back(mul_quad);
549 BB_ASSERT(!result.empty(),
"split_into_mul_quad_gates: resulted in zero gates.");
550 result.shrink_to_fit();
559 return ((gate.mul_scaling ==
fr(0)) && (gate.a_scaling ==
fr(0)) && (gate.b_scaling ==
fr(0)) &&
560 (gate.c_scaling ==
fr(0)) && (gate.d_scaling ==
fr(0)) && (gate.const_scaling ==
fr(0)));
567 if (is_single_gate) {
568 BB_ASSERT_EQ(mul_quads.size(), 1U,
"acir_format::handle_arithmetic: expected a single gate.");
569 auto mul_quad = mul_quads[0];
574 BB_ASSERT_GT(mul_quads.size(), 1U,
"acir_format::handle_arithmetic: expected multiple gates but found one.");
579 for (
auto const& mul_quad : mul_quads) {
580 BB_ASSERT(!is_zero_gate(mul_quad),
"acir_format::handle_arithmetic: produced an arithmetic zero gate.");
588 auto to_witness_or_constant = [&](
auto& e) {
return parse_input(e); };
589 auto to_witness = [&](
auto& e) {
return e.value; };
599 .result = to_witness(arg.output),
600 .num_bits = arg.num_bits,
601 .is_xor_gate =
false,
608 .result = to_witness(arg.output),
609 .num_bits = arg.num_bits,
616 .num_bits = arg.num_bits,
630 .hash_values =
transform::map(*arg.hash_values, to_witness_or_constant),
639 .blackbox_input = parse_input(e),
650 [&](
auto& e) { return Blake3Input{ .blackbox_input = parse_input(e), .num_bits = 8 }; }),
655 af.ecdsa_k1_constraints.push_back(EcdsaConstraint{
657 .hashed_message =
transform::map(*arg.hashed_message, to_witness_from_input),
658 .signature =
transform::map(*arg.signature, to_witness_from_input),
659 .pub_x_indices =
transform::map(*arg.public_key_x, to_witness_from_input),
660 .pub_y_indices =
transform::map(*arg.public_key_y, to_witness_from_input),
662 .result = to_witness(arg.output),
664 af.original_opcode_indices.ecdsa_k1_constraints.push_back(opcode_index);
666 af.ecdsa_r1_constraints.push_back(EcdsaConstraint{
668 .hashed_message =
transform::map(*arg.hashed_message, to_witness_from_input),
669 .signature =
transform::map(*arg.signature, to_witness_from_input),
670 .pub_x_indices =
transform::map(*arg.public_key_x, to_witness_from_input),
671 .pub_y_indices =
transform::map(*arg.public_key_y, to_witness_from_input),
673 .result = to_witness(arg.output),
675 af.original_opcode_indices.ecdsa_r1_constraints.push_back(opcode_index);
677 af.multi_scalar_mul_constraints.push_back(MultiScalarMul{
681 .out_point_x = to_witness((*arg.outputs)[0]),
682 .out_point_y = to_witness((*arg.outputs)[1]),
683 .out_point_is_infinite = to_witness((*arg.outputs)[2]),
685 af.original_opcode_indices.multi_scalar_mul_constraints.push_back(opcode_index);
687 af.ec_add_constraints.push_back(EcAdd{
695 .result_x = to_witness((*arg.outputs)[0]),
696 .result_y = to_witness((*arg.outputs)[1]),
697 .result_infinite = to_witness((*arg.outputs)[2]),
699 af.original_opcode_indices.ec_add_constraints.push_back(opcode_index);
701 af.keccak_permutations.push_back(Keccakf1600{
705 af.original_opcode_indices.keccak_permutations.push_back(opcode_index);
708 if (predicate.is_constant && predicate.value.is_zero()) {
712 auto c = RecursionConstraint{
713 .key =
transform::map(arg.verification_key, to_witness_from_input),
715 .public_inputs =
transform::map(arg.public_inputs, to_witness_from_input),
717 .proof_type = arg.proof_type,
718 .predicate = predicate,
722 switch (c.proof_type) {
727 af.honk_recursion_constraints.push_back(c);
728 af.original_opcode_indices.honk_recursion_constraints.push_back(opcode_index);
734 af.hn_recursion_constraints.push_back(c);
735 af.original_opcode_indices.hn_recursion_constraints.push_back(opcode_index);
738 af.avm_recursion_constraints.push_back(c);
739 af.original_opcode_indices.avm_recursion_constraints.push_back(opcode_index);
742 af.chonk_recursion_constraints.push_back(c);
743 af.original_opcode_indices.chonk_recursion_constraints.push_back(opcode_index);
747 "acir_format::handle_black_box_fun_call: Invalid PROOF_TYPE in RecursionConstraint.");
750 af.poseidon2_constraints.push_back(Poseidon2Constraint{
754 af.original_opcode_indices.poseidon2_constraints.push_back(opcode_index);
756 bb::assert_failure(
"acir_format::handle_blackbox_func_call: Unrecognized BlackBoxFuncCall variant. An "
757 "error here means there was a serialization error.");
770 .type = BlockType::ROM,
771 .calldata_id = CallDataType::None,
774 for (
const auto&
init : mem_init.
init) {
775 block.init.push_back(
init.value);
782 BB_ASSERT(calldata_id == 0 || calldata_id == 1,
"acir_format::handle_memory_init: Unsupported calldata id");
784 block.type = BlockType::CallData;
785 block.calldata_id = calldata_id == 0 ? CallDataType::Primary : CallDataType::Secondary;
787 block.type = BlockType::ReturnData;
796 auto acir_expression_to_witness_or_constant = [&](
const Acir::Expression& expr) {
799 BB_ASSERT(expr.mul_terms.empty(),
"MemoryOp should not have multiplication terms");
800 BB_ASSERT_LTE(expr.linear_combinations.size(), 1U,
"MemoryOp should have at most one linear term");
802 const fr a_scaling = expr.linear_combinations.size() == 1
807 bool is_witness = a_scaling ==
fr::one() && constant_term ==
fr::zero();
808 bool is_constant = a_scaling ==
fr::zero();
809 BB_ASSERT(is_witness || is_constant,
"MemoryOp expression must be a witness or a constant");
812 .
index = is_witness ?
std::get<1>(expr.linear_combinations[0]).value : bb::stdlib::IS_CONSTANT,
813 .value = is_constant ? constant_term :
fr::zero(),
814 .is_constant = is_constant,
820 BB_ASSERT(expr.mul_terms.empty(),
"MemoryOp expression should not have multiplication terms");
821 BB_ASSERT(expr.linear_combinations.empty(),
"MemoryOp expression should not have linear terms");
826 "MemoryOp expression should be either zero or one");
832 AccessType access_type = is_read_operation(mem_op.
op.
operation) ? AccessType::Read : AccessType::Write;
833 if (access_type == AccessType::Write) {
835 BB_ASSERT((block.
type != BlockType::CallData) && (block.
type != BlockType::ReturnData));
837 block.
type = BlockType::RAM;
845 block.
trace.push_back(acir_mem_op);
850 static constexpr size_t NUM_WIRES = 4;
853 if (linear_terms.size() > NUM_WIRES) {
876 size_t num_witnesses_to_be_put_in_wires = 2 + linear_terms.size();
881 bool lhs_is_distinct_from_linear_terms = !linear_terms.contains(witness_idx_lhs);
882 bool rhs_is_distinct_from_linear_terms = !linear_terms.contains(witness_idx_rhs);
884 if (witness_idx_lhs != witness_idx_rhs) {
885 num_witnesses_to_be_put_in_wires -= lhs_is_distinct_from_linear_terms ? 0U : 1U;
886 num_witnesses_to_be_put_in_wires -= rhs_is_distinct_from_linear_terms ? 0U : 1U;
888 num_witnesses_to_be_put_in_wires -= lhs_is_distinct_from_linear_terms ? 0U : 1U;
891 return num_witnesses_to_be_put_in_wires <= NUM_WIRES;
894 return linear_terms.size() <= NUM_WIRES;
902 uint32_t witness_idx =
std::get<1>(linear_term).value;
903 if (linear_terms.contains(witness_idx)) {
904 linear_terms[witness_idx] += selector_value;
906 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,...)
std::string format(Args... args)
uint8_t buffer[RANDOM_BUFFER_SIZE]
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::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
std::vector< Acir::Witness > init
Acir::BlockType block_type
std::variant< AssertZero, BlackBoxFuncCall, MemoryOp, MemoryInit, BrilligCall, Call > value
std::vector< Acir::Circuit > functions
static Program bincodeDeserialize(std::vector< uint8_t >)
std::vector< Acir::Circuit > functions
std::map< Witnesses::Witness, std::vector< uint8_t > > value
static WitnessStack bincodeDeserialize(std::vector< uint8_t >)
static constexpr field one()
static field serialize_from_buffer(const uint8_t *buffer)
static constexpr field zero()