From 8a7eda2782d46a502964e1ed6b5f302b44d402d4 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 6 Jun 2023 13:36:19 +0000 Subject: [PATCH 1/5] Fixed the memory issue --- .../ultra_honk_composer_helper.cpp | 21 ++++++++----- .../ultra_plonk_composer_helper.cpp | 21 ++++++++----- .../ultra_circuit_constructor.cpp | 30 +++++++++---------- .../ultra_circuit_constructor.hpp | 8 ++--- 4 files changed, 46 insertions(+), 34 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp b/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp index f5c5da1594..73a3c9cbcc 100644 --- a/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp +++ b/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp @@ -283,13 +283,20 @@ std::shared_ptr UltraHonkComposerHe // Copy memory read/write record data into proving key. Prover needs to know which gates contain a read/write // 'record' witness on the 4th wire. This wire value can only be fully computed once the first 3 wire polynomials // have been committed to. The 4th wire on these gates will be a random linear combination of the first 3 wires, - // using the plookup challenge `eta` - std::copy(circuit_constructor.memory_read_records.begin(), - circuit_constructor.memory_read_records.end(), - std::back_inserter(proving_key->memory_read_records)); - std::copy(circuit_constructor.memory_write_records.begin(), - circuit_constructor.memory_write_records.end(), - std::back_inserter(proving_key->memory_write_records)); + // using the plookup challenge `eta`. Because we shift the gates by the number of public inputs, we need to update + // the records with the public_inputs offset + const uint32_t public_inputs_count = static_cast(circuit_constructor.public_inputs.size()); + auto add_public_inputs_offset = [public_inputs_count](uint32_t gate_index) { + return gate_index + public_inputs_count; + }; + std::transform(circuit_constructor.memory_read_records.begin(), + circuit_constructor.memory_read_records.end(), + std::back_inserter(proving_key->memory_read_records), + add_public_inputs_offset); + std::transform(circuit_constructor.memory_write_records.begin(), + circuit_constructor.memory_write_records.end(), + std::back_inserter(proving_key->memory_write_records), + add_public_inputs_offset); proving_key->recursive_proof_public_input_indices = std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); diff --git a/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp b/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp index 788500fb9d..78df31401a 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp @@ -457,13 +457,20 @@ std::shared_ptr UltraPlonkComposerHelper::compute_proving_key(Circu // Copy memory read/write record data into proving key. Prover needs to know which gates contain a read/write // 'record' witness on the 4th wire. This wire value can only be fully computed once the first 3 wire polynomials // have been committed to. The 4th wire on these gates will be a random linear combination of the first 3 wires, - // using the plookup challenge `eta` - std::copy(circuit_constructor.memory_read_records.begin(), - circuit_constructor.memory_read_records.end(), - std::back_inserter(circuit_proving_key->memory_read_records)); - std::copy(circuit_constructor.memory_write_records.begin(), - circuit_constructor.memory_write_records.end(), - std::back_inserter(circuit_proving_key->memory_write_records)); + // using the plookup challenge `eta`. Because we shift the gates by the number of public inputs, we need to update + // the records with the public_inputs offset + const uint32_t public_inputs_count = static_cast(circuit_constructor.public_inputs.size()); + auto add_public_inputs_offset = [public_inputs_count](uint32_t gate_index) { + return gate_index + public_inputs_count; + }; + std::transform(circuit_constructor.memory_read_records.begin(), + circuit_constructor.memory_read_records.end(), + std::back_inserter(circuit_proving_key->memory_read_records), + add_public_inputs_offset); + std::transform(circuit_constructor.memory_write_records.begin(), + circuit_constructor.memory_write_records.end(), + std::back_inserter(circuit_proving_key->memory_write_records), + add_public_inputs_offset); circuit_proving_key->recursive_proof_public_input_indices = std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); diff --git a/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.cpp b/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.cpp index f8b3ddc02b..3da924b4e6 100644 --- a/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.cpp +++ b/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.cpp @@ -44,8 +44,8 @@ void UltraCircuitConstructor::finalize_circuit() */ if (!circuit_finalised) { process_non_native_field_multiplications(); - process_ROM_arrays(public_inputs.size()); - process_RAM_arrays(public_inputs.size()); + process_ROM_arrays(); + process_RAM_arrays(); process_range_lists(); circuit_finalised = true; } @@ -2275,7 +2275,7 @@ std::array UltraCircuitConstructor::read_ROM_array_pair(const size_ * @param rom_id The id of the ROM table * @param gate_offset_from_public_inputs Required to track the gate position of where we're adding extra gates */ -void UltraCircuitConstructor::process_ROM_array(const size_t rom_id, const size_t gate_offset_from_public_inputs) +void UltraCircuitConstructor::process_ROM_array(const size_t rom_id) { auto& rom_array = rom_arrays[rom_id]; @@ -2328,8 +2328,8 @@ void UltraCircuitConstructor::process_ROM_array(const size_t rom_id, const size_ // record (w4) = w3 * eta^3 + w2 * eta^2 + w1 * eta + read_write_flag (0 for reads, 1 for writes) // Separate containers used to store gate indices of reads and writes. Need to differentiate because of // `read_write_flag` (N.B. all ROM accesses are considered reads. Writes are for RAM operations) - memory_read_records.push_back(static_cast(sorted_record.gate_index + gate_offset_from_public_inputs)); - memory_read_records.push_back(static_cast(record.gate_index + gate_offset_from_public_inputs)); + memory_read_records.push_back(static_cast(sorted_record.gate_index)); + memory_read_records.push_back(static_cast(record.gate_index)); } // One of the checks we run on the sorted list, is to validate the difference between // the index field across two gates is either 0 or 1. @@ -2361,7 +2361,7 @@ void UltraCircuitConstructor::process_ROM_array(const size_t rom_id, const size_ * @param ram_id The id of the RAM table * @param gate_offset_from_public_inputs Required to track the gate position of where we're adding extra gates */ -void UltraCircuitConstructor::process_RAM_array(const size_t ram_id, const size_t gate_offset_from_public_inputs) +void UltraCircuitConstructor::process_RAM_array(const size_t ram_id) { RamTranscript& ram_array = ram_arrays[ram_id]; const auto access_tag = get_new_tag(); // current_tag + 1; @@ -2430,15 +2430,13 @@ void UltraCircuitConstructor::process_RAM_array(const size_t ram_id, const size_ switch (record.access_type) { case RamRecord::AccessType::READ: { - memory_read_records.push_back( - static_cast(sorted_record.gate_index + gate_offset_from_public_inputs)); - memory_read_records.push_back(static_cast(record.gate_index + gate_offset_from_public_inputs)); + memory_read_records.push_back(static_cast(sorted_record.gate_index)); + memory_read_records.push_back(static_cast(record.gate_index)); break; } case RamRecord::AccessType::WRITE: { - memory_write_records.push_back( - static_cast(sorted_record.gate_index + gate_offset_from_public_inputs)); - memory_write_records.push_back(static_cast(record.gate_index + gate_offset_from_public_inputs)); + memory_write_records.push_back(static_cast(sorted_record.gate_index)); + memory_write_records.push_back(static_cast(record.gate_index)); break; } default: { @@ -2498,16 +2496,16 @@ void UltraCircuitConstructor::process_RAM_array(const size_t ram_id, const size_ } } -void UltraCircuitConstructor::process_ROM_arrays(const size_t gate_offset_from_public_inputs) +void UltraCircuitConstructor::process_ROM_arrays() { for (size_t i = 0; i < rom_arrays.size(); ++i) { - process_ROM_array(i, gate_offset_from_public_inputs); + process_ROM_array(i); } } -void UltraCircuitConstructor::process_RAM_arrays(const size_t gate_offset_from_public_inputs) +void UltraCircuitConstructor::process_RAM_arrays() { for (size_t i = 0; i < ram_arrays.size(); ++i) { - process_RAM_array(i, gate_offset_from_public_inputs); + process_RAM_array(i); } } diff --git a/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp b/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp index 9825438792..4f91414c82 100644 --- a/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp +++ b/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp @@ -1113,8 +1113,8 @@ class UltraCircuitConstructor : public CircuitConstructorBase read_ROM_array_pair(const size_t rom_id, const uint32_t index_witness); void create_ROM_gate(RomRecord& record); void create_sorted_ROM_gate(RomRecord& record); - void process_ROM_array(const size_t rom_id, const size_t gate_offset_from_public_inputs); - void process_ROM_arrays(const size_t gate_offset_from_public_inputs); + void process_ROM_array(const size_t rom_id); + void process_ROM_arrays(); void create_RAM_gate(RamRecord& record); void create_sorted_RAM_gate(RamRecord& record); @@ -1124,8 +1124,8 @@ class UltraCircuitConstructor : public CircuitConstructorBase Date: Tue, 6 Jun 2023 20:15:51 +0000 Subject: [PATCH 2/5] Switched recursion to use check_circuit (but still use composers) --- .../standard_plonk_composer_helper.cpp | 10 +- .../standard_plonk_composer_helper.hpp | 16 -- .../turbo_plonk_composer_helper.cpp | 10 +- .../turbo_plonk_composer_helper.hpp | 17 -- .../ultra_plonk_composer_helper.cpp | 10 +- .../ultra_plonk_composer_helper.hpp | 23 --- .../composer/standard_plonk_composer.hpp | 18 +- .../plonk/composer/turbo_plonk_composer.hpp | 18 +- .../plonk/composer/ultra_plonk_composer.hpp | 10 +- .../circuit_constructor_base.hpp | 27 ++- .../ultra_circuit_constructor.hpp | 13 -- .../recursion/verifier/verifier.test.cpp | 167 +++++++++++------- .../verifier/verifier_turbo.test.cpp | 142 +++++++++------ 13 files changed, 254 insertions(+), 227 deletions(-) diff --git a/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.cpp b/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.cpp index 62a59c960a..dd2d35acce 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.cpp @@ -76,9 +76,10 @@ std::shared_ptr StandardPlonkComposerHelper::compute_proving compute_standard_plonk_sigma_permutations(circuit_constructor, circuit_proving_key.get()); circuit_proving_key->recursive_proof_public_input_indices = - std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); + std::vector(circuit_constructor.recursive_proof_public_input_indices.begin(), + circuit_constructor.recursive_proof_public_input_indices.end()); // What does this line do exactly? - circuit_proving_key->contains_recursive_proof = contains_recursive_proof; + circuit_proving_key->contains_recursive_proof = circuit_constructor.contains_recursive_proof; return circuit_proving_key; } @@ -101,8 +102,9 @@ std::shared_ptr StandardPlonkComposerHelper::compute_ve plonk::compute_verification_key_common(circuit_proving_key, crs_factory_->get_verifier_crs()); circuit_verification_key->composer_type = circuit_proving_key->composer_type; circuit_verification_key->recursive_proof_public_input_indices = - std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); - circuit_verification_key->contains_recursive_proof = contains_recursive_proof; + std::vector(circuit_constructor.recursive_proof_public_input_indices.begin(), + circuit_constructor.recursive_proof_public_input_indices.end()); + circuit_verification_key->contains_recursive_proof = circuit_constructor.contains_recursive_proof; return circuit_verification_key; } diff --git a/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.hpp b/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.hpp index cb3676f4dc..8b371c23ca 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_helper/standard_plonk_composer_helper.hpp @@ -25,8 +25,6 @@ class StandardPlonkComposerHelper { // at all std::shared_ptr crs_factory_; - std::vector recursive_proof_public_input_indices; - bool contains_recursive_proof = false; bool computed_witness = false; StandardPlonkComposerHelper() @@ -59,20 +57,6 @@ class StandardPlonkComposerHelper { }; return result; } - void add_recursive_proof(CircuitConstructor& circuit_constructor, - const std::vector& proof_output_witness_indices) - { - - if (contains_recursive_proof) { - circuit_constructor.failure("added recursive proof when one already exists"); - } - contains_recursive_proof = true; - - for (const auto& idx : proof_output_witness_indices) { - circuit_constructor.set_public_input(idx); - recursive_proof_public_input_indices.push_back((uint32_t)(circuit_constructor.public_inputs.size() - 1)); - } - } std::shared_ptr compute_proving_key(const CircuitConstructor& circuit_constructor); std::shared_ptr compute_verification_key(const CircuitConstructor& circuit_constructor); diff --git a/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.cpp b/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.cpp index f9086c111d..d571b24d11 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.cpp @@ -50,8 +50,9 @@ std::shared_ptr TurboPlonkComposerHelper::compute_proving_ke // Compute sigma polynomials (TODO(kesha): we should update that late) compute_standard_plonk_sigma_permutations(circuit_constructor, circuit_proving_key.get()); circuit_proving_key->recursive_proof_public_input_indices = - std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); - circuit_proving_key->contains_recursive_proof = contains_recursive_proof; + std::vector(circuit_constructor.recursive_proof_public_input_indices.begin(), + circuit_constructor.recursive_proof_public_input_indices.end()); + circuit_proving_key->contains_recursive_proof = circuit_constructor.contains_recursive_proof; return circuit_proving_key; } @@ -74,8 +75,9 @@ std::shared_ptr TurboPlonkComposerHelper::compute_verif plonk::compute_verification_key_common(circuit_proving_key, crs_factory_->get_verifier_crs()); circuit_verification_key->composer_type = circuit_proving_key->composer_type; circuit_verification_key->recursive_proof_public_input_indices = - std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); - circuit_verification_key->contains_recursive_proof = contains_recursive_proof; + std::vector(circuit_constructor.recursive_proof_public_input_indices.begin(), + circuit_constructor.recursive_proof_public_input_indices.end()); + circuit_verification_key->contains_recursive_proof = circuit_constructor.contains_recursive_proof; return circuit_verification_key; } diff --git a/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.hpp b/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.hpp index eaf1755eb6..410c18e9f5 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_helper/turbo_plonk_composer_helper.hpp @@ -24,9 +24,6 @@ class TurboPlonkComposerHelper { // at all std::shared_ptr crs_factory_; - std::vector recursive_proof_public_input_indices; - bool contains_recursive_proof = false; - bool computed_witness = false; TurboPlonkComposerHelper() : TurboPlonkComposerHelper(std::shared_ptr( @@ -62,20 +59,6 @@ class TurboPlonkComposerHelper { }; return result; } - void add_recursive_proof(CircuitConstructor& circuit_constructor, - const std::vector& proof_output_witness_indices) - { - - if (contains_recursive_proof) { - circuit_constructor.failure("added recursive proof when one already exists"); - } - contains_recursive_proof = true; - - for (const auto& idx : proof_output_witness_indices) { - circuit_constructor.set_public_input(idx); - recursive_proof_public_input_indices.push_back((uint32_t)(circuit_constructor.public_inputs.size() - 1)); - } - } static transcript::Manifest create_manifest(const size_t num_public_inputs) { // add public inputs.... diff --git a/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp b/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp index 78df31401a..332beb59a9 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp +++ b/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.cpp @@ -473,9 +473,10 @@ std::shared_ptr UltraPlonkComposerHelper::compute_proving_key(Circu add_public_inputs_offset); circuit_proving_key->recursive_proof_public_input_indices = - std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); + std::vector(circuit_constructor.recursive_proof_public_input_indices.begin(), + circuit_constructor.recursive_proof_public_input_indices.end()); - circuit_proving_key->contains_recursive_proof = contains_recursive_proof; + circuit_proving_key->contains_recursive_proof = circuit_constructor.contains_recursive_proof; return circuit_proving_key; } @@ -503,9 +504,10 @@ std::shared_ptr UltraPlonkComposerHelper::compute_verif // See `add_recusrive_proof()` for how this recursive data is assigned. circuit_verification_key->recursive_proof_public_input_indices = - std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); + std::vector(circuit_constructor.recursive_proof_public_input_indices.begin(), + circuit_constructor.recursive_proof_public_input_indices.end()); - circuit_verification_key->contains_recursive_proof = contains_recursive_proof; + circuit_verification_key->contains_recursive_proof = circuit_constructor.contains_recursive_proof; return circuit_verification_key; } diff --git a/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.hpp b/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.hpp index bc0d5c80ba..158a8bac13 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_helper/ultra_plonk_composer_helper.hpp @@ -26,8 +26,6 @@ class UltraPlonkComposerHelper { // at all std::shared_ptr crs_factory_; - std::vector recursive_proof_public_input_indices; - bool contains_recursive_proof = false; bool computed_witness = false; // This variable controls the amount with which the lookup table and witness values need to be shifted @@ -72,27 +70,6 @@ class UltraPlonkComposerHelper { [[nodiscard]] size_t get_num_selectors() { return ultra_selector_properties().size(); } - /** - * @brief Add information about which witnesses contain the recursive proof computation information - * - * @param circuit_constructor Object with the circuit - * @param proof_output_witness_indices Witness indices that need to become public and stored as recurisve proof - * specific - */ - void add_recursive_proof(CircuitConstructor& circuit_constructor, - const std::vector& proof_output_witness_indices) - { - - if (contains_recursive_proof) { - circuit_constructor.failure("added recursive proof when one already exists"); - } - contains_recursive_proof = true; - - for (const auto& idx : proof_output_witness_indices) { - circuit_constructor.set_public_input(idx); - recursive_proof_public_input_indices.push_back((uint32_t)(circuit_constructor.public_inputs.size() - 1)); - } - } void finalize_circuit(CircuitConstructor& circuit_constructor) { circuit_constructor.finalize_circuit(); }; std::shared_ptr compute_proving_key(CircuitConstructor& circuit_constructor); diff --git a/cpp/src/barretenberg/plonk/composer/standard_plonk_composer.hpp b/cpp/src/barretenberg/plonk/composer/standard_plonk_composer.hpp index f08d9a3d73..eb743cf2f8 100644 --- a/cpp/src/barretenberg/plonk/composer/standard_plonk_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/standard_plonk_composer.hpp @@ -54,8 +54,8 @@ class StandardPlonkComposer { , num_gates(circuit_constructor.num_gates) , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices){}; + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices){}; StandardPlonkComposer(std::string const& crs_path, const size_t size_hint = 0) : StandardPlonkComposer( @@ -68,8 +68,8 @@ class StandardPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(crs_factory) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices) + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices) {} StandardPlonkComposer(std::unique_ptr&& crs_factory, const size_t size_hint = 0) @@ -78,8 +78,8 @@ class StandardPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(std::move(crs_factory)) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices) + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices) {} @@ -91,8 +91,8 @@ class StandardPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(p_key, v_key) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices) + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices) {} StandardPlonkComposer(const StandardPlonkComposer& other) = delete; @@ -224,7 +224,7 @@ class StandardPlonkComposer { void add_recursive_proof(const std::vector& proof_output_witness_indices) { - composer_helper.add_recursive_proof(circuit_constructor, proof_output_witness_indices); + circuit_constructor.add_recursive_proof(proof_output_witness_indices); } bool failed() const { return circuit_constructor.failed(); }; const std::string& err() const { return circuit_constructor.err(); }; diff --git a/cpp/src/barretenberg/plonk/composer/turbo_plonk_composer.hpp b/cpp/src/barretenberg/plonk/composer/turbo_plonk_composer.hpp index 850813129b..aa9735df8f 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_plonk_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_plonk_composer.hpp @@ -51,8 +51,8 @@ class TurboPlonkComposer { , num_gates(circuit_constructor.num_gates) , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices){}; + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices){}; TurboPlonkComposer(std::string const& crs_path, const size_t size_hint = 0) : TurboPlonkComposer( @@ -65,8 +65,8 @@ class TurboPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(crs_factory) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices){}; + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices){}; TurboPlonkComposer(std::unique_ptr&& crs_factory, const size_t size_hint = 0) : circuit_constructor(size_hint) @@ -74,8 +74,8 @@ class TurboPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(std::move(crs_factory)) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices){}; + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices){}; TurboPlonkComposer(std::shared_ptr const& p_key, std::shared_ptr const& v_key, @@ -85,8 +85,8 @@ class TurboPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(p_key, v_key) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices){}; + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices){}; TurboPlonkComposer(const TurboPlonkComposer& other) = delete; TurboPlonkComposer(TurboPlonkComposer&& other) = default; @@ -229,7 +229,7 @@ class TurboPlonkComposer { void add_recursive_proof(const std::vector& proof_output_witness_indices) { - composer_helper.add_recursive_proof(circuit_constructor, proof_output_witness_indices); + circuit_constructor.add_recursive_proof(proof_output_witness_indices); } bool failed() const { return circuit_constructor.failed(); }; const std::string& err() const { return circuit_constructor.err(); }; diff --git a/cpp/src/barretenberg/plonk/composer/ultra_plonk_composer.hpp b/cpp/src/barretenberg/plonk/composer/ultra_plonk_composer.hpp index 3078cecbb0..10e01a9c34 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_plonk_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_plonk_composer.hpp @@ -52,8 +52,8 @@ class UltraPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(crs_factory) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices){}; + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices){}; UltraPlonkComposer(std::shared_ptr const& p_key, std::shared_ptr const& v_key, @@ -63,8 +63,8 @@ class UltraPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(p_key, v_key) - , contains_recursive_proof(composer_helper.contains_recursive_proof) - , recursive_proof_public_input_indices(composer_helper.recursive_proof_public_input_indices){}; + , contains_recursive_proof(circuit_constructor.contains_recursive_proof) + , recursive_proof_public_input_indices(circuit_constructor.recursive_proof_public_input_indices){}; UltraPlonkComposer(UltraPlonkComposer&& other) = default; UltraPlonkComposer& operator=(UltraPlonkComposer&& other) @@ -206,7 +206,7 @@ class UltraPlonkComposer { } void add_recursive_proof(const std::vector& proof_output_witness_indices) { - composer_helper.add_recursive_proof(circuit_constructor, proof_output_witness_indices); + circuit_constructor.add_recursive_proof(proof_output_witness_indices); } void create_new_range_constraint(const uint32_t variable_index, diff --git a/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp b/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp index 6b059dc92d..20c3814d2e 100644 --- a/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp +++ b/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp @@ -40,6 +40,10 @@ template class CircuitConstructorBase { // DOCTODO(#231): replace with the relevant wiki link. std::map tau; + // Publicin put indices which contain recursive proof information + std::vector recursive_proof_public_input_indices; + bool contains_recursive_proof = false; + bool _failed = false; std::string _err; static constexpr uint32_t REAL_VARIABLE = UINT32_MAX - 1; @@ -227,6 +231,27 @@ template class CircuitConstructorBase { } bool is_valid_variable(uint32_t variable_index) { return variable_index < variables.size(); }; + /** + * @brief Add information about which witnesses contain the recursive proof computation information + * + * @param circuit_constructor Object with the circuit + * @param proof_output_witness_indices Witness indices that need to become public and stored as recurisve proof + * specific + */ + void add_recursive_proof(const std::vector& proof_output_witness_indices) + { + + if (contains_recursive_proof) { + failure("added recursive proof when one already exists"); + } + contains_recursive_proof = true; + + for (const auto& idx : proof_output_witness_indices) { + set_public_input(idx); + recursive_proof_public_input_indices.push_back((uint32_t)(public_inputs.size() - 1)); + } + } + bool failed() const { return _failed; }; const std::string& err() const { return _err; }; @@ -236,7 +261,7 @@ template class CircuitConstructorBase { _failed = true; set_err(msg); } -}; +}; // namespace proof_system } // namespace proof_system diff --git a/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp b/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp index 4f91414c82..abb838ec0b 100644 --- a/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp +++ b/cpp/src/barretenberg/proof_system/circuit_constructors/ultra_circuit_constructor.hpp @@ -637,19 +637,6 @@ class UltraCircuitConstructor : public CircuitConstructorBase& proof_output_witness_indices) - // { - // if (contains_recursive_proof) { - // failure("added recursive proof when one already exists"); - // } - // contains_recursive_proof = true; - - // for (const auto& idx : proof_output_witness_indices) { - // set_public_input(idx); - // recursive_proof_public_input_indices.push_back((uint32_t)(public_inputs.size() - 1)); - // } - // } - void create_new_range_constraint(const uint32_t variable_index, const uint64_t target_range, std::string const msg = "create_new_range_constraint"); diff --git a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp index 97cd566e3a..bc943a2051 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp +++ b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp @@ -276,6 +276,63 @@ template class stdlib_verifier : public testing::Test { return { output, verification_key }; } + /** + * @brief Check the correctness of the recursive proof public inputs + * + * @details Circuit constructors have no notion of SRS and any proof-related stuff except for the existence of + * recursive proof-specific public inputs, so we can't check the recursive proof fully in check_circuit. So we use + * this additional function to check that the recursive proof points work. + * + * @return true + * @return false + */ + static bool check_recursive_proof_public_inputs(OuterComposer& composer, + const barretenberg::pairing::miller_lines* lines) + { + if (composer.contains_recursive_proof && composer.recursive_proof_public_input_indices.size() == 16) { + const auto& inputs = composer.circuit_constructor.public_inputs; + const auto recover_fq_from_public_inputs = + [&inputs, &composer](const size_t idx0, const size_t idx1, const size_t idx2, const size_t idx3) { + const uint256_t l0 = composer.circuit_constructor.get_variable(inputs[idx0]); + const uint256_t l1 = composer.circuit_constructor.get_variable(inputs[idx1]); + const uint256_t l2 = composer.circuit_constructor.get_variable(inputs[idx2]); + const uint256_t l3 = composer.circuit_constructor.get_variable(inputs[idx3]); + + const uint256_t limb = l0 + (l1 << NUM_LIMB_BITS_IN_FIELD_SIMULATION) + + (l2 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2)) + + (l3 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3)); + return barretenberg::fq(limb); + }; + + const auto x0 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[0], + composer.recursive_proof_public_input_indices[1], + composer.recursive_proof_public_input_indices[2], + composer.recursive_proof_public_input_indices[3]); + const auto y0 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[4], + composer.recursive_proof_public_input_indices[5], + composer.recursive_proof_public_input_indices[6], + composer.recursive_proof_public_input_indices[7]); + const auto x1 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[8], + composer.recursive_proof_public_input_indices[9], + composer.recursive_proof_public_input_indices[10], + composer.recursive_proof_public_input_indices[11]); + const auto y1 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[12], + composer.recursive_proof_public_input_indices[13], + composer.recursive_proof_public_input_indices[14], + composer.recursive_proof_public_input_indices[15]); + g1::affine_element P_affine[2]{ + { x0, y0 }, + { x1, y1 }, + }; + + barretenberg::fq12 result = + barretenberg::pairing::reduced_ate_pairing_batch_precomputed(P_affine, lines, 2); + + return (result == barretenberg::fq12::one()); + } + return true; + } + public: static void test_recursive_proof_composition() { @@ -307,23 +364,14 @@ template class stdlib_verifier : public testing::Test { EXPECT_EQ(outer_composer.failed(), false); - info("creating prover for outer circuit"); - info("composer gates = ", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - info("created prover for outer circuit"); - - info("creating verifier for outer proof"); - auto verifier = outer_composer.create_verifier(); - - info("creating outer proof for outer circuit"); - plonk::proof proof = prover.construct_proof(); - info("created outer proof"); - - info("verifying the outer proof"); - bool result = verifier.verify_proof(proof); - info("Outer proof verification result: ", result); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_recursive_proof_composition_ultra_no_tables() @@ -352,23 +400,16 @@ template class stdlib_verifier : public testing::Test { EXPECT_EQ(outer_composer.failed(), false); - info("creating prover for outer circuit"); info("composer gates = ", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - info("created prover for outer circuit"); - - info("creating verifier for outer proof"); - auto verifier = outer_composer.create_verifier(); - - info("creating outer proof for outer circuit"); - plonk::proof proof = prover.construct_proof(); - info("created outer proof"); - info("verifying the outer proof"); - bool result = verifier.verify_proof(proof); - info("Outer proof verification result: ", result); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_double_verification() @@ -377,7 +418,6 @@ template class stdlib_verifier : public testing::Test { return; // We only care about running this test for turbo and ultra outer circuits, since in practice the // only circuits which verify >1 proof are ultra or turbo circuits. Standard uses so many gates // (16m) that it's a waste of time testing it. - InnerComposer inner_composer_a = InnerComposer("../srs_db/ignition"); InnerComposer inner_composer_b = InnerComposer("../srs_db/ignition"); @@ -430,19 +470,13 @@ template class stdlib_verifier : public testing::Test { printf("composer gates = %zu\n", outer_composer.get_num_gates()); - std::cout << "creating prover" << std::endl; - auto prover = outer_composer.create_prover(); - std::cout << "created prover" << std::endl; - - std::cout << "creating verifier" << std::endl; - auto verifier = outer_composer.create_verifier(); - - std::cout << "validated. creating proof" << std::endl; - plonk::proof proof = prover.construct_proof(); - std::cout << "created proof" << std::endl; - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } // verifies a proof of a circuit that verifies one of two proofs. Test 'a' uses a proof over the first of the two @@ -481,14 +515,14 @@ template class stdlib_verifier : public testing::Test { EXPECT_EQ(inner_proof_result, barretenberg::fq12::one()); printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } // verifies a proof of a circuit that verifies one of two proofs. Test 'b' uses a proof over the second of the two @@ -528,14 +562,13 @@ template class stdlib_verifier : public testing::Test { printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_recursive_proof_composition_with_variable_verification_key_failure_case() @@ -573,14 +606,13 @@ template class stdlib_verifier : public testing::Test { printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, false); + + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_recursive_proof_composition_with_constant_verification_key() @@ -618,14 +650,13 @@ template class stdlib_verifier : public testing::Test { printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_inner_circuit() diff --git a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier_turbo.test.cpp b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier_turbo.test.cpp index 833949aa8e..e8349f8eb9 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier_turbo.test.cpp +++ b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier_turbo.test.cpp @@ -26,7 +26,62 @@ template class stdlib_verifier_turbo : public testing:: stdlib::recursion::aggregation_state aggregation_state; std::shared_ptr verification_key; }; - + /** + * @brief Check the correctness of the recursive proof public inputs + * + * @details Circuit constructors have no notion of SRS and any proof-related stuff except for the existence of + * recursive proof-specific public inputs, so we can't check the recursive proof fully in check_circuit. So we use + * this additional function to check that the recursive proof points work. + * + * @return true + * @return false + */ + static bool check_recursive_proof_public_inputs(OuterComposer& composer, + const barretenberg::pairing::miller_lines* lines) + { + if (composer.contains_recursive_proof && composer.recursive_proof_public_input_indices.size() == 16) { + const auto& inputs = composer.circuit_constructor.public_inputs; + const auto recover_fq_from_public_inputs = + [&inputs, &composer](const size_t idx0, const size_t idx1, const size_t idx2, const size_t idx3) { + const uint256_t l0 = composer.circuit_constructor.get_variable(inputs[idx0]); + const uint256_t l1 = composer.circuit_constructor.get_variable(inputs[idx1]); + const uint256_t l2 = composer.circuit_constructor.get_variable(inputs[idx2]); + const uint256_t l3 = composer.circuit_constructor.get_variable(inputs[idx3]); + + const uint256_t limb = l0 + (l1 << NUM_LIMB_BITS_IN_FIELD_SIMULATION) + + (l2 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2)) + + (l3 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3)); + return barretenberg::fq(limb); + }; + + const auto x0 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[0], + composer.recursive_proof_public_input_indices[1], + composer.recursive_proof_public_input_indices[2], + composer.recursive_proof_public_input_indices[3]); + const auto y0 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[4], + composer.recursive_proof_public_input_indices[5], + composer.recursive_proof_public_input_indices[6], + composer.recursive_proof_public_input_indices[7]); + const auto x1 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[8], + composer.recursive_proof_public_input_indices[9], + composer.recursive_proof_public_input_indices[10], + composer.recursive_proof_public_input_indices[11]); + const auto y1 = recover_fq_from_public_inputs(composer.recursive_proof_public_input_indices[12], + composer.recursive_proof_public_input_indices[13], + composer.recursive_proof_public_input_indices[14], + composer.recursive_proof_public_input_indices[15]); + g1::affine_element P_affine[2]{ + { x0, y0 }, + { x1, y1 }, + }; + + barretenberg::fq12 result = + barretenberg::pairing::reduced_ate_pairing_batch_precomputed(P_affine, lines, 2); + + return (result == barretenberg::fq12::one()); + } + return true; + } static void create_inner_circuit(InnerComposer& composer, const std::vector& public_inputs) { fr_ct a(public_witness_ct(&composer, public_inputs[0])); @@ -191,25 +246,19 @@ template class stdlib_verifier_turbo : public testing:: circuit_output.aggregation_state.assign_object_to_proof_outputs(); EXPECT_EQ(outer_composer.failed(), false); - std::cout << "creating prover" << std::endl; - std::cout << "composer gates = " << outer_composer.get_num_gates() << std::endl; - auto prover = outer_composer.create_prover(); - std::cout << "created prover" << std::endl; - - std::cout << "creating verifier" << std::endl; - auto verifier = outer_composer.create_verifier(); - - std::cout << "validated. creating proof" << std::endl; - plonk::proof proof = prover.construct_proof(); - std::cout << "created proof" << std::endl; - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_double_verification() { - if constexpr (std::is_same::value) + if constexpr (!(std::is_same::value || + std::is_same::value)) return; // We only care about running this test for turbo and ultra outer circuits, since in practice the // only circuits which verify >1 proof are ultra or turbo circuits. Standard uses so many gates // (16m) that it's a waste of time testing it. @@ -243,19 +292,12 @@ template class stdlib_verifier_turbo : public testing:: printf("composer gates = %zu\n", outer_composer.get_num_gates()); - std::cout << "creating prover" << std::endl; - auto prover = outer_composer.create_prover(); - std::cout << "created prover" << std::endl; - - std::cout << "creating verifier" << std::endl; - auto verifier = outer_composer.create_verifier(); - - std::cout << "validated. creating proof" << std::endl; - plonk::proof proof = prover.construct_proof(); - std::cout << "created proof" << std::endl; - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } // verifies a proof of a circuit that verifies one of two proofs. Test 'a' uses a proof over the first of the two @@ -295,14 +337,12 @@ template class stdlib_verifier_turbo : public testing:: printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } // verifies a proof of a circuit that verifies one of two proofs. Test 'b' uses a proof over the second of the two @@ -342,14 +382,12 @@ template class stdlib_verifier_turbo : public testing:: printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_recursive_proof_composition_with_variable_verification_key_failure_case() @@ -387,14 +425,12 @@ template class stdlib_verifier_turbo : public testing:: printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, false); + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_recursive_proof_composition_with_constant_verification_key() @@ -432,14 +468,12 @@ template class stdlib_verifier_turbo : public testing:: printf("composer gates = %zu\n", outer_composer.get_num_gates()); - auto prover = outer_composer.create_prover(); - - auto verifier = outer_composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); + bool result = outer_composer.check_circuit(); EXPECT_EQ(result, true); + EXPECT_EQ(check_recursive_proof_public_inputs( + outer_composer, + outer_composer.composer_helper.crs_factory_->get_verifier_crs()->get_precomputed_g2_lines()), + true); } static void test_inner_circuit() From 21f1a131fade14c205981c7b1f976922c2234e3d Mon Sep 17 00:00:00 2001 From: codygunton Date: Fri, 9 Jun 2023 18:38:19 +0000 Subject: [PATCH 3/5] Low-impact fix of circular dependency --- cpp/src/barretenberg/ecc/CMakeLists.txt | 2 +- .../ecc/scalar_multiplication/point_table.hpp | 1 + cpp/src/barretenberg/plonk/CMakeLists.txt | 2 +- .../scalar_multiplication.test.cpp | 59 +++++++++++-------- 4 files changed, 38 insertions(+), 26 deletions(-) rename cpp/src/barretenberg/{ecc/scalar_multiplication => srs}/scalar_multiplication.test.cpp (95%) diff --git a/cpp/src/barretenberg/ecc/CMakeLists.txt b/cpp/src/barretenberg/ecc/CMakeLists.txt index 588d8e2c2e..2efdfb493a 100644 --- a/cpp/src/barretenberg/ecc/CMakeLists.txt +++ b/cpp/src/barretenberg/ecc/CMakeLists.txt @@ -1,4 +1,4 @@ -barretenberg_module(ecc numeric crypto_keccak srs) +barretenberg_module(ecc numeric crypto_keccak) if(DISABLE_ADX) message(STATUS "Disabling ADX assembly variant.") diff --git a/cpp/src/barretenberg/ecc/scalar_multiplication/point_table.hpp b/cpp/src/barretenberg/ecc/scalar_multiplication/point_table.hpp index 39c20bba71..757c540e8c 100644 --- a/cpp/src/barretenberg/ecc/scalar_multiplication/point_table.hpp +++ b/cpp/src/barretenberg/ecc/scalar_multiplication/point_table.hpp @@ -17,6 +17,7 @@ inline size_t point_table_size(size_t num_points) inline size_t point_table_buf_size(size_t num_points) { + // TODO(Cody): This could be trouble if we change curves. return sizeof(g1::affine_element) * point_table_size(num_points); } diff --git a/cpp/src/barretenberg/plonk/CMakeLists.txt b/cpp/src/barretenberg/plonk/CMakeLists.txt index 0893749023..aa1a5dcf7d 100644 --- a/cpp/src/barretenberg/plonk/CMakeLists.txt +++ b/cpp/src/barretenberg/plonk/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(plonk proof_system transcript crypto_pedersen_commitment polynomials crypto_sha256 ecc crypto_blake3s) \ No newline at end of file +barretenberg_module(plonk proof_system transcript crypto_pedersen_commitment polynomials crypto_sha256 ecc crypto_blake3s srs) \ No newline at end of file diff --git a/cpp/src/barretenberg/ecc/scalar_multiplication/scalar_multiplication.test.cpp b/cpp/src/barretenberg/srs/scalar_multiplication.test.cpp similarity index 95% rename from cpp/src/barretenberg/ecc/scalar_multiplication/scalar_multiplication.test.cpp rename to cpp/src/barretenberg/srs/scalar_multiplication.test.cpp index a38bab59b5..73f810aa39 100644 --- a/cpp/src/barretenberg/ecc/scalar_multiplication/scalar_multiplication.test.cpp +++ b/cpp/src/barretenberg/srs/scalar_multiplication.test.cpp @@ -1,21 +1,32 @@ -#include "point_table.hpp" -#include "scalar_multiplication.hpp" +/** + * @file scalar_multiplication.test.cpp + * @brief Tests of our implementation of Pippenger's multi-scalar multiplication algorithm. + * + * @details This file is here with the SRS code, rather than being next to the Pippenger implementation, to avoid a + * cyclic dependency between our srs and ecc modules. Namely, srs depends on ecc via the FileProverCrs constructor that + * constructs a Pippenger point table. It may make sense to create a function in the ecc module that initializes a CRS, + * but for now a low-impact solution (to a newly-encountered linker error) is to move this test file, as it was the sole + * reason for for ecc to depend on srs. + */ + +#include "barretenberg/common/mem.hpp" #include "barretenberg/common/test.hpp" +#include "barretenberg/ecc/scalar_multiplication/point_table.hpp" +#include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp" +#include "barretenberg/numeric/random/engine.hpp" #include "barretenberg/srs/io.hpp" #include "barretenberg/srs/factories/file_crs_factory.hpp" + #include #include -#include "barretenberg/numeric/random/engine.hpp" -#include "barretenberg/common/mem.hpp" - namespace { auto& engine = numeric::random::get_debug_engine(); } using namespace barretenberg; -template class SRSIO : public ::testing::Test { +template class ScalarMultiplicationTests : public ::testing::Test { public: const std::string SRS_PATH = []() { if constexpr (std::same_as) { @@ -44,9 +55,9 @@ template class SRSIO : public ::testing::Test { using Curves = ::testing::Types; -TYPED_TEST_SUITE(SRSIO, Curves); +TYPED_TEST_SUITE(ScalarMultiplicationTests, Curves); -TYPED_TEST(SRSIO, ReduceBucketsSimple) +TYPED_TEST(ScalarMultiplicationTests, ReduceBucketsSimple) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -235,7 +246,7 @@ TYPED_TEST(SRSIO, ReduceBucketsSimple) } } -TYPED_TEST(SRSIO, ReduceBuckets) +TYPED_TEST(ScalarMultiplicationTests, ReduceBuckets) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -361,7 +372,7 @@ TYPED_TEST(SRSIO, ReduceBuckets) } // This test intermittenly fails. -TYPED_TEST(SRSIO, DISABLED_ReduceBucketsBasic) +TYPED_TEST(ScalarMultiplicationTests, DISABLED_ReduceBucketsBasic) { using Curve = TypeParam; using AffineElement = typename Curve::AffineElement; @@ -446,7 +457,7 @@ TYPED_TEST(SRSIO, DISABLED_ReduceBucketsBasic) aligned_free(bucket_counts); } -TYPED_TEST(SRSIO, AddAffinePoints) +TYPED_TEST(ScalarMultiplicationTests, AddAffinePoints) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -483,7 +494,7 @@ TYPED_TEST(SRSIO, AddAffinePoints) aligned_free(scratch_space); } -TYPED_TEST(SRSIO, ConstructAdditionChains) +TYPED_TEST(ScalarMultiplicationTests, ConstructAdditionChains) { using Curve = TypeParam; using AffineElement = typename Curve::AffineElement; @@ -554,7 +565,7 @@ TYPED_TEST(SRSIO, ConstructAdditionChains) aligned_free(bucket_counts); } -TYPED_TEST(SRSIO, EndomorphismSplit) +TYPED_TEST(ScalarMultiplicationTests, EndomorphismSplit) { using Curve = TypeParam; using Group = typename Curve::Group; @@ -597,7 +608,7 @@ TYPED_TEST(SRSIO, EndomorphismSplit) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, RadixSort) +TYPED_TEST(ScalarMultiplicationTests, RadixSort) { using Curve = TypeParam; using Fr = typename Curve::ScalarField; @@ -645,7 +656,7 @@ TYPED_TEST(SRSIO, RadixSort) free(wnaf_copy); } -TYPED_TEST(SRSIO, OversizedInputs) +TYPED_TEST(ScalarMultiplicationTests, OversizedInputs) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -696,7 +707,7 @@ TYPED_TEST(SRSIO, OversizedInputs) aligned_free(scalars); } -TYPED_TEST(SRSIO, UndersizedInputs) +TYPED_TEST(ScalarMultiplicationTests, UndersizedInputs) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -736,7 +747,7 @@ TYPED_TEST(SRSIO, UndersizedInputs) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, PippengerSmall) +TYPED_TEST(ScalarMultiplicationTests, PippengerSmall) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -773,7 +784,7 @@ TYPED_TEST(SRSIO, PippengerSmall) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, PippengerEdgeCaseDbl) +TYPED_TEST(ScalarMultiplicationTests, PippengerEdgeCaseDbl) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -812,7 +823,7 @@ TYPED_TEST(SRSIO, PippengerEdgeCaseDbl) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, PippengerShortInputs) +TYPED_TEST(ScalarMultiplicationTests, PippengerShortInputs) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -869,7 +880,7 @@ TYPED_TEST(SRSIO, PippengerShortInputs) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, PippengerUnsafe) +TYPED_TEST(ScalarMultiplicationTests, PippengerUnsafe) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -906,7 +917,7 @@ TYPED_TEST(SRSIO, PippengerUnsafe) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, PippengerUnsafeShortInputs) +TYPED_TEST(ScalarMultiplicationTests, PippengerUnsafeShortInputs) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -964,7 +975,7 @@ TYPED_TEST(SRSIO, PippengerUnsafeShortInputs) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, PippengerOne) +TYPED_TEST(ScalarMultiplicationTests, PippengerOne) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -1001,7 +1012,7 @@ TYPED_TEST(SRSIO, PippengerOne) EXPECT_EQ(result == expected, true); } -TYPED_TEST(SRSIO, PippengerZeroPoints) +TYPED_TEST(ScalarMultiplicationTests, PippengerZeroPoints) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -1021,7 +1032,7 @@ TYPED_TEST(SRSIO, PippengerZeroPoints) EXPECT_EQ(result.is_point_at_infinity(), true); } -TYPED_TEST(SRSIO, PippengerMulByZero) +TYPED_TEST(ScalarMultiplicationTests, PippengerMulByZero) { using Curve = TypeParam; using Group = typename Curve::Group; From e76d0607a718e4d4486b2f4c487ead67e2a521df Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Mon, 12 Jun 2023 13:44:13 +0000 Subject: [PATCH 4/5] Switch aztec packages to master --- cpp/.aztec-packages-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/.aztec-packages-commit b/cpp/.aztec-packages-commit index e0ba790642..8b25206ff9 100644 --- a/cpp/.aztec-packages-commit +++ b/cpp/.aztec-packages-commit @@ -1 +1 @@ -1dbca53b4cf6c83d1a25be66bb7b7f4a9d5e484b \ No newline at end of file +master \ No newline at end of file From c01216180ff2ab8745218769f0d113bed09c65f7 Mon Sep 17 00:00:00 2001 From: codygunton Date: Mon, 12 Jun 2023 16:23:36 +0000 Subject: [PATCH 5/5] Cleanup --- .../ultra_honk_composer_helper.cpp | 18 ------------------ .../circuit_constructor_base.hpp | 2 +- .../recursion/verifier/verifier.test.cpp | 3 +-- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp b/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp index 8ca5c7a7d6..3516adb6e8 100644 --- a/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp +++ b/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp @@ -297,24 +297,6 @@ std::shared_ptr UltraHonkComposerHe proving_key->table_3 = poly_q_table_column_3; proving_key->table_4 = poly_q_table_column_4; - // Copy memory read/write record data into proving key. Prover needs to know which gates contain a read/write - // 'record' witness on the 4th wire. This wire value can only be fully computed once the first 3 wire polynomials - // have been committed to. The 4th wire on these gates will be a random linear combination of the first 3 wires, - // using the plookup challenge `eta`. Because we shift the gates by the number of public inputs, we need to update - // the records with the public_inputs offset - const uint32_t public_inputs_count = static_cast(circuit_constructor.public_inputs.size()); - auto add_public_inputs_offset = [public_inputs_count](uint32_t gate_index) { - return gate_index + public_inputs_count; - }; - std::transform(circuit_constructor.memory_read_records.begin(), - circuit_constructor.memory_read_records.end(), - std::back_inserter(proving_key->memory_read_records), - add_public_inputs_offset); - std::transform(circuit_constructor.memory_write_records.begin(), - circuit_constructor.memory_write_records.end(), - std::back_inserter(proving_key->memory_write_records), - add_public_inputs_offset); - proving_key->recursive_proof_public_input_indices = std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); diff --git a/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp b/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp index 3ef4a3457e..cc75e8881c 100644 --- a/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp +++ b/cpp/src/barretenberg/proof_system/circuit_constructors/circuit_constructor_base.hpp @@ -297,7 +297,7 @@ template class CircuitConstructorBase { _failed = true; set_err(msg); } -}; // namespace proof_system +}; } // namespace proof_system diff --git a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp index bc943a2051..95c433dbfc 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp +++ b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp @@ -283,8 +283,7 @@ template class stdlib_verifier : public testing::Test { * recursive proof-specific public inputs, so we can't check the recursive proof fully in check_circuit. So we use * this additional function to check that the recursive proof points work. * - * @return true - * @return false + * @return boolean result */ static bool check_recursive_proof_public_inputs(OuterComposer& composer, const barretenberg::pairing::miller_lines* lines)