diff --git a/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh b/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh index 6c834b324b92..ee1dfad73ff1 100755 --- a/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh +++ b/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh @@ -11,7 +11,7 @@ cd .. # - Generate a hash for versioning: sha256sum bb-civc-inputs.tar.gz # - Upload the compressed results: aws s3 cp bb-civc-inputs.tar.gz s3://aztec-ci-artifacts/protocol/bb-civc-inputs-[hash(0:8)].tar.gz # Note: In case of the "Test suite failed to run ... Unexpected token 'with' " error, need to run: docker pull aztecprotocol/build:3.0 -pinned_civc_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-civc-inputs-e0c3365e.tar.gz" +pinned_civc_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-civc-inputs-8775f2ab.tar.gz" # For easily rerunning the inputs generation if [[ "${1:-}" == "--update-inputs" ]]; then diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/CMakeLists.txt index 3fbace27b656..00257d6b32f4 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(boomerang_value_detection stdlib_circuit_builders circuit_checker stdlib_primitives numeric stdlib_aes128 stdlib_sha256 stdlib_blake2s stdlib_blake3s stdlib_poseidon2 stdlib_honk_verifier) +barretenberg_module(boomerang_value_detection stdlib_circuit_builders circuit_checker stdlib_primitives numeric stdlib_aes128 stdlib_sha256 stdlib_blake2s stdlib_blake3s stdlib_poseidon2 stdlib_goblin_verifier) diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/commits.txt b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/commits.txt new file mode 100644 index 000000000000..fcda655ebca7 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/commits.txt @@ -0,0 +1,12 @@ +dc8cda19d2 forget to remove constructor +deae720e8a useless constructor for standard circuit builder +a582c39457 remove useless includes from ecc_lookup_relation +3e2624be40 preparings to PR for ECCVM +37baac11e4 eccvm lookup optimization +809d2b15ad removing false-cases for finalizing method +1002a144db quick and dirty fixes +410d798175 small fixes to remove unnecessary gates +7877a7d3bb test redesign after rebase +5aeb0d685f another boring routine +076cd60d41 some experiments with graph acceleration +444794b7ac stuff for tests diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.cpp index c2211200ecc9..aac299095214 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.cpp @@ -16,7 +16,8 @@ namespace cdg { * @param block block to find * @return size_t index of the found block */ -template size_t Graph_::find_block_index(UltraCircuitBuilder& ultra_builder, const UltraBlock& block) +template +size_t StaticAnalyzer_::find_block_index(UltraCircuitBuilder& ultra_builder, const UltraBlock& block) { auto blocks_data = ultra_builder.blocks.get(); size_t index = 0; @@ -44,10 +45,9 @@ template size_t Graph_::find_block_index(UltraCircuitBuilder& * 5) Increments the gate count for each processed variable */ template -inline void Graph_::process_gate_variables(UltraCircuitBuilder& ultra_circuit_builder, - std::vector& gate_variables, - size_t gate_index, - size_t block_idx) +inline void StaticAnalyzer_::process_gate_variables(std::vector& gate_variables, + size_t gate_index, + size_t block_idx) { auto unique_variables = std::unique(gate_variables.begin(), gate_variables.end()); gate_variables.erase(unique_variables, gate_variables.end()); @@ -55,7 +55,6 @@ inline void Graph_::process_gate_variables(UltraCircuitBuilder& ultra_circui return; } for (auto& var_idx : gate_variables) { - var_idx = this->to_real(ultra_circuit_builder, var_idx); KeyPair key = std::make_pair(var_idx, block_idx); variable_gates[key].emplace_back(gate_index); } @@ -76,7 +75,7 @@ inline void Graph_::process_gate_variables(UltraCircuitBuilder& ultra_circui * and different arithmetic operations based on selector values */ template -inline std::vector> Graph_::get_arithmetic_gate_connected_component( +inline std::vector> StaticAnalyzer_::get_arithmetic_gate_connected_component( bb::UltraCircuitBuilder& ultra_circuit_builder, size_t index, size_t block_idx, UltraBlock& blk) { auto q_arith = blk.q_arith()[index]; @@ -100,7 +99,7 @@ inline std::vector> Graph_::get_arithmetic_gate_connec // this is fixed_witness gate. So, variable index contains in left wire. So, we have to take only it. fixed_variables.insert(this->to_real(ultra_circuit_builder, left_idx)); } else if (!q_m.is_zero() || q_1 != FF::one() || !q_2.is_zero() || !q_3.is_zero() || !q_4.is_zero()) { - // this is not the gate for fix_witness, so we have to process this gate + // this is not the gate for fix_witness, so we have to process this gate if (!q_m.is_zero()) { gate_variables.emplace_back(left_idx); gate_variables.emplace_back(right_idx); @@ -128,10 +127,11 @@ inline std::vector> Graph_::get_arithmetic_gate_connec } } if (q_arith == FF(3)) { - // In this gate mini gate is enabled, we have 2 equations: - // q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + 2 * w_4_omega = 0 - // w_1 + w_4 - w_1_omega + q_m = 0 - minigate_variables.insert(minigate_variables.end(), { left_idx, fourth_idx }); + // In this gate mini gate is enabled, we have 2 equations: + // q_1 * w_1 + q_2 * w_2 + q_3 * w_3 + q_4 * w_4 + q_c + 2 * w_4_omega = 0 + // w_1 + w_4 - w_1_omega + q_m = 0 + minigate_variables.emplace_back(left_idx); + minigate_variables.emplace_back(fourth_idx); if (index != blk.size() - 1) { gate_variables.emplace_back(blk.w_4()[index + 1]); minigate_variables.emplace_back(blk.w_l()[index + 1]); @@ -140,8 +140,8 @@ inline std::vector> Graph_::get_arithmetic_gate_connec } gate_variables = this->to_real(ultra_circuit_builder, gate_variables); minigate_variables = this->to_real(ultra_circuit_builder, minigate_variables); - this->process_gate_variables(ultra_circuit_builder, gate_variables, index, block_idx); - this->process_gate_variables(ultra_circuit_builder, minigate_variables, index, block_idx); + this->process_gate_variables(gate_variables, index, block_idx); + this->process_gate_variables(minigate_variables, index, block_idx); all_gates_variables.emplace_back(gate_variables); if (!minigate_variables.empty()) { all_gates_variables.emplace_back(minigate_variables); @@ -162,11 +162,12 @@ inline std::vector> Graph_::get_arithmetic_gate_connec * collecting variables from current and next gates as needed */ template -inline std::vector Graph_::get_elliptic_gate_connected_component( +inline std::vector StaticAnalyzer_::get_elliptic_gate_connected_component( bb::UltraCircuitBuilder& ultra_circuit_builder, size_t index, size_t block_idx, UltraBlock& blk) { - std::vector gate_variables = {}; + std::vector gate_variables; if (!blk.q_elliptic()[index].is_zero()) { + gate_variables.reserve(6); bool is_elliptic_add_gate = !blk.q_1()[index].is_zero() && blk.q_m()[index].is_zero(); bool is_elliptic_dbl_gate = blk.q_1()[index].is_zero() && blk.q_m()[index] == FF::one(); auto right_idx = blk.w_r()[index]; @@ -188,7 +189,7 @@ inline std::vector Graph_::get_elliptic_gate_connected_component( } } gate_variables = this->to_real(ultra_circuit_builder, gate_variables); - this->process_gate_variables(ultra_circuit_builder, gate_variables, index, block_idx); + this->process_gate_variables(gate_variables, index, block_idx); } return gate_variables; } @@ -205,19 +206,19 @@ inline std::vector Graph_::get_elliptic_gate_connected_component( * from the current gate */ template -inline std::vector Graph_::get_sort_constraint_connected_component( +inline std::vector StaticAnalyzer_::get_sort_constraint_connected_component( bb::UltraCircuitBuilder& ultra_circuit_builder, size_t index, size_t blk_idx, UltraBlock& block) { std::vector gate_variables = {}; if (!block.q_delta_range()[index].is_zero()) { - auto left_idx = block.w_l()[index]; - auto right_idx = block.w_r()[index]; - auto out_idx = block.w_o()[index]; - auto fourth_idx = block.w_4()[index]; - gate_variables.insert(gate_variables.end(), { left_idx, right_idx, out_idx, fourth_idx }); + gate_variables.reserve(4); + gate_variables.emplace_back(block.w_l()[index]); + gate_variables.emplace_back(block.w_r()[index]); + gate_variables.emplace_back(block.w_o()[index]); + gate_variables.emplace_back(block.w_4()[index]); } gate_variables = this->to_real(ultra_circuit_builder, gate_variables); - this->process_gate_variables(ultra_circuit_builder, gate_variables, index, blk_idx); + this->process_gate_variables(gate_variables, index, blk_idx); return gate_variables; } @@ -233,21 +234,19 @@ inline std::vector Graph_::get_sort_constraint_connected_component * including variables from the next gate when necessary */ template -inline std::vector Graph_::get_plookup_gate_connected_component( +inline std::vector StaticAnalyzer_::get_plookup_gate_connected_component( bb::UltraCircuitBuilder& ultra_circuit_builder, size_t index, size_t blk_idx, UltraBlock& block) { std::vector gate_variables; auto q_lookup_type = block.q_lookup_type()[index]; if (!q_lookup_type.is_zero()) { + gate_variables.reserve(6); auto q_2 = block.q_2()[index]; auto q_m = block.q_m()[index]; auto q_c = block.q_c()[index]; - auto left_idx = block.w_l()[index]; - auto right_idx = block.w_r()[index]; - auto out_idx = block.w_o()[index]; - gate_variables.emplace_back(left_idx); - gate_variables.emplace_back(right_idx); - gate_variables.emplace_back(out_idx); + gate_variables.emplace_back(block.w_l()[index]); + gate_variables.emplace_back(block.w_r()[index]); + gate_variables.emplace_back(block.w_o()[index]); if (index < block.size() - 1) { if (!q_2.is_zero()) { gate_variables.emplace_back(block.w_l()[index + 1]); @@ -260,7 +259,7 @@ inline std::vector Graph_::get_plookup_gate_connected_component( } } gate_variables = this->to_real(ultra_circuit_builder, gate_variables); - this->process_gate_variables(ultra_circuit_builder, gate_variables, index, blk_idx); + this->process_gate_variables(gate_variables, index, blk_idx); } return gate_variables; } @@ -275,22 +274,26 @@ inline std::vector Graph_::get_plookup_gate_connected_component( * @return std::vector vector of connected variables from the gate */ template -inline std::vector Graph_::get_poseido2s_gate_connected_component( +inline std::vector StaticAnalyzer_::get_poseido2s_gate_connected_component( bb::UltraCircuitBuilder& ultra_circuit_builder, size_t index, size_t blk_idx, UltraBlock& block) { std::vector gate_variables; auto internal_selector = block.q_poseidon2_internal()[index]; auto external_selector = block.q_poseidon2_external()[index]; if (!internal_selector.is_zero() || !external_selector.is_zero()) { - gate_variables.insert(gate_variables.end(), - { block.w_l()[index], block.w_r()[index], block.w_o()[index], block.w_4()[index] }); + gate_variables.reserve(8); + gate_variables.emplace_back(block.w_l()[index]); + gate_variables.emplace_back(block.w_r()[index]); + gate_variables.emplace_back(block.w_o()[index]); + gate_variables.emplace_back(block.w_4()[index]); if (index != block.size() - 1) { - gate_variables.insert( - gate_variables.end(), - { block.w_l()[index + 1], block.w_r()[index + 1], block.w_o()[index + 1], block.w_4()[index + 1] }); + gate_variables.emplace_back(block.w_l()[index + 1]); + gate_variables.emplace_back(block.w_r()[index + 1]); + gate_variables.emplace_back(block.w_o()[index + 1]); + gate_variables.emplace_back(block.w_4()[index + 1]); } gate_variables = this->to_real(ultra_circuit_builder, gate_variables); - this->process_gate_variables(ultra_circuit_builder, gate_variables, index, blk_idx); + this->process_gate_variables(gate_variables, index, blk_idx); } return gate_variables; } @@ -306,13 +309,12 @@ inline std::vector Graph_::get_poseido2s_gate_connected_component( * @return std::vector vector of connected variables from the gate */ template -inline std::vector Graph_::get_auxiliary_gate_connected_component(bb::UltraCircuitBuilder& ultra_builder, - size_t index, - size_t blk_idx, - UltraBlock& block) +inline std::vector StaticAnalyzer_::get_auxiliary_gate_connected_component( + bb::UltraCircuitBuilder& ultra_builder, size_t index, size_t blk_idx, UltraBlock& block) { std::vector gate_variables; if (!block.q_aux()[index].is_zero()) { + gate_variables.reserve(8); auto q_1 = block.q_1()[index]; auto q_2 = block.q_2()[index]; auto q_3 = block.q_3()[index]; @@ -330,7 +332,7 @@ inline std::vector Graph_::get_auxiliary_gate_connected_component( ASSERT(q_arith.is_zero()); if (index < block.size() - 1) { gate_variables.insert(gate_variables.end(), - { w_l, w_r, w_o, w_4, block.w_l()[index + 1], block.w_r()[index + 1] }); + { w_l, w_r, w_o, w_4, block.w_l()[index + 1], block.w_r()[index + 1] }); // 6 } } else if (q_3 == FF::one() && q_m == FF::one()) { ASSERT(q_arith.is_zero()); @@ -411,7 +413,8 @@ inline std::vector Graph_::get_auxiliary_gate_connected_component( } } } - this->process_gate_variables(ultra_builder, gate_variables, index, blk_idx); + gate_variables = this->to_real(ultra_builder, gate_variables); + this->process_gate_variables(gate_variables, index, blk_idx); return gate_variables; } @@ -423,7 +426,7 @@ inline std::vector Graph_::get_auxiliary_gate_connected_component( * @return std::vector vector of connected variables from ROM table gates */ template -inline std::vector Graph_::get_rom_table_connected_component( +inline std::vector StaticAnalyzer_::get_rom_table_connected_component( bb::UltraCircuitBuilder& ultra_builder, const UltraCircuitBuilder::RomTranscript& rom_array) { size_t block_index = find_block_index(ultra_builder, ultra_builder.blocks.aux); @@ -466,7 +469,7 @@ inline std::vector Graph_::get_rom_table_connected_component( gate_variables.emplace_back(record_witness); } gate_variables = this->to_real(ultra_builder, gate_variables); - this->process_gate_variables(ultra_builder, gate_variables, gate_index, block_index); + this->process_gate_variables(gate_variables, gate_index, block_index); // after process_gate_variables function gate_variables constists of real variables indexes, so we can add all // this variables in the final vector to connect all of them if (!gate_variables.empty()) { @@ -484,7 +487,7 @@ inline std::vector Graph_::get_rom_table_connected_component( * @return std::vector vector of connected variables from RAM table gates */ template -inline std::vector Graph_::get_ram_table_connected_component( +inline std::vector StaticAnalyzer_::get_ram_table_connected_component( bb::UltraCircuitBuilder& ultra_builder, const UltraCircuitBuilder::RamTranscript& ram_array) { size_t block_index = find_block_index(ultra_builder, ultra_builder.blocks.aux); @@ -521,7 +524,7 @@ inline std::vector Graph_::get_ram_table_connected_component( gate_variables.emplace_back(record_witness); } gate_variables = this->to_real(ultra_builder, gate_variables); - this->process_gate_variables(ultra_builder, gate_variables, gate_index, block_index); + this->process_gate_variables(gate_variables, gate_index, block_index); // after process_gate_variables function gate_variables constists of real variables indexes, so we can add all // these variables in the final vector to connect all of them ram_table_variables.insert(ram_table_variables.end(), gate_variables.begin(), gate_variables.end()); @@ -530,7 +533,7 @@ inline std::vector Graph_::get_ram_table_connected_component( } /** - * @brief Construct a new Graph from Ultra Circuit Builder + * @brief Construct a new StaticAnalyzer from Ultra Circuit Builder * @tparam FF field type used in the circuit * @param ultra_circuit_constructor circuit builder containing all gates and variables * @details This constructor initializes the graph structure by: @@ -548,7 +551,8 @@ inline std::vector Graph_::get_ram_table_connected_component( * 3) Creating connections between variables that appear in the same gate * 4) Special handling for sorted constraints in delta range blocks */ -template Graph_::Graph_(bb::UltraCircuitBuilder& ultra_circuit_constructor) +template +StaticAnalyzer_::StaticAnalyzer_(bb::UltraCircuitBuilder& ultra_circuit_constructor, bool connect_variables) { this->variables_gate_counts = std::unordered_map(ultra_circuit_constructor.real_variable_index.size()); @@ -571,23 +575,31 @@ template Graph_::Graph_(bb::UltraCircuitBuilder& ultra_circuit for (size_t gate_idx = 0; gate_idx < block_data[blk_idx].size(); gate_idx++) { auto arithmetic_gates_variables = get_arithmetic_gate_connected_component( ultra_circuit_constructor, gate_idx, blk_idx, block_data[blk_idx]); - if (!arithmetic_gates_variables.empty()) { + if (!arithmetic_gates_variables.empty() && connect_variables) { for (const auto& gate_variables : arithmetic_gates_variables) { connect_all_variables_in_vector(ultra_circuit_constructor, gate_variables); } } auto elliptic_gate_variables = get_elliptic_gate_connected_component( ultra_circuit_constructor, gate_idx, blk_idx, block_data[blk_idx]); - connect_all_variables_in_vector(ultra_circuit_constructor, elliptic_gate_variables); + if (connect_variables) { + connect_all_variables_in_vector(ultra_circuit_constructor, elliptic_gate_variables); + } auto lookup_gate_variables = get_plookup_gate_connected_component(ultra_circuit_constructor, gate_idx, blk_idx, block_data[blk_idx]); - connect_all_variables_in_vector(ultra_circuit_constructor, lookup_gate_variables); + if (connect_variables) { + connect_all_variables_in_vector(ultra_circuit_constructor, lookup_gate_variables); + } auto poseidon2_gate_variables = get_poseido2s_gate_connected_component( ultra_circuit_constructor, gate_idx, blk_idx, block_data[blk_idx]); - connect_all_variables_in_vector(ultra_circuit_constructor, poseidon2_gate_variables); + if (connect_variables) { + connect_all_variables_in_vector(ultra_circuit_constructor, poseidon2_gate_variables); + } auto aux_gate_variables = get_auxiliary_gate_connected_component( ultra_circuit_constructor, gate_idx, blk_idx, block_data[blk_idx]); - connect_all_variables_in_vector(ultra_circuit_constructor, aux_gate_variables); + if (connect_variables) { + connect_all_variables_in_vector(ultra_circuit_constructor, aux_gate_variables); + } if (arithmetic_gates_variables.empty() && elliptic_gate_variables.empty() && lookup_gate_variables.empty() && poseidon2_gate_variables.empty() && aux_gate_variables.empty()) { // if all vectors are empty it means that current block is delta range, and it needs another @@ -595,7 +607,9 @@ template Graph_::Graph_(bb::UltraCircuitBuilder& ultra_circuit auto delta_range_gate_variables = get_sort_constraint_connected_component( ultra_circuit_constructor, gate_idx, blk_idx, block_data[blk_idx]); if (delta_range_gate_variables.empty()) { - connect_all_variables_in_vector(ultra_circuit_constructor, sorted_variables); + if (connect_variables) { + connect_all_variables_in_vector(ultra_circuit_constructor, sorted_variables); + } sorted_variables.clear(); } else { sorted_variables.insert( @@ -610,7 +624,9 @@ template Graph_::Graph_(bb::UltraCircuitBuilder& ultra_circuit for (const auto& rom_array : rom_arrays) { std::vector variable_indices = this->get_rom_table_connected_component(ultra_circuit_constructor, rom_array); - this->connect_all_variables_in_vector(ultra_circuit_constructor, variable_indices); + if (connect_variables) { + this->connect_all_variables_in_vector(ultra_circuit_constructor, variable_indices); + } } } @@ -619,7 +635,9 @@ template Graph_::Graph_(bb::UltraCircuitBuilder& ultra_circuit for (const auto& ram_array : ram_arrays) { std::vector variable_indices = this->get_ram_table_connected_component(ultra_circuit_constructor, ram_array); - this->connect_all_variables_in_vector(ultra_circuit_constructor, variable_indices); + if (connect_variables) { + this->connect_all_variables_in_vector(ultra_circuit_constructor, variable_indices); + } } } } @@ -634,8 +652,8 @@ template Graph_::Graph_(bb::UltraCircuitBuilder& ultra_circuit */ template -bool Graph_::check_is_not_constant_variable(bb::UltraCircuitBuilder& ultra_circuit_builder, - const uint32_t& variable_index) +bool StaticAnalyzer_::check_is_not_constant_variable(bb::UltraCircuitBuilder& ultra_circuit_builder, + const uint32_t& variable_index) { bool is_not_constant = true; const auto& constant_variable_indices = ultra_circuit_builder.constant_variable_indices; @@ -660,8 +678,8 @@ bool Graph_::check_is_not_constant_variable(bb::UltraCircuitBuilder& ultra_c */ template -void Graph_::connect_all_variables_in_vector(bb::UltraCircuitBuilder& ultra_circuit_builder, - const std::vector& variables_vector) +void StaticAnalyzer_::connect_all_variables_in_vector(bb::UltraCircuitBuilder& ultra_circuit_builder, + const std::vector& variables_vector) { if (variables_vector.empty()) { return; @@ -695,7 +713,7 @@ void Graph_::connect_all_variables_in_vector(bb::UltraCircuitBuilder& ultra_ */ template -void Graph_::add_new_edge(const uint32_t& first_variable_index, const uint32_t& second_variable_index) +void StaticAnalyzer_::add_new_edge(const uint32_t& first_variable_index, const uint32_t& second_variable_index) { variable_adjacency_lists[first_variable_index].emplace_back(second_variable_index); variable_adjacency_lists[second_variable_index].emplace_back(first_variable_index); @@ -712,9 +730,9 @@ void Graph_::add_new_edge(const uint32_t& first_variable_index, const uint32 */ template -void Graph_::depth_first_search(const uint32_t& variable_index, - std::unordered_set& is_used, - std::vector& connected_component) +void StaticAnalyzer_::depth_first_search(const uint32_t& variable_index, + std::unordered_set& is_used, + std::vector& connected_component) { std::stack variable_stack; variable_stack.push(variable_index); @@ -738,7 +756,7 @@ void Graph_::depth_first_search(const uint32_t& variable_index, * indices */ -template std::vector> Graph_::find_connected_components() +template std::vector> StaticAnalyzer_::find_connected_components() { std::unordered_set is_used; std::vector> connected_components; @@ -771,9 +789,9 @@ template std::vector> Graph_::find_conne */ template -inline size_t Graph_::process_current_decompose_chain(bb::UltraCircuitBuilder& ultra_circuit_constructor, - std::unordered_set& variables_in_one_gate, - size_t index) +inline size_t StaticAnalyzer_::process_current_decompose_chain(bb::UltraCircuitBuilder& ultra_circuit_constructor, + std::unordered_set& variables_in_one_gate, + size_t index) { auto& arithmetic_block = ultra_circuit_constructor.blocks.arithmetic; auto zero_idx = ultra_circuit_constructor.zero_idx; @@ -827,9 +845,10 @@ inline size_t Graph_::process_current_decompose_chain(bb::UltraCircuitBuilde */ template -inline void Graph_::remove_unnecessary_decompose_variables(bb::UltraCircuitBuilder& ultra_circuit_builder, - std::unordered_set& variables_in_one_gate, - const std::unordered_set& decompose_variables) +inline void StaticAnalyzer_::remove_unnecessary_decompose_variables( + bb::UltraCircuitBuilder& ultra_circuit_builder, + std::unordered_set& variables_in_one_gate, + const std::unordered_set& decompose_variables) { auto is_power_two = [&](const uint256_t& number) { return number > 0 && ((number & (number - 1)) == 0); }; auto find_position = [&](uint32_t variable_index) { @@ -878,7 +897,7 @@ inline void Graph_::remove_unnecessary_decompose_variables(bb::UltraCircuitB * 2) Variables from range_constraints created by range_constraint_into_two_limbs */ template -void Graph_::remove_unnecessary_range_constrains_variables(bb::UltraCircuitBuilder& ultra_builder) +void StaticAnalyzer_::remove_unnecessary_range_constrains_variables(bb::UltraCircuitBuilder& ultra_builder) { std::map range_lists = ultra_builder.range_lists; std::unordered_set range_lists_tau_tags; @@ -917,10 +936,11 @@ void Graph_::remove_unnecessary_range_constrains_variables(bb::UltraCircuitB * @param gate_index */ template -inline void Graph_::remove_unnecessary_aes_plookup_variables(std::unordered_set& variables_in_one_gate, - UltraCircuitBuilder& ultra_circuit_builder, - BasicTableId& table_id, - size_t gate_index) +inline void StaticAnalyzer_::remove_unnecessary_aes_plookup_variables( + std::unordered_set& variables_in_one_gate, + UltraCircuitBuilder& ultra_circuit_builder, + BasicTableId& table_id, + size_t gate_index) { auto find_position = [&](uint32_t real_variable_index) { @@ -958,10 +978,11 @@ inline void Graph_::remove_unnecessary_aes_plookup_variables(std::unordered_ */ template -inline void Graph_::remove_unnecessary_sha256_plookup_variables(std::unordered_set& variables_in_one_gate, - UltraCircuitBuilder& ultra_circuit_builder, - BasicTableId& table_id, - size_t gate_index) +inline void StaticAnalyzer_::remove_unnecessary_sha256_plookup_variables( + std::unordered_set& variables_in_one_gate, + UltraCircuitBuilder& ultra_circuit_builder, + BasicTableId& table_id, + size_t gate_index) { auto find_position = [&](uint32_t real_variable_index) { @@ -1013,7 +1034,8 @@ inline void Graph_::remove_unnecessary_sha256_plookup_variables(std::unorder */ template -inline void Graph_::process_current_plookup_gate(bb::UltraCircuitBuilder& ultra_circuit_builder, size_t gate_index) +inline void StaticAnalyzer_::process_current_plookup_gate(bb::UltraCircuitBuilder& ultra_circuit_builder, + size_t gate_index) { auto find_position = [&](uint32_t real_variable_index) { return variables_in_one_gate.contains(real_variable_index); @@ -1069,7 +1091,7 @@ inline void Graph_::process_current_plookup_gate(bb::UltraCircuitBuilder& ul */ template -inline void Graph_::remove_unnecessary_plookup_variables(bb::UltraCircuitBuilder& ultra_circuit_builder) +inline void StaticAnalyzer_::remove_unnecessary_plookup_variables(bb::UltraCircuitBuilder& ultra_circuit_builder) { auto& lookup_block = ultra_circuit_builder.blocks.lookup; if (lookup_block.size() > 0) { @@ -1087,7 +1109,8 @@ inline void Graph_::remove_unnecessary_plookup_variables(bb::UltraCircuitBui * @param ultra_builder */ -template inline void Graph_::remove_record_witness_variables(bb::UltraCircuitBuilder& ultra_builder) +template +inline void StaticAnalyzer_::remove_record_witness_variables(bb::UltraCircuitBuilder& ultra_builder) { auto block_data = ultra_builder.blocks.get(); size_t blk_idx = find_block_index(ultra_builder, ultra_builder.blocks.aux); @@ -1129,7 +1152,8 @@ template inline void Graph_::remove_record_witness_variables(b */ template -std::unordered_set Graph_::show_variables_in_one_gate(bb::UltraCircuitBuilder& ultra_circuit_builder) +std::unordered_set StaticAnalyzer_::show_variables_in_one_gate( + bb::UltraCircuitBuilder& ultra_circuit_builder) { for (const auto& pair : variables_gate_counts) { bool is_not_constant_variable = this->check_is_not_constant_variable(ultra_circuit_builder, pair.first); @@ -1190,7 +1214,7 @@ std::pair, size_t> get_connected_component_with_index( * @tparam FF */ -template void Graph_::print_graph() +template void StaticAnalyzer_::print_graph() { for (const auto& elem : variable_adjacency_lists) { info("variable with index ", elem.first); @@ -1209,7 +1233,7 @@ template void Graph_::print_graph() * @tparam FF */ -template void Graph_::print_connected_components() +template void StaticAnalyzer_::print_connected_components() { auto connected_components = find_connected_components(); for (size_t i = 0; i < connected_components.size(); i++) { @@ -1225,7 +1249,7 @@ template void Graph_::print_connected_components() * @tparam FF */ -template void Graph_::print_variables_gate_counts() +template void StaticAnalyzer_::print_variables_gate_counts() { for (const auto& it : variables_gate_counts) { info("number of gates with variables ", it.first, " == ", it.second); @@ -1240,7 +1264,7 @@ template void Graph_::print_variables_gate_counts() */ template -void Graph_::print_variable_in_one_gate(bb::UltraCircuitBuilder& ultra_builder, const uint32_t real_idx) +void StaticAnalyzer_::print_variable_in_one_gate(bb::UltraCircuitBuilder& ultra_builder, const uint32_t real_idx) { const auto& block_data = ultra_builder.blocks.get(); for (const auto& [key, gates] : variable_gates) { @@ -1248,7 +1272,6 @@ void Graph_::print_variable_in_one_gate(bb::UltraCircuitBuilder& ultra_build ASSERT(gates.size() == 1); size_t gate_index = gates[0]; UltraBlock block = block_data[key.second]; - info("gate index == ", gate_index); info("---- printing variables in this gate"); info("w_l == ", block.w_l()[gate_index], @@ -1259,24 +1282,63 @@ void Graph_::print_variable_in_one_gate(bb::UltraCircuitBuilder& ultra_build " w_4 == ", block.w_4()[gate_index]); info("---- printing gate selectors where variable with index ", key.first, " was found ----"); - info("q_m == ", block.q_m()[gate_index]); - info("q_c == ", block.q_c()[gate_index]); - info("q_1 == ", block.q_1()[gate_index]); - info("q_2 == ", block.q_2()[gate_index]); - info("q_3 == ", block.q_3()[gate_index]); - info("q_4 == ", block.q_4()[gate_index]); - info("q_arith == ", block.q_arith()[gate_index]); - info("q_delta_range == ", block.q_delta_range()[gate_index]); - info("q_elliptic == ", block.q_elliptic()[gate_index]); - info("q_aux == ", block.q_aux()[gate_index]); - info("q_lookup_type == ", block.q_lookup_type()[gate_index]); - info("q_poseidon2_external == ", block.q_poseidon2_external()[gate_index]); - info("q_poseidon2_internal == ", block.q_poseidon2_internal()[gate_index]); + auto q_m = block.q_m()[gate_index]; + if (!q_m.is_zero()) { + info("q_m == ", q_m); + } + auto q_1 = block.q_1()[gate_index]; + if (!q_1.is_zero()) { + info("q1 == ", q_1); + } + auto q_2 = block.q_2()[gate_index]; + if (!q_2.is_zero()) { + info("q2 == ", q_2); + } + auto q_3 = block.q_3()[gate_index]; + if (!q_3.is_zero()) { + info("q3 == ", q_3); + } + auto q_4 = block.q_4()[gate_index]; + if (!q_4.is_zero()) { + info("q4 == ", q_4); + } + auto q_c = block.q_c()[gate_index]; + if (!q_c.is_zero()) { + info("q_c == ", q_c); + } + auto q_arith = block.q_arith()[gate_index]; + if (!q_arith.is_zero()) { + info("q_arith == ", q_arith); + } + auto q_delta_range = block.q_delta_range()[gate_index]; + if (!q_delta_range.is_zero()) { + info("q_delta_range == ", q_delta_range); + } + auto q_elliptic = block.q_elliptic()[gate_index]; + if (!q_elliptic.is_zero()) { + info("q_elliptic == ", q_elliptic); + } + auto q_aux = block.q_aux()[gate_index]; + if (!q_aux.is_zero()) { + info("q_aux == ", q_aux); + } + auto q_lookup_type = block.q_lookup_type()[gate_index]; + if (!q_lookup_type.is_zero()) { + info("q_lookup_type == ", q_lookup_type); + } + auto q_poseidon2_external = block.q_poseidon2_external()[gate_index]; + if (!q_poseidon2_external.is_zero()) { + info("q_poseidon2_external == ", q_poseidon2_external); + } + auto q_poseidon2_internal = block.q_poseidon2_internal()[gate_index]; + if (!q_poseidon2_internal.is_zero()) { + info("q_poseidon2_internal == ", q_poseidon2_internal); + } info("---- finished printing ----"); } } } -template class Graph_; +template class StaticAnalyzer_; } // namespace cdg diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.hpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.hpp index 59e44b3e636f..e41404645f98 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.hpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph.hpp @@ -57,14 +57,14 @@ struct KeyEquals { * variable wasn't constrained properly. If the number of connected components > 1, it means that there were some missed * connections between variables. */ -template class Graph_ { +template class StaticAnalyzer_ { public: - Graph_() = default; - Graph_(const Graph_& other) = delete; - Graph_(Graph_&& other) = delete; - Graph_& operator=(const Graph_& other) = delete; - Graph_&& operator=(Graph_&& other) = delete; - Graph_(bb::UltraCircuitBuilder& ultra_circuit_constructor); + StaticAnalyzer_() = default; + StaticAnalyzer_(const StaticAnalyzer_& other) = delete; + StaticAnalyzer_(StaticAnalyzer_&& other) = delete; + StaticAnalyzer_& operator=(const StaticAnalyzer_& other) = delete; + StaticAnalyzer_&& operator=(StaticAnalyzer_&& other) = delete; + StaticAnalyzer_(bb::UltraCircuitBuilder& ultra_circuit_constructor, bool connect_variables = true); /** * @brief Convert a vector of variable indices to their real indices @@ -88,10 +88,7 @@ template class Graph_ { return ultra_circuit_constructor.real_variable_index[variable_index]; }; size_t find_block_index(bb::UltraCircuitBuilder& ultra_builder, const UltraBlock& block); - void process_gate_variables(bb::UltraCircuitBuilder& ultra_circuit_constructor, - std::vector& gate_variables, - size_t gate_index, - size_t blk_idx); + void process_gate_variables(std::vector& gate_variables, size_t gate_index, size_t blk_idx); std::unordered_map get_variables_gate_counts() { return this->variables_gate_counts; }; std::vector> get_arithmetic_gate_connected_component( @@ -180,7 +177,7 @@ template class Graph_ { void print_variables_gate_counts(); void print_variables_edge_counts(); void print_variable_in_one_gate(bb::UltraCircuitBuilder& ultra_builder, const uint32_t real_idx); - ~Graph_() = default; + ~StaticAnalyzer_() = default; private: std::unordered_map> @@ -197,6 +194,6 @@ template class Graph_ { std::unordered_set fixed_variables; }; -using Graph = Graph_; +using StaticAnalyzer = StaticAnalyzer_; } // namespace cdg diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description.test.cpp index e2234cae86d3..5419442758bf 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description.test.cpp @@ -39,7 +39,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_arithmetic_gates) } } - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto variables_in_one_gate = graph.show_variables_in_one_gate(circuit_constructor); EXPECT_EQ(variables_in_one_gate.size(), 1024); @@ -71,7 +71,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_arithmetic_gates_with_s } } - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto num_connected_components = connected_components.size(); bool result = num_connected_components == 1; @@ -96,7 +96,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_boolean_gates) circuit_constructor.create_bool_gate(a_idx); } - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto num_connected_components = connected_components.size(); auto variables_in_one_gate = graph.show_variables_in_one_gate(circuit_constructor); @@ -133,7 +133,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_add_gate) circuit_constructor.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, 1 }); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto num_connected_components = connected_components.size(); bool result = num_connected_components == 1; @@ -164,7 +164,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_double_gate) circuit_constructor.create_ecc_dbl_gate({ x1, y1, x3, y3 }); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto num_connected_components = connected_components.size(); bool result = num_connected_components == 1; @@ -221,7 +221,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_together) uint32_t y8 = circuit_constructor.add_variable(p8.y); circuit_constructor.create_ecc_dbl_gate({ x7, y7, x8, y8 }); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto num_connected_components = connected_components.size(); bool result = num_connected_components == 2; @@ -261,7 +261,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_sort_constraints) auto h_idx = circuit_constructor.add_variable(h); circuit_constructor.create_sort_constraint({ e_idx, f_idx, g_idx, h_idx }); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components[0].size(), 4); EXPECT_EQ(connected_components[1].size(), 4); @@ -320,7 +320,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_sort_constraints_with_e circuit_constructor.create_sort_constraint_with_edges( { a1_idx, b1_idx, c1_idx, d1_idx, e1_idx, f1_idx, g1_idx, h1_idx }, a1, h1); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto num_connected_components = connected_components.size(); bool result = num_connected_components == 2; @@ -351,7 +351,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_with_plookup_accumulators) EXPECT_EQ(num_lookups, lookup_witnesses[plookup::ColumnIdx::C1].size()); - Graph graph = Graph(circuit_builder); + StaticAnalyzer graph = StaticAnalyzer(circuit_builder); auto connected_components = graph.find_connected_components(); auto num_connected_components = connected_components.size(); bool result = num_connected_components == 1; @@ -384,7 +384,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_arithm } } - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto variables_gate_counts = graph.get_variables_gate_counts(); bool result = true; for (const auto pair : variables_gate_counts) { @@ -420,7 +420,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_arithm } } - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); bool result = true; auto variables_gate_counts = graph.get_variables_gate_counts(); for (const auto& pair : variables_gate_counts) { @@ -450,7 +450,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_boolea circuit_constructor.create_bool_gate(a_idx); } - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto variables_gate_counts = graph.get_variables_gate_counts(); bool result = true; for (const auto& part : variables_gate_counts) { @@ -490,7 +490,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_sorted auto h_idx = circuit_constructor.add_variable(h); circuit_constructor.create_sort_constraint({ e_idx, f_idx, g_idx, h_idx }); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto variables_gate_counts = graph.get_variables_gate_counts(); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 2); @@ -555,7 +555,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_sorted circuit_constructor.create_sort_constraint_with_edges( { a1_idx, b1_idx, c1_idx, d1_idx, e1_idx, f1_idx, g1_idx, h1_idx }, a1, h1); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); auto variables_gate_counts = graph.get_variables_gate_counts(); bool result = true; @@ -597,7 +597,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_ecc_ad circuit_constructor.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, 1 }); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto variables_gate_counts = graph.get_variables_gate_counts(); auto connected_components = graph.find_connected_components(); bool result = (variables_gate_counts[connected_components[0][0]] == 1) && @@ -634,7 +634,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_ecc_db circuit_constructor.create_ecc_dbl_gate({ x1, y1, x3, y3 }); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto variables_gate_counts = graph.get_variables_gate_counts(); auto connected_components = graph.find_connected_components(); @@ -671,7 +671,7 @@ TEST(boomerang_ultra_circuit_constructor, test_graph_for_range_constraints) circuit_constructor.create_new_range_constraint(indices[i], 5); } circuit_constructor.create_sort_constraint(indices); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); } @@ -694,7 +694,7 @@ TEST(boomerang_ultra_circuit_constructor, composed_range_constraint) { a_idx, circuit_constructor.zero_idx, circuit_constructor.zero_idx, 1, 0, 0, -fr(e) }); circuit_constructor.decompose_into_default_range(a_idx, 134); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_aes128.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_aes128.test.cpp index de25c3fe6905..49321788a779 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_aes128.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_aes128.test.cpp @@ -78,7 +78,7 @@ TEST(boomerang_stdlib_aes, test_graph_for_aes_64_bytes) auto result = stdlib::aes128::encrypt_buffer_cbc(in_field, iv_field, key_field); fix_vector_witness(result); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -132,7 +132,7 @@ TEST(boomerang_stdlib_aes, test_variable_gates_count_for_aes128cbc) auto result = stdlib::aes128::encrypt_buffer_cbc(in_field, iv_field, key_field); fix_vector_witness(result); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); std::unordered_set variables_in_one_gate = graph.show_variables_in_one_gate(builder); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp index 16f847f67e83..e13d3d598b11 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp @@ -67,7 +67,7 @@ TEST(boomerang_bigfield, test_graph_description_bigfield_constructors) [[maybe_unused]] fq_ct mixed = fq_ct(1).add_to_lower_limb(small_var, 1); [[maybe_unused]] fq_ct r; - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -98,7 +98,7 @@ TEST(boomerang_bigfield, test_graph_description_bigfield_addition) r2 = r + var; fix_bigfield_element(r2); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -130,7 +130,7 @@ TEST(boomerang_bigfield, test_graph_description_bigfield_substraction) r = var - mixed; fix_bigfield_element(r); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -161,7 +161,7 @@ TEST(boomerang_bigfield, test_graph_description_bigfield_multiplication) r = mixed * var; r = mixed * constant; r = mixed * mixed; - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -195,7 +195,7 @@ TEST(boomerang_bigfield, test_graph_description_bigfield_division) fix_bigfield_element(r); CircuitChecker::check(builder); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -248,7 +248,7 @@ TEST(boomerang_bigfield, test_graph_description_bigfield_mix_operations) fix_bigfield_element(r); r = mixed * constant; fix_bigfield_element(r); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -276,7 +276,7 @@ TEST(boomerang_bigfield, test_graph_description_constructor_high_low_bits_and_op witness_ct(&builder, fr(uint256_t(d).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); c = c + d1; fix_bigfield_element(c); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -300,7 +300,7 @@ TEST(boomerang_bigfield, test_graph_description_mul_function) witness_ct(&builder, fr(uint256_t(inputs[1]).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); fq_ct c = a * b; fix_bigfield_element(c); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -322,7 +322,7 @@ TEST(boomerang_bigfield, test_graph_description_sqr_function) witness_ct(&builder, fr(uint256_t(input).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); fq_ct c = a.sqr(); fix_bigfield_element(c); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -348,7 +348,7 @@ TEST(boomerang_bigfield, test_graph_description_madd_function) witness_ct(&builder, fr(uint256_t(inputs[2]).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); fq_ct d = a.madd(b, { c }); fix_bigfield_element(d); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -388,7 +388,7 @@ TEST(boomerang_bigfield, test_graph_description_mult_madd_function) fq_ct f = fq_ct::mult_madd(mul_left, mul_right, to_add); fix_bigfield_element(f); builder.finalize_circuit(false); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); EXPECT_EQ(variables_in_one_gate.size(), 0); } @@ -413,7 +413,7 @@ TEST(boomerang_bigfield, test_graph_description_constructor_high_low_bits) fq_ct product = mul_left * mul_right; fix_bigfield_element(product); builder.finalize_circuit(false); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); EXPECT_EQ(variables_in_one_gate.size(), 0); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake2s.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake2s.test.cpp index b25381f4ab7f..51ec1d9ed0f0 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake2s.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake2s.test.cpp @@ -34,7 +34,7 @@ TEST(boomerang_stdlib_blake2s, graph_description_single_block_plookup) byte_array_ct input_arr(&builder, input_v); byte_array_ct output = stdlib::blake2s(input_arr); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -63,7 +63,7 @@ TEST(boomerang_stdlib_blake2s, graph_description_double_block_plookup) EXPECT_EQ(output.get_value(), std::vector(expected.begin(), expected.end())); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake3s.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake3s.test.cpp index 3fdc5d33632b..569efea4755c 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake3s.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_blake3s.test.cpp @@ -36,7 +36,7 @@ TEST(boomerang_stdlib_blake3s, test_single_block_plookup) byte_array_plookup input_arr(&builder, input_v); byte_array_plookup output = stdlib::blake3s(input_arr); std::vector expected = blake3::blake3s(input_v); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -60,7 +60,7 @@ TEST(boomerang_stdlib_blake3s, test_double_block_plookup) std::vector expected = blake3::blake3s(input_v); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_dynamic_array.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_dynamic_array.test.cpp index a8767b90397f..1ad87624e0f0 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_dynamic_array.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_dynamic_array.test.cpp @@ -41,7 +41,7 @@ TEST(boomerang_stdlib_dynamic_array, graph_description_dynamic_array_method_resi } array.resize(next_size, 7); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); EXPECT_EQ(connected_components.size(), 1); @@ -80,7 +80,7 @@ TEST(boomerang_stdlib_dynamic_array, graph_description_dynamic_array_consistency array.conditional_push(true, 100); array.conditional_pop(false); array.conditional_pop(true); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_goblin.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_goblin.test.cpp new file mode 100644 index 000000000000..126b893600a0 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_goblin.test.cpp @@ -0,0 +1,94 @@ +#include "barretenberg/boomerang_value_detection/graph.hpp" +#include "barretenberg/circuit_checker/circuit_checker.hpp" +#include "barretenberg/common/test.hpp" + +#include "barretenberg/goblin/goblin.hpp" +#include "barretenberg/goblin/mock_circuits.hpp" +#include "barretenberg/srs/global_crs.hpp" +#include "barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp" +#include "barretenberg/stdlib/honk_verifier/ultra_verification_keys_comparator.hpp" +#include "barretenberg/ultra_honk/ultra_prover.hpp" +#include "barretenberg/ultra_honk/ultra_verifier.hpp" + +namespace bb::stdlib::recursion::honk { +class BoomerangGoblinRecursiveVerifierTests : public testing::Test { + public: + using Builder = GoblinRecursiveVerifier::Builder; + using ECCVMVK = Goblin::ECCVMVerificationKey; + using TranslatorVK = Goblin::TranslatorVerificationKey; + + using OuterFlavor = UltraFlavor; + using OuterProver = UltraProver_; + using OuterVerifier = UltraVerifier_; + using OuterDeciderProvingKey = DeciderProvingKey_; + + static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } + + struct ProverOutput { + GoblinProof proof; + Goblin::VerificationKey verfier_input; + }; + + /** + * @brief Create a goblin proof and the VM verification keys needed by the goblin recursive verifier + * + * @return ProverOutput + */ + static ProverOutput create_goblin_prover_output(const size_t NUM_CIRCUITS = 3) + { + Goblin goblin; + // Construct and accumulate multiple circuits + for (size_t idx = 0; idx < NUM_CIRCUITS - 1; ++idx) { + MegaCircuitBuilder builder{ goblin.op_queue }; + GoblinMockCircuits::construct_simple_circuit(builder); + goblin.prove_merge(); + } + + auto goblin_transcript = std::make_shared(); + + Goblin goblin_final; + goblin_final.op_queue = goblin.op_queue; + MegaCircuitBuilder builder{ goblin_final.op_queue }; + builder.queue_ecc_no_op(); + GoblinMockCircuits::construct_simple_circuit(builder); + + // Output is a goblin proof plus ECCVM/Translator verification keys + return { goblin_final.prove(), { std::make_shared(), std::make_shared() } }; + } +}; + +/** + * @brief Construct and check a goblin recursive verification circuit + * + */ +TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic) +{ + auto [proof, verifier_input] = create_goblin_prover_output(); + + Builder builder; + GoblinRecursiveVerifier verifier{ &builder, verifier_input }; + GoblinRecursiveVerifierOutput output = verifier.verify(proof); + output.points_accumulator.set_public(); + // Construct and verify a proof for the Goblin Recursive Verifier circuit + { + auto proving_key = std::make_shared(builder); + auto verification_key = std::make_shared(proving_key->proving_key); + OuterProver prover(proving_key, verification_key); + OuterVerifier verifier(verification_key); + auto proof = prover.construct_proof(); + bool verified = verifier.verify_proof(proof); + + ASSERT(verified); + } + auto translator_pairing_points = output.points_accumulator; + translator_pairing_points.P0.x.fix_witness(); + translator_pairing_points.P0.y.fix_witness(); + translator_pairing_points.P1.x.fix_witness(); + translator_pairing_points.P1.y.fix_witness(); + info("Recursive Verifier: num gates = ", builder.num_gates); + auto graph = cdg::StaticAnalyzer(builder, false); + auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); + EXPECT_EQ(variables_in_one_gate.size(), 0); +} + +} // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_poseidon2s_permutation.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_poseidon2s_permutation.test.cpp index 0df624b3fca3..d660f103591a 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_poseidon2s_permutation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_poseidon2s_permutation.test.cpp @@ -71,7 +71,7 @@ void test_poseidon2s_circuit(size_t num_inputs = 5) elem.fix_witness(); } [[maybe_unused]] auto result = stdlib::poseidon2::hash(builder, inputs); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -102,7 +102,7 @@ void test_poseidon2s_hash_byte_array(size_t num_inputs = 5) byte_array_ct circuit_input(&builder, input); auto result = stdlib::poseidon2::hash_buffer(builder, circuit_input); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -142,7 +142,7 @@ void test_poseidon2s_hash_repeated_pairs(size_t num_inputs = 5) } left.fix_witness(); - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -173,7 +173,7 @@ TEST(boomerang_poseidon2s, test_graph_for_poseidon2s_one_permutation) elem.fix_witness(); } - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -209,7 +209,7 @@ TEST(boomerang_poseidon2s, test_graph_for_poseidon2s_two_permutations) for (auto& elem : state2) { elem.fix_witness(); } - auto graph = Graph(builder); + auto graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 2); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ram_rom.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ram_rom.test.cpp index 1abdb9cc74b4..a6e981b0ed09 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ram_rom.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ram_rom.test.cpp @@ -49,7 +49,7 @@ TEST(boomerang_rom_ram_table, graph_description_rom_table) } result.fix_witness(); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -91,7 +91,7 @@ TEST(boomerang_rom_ram_table, graph_description_ram_table_read) } result.fix_witness(); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -164,7 +164,7 @@ TEST(boomerang_rom_ram_table, graph_description_ram_table_write) update(); result.fix_witness(); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_sha256.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_sha256.test.cpp index 2d8a2f264ef8..c8b44b02c0e4 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_sha256.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_sha256.test.cpp @@ -63,7 +63,7 @@ TEST(boomerang_stdlib_sha256, test_graph_for_sha256_55_bytes) std::vector output = output_bits.to_unverified_byte_slices(4); fix_vector(output); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -106,7 +106,7 @@ HEAVY_TEST(boomerang_stdlib_sha256, test_graph_for_sha256_NIST_vector_five) std::vector output = output_bits.to_unverified_byte_slices(4); fix_vector(output); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); auto variables_in_one_gate = graph.show_variables_in_one_gate(builder); EXPECT_EQ(variables_in_one_gate.size(), 0); @@ -130,7 +130,7 @@ TEST(boomerang_stdlib_sha256, test_graph_for_sha256_NIST_vector_one) fix_byte_array(input); packed_byte_array_pt output_bits = stdlib::sha256(input); fix_byte_array(output_bits); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); std::unordered_set variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -150,7 +150,7 @@ TEST(boomerang_stdlib_sha256, test_graph_for_sha256_NIST_vector_two) fix_byte_array(input); packed_byte_array_pt output_bits = stdlib::sha256(input); fix_byte_array(output_bits); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); std::unordered_set variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -172,7 +172,7 @@ TEST(boomerang_stdlib_sha256, test_graph_for_sha256_NIST_vector_three) fix_byte_array(input); packed_byte_array_pt output_bits = stdlib::sha256(input); fix_byte_array(output_bits); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); std::unordered_set variables_in_one_gate = graph.show_variables_in_one_gate(builder); @@ -194,7 +194,7 @@ TEST(boomerang_stdlib_sha256, test_graph_for_sha256_NIST_vector_four) fix_byte_array(input); packed_byte_array_pt output_bits = stdlib::sha256(input); fix_byte_array(output_bits); - Graph graph = Graph(builder); + StaticAnalyzer graph = StaticAnalyzer(builder); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 1); std::unordered_set variables_in_one_gate = graph.show_variables_in_one_gate(builder); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ultra_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ultra_recursive_verifier.test.cpp index d17c67de38bd..1b52b4959ab7 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ultra_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ultra_recursive_verifier.test.cpp @@ -128,7 +128,7 @@ template class BoomerangRecursiveVerifierTest : publi EXPECT_EQ(outer_circuit.failed(), false) << outer_circuit.err(); outer_circuit.finalize_circuit(false); - auto graph = cdg::Graph(outer_circuit); + auto graph = cdg::StaticAnalyzer(outer_circuit); auto connected_components = graph.find_connected_components(); EXPECT_EQ(connected_components.size(), 4); info("Connected components: ", connected_components.size()); diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/variable_gates_count.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/variable_gates_count.test.cpp index 066b8f03e974..91e77c30e146 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/variable_gates_count.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/variable_gates_count.test.cpp @@ -23,7 +23,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variable_gates_count_for_decompos { a_idx, circuit_constructor.zero_idx, circuit_constructor.zero_idx, 1, 0, 0, -fr(e) }); circuit_constructor.decompose_into_default_range(a_idx, 134); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); std::unordered_set variables_in_on_gate = graph.show_variables_in_one_gate(circuit_constructor); EXPECT_EQ(variables_in_on_gate.size(), 0); } @@ -39,7 +39,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variable_gates_count_for_decompos { a_idx, circuit_constructor.zero_idx, circuit_constructor.zero_idx, 1, 0, 0, -fr(e) }); circuit_constructor.decompose_into_default_range(a_idx, 42); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); auto variables_in_on_gate = graph.show_variables_in_one_gate(circuit_constructor); EXPECT_EQ(variables_in_on_gate.size(), 0); } @@ -84,7 +84,7 @@ TEST(boomerang_ultra_circuit_constructor, test_variable_gates_count_for_two_deco circuit_constructor.decompose_into_default_range(a1_idx, 42); circuit_constructor.decompose_into_default_range(a2_idx, 42); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); std::unordered_set variables_in_one_gate = graph.show_variables_in_one_gate(circuit_constructor); EXPECT_EQ(variables_in_one_gate.size(), 0); } @@ -109,7 +109,7 @@ TEST(boomerang_ultra_circuit_constructor, test_decompose_with_boolean_gates) circuit_constructor.create_bool_gate(a_idx); } - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); std::unordered_set variables_in_one_gate = graph.show_variables_in_one_gate(circuit_constructor); EXPECT_EQ(variables_in_one_gate.size(), 22); } @@ -125,7 +125,7 @@ TEST(boomerang_ultra_circuit_constructor, test_decompose_for_6_bit_number) { a_idx, circuit_constructor.zero_idx, circuit_constructor.zero_idx, 1, 0, 0, -fr(e) }); circuit_constructor.decompose_into_default_range(a_idx, 6); - Graph graph = Graph(circuit_constructor); + StaticAnalyzer graph = StaticAnalyzer(circuit_constructor); std::unordered_set variables_in_on_gate = graph.show_variables_in_one_gate(circuit_constructor); EXPECT_EQ(variables_in_on_gate.size(), 0); } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/claim_batcher.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/claim_batcher.hpp index 0ad27b9528db..9ffc22634370 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/claim_batcher.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/claim_batcher.hpp @@ -121,8 +121,11 @@ template struct ClaimBatcher_ { for (size_t i = 0; i < get_groups_to_be_interleaved_size(); i++) { interleaved->scalars_pos.push_back(r_shift_pos); interleaved->scalars_neg.push_back(r_shift_neg); - r_shift_pos *= r_challenge; - r_shift_neg *= (-r_challenge); + if (i < get_groups_to_be_interleaved_size() - 1) { + // to avoid unnecessary multiplication gates in a circuit + r_shift_pos *= r_challenge; + r_shift_neg *= (-r_challenge); + } } } } @@ -178,18 +181,20 @@ template struct ClaimBatcher_ { } size_t group_idx = 0; - for (auto group : interleaved->commitments_groups) { + for (size_t j = 0; j < interleaved->commitments_groups.size(); j++) { for (size_t i = 0; i < get_groups_to_be_interleaved_size(); i++) { // The j-th commitment in group i is multiplied by ρ^{k+m+i} and ν^{n+1} \cdot r^j + ν^{n+2} ⋅(-r)^j // where k is the number of unshifted, m is number of shifted and n is the log_circuit_size // (assuming to right-shifted-by-k commitments in this example) - commitments.emplace_back(std::move(group[i])); + commitments.emplace_back(std::move(interleaved->commitments_groups[j][i])); scalars.emplace_back(-rho_power * interleaved->shplonk_denominator * (shplonk_batching_pos * interleaved->scalars_pos[i] + shplonk_batching_neg * interleaved->scalars_neg[i])); } batched_evaluation += interleaved->evaluations[group_idx] * rho_power; - rho_power *= rho; + if (j != interleaved->commitments_groups.size() - 1) { + rho_power *= rho; + } group_idx++; } } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.hpp index 47e300b381c4..9667e2e451f2 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.hpp @@ -373,7 +373,13 @@ template class SmallSubgroupIPAVerifier { static std::array compute_batched_barycentric_evaluations( const std::vector& coeffs, const FF& r, const FF& vanishing_poly_eval) { - FF one = FF{ 1 }; + FF one{ 1 }; + FF zero{ 0 }; + if constexpr (Curve::is_stdlib_type) { + auto builder = r.get_context(); + one.convert_constant_to_fixed_witness(builder); + zero.convert_constant_to_fixed_witness(builder); + } // Construct the denominators of the Lagrange polynomials evaluated // at r @@ -396,7 +402,7 @@ template class SmallSubgroupIPAVerifier { // Lagrange last evaluated at r FF numerator = vanishing_poly_eval * FF(SUBGROUP_SIZE).invert(); // (r^n - 1) / n std::array result{ - std::inner_product(coeffs.begin(), coeffs.end(), denominators.begin(), FF(0)), + std::inner_product(coeffs.begin(), coeffs.end(), denominators.begin(), zero), denominators[0], denominators[SUBGROUP_SIZE - 1] }; @@ -427,24 +433,40 @@ template static std::vector compute_challenge_polynomial_coeffs( const std::vector& multivariate_challenge) { - using FF = typename Curve::ScalarField; + using FF = typename Curve::ScalarField; std::vector challenge_polynomial_lagrange(Curve::SUBGROUP_SIZE); static constexpr size_t libra_univariates_length = Curve::LIBRA_UNIVARIATES_LENGTH; - challenge_polynomial_lagrange[0] = FF{ 1 }; + const size_t challenge_poly_length = libra_univariates_length * multivariate_challenge.size() + 1; + + FF one{ 1 }; + FF zero{ 0 }; + if constexpr (Curve::is_stdlib_type) { + auto builder = multivariate_challenge[0].get_context(); + one.convert_constant_to_fixed_witness(builder); + zero.convert_constant_to_fixed_witness(builder); + } + + challenge_polynomial_lagrange[0] = one; // Populate the vector with the powers of the challenges size_t round_idx = 0; for (auto challenge : multivariate_challenge) { size_t current_idx = 1 + libra_univariates_length * round_idx; - challenge_polynomial_lagrange[current_idx] = FF(1); + challenge_polynomial_lagrange[current_idx] = one; for (size_t idx = current_idx + 1; idx < current_idx + libra_univariates_length; idx++) { // Recursively compute the powers of the challenge up to the length of libra univariates challenge_polynomial_lagrange[idx] = challenge_polynomial_lagrange[idx - 1] * challenge; } round_idx++; } + + // Ensure that the coefficients are padded with fixed witnesses obtained from 0 + for (size_t idx = challenge_poly_length; idx < Curve::SUBGROUP_SIZE; idx++) { + challenge_polynomial_lagrange[idx] = zero; + } + return challenge_polynomial_lagrange; } @@ -465,9 +487,15 @@ std::vector compute_eccvm_challenge_coeffs( const typename Curve::ScalarField& evaluation_challenge_x, const typename Curve::ScalarField& batching_challenge_v) { using FF = typename Curve::ScalarField; - std::vector coeffs_lagrange_basis(Curve::SUBGROUP_SIZE, FF{ 0 }); - - FF v_power = FF{ 1 }; + std::vector coeffs_lagrange_basis(Curve::SUBGROUP_SIZE); + FF one{ 1 }; + FF zero{ 0 }; + if constexpr (Curve::is_stdlib_type) { + auto builder = evaluation_challenge_x.get_context(); + one.convert_constant_to_fixed_witness(builder); + zero.convert_constant_to_fixed_witness(builder); + } + FF v_power = one; for (size_t poly_idx = 0; poly_idx < NUM_TRANSLATION_EVALUATIONS; poly_idx++) { const size_t start = NUM_DISABLED_ROWS_IN_SUMCHECK * poly_idx; coeffs_lagrange_basis[start] = v_power; @@ -479,6 +507,13 @@ std::vector compute_eccvm_challenge_coeffs( v_power *= batching_challenge_v; } + static constexpr size_t challenge_poly_length = NUM_TRANSLATION_EVALUATIONS * NUM_DISABLED_ROWS_IN_SUMCHECK; + + // Ensure that the coefficients are padded with fixed witnesses obtained from 0 + for (size_t idx = challenge_poly_length; idx < Curve::SUBGROUP_SIZE; idx++) { + coeffs_lagrange_basis[idx] = zero; + } + return coeffs_lagrange_basis; } } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/relations/utils.hpp index fc5c01bac3d0..8116bba45f97 100644 --- a/barretenberg/cpp/src/barretenberg/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/utils.hpp @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include "barretenberg/common/constexpr_utils.hpp" @@ -257,10 +258,17 @@ template class RelationUtils { static void scale_and_batch_elements(auto& tuple, const RelationSeparator& challenge, FF current_scalar, FF& result) requires(!bb::IsFoldingFlavor) { + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1443) write one method to remove IsFoldingFlavor + // and !IsFoldingFlavor + constexpr const size_t last_index = std::tuple_size_v> - 1; + const auto& last_array = std::get(tuple); + const auto* last_element_ptr = last_array.empty() ? nullptr : &last_array.back(); auto scale_by_challenge_and_accumulate = [&](auto& element) { for (auto& entry : element) { result += entry * current_scalar; - current_scalar *= challenge; + if (last_element_ptr == nullptr || &entry != last_element_ptr) { + current_scalar *= challenge; + } } }; apply_to_tuple_of_arrays(scale_by_challenge_and_accumulate, tuple); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp index 652bab89f3d5..977cc8e14ceb 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp @@ -258,7 +258,7 @@ template class RecursiveVerifierTest : public testing } // Check the size of the recursive verifier if constexpr (std::same_as>) { - uint32_t NUM_GATES_EXPECTED = 874952; + uint32_t NUM_GATES_EXPECTED = 875529; BB_ASSERT_EQ(static_cast(outer_circuit.get_num_finalized_gates()), NUM_GATES_EXPECTED, "MegaZKHonk Recursive verifier changed in Ultra gate count! Update this value if you " diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp index d3b0d048431e..3f4bea86caca 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp @@ -89,7 +89,9 @@ MergeRecursiveVerifier_::PairingPoints MergeRecursiveVerifier_ bigfield bigfield= 2) { running_power = running_power.sqr(); } shifted_exponent >>= 1; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp index 49bd61a8ebf9..9c857c1e5d38 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp @@ -742,7 +742,9 @@ template cycle_group cycle_group::operator- const bool_t y_coordinates_match = (y == other.y); const bool_t double_predicate = (x_coordinates_match && !y_coordinates_match).normalize(); const bool_t infinity_predicate = (x_coordinates_match && y_coordinates_match).normalize(); - + if constexpr (IsUltraBuilder) { + infinity_predicate.get_context()->update_used_witnesses(infinity_predicate.witness_index); + } auto x1 = x; auto y1 = y; auto x2 = other.x; @@ -771,6 +773,11 @@ template cycle_group cycle_group::operator- auto result_x = field_t::conditional_assign(double_predicate, dbl_result.x, add_result.x); auto result_y = field_t::conditional_assign(double_predicate, dbl_result.y, add_result.y); + if constexpr (IsUltraBuilder) { + result_x.get_context()->update_used_witnesses(result_x.witness_index); + result_y.get_context()->update_used_witnesses(result_y.witness_index); + } + const bool_t lhs_infinity = is_point_at_infinity(); const bool_t rhs_infinity = other.is_point_at_infinity(); // if lhs infinity, return -rhs diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp index 91c493fb2ef1..62f415365c07 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp @@ -83,6 +83,9 @@ TranslatorRecursiveVerifier_::PairingPoints TranslatorRecursiveVerifier_ CommitmentLabels commitment_labels; const BF accumulated_result = transcript->template receive_from_prover("accumulated_result"); + // The point is prime basis limb of accumulated result can be easily recovered from binary basis limbs, so + // there's no meaning to use it at the circuit next and we can put it in used_witnesses + accumulated_result.get_context()->update_used_witnesses(accumulated_result.prime_basis_limb.witness_index); put_translation_data_in_relation_parameters(evaluation_input_x, batching_challenge_v, accumulated_result); @@ -200,6 +203,5 @@ void TranslatorRecursiveVerifier_::verify_consistency_with_final_merge( } } template class TranslatorRecursiveVerifier_>; -template class TranslatorRecursiveVerifier_>; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp index cf94d8c79d4f..9a931009b6b5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp @@ -193,8 +193,7 @@ template class TranslatorRecursiveTests : public ::te }; }; -using FlavorTypes = - testing::Types, TranslatorRecursiveFlavor_>; +using FlavorTypes = testing::Types>; TYPED_TEST_SUITE(TranslatorRecursiveTests, FlavorTypes); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp index 4d0155f6722b..98f31ea00df2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp @@ -188,9 +188,20 @@ void UltraCircuitBuilder_::add_gates_to_ensure_all_polys_are_non uint32_t right_witness_index = this->add_variable(right_witness_value); const auto dummy_accumulators = plookup::get_lookup_accumulators( plookup::MultiTableId::HONK_DUMMY_MULTI, left_witness_value, right_witness_value, true); - create_gates_from_plookup_accumulators( + auto read_data = create_gates_from_plookup_accumulators( plookup::MultiTableId::HONK_DUMMY_MULTI, dummy_accumulators, left_witness_index, right_witness_index); + update_used_witnesses(left_witness_index); + update_used_witnesses(right_witness_index); + std::array, 3> parse_read_data{ read_data[plookup::ColumnIdx::C1], + read_data[plookup::ColumnIdx::C2], + read_data[plookup::ColumnIdx::C3] }; + for (const auto& column : parse_read_data) { + for (const auto& index : column) { + update_used_witnesses(index); + } + } + // mock a poseidon external gate, with all zeros as input blocks.poseidon2_external.populate_wires(this->zero_idx, this->zero_idx, this->zero_idx, this->zero_idx); blocks.poseidon2_external.q_m().emplace_back(0);