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 diff --git a/cpp/src/barretenberg/common/log.hpp b/cpp/src/barretenberg/common/log.hpp index 8207ccf478..a347f0bd5f 100644 --- a/cpp/src/barretenberg/common/log.hpp +++ b/cpp/src/barretenberg/common/log.hpp @@ -9,15 +9,23 @@ #define BENCHMARK_INFO_SEPARATOR "#" #define BENCHMARK_INFO_SUFFIX "##BENCHMARK_INFO_SUFFIX##" #define GET_COMPOSER_NAME_STRING(composer) \ - (typeid(composer) == typeid(plonk::StandardPlonkComposer) ? "StandardPlonk" \ - : typeid(composer) == typeid(plonk::TurboPlonkComposer) ? "TurboPlonk" \ - : typeid(composer) == typeid(plonk::UltraPlonkComposer) ? "UltraPlonk" \ - : typeid(composer) == typeid(honk::StandardHonkComposer) ? "StandardHonk" \ - : typeid(composer) == typeid(honk::UltraHonkComposer) ? "UltraHonk" \ - : typeid(composer) == typeid(proof_system::StandardCircuitConstructor) ? "StandardArithemtization" \ - : typeid(composer) == typeid(proof_system::TurboCircuitConstructor) ? "TurboArithemtization" \ - : typeid(composer) == typeid(proof_system::UltraCircuitConstructor) ? "UltraArithmetization" \ - : "NullPlonk") + (typeid(composer) == typeid(plonk::StandardPlonkComposer) \ + ? "StandardPlonk" \ + : typeid(composer) == typeid(plonk::TurboPlonkComposer) \ + ? "TurboPlonk" \ + : typeid(composer) == typeid(plonk::UltraPlonkComposer) \ + ? "UltraPlonk" \ + : typeid(composer) == typeid(honk::StandardHonkComposer) \ + ? "StandardHonk" \ + : typeid(composer) == typeid(honk::UltraHonkComposer) \ + ? "UltraHonk" \ + : typeid(composer) == typeid(proof_system::StandardCircuitConstructor) \ + ? "StandardArithemtization" \ + : typeid(composer) == typeid(proof_system::TurboCircuitConstructor) \ + ? "TurboArithemtization" \ + : typeid(composer) == typeid(proof_system::UltraCircuitConstructor) \ + ? "UltraArithmetization" \ + : "NullPlonk") namespace { diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index ae44bfb2dd..9a7ca42767 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -103,7 +103,7 @@ void create_circuit(Composer& composer, acir_format const& constraint_system) if (i == constraint_system.recursion_constraints.size() - 1) { std::vector proof_output_witness_indices(constraint.output_aggregation_object.begin(), constraint.output_aggregation_object.end()); - composer.set_recursive_proof(proof_output_witness_indices); + composer.circuit_constructor.set_recursive_proof(proof_output_witness_indices); } } } @@ -230,7 +230,7 @@ void create_circuit_with_witness(Composer& composer, acir_format const& constrai if (i == constraint_system.recursion_constraints.size() - 1) { std::vector proof_output_witness_indices(constraint.output_aggregation_object.begin(), constraint.output_aggregation_object.end()); - composer.set_recursive_proof(proof_output_witness_indices); + composer.circuit_constructor.set_recursive_proof(proof_output_witness_indices); } } } 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/honk/composer/composer_helper/ultra_honk_composer_helper.cpp b/cpp/src/barretenberg/honk/composer/composer_helper/ultra_honk_composer_helper.cpp index f48db805ea..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 @@ -134,17 +134,23 @@ void UltraHonkComposerHelper::compute_witness(CircuitConstructor& circuit_constr // 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` + // 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; + }; proving_key->memory_read_records = std::vector(); proving_key->memory_write_records = std::vector(); - proving_key->memory_read_records.reserve(circuit_constructor.memory_read_records.size()); - proving_key->memory_write_records.reserve(circuit_constructor.memory_write_records.size()); - 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)); + + 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); computed_witness = true; } diff --git a/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp index d84918c766..23ba1b043f 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_honk_composer.hpp @@ -52,8 +52,8 @@ class UltraHonkComposer { , 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) { // TODO(#217/#423): Related to issue of ensuring no identically 0 polynomials add_gates_to_ensure_all_polys_are_non_zero(); 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/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 ffe110da21..82273ebda0 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 { // The crs_factory holds the path to the srs and exposes methods to extract the srs elements 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 63d68b5425..79bd7015e8 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 @@ -23,9 +23,6 @@ class TurboPlonkComposerHelper { // The crs_factory holds the path to the srs and exposes methods to extract the srs elements 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( @@ -61,20 +58,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 3189ff8a66..580c67bf8a 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 @@ -142,17 +142,23 @@ void UltraPlonkComposerHelper::compute_witness(CircuitConstructor& circuit_const // 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` + // 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; + }; circuit_proving_key->memory_read_records = std::vector(); circuit_proving_key->memory_write_records = std::vector(); - circuit_proving_key->memory_read_records.reserve(circuit_constructor.memory_read_records.size()); - circuit_proving_key->memory_write_records.reserve(circuit_constructor.memory_write_records.size()); - 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)); + + 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); computed_witness = true; } @@ -469,9 +475,10 @@ std::shared_ptr UltraPlonkComposerHelper::compute_proving_key(Circu circuit_proving_key->polynomial_store.put("s_fft", std::move(s_fft)); 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; } @@ -498,9 +505,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 9bdc18fd37..bcd81480f4 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 { // The crs_factory holds the path to the srs and exposes methods to extract the srs elements 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,46 +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)); - } - } - - /** - * @brief Update recursive_proof_public_input_indices with existing public inputs that represent a recursive proof - * - * @param proof_output_witness_indices - */ - void set_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 (size_t i = 0; i < proof_output_witness_indices.size(); ++i) { - recursive_proof_public_input_indices.push_back(circuit_constructor.get_public_input_index( - circuit_constructor.real_variable_index[proof_output_witness_indices[i]])); - } - } - 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 16e2086597..fcb2dfaf83 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(std::unique_ptr( @@ -69,8 +69,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, @@ -80,8 +80,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) {} @@ -93,8 +93,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; @@ -104,8 +104,8 @@ class StandardPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(std::move(other.composer_helper)) - , 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& operator=(StandardPlonkComposer&& other) { @@ -114,8 +114,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; return *this; }; // TODO(#230)(Cody): This constructor started to be implicitly deleted when I added `n` and `variables` members. @@ -244,7 +244,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 13baceab2d..21a650ecdc 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(std::unique_ptr( @@ -66,8 +66,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) @@ -76,8 +76,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, @@ -87,8 +87,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; @@ -98,8 +98,8 @@ class TurboPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(std::move(other.composer_helper)) - , 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& operator=(TurboPlonkComposer&& other) { @@ -108,8 +108,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; return *this; }; // TODO(#230)(Cody): This constructor started to be implicitly deleted when I added `n` and `variables` members. @@ -250,7 +250,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 1a73a4e022..878042a1be 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_plonk_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_plonk_composer.hpp @@ -54,8 +54,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, @@ -65,8 +65,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) : circuit_constructor(std::move(other.circuit_constructor)) @@ -74,8 +74,8 @@ class UltraPlonkComposer { , variables(circuit_constructor.variables) , zero_idx(circuit_constructor.zero_idx) , composer_helper(std::move(other.composer_helper)) - , 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& operator=(UltraPlonkComposer&& other) { circuit_constructor = std::move(other.circuit_constructor); @@ -83,8 +83,8 @@ class UltraPlonkComposer { 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; return *this; }; ~UltraPlonkComposer() = default; @@ -227,12 +227,12 @@ 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 set_recursive_proof(const std::vector& proof_output_witness_indices) { - composer_helper.set_recursive_proof(circuit_constructor, proof_output_witness_indices); + circuit_constructor.set_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 58b21aa987..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 @@ -41,6 +41,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; @@ -246,6 +250,44 @@ 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)); + } + } + + /** + * @brief Update recursive_proof_public_input_indices with existing public inputs that represent a recursive proof + * + * @param proof_output_witness_indices + */ + void set_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 (size_t i = 0; i < proof_output_witness_indices.size(); ++i) { + recursive_proof_public_input_indices.push_back( + get_public_input_index(real_variable_index[proof_output_witness_indices[i]])); + } + } + bool failed() const { return _failed; }; const std::string& err() const { return _err; }; 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 89903893dd..3f7ce41ed1 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; } @@ -2279,7 +2279,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]; @@ -2332,8 +2332,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. @@ -2365,7 +2365,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; @@ -2439,15 +2439,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: { @@ -2507,16 +2505,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 d11c475169..e5bcd0b5f4 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 @@ -645,19 +645,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"); @@ -1121,8 +1108,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); @@ -1132,8 +1119,8 @@ class UltraCircuitConstructor : public CircuitConstructorBase -concept HasMsgPack = requires(T t, DoNothing nop) { t.msgpack(nop); }; +template concept HasMsgPack = requires(T t, DoNothing nop) +{ + t.msgpack(nop); +}; -template -concept HasMsgPackSchema = requires(const T t, DoNothing nop) { t.msgpack_schema(nop); }; +template concept HasMsgPackSchema = requires(const T t, DoNothing nop) +{ + t.msgpack_schema(nop); +}; -template -concept HasMsgPackPack = requires(T t, DoNothing nop) { t.msgpack_pack(nop); }; +template concept HasMsgPackPack = requires(T t, DoNothing nop) +{ + t.msgpack_pack(nop); +}; } // namespace msgpack_concepts diff --git a/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp b/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp index 370272a004..a5d4213635 100644 --- a/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp +++ b/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp @@ -102,8 +102,10 @@ inline void _schema_pack_map_content(MsgpackSchemaPacker&) } namespace msgpack_concepts { -template -concept SchemaPackable = requires(T value, MsgpackSchemaPacker packer) { msgpack_schema_pack(packer, value); }; +template concept SchemaPackable = requires(T value, MsgpackSchemaPacker packer) +{ + msgpack_schema_pack(packer, value); +}; } // namespace msgpack_concepts // Helper for packing (key, value, key, value, ...) arguments @@ -119,8 +121,8 @@ inline void _schema_pack_map_content(MsgpackSchemaPacker& packer, std::string ke } template - requires(!msgpack_concepts::HasMsgPackSchema && !msgpack_concepts::HasMsgPack) -inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const& obj) +requires(!msgpack_concepts::HasMsgPackSchema && + !msgpack_concepts::HasMsgPack) inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const& obj) { packer.pack(msgpack_schema_name(obj)); } @@ -144,8 +146,8 @@ inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const& obj) * @param object The object in question. */ template - requires(!msgpack_concepts::HasMsgPackSchema) -inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const& object) +requires(!msgpack_concepts::HasMsgPackSchema) inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, + T const& object) { std::string type = msgpack_schema_name(object); packer.pack_with_name(type, object); diff --git a/cpp/src/barretenberg/srs/io.hpp b/cpp/src/barretenberg/srs/io.hpp index 4d1a1a2288..594deb77eb 100644 --- a/cpp/src/barretenberg/srs/io.hpp +++ b/cpp/src/barretenberg/srs/io.hpp @@ -46,8 +46,10 @@ struct Manifest { }; // Detect whether a curve has a G2AffineElement defined -template -concept HasG2 = requires { typename Curve::G2AffineElement; }; +template concept HasG2 = requires +{ + typename Curve::G2AffineElement; +}; // If Curve has a G2AffineElement type, check whether T is this type. template @@ -321,8 +323,7 @@ template class IO { } } - static void read_transcript_g2(auto& g2_x, std::string const& dir) - requires HasG2 + static void read_transcript_g2(auto& g2_x, std::string const& dir) requires HasG2 { const size_t g2_size = sizeof(typename Curve::G2BaseField) * 2; std::string path = format(dir, "/g2.dat"); @@ -355,8 +356,10 @@ template class IO { byteswap(&g2_x, size); } - static void read_transcript(AffineElement* monomials, auto& g2_x, size_t degree, std::string const& path) - requires HasG2 + static void read_transcript(AffineElement* monomials, + auto& g2_x, + size_t degree, + std::string const& path) requires HasG2 { read_transcript_g1(monomials, degree, path); read_transcript_g2(g2_x, path); @@ -371,8 +374,7 @@ template class IO { static void write_transcript(AffineElement const* g1_x, auto const* g2_x, Manifest const& manifest, - std::string const& dir) - requires HasG2 + std::string const& dir) requires HasG2 { const size_t num_g1_x = manifest.num_g1_points; const size_t num_g2_x = manifest.num_g2_points; 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 da27ec1814..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) { @@ -25,8 +36,7 @@ template class SRSIO : public ::testing::Test { } }(); - static void read_transcript_g2(std::string const& srs_path) - requires srs::HasG2 + static void read_transcript_g2(std::string const& srs_path) requires srs::HasG2 { typename Curve::G2AffineElement g2_x; srs::IO::read_transcript_g2(g2_x, srs_path); @@ -45,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; @@ -236,7 +246,7 @@ TYPED_TEST(SRSIO, ReduceBucketsSimple) } } -TYPED_TEST(SRSIO, ReduceBuckets) +TYPED_TEST(ScalarMultiplicationTests, ReduceBuckets) { using Curve = TypeParam; using Element = typename Curve::Element; @@ -362,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; @@ -447,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; @@ -484,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; @@ -555,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; @@ -598,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; @@ -646,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; @@ -697,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; @@ -737,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; @@ -774,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; @@ -813,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; @@ -870,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; @@ -907,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; @@ -965,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; @@ -1002,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; @@ -1022,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; diff --git a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp index 97cd566e3a..95c433dbfc 100644 --- a/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp +++ b/cpp/src/barretenberg/stdlib/recursion/verifier/verifier.test.cpp @@ -276,6 +276,62 @@ 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 boolean result + */ + 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 +363,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 +399,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 +417,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 +469,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 +514,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 +561,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 +605,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 +649,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()