diff --git a/barretenberg/Earthfile b/barretenberg/Earthfile index 73dc1443992..1eb57ff2507 100644 --- a/barretenberg/Earthfile +++ b/barretenberg/Earthfile @@ -42,7 +42,7 @@ barretenberg-acir-tests-bb: RUN FLOW=prove_and_verify_mega_honk_program ./run_acir_tests.sh # Fold and verify an ACIR program stack using ClientIvc RUN FLOW=fold_and_verify_program ./run_acir_tests.sh fold_basic - # Fold and verify an ACIR program stack using ClientIvc, recursively verify as part of the Tube circuit and produce and verify a Honk proof + # Fold and verify an ACIR program stack using ClientIvc, recursively verify as part of the Tube circuit and produce and verify a Honk proof RUN FLOW=prove_then_verify_tube ./run_acir_tests.sh fold_basic # Construct and separately verify a UltraHonk proof for a single program that recursively verifies a Honk proof RUN FLOW=prove_then_verify_ultra_honk ./run_acir_tests.sh verify_honk_proof diff --git a/barretenberg/acir_tests/flows/prove_then_verify_ultra_honk.sh b/barretenberg/acir_tests/flows/prove_then_verify_ultra_honk.sh index fd559e256c6..ac3bb9bc962 100755 --- a/barretenberg/acir_tests/flows/prove_then_verify_ultra_honk.sh +++ b/barretenberg/acir_tests/flows/prove_then_verify_ultra_honk.sh @@ -1,5 +1,5 @@ #!/bin/sh -set -eu +set -eux VFLAG=${VERBOSE:+-v} BFLAG="-b ./target/program.json" diff --git a/barretenberg/cpp/src/CMakeLists.txt b/barretenberg/cpp/src/CMakeLists.txt index be6d254b723..077d20a4c3b 100644 --- a/barretenberg/cpp/src/CMakeLists.txt +++ b/barretenberg/cpp/src/CMakeLists.txt @@ -56,6 +56,7 @@ add_subdirectory(barretenberg/bb) add_subdirectory(barretenberg/circuit_checker) add_subdirectory(barretenberg/client_ivc) add_subdirectory(barretenberg/commitment_schemes) +add_subdirectory(barretenberg/commitment_schemes_recursion) add_subdirectory(barretenberg/common) add_subdirectory(barretenberg/crypto) add_subdirectory(barretenberg/dsl) diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index 114e2f0caf2..1045d543d21 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -741,18 +741,15 @@ bool avm_verify(const std::filesystem::path& proof_path, const std::filesystem:: #endif /** - * @brief Creates a proof for an ACIR circuit - * - * Communication: - * - stdout: The proof is written to stdout as a byte array - * - Filesystem: The proof is written to the path specified by outputPath + * @brief Create a Honk a prover from program bytecode and an optional witness * - * @param bytecodePath Path to the file containing the serialized circuit - * @param witnessPath Path to the file containing the serialized witness - * @param outputPath Path to write the proof to + * @tparam Flavor + * @param bytecodePath + * @param witnessPath + * @return UltraProver_ */ -template -void prove_honk(const std::string& bytecodePath, const std::string& witnessPath, const std::string& outputPath) +template +UltraProver_ compute_valid_prover(const std::string& bytecodePath, const std::string& witnessPath) { using Builder = Flavor::CircuitBuilder; using Prover = UltraProver_; @@ -762,7 +759,10 @@ void prove_honk(const std::string& bytecodePath, const std::string& witnessPath, honk_recursion = true; } auto constraint_system = get_constraint_system(bytecodePath, honk_recursion); - auto witness = get_witness(witnessPath); + acir_format::WitnessVector witness = {}; + if (!witnessPath.empty()) { + witness = get_witness(witnessPath); + } auto builder = acir_format::create_circuit(constraint_system, 0, witness, honk_recursion); @@ -770,8 +770,29 @@ void prove_honk(const std::string& bytecodePath, const std::string& witnessPath, size_t srs_size = builder.get_circuit_subgroup_size(builder.get_total_circuit_size() + num_extra_gates); init_bn254_crs(srs_size); - // Construct Honk proof Prover prover{ builder }; + return prover; +} + +/** + * @brief Creates a proof for an ACIR circuit + * + * Communication: + * - stdout: The proof is written to stdout as a byte array + * - Filesystem: The proof is written to the path specified by outputPath + * + * @param bytecodePath Path to the file containing the serialized circuit + * @param witnessPath Path to the file containing the serialized witness + * @param outputPath Path to write the proof to + */ +template +void prove_honk(const std::string& bytecodePath, const std::string& witnessPath, const std::string& outputPath) +{ + // using Builder = Flavor::CircuitBuilder; + using Prover = UltraProver_; + + // Construct Honk proof + Prover prover = compute_valid_prover(bytecodePath, witnessPath); auto proof = prover.construct_proof(); if (outputPath == "-") { @@ -807,10 +828,9 @@ template bool verify_honk(const std::string& proof_path, auto g2_data = get_bn254_g2_data(CRS_PATH); srs::init_crs_factory({}, g2_data); auto proof = from_buffer>(read_file(proof_path)); - auto verification_key = std::make_shared(from_buffer(read_file(vk_path))); - verification_key->pcs_verification_key = std::make_shared(); - - Verifier verifier{ verification_key }; + auto vk = std::make_shared(from_buffer(read_file(vk_path))); + vk->pcs_verification_key = std::make_shared(); + Verifier verifier{ vk }; bool verified = verifier.verify_proof(proof); @@ -830,22 +850,12 @@ template bool verify_honk(const std::string& proof_path, */ template void write_vk_honk(const std::string& bytecodePath, const std::string& outputPath) { - using Builder = Flavor::CircuitBuilder; + using Prover = UltraProver_; using ProverInstance = ProverInstance_; using VerificationKey = Flavor::VerificationKey; - bool honk_recursion = false; - if constexpr (IsAnyOf) { - honk_recursion = true; - } - auto constraint_system = get_constraint_system(bytecodePath, honk_recursion); - auto builder = acir_format::create_circuit(constraint_system, 0, {}, honk_recursion); - - auto num_extra_gates = builder.get_num_gates_added_to_ensure_nonzero_polynomials(); - size_t srs_size = builder.get_circuit_subgroup_size(builder.get_total_circuit_size() + num_extra_gates); - init_bn254_crs(srs_size); - - ProverInstance prover_inst(builder); + Prover prover = compute_valid_prover(bytecodePath, ""); + ProverInstance& prover_inst = *prover.instance; VerificationKey vk( prover_inst.proving_key); // uses a partial form of the proving key which only has precomputed entities diff --git a/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/goblin.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/goblin.bench.cpp deleted file mode 100644 index 5ad7944451a..00000000000 --- a/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/goblin.bench.cpp +++ /dev/null @@ -1,144 +0,0 @@ - -#include - -#include "barretenberg/common/op_count_google_bench.hpp" -#include "barretenberg/goblin/goblin.hpp" -#include "barretenberg/goblin/mock_circuits.hpp" -#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" - -using namespace benchmark; -using namespace bb; - -namespace { - -class GoblinBench : public benchmark::Fixture { - public: - GoblinAccumulationOutput kernel_accum; - - // Number of function circuits to accumulate(based on Zacs target numbers) - static constexpr size_t NUM_ITERATIONS_MEDIUM_COMPLEXITY = 6; - - void SetUp([[maybe_unused]] const ::benchmark::State& state) override - { - bb::srs::init_crs_factory("../srs_db/ignition"); - bb::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } - - /** - * @brief Perform a specified number of function circuit accumulation rounds - * @details Each round "accumulates" a mock function circuit and a mock kernel circuit. Each round thus consists of - * the generation of two circuits, two MegaHonk proofs and two Merge proofs. To match the sizes called out in the - * spec - * (https://github.com/AztecProtocol/aztec-packages/blob/master/yellow-paper/docs/cryptography/performance-targets.md) - * we set the size of the function circuit to be 2^17 except for the first one which is 2^19. - * - * @param state - */ - void perform_goblin_accumulation_rounds(State& state, GoblinProver& goblin) - { - auto NUM_CIRCUITS = static_cast(state.range(0)); - for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - - // Construct and accumulate a mock function circuit - MegaCircuitBuilder function_circuit{ goblin.op_queue }; - // On the first iteration construct a "large" function circuit (2^19), otherwise medium (2^17) - GoblinMockCircuits::construct_mock_function_circuit(function_circuit, /*large=*/circuit_idx == 0); - auto function_accum = goblin.accumulate(function_circuit); - - // Construct and accumulate the mock kernel circuit - // Note: in first round, kernel_accum is empty since there is no previous kernel to recursively verify - MegaCircuitBuilder circuit_builder{ goblin.op_queue }; - GoblinMockCircuits::construct_mock_recursion_kernel_circuit( - circuit_builder, - { function_accum.proof, function_accum.verification_key }, - { kernel_accum.proof, kernel_accum.verification_key }); - kernel_accum = goblin.accumulate(circuit_builder); - } - } -}; - -/** - * @brief Benchmark the full Goblin IVC protocol - * - */ -BENCHMARK_DEFINE_F(GoblinBench, GoblinFull)(benchmark::State& state) -{ - GoblinProver goblin; - - for (auto _ : state) { - BB_REPORT_OP_COUNT_IN_BENCH(state); - // Perform a specified number of iterations of function/kernel accumulation - perform_goblin_accumulation_rounds(state, goblin); - - // Construct proofs for ECCVM and Translator - goblin.prove(); - } -} - -/** - * @brief Benchmark only the accumulation rounds - * - */ -BENCHMARK_DEFINE_F(GoblinBench, GoblinAccumulate)(benchmark::State& state) -{ - GoblinProver goblin; - - // Perform a specified number of iterations of function/kernel accumulation - for (auto _ : state) { - perform_goblin_accumulation_rounds(state, goblin); - } -} - -/** - * @brief Benchmark only the ECCVM component - * - */ -BENCHMARK_DEFINE_F(GoblinBench, GoblinECCVMProve)(benchmark::State& state) -{ - GoblinProver goblin; - - // Perform a specified number of iterations of function/kernel accumulation - perform_goblin_accumulation_rounds(state, goblin); - - // Prove ECCVM only - for (auto _ : state) { - goblin.prove_eccvm(); - } -} - -/** - * @brief Benchmark only the Translator component - * - */ -BENCHMARK_DEFINE_F(GoblinBench, TranslatorProve)(benchmark::State& state) -{ - GoblinProver goblin; - - // Perform a specified number of iterations of function/kernel accumulation - perform_goblin_accumulation_rounds(state, goblin); - - // Prove ECCVM (unmeasured) and Translator (measured) - goblin.prove_eccvm(); - for (auto _ : state) { - goblin.prove_translator(); - } -} - -#define ARGS \ - Arg(GoblinBench::NUM_ITERATIONS_MEDIUM_COMPLEXITY) \ - ->Arg(1 << 0) \ - ->Arg(1 << 1) \ - ->Arg(1 << 2) \ - ->Arg(1 << 3) \ - ->Arg(1 << 4) \ - ->Arg(1 << 5) \ - ->Arg(1 << 6) - -BENCHMARK_REGISTER_F(GoblinBench, GoblinFull)->Unit(benchmark::kMillisecond)->ARGS; -BENCHMARK_REGISTER_F(GoblinBench, GoblinAccumulate)->Unit(benchmark::kMillisecond)->ARGS; -BENCHMARK_REGISTER_F(GoblinBench, GoblinECCVMProve)->Unit(benchmark::kMillisecond)->ARGS; -BENCHMARK_REGISTER_F(GoblinBench, TranslatorProve)->Unit(benchmark::kMillisecond)->ARGS; - -} // namespace - -BENCHMARK_MAIN(); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp index 23fb76a9502..909a40cd439 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp @@ -29,11 +29,11 @@ template class VerifierCommitmentKey; * @tparam curve::BN254 */ template <> class VerifierCommitmentKey { + public: using Curve = curve::BN254; using GroupElement = typename Curve::Element; using Commitment = typename Curve::AffineElement; - public: VerifierCommitmentKey() { srs::init_crs_factory("../srs_db/ignition"); @@ -69,11 +69,11 @@ template <> class VerifierCommitmentKey { * @tparam curve::Grumpkin */ template <> class VerifierCommitmentKey { + public: using Curve = curve::Grumpkin; using GroupElement = typename Curve::Element; using Commitment = typename Curve::AffineElement; - public: /** * @brief Construct a new IPA Verification Key object from existing SRS * diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp index f6a77ba302c..2b507523865 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp @@ -6,6 +6,8 @@ #include "barretenberg/common/ref_vector.hpp" #include "barretenberg/common/zip_view.hpp" #include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" +#include "barretenberg/stdlib/primitives/witness/witness.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb { @@ -69,9 +71,6 @@ template class ZeroMorphProver_ { std::span u_challenge) { size_t log_N = numeric::get_msb(polynomial.size()); - // The size of the multilinear challenge must equal the log of the polynomial size - ASSERT(log_N == u_challenge.size()); - // Define the vector of quotients q_k, k = 0, ..., log_N-1 std::vector quotients; for (size_t k = 0; k < log_N; ++k) { @@ -323,7 +322,8 @@ template class ZeroMorphProver_ { * * @todo https://github.com/AztecProtocol/barretenberg/issues/1030: document concatenation trick */ - static OpeningClaim prove(RefSpan f_polynomials, + static OpeningClaim prove(FF circuit_size, + RefSpan f_polynomials, RefSpan g_polynomials, RefSpan f_evaluations, RefSpan g_shift_evaluations, @@ -339,7 +339,7 @@ template class ZeroMorphProver_ { // Extract multilinear challenge u and claimed multilinear evaluations from Sumcheck output std::span u_challenge = multilinear_challenge; - size_t log_N = u_challenge.size(); + size_t log_N = numeric::get_msb(static_cast(circuit_size)); size_t N = 1 << log_N; // Compute batching of unshifted polynomials f_i and to-be-shifted polynomials g_i: @@ -392,15 +392,18 @@ template class ZeroMorphProver_ { f_polynomial += concatenated_batched; // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) - auto quotients = compute_multilinear_quotients(f_polynomial, u_challenge); - + std::vector quotients = compute_multilinear_quotients(f_polynomial, u_challenge); // Compute and send commitments C_{q_k} = [q_k], k = 0,...,d-1 - std::vector q_k_commitments; - q_k_commitments.reserve(log_N); for (size_t idx = 0; idx < log_N; ++idx) { - q_k_commitments[idx] = commitment_key->commit(quotients[idx]); + Commitment q_k_commitment = commitment_key->commit(quotients[idx]); std::string label = "ZM:C_q_" + std::to_string(idx); - transcript->send_to_verifier(label, q_k_commitments[idx]); + transcript->send_to_verifier(label, q_k_commitment); + } + // Add buffer elements to remove log_N dependence in proof + for (size_t idx = log_N; idx < CONST_PROOF_SIZE_LOG_N; ++idx) { + auto buffer_element = Commitment::one(); + std::string label = "ZM:C_q_" + std::to_string(idx); + transcript->send_to_verifier(label, buffer_element); } // Get challenge y @@ -462,10 +465,19 @@ template class ZeroMorphVerifier_ { static Commitment compute_C_zeta_x(const Commitment& C_q, std::vector& C_q_k, FF y_challenge, - FF x_challenge) + FF x_challenge, + const FF log_circuit_size, + const FF circuit_size) { - size_t log_N = C_q_k.size(); - size_t N = 1 << log_N; + size_t N{ 0 }; + size_t log_N{ 0 }; + if constexpr (Curve::is_stdlib_type) { + N = static_cast(circuit_size.get_value()); + log_N = static_cast(log_circuit_size.get_value()); + } else { + N = static_cast(circuit_size); + log_N = static_cast(log_circuit_size); + } // Instantiate containers for input to batch mul std::vector scalars; @@ -480,21 +492,40 @@ template class ZeroMorphVerifier_ { } commitments.emplace_back(C_q); - // Contribution from C_q_k, k = 0,...,log_N - for (size_t k = 0; k < log_N; ++k) { + // Contribution from C_q_k, k = 0,...,log_N-1 + for (size_t k = 0; k < CONST_PROOF_SIZE_LOG_N; ++k) { + // Utilize dummy rounds in order to make verifier circuit independent of proof size + bool is_dummy_round = k >= log_N; auto deg_k = static_cast((1 << k) - 1); // Compute scalar y^k * x^{N - deg_k - 1} - auto scalar = y_challenge.pow(k); - scalar *= x_challenge.pow(N - deg_k - 1); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1039): pow may not add proper constraints + FF scalar = y_challenge.pow(k); + size_t x_exponent = is_dummy_round ? 0 : N - deg_k - 1; + scalar *= x_challenge.pow(x_exponent); scalar *= FF(-1); - + if constexpr (Curve::is_stdlib_type) { + auto builder = x_challenge.get_context(); + FF zero = FF::from_witness(builder, 0); + stdlib::bool_t dummy_round = stdlib::witness_t(builder, is_dummy_round); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1039): is it kosher to reassign like this? + scalar = FF::conditional_assign(dummy_round, zero, scalar); + } else { + if (is_dummy_round) { + scalar = 0; + } + } scalars.emplace_back(scalar); commitments.emplace_back(C_q_k[k]); } // Compute batch mul to get the result if constexpr (Curve::is_stdlib_type) { - return Commitment::batch_mul(commitments, scalars); + // If Ultra and using biggroup, handle edge cases in batch_mul + if constexpr (IsUltraBuilder && stdlib::IsBigGroup) { + return Commitment::batch_mul(commitments, scalars, /*max_num_bits=*/0, /*with_edgecases=*/true); + } else { + return Commitment::batch_mul(commitments, scalars); + } } else { return batch_mul_native(commitments, scalars); } @@ -533,15 +564,25 @@ template class ZeroMorphVerifier_ { FF batched_evaluation, FF x_challenge, std::span u_challenge, + const FF log_circuit_size, + const FF circuit_size, const std::vector>& concatenation_groups_commitments = {}) { - size_t log_N = C_q_k.size(); - size_t N = 1 << log_N; + size_t N{ 0 }; + size_t log_N{ 0 }; + if constexpr (Curve::is_stdlib_type) { + N = static_cast(circuit_size.get_value()); + log_N = static_cast(log_circuit_size.get_value()); + } else { + N = static_cast(circuit_size); + log_N = static_cast(log_circuit_size); + } std::vector scalars; std::vector commitments; // Phi_n(x) = (x^N - 1) / (x - 1) + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1039): pow may not add proper constraints auto phi_numerator = x_challenge.pow(N) - 1; // x^N - 1 auto phi_n_x = phi_numerator / (x_challenge - 1); @@ -590,26 +631,57 @@ template class ZeroMorphVerifier_ { // scalar = -x * (x^{2^k} * \Phi_{n-k-1}(x^{2^{k+1}}) - u_k * \Phi_{n-k}(x^{2^k})) auto x_pow_2k = x_challenge; // x^{2^k} auto x_pow_2kp1 = x_challenge * x_challenge; // x^{2^{k + 1}} - for (size_t k = 0; k < log_N; ++k) { - - auto phi_term_1 = phi_numerator / (x_pow_2kp1 - 1); // \Phi_{n-k-1}(x^{2^{k + 1}}) - auto phi_term_2 = phi_numerator / (x_pow_2k - 1); // \Phi_{n-k}(x^{2^k}) - - auto scalar = x_pow_2k * phi_term_1; - scalar -= u_challenge[k] * phi_term_2; - scalar *= x_challenge; - scalar *= FF(-1); - - scalars.emplace_back(scalar); - commitments.emplace_back(C_q_k[k]); - - // Update powers of challenge x - x_pow_2k = x_pow_2kp1; - x_pow_2kp1 *= x_pow_2kp1; + for (size_t k = 0; k < CONST_PROOF_SIZE_LOG_N; ++k) { + // Utilize dummy rounds in order to make verifier circuit independent of proof size + bool is_dummy_round = k >= log_N; + if constexpr (Curve::is_stdlib_type) { + auto builder = x_challenge.get_context(); + stdlib::bool_t dummy_scalar = stdlib::witness_t(builder, is_dummy_round); + auto phi_term_1 = phi_numerator / (x_pow_2kp1 - 1); // \Phi_{n-k-1}(x^{2^{k + 1}}) + auto phi_term_2 = phi_numerator / (x_pow_2k - 1); // \Phi_{n-k}(x^{2^k}) + + auto scalar = x_pow_2k * phi_term_1; + scalar -= u_challenge[k] * phi_term_2; + scalar *= x_challenge; + scalar *= -FF(1); + + FF zero = FF::from_witness(builder, 0); + scalar = FF::conditional_assign(dummy_scalar, zero, scalar); + scalars.emplace_back(scalar); + commitments.emplace_back(C_q_k[k]); + + x_pow_2k = FF::conditional_assign(dummy_scalar, x_pow_2k, x_pow_2kp1); + x_pow_2kp1 = FF::conditional_assign(dummy_scalar, x_pow_2kp1, x_pow_2kp1 * x_pow_2kp1); + } else { + if (is_dummy_round) { + scalars.emplace_back(0); + commitments.emplace_back(C_q_k[k]); + } else { + auto phi_term_1 = phi_numerator / (x_pow_2kp1 - 1); // \Phi_{n-k-1}(x^{2^{k + 1}}) + auto phi_term_2 = phi_numerator / (x_pow_2k - 1); // \Phi_{n-k}(x^{2^k}) + + auto scalar = x_pow_2k * phi_term_1; + scalar -= u_challenge[k] * phi_term_2; + scalar *= x_challenge; + scalar *= FF(-1); + + scalars.emplace_back(scalar); + commitments.emplace_back(C_q_k[k]); + + // Update powers of challenge x + x_pow_2k = x_pow_2kp1; + x_pow_2kp1 *= x_pow_2kp1; + } + } } if constexpr (Curve::is_stdlib_type) { - return Commitment::batch_mul(commitments, scalars); + // If Ultra and using biggroup, handle edge cases in batch_mul + if constexpr (IsUltraBuilder && stdlib::IsBigGroup) { + return Commitment::batch_mul(commitments, scalars, /*max_num_bits=*/0, /*with_edgecases=*/true); + } else { + return Commitment::batch_mul(commitments, scalars); + } } else { return batch_mul_native(commitments, scalars); } @@ -638,7 +710,8 @@ template class ZeroMorphVerifier_ { * @param transcript * @return VerifierAccumulator Inputs to the final PCS verification check that will be accumulated */ - static OpeningClaim verify(RefSpan unshifted_commitments, + static OpeningClaim verify(FF circuit_size, + RefSpan unshifted_commitments, RefSpan to_be_shifted_commitments, RefSpan unshifted_evaluations, RefSpan shifted_evaluations, @@ -648,7 +721,13 @@ template class ZeroMorphVerifier_ { const std::vector>& concatenation_group_commitments = {}, RefSpan concatenated_evaluations = {}) { - size_t log_N = multivariate_challenge.size(); + FF log_N; + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1039): Connect witness log_N to circuit size + if constexpr (Curve::is_stdlib_type) { + log_N = FF(static_cast(numeric::get_msb(static_cast(circuit_size.get_value())))); + } else { + log_N = numeric::get_msb(static_cast(circuit_size)); + } FF rho = transcript->template get_challenge("rho"); // Construct batched evaluation v = sum_{i=0}^{m-1}\rho^i*f_i(u) + sum_{i=0}^{l-1}\rho^{m+i}*h_i(u) @@ -669,8 +748,8 @@ template class ZeroMorphVerifier_ { // Receive commitments [q_k] std::vector C_q_k; - C_q_k.reserve(log_N); - for (size_t i = 0; i < log_N; ++i) { + C_q_k.reserve(CONST_PROOF_SIZE_LOG_N); + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { C_q_k.emplace_back(transcript->template receive_from_prover("ZM:C_q_" + std::to_string(i))); } @@ -684,7 +763,7 @@ template class ZeroMorphVerifier_ { auto [x_challenge, z_challenge] = transcript->template get_challenges("ZM:x", "ZM:z"); // Compute commitment C_{\zeta_x} - auto C_zeta_x = compute_C_zeta_x(C_q, C_q_k, y_challenge, x_challenge); + auto C_zeta_x = compute_C_zeta_x(C_q, C_q_k, y_challenge, x_challenge, log_N, circuit_size); // Compute commitment C_{Z_x} Commitment C_Z_x = compute_C_Z_x(g1_identity, @@ -695,17 +774,23 @@ template class ZeroMorphVerifier_ { batched_evaluation, x_challenge, multivariate_challenge, + log_N, + circuit_size, concatenation_group_commitments); // Compute commitment C_{\zeta,Z} Commitment C_zeta_Z; if constexpr (Curve::is_stdlib_type) { - // Express operation as a batch_mul in order to use Goblinization if available auto builder = z_challenge.get_context(); std::vector scalars = { FF(builder, 1), z_challenge }; std::vector points = { C_zeta_x, C_Z_x }; - C_zeta_Z = Commitment::batch_mul(points, scalars); + // If Ultra and using biggroup, handle edge cases in batch_mul + if constexpr (IsUltraBuilder && stdlib::IsBigGroup) { + C_zeta_Z = Commitment::batch_mul(points, scalars, /*max_num_bits=*/0, /*with_edgecases=*/true); + } else { + C_zeta_Z = Commitment::batch_mul(points, scalars); + } } else { C_zeta_Z = C_zeta_x + C_Z_x * z_challenge; } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp index 122fcb1187f..146ce53b461 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp @@ -1,9 +1,7 @@ #include "zeromorph.hpp" -#include "../commitment_key.test.hpp" +#include "barretenberg/commitment_schemes/commitment_key.test.hpp" #include "barretenberg/commitment_schemes/ipa/ipa.hpp" #include "barretenberg/commitment_schemes/kzg/kzg.hpp" -#include "barretenberg/transcript/transcript.hpp" - #include namespace bb { @@ -89,10 +87,10 @@ template class ZeroMorphTest : public CommitmentTest class ZeroMorphTest : public CommitmentTest u_challenge) { auto prover_transcript = NativeTranscript::prover_init_empty(); // Execute Prover protocol - auto prover_opening_claim = ZeroMorphProver::prove(RefVector(unshifted.polynomials), // unshifted + auto prover_opening_claim = ZeroMorphProver::prove(N, + RefVector(unshifted.polynomials), // unshifted RefVector(shifted.polynomials), // to-be shifted RefVector(unshifted.evaluations), // unshifted RefVector(shifted.evaluations), // shifted @@ -224,7 +224,8 @@ template class ZeroMorphTest : public CommitmentTest class ZeroMorphTest : public CommitmentTest u_challenge, size_t NUM_CONCATENATED) @@ -261,7 +263,8 @@ template class ZeroMorphTest : public CommitmentTest class ZeroMorphTest : public CommitmentTestexecute_zeromorph_protocol(num_unshifted, num_shifted, num_concatenated); EXPECT_TRUE(verified); } -} // namespace bb +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/CMakeLists.txt new file mode 100644 index 00000000000..71ce791bd34 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(commitment_schemes_recursion commitment_schemes stdlib_primitives) \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/zeromorph.test.cpp new file mode 100644 index 00000000000..93cfbc82d89 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/zeromorph.test.cpp @@ -0,0 +1,140 @@ +#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" +#include "barretenberg/circuit_checker/circuit_checker.hpp" +#include "barretenberg/commitment_schemes/commitment_key.test.hpp" +#include "barretenberg/commitment_schemes/ipa/ipa.hpp" +#include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/srs/global_crs.hpp" +#include "barretenberg/stdlib/honk_recursion/transcript/transcript.hpp" +#include "barretenberg/stdlib/primitives/curves/bn254.hpp" +#include "barretenberg/stdlib/primitives/curves/grumpkin.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" +#include + +#include + +using namespace bb; + +template class ZeroMorphRecursionTest : public CommitmentTest {}; + +numeric::RNG& engine = numeric::get_debug_randomness(); + +/** + * @brief Test full Prover/Verifier protocol for proving single multilinear evaluation + * + */ +TEST(ZeroMorphRecursionTest, ProveAndVerifySingle) +{ + // Define some useful type aliases + using Builder = UltraCircuitBuilder; + using Curve = typename stdlib::bn254; + using NativeCurve = typename Curve::NativeCurve; + using Commitment = typename Curve::AffineElement; + using NativeCommitment = typename Curve::AffineElementNative; + using NativeCurve = typename Curve::NativeCurve; + using NativePCS = std::conditional_t, KZG, IPA>; + using CommitmentKey = typename NativePCS::CK; + using ZeroMorphProver = ZeroMorphProver_; + using Fr = typename Curve::ScalarField; + using NativeFr = typename Curve::NativeCurve::ScalarField; + using Polynomial = bb::Polynomial; + using ZeroMorphVerifier = ZeroMorphVerifier_; + using Transcript = bb::BaseTranscript>; + + constexpr size_t N = 2; + constexpr size_t NUM_UNSHIFTED = 1; + constexpr size_t NUM_SHIFTED = 0; + + srs::init_crs_factory("../srs_db/ignition"); + + std::vector u_challenge = { NativeFr::random_element(&engine) }; + + // Construct some random multilinear polynomials f_i and their evaluations v_i = f_i(u) + std::vector f_polynomials; // unshifted polynomials + std::vector v_evaluations; + for (size_t i = 0; i < NUM_UNSHIFTED; ++i) { + f_polynomials.emplace_back(Polynomial::random(N)); + f_polynomials[i][0] = NativeFr(0); // ensure f is "shiftable" + v_evaluations.emplace_back(f_polynomials[i].evaluate_mle(u_challenge)); + } + + // Construct some "shifted" multilinear polynomials h_i as the left-shift-by-1 of f_i + std::vector g_polynomials; // to-be-shifted polynomials + std::vector h_polynomials; // shifts of the to-be-shifted polynomials + std::vector w_evaluations; + for (size_t i = 0; i < NUM_SHIFTED; ++i) { + g_polynomials.emplace_back(f_polynomials[i]); + h_polynomials.emplace_back(g_polynomials[i].shifted()); + w_evaluations.emplace_back(h_polynomials[i].evaluate_mle(u_challenge)); + } + + // Compute commitments [f_i] + std::vector f_commitments; + auto commitment_key = std::make_shared(1024); + for (size_t i = 0; i < NUM_UNSHIFTED; ++i) { + f_commitments.emplace_back(commitment_key->commit(f_polynomials[i])); + } + + // Construct container of commitments of the "to-be-shifted" polynomials [g_i] (= [f_i]) + std::vector g_commitments; + for (size_t i = 0; i < NUM_SHIFTED; ++i) { + g_commitments.emplace_back(f_commitments[i]); + } + + // Initialize an empty NativeTranscript + auto prover_transcript = NativeTranscript::prover_init_empty(); + + // Execute Prover protocol + ZeroMorphProver::prove(N, + RefVector(f_polynomials), + RefVector(g_polynomials), + RefVector(v_evaluations), + RefVector(w_evaluations), + u_challenge, + commitment_key, + prover_transcript); + + Builder builder; + StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, prover_transcript->proof_data); + auto stdlib_verifier_transcript = std::make_shared(stdlib_proof); + [[maybe_unused]] auto _ = stdlib_verifier_transcript->template receive_from_prover("Init"); + + // Execute Verifier protocol without the need for vk prior the final check + const auto commitments_to_witnesses = [&builder](const auto& commitments) { + std::vector commitments_in_biggroup(commitments.size()); + std::transform(commitments.begin(), + commitments.end(), + commitments_in_biggroup.begin(), + [&builder](const auto& native_commitment) { + return Commitment::from_witness(&builder, native_commitment); + }); + return commitments_in_biggroup; + }; + const auto elements_to_witness = [&](const auto& elements) { + std::vector elements_in_circuit(elements.size()); + std::transform(elements.begin(), + elements.end(), + elements_in_circuit.begin(), + [&builder](const auto& native_element) { return Fr::from_witness(&builder, native_element); }); + return elements_in_circuit; + }; + auto stdlib_f_commitments = commitments_to_witnesses(f_commitments); + auto stdlib_g_commitments = commitments_to_witnesses(g_commitments); + auto stdlib_v_evaluations = elements_to_witness(v_evaluations); + auto stdlib_w_evaluations = elements_to_witness(w_evaluations); + + std::vector u_challenge_in_circuit(CONST_PROOF_SIZE_LOG_N); + std::fill_n(u_challenge_in_circuit.begin(), CONST_PROOF_SIZE_LOG_N, Fr::from_witness(&builder, 0)); + u_challenge_in_circuit[0] = Fr::from_witness(&builder, u_challenge[0]); + + [[maybe_unused]] auto opening_claim = ZeroMorphVerifier::verify(Fr::from_witness(&builder, N), + RefVector(stdlib_f_commitments), // unshifted + RefVector(stdlib_g_commitments), // to-be-shifted + RefVector(stdlib_v_evaluations), // unshifted + RefVector(stdlib_w_evaluations), // shifted + u_challenge_in_circuit, + Commitment::one(&builder), + stdlib_verifier_transcript, + {}, + {}); + EXPECT_TRUE(CircuitChecker::check(builder)); +} diff --git a/barretenberg/cpp/src/barretenberg/constants.hpp b/barretenberg/cpp/src/barretenberg/constants.hpp new file mode 100644 index 00000000000..4adf2c4a6b1 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/constants.hpp @@ -0,0 +1,7 @@ +#pragma once +#include + +namespace bb { +// The log of the max circuit size assumed in order to achieve constant sized proofs +static constexpr uint32_t CONST_PROOF_SIZE_LOG_N = 28; +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index bcfcce6776f..528fd947ed3 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -341,7 +341,7 @@ void build_constraints(Builder& builder, // Add recursion constraints for (size_t i = 0; i < constraint_system.honk_recursion_constraints.size(); ++i) { - auto constraint = constraint_system.honk_recursion_constraints.at(i); + auto& constraint = constraint_system.honk_recursion_constraints.at(i); // A proof passed into the constraint should be stripped of its inner public inputs, but not the // nested aggregation object itself. The verifier circuit requires that the indices to a nested // proof aggregation state are a circuit constant. The user tells us they how they want these diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp index 4b32ec0a14f..fb778929845 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp @@ -117,8 +117,6 @@ std::array create_ho } } - // Recursively verify the proof - auto vkey = std::make_shared(builder, key_fields); if (!has_valid_witness_assignments) { // Set vkey->circuit_size correctly based on the proof size size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs(); @@ -128,14 +126,86 @@ std::array create_ho 2 * num_frs_comm) % (num_frs_comm + num_frs_fr * UltraFlavor::BATCHED_RELATION_PARTIAL_LENGTH) == 0); - vkey->log_circuit_size = (input.proof.size() - HonkRecursionConstraint::inner_public_input_offset - - UltraFlavor::NUM_WITNESS_ENTITIES * num_frs_comm - - UltraFlavor::NUM_ALL_ENTITIES * num_frs_fr - 2 * num_frs_comm) / - (num_frs_comm + num_frs_fr * UltraFlavor::BATCHED_RELATION_PARTIAL_LENGTH); - vkey->circuit_size = (1 << vkey->log_circuit_size); - vkey->num_public_inputs = input.public_inputs.size(); - vkey->pub_inputs_offset = UltraFlavor::has_zero_row ? 1 : 0; + // Note: this computation should always result in log_circuit_size = CONST_PROOF_SIZE_LOG_N + auto log_circuit_size = (input.proof.size() - HonkRecursionConstraint::inner_public_input_offset - + UltraFlavor::NUM_WITNESS_ENTITIES * num_frs_comm - + UltraFlavor::NUM_ALL_ENTITIES * num_frs_fr - 2 * num_frs_comm) / + (num_frs_comm + num_frs_fr * UltraFlavor::BATCHED_RELATION_PARTIAL_LENGTH); + builder.assert_equal(builder.add_variable(1 << log_circuit_size), key_fields[0].witness_index); + builder.assert_equal(builder.add_variable(input.public_inputs.size()), key_fields[1].witness_index); + builder.assert_equal(builder.add_variable(UltraFlavor::has_zero_row ? 1 : 0), key_fields[2].witness_index); + uint32_t offset = 3; + + for (size_t i = 0; i < Flavor::NUM_PRECOMPUTED_ENTITIES; ++i) { + auto comm = curve::BN254::AffineElement::one() * fr::random_element(); + auto frs = field_conversion::convert_to_bn254_frs(comm); + builder.assert_equal(builder.add_variable(frs[0]), key_fields[offset].witness_index); + builder.assert_equal(builder.add_variable(frs[1]), key_fields[offset + 1].witness_index); + builder.assert_equal(builder.add_variable(frs[2]), key_fields[offset + 2].witness_index); + builder.assert_equal(builder.add_variable(frs[3]), key_fields[offset + 3].witness_index); + offset += 4; + } + + offset = HonkRecursionConstraint::inner_public_input_offset; + // first 3 things + builder.assert_equal(builder.add_variable(1 << log_circuit_size), proof_fields[0].witness_index); + builder.assert_equal(builder.add_variable(input.public_inputs.size()), proof_fields[1].witness_index); + builder.assert_equal(builder.add_variable(UltraFlavor::has_zero_row ? 1 : 0), proof_fields[2].witness_index); + + // the public inputs + for (size_t i = 0; i < input.public_inputs.size(); i++) { + builder.assert_equal(builder.add_variable(fr::random_element()), proof_fields[offset].witness_index); + offset++; + } + + // first 7 commitments + for (size_t i = 0; i < Flavor::NUM_WITNESS_ENTITIES; i++) { + auto comm = curve::BN254::AffineElement::one() * fr::random_element(); + auto frs = field_conversion::convert_to_bn254_frs(comm); + builder.assert_equal(builder.add_variable(frs[0]), proof_fields[offset].witness_index); + builder.assert_equal(builder.add_variable(frs[1]), proof_fields[offset + 1].witness_index); + builder.assert_equal(builder.add_variable(frs[2]), proof_fields[offset + 2].witness_index); + builder.assert_equal(builder.add_variable(frs[3]), proof_fields[offset + 3].witness_index); + offset += 4; + } + + // now the univariates, which can just be 0s (7*CONST_PROOF_SIZE_LOG_N Frs) + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N * Flavor::BATCHED_RELATION_PARTIAL_LENGTH; i++) { + builder.assert_equal(builder.add_variable(fr::random_element()), proof_fields[offset].witness_index); + offset++; + } + + // now the sumcheck evalutions, which is just 43 0s + for (size_t i = 0; i < Flavor::NUM_ALL_ENTITIES; i++) { + builder.assert_equal(builder.add_variable(fr::random_element()), proof_fields[offset].witness_index); + offset++; + } + + // now the zeromorph commitments, which are CONST_PROOF_SIZE_LOG_N comms + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; i++) { + auto comm = curve::BN254::AffineElement::one() * fr::random_element(); + auto frs = field_conversion::convert_to_bn254_frs(comm); + builder.assert_equal(builder.add_variable(frs[0]), proof_fields[offset].witness_index); + builder.assert_equal(builder.add_variable(frs[1]), proof_fields[offset + 1].witness_index); + builder.assert_equal(builder.add_variable(frs[2]), proof_fields[offset + 2].witness_index); + builder.assert_equal(builder.add_variable(frs[3]), proof_fields[offset + 3].witness_index); + offset += 4; + } + + // lastly the 2 commitments + for (size_t i = 0; i < 2; i++) { + auto comm = curve::BN254::AffineElement::one() * fr::random_element(); + auto frs = field_conversion::convert_to_bn254_frs(comm); + builder.assert_equal(builder.add_variable(frs[0]), proof_fields[offset].witness_index); + builder.assert_equal(builder.add_variable(frs[1]), proof_fields[offset + 1].witness_index); + builder.assert_equal(builder.add_variable(frs[2]), proof_fields[offset + 2].witness_index); + builder.assert_equal(builder.add_variable(frs[3]), proof_fields[offset + 3].witness_index); + offset += 4; + } + ASSERT(offset == input.proof.size() + input.public_inputs.size()); } + // Recursively verify the proof + auto vkey = std::make_shared(builder, key_fields); RecursiveVerifier verifier(&builder, vkey); std::array pairing_points = verifier.verify_proof(proof_fields); diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 4a87e300d09..bdb969415cb 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -936,7 +936,6 @@ class ECCVMFlavor { size_t num_frs_read = 0; circuit_size = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, num_frs_read); - size_t log_n = numeric::get_msb(circuit_size); transcript_add_comm = NativeTranscript::template deserialize_from_buffer( NativeTranscript::proof_data, num_frs_read); transcript_mul_comm = NativeTranscript::template deserialize_from_buffer( @@ -1113,14 +1112,14 @@ class ECCVMFlavor { NativeTranscript::proof_data, num_frs_read); z_perm_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, num_frs_read); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { sumcheck_univariates.emplace_back(NativeTranscript::template deserialize_from_buffer< bb::Univariate>( NativeTranscript::proof_data, num_frs_read)); } sumcheck_evaluations = NativeTranscript::template deserialize_from_buffer>( NativeTranscript::proof_data, num_frs_read); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { zm_cq_comms.push_back( NativeTranscript::template deserialize_from_buffer(proof_data, num_frs_read)); } @@ -1164,7 +1163,6 @@ class ECCVMFlavor { NativeTranscript::proof_data.clear(); NativeTranscript::template serialize_to_buffer(circuit_size, NativeTranscript::proof_data); - size_t log_n = numeric::get_msb(circuit_size); NativeTranscript::template serialize_to_buffer(transcript_add_comm, NativeTranscript::proof_data); NativeTranscript::template serialize_to_buffer(transcript_mul_comm, NativeTranscript::proof_data); @@ -1264,11 +1262,11 @@ class ECCVMFlavor { NativeTranscript::proof_data); NativeTranscript::template serialize_to_buffer(lookup_inverses_comm, NativeTranscript::proof_data); NativeTranscript::template serialize_to_buffer(z_perm_comm, NativeTranscript::proof_data); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { NativeTranscript::template serialize_to_buffer(sumcheck_univariates[i], NativeTranscript::proof_data); } NativeTranscript::template serialize_to_buffer(sumcheck_evaluations, NativeTranscript::proof_data); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { NativeTranscript::template serialize_to_buffer(zm_cq_comms[i], NativeTranscript::proof_data); } NativeTranscript::template serialize_to_buffer(zm_cq_comm, NativeTranscript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index 7d049b16970..830eb760683 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -121,7 +121,8 @@ void ECCVMProver::execute_pcs_rounds() // Execute the ZeroMorph protocol to produce a univariate opening claim for the multilinear evaluations produced by // Sumcheck auto multivariate_to_univariate_opening_claim = - ZeroMorph::prove(key->polynomials.get_unshifted(), + ZeroMorph::prove(key->circuit_size, + key->polynomials.get_unshifted(), key->polynomials.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_unshifted(), sumcheck_output.claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp index 9eaedc9df93..2f8999ada5d 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp @@ -140,7 +140,7 @@ class ECCVMTranscriptTests : public ::testing::Test { manifest_expected.add_challenge(round, label); } - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { round++; std::string idx = std::to_string(i); manifest_expected.add_entry(round, "Sumcheck:univariate_" + idx, frs_per_uni); @@ -153,7 +153,7 @@ class ECCVMTranscriptTests : public ::testing::Test { manifest_expected.add_challenge(round, "rho"); round++; - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { std::string idx = std::to_string(i); manifest_expected.add_entry(round, "ZM:C_q_" + idx, frs_per_G); } diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp index 2c1e3d6dc57..26bd5ac6ce6 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp @@ -61,7 +61,8 @@ bool ECCVMVerifier::verify_proof(const HonkProof& proof) } // Reduce the multivariate evaluation claims produced by sumcheck to a single univariate opening claim - auto multivariate_to_univariate_opening_claim = ZeroMorph::verify(commitments.get_unshifted(), + auto multivariate_to_univariate_opening_claim = ZeroMorph::verify(circuit_size, + commitments.get_unshifted(), commitments.get_to_be_shifted(), claimed_evaluations.get_unshifted(), claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/eccvm_recursion/eccvm_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/eccvm_recursion/eccvm_recursive_verifier.cpp index 4ceb6478179..e2821b7789b 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm_recursion/eccvm_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm_recursion/eccvm_recursive_verifier.cpp @@ -31,7 +31,11 @@ template void ECCVMRecursiveVerifier_::verify_proof(co VerifierCommitments commitments{ key }; CommitmentLabels commitment_labels; - const auto circuit_size = transcript->template receive_from_prover("circuit_size"); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1040): Extract circuit size as BF (field_t) then + // convert to FF (bigfield fq) since this is what's expected by ZM. See issue for more details. + const BF circuit_size_bf = transcript->template receive_from_prover("circuit_size"); + const FF circuit_size{ static_cast(static_cast(circuit_size_bf.get_value())) }; + for (auto [comm, label] : zip_view(commitments.get_wires(), commitment_labels.get_wires())) { comm = transcript->template receive_from_prover(label); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1017): This is a hack to ensure zero commitments @@ -75,7 +79,8 @@ template void ECCVMRecursiveVerifier_::verify_proof(co auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = sumcheck.verify(relation_parameters, alpha, gate_challenges); - auto multivariate_to_univariate_opening_claim = ZeroMorph::verify(commitments.get_unshifted(), + auto multivariate_to_univariate_opening_claim = ZeroMorph::verify(circuit_size, + commitments.get_unshifted(), commitments.get_to_be_shifted(), claimed_evaluations.get_unshifted(), claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/eccvm_recursion/verifier_commitment_key.hpp b/barretenberg/cpp/src/barretenberg/eccvm_recursion/verifier_commitment_key.hpp index 5dcb13ffacb..b25e5369adb 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm_recursion/verifier_commitment_key.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm_recursion/verifier_commitment_key.hpp @@ -7,12 +7,13 @@ namespace bb { * * @tparam Builder */ -template class VerifierCommitmentKey { +template class VerifierCommitmentKey { + public: + using Curve = Curve_; using Builder = Curve::Builder; using Commitment = Curve::AffineElement; using NativeEmbeddedCurve = typename Builder::EmbeddedCurve; - public: /** * @brief Construct a new Verifier Commitment Key object from its native counterpart. instantiated on Grumpkin. * This will be part of the ECCVMRecursiveFlavor once implemented. The Grumpkin SRS points are represented after diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index 301597a6299..0059b7e166f 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -68,6 +68,9 @@ #include "barretenberg/common/std_array.hpp" #include "barretenberg/common/std_vector.hpp" #include "barretenberg/common/zip_view.hpp" +#include "barretenberg/constants.hpp" +#include "barretenberg/crypto/sha256/sha256.hpp" +#include "barretenberg/ecc/fields/field_conversion.hpp" #include "barretenberg/plonk_honk_shared/types/circuit_type.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" @@ -181,6 +184,8 @@ class ProvingKeyAvm_ : public PrecomputedPolynomials, public WitnessPolynomials template class VerificationKey_ : public PrecomputedCommitments { public: + using FF = typename VerifierCommitmentKey::Curve::ScalarField; + using Commitment = typename VerifierCommitmentKey::Commitment; std::shared_ptr pcs_verification_key; uint64_t pub_inputs_offset = 0; @@ -191,6 +196,46 @@ class VerificationKey_ : public PrecomputedCommitments { this->log_circuit_size = numeric::get_msb(circuit_size); this->num_public_inputs = num_public_inputs; }; + + /** + * @brief Serialize verification key to field elements + * + * @return std::vector + */ + std::vector to_field_elements() + { + std::vector elements; + std::vector circuit_size_elements = bb::field_conversion::convert_to_bn254_frs(this->circuit_size); + elements.insert(elements.end(), circuit_size_elements.begin(), circuit_size_elements.end()); + // do the same for the rest of the fields + std::vector num_public_inputs_elements = + bb::field_conversion::convert_to_bn254_frs(this->num_public_inputs); + elements.insert(elements.end(), num_public_inputs_elements.begin(), num_public_inputs_elements.end()); + std::vector pub_inputs_offset_elements = + bb::field_conversion::convert_to_bn254_frs(this->pub_inputs_offset); + elements.insert(elements.end(), pub_inputs_offset_elements.begin(), pub_inputs_offset_elements.end()); + + for (Commitment& comm : this->get_all()) { + std::vector comm_elements = bb::field_conversion::convert_to_bn254_frs(comm); + elements.insert(elements.end(), comm_elements.begin(), comm_elements.end()); + } + return elements; + } + + uint256_t hash() + { + std::vector field_elements = to_field_elements(); + std::vector to_hash(field_elements.size() * sizeof(FF)); + + const auto convert_and_insert = [&to_hash](auto& vector) { + std::vector buffer = to_buffer(vector); + to_hash.insert(to_hash.end(), buffer.begin(), buffer.end()); + }; + + convert_and_insert(field_elements); + + return from_buffer(crypto::sha256(to_hash)); + } }; // Because of how Gemini is written, is importat to put the polynomials out in this order. diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 0fbdef6204f..9e696ae3580 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -136,41 +136,6 @@ class GoblinMockCircuits { MockCircuits::construct_arithmetic_circuit(builder); } - /** - * @brief Construct a size 2^17 mock kernel circuit based on vanilla recursion for benchmarking - * @details This circuit contains (1) some arbitrary operations representing general kernel logic, (2) recursive - * verification of a function circuit proof, and optionally (3) recursive verification of a previous kernel circuit - * proof. The arbitrary kernel logic is structured to bring the final dyadic circuit size of the kernel to 2^17. - * - * TODO(https://github.com/AztecProtocol/barretenberg/issues/801): Pairing point aggregation not implemented - * @param builder - * @param function_accum {proof, vkey} for function circuit to be recursively verified - * @param prev_kernel_accum {proof, vkey} for previous kernel circuit to be recursively verified - */ - static void construct_mock_recursion_kernel_circuit(MegaBuilder& builder, - const KernelInput& function_accum, - const KernelInput& prev_kernel_accum) - { - // Add operations representing general kernel logic e.g. state updates. Note: these are structured to make the - // kernel "full" within the dyadic size 2^17 (130914 gates) - const size_t NUM_MERKLE_CHECKS = 40; - const size_t NUM_ECDSA_VERIFICATIONS = 1; - const size_t NUM_SHA_HASHES = 1; - stdlib::generate_merkle_membership_test_circuit(builder, NUM_MERKLE_CHECKS); - stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ECDSA_VERIFICATIONS); - stdlib::generate_sha256_test_circuit(builder, NUM_SHA_HASHES); - - // Execute recursive aggregation of function proof - RecursiveVerifier verifier1{ &builder, function_accum.verification_key }; - verifier1.verify_proof(function_accum.proof); - - // Execute recursive aggregation of previous kernel proof if one exists - if (!prev_kernel_accum.proof.empty()) { - RecursiveVerifier verifier2{ &builder, prev_kernel_accum.verification_key }; - verifier2.verify_proof(prev_kernel_accum.proof); - } - } - /** * @brief Construct a mock kernel circuit * @details Construct an arbitrary circuit meant to represent the aztec private function execution kernel. Recursive diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp index a31ee0cc09b..b37cdd16206 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp @@ -32,31 +32,4 @@ TEST_F(MegaMockCircuitsPinning, FunctionSizes) }; run_test(true); run_test(false); -} - -TEST_F(MegaMockCircuitsPinning, RecursionKernelSizes) -{ - const auto run_test = [](bool large) { - { - GoblinProver goblin; - GoblinAccumulationOutput kernel_accum; - MegaCircuitBuilder app_circuit{ goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(app_circuit, large); - auto function_accum = goblin.accumulate(app_circuit); - MegaCircuitBuilder kernel_circuit{ goblin.op_queue }; - GoblinMockCircuits::construct_mock_recursion_kernel_circuit( - kernel_circuit, - { function_accum.proof, function_accum.verification_key }, - { kernel_accum.proof, kernel_accum.verification_key }); - - auto instance = std::make_shared(kernel_circuit); - if (large) { - EXPECT_EQ(instance->proving_key.log_circuit_size, 17); - } else { - EXPECT_EQ(instance->proving_key.log_circuit_size, 17); - }; - } - }; - run_test(true); - run_test(false); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_delta.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_delta.hpp index a68b398b118..b967dc0e93a 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_delta.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_delta.hpp @@ -61,26 +61,4 @@ typename Flavor::FF compute_public_input_delta(std::span -Field compute_lookup_grand_product_delta(const Field& beta, const Field& gamma, const auto domain_size) -{ - Field gamma_by_one_plus_beta = gamma * (Field(1) + beta); // γ(1 + β) - return gamma_by_one_plus_beta.pow(domain_size); // (γ(1 + β))^n -} - } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp b/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp index 583a9d3ddf1..7dda9aaa485 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp @@ -2,6 +2,7 @@ #include "barretenberg/common/compiler_hints.hpp" #include "barretenberg/common/op_count.hpp" #include "barretenberg/common/thread.hpp" +#include "barretenberg/stdlib/primitives/bool/bool.hpp" #include #include @@ -63,6 +64,21 @@ template struct PowPolynomial { */ FF univariate_eval(FF challenge) const { return (FF(1) + (challenge * (betas[current_element_idx] - FF(1)))); }; + /** + * @brief Evaluate \f$ ((1−X_{i}) + X_{i}\cdot \beta_{i})\f$ at the challenge point \f$ X_{i}=u_{i} \f$. + */ + template FF univariate_eval(const FF& challenge, const Bool& dummy_round) const + { + FF beta_or_dummy; + if (!dummy_round.get_value()) { + beta_or_dummy = betas[current_element_idx]; + } else { + beta_or_dummy = FF::from_witness(challenge.get_context(), 1); + } + FF beta_val = FF::conditional_assign(dummy_round, FF::from_witness(challenge.get_context(), 1), beta_or_dummy); + return (FF(1) + (challenge * (beta_val - FF(1)))); + } + /** * @brief Partially evaluate the \f$pow_{\beta} \f$-polynomial at the new challenge and update \f$ c_i \f$ * @details Update the constant \f$c_{i} \to c_{i+1} \f$ multiplying it by \f$pow_{\beta}\f$'s factor \f$\left( @@ -77,6 +93,22 @@ template struct PowPolynomial { periodicity *= 2; } + /** + * @brief Partially evaluate the \f$pow_{\beta} \f$-polynomial at the new challenge and update \f$ c_i \f$ + * @details Update the constant \f$c_{i} \to c_{i+1} \f$ multiplying it by \f$pow_{\beta}\f$'s factor \f$\left( + * (1-X_i) + X_i\cdot \beta_i\right)\vert_{X_i = u_i}\f$ computed by \ref univariate_eval. + * @param challenge \f$ i \f$-th verifier challenge \f$ u_{i}\f$ + */ + template void partially_evaluate(const FF& challenge, const stdlib::bool_t& dummy) + { + FF current_univariate_eval = univariate_eval(challenge, dummy); + // If dummy round, make no update to the partial_evaluation_result + partial_evaluation_result = FF::conditional_assign( + dummy, partial_evaluation_result, partial_evaluation_result * current_univariate_eval); + current_element_idx++; + periodicity *= 2; + } + /** * @brief Given \f$ \vec\beta = (\beta_0,...,\beta_{d-1})\f$ compute \f$ pow_{\ell}(\vec \beta) = pow_{\beta}(\vec * \ell)\f$ for \f$ \ell =0,\ldots,2^{d}-1\f$. diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp index 5ae609a0e9a..080a4f322f0 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp @@ -44,12 +44,14 @@ template bool DeciderVerifier_::verify_proof(const Hon // If Sumcheck did not verify, return false if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { + info("Sumcheck verification failed."); return false; } // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the // unrolled protocol. - auto opening_claim = ZeroMorph::verify(commitments.get_unshifted(), + auto opening_claim = ZeroMorph::verify(accumulator->verification_key->circuit_size, + commitments.get_unshifted(), commitments.get_to_be_shifted(), claimed_evaluations.get_unshifted(), claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/transcript/transcript.hpp index 6b09876cd15..5aeeaf8a6c6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/transcript/transcript.hpp @@ -17,6 +17,7 @@ template struct StdlibTranscriptParams { Builder* builder = data[0].get_context(); return stdlib::poseidon2::hash(*builder, data); } else { + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1035): Add constraints for hashing in Ultra using NativeFr = bb::fr; ASSERT(!data.empty() && data[0].get_context() != nullptr); Builder* builder = data[0].get_context(); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/decider_recursive_verifier.cpp index 44c083a544c..e3d29e360a5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/decider_recursive_verifier.cpp @@ -33,7 +33,8 @@ std::array DeciderRecursiveVerifier_:: // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the // unrolled protocol. - auto opening_claim = ZeroMorph::verify(commitments.get_unshifted(), + auto opening_claim = ZeroMorph::verify(accumulator->verification_key->circuit_size, + commitments.get_unshifted(), commitments.get_to_be_shifted(), claimed_evaluations.get_unshifted(), claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp index 0a1b48068bd..bac5ef6dd7b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp @@ -91,10 +91,7 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst gamma, inst->verification_key->circuit_size, static_cast(inst->verification_key->pub_inputs_offset)); - const FF lookup_grand_product_delta = - compute_lookup_grand_product_delta(beta, gamma, inst->verification_key->circuit_size); - inst->relation_parameters = - RelationParameters{ eta, eta_two, eta_three, beta, gamma, public_input_delta, lookup_grand_product_delta }; + inst->relation_parameters = RelationParameters{ eta, eta_two, eta_three, beta, gamma, public_input_delta }; // Get the relation separation challenges for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/ultra_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/ultra_recursive_verifier.cpp index f609464efec..38100654bd9 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/ultra_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/ultra_recursive_verifier.cpp @@ -53,7 +53,7 @@ std::array UltraRecursiveVerifier_::ve VerifierCommitments commitments{ key }; CommitmentLabels commitment_labels; - transcript->template receive_from_prover("circuit_size"); + FF circuit_size = transcript->template receive_from_prover("circuit_size"); transcript->template receive_from_prover("public_input_size"); transcript->template receive_from_prover("pub_inputs_offset"); @@ -117,15 +117,12 @@ std::array UltraRecursiveVerifier_::ve commitments.return_data_inverses = transcript->template receive_from_prover(commitment_labels.return_data_inverses); } - const FF public_input_delta = compute_public_input_delta( - public_inputs, beta, gamma, key->circuit_size, static_cast(key->pub_inputs_offset)); - const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, key->circuit_size); + public_inputs, beta, gamma, circuit_size, static_cast(key->pub_inputs_offset)); relation_parameters.beta = beta; relation_parameters.gamma = gamma; relation_parameters.public_input_delta = public_input_delta; - relation_parameters.lookup_grand_product_delta = lookup_grand_product_delta; // Get commitment to permutation and lookup grand products commitments.z_perm = transcript->template receive_from_prover(commitment_labels.z_perm); @@ -139,6 +136,9 @@ std::array UltraRecursiveVerifier_::ve alpha[idx] = transcript->template get_challenge("alpha_" + std::to_string(idx)); } + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1041): Once hashing produces constraints for Ultra in + // the transcript, a fixed number of gate_challenges must be generated by the prover/verifier in order to achieve a + // verification circuit that is independent of proof size. auto gate_challenges = std::vector(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; idx++) { gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); @@ -147,7 +147,8 @@ std::array UltraRecursiveVerifier_::ve sumcheck.verify(relation_parameters, alpha, gate_challenges); // Execute ZeroMorph to produce an opening claim subsequently verified by a univariate PCS - auto opening_claim = ZeroMorph::verify(commitments.get_unshifted(), + auto opening_claim = ZeroMorph::verify(circuit_size, + commitments.get_unshifted(), commitments.get_to_be_shifted(), claimed_evaluations.get_unshifted(), claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/verifier.test.cpp index 605b44b702f..c1d2acecf79 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/verifier.test.cpp @@ -50,19 +50,12 @@ template class RecursiveVerifierTest : public testing */ static InnerBuilder create_inner_circuit(size_t log_num_gates = 10) { - using fr_ct = InnerCurve::ScalarField; - using fq_ct = InnerCurve::BaseField; - using point_ct = InnerCurve::AffineElement; - using public_witness_ct = InnerCurve::public_witness_ct; - using witness_ct = InnerCurve::witness_ct; - using byte_array_ct = InnerCurve::byte_array_ct; using fr = typename InnerCurve::ScalarFieldNative; - using point = typename InnerCurve::GroupNative::affine_element; InnerBuilder builder; // Create 2^log_n many add gates based on input log num gates - const size_t num_gates = 1 << log_num_gates; + const size_t num_gates = (1 << log_num_gates); for (size_t i = 0; i < num_gates; ++i) { fr a = fr::random_element(); uint32_t a_idx = builder.add_variable(a); @@ -77,39 +70,6 @@ template class RecursiveVerifierTest : public testing builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) }); } - // Perform a batch mul which will add some arbitrary goblin-style ECC op gates if the circuit arithmetic is - // goblinisied otherwise it will add the conventional nonnative gates - size_t num_points = 5; - std::vector circuit_points; - std::vector circuit_scalars; - for (size_t i = 0; i < num_points; ++i) { - circuit_points.push_back(point_ct::from_witness(&builder, point::random_element())); - circuit_scalars.push_back(fr_ct::from_witness(&builder, fr::random_element())); - } - point_ct::batch_mul(circuit_points, circuit_scalars); - - // Define some additional arbitrary convetional circuit logic - fr_ct a(public_witness_ct(&builder, fr::random_element())); - fr_ct b(public_witness_ct(&builder, fr::random_element())); - fr_ct c(public_witness_ct(&builder, fr::random_element())); - - for (size_t i = 0; i < 32; ++i) { - a = (a * b) + b + a; - a = a.madd(b, c); - } - pedersen_hash::hash({ a, b }); - byte_array_ct to_hash(&builder, "nonsense test data"); - blake3s(to_hash); - - fr bigfield_data = fr::random_element(); - fr bigfield_data_a{ bigfield_data.data[0], bigfield_data.data[1], 0, 0 }; - fr bigfield_data_b{ bigfield_data.data[2], bigfield_data.data[3], 0, 0 }; - - fq_ct big_a(fr_ct(witness_ct(&builder, bigfield_data_a.to_montgomery_form())), fr_ct(witness_ct(&builder, 0))); - fq_ct big_b(fr_ct(witness_ct(&builder, bigfield_data_b.to_montgomery_form())), fr_ct(witness_ct(&builder, 0))); - - big_a* big_b; - return builder; }; @@ -156,6 +116,52 @@ template class RecursiveVerifierTest : public testing } } + static void test_independent_vk_hash() + { + auto get_blocks = [](size_t inner_size) { // Create an arbitrary inner circuit + auto inner_circuit = create_inner_circuit(inner_size); + + // Generate a proof over the inner circuit + auto instance = std::make_shared(inner_circuit); + InnerProver inner_prover(instance); + info("test circuit size: ", instance->proving_key.circuit_size); + auto verification_key = std::make_shared(instance->proving_key); + auto inner_proof = inner_prover.construct_proof(); + + // Create a recursive verification circuit for the proof of the inner circuit + OuterBuilder outer_circuit; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; + [[maybe_unused]] auto pairing_points = verifier.verify_proof(inner_proof); + return outer_circuit.blocks; + }; + + bool broke(false); + auto check_eq = [&broke](auto& p1, auto& p2) { + for (size_t idx = 0; idx < p1.size(); idx++) { + if (p1[idx] != p2[idx]) { + broke = true; + info("discrepancy at value index: ", idx); + break; + } + } + }; + + auto blocks_10 = get_blocks(10); + auto blocks_11 = get_blocks(11); + size_t block_idx = 0; + for (auto [b_10, b_11] : zip_view(blocks_10.get(), blocks_11.get())) { + info("block index: ", block_idx); + size_t sel_idx = 0; + for (auto [p_10, p_11] : zip_view(b_10.selectors, b_11.selectors)) { + info("sel index: ", sel_idx); + check_eq(p_10, p_11); + sel_idx++; + } + block_idx++; + } + EXPECT_FALSE(broke); + } + /** * @brief Construct a recursive verification circuit for the proof of an inner circuit then call check_circuit on * it. @@ -269,6 +275,15 @@ HEAVY_TYPED_TEST(RecursiveVerifierTest, SingleRecursiveVerification) TestFixture::test_recursive_verification(); }; +HEAVY_TYPED_TEST(RecursiveVerifierTest, IndependentVKHash) +{ + if constexpr (std::same_as>) { + TestFixture::test_independent_vk_hash(); + } else { + GTEST_SKIP() << "Not built for this parameter"; + } +}; + HEAVY_TYPED_TEST(RecursiveVerifierTest, SingleRecursiveVerificationFailure) { TestFixture::test_recursive_verification_fails(); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp index f73d389cab0..83ce2a6c7de 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp @@ -22,6 +22,7 @@ namespace bb::stdlib { template class element { public: using bool_ct = stdlib::bool_t; + using biggroup_tag = element; // Facilitates a constexpr check IsBigGroup struct secp256k1_wnaf { std::vector> wnaf; @@ -937,6 +938,9 @@ template class element { typename std::conditional, batch_lookup_table_plookup<>, batch_lookup_table_base>::type; }; +template +concept IsBigGroup = std::is_same_v; + template inline std::ostream& operator<<(std::ostream& os, element const& v) { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp index 49c8a471ca5..84359b97214 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp @@ -443,6 +443,8 @@ template class stdlib_biggroup : public testing::Test { static void test_batch_mul() { + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1043): this test will fail with num_points is 1 + // (and this case gets hit sometimes when handling points at infinity). const size_t num_points = 5; Builder builder; std::vector points; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp index d437cee5044..83b8f3b70b1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp @@ -12,6 +12,7 @@ template struct bn254 { // classes are instantiated with "native" curve types. Eventually, the verifier classes will be instantiated only // with stdlib types, and "native" verification will be acheived via a simulated builder. static constexpr bool is_stdlib_type = true; + using NativeCurve = curve::BN254; // Corresponding native types (used exclusively for testing) using ScalarFieldNative = curve::BN254::ScalarField; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/grumpkin.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/grumpkin.hpp index 66c704e9d9b..8f8555886e6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/grumpkin.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/grumpkin.hpp @@ -14,8 +14,8 @@ namespace bb::stdlib { */ template struct grumpkin { static constexpr bool is_stdlib_type = true; - using Builder = CircuitBuilder; + using NativeCurve = curve::Grumpkin; // Stdlib types corresponding to those defined in the native description of the curve. // Note: its useful to have these type names match the native analog exactly so that components that digest a diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.cpp index 44da799f729..5d84e42450f 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.cpp @@ -388,6 +388,19 @@ template field_t field_t::pow(const field_t return accumulator; } +/** + * @brief raise a field_t to a power of an exponent (field_t). Note that the exponent must not exceed 32 bits and is + * implicitly range constrained. + * + * @returns this ** (exponent) + */ +template field_t field_t::pow(const size_t exponent) const +{ + auto* ctx = get_context(); + auto exponent_field_elt = field_t::from_witness(ctx, exponent); + return pow(exponent_field_elt); +} + /** * @returns `this * to_mul + to_add` */ diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp index c3c4a19c140..2bbfe93989b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp @@ -129,6 +129,9 @@ template class field_t { // N.B. we implicitly range-constrain 'exponent' to be a 32-bit integer! field_t pow(const field_t& exponent) const; + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1039): Use of this function in ZM verifier is insecure. + field_t pow(size_t exponent) const; + field_t operator+=(const field_t& other) { *this = *this + other; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 45467f78325..37680a5c543 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -416,9 +416,6 @@ class MegaFlavor { this->circuit_size, this->pub_inputs_offset); relation_parameters.public_input_delta = public_input_delta; - auto lookup_grand_product_delta = compute_lookup_grand_product_delta( - relation_parameters.beta, relation_parameters.gamma, this->circuit_size); - relation_parameters.lookup_grand_product_delta = lookup_grand_product_delta; // Compute permutation and lookup grand product polynomials compute_grand_products(this->polynomials, relation_parameters); @@ -560,31 +557,6 @@ class MegaFlavor { lagrange_last, lagrange_ecc_op, databus_id); - - /** - * @brief Serialize verification key to field elements - * - * @return std::vector - */ - std::vector to_field_elements() - { - std::vector elements; - std::vector circuit_size_elements = bb::field_conversion::convert_to_bn254_frs(this->circuit_size); - elements.insert(elements.end(), circuit_size_elements.begin(), circuit_size_elements.end()); - // do the same for the rest of the fields - std::vector num_public_inputs_elements = - bb::field_conversion::convert_to_bn254_frs(this->num_public_inputs); - elements.insert(elements.end(), num_public_inputs_elements.begin(), num_public_inputs_elements.end()); - std::vector pub_inputs_offset_elements = - bb::field_conversion::convert_to_bn254_frs(this->pub_inputs_offset); - elements.insert(elements.end(), pub_inputs_offset_elements.begin(), pub_inputs_offset_elements.end()); - - for (Commitment& comm : this->get_all()) { - std::vector comm_elements = bb::field_conversion::convert_to_bn254_frs(comm); - elements.insert(elements.end(), comm_elements.begin(), comm_elements.end()); - } - return elements; - } }; /** * @brief A container for storing the partially evaluated multivariates produced by sumcheck. @@ -814,7 +786,6 @@ class MegaFlavor { // take current proof and put them into the struct size_t num_frs_read = 0; circuit_size = deserialize_from_buffer(proof_data, num_frs_read); - size_t log_n = numeric::get_msb(circuit_size); public_input_size = deserialize_from_buffer(proof_data, num_frs_read); pub_inputs_offset = deserialize_from_buffer(proof_data, num_frs_read); @@ -839,13 +810,13 @@ class MegaFlavor { w_4_comm = deserialize_from_buffer(proof_data, num_frs_read); lookup_inverses_comm = deserialize_from_buffer(proof_data, num_frs_read); z_perm_comm = deserialize_from_buffer(proof_data, num_frs_read); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { sumcheck_univariates.push_back( deserialize_from_buffer>(proof_data, num_frs_read)); } sumcheck_evaluations = deserialize_from_buffer>(proof_data, num_frs_read); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { zm_cq_comms.push_back(deserialize_from_buffer(proof_data, num_frs_read)); } zm_cq_comm = deserialize_from_buffer(proof_data, num_frs_read); @@ -856,7 +827,6 @@ class MegaFlavor { { size_t old_proof_length = proof_data.size(); proof_data.clear(); - size_t log_n = numeric::get_msb(circuit_size); serialize_to_buffer(circuit_size, proof_data); serialize_to_buffer(public_input_size, proof_data); serialize_to_buffer(pub_inputs_offset, proof_data); @@ -881,11 +851,11 @@ class MegaFlavor { serialize_to_buffer(w_4_comm, proof_data); serialize_to_buffer(lookup_inverses_comm, proof_data); serialize_to_buffer(z_perm_comm, proof_data); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { serialize_to_buffer(sumcheck_univariates[i], proof_data); } serialize_to_buffer(sumcheck_evaluations, proof_data); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { serialize_to_buffer(zm_cq_comms[i], proof_data); } serialize_to_buffer(zm_cq_comm, proof_data); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp index 6ca68d7037e..d9b010c320d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -344,9 +344,6 @@ class UltraFlavor { this->circuit_size, this->pub_inputs_offset); relation_parameters.public_input_delta = public_input_delta; - auto lookup_grand_product_delta = compute_lookup_grand_product_delta( - relation_parameters.beta, relation_parameters.gamma, this->circuit_size); - relation_parameters.lookup_grand_product_delta = lookup_grand_product_delta; // Compute permutation and lookup grand product polynomials compute_grand_products(this->polynomials, relation_parameters); @@ -361,7 +358,6 @@ class UltraFlavor { * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our * circuits. */ - // using VerificationKey = VerificationKey_, VerifierCommitmentKey>; class VerificationKey : public VerificationKey_, VerifierCommitmentKey> { public: VerificationKey() = default; @@ -472,31 +468,6 @@ class UltraFlavor { table_4, lagrange_first, lagrange_last); - - /** - * @brief Serialize verification key to field elements - * - * @return std::vector - */ - std::vector to_field_elements() - { - std::vector elements; - std::vector circuit_size_elements = bb::field_conversion::convert_to_bn254_frs(this->circuit_size); - elements.insert(elements.end(), circuit_size_elements.begin(), circuit_size_elements.end()); - // do the same for the rest of the fields - std::vector num_public_inputs_elements = - bb::field_conversion::convert_to_bn254_frs(this->num_public_inputs); - elements.insert(elements.end(), num_public_inputs_elements.begin(), num_public_inputs_elements.end()); - std::vector pub_inputs_offset_elements = - bb::field_conversion::convert_to_bn254_frs(this->pub_inputs_offset); - elements.insert(elements.end(), pub_inputs_offset_elements.begin(), pub_inputs_offset_elements.end()); - - for (Commitment& comm : this->get_all()) { - std::vector comm_elements = bb::field_conversion::convert_to_bn254_frs(comm); - elements.insert(elements.end(), comm_elements.begin(), comm_elements.end()); - } - return elements; - } }; /** @@ -696,7 +667,6 @@ class UltraFlavor { // take current proof and put them into the struct size_t num_frs_read = 0; circuit_size = deserialize_from_buffer(proof_data, num_frs_read); - size_t log_n = numeric::get_msb(circuit_size); public_input_size = deserialize_from_buffer(proof_data, num_frs_read); pub_inputs_offset = deserialize_from_buffer(proof_data, num_frs_read); @@ -711,13 +681,13 @@ class UltraFlavor { w_4_comm = deserialize_from_buffer(proof_data, num_frs_read); lookup_inverses_comm = deserialize_from_buffer(proof_data, num_frs_read); z_perm_comm = deserialize_from_buffer(proof_data, num_frs_read); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { sumcheck_univariates.push_back( deserialize_from_buffer>(proof_data, num_frs_read)); } sumcheck_evaluations = deserialize_from_buffer>(proof_data, num_frs_read); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { zm_cq_comms.push_back(deserialize_from_buffer(proof_data, num_frs_read)); } zm_cq_comm = deserialize_from_buffer(proof_data, num_frs_read); @@ -733,7 +703,6 @@ class UltraFlavor { { size_t old_proof_length = proof_data.size(); proof_data.clear(); // clear proof_data so the rest of the function can replace it - size_t log_n = numeric::get_msb(circuit_size); serialize_to_buffer(circuit_size, proof_data); serialize_to_buffer(public_input_size, proof_data); serialize_to_buffer(pub_inputs_offset, proof_data); @@ -748,11 +717,11 @@ class UltraFlavor { serialize_to_buffer(w_4_comm, proof_data); serialize_to_buffer(lookup_inverses_comm, proof_data); serialize_to_buffer(z_perm_comm, proof_data); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { serialize_to_buffer(sumcheck_univariates[i], proof_data); } serialize_to_buffer(sumcheck_evaluations, proof_data); - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { serialize_to_buffer(zm_cq_comms[i], proof_data); } serialize_to_buffer(zm_cq_comm, proof_data); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 71918f18a98..d5f71eec3c1 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -213,6 +213,12 @@ template class SumcheckProver { pow_univariate.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; } + auto zero_univariate = bb::Univariate::zero(); + for (size_t idx = multivariate_d; idx < CONST_PROOF_SIZE_LOG_N; idx++) { + transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(idx), zero_univariate); + FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(idx)); + multivariate_challenge.emplace_back(round_challenge); + } // Final round: Extract multivariate evaluations from #partially_evaluated_polynomials and add to transcript ClaimedEvaluations multivariate_evaluations; @@ -385,21 +391,39 @@ template class SumcheckVerifier { std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); - - for (size_t round_idx = 0; round_idx < multivariate_d; round_idx++) { + for (size_t round_idx = 0; round_idx < CONST_PROOF_SIZE_LOG_N; round_idx++) { // Obtain the round univariate from the transcript std::string round_univariate_label = "Sumcheck:univariate_" + std::to_string(round_idx); auto round_univariate = transcript->template receive_from_prover>( round_univariate_label); - - bool checked = round.check_sum(round_univariate); - verified = verified && checked; FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); - multivariate_challenge.emplace_back(round_challenge); - round.compute_next_target_sum(round_univariate, round_challenge); - pow_univariate.partially_evaluate(round_challenge); + if constexpr (IsRecursiveFlavor) { + typename Flavor::CircuitBuilder* builder = round_challenge.get_context(); + stdlib::bool_t dummy_round = stdlib::witness_t(builder, round_idx >= multivariate_d); + bool checked = round.check_sum(round_univariate, dummy_round); + // Only utilize the checked value if this is not a constant proof size padding round + if (round_idx < multivariate_d) { + verified = verified && checked; + } + multivariate_challenge.emplace_back(round_challenge); + + round.compute_next_target_sum(round_univariate, round_challenge, dummy_round); + pow_univariate.partially_evaluate(round_challenge, dummy_round); + + } else { + if (round_idx < multivariate_d) { + bool checked = round.check_sum(round_univariate); + verified = verified && checked; + multivariate_challenge.emplace_back(round_challenge); + + round.compute_next_target_sum(round_univariate, round_challenge); + pow_univariate.partially_evaluate(round_challenge); + } else { + multivariate_challenge.emplace_back(round_challenge); + } + } } // Final round diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 41aead2179a..6b014b66378 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -5,6 +5,7 @@ #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/relation_types.hpp" #include "barretenberg/relations/utils.hpp" +#include "barretenberg/stdlib/primitives/bool/bool.hpp" namespace bb { @@ -393,6 +394,42 @@ template class SumcheckVerifierRound { return !sumcheck_round_failed; }; + /** + * @brief Check that the round target sum is correct + * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i = + * 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + \tilde{S}^i(1) + * \f$ + * @param univariate Round univariate \f$\tilde{S}^{i}\f$ represented by its evaluations over \f$0,\ldots,D\f$. + * + */ + template + bool check_sum(bb::Univariate& univariate, stdlib::bool_t dummy_round) + { + FF total_sum = + FF::conditional_assign(dummy_round, target_total_sum, univariate.value_at(0) + univariate.value_at(1)); + // TODO(#673): Conditionals like this can go away once native verification is is just recursive verification + // with a simulated builder. + bool sumcheck_round_failed(false); + if constexpr (IsRecursiveFlavor) { + if constexpr (IsECCVMRecursiveFlavor) { + // https://github.com/AztecProtocol/barretenberg/issues/998): Avoids the scenario where the assert_equal + // below fails because we are comparing a constant against a non-constant value and the non-constant + // value is in relaxed form. This happens at the first round when target_total_sum is initially set to + // 0. + total_sum.self_reduce(); + } + target_total_sum.assert_equal(total_sum); + if (!dummy_round.get_value()) { + sumcheck_round_failed = (target_total_sum.get_value() != total_sum.get_value()); + } + } else { + sumcheck_round_failed = (target_total_sum != total_sum); + } + + round_failed = round_failed || sumcheck_round_failed; + return !sumcheck_round_failed; + }; + /** * @brief After checking that the univariate is good for this round, compute the next target sum. * @@ -407,6 +444,23 @@ template class SumcheckVerifierRound { return target_total_sum; } + /** + * @brief After checking that the univariate is good for this round, compute the next target sum. + * + * @param univariate \f$ \tilde{S}^i(X) \f$, given by its evaluations over \f$ \{0,1,2,\ldots, D\}\f$. + * @param round_challenge \f$ u_i\f$ + * @return FF \f$ \sigma_{i+1} = \tilde{S}^i(u_i)\f$ + */ + template + FF compute_next_target_sum(bb::Univariate& univariate, + FF& round_challenge, + stdlib::bool_t dummy_round) + { + // Evaluate \f$\tilde{S}^{i}(u_{i}) \f$ + target_total_sum = FF::conditional_assign(dummy_round, target_total_sum, univariate.evaluate(round_challenge)); + return target_total_sum; + } + /** * @brief Given the evaluations \f$P_1(u_0,\ldots, u_{d-1}), \ldots, P_N(u_0,\ldots, u_{d-1}) \f$ of the * ProverPolynomials at the challenge point \f$(u_0,\ldots, u_{d-1})\f$ stored in \p purported_evaluations, this @@ -425,8 +479,8 @@ template class SumcheckVerifierRound { Utils::template accumulate_relation_evaluations_without_skipping<>( purported_evaluations, relation_evaluations, relation_parameters, pow_polynomial.partial_evaluation_result); - auto running_challenge = FF(1); - auto output = FF(0); + FF running_challenge{ 1 }; + FF output{ 0 }; Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); return output; } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp index 0d103c30291..560b208f605 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp @@ -173,7 +173,8 @@ void TranslatorProver::execute_pcs_rounds() using Curve = typename Flavor::Curve; using ZeroMorph = ZeroMorphProver_; auto prover_opening_claim = - ZeroMorph::prove(key->polynomials.get_unshifted_without_concatenated(), + ZeroMorph::prove(key->circuit_size, + key->polynomials.get_unshifted_without_concatenated(), key->polynomials.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_unshifted_without_concatenated(), sumcheck_output.claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp index cfae12f3a5c..59429a35927 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp @@ -113,7 +113,8 @@ bool TranslatorVerifier::verify_proof(const HonkProof& proof) // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description ofthe // unrolled protocol. - auto opening_claim = ZeroMorph::verify(commitments.get_unshifted_without_concatenated(), + auto opening_claim = ZeroMorph::verify(circuit_size, + commitments.get_unshifted_without_concatenated(), commitments.get_to_be_shifted(), claimed_evaluations.get_unshifted_without_concatenated(), claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp index bf171d2c4a1..a34af2cf2fa 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp @@ -73,7 +73,7 @@ std::array TranslatorRecursiveVerifier_template receive_from_prover("circuit_size"); + const FF circuit_size = transcript->template receive_from_prover("circuit_size"); ASSERT(static_cast(circuit_size.get_value()) == key->circuit_size); evaluation_input_x = transcript->template receive_from_prover("evaluation_input_x"); @@ -113,7 +113,8 @@ std::array TranslatorRecursiveVerifier_ void DeciderProver_::execute_relation_ch template void DeciderProver_::execute_pcs_rounds() { using ZeroMorph = ZeroMorphProver_; - auto prover_opening_claim = ZeroMorph::prove(accumulator->proving_key.polynomials.get_unshifted(), + auto prover_opening_claim = ZeroMorph::prove(accumulator->proving_key.circuit_size, + accumulator->proving_key.polynomials.get_unshifted(), accumulator->proving_key.polynomials.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_unshifted(), sumcheck_output.claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp index 8dfc816e01a..87dcb15cebe 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp @@ -88,7 +88,7 @@ class MegaTranscriptTests : public ::testing::Test { round++; } - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { std::string idx = std::to_string(i); manifest_expected.add_entry(round, "Sumcheck:univariate_" + idx, frs_per_uni); std::string label = "Sumcheck:u_" + idx; @@ -100,7 +100,7 @@ class MegaTranscriptTests : public ::testing::Test { manifest_expected.add_challenge(round, "rho"); round++; - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { std::string idx = std::to_string(i); manifest_expected.add_entry(round, "ZM:C_q_" + idx, frs_per_G); } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp index 0a5a1810e4c..c3d89c226df 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp @@ -136,11 +136,8 @@ template void OinkVerifier::execute_grand_product relation_parameters.gamma, key->circuit_size, static_cast(key->pub_inputs_offset)); - const FF lookup_grand_product_delta = - compute_lookup_grand_product_delta(relation_parameters.beta, relation_parameters.gamma, key->circuit_size); relation_parameters.public_input_delta = public_input_delta; - relation_parameters.lookup_grand_product_delta = lookup_grand_product_delta; // Get commitment to permutation and lookup grand products witness_comms.z_perm = transcript->template receive_from_prover(domain_separator + comm_labels.z_perm); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp index df541aeb2df..5124a0f64eb 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp @@ -79,7 +79,7 @@ class UltraTranscriptTests : public ::testing::Test { round++; } - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { std::string idx = std::to_string(i); manifest_expected.add_entry(round, "Sumcheck:univariate_" + idx, frs_per_uni); std::string label = "Sumcheck:u_" + idx; @@ -91,7 +91,7 @@ class UltraTranscriptTests : public ::testing::Test { manifest_expected.add_challenge(round, "rho"); round++; - for (size_t i = 0; i < log_n; ++i) { + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { std::string idx = std::to_string(i); manifest_expected.add_entry(round, "ZM:C_q_" + idx, frs_per_G); } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 942af05365b..6804be61836 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -70,12 +70,14 @@ template bool UltraVerifier_::verify_proof(const HonkP // If Sumcheck did not verify, return false if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { + info("Sumcheck verification failed."); return false; } // Execute ZeroMorph rounds to produce an opening claim and verify it with a univariate PCS. See // https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the unrolled protocol. - auto opening_claim = ZeroMorph::verify(commitments.get_unshifted(), + auto opening_claim = ZeroMorph::verify(key->circuit_size, + commitments.get_unshifted(), commitments.get_to_be_shifted(), claimed_evaluations.get_unshifted(), claimed_evaluations.get_shifted(), @@ -83,7 +85,6 @@ template bool UltraVerifier_::verify_proof(const HonkP Commitment::one(), transcript); auto pairing_points = PCS::reduce_verify(opening_claim, transcript); - auto pcs_verified = key->pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]); return sumcheck_verified.value() && pcs_verified; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp index b35428e51f1..17c2e68976e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -965,7 +965,8 @@ void AvmProver::execute_relation_check_rounds() * */ void AvmProver::execute_pcs_rounds() { - auto prover_opening_claim = ZeroMorph::prove(prover_polynomials.get_unshifted(), + auto prover_opening_claim = ZeroMorph::prove(key->circuit_size, + prover_polynomials.get_unshifted(), prover_polynomials.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_unshifted(), sumcheck_output.claimed_evaluations.get_shifted(), diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 49302f921bb..6a23f8e56fd 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -713,27 +713,26 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector mle_challenge(multivariate_challenge.begin(), + multivariate_challenge.begin() + static_cast(log_circuit_size)); + FF kernel_kernel_inputs_evaluation = evaluate_public_input_column(public_inputs[0], circuit_size, mle_challenge); if (kernel_kernel_inputs_evaluation != claimed_evaluations.kernel_kernel_inputs) { return false; } - FF kernel_kernel_value_out_evaluation = - evaluate_public_input_column(public_inputs[1], circuit_size, multivariate_challenge); + FF kernel_kernel_value_out_evaluation = evaluate_public_input_column(public_inputs[1], circuit_size, mle_challenge); if (kernel_kernel_value_out_evaluation != claimed_evaluations.kernel_kernel_value_out) { return false; } FF kernel_kernel_side_effect_out_evaluation = - evaluate_public_input_column(public_inputs[2], circuit_size, multivariate_challenge); + evaluate_public_input_column(public_inputs[2], circuit_size, mle_challenge); if (kernel_kernel_side_effect_out_evaluation != claimed_evaluations.kernel_kernel_side_effect_out) { return false; } FF kernel_kernel_metadata_out_evaluation = - evaluate_public_input_column(public_inputs[3], circuit_size, multivariate_challenge); + evaluate_public_input_column(public_inputs[3], circuit_size, mle_challenge); if (kernel_kernel_metadata_out_evaluation != claimed_evaluations.kernel_kernel_metadata_out) { return false; } diff --git a/bb-pilcom/bb-pil-backend/src/prover_builder.rs b/bb-pilcom/bb-pil-backend/src/prover_builder.rs index ee129d6ca83..c0ea19709a5 100644 --- a/bb-pilcom/bb-pil-backend/src/prover_builder.rs +++ b/bb-pilcom/bb-pil-backend/src/prover_builder.rs @@ -192,7 +192,8 @@ impl ProverBuilder for BBFiles { * */ void {name}Prover::execute_pcs_rounds() {{ - auto prover_opening_claim = ZeroMorph::prove(prover_polynomials.get_unshifted(), + auto prover_opening_claim = ZeroMorph::prove(key->circuit_size, + prover_polynomials.get_unshifted(), prover_polynomials.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_unshifted(), sumcheck_output.claimed_evaluations.get_shifted(), diff --git a/bb-pilcom/bb-pil-backend/src/verifier_builder.rs b/bb-pilcom/bb-pil-backend/src/verifier_builder.rs index ed93731b67f..a10a7bea021 100644 --- a/bb-pilcom/bb-pil-backend/src/verifier_builder.rs +++ b/bb-pilcom/bb-pil-backend/src/verifier_builder.rs @@ -56,7 +56,7 @@ impl VerifierBuilder for BBFiles { |public_inputs_column_name: &String, idx: usize| { format!( " - FF {public_inputs_column_name}_evaluation = evaluate_public_input_column(public_inputs[{idx}], circuit_size, multivariate_challenge); + FF {public_inputs_column_name}_evaluation = evaluate_public_input_column(public_inputs[{idx}], circuit_size, mle_challenge); if ({public_inputs_column_name}_evaluation != claimed_evaluations.{public_inputs_column_name}) {{ return false; }} @@ -178,6 +178,8 @@ impl VerifierBuilder for BBFiles { }} // Public columns evaluation checks + std::vector mle_challenge(multivariate_challenge.begin(), + multivariate_challenge.begin() + static_cast(log_circuit_size)); {public_inputs_check} // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the diff --git a/noir/noir-repo/test_programs/benchmarks/bench_sha256/Prover.toml b/noir/noir-repo/test_programs/benchmarks/bench_sha256/Prover.toml deleted file mode 100644 index 66779dea9d7..00000000000 --- a/noir/noir-repo/test_programs/benchmarks/bench_sha256/Prover.toml +++ /dev/null @@ -1 +0,0 @@ -input = [1,2] diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml index 4619fd298dd..c1ec4049fa9 100644 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml @@ -1,4 +1,4 @@ key_hash = "0x096129b1c6e108252fc5c829c4cc9b7e8f0d1fd9f29c2532b563d6396645e08f" -proof = ["0x0000000000000000000000000000000000000000000000000000000000000020","0x0000000000000000000000000000000000000000000000000000000000000011","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf","0x00000000000000000000000000000000000000000000000b75c020998797da78","0x0000000000000000000000000000000000000000000000005a107acb64952eca","0x000000000000000000000000000000000000000000000000000031e97a575e9d","0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4","0x00000000000000000000000000000000000000000000000c410db10a01750aeb","0x00000000000000000000000000000000000000000000000d722669117f9758a4","0x000000000000000000000000000000000000000000000000000178cbf4206471","0x000000000000000000000000000000000000000000000000e91b8a11e7842c38","0x000000000000000000000000000000000000000000000007fd51009034b3357f","0x000000000000000000000000000000000000000000000009889939f81e9c7402","0x0000000000000000000000000000000000000000000000000000f94656a2ca48","0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f","0x0000000000000000000000000000000000000000000000093fe27776f50224bd","0x000000000000000000000000000000000000000000000004a0c80c0da527a081","0x0000000000000000000000000000000000000000000000000001b52c2020d746","0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632","0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc","0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62","0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c","0x000000000000000000000000000000b0804efd6573805f991458295f510a2004","0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e","0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47","0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15","0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd","0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383","0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4","0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98","0x0000000000000000000000000000000d9d719a8b9f020ad3642d60fe704e696f","0x00000000000000000000000000000000000ddfdbbdefc4ac1580ed38e12cfa49","0x0000000000000000000000000000008289fe9754ce48cd01b7be96a861b5e157","0x00000000000000000000000000000000000ff3e0896bdea021253b3d360fa678","0x0000000000000000000000000000000d9d719a8b9f020ad3642d60fe704e696f","0x00000000000000000000000000000000000ddfdbbdefc4ac1580ed38e12cfa49","0x0000000000000000000000000000008289fe9754ce48cd01b7be96a861b5e157","0x00000000000000000000000000000000000ff3e0896bdea021253b3d360fa678","0x000000000000000000000000000000f968b227a358a305607f3efc933823d288","0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08","0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f","0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1","0x0000000000000000000000000000005b739ed2075f2b046062b8fc6a2d1e9863","0x00000000000000000000000000000000001285cd1030d338c0e1603b4da2c838","0x00000000000000000000000000000027447d6c281eb38b2b937af4a516d60c04","0x000000000000000000000000000000000019bc3d980465fbb4a656a74296fc58","0x000000000000000000000000000000b484788ace8f7df86dd5e325d2e9b12599","0x00000000000000000000000000000000000a2ca0d10eb7b767114ae230b728d3","0x000000000000000000000000000000c6dfc7092f16f95795e437664498b88d53","0x0000000000000000000000000000000000131067b4e4d95a4f6f8cf5c9b5450a","0x0f413f22eec51f2a02800e0cafaeec1d92d744fbbaef213c687b9edabd6985f5","0x21230f4ff26c80ffb5d037a9d1d26c3f955ca34cbeca4f54db6656b932967a0c","0x0521f877fe35535767f99597cc50effbd283dcae6812ee0a7620d796ccbfd642","0x202b01350a9cc5c20ec0f3eaada338c0a3b793811bd539418ffa3cc4302615e2","0x2d1214d9b0d41058ad4a172d9c0aecc5bdabe95e687c3465050c6b5396509be4","0x1113b344a151b0af091cb28d728b752ebb4865da6cd7ee68471b961ca5cf69b9","0x2aa66d0954bb83e17bd5c9928d3aa7a7df75d741d409f7c15ba596804ba643fb","0x2e26bc7a530771ef7a95d5360d537e41cf94d8a0942764ff09881c107f91a106","0x0f14f32b921bb63ad1df00adab7c82af58ea8aa7f353f14b281208d8c5fab504","0x13429515c0c53b6502bbcdf545defb3cb69a986c9263e070fcbb397391aae1a3","0x1f21cac5e2f262afc1006a21454cc6bcb018c44e53ad8ab61cebbac99e539176","0x2a9886a6ddc8a61b097c668cd362fc8acdee8dde74f7b1af192c3e060bb2948f","0x2d718181e408ead2e9bcd30a84ad1fccbaf8d48ab6d1820bad4933d284b503c4","0x2634c1aafc902f14508f34d3d7e9d485f42d1a4c95b5a1ef73711ed0d3c68d77","0x092ede9777e6472ce5ffd8c963d466006189e960e2c591d338dc8d4af1a057fb","0x1cba45b17fd24f1cb1b4ab7b83eee741f6c77ba70a497dc4de259eceb7d5ea26","0x246e887c7bf2e17f919b2393b6e9b00b33e8822d862544a775aac05cb7bff710","0x04c3f539fe8689971948afcb437f1ecbd444a5bddaca1c8a450348dcd8480047","0x20c6a423ae4fd58e8951aa378d02d77baf90508ceb48856db2319d70938b186e","0x1bcf8786b554b3316d8ebdbc9d006a4e5d4865aad512ffd404b7f83550d3d030","0x09ab038260518f0970564afcd6bf22e2abf6b1fa5e12a327bbf195b6ca5edd78","0x1024e32554746f89c195286ba6ccfc9765e5d14bbe8064bc6fdf22d16ec6b495","0x17706656f8dbd7e47bb257a6428f0cb7278ea02fa9e6ce431d7bcc9133fba9c7","0x25a3e8a33c15ef2a4dd16313a6049bf1d468b4cdc141f238f2d51a1e8e1c22b3","0x1198863f08006edb27aee23164fb117a4ddec1bf1ed89807aa907e5cd24bf068","0x1862b4856b5b4d4a064f873e221703e4e2cd1ebfca1337dedca56485c38ed5a0","0x062214af1ea6dd6bf8895b92d394571c43970b6f967e1c794624d96071b25ad3","0x1e5be9428ddcf1f9b0cbafc28101e792ec5cf73852b0cd0b84fbff71b4490e09","0x2d4189bea5b1e30f63c64bd26df82f18bcaf885ec8887b54634b2557869ce87f","0x0f2e5d9a908850e9d44925e17d8b12d1adb1ed029799c9b5858598504242bbc0","0x3050dc85746a57931d99f3f35e77c2ba561fba0baa018b79ff1fd544026833ae","0x2a591a32437e5e0b875a137fd868bd1b6dbc003ff1b661f26e00627cc7c5cf47","0x27946841e1670ad9c65717016d0cedf524724217236e81b9fd0a264a36ebfb0e","0x0fc396e9d19d6e68e289602e292ee345542d0d28bf6de34fa62cc577cbdfb1df","0x08e7433a07a44c0c9c4dd4b273a2685bbd1a91fd5cf2b43409458fab42a23e1b","0x12bd9bfb029c3503a5c6deea87b0a0f11bb9f7ea584af2d48f3e48d7e09247ae","0x2ccc4810748c0a82dfc0f063d0b8c7999ffe9474653080e6ef92b3cb7a428784","0x08eb574d7fecadadb508c8bd35fdad06b99110609d679763c2e3645229b1b95a","0x0f1a65e747c8021ed7c454a4be1e89b1bce66ead9ed980fa98a7a050eafe98a1","0x1c8ff9e36684ec71614dee4c17859b06c742089f6029d3694a16e00dac9b57f1","0x0303101a8ba712aeca4da85b767ab8d3ecf489ec7d746f8ee20041717cc000e9","0x0aaf64c65e7088e5596108c9601467911fea809ca6540d79af77e6e66e36cd99","0x17caf164ce74ea7edfb1390e07763d2197797ec26661b92cde18a98d61d2fddc","0x18cb055c7ad6d01437725bb457681d81f3ecadc4f35d838a3c13daf25a44456a","0x2d78602b8bbcd32b36a99a6e2d248e7fe044ef1b50813133370412f9ef5299f0","0x2b139276ea86d426a115479e4154f72a6bd83a6253bf13e9670dc6b4664378f0","0x127c7837b384902c39a104036c09546728571c46c8166b1b9b13b3a615ebb781","0x05faa4816f83cf0189a482ad943c94b9ec6474002f2b327f8698763ad0ea0985","0x2f90359cc30ee693fb3aced96523cf7aebd152c22329eee56a398d9a4ac0628e","0x0a71beaf17a59c5a238f04c1f203848d87502c5057a78c13f0cfb0f9876e7714","0x2696c1e6d089556adaeb95c8a5e3065b00a393a38c2d69e9bd6ce8cdc49d87da","0x1f3d165a7dc6564a036e451eb9cb7f1e1cb1e6d29daa75e3f135ea3e58a79ccd","0x1473a660819bdd838d56122b72b32b267211e9f1103239480ec50fa85c9e1035","0x0a8ccaeb22451f391b3fc3467c8e6e900270a7afb7b510e8acf5a4f06f1c0888","0x03b3080afc0658cc87e307758cebc171921f43eca159b9dedf7f72aa8dd926bd","0x2dd7d6663fa0e1755dfafac352c361fcd64c7f4d53627e3646870ac169cc4a07","0x1ec54b883f5f35ccad0e75695af20790d9860104095bab34c9bf01628dd40cb9","0x193dff50f83c241f7a9e087a29ce72ecf3f6d8563593f786dcd04c32bcfd4ced","0x135122c0dae26cda8ca1c09de8225064ad86d10423ab0aaa53b481aa4626e1d6","0x08d5a56cbfab5aeed56d3cdd7fb6b30fc26b0c1a5b63fccd7fa44c53ba6fd35a","0x0d12f126dfa2daad3726d00ca339284cc22e36c6d81bb7a4b95c6f9598b60e7c","0x2e8b24bbdf2fd839d3c7cae1f0eeb96bfcfaeef30b27476f2fafcb17da78cd5e","0x2364acfe0cea39b7f749c5f303b99504977357925f810f684c60f35d16315211","0x06ca062eb70b8c51cfac35345e7b6b51f33a8ec9ebe204fb9b4911200bf508b7","0x266c0aa1ccb97186815bf69084f600d06ddd934e59a38dfe602ee5d6b9487f22","0x1d817537a49c6d0e3b4b65c6665334b91d7593142e60065048be9e55ceb5e7ab","0x05e9b7256a368df053c691952b59e9327a7c12ed322bbd6f72c669b9b9c26d49","0x05e9b7256a368df053c691952b59e9327a7c12ed322bbd6f72c669b9b9c26d49","0x25b77026673a1e613e50df0e88fb510973739d5f9064bd364079a9f884209632","0x25c9bc7a3f6aae3d43ff68b5614b34b5eaceff37157b37347995d231784ac1fd","0x085f69baef22680ae15f4801ef4361ebe9c7fc24a94b5bc2527dce8fb705439e","0x0d7c6b9ce31bfc32238a205455baf5ffe99cd30eb0f7bb5b504e1d4501e01382","0x1001a8cc4bc1221c814fba0eddcf3c40619b133373640c600de5bed0a0a05b10","0x20f5894be90e52977cb70f4f4cbd5101693db0360848939750db7e91109d54b6","0x22c09cb26db43f0599408b4daed0f4f496c66424e6affa41c14387d8e0af851b","0x24e5f41357798432426a9549d71e8cc681eaebacbe87f6e3bf38e85de5aa2f3d","0x06eb90100c736fbf2b87432d7821ecdc0b365024739bc36363d48b905973f5b9","0x0000000000000000000000000000007f36e0b4f59927ebbb2302e76cbe8bd44e","0x00000000000000000000000000000000001b95777c6c98640c80638c195909ca","0x0000000000000000000000000000006d4b1ad71244248cb2070fbbbb0ac9df88","0x00000000000000000000000000000000001abada4d5d816a67b6fc75746cb723","0x000000000000000000000000000000465811089df032ceb5269254547a101e57","0x000000000000000000000000000000000011a4a909c59776a6df9c7615e8e87d","0x000000000000000000000000000000311f6f724e7199351c9774225f15c25f20","0x00000000000000000000000000000000001ddba8eb0ab208ad3d96c70941fcbc","0x0000000000000000000000000000000dfa80bdf5be151b21ad89466b7201b63d","0x000000000000000000000000000000000015ca7dc258adab8ea406d94e00c56d","0x000000000000000000000000000000507ea3454165f92295b6e435c7d30d14f0","0x00000000000000000000000000000000002f522608db7b7d389d1df67eab104d","0x000000000000000000000000000000950102cce743fadb23965fc72e31efd36c","0x000000000000000000000000000000000018b4a7ec90df68dfe97d3c5367d1bf","0x000000000000000000000000000000118d90258b25dba8bc0f99d9f7547c6a62","0x000000000000000000000000000000000012d78638701da6322abbf325693b0f","0x000000000000000000000000000000144743e0d082f35295b51561af65f94c6b","0x00000000000000000000000000000000002322a615615e5405836374bb3c5336","0x000000000000000000000000000000e6f08dd5904ee42f826cde680919b41a96","0x00000000000000000000000000000000002d3f823ea255b68465e4b5360bf864","0x00000000000000000000000000000076d4db93683b6363ae92a5a20d8bb9922e","0x00000000000000000000000000000000002f8a7009cac72c9599b81cb9054308","0x00000000000000000000000000000085c12dd2be9f2b29e54c1a4bc3cbf9b6ce","0x000000000000000000000000000000000024e3688a1f4f50b0c6bd6c068f32b2","0x00000000000000000000000000000023a2015e7ea351e444c9405adfbd81e84d","0x00000000000000000000000000000000001fb3e4228c15dc4380db796925ec49","0x000000000000000000000000000000834ad9406b8ded7208b872373be7445e47","0x0000000000000000000000000000000000267544d6a9f5cc46d10555f2617c65"] +proof = ["0x0000000000000000000000000000000000000000000000000000000000000020","0x0000000000000000000000000000000000000000000000000000000000000011","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf","0x00000000000000000000000000000000000000000000000b75c020998797da78","0x0000000000000000000000000000000000000000000000005a107acb64952eca","0x000000000000000000000000000000000000000000000000000031e97a575e9d","0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4","0x00000000000000000000000000000000000000000000000c410db10a01750aeb","0x00000000000000000000000000000000000000000000000d722669117f9758a4","0x000000000000000000000000000000000000000000000000000178cbf4206471","0x000000000000000000000000000000000000000000000000e91b8a11e7842c38","0x000000000000000000000000000000000000000000000007fd51009034b3357f","0x000000000000000000000000000000000000000000000009889939f81e9c7402","0x0000000000000000000000000000000000000000000000000000f94656a2ca48","0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f","0x0000000000000000000000000000000000000000000000093fe27776f50224bd","0x000000000000000000000000000000000000000000000004a0c80c0da527a081","0x0000000000000000000000000000000000000000000000000001b52c2020d746","0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632","0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc","0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62","0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c","0x000000000000000000000000000000b0804efd6573805f991458295f510a2004","0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e","0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47","0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15","0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd","0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383","0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4","0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98","0x0000000000000000000000000000000d9d719a8b9f020ad3642d60fe704e696f","0x00000000000000000000000000000000000ddfdbbdefc4ac1580ed38e12cfa49","0x0000000000000000000000000000008289fe9754ce48cd01b7be96a861b5e157","0x00000000000000000000000000000000000ff3e0896bdea021253b3d360fa678","0x0000000000000000000000000000000d9d719a8b9f020ad3642d60fe704e696f","0x00000000000000000000000000000000000ddfdbbdefc4ac1580ed38e12cfa49","0x0000000000000000000000000000008289fe9754ce48cd01b7be96a861b5e157","0x00000000000000000000000000000000000ff3e0896bdea021253b3d360fa678","0x000000000000000000000000000000f968b227a358a305607f3efc933823d288","0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08","0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f","0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1","0x0000000000000000000000000000005b739ed2075f2b046062b8fc6a2d1e9863","0x00000000000000000000000000000000001285cd1030d338c0e1603b4da2c838","0x00000000000000000000000000000027447d6c281eb38b2b937af4a516d60c04","0x000000000000000000000000000000000019bc3d980465fbb4a656a74296fc58","0x000000000000000000000000000000b484788ace8f7df86dd5e325d2e9b12599","0x00000000000000000000000000000000000a2ca0d10eb7b767114ae230b728d3","0x000000000000000000000000000000c6dfc7092f16f95795e437664498b88d53","0x0000000000000000000000000000000000131067b4e4d95a4f6f8cf5c9b5450a","0x0f413f22eec51f2a02800e0cafaeec1d92d744fbbaef213c687b9edabd6985f5","0x21230f4ff26c80ffb5d037a9d1d26c3f955ca34cbeca4f54db6656b932967a0c","0x0521f877fe35535767f99597cc50effbd283dcae6812ee0a7620d796ccbfd642","0x202b01350a9cc5c20ec0f3eaada338c0a3b793811bd539418ffa3cc4302615e2","0x2d1214d9b0d41058ad4a172d9c0aecc5bdabe95e687c3465050c6b5396509be4","0x1113b344a151b0af091cb28d728b752ebb4865da6cd7ee68471b961ca5cf69b9","0x2aa66d0954bb83e17bd5c9928d3aa7a7df75d741d409f7c15ba596804ba643fb","0x2e26bc7a530771ef7a95d5360d537e41cf94d8a0942764ff09881c107f91a106","0x0f14f32b921bb63ad1df00adab7c82af58ea8aa7f353f14b281208d8c5fab504","0x13429515c0c53b6502bbcdf545defb3cb69a986c9263e070fcbb397391aae1a3","0x1f21cac5e2f262afc1006a21454cc6bcb018c44e53ad8ab61cebbac99e539176","0x2a9886a6ddc8a61b097c668cd362fc8acdee8dde74f7b1af192c3e060bb2948f","0x2d718181e408ead2e9bcd30a84ad1fccbaf8d48ab6d1820bad4933d284b503c4","0x2634c1aafc902f14508f34d3d7e9d485f42d1a4c95b5a1ef73711ed0d3c68d77","0x092ede9777e6472ce5ffd8c963d466006189e960e2c591d338dc8d4af1a057fb","0x1cba45b17fd24f1cb1b4ab7b83eee741f6c77ba70a497dc4de259eceb7d5ea26","0x246e887c7bf2e17f919b2393b6e9b00b33e8822d862544a775aac05cb7bff710","0x04c3f539fe8689971948afcb437f1ecbd444a5bddaca1c8a450348dcd8480047","0x20c6a423ae4fd58e8951aa378d02d77baf90508ceb48856db2319d70938b186e","0x1bcf8786b554b3316d8ebdbc9d006a4e5d4865aad512ffd404b7f83550d3d030","0x09ab038260518f0970564afcd6bf22e2abf6b1fa5e12a327bbf195b6ca5edd78","0x1024e32554746f89c195286ba6ccfc9765e5d14bbe8064bc6fdf22d16ec6b495","0x17706656f8dbd7e47bb257a6428f0cb7278ea02fa9e6ce431d7bcc9133fba9c7","0x25a3e8a33c15ef2a4dd16313a6049bf1d468b4cdc141f238f2d51a1e8e1c22b3","0x1198863f08006edb27aee23164fb117a4ddec1bf1ed89807aa907e5cd24bf068","0x1862b4856b5b4d4a064f873e221703e4e2cd1ebfca1337dedca56485c38ed5a0","0x062214af1ea6dd6bf8895b92d394571c43970b6f967e1c794624d96071b25ad3","0x1e5be9428ddcf1f9b0cbafc28101e792ec5cf73852b0cd0b84fbff71b4490e09","0x2d4189bea5b1e30f63c64bd26df82f18bcaf885ec8887b54634b2557869ce87f","0x0f2e5d9a908850e9d44925e17d8b12d1adb1ed029799c9b5858598504242bbc0","0x3050dc85746a57931d99f3f35e77c2ba561fba0baa018b79ff1fd544026833ae","0x2a591a32437e5e0b875a137fd868bd1b6dbc003ff1b661f26e00627cc7c5cf47","0x27946841e1670ad9c65717016d0cedf524724217236e81b9fd0a264a36ebfb0e","0x0fc396e9d19d6e68e289602e292ee345542d0d28bf6de34fa62cc577cbdfb1df","0x08e7433a07a44c0c9c4dd4b273a2685bbd1a91fd5cf2b43409458fab42a23e1b","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x12bd9bfb029c3503a5c6deea87b0a0f11bb9f7ea584af2d48f3e48d7e09247ae","0x2ccc4810748c0a82dfc0f063d0b8c7999ffe9474653080e6ef92b3cb7a428784","0x08eb574d7fecadadb508c8bd35fdad06b99110609d679763c2e3645229b1b95a","0x0f1a65e747c8021ed7c454a4be1e89b1bce66ead9ed980fa98a7a050eafe98a1","0x1c8ff9e36684ec71614dee4c17859b06c742089f6029d3694a16e00dac9b57f1","0x0303101a8ba712aeca4da85b767ab8d3ecf489ec7d746f8ee20041717cc000e9","0x0aaf64c65e7088e5596108c9601467911fea809ca6540d79af77e6e66e36cd99","0x17caf164ce74ea7edfb1390e07763d2197797ec26661b92cde18a98d61d2fddc","0x18cb055c7ad6d01437725bb457681d81f3ecadc4f35d838a3c13daf25a44456a","0x2d78602b8bbcd32b36a99a6e2d248e7fe044ef1b50813133370412f9ef5299f0","0x2b139276ea86d426a115479e4154f72a6bd83a6253bf13e9670dc6b4664378f0","0x127c7837b384902c39a104036c09546728571c46c8166b1b9b13b3a615ebb781","0x05faa4816f83cf0189a482ad943c94b9ec6474002f2b327f8698763ad0ea0985","0x2f90359cc30ee693fb3aced96523cf7aebd152c22329eee56a398d9a4ac0628e","0x0a71beaf17a59c5a238f04c1f203848d87502c5057a78c13f0cfb0f9876e7714","0x2696c1e6d089556adaeb95c8a5e3065b00a393a38c2d69e9bd6ce8cdc49d87da","0x1f3d165a7dc6564a036e451eb9cb7f1e1cb1e6d29daa75e3f135ea3e58a79ccd","0x1473a660819bdd838d56122b72b32b267211e9f1103239480ec50fa85c9e1035","0x0a8ccaeb22451f391b3fc3467c8e6e900270a7afb7b510e8acf5a4f06f1c0888","0x03b3080afc0658cc87e307758cebc171921f43eca159b9dedf7f72aa8dd926bd","0x2dd7d6663fa0e1755dfafac352c361fcd64c7f4d53627e3646870ac169cc4a07","0x1ec54b883f5f35ccad0e75695af20790d9860104095bab34c9bf01628dd40cb9","0x193dff50f83c241f7a9e087a29ce72ecf3f6d8563593f786dcd04c32bcfd4ced","0x135122c0dae26cda8ca1c09de8225064ad86d10423ab0aaa53b481aa4626e1d6","0x08d5a56cbfab5aeed56d3cdd7fb6b30fc26b0c1a5b63fccd7fa44c53ba6fd35a","0x0d12f126dfa2daad3726d00ca339284cc22e36c6d81bb7a4b95c6f9598b60e7c","0x2e8b24bbdf2fd839d3c7cae1f0eeb96bfcfaeef30b27476f2fafcb17da78cd5e","0x2364acfe0cea39b7f749c5f303b99504977357925f810f684c60f35d16315211","0x06ca062eb70b8c51cfac35345e7b6b51f33a8ec9ebe204fb9b4911200bf508b7","0x266c0aa1ccb97186815bf69084f600d06ddd934e59a38dfe602ee5d6b9487f22","0x1d817537a49c6d0e3b4b65c6665334b91d7593142e60065048be9e55ceb5e7ab","0x05e9b7256a368df053c691952b59e9327a7c12ed322bbd6f72c669b9b9c26d49","0x05e9b7256a368df053c691952b59e9327a7c12ed322bbd6f72c669b9b9c26d49","0x25b77026673a1e613e50df0e88fb510973739d5f9064bd364079a9f884209632","0x25c9bc7a3f6aae3d43ff68b5614b34b5eaceff37157b37347995d231784ac1fd","0x085f69baef22680ae15f4801ef4361ebe9c7fc24a94b5bc2527dce8fb705439e","0x0d7c6b9ce31bfc32238a205455baf5ffe99cd30eb0f7bb5b504e1d4501e01382","0x1001a8cc4bc1221c814fba0eddcf3c40619b133373640c600de5bed0a0a05b10","0x20f5894be90e52977cb70f4f4cbd5101693db0360848939750db7e91109d54b6","0x22c09cb26db43f0599408b4daed0f4f496c66424e6affa41c14387d8e0af851b","0x24e5f41357798432426a9549d71e8cc681eaebacbe87f6e3bf38e85de5aa2f3d","0x06eb90100c736fbf2b87432d7821ecdc0b365024739bc36363d48b905973f5b9","0x000000000000000000000000000000ece6d09ed58e9f5661c01140b10558a8c2","0x000000000000000000000000000000000012b6e4f37adcb34b8e88ff8b6eebce","0x000000000000000000000000000000b226a2bb93593fa1fab19a44767828a3f5","0x00000000000000000000000000000000002b5b518342030543092e1428a7e33c","0x00000000000000000000000000000022ba33857034a0574c216eb3c1ddff3025","0x00000000000000000000000000000000001918e58df857985a7cf9eae7802165","0x00000000000000000000000000000045c2d840b96fb6106cc14dcad89dd5f675","0x00000000000000000000000000000000000afdfac1e3a1febdd0208867d44f98","0x00000000000000000000000000000042ebed6c5ec45d794f119aef24c192af0f","0x00000000000000000000000000000000002d05ef250900bbcc5751bbeb210d6a","0x00000000000000000000000000000060d604bdda48eecc90ed065bd9770e1323","0x00000000000000000000000000000000001fed91c63d0041660c1cbc84c2ffbb","0x00000000000000000000000000000054196b549cde36092e8184c7f4f7d878de","0x00000000000000000000000000000000000153f26a01294329922b492485cc31","0x00000000000000000000000000000056ebea579d10dbb440f0222931df2c0059","0x00000000000000000000000000000000000d2cbc61ce5b7cdd7fce398da4637b","0x000000000000000000000000000000e2b9512360b9797d96675d8a2fd2f7aa5d","0x000000000000000000000000000000000025742905f105ff895f74e7c3daa34a","0x000000000000000000000000000000a2dd7df55db59bd41b83518d4403fbc382","0x00000000000000000000000000000000002c1d9c3cbb9371d4cc4e9f900b9a46","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000000000bcf12ae40c9425c3e67654b84181f90502","0x00000000000000000000000000000000000b6d3faa8a71ff6ef1aa887b7307cf","0x0000000000000000000000000000001f6f719acc23b8f84808c0275d61cfb456","0x0000000000000000000000000000000000296030933ed0c134457ae71c393dfe","0x000000000000000000000000000000ebe1a57cdd7d3d763289b40ef5ed9a7ae0","0x000000000000000000000000000000000010f30483e7df51fca2316d3367603c","0x0000000000000000000000000000000149b7b283ab18060618c8e051864c03cd","0x00000000000000000000000000000000001ef7763235a3a25e241a5f06704dc3"] public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000020","0x0000000000000000000000000000000000000000000000000000000000000011","0x0000000000000000000000000000000000000000000000000000000000000001","0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84","0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae","0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16","0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1","0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c","0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7","0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8","0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c","0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5","0x00000000000000000000000000000000002002681bb417184b2df070a16a3858","0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511","0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223","0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7","0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c","0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130","0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f","0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3","0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592","0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3","0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1","0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0","0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c","0x0000000000000000000000000000009f825dde88092070747180d581c342444a","0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01","0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff","0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9","0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1","0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b","0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2","0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f","0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0","0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349","0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8","0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2","0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556","0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d","0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb","0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d","0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8","0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862","0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e","0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830","0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f","0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe","0x000000000000000000000000000000231147211b3c75e1f47d150e4bbd2fb22e","0x00000000000000000000000000000000000d19ee104a10d3c701cfd87473cbbe","0x0000000000000000000000000000006705f3f382637d00f698e2c5c94ed05ae9","0x00000000000000000000000000000000000b9c792da28bb60601dd7ce4b74e68","0x000000000000000000000000000000ac5acc8cc21e4ddb225c510670f80c80b3","0x00000000000000000000000000000000002da9d3fa57343e6998aba19429b9fa","0x0000000000000000000000000000004bacbf54b7c17a560df0af18b6d0d527be","0x00000000000000000000000000000000000faea33aeca2025b22c288964b21eb","0x000000000000000000000000000000492e756298d68d6e95de096055cc0336c3","0x00000000000000000000000000000000001a12a12f004859e5a3675c7315121b","0x000000000000000000000000000000893d521d512f30e6d32afbbc0cecd8ee00","0x00000000000000000000000000000000001674b3c1ef12c6da690631e0d86c04","0x000000000000000000000000000000aa6cb02a52e7a613873d4ac9b411349945","0x00000000000000000000000000000000001ecb1fe9c493add46751f9940f73e1","0x00000000000000000000000000000045b3d362ca82cba69fb2b9c733a5b8c351","0x000000000000000000000000000000000019a683586af466e331945b732d2f8c","0x000000000000000000000000000000fc79b052dfdfe67c0ecfc06b4267ffd694","0x00000000000000000000000000000000001336a70c396393038d5e9913744ac2","0x0000000000000000000000000000005450d29af1e9438e91cd33ddeb2548226e","0x000000000000000000000000000000000000993a602891cfd0e6f6ecf7404933","0x000000000000000000000000000000498efddab90a32e9b2db729ed6e9b40192","0x00000000000000000000000000000000002425efebe9628c63ca6fc28bdb5901","0x000000000000000000000000000000d8488157f875a21ab5f93f1c2b641f3de9","0x0000000000000000000000000000000000290f95ada3936604dc4b14df7504e3","0x0000000000000000000000000000005d6902187f3ed60dcce06fca211b40329a","0x00000000000000000000000000000000002b5870a6ba0b20aaa0178e5adfbc36","0x000000000000000000000000000000e5c2519171fa0e548fc3c4966ffc1ce570","0x00000000000000000000000000000000001cb8d8f4793b7debbdc429389dbf2d","0x000000000000000000000000000000a3ee22dd60456277b86c32a18982dcb185","0x00000000000000000000000000000000002493c99a3d068b03f8f2b8d28b57ce","0x000000000000000000000000000000f6c3731486320082c20ec71bbdc92196c1","0x00000000000000000000000000000000001ded39c4c8366469843cd63f09ecac","0x000000000000000000000000000000494997477ab161763e46601d95844837ef","0x00000000000000000000000000000000002e0cddbc5712d79b59cb3b41ebbcdd","0x000000000000000000000000000000426db4c64531d350750df62dbbc41a1bd9","0x0000000000000000000000000000000000303126892f664d8d505964d14315ec","0x00000000000000000000000000000076a6b2c6040c0c62bd59acfe3e3e125672","0x000000000000000000000000000000000000874a5ad262eecc6b565e0b085074","0x000000000000000000000000000000ef082fb517183c9c6841c2b8ef2ca1df04","0x0000000000000000000000000000000000127b2a745a1b74968c3edc18982b9b","0x000000000000000000000000000000c9efd4f8c3d56e1eb23d789a8f710d5be6","0x000000000000000000000000000000000015a18748490ff4c2b1871081954e86","0x000000000000000000000000000000a0011ef987dc016ab110eacd554a1d8bbf","0x00000000000000000000000000000000002097c84955059442a95df075833071","0x000000000000000000000000000000d38e9426ad3085b68b00a93c17897c2877","0x00000000000000000000000000000000002aecd48089890ea0798eb952c66824","0x00000000000000000000000000000078d8a9ce405ce559f441f2e71477ff3ddb","0x00000000000000000000000000000000001216bdb2f0d961bb8a7a23331d2150","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb","0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56","0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc","0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4"] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr index 9fd55df16e1..ecfd18f3837 100644 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr @@ -1,11 +1,12 @@ // This circuit aggregates a single Honk proof from `assert_statement_recursive`. +global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 409; fn main( verification_key: [Field; 103], // This is the proof without public inputs attached. // // This means: the size of this does not change with the number of public inputs. - proof: [Field; 156], + proof: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], public_inputs: pub [Field; 1], // This is currently not public. It is fine given that the vk is a part of the circuit definition. // I believe we want to eventually make it public too though.