barretenberg
Loading...
Searching...
No Matches
standard_circuit_builder.hpp
1#pragma once
2#include "barretenberg/ecc/curves/bn254/bn254.hpp"
3#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
4#include "barretenberg/proof_system/types/circuit_type.hpp"
5#include "barretenberg/proof_system/types/merkle_hash_type.hpp"
6#include "barretenberg/proof_system/types/pedersen_commitment_type.hpp"
7#include "circuit_builder_base.hpp"
8#include <array>
9
10namespace proof_system {
11
12template <typename FF> class StandardCircuitBuilder_ : public CircuitBuilderBase<FF> {
13 public:
15 static constexpr size_t NUM_WIRES = Arithmetization::NUM_WIRES;
16 // Keeping NUM_WIRES, at least temporarily, for backward compatibility
17 static constexpr size_t program_width = Arithmetization::NUM_WIRES;
18 static constexpr size_t num_selectors = Arithmetization::NUM_SELECTORS;
19 std::vector<std::string> selector_names = Arithmetization::selector_names;
20
21 static constexpr std::string_view NAME_STRING = "StandardArithmetization";
22 static constexpr CircuitType CIRCUIT_TYPE = CircuitType::STANDARD;
23 static constexpr merkle::HashType merkle_hash_type = merkle::HashType::FIXED_BASE_PEDERSEN;
24 static constexpr pedersen::CommitmentType commitment_type = pedersen::CommitmentType::FIXED_BASE_PEDERSEN;
25
26 std::array<std::vector<uint32_t, barretenberg::ContainerSlabAllocator<uint32_t>>, NUM_WIRES> wires;
27 Arithmetization selectors;
28
29 using WireVector = std::vector<uint32_t, barretenberg::ContainerSlabAllocator<uint32_t>>;
30 using SelectorVector = std::vector<FF, barretenberg::ContainerSlabAllocator<FF>>;
31
32 WireVector& w_l() { return std::get<0>(wires); };
33 WireVector& w_r() { return std::get<1>(wires); };
34 WireVector& w_o() { return std::get<2>(wires); };
35
36 const WireVector& w_l() const { return std::get<0>(wires); };
37 const WireVector& w_r() const { return std::get<1>(wires); };
38 const WireVector& w_o() const { return std::get<2>(wires); };
39
40 SelectorVector& q_m() { return this->selectors.q_m(); };
41 SelectorVector& q_1() { return this->selectors.q_1(); };
42 SelectorVector& q_2() { return this->selectors.q_2(); };
43 SelectorVector& q_3() { return this->selectors.q_3(); };
44 SelectorVector& q_c() { return this->selectors.q_c(); };
45
46 const SelectorVector& q_m() const { return this->selectors.q_m(); };
47 const SelectorVector& q_1() const { return this->selectors.q_1(); };
48 const SelectorVector& q_2() const { return this->selectors.q_2(); };
49 const SelectorVector& q_3() const { return this->selectors.q_3(); };
50 const SelectorVector& q_c() const { return this->selectors.q_c(); };
51
52 static constexpr size_t UINT_LOG2_BASE = 2;
53
54 // These are variables that we have used a gate on, to enforce that they are
55 // equal to a defined value.
56 // TODO(#216)(Adrian): Why is this not in CircuitBuilderBase
57 std::map<FF, uint32_t> constant_variable_indices;
58
59 StandardCircuitBuilder_(const size_t size_hint = 0)
60 : CircuitBuilderBase<FF>(size_hint)
61 {
62 selectors.reserve(size_hint);
63 w_l().reserve(size_hint);
64 w_r().reserve(size_hint);
65 w_o().reserve(size_hint);
66 // To effieciently constrain wires to zero, we set the first value of w_1 to be 0, and use copy constraints for
67 // all future zero values.
68 // (#216)(Adrian): This should be done in a constant way, maybe by initializing the constant_variable_indices
69 // map
70 this->zero_idx = put_constant_variable(FF::zero());
71 // TODO(#217)(Cody): Ensure that no polynomial is ever zero. Maybe there's a better way.
72 this->one_idx = put_constant_variable(FF::one());
73 // 1 * 1 * 1 + 1 * 1 + 1 * 1 + 1 * 1 + -4
74 // m l r o c
75 create_poly_gate({ this->one_idx, this->one_idx, this->one_idx, 1, 1, 1, 1, -4 });
76 };
79 StandardCircuitBuilder_& operator=(const StandardCircuitBuilder_& other) = delete;
81 {
82 CircuitBuilderBase<FF>::operator=(std::move(other));
83 constant_variable_indices = other.constant_variable_indices;
84 wires = other.wires;
85 selectors = other.selectors;
86 return *this;
87 };
88 ~StandardCircuitBuilder_() override = default;
89
90 void assert_equal_constant(uint32_t const a_idx, FF const& b, std::string const& msg = "assert equal constant");
91
92 void create_add_gate(const add_triple_<FF>& in) override;
93 void create_mul_gate(const mul_triple_<FF>& in) override;
94 void create_bool_gate(const uint32_t a) override;
95 void create_poly_gate(const poly_triple_<FF>& in) override;
96 void create_big_add_gate(const add_quad_<FF>& in);
97 void create_big_add_gate_with_bit_extraction(const add_quad_<FF>& in);
98 void create_big_mul_gate(const mul_quad_<FF>& in);
100 void create_fixed_group_add_gate(const fixed_group_add_quad_<FF>& in);
101 void create_fixed_group_add_gate_with_init(const fixed_group_add_quad_<FF>& in,
102 const fixed_group_init_quad_<FF>& init);
103 void create_fixed_group_add_gate_final(const add_quad_<FF>& in);
104
105 fixed_group_add_quad_<FF> previous_add_quad;
106
107 // TODO(#216)(Adrian): This should be a virtual overridable method in the base class.
108 void fix_witness(const uint32_t witness_index, const FF& witness_value);
109
110 std::vector<uint32_t> decompose_into_base4_accumulators(const uint32_t witness_index,
111 const size_t num_bits,
112 std::string const& msg = "create_range_constraint");
113
114 void create_range_constraint(const uint32_t variable_index,
115 const size_t num_bits,
116 std::string const& msg = "create_range_constraint")
117 {
118 decompose_into_base4_accumulators(variable_index, num_bits, msg);
119 }
120
121 accumulator_triple_<FF> create_logic_constraint(const uint32_t a,
122 const uint32_t b,
123 const size_t num_bits,
124 bool is_xor_gate);
125 accumulator_triple_<FF> create_and_constraint(const uint32_t a, const uint32_t b, const size_t num_bits);
126 accumulator_triple_<FF> create_xor_constraint(const uint32_t a, const uint32_t b, const size_t num_bits);
127
128 // TODO(#216)(Adrian): The 2 following methods should be virtual in the base class
129 uint32_t put_constant_variable(const FF& variable);
130
131 size_t get_num_constant_gates() const override { return 0; }
132
133 bool check_circuit();
134
135 msgpack::sbuffer export_circuit() override;
136
137 private:
138 struct CircuitSchema {
139 std::string modulus;
140 std::vector<uint32_t> public_inps;
141 std::unordered_map<uint32_t, std::string> vars_of_interest;
142 std::vector<FF> variables;
143 std::vector<std::vector<FF>> selectors;
144 std::vector<std::vector<uint32_t>> wires;
145 MSGPACK_FIELDS(modulus, public_inps, vars_of_interest, variables, selectors, wires);
146 } circuit_schema;
147};
148
150extern template class StandardCircuitBuilder_<grumpkin::fr>;
153} // namespace proof_system
Definition: circuit_builder_base.hpp:14
Definition: standard_circuit_builder.hpp:12
void create_poly_gate(const poly_triple_< FF > &in) override
Definition: standard_circuit_builder.cpp:230
msgpack::sbuffer export_circuit() override
Definition: standard_circuit_builder.cpp:519
bool check_circuit()
Definition: standard_circuit_builder.cpp:494
void create_bool_gate(const uint32_t a) override
Definition: standard_circuit_builder.cpp:208
void create_balanced_add_gate(const add_quad_< FF > &in)
Definition: standard_circuit_builder.cpp:64
void create_big_add_gate(const add_quad_< FF > &in)
Definition: standard_circuit_builder.cpp:43
void create_mul_gate(const mul_triple_< FF > &in) override
Definition: standard_circuit_builder.cpp:186
void create_add_gate(const add_triple_< FF > &in) override
Definition: standard_circuit_builder.cpp:20
Definition: gate_data.hpp:115
Definition: gate_data.hpp:20
Definition: gate_data.hpp:10
Definition: gate_data.hpp:99
Definition: gate_data.hpp:109
Definition: gate_data.hpp:31
Definition: gate_data.hpp:43
Definition: gate_data.hpp:51