5#include "barretenberg/polynomials/polynomial.hpp"
6#include "barretenberg/proof_system/op_queue/ecc_op_queue.hpp"
7#include "barretenberg/proof_system/plookup_tables/plookup_tables.hpp"
8#include "barretenberg/proof_system/plookup_tables/types.hpp"
9#include "barretenberg/proof_system/types/circuit_type.hpp"
10#include "barretenberg/proof_system/types/merkle_hash_type.hpp"
11#include "barretenberg/proof_system/types/pedersen_commitment_type.hpp"
12#include "circuit_builder_base.hpp"
15namespace proof_system {
20 std::array<uint32_t, 5> a;
21 std::array<uint32_t, 5> b;
22 std::array<uint32_t, 5> q;
23 std::array<uint32_t, 5> r;
24 std::array<FF, 5> neg_modulus;
30template <
typename Arithmetization>
33 using FF =
typename Arithmetization::FF;
34 static constexpr size_t NUM_WIRES = Arithmetization::NUM_WIRES;
36 static constexpr size_t program_width = Arithmetization::NUM_WIRES;
37 static constexpr size_t num_selectors = Arithmetization::NUM_SELECTORS;
38 std::vector<std::string> selector_names = Arithmetization::selector_names;
40 static constexpr std::string_view NAME_STRING =
"UltraArithmetization";
41 static constexpr CircuitType CIRCUIT_TYPE = CircuitType::ULTRA;
42 static constexpr merkle::HashType merkle_hash_type = merkle::HashType::LOOKUP_PEDERSEN;
43 static constexpr pedersen::CommitmentType commitment_type = pedersen::CommitmentType::FIXED_BASE_PEDERSEN;
44 static constexpr size_t UINT_LOG2_BASE = 6;
48 static constexpr size_t DEFAULT_PLOOKUP_RANGE_BITNUM = 14;
49 static constexpr size_t DEFAULT_PLOOKUP_RANGE_STEP_SIZE = 3;
50 static constexpr size_t DEFAULT_PLOOKUP_RANGE_SIZE = (1 << DEFAULT_PLOOKUP_RANGE_BITNUM) - 1;
51 static constexpr size_t DEFAULT_NON_NATIVE_FIELD_LIMB_BITS = 68;
52 static constexpr uint32_t UNINITIALIZED_MEMORY_RECORD = UINT32_MAX;
53 static constexpr size_t NUMBER_OF_GATES_PER_RAM_ACCESS = 2;
54 static constexpr size_t NUMBER_OF_ARITHMETIC_GATES_PER_RAM_ARRAY = 1;
55 static constexpr size_t NUM_RESERVED_GATES = 4;
57 static constexpr size_t GATES_PER_NON_NATIVE_FIELD_MULTIPLICATION_ARITHMETIC = 7;
59 size_t num_vars_added_in_constructor = 0;
68 RAM_CONSISTENCY_CHECK,
69 ROM_CONSISTENCY_CHECK,
77 uint64_t target_range;
80 std::vector<uint32_t> variable_indices;
81 bool operator==(
const RangeList& other)
const noexcept
83 return target_range == other.target_range && range_tag == other.range_tag && tau_tag == other.tau_tag &&
84 variable_indices == other.variable_indices;
94 uint32_t index_witness = 0;
95 uint32_t value_column1_witness = 0;
96 uint32_t value_column2_witness = 0;
98 uint32_t record_witness = 0;
99 size_t gate_index = 0;
100 bool operator<(
const RomRecord& other)
const {
return index < other.index; }
101 bool operator==(
const RomRecord& other)
const noexcept
103 return index_witness == other.index_witness && value_column1_witness == other.value_column1_witness &&
104 value_column2_witness == other.value_column2_witness && index == other.index &&
105 record_witness == other.record_witness && gate_index == other.gate_index;
119 uint32_t index_witness = 0;
120 uint32_t timestamp_witness = 0;
121 uint32_t value_witness = 0;
123 uint32_t timestamp = 0;
124 AccessType access_type = AccessType::READ;
125 uint32_t record_witness = 0;
126 size_t gate_index = 0;
127 bool operator<(
const RamRecord& other)
const
129 bool index_test = (index) < (other.index);
130 return index_test || (index == other.index && timestamp < other.timestamp);
132 bool operator==(
const RamRecord& other)
const noexcept
134 return index_witness == other.index_witness && timestamp_witness == other.timestamp_witness &&
135 value_witness == other.value_witness && index == other.index && timestamp == other.timestamp &&
136 access_type == other.access_type && record_witness == other.record_witness &&
137 gate_index == other.gate_index;
149 std::vector<uint32_t> state;
155 std::vector<RamRecord> records;
158 size_t access_count = 0;
162 return (state == other.state && records == other.records && access_count == other.access_count);
174 std::vector<std::array<uint32_t, 2>> state;
180 std::vector<RomRecord> records;
185 return (state == other.state && records == other.records);
195 std::array<uint32_t, 5> a;
196 std::array<uint32_t, 5> b;
204 for (
size_t i = 0; i < 5; ++i) {
205 valid = valid && (a[i] == other.a[i]);
206 valid = valid && (b[i] == other.b[i]);
211 static void deduplicate(std::vector<cached_partial_non_native_field_multiplication>& vec)
213 std::unordered_set<cached_partial_non_native_field_multiplication, Hash, std::equal_to<>> seen;
215 std::vector<cached_partial_non_native_field_multiplication> uniqueVec;
217 for (
const auto& item : vec) {
218 if (seen.insert(item).second) {
219 uniqueVec.push_back(item);
243 size_t combined_hash = 0;
250 auto hash_combiner = [](
size_t lhs,
size_t rhs) {
251 return lhs ^ (rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2));
254 for (
const auto& elem : obj.a) {
255 combined_hash = hash_combiner(combined_hash, std::hash<uint32_t>()(elem));
257 for (
const auto& elem : obj.b) {
258 combined_hash = hash_combiner(combined_hash, std::hash<uint32_t>()(elem));
261 return combined_hash;
284 using WireVector = std::vector<uint32_t, barretenberg::ContainerSlabAllocator<uint32_t>>;
285 using SelectorVector = std::vector<FF, barretenberg::ContainerSlabAllocator<FF>>;
287 std::vector<uint32_t> public_inputs;
288 std::vector<FF> variables;
290 std::vector<uint32_t> next_var_index;
292 std::vector<uint32_t> prev_var_index;
294 std::vector<uint32_t> real_variable_index;
295 std::vector<uint32_t> real_variable_tags;
296 std::map<FF, uint32_t> constant_variable_indices;
307 SelectorVector q_arith;
308 SelectorVector q_sort;
309 SelectorVector q_elliptic;
310 SelectorVector q_aux;
311 SelectorVector q_lookup_type;
312 uint32_t current_tag = DUMMY_TAG;
313 std::map<uint32_t, uint32_t> tau;
315 std::vector<RamTranscript> ram_arrays;
316 std::vector<RomTranscript> rom_arrays;
318 std::vector<uint32_t> memory_read_records;
319 std::vector<uint32_t> memory_write_records;
320 std::map<uint64_t, RangeList> range_lists;
322 std::vector<UltraCircuitBuilder_::cached_partial_non_native_field_multiplication>
323 cached_partial_non_native_field_multiplications;
326 bool circuit_finalized =
false;
339 stored_state.public_inputs = builder.public_inputs;
340 stored_state.variables = builder.variables;
342 stored_state.next_var_index = builder.next_var_index;
344 stored_state.prev_var_index = builder.prev_var_index;
346 stored_state.real_variable_index = builder.real_variable_index;
347 stored_state.real_variable_tags = builder.real_variable_tags;
348 stored_state.constant_variable_indices = builder.constant_variable_indices;
349 stored_state.w_l = builder.w_l();
350 stored_state.w_r = builder.w_r();
351 stored_state.w_o = builder.w_o();
352 stored_state.w_4 = builder.w_4();
353 stored_state.q_m = builder.q_m();
354 stored_state.q_c = builder.q_c();
355 stored_state.q_1 = builder.q_1();
356 stored_state.q_2 = builder.q_2();
357 stored_state.q_3 = builder.q_3();
358 stored_state.q_4 = builder.q_4();
359 stored_state.q_arith = builder.q_arith();
360 stored_state.q_sort = builder.q_sort();
361 stored_state.q_elliptic = builder.q_elliptic();
362 stored_state.q_aux = builder.q_aux();
363 stored_state.q_lookup_type = builder.q_lookup_type();
364 stored_state.current_tag = builder.current_tag;
365 stored_state.tau = builder.tau;
367 stored_state.ram_arrays = builder.ram_arrays;
368 stored_state.rom_arrays = builder.rom_arrays;
370 stored_state.memory_read_records = builder.memory_read_records;
371 stored_state.memory_write_records = builder.memory_write_records;
372 stored_state.range_lists = builder.range_lists;
373 stored_state.circuit_finalized = builder.circuit_finalized;
374 stored_state.num_gates = builder.num_gates;
375 stored_state.cached_partial_non_native_field_multiplications =
376 builder.cached_partial_non_native_field_multiplications;
387 template <
typename CircuitBuilder>
391 stored_state.public_inputs = builder->public_inputs;
392 stored_state.variables = builder->variables;
394 stored_state.next_var_index = builder->next_var_index;
396 stored_state.prev_var_index = builder->prev_var_index;
398 stored_state.real_variable_index = builder->real_variable_index;
399 stored_state.real_variable_tags = builder->real_variable_tags;
400 stored_state.constant_variable_indices = builder->constant_variable_indices;
401 stored_state.current_tag = builder->current_tag;
402 stored_state.tau = builder->tau;
404 stored_state.ram_arrays = builder->ram_arrays;
405 stored_state.rom_arrays = builder->rom_arrays;
407 stored_state.memory_read_records = builder->memory_read_records;
408 stored_state.memory_write_records = builder->memory_write_records;
409 stored_state.range_lists = builder->range_lists;
410 stored_state.circuit_finalized = builder->circuit_finalized;
411 stored_state.num_gates = builder->num_gates;
412 stored_state.cached_partial_non_native_field_multiplications =
413 builder->cached_partial_non_native_field_multiplications;
426 builder->public_inputs = public_inputs;
427 builder->variables = variables;
429 builder->next_var_index = next_var_index;
431 builder->prev_var_index = prev_var_index;
433 builder->real_variable_index = real_variable_index;
434 builder->real_variable_tags = real_variable_tags;
435 builder->constant_variable_indices = constant_variable_indices;
436 builder->current_tag = current_tag;
439 builder->ram_arrays = ram_arrays;
440 builder->rom_arrays = rom_arrays;
442 builder->memory_read_records = memory_read_records;
443 builder->memory_write_records = memory_write_records;
444 builder->range_lists = range_lists;
445 builder->circuit_finalized = circuit_finalized;
446 builder->num_gates = num_gates;
447 builder->cached_partial_non_native_field_multiplications = cached_partial_non_native_field_multiplications;
448 builder->w_l().resize(num_gates);
449 builder->w_r().resize(num_gates);
450 builder->w_o().resize(num_gates);
451 builder->w_4().resize(num_gates);
452 builder->q_m().resize(num_gates);
453 builder->q_c().resize(num_gates);
454 builder->q_1().resize(num_gates);
455 builder->q_2().resize(num_gates);
456 builder->q_3().resize(num_gates);
457 builder->q_4().resize(num_gates);
458 builder->q_arith().resize(num_gates);
459 builder->q_sort().resize(num_gates);
460 builder->q_elliptic().resize(num_gates);
461 builder->q_aux().resize(num_gates);
462 builder->q_lookup_type().resize(num_gates);
471 template <
typename CircuitBuilder>
bool is_same_state(
const CircuitBuilder& builder)
473 if (!(public_inputs == builder.public_inputs)) {
476 if (!(variables == builder.variables)) {
479 if (!(next_var_index == builder.next_var_index)) {
482 if (!(prev_var_index == builder.prev_var_index)) {
485 if (!(real_variable_index == builder.real_variable_index)) {
488 if (!(real_variable_tags == builder.real_variable_tags)) {
491 if (!(constant_variable_indices == builder.constant_variable_indices)) {
494 if (!(w_l == builder.w_l())) {
497 if (!(w_r == builder.w_r())) {
500 if (!(w_o == builder.w_o())) {
503 if (!(w_4 == builder.w_4())) {
506 if (!(q_m == builder.q_m())) {
509 if (!(q_c == builder.q_c())) {
512 if (!(q_1 == builder.q_1())) {
515 if (!(q_2 == builder.q_2())) {
518 if (!(q_3 == builder.q_3())) {
521 if (!(q_4 == builder.q_4())) {
524 if (!(q_arith == builder.q_arith())) {
527 if (!(q_sort == builder.q_sort())) {
530 if (!(q_elliptic == builder.q_elliptic())) {
533 if (!(q_aux == builder.q_aux())) {
536 if (!(q_lookup_type == builder.q_lookup_type())) {
539 if (!(current_tag == builder.current_tag)) {
542 if (!(tau == builder.tau)) {
545 if (!(ram_arrays == builder.ram_arrays)) {
548 if (!(rom_arrays == builder.rom_arrays)) {
551 if (!(memory_read_records == builder.memory_read_records)) {
554 if (!(memory_write_records == builder.memory_write_records)) {
557 if (!(range_lists == builder.range_lists)) {
560 if (!(cached_partial_non_native_field_multiplications ==
561 builder.cached_partial_non_native_field_multiplications)) {
564 if (!(num_gates == builder.num_gates)) {
567 if (!(circuit_finalized == builder.circuit_finalized)) {
574 std::array<std::vector<uint32_t, barretenberg::ContainerSlabAllocator<uint32_t>>, NUM_WIRES> wires;
575 Arithmetization selectors;
577 using WireVector = std::vector<uint32_t, ContainerSlabAllocator<uint32_t>>;
578 using SelectorVector = std::vector<FF, ContainerSlabAllocator<FF>>;
580 WireVector& w_l() {
return std::get<0>(wires); };
581 WireVector& w_r() {
return std::get<1>(wires); };
582 WireVector& w_o() {
return std::get<2>(wires); };
583 WireVector& w_4() {
return std::get<3>(wires); };
585 const WireVector& w_l()
const {
return std::get<0>(wires); };
586 const WireVector& w_r()
const {
return std::get<1>(wires); };
587 const WireVector& w_o()
const {
return std::get<2>(wires); };
588 const WireVector& w_4()
const {
return std::get<3>(wires); };
590 SelectorVector& q_m() {
return selectors.q_m(); };
591 SelectorVector& q_c() {
return selectors.q_c(); };
592 SelectorVector& q_1() {
return selectors.q_1(); };
593 SelectorVector& q_2() {
return selectors.q_2(); };
594 SelectorVector& q_3() {
return selectors.q_3(); };
595 SelectorVector& q_4() {
return selectors.q_4(); };
596 SelectorVector& q_arith() {
return selectors.q_arith(); };
597 SelectorVector& q_sort() {
return selectors.q_sort(); };
598 SelectorVector& q_elliptic() {
return selectors.q_elliptic(); };
599 SelectorVector& q_aux() {
return selectors.q_aux(); };
600 SelectorVector& q_lookup_type() {
return selectors.q_lookup_type(); };
602 const SelectorVector& q_c()
const {
return selectors.q_c(); };
603 const SelectorVector& q_1()
const {
return selectors.q_1(); };
604 const SelectorVector& q_2()
const {
return selectors.q_2(); };
605 const SelectorVector& q_3()
const {
return selectors.q_3(); };
606 const SelectorVector& q_4()
const {
return selectors.q_4(); };
607 const SelectorVector& q_arith()
const {
return selectors.q_arith(); };
608 const SelectorVector& q_sort()
const {
return selectors.q_sort(); };
609 const SelectorVector& q_elliptic()
const {
return selectors.q_elliptic(); };
610 const SelectorVector& q_aux()
const {
return selectors.q_aux(); };
611 const SelectorVector& q_lookup_type()
const {
return selectors.q_lookup_type(); };
612 const SelectorVector& q_m()
const {
return selectors.q_m(); };
617 std::map<FF, uint32_t> constant_variable_indices;
619 std::vector<plookup::BasicTable> lookup_tables;
620 std::vector<plookup::MultiTable> lookup_multi_tables;
621 std::map<uint64_t, RangeList> range_lists;
641 std::vector<uint32_t> memory_read_records;
643 std::vector<uint32_t> memory_write_records;
645 std::vector<cached_partial_non_native_field_multiplication> cached_partial_non_native_field_multiplications;
647 bool circuit_finalized =
false;
653 selectors.reserve(size_hint);
654 w_l().reserve(size_hint);
655 w_r().reserve(size_hint);
656 w_o().reserve(size_hint);
657 w_4().reserve(size_hint);
658 this->zero_idx = put_constant_variable(FF::zero());
659 this->tau.insert({ DUMMY_TAG, DUMMY_TAG });
660 num_vars_added_in_constructor = this->variables.size();
662 UltraCircuitBuilder_(
const UltraCircuitBuilder_& other) =
default;
663 UltraCircuitBuilder_(UltraCircuitBuilder_&& other)
664 : CircuitBuilderBase<
FF>(std::move(other))
667 selectors = other.selectors;
668 constant_variable_indices = other.constant_variable_indices;
670 lookup_tables = other.lookup_tables;
671 lookup_multi_tables = other.lookup_multi_tables;
672 range_lists = other.range_lists;
675 memory_read_records = other.memory_read_records;
676 memory_write_records = other.memory_write_records;
677 cached_partial_non_native_field_multiplications = other.cached_partial_non_native_field_multiplications;
678 circuit_finalized = other.circuit_finalized;
680 UltraCircuitBuilder_& operator=(
const UltraCircuitBuilder_& other) =
default;
681 UltraCircuitBuilder_& operator=(UltraCircuitBuilder_&& other)
683 CircuitBuilderBase<FF>::operator=(std::move(other));
685 selectors = other.selectors;
686 constant_variable_indices = other.constant_variable_indices;
688 lookup_tables = other.lookup_tables;
689 lookup_multi_tables = other.lookup_multi_tables;
690 range_lists = other.range_lists;
693 memory_read_records = other.memory_read_records;
694 memory_write_records = other.memory_write_records;
695 cached_partial_non_native_field_multiplications = other.cached_partial_non_native_field_multiplications;
696 circuit_finalized = other.circuit_finalized;
699 ~UltraCircuitBuilder_()
override =
default;
713 size_t nominal_size = selectors.get()[0].size();
714 for (
size_t idx = 1; idx < selectors.get().size(); ++idx) {
715 ASSERT(selectors.get()[idx].size() == nominal_size);
737 void fix_witness(
const uint32_t witness_index,
const FF& witness_value);
740 const uint64_t target_range,
741 std::string
const msg =
"create_new_range_constraint");
744 if (num_bits <= DEFAULT_PLOOKUP_RANGE_BITNUM) {
777 const size_t num_bits,
782 uint32_t put_constant_variable(
const FF& variable);
785 size_t get_num_constant_gates()
const override {
return 0; }
802 size_t& count,
size_t& rangecount,
size_t& romcount,
size_t& ramcount,
size_t& nnfcount)
const
804 count = this->num_gates;
806 for (
size_t i = 0; i <
rom_arrays.size(); ++i) {
807 for (
size_t j = 0; j <
rom_arrays[i].state.size(); ++j) {
808 if (
rom_arrays[i].state[j][0] == UNINITIALIZED_MEMORY_RECORD) {
818 std::vector<size_t> ram_timestamps;
819 std::vector<size_t> ram_range_sizes;
820 std::vector<size_t> ram_range_exists;
821 for (
size_t i = 0; i <
ram_arrays.size(); ++i) {
822 for (
size_t j = 0; j <
ram_arrays[i].state.size(); ++j) {
823 if (
ram_arrays[i].state[j] == UNINITIALIZED_MEMORY_RECORD) {
824 ramcount += NUMBER_OF_GATES_PER_RAM_ACCESS;
827 ramcount += (
ram_arrays[i].records.size() * NUMBER_OF_GATES_PER_RAM_ACCESS);
828 ramcount += NUMBER_OF_ARITHMETIC_GATES_PER_RAM_ARRAY;
831 const auto max_timestamp =
ram_arrays[i].access_count - 1;
835 ram_timestamps.push_back(max_timestamp);
836 size_t padding = (NUM_WIRES - (max_timestamp % NUM_WIRES)) % NUM_WIRES;
837 if (max_timestamp == NUM_WIRES)
838 padding += NUM_WIRES;
839 const size_t ram_range_check_list_size = max_timestamp + padding;
841 size_t ram_range_check_gate_count = (ram_range_check_list_size / NUM_WIRES);
842 ram_range_check_gate_count += 1;
844 ram_range_sizes.push_back(ram_range_check_gate_count);
845 ram_range_exists.push_back(
false);
847 for (
const auto& list : range_lists) {
848 auto list_size = list.second.variable_indices.size();
849 size_t padding = (NUM_WIRES - (list.second.variable_indices.size() % NUM_WIRES)) % NUM_WIRES;
850 if (list.second.variable_indices.size() == NUM_WIRES)
851 padding += NUM_WIRES;
852 list_size += padding;
854 for (
size_t i = 0; i < ram_timestamps.size(); ++i) {
855 if (list.second.target_range == ram_timestamps[i]) {
856 ram_range_exists[i] =
true;
859 rangecount += (list_size / NUM_WIRES);
863 for (
size_t i = 0; i < ram_range_sizes.size(); ++i) {
864 if (!ram_range_exists[i]) {
865 rangecount += ram_range_sizes[i];
868 std::vector<cached_partial_non_native_field_multiplication> nnf_copy(
869 cached_partial_non_native_field_multiplications);
871 std::sort(nnf_copy.begin(), nnf_copy.end());
873 auto last = std::unique(nnf_copy.begin(), nnf_copy.end());
874 const size_t num_nnf_ops =
static_cast<size_t>(std::distance(nnf_copy.begin(), last));
875 nnfcount = num_nnf_ops * GATES_PER_NON_NATIVE_FIELD_MULTIPLICATION_ARITHMETIC;
891 if (circuit_finalized) {
892 return this->num_gates;
895 size_t rangecount = 0;
900 return count + romcount + ramcount + rangecount + nnfcount;
914 size_t tables_size = 0;
915 size_t lookups_size = 0;
916 for (
const auto& table : lookup_tables) {
917 tables_size += table.size;
918 lookups_size += table.lookup_gates.size();
921 auto minimum_circuit_size = tables_size + lookups_size;
922 auto num_filled_gates =
get_num_gates() + this->public_inputs.size();
923 return std::max(minimum_circuit_size, num_filled_gates) + NUM_RESERVED_GATES;
933 size_t rangecount = 0;
939 size_t total = count + romcount + ramcount + rangecount;
940 std::cout <<
"gates = " << total <<
" (arith " << count <<
", rom " << romcount <<
", ram " << ramcount
941 <<
", range " << rangecount <<
", non native field gates " << nnfcount
942 <<
"), pubinp = " << this->public_inputs.size() << std::endl;
945 void assert_equal_constant(
const uint32_t a_idx,
const FF& b, std::string
const& msg =
"assert equal constant")
947 if (this->variables[a_idx] != b && !this->failed()) {
950 auto b_idx = put_constant_variable(b);
958 void initialize_precomputed_table(
const plookup::BasicTableId
id,
959 bool (*generator)(std::vector<FF>&, std::vector<FF>&, std::vector<FF>&),
960 std::array<FF, 2> (*get_values_from_key)(
const std::array<uint64_t, 2>));
966 const plookup::MultiTableId&
id,
968 const uint32_t key_a_index,
969 std::optional<uint32_t> key_b_index = std::nullopt);
975 const uint32_t variable_index,
976 const uint64_t num_bits,
977 const uint64_t target_range_bitnum = DEFAULT_PLOOKUP_RANGE_BITNUM,
978 std::string
const& msg =
"decompose_into_default_range");
979 std::vector<uint32_t> decompose_into_default_range_better_for_oddlimbnum(
980 const uint32_t variable_index,
981 const size_t num_bits,
982 std::string
const& msg =
"decompose_into_default_range_better_for_oddlimbnum");
983 void create_dummy_constraints(
const std::vector<uint32_t>& variable_index);
984 void create_sort_constraint(
const std::vector<uint32_t>& variable_index);
985 void create_sort_constraint_with_edges(
const std::vector<uint32_t>& variable_index,
const FF&,
const FF&);
986 void assign_tag(
const uint32_t variable_index,
const uint32_t tag)
988 ASSERT(tag <= this->current_tag);
990 if (this->real_variable_tags[this->real_variable_index[variable_index]] == tag) {
993 ASSERT(this->real_variable_tags[this->real_variable_index[variable_index]] == DUMMY_TAG);
994 this->real_variable_tags[this->real_variable_index[variable_index]] = tag;
997 uint32_t create_tag(
const uint32_t tag_index,
const uint32_t tau_index)
999 this->tau.insert({ tag_index, tau_index });
1000 this->current_tag++;
1001 return this->current_tag;
1004 uint32_t get_new_tag()
1006 this->current_tag++;
1007 return this->current_tag;
1011 void process_range_list(RangeList& list);
1012 void process_range_lists();
1023 const uint32_t hi_idx,
1024 const size_t lo_limb_bits = DEFAULT_NON_NATIVE_FIELD_LIMB_BITS,
1025 const size_t hi_limb_bits = DEFAULT_NON_NATIVE_FIELD_LIMB_BITS);
1027 const uint32_t limb_idx,
const size_t num_limb_bits = (2 * DEFAULT_NON_NATIVE_FIELD_LIMB_BITS));
1029 const non_native_field_witnesses<FF>& input,
const bool range_constrain_quotient_and_remainder =
true);
1031 typedef std::pair<uint32_t, FF> scaled_witness;
1032 typedef std::tuple<scaled_witness, scaled_witness, FF> add_simple;
1037 std::tuple<uint32_t, uint32_t, FF> limbp);
1042 std::tuple<uint32_t, uint32_t, FF> limbp);
1051 void set_ROM_element(
const size_t rom_id,
const size_t index_value,
const uint32_t value_witness);
1053 const size_t index_value,
1054 const std::array<uint32_t, 2>& value_witnesses);
1055 uint32_t
read_ROM_array(
const size_t rom_id,
const uint32_t index_witness);
1056 std::array<uint32_t, 2>
read_ROM_array_pair(
const size_t rom_id,
const uint32_t index_witness);
1060 void process_ROM_arrays();
1067 void init_RAM_element(
const size_t ram_id,
const size_t index_value,
const uint32_t value_witness);
1068 uint32_t read_RAM_array(
const size_t ram_id,
const uint32_t index_witness);
1069 void write_RAM_array(
const size_t ram_id,
const uint32_t index_witness,
const uint32_t value_witness);
1071 void process_RAM_arrays();
1086 FF w_1_shifted_value,
1087 FF w_4_shifted_value,
1088 const FF alpha_base,
1089 const FF alpha)
const;
1102 FF w_1_shifted_value,
1103 FF w_2_shifted_value,
1104 FF w_3_shifted_value,
1105 FF w_4_shifted_value,
1114 FF w_1_shifted_value,
1115 FF w_2_shifted_value,
1116 FF w_3_shifted_value,
1117 FF w_4_shifted_value,
1125 FF w_1_shifted_value,
1131extern template class UltraCircuitBuilder_<arithmetization::Ultra<barretenberg::fr>>;
1132extern template class UltraCircuitBuilder_<arithmetization::UltraHonk<barretenberg::fr>>;
1133using UltraCircuitBuilder = UltraCircuitBuilder_<arithmetization::Ultra<barretenberg::fr>>;
Container type for lookup table reads.
Definition: types.hpp:316
Definition: circuit_builder_base.hpp:14
virtual void assert_equal(const uint32_t a_idx, const uint32_t b_idx, std::string const &msg="assert_equal")
Definition: circuit_builder_base.cpp:15
Definition: ultra_circuit_builder.hpp:31
std::vector< RamTranscript > ram_arrays
Each entry in ram_arrays represents an independent RAM table. RamTranscript tracks the current table ...
Definition: ultra_circuit_builder.hpp:630
virtual void print_num_gates() const override
Print the number and composition of gates in the circuit.
Definition: ultra_circuit_builder.hpp:930
void create_ROM_gate(RomRecord &record)
Gate that'reads' from a ROM table. i.e. table index is a witness not precomputed.
Definition: ultra_circuit_builder.cpp:2043
void process_ROM_array(const size_t rom_id)
Compute additional gates required to validate ROM reads. Called when generating the proving key.
Definition: ultra_circuit_builder.cpp:2436
void create_new_range_constraint(const uint32_t variable_index, const uint64_t target_range, std::string const msg="create_new_range_constraint")
Constrain a variable to a range.
Definition: ultra_circuit_builder.cpp:809
std::array< uint32_t, 2 > evaluate_non_native_field_multiplication(const non_native_field_witnesses< FF > &input, const bool range_constrain_quotient_and_remainder=true)
Queue up non-native field multiplication data.
Definition: ultra_circuit_builder.cpp:1529
RangeList create_range_list(const uint64_t target_range)
Definition: ultra_circuit_builder.cpp:662
void add_table_column_selector_poly_to_proving_key(barretenberg::polynomial &small, const std::string &tag)
FF compute_auxilary_identity(FF q_aux_value, FF q_arith_value, FF q_1_value, FF q_2_value, FF q_3_value, FF q_4_value, FF q_m_value, FF q_c_value, FF w_1_value, FF w_2_value, FF w_3_value, FF w_4_value, FF w_1_shifted_value, FF w_2_shifted_value, FF w_3_shifted_value, FF w_4_shifted_value, FF alpha_base, FF alpha, FF eta) const
Plookup Auxiliary Gate Identity.
Definition: ultra_circuit_builder.cpp:2953
FF compute_genperm_sort_identity(FF q_sort_value, FF w_1_value, FF w_2_value, FF w_3_value, FF w_4_value, FF w_1_shifted_value, FF alpha_base, FF alpha) const
General permutation sorting identity.
Definition: ultra_circuit_builder.cpp:2809
void finalize_circuit()
Definition: ultra_circuit_builder.cpp:17
FF compute_elliptic_identity(FF q_elliptic_value, FF q_1_value, FF q_m_value, FF w_2_value, FF w_3_value, FF w_1_shifted_value, FF w_2_shifted_value, FF w_3_shifted_value, FF w_4_shifted_value, FF alpha_base, FF alpha) const
Elliptic curve identity gate methods implement elliptic curve point addition.
Definition: ultra_circuit_builder.cpp:2869
void create_big_add_gate_with_bit_extraction(const add_quad_< FF > &in)
A legacy method that was used to extract a bit from c-4d by using gate selectors in the Turboplonk,...
Definition: ultra_circuit_builder.cpp:188
std::array< uint32_t, 5 > evaluate_non_native_field_addition(add_simple limb0, add_simple limb1, add_simple limb2, add_simple limb3, std::tuple< uint32_t, uint32_t, FF > limbp)
Definition: ultra_circuit_builder.cpp:1789
void check_selector_length_consistency()
Debug helper method for ensuring all selectors have the same size.
Definition: ultra_circuit_builder.hpp:708
std::vector< RomTranscript > rom_arrays
Each entry in ram_arrays represents an independent ROM table. RomTranscript tracks the current table ...
Definition: ultra_circuit_builder.hpp:638
void create_big_mul_gate(const mul_quad_< FF > &in)
Create a basic multiplication gate q_m * a * b + q_1 * a + q_2 * b + q_3 * c + q_4 * d + q_c = 0 (q_a...
Definition: ultra_circuit_builder.cpp:252
void create_sorted_ROM_gate(RomRecord &record)
Gate that performs consistency checks to validate that a claimed ROM read value is correct.
Definition: ultra_circuit_builder.cpp:2064
std::array< uint32_t, 2 > decompose_non_native_field_double_width_limb(const uint32_t limb_idx, const size_t num_limb_bits=(2 *DEFAULT_NON_NATIVE_FIELD_LIMB_BITS))
Decompose a single witness into two, where the lowest is DEFAULT_NON_NATIVE_FIELD_LIMB_BITS (68) rang...
Definition: ultra_circuit_builder.cpp:1490
std::array< uint32_t, 2 > read_ROM_array_pair(const size_t rom_id, const uint32_t index_witness)
Read a pair of elements from ROM.
Definition: ultra_circuit_builder.cpp:2400
void create_range_constraint(const uint32_t variable_index, const size_t num_bits, std::string const &msg)
Definition: ultra_circuit_builder.hpp:742
void create_big_add_gate(const add_quad_< FF > &in, const bool use_next_gate_w_4=false)
Create a big addition gate, where in.a * in.a_scaling + in.b * in.b_scaling + in.c * in....
Definition: ultra_circuit_builder.cpp:157
void create_final_sorted_RAM_gate(RamRecord &record, const size_t ram_array_size)
Performs consistency checks to validate that a claimed RAM read/write value is correct....
Definition: ultra_circuit_builder.cpp:2150
void create_ecc_dbl_gate(const ecc_dbl_gate_< FF > &in)
Create an elliptic curve doubling gate.
Definition: ultra_circuit_builder.cpp:488
void process_RAM_array(const size_t ram_id)
Compute additional gates required to validate RAM read/writes. Called when generating the proving key...
Definition: ultra_circuit_builder.cpp:2522
void create_poly_gate(const poly_triple_< FF > &in) override
A plonk gate with disabled (set to zero) fourth wire. q_m * a * b + q_1 * a + q_2 * b + q_3.
Definition: ultra_circuit_builder.cpp:383
void fix_witness(const uint32_t witness_index, const FF &witness_value)
Add a gate equating a particular witness to a constant, fixing it the value.
Definition: ultra_circuit_builder.cpp:556
size_t get_num_gates() const override
Get the final number of gates in a circuit, which consists of the sum of: 1) Current number number of...
Definition: ultra_circuit_builder.hpp:888
void create_add_gate(const add_triple_< FF > &in) override
Create an addition gate, where in.a * in.a_scaling + in.b * in.b_scaling + in.c * in....
Definition: ultra_circuit_builder.cpp:124
void add_gates_to_ensure_all_polys_are_non_zero()
Ensure all polynomials have at least one non-zero coefficient to avoid commiting to the zero-polynomi...
Definition: ultra_circuit_builder.cpp:62
size_t get_total_circuit_size() const
Get the size of the circuit if it was finalized now.
Definition: ultra_circuit_builder.hpp:912
void set_ROM_element_pair(const size_t rom_id, const size_t index_value, const std::array< uint32_t, 2 > &value_witnesses)
Initialize a ROM array element with a pair of witness values.
Definition: ultra_circuit_builder.cpp:2336
std::vector< uint32_t > decompose_into_default_range(const uint32_t variable_index, const uint64_t num_bits, const uint64_t target_range_bitnum=DEFAULT_PLOOKUP_RANGE_BITNUM, std::string const &msg="decompose_into_default_range")
Definition: ultra_circuit_builder.cpp:696
void apply_aux_selectors(const AUX_SELECTORS type)
Enable the auxilary gate of particular type.
Definition: ultra_circuit_builder.cpp:1214
std::array< uint32_t, 5 > evaluate_non_native_field_subtraction(add_simple limb0, add_simple limb1, add_simple limb2, add_simple limb3, std::tuple< uint32_t, uint32_t, FF > limbp)
Definition: ultra_circuit_builder.cpp:1914
size_t create_RAM_array(const size_t array_size)
Create a new updatable memory region.
Definition: ultra_circuit_builder.cpp:2179
void range_constrain_two_limbs(const uint32_t lo_idx, const uint32_t hi_idx, const size_t lo_limb_bits=DEFAULT_NON_NATIVE_FIELD_LIMB_BITS, const size_t hi_limb_bits=DEFAULT_NON_NATIVE_FIELD_LIMB_BITS)
Definition: ultra_circuit_builder.cpp:1399
void create_bool_gate(const uint32_t a) override
Generate an arithmetic gate equivalent to x^2 - x = 0, which forces x to be 0 or 1.
Definition: ultra_circuit_builder.cpp:351
void create_ecc_add_gate(const ecc_add_gate_< FF > &in)
Create an elliptic curve addition gate.
Definition: ultra_circuit_builder.cpp:417
void create_sorted_RAM_gate(RamRecord &record)
Gate that performs consistency checks to validate that a claimed RAM read/write value is correct.
Definition: ultra_circuit_builder.cpp:2131
void get_num_gates_split_into_components(size_t &count, size_t &rangecount, size_t &romcount, size_t &ramcount, size_t &nnfcount) const
Get the final number of gates in a circuit, which consists of the sum of: 1) Current number number of...
Definition: ultra_circuit_builder.hpp:801
size_t create_ROM_array(const size_t array_size)
Create a new read-only memory region.
Definition: ultra_circuit_builder.cpp:2088
plookup::ReadData< uint32_t > create_gates_from_plookup_accumulators(const plookup::MultiTableId &id, const plookup::ReadData< FF > &read_values, const uint32_t key_a_index, std::optional< uint32_t > key_b_index=std::nullopt)
Perform a series of lookups, one for each 'row' in read_values.
Definition: ultra_circuit_builder.cpp:611
void create_RAM_gate(RamRecord &record)
Gate that performs a read/write operation into a RAM table. i.e. table index is a witness not precomp...
Definition: ultra_circuit_builder.cpp:2105
void create_mul_gate(const mul_triple_< FF > &in) override
Create a multiplication gate with q_m * a * b + q_3 * c + q_const = 0.
Definition: ultra_circuit_builder.cpp:322
std::array< uint32_t, 2 > queue_partial_non_native_field_multiplication(const non_native_field_witnesses< FF > &input)
Definition: ultra_circuit_builder.cpp:1742
FF compute_arithmetic_identity(FF q_arith_value, FF q_1_value, FF q_2_value, FF q_3_value, FF q_4_value, FF q_m_value, FF q_c_value, FF w_1_value, FF w_2_value, FF w_3_value, FF w_4_value, FF w_1_shifted_value, FF w_4_shifted_value, const FF alpha_base, const FF alpha) const
Arithmetic gate-related methods.
Definition: ultra_circuit_builder.cpp:2743
void set_ROM_element(const size_t rom_id, const size_t index_value, const uint32_t value_witness)
Initialize a rom cell to equal value_witness
Definition: ultra_circuit_builder.cpp:2293
void process_non_native_field_multiplications()
Called in compute_proving_key when finalizing circuit. Iterates over the cached_non_native_field_mult...
Definition: ultra_circuit_builder.cpp:1692
void init_RAM_element(const size_t ram_id, const size_t index_value, const uint32_t value_witness)
Initialize a RAM cell to equal value_witness
Definition: ultra_circuit_builder.cpp:2197
uint32_t read_ROM_array(const size_t rom_id, const uint32_t index_witness)
Read a single element from ROM.
Definition: ultra_circuit_builder.cpp:2367
bool check_circuit()
Check that the circuit is correct in its current state.
Definition: ultra_circuit_builder.cpp:3227
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a cons...
Definition: constexpr_utils.hpp:16
The structure contains the most basic table serving one function (for, example an xor table)
Definition: types.hpp:263
Definition: types.hpp:124
CircuitDataBackup is a structure we use to store all the information about the circuit that is needed...
Definition: ultra_circuit_builder.hpp:283
static CircuitDataBackup store_full_state(const CircuitBuilder &builder)
Stores the state of everything logic-related in the builder.
Definition: ultra_circuit_builder.hpp:336
bool is_same_state(const CircuitBuilder &builder)
Checks that the circuit state is the same as the stored circuit's one.
Definition: ultra_circuit_builder.hpp:471
void restore_prefinilized_state(CircuitBuilder *builder)
Restores circuit constructor to a prefinilized state.
Definition: ultra_circuit_builder.hpp:424
static CircuitDataBackup store_prefinilized_state(const CircuitBuilder *builder)
Stores the state of all members of the circuit constructor that are needed to restore the state after...
Definition: ultra_circuit_builder.hpp:388
A RAM memory record that can be ordered.
Definition: ultra_circuit_builder.hpp:114
Each ram array is an instance of memory transcript. It saves values and indexes for a particular memo...
Definition: ultra_circuit_builder.hpp:147
Definition: ultra_circuit_builder.hpp:76
A ROM memory record that can be ordered.
Definition: ultra_circuit_builder.hpp:93
Each rom array is an instance of memory transcript. It saves values and indexes for a particular memo...
Definition: ultra_circuit_builder.hpp:172
Definition: ultra_circuit_builder.hpp:240
Used to store instructions to create partial_non_native_field_multiplication gates....
Definition: ultra_circuit_builder.hpp:194
Definition: ultra_circuit_builder.hpp:266
Definition: gate_data.hpp:115
Definition: gate_data.hpp:20
Definition: gate_data.hpp:10
Definition: gate_data.hpp:120
Definition: gate_data.hpp:129
Definition: gate_data.hpp:31
Definition: gate_data.hpp:43
Definition: ultra_circuit_builder.hpp:17
Definition: gate_data.hpp:51