diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp index 907ef89aab3e..0b516c88a205 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp @@ -50,6 +50,8 @@ void create_dummy_vkey_and_proof(Builder& builder, const std::vector& key_fields, const std::vector& proof_fields) { + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1514): restructure this function to use functions from + // mock_verifier_inputs using Flavor = avm2::AvmFlavor; // Relevant source for proof layout: AvmFlavor::Transcript::serialize_full_transcript() 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 c89f27f73c7a..0f81c5b92e33 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 @@ -7,6 +7,7 @@ #include "honk_recursion_constraint.hpp" #include "barretenberg/common/assert.hpp" #include "barretenberg/constants.hpp" +#include "barretenberg/dsl/acir_format/mock_verifier_inputs.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/flavor/ultra_recursive_flavor.hpp" #include "barretenberg/flavor/ultra_rollup_recursive_flavor.hpp" @@ -54,150 +55,37 @@ void create_dummy_vkey_and_proof(typename Flavor::CircuitBuilder& builder, { using Builder = typename Flavor::CircuitBuilder; using NativeFlavor = typename Flavor::NativeFlavor; - - static constexpr size_t IPA_CLAIM_SIZE = stdlib::recursion::honk::RollupIO::IpaClaim::PUBLIC_INPUTS_SIZE; + using IO = std::conditional_t, + stdlib::recursion::honk::RollupIO, + stdlib::recursion::honk::DefaultIO>; // Set vkey->circuit_size correctly based on the proof size BB_ASSERT_EQ(proof_size, NativeFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS()); - // a lambda that adds dummy commitments (libra and gemini) - auto set_dummy_commitment = [&](size_t& offset) { - auto comm = curve::BN254::AffineElement::one() * fr::random_element(); - auto frs = field_conversion::convert_to_bn254_frs(comm); - builder.set_variable(proof_fields[offset].witness_index, frs[0]); - builder.set_variable(proof_fields[offset + 1].witness_index, frs[1]); - builder.set_variable(proof_fields[offset + 2].witness_index, frs[2]); - builder.set_variable(proof_fields[offset + 3].witness_index, frs[3]); - offset += 4; - }; - auto set_dummy_evaluation = [&](size_t& offset) { - builder.set_variable(proof_fields[offset].witness_index, fr::random_element()); - offset++; - }; - - // Note: this computation should always result in log_circuit_size = CONST_PROOF_SIZE_LOG_N - auto log_circuit_size = CONST_PROOF_SIZE_LOG_N; - size_t offset = 0; - // First key field is circuit size - builder.set_variable(key_fields[offset++].witness_index, 1 << log_circuit_size); - // Second key field is number of public inputs - builder.set_variable(key_fields[offset++].witness_index, public_inputs_size); - // Third key field is the pub inputs offset + size_t num_inner_public_inputs = public_inputs_size - IO::PUBLIC_INPUTS_SIZE; uint32_t pub_inputs_offset = NativeFlavor::has_zero_row ? 1 : 0; - builder.set_variable(key_fields[offset++].witness_index, pub_inputs_offset); - size_t num_inner_public_inputs = HasIPAAccumulator ? public_inputs_size - bb::RollupIO::PUBLIC_INPUTS_SIZE - : public_inputs_size - bb::DefaultIO::PUBLIC_INPUTS_SIZE; - - for (size_t i = 0; i < Flavor::NUM_PRECOMPUTED_ENTITIES; ++i) { - set_dummy_commitment(offset); - } - offset = 0; // Reset offset for parsing proof fields + // Generate mock honk vk + // Note: log_circuit_size = CONST_PROOF_SIZE_LOG_N + auto honk_vk = create_mock_honk_vk( + 1 << CONST_PROOF_SIZE_LOG_N, pub_inputs_offset, num_inner_public_inputs); - // the inner public inputs - for (size_t i = 0; i < num_inner_public_inputs; i++) { - set_dummy_evaluation(offset); - } + size_t offset = 0; - // Get some values for a valid aggregation object and use them here to avoid divide by 0 or other issues. - std::array::PUBLIC_INPUTS_SIZE> dummy_pairing_points_values = - PairingPoints::construct_dummy(); - for (size_t i = 0; i < PairingPoints::PUBLIC_INPUTS_SIZE; i++) { - builder.set_variable(proof_fields[offset].witness_index, dummy_pairing_points_values[i]); + // Set honk vk in builder + for (auto& vk_element : honk_vk->to_field_elements()) { + builder.set_variable(key_fields[offset].witness_index, vk_element); offset++; } - // IPA claim - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1392): Don't use random elements here. - if constexpr (HasIPAAccumulator) { - for (size_t i = 0; i < IPA_CLAIM_SIZE; i++) { - set_dummy_evaluation(offset); - } - } - - // first NUM_WITNESS_ENTITIES witness commitments - for (size_t i = 0; i < Flavor::NUM_WITNESS_ENTITIES; i++) { - set_dummy_commitment(offset); - } - - if constexpr (Flavor::HasZK) { - // Libra concatenation commitment - set_dummy_commitment(offset); - // libra sum - set_dummy_evaluation(offset); - } - - // now the univariates, which can just be 0s (8*CONST_PROOF_SIZE_LOG_N Frs, where 8 is the maximum relation - // degree) - for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N * Flavor::BATCHED_RELATION_PARTIAL_LENGTH; i++) { - set_dummy_evaluation(offset); - } - - // now the sumcheck evaluations, which is just 44 0s - for (size_t i = 0; i < Flavor::NUM_ALL_ENTITIES; i++) { - set_dummy_evaluation(offset); - } + // Generate dummy honk proof + bb::HonkProof honk_proof = create_mock_honk_proof(num_inner_public_inputs); - if constexpr (Flavor::HasZK) { - // Libra claimed evaluation - set_dummy_evaluation(offset); - // Libra grand sum commitment - - set_dummy_commitment(offset); - // Libra quotient commitment - set_dummy_commitment(offset); - // Gemini masking commitment - set_dummy_commitment(offset); - // Gemini masking evaluation - set_dummy_evaluation(offset); - } - - // now the gemini fold commitments which are CONST_PROOF_SIZE_LOG_N - 1 - for (size_t i = 1; i < CONST_PROOF_SIZE_LOG_N; i++) { - set_dummy_commitment(offset); - } - - // the gemini fold evaluations which are also CONST_PROOF_SIZE_LOG_N - for (size_t i = 1; i <= CONST_PROOF_SIZE_LOG_N; i++) { - set_dummy_evaluation(offset); - } - - if constexpr (Flavor::HasZK) { - // NUM_SMALL_IPA_EVALUATIONS libra evals - for (size_t i = 0; i < NUM_SMALL_IPA_EVALUATIONS; i++) { - set_dummy_evaluation(offset); - } - } - - // lastly the shplonk batched quotient commitment and kzg quotient commitment - for (size_t i = 0; i < 2; i++) { - set_dummy_commitment(offset); - } - // IPA Proof - if constexpr (HasIPAAccumulator) { - - // Ls and Rs - for (size_t i = 0; i < static_cast(2) * CONST_ECCVM_LOG_N; i++) { - auto comm = curve::Grumpkin::AffineElement::one() * fq::random_element(); - auto frs = field_conversion::convert_to_bn254_frs(comm); - builder.set_variable(proof_fields[offset].witness_index, frs[0]); - builder.set_variable(proof_fields[offset + 1].witness_index, frs[1]); - offset += 2; - } - - // G_zero - auto G_zero = curve::Grumpkin::AffineElement::one() * fq::random_element(); - auto G_zero_frs = field_conversion::convert_to_bn254_frs(G_zero); - builder.set_variable(proof_fields[offset].witness_index, G_zero_frs[0]); - builder.set_variable(proof_fields[offset + 1].witness_index, G_zero_frs[1]); - offset += 2; - - // a_zero - auto a_zero = fq::random_element(); - auto a_zero_frs = field_conversion::convert_to_bn254_frs(a_zero); - builder.set_variable(proof_fields[offset].witness_index, a_zero_frs[0]); - builder.set_variable(proof_fields[offset + 1].witness_index, a_zero_frs[1]); - offset += 2; + offset = 0; + // Set honk proof in builder + for (auto& proof_element : honk_proof) { + builder.set_variable(proof_fields[offset].witness_index, proof_element); + offset++; } BB_ASSERT_EQ(offset, proof_size + public_inputs_size); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.test.cpp index 1379ec7ba02b..8c1e8374a107 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.test.cpp @@ -255,15 +255,6 @@ class IvcRecursionConstraintTest : public ::testing::Test { void SetUp() override { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } }; -/** - * @brief Check that the size of a mock merge proof matches expectation - */ -TEST_F(IvcRecursionConstraintTest, MockMergeProofSize) -{ - Goblin::MergeProof merge_proof = create_mock_merge_proof(); - EXPECT_EQ(merge_proof.size(), MERGE_PROOF_SIZE); -} - /** * @brief Test IVC accumulation of a one app and one kernel; The kernel includes a recursive oink verification for the * app, specified via an ACIR RecursionConstraint. diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.cpp index b13f669d943e..088ba275b40c 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.cpp @@ -27,9 +27,10 @@ using namespace bb; * @param fields field buffer to append mock commitment values to * @param num_commitments number of mock commitments to append */ +template void populate_field_elements_for_mock_commitments(std::vector& fields, const size_t& num_commitments) { - auto mock_commitment = curve::BN254::AffineElement::one(); + auto mock_commitment = Curve::AffineElement::one(); std::vector mock_commitment_frs = field_conversion::convert_to_bn254_frs(mock_commitment); for (size_t i = 0; i < num_commitments; ++i) { for (const fr& val : mock_commitment_frs) { @@ -38,18 +39,43 @@ void populate_field_elements_for_mock_commitments(std::vector& fields, const } } +/** + * @brief Helper to populate a field buffer with some number of field elements + * + * @param fields field buffer to append field elements to + * @param num_elements number of mock field elements to append + * @param value optional mock value appended + */ +template +void populate_field_elements(std::vector& fields, + const size_t& num_elements, + std::optional value = std::nullopt) +{ + for (size_t i = 0; i < num_elements; ++i) { + std::vector field_elements = value.has_value() + ? field_conversion::convert_to_bn254_frs(value.value()) + : field_conversion::convert_to_bn254_frs(FF::random_element()); + fields.insert(fields.end(), field_elements.begin(), field_elements.end()); + } +} + /** * @brief Create a mock oink proof that has the correct structure but is not in general valid * + * @param inner_public_inputs_size Number of public inputs coming from the ACIR constraints */ -template HonkProof create_mock_oink_proof() +template HonkProof create_mock_oink_proof(const size_t inner_public_inputs_size) { HonkProof proof; // Populate mock public inputs - typename Flavor::CircuitBuilder builder; + typename PublicInputs::Builder builder; PublicInputs::add_default(builder); + // Populate the proof with as many public inputs as required from the ACIR constraints + populate_field_elements(proof, inner_public_inputs_size); + + // Populate the proof with the public inputs added from barretenberg for (const auto& pub : builder.public_inputs()) { proof.emplace_back(builder.get_variable(pub)); } @@ -64,37 +90,69 @@ template HonkProof create_mock_oink_proof( * @brief Create a mock decider proof that has the correct structure but is not in general valid * */ -template HonkProof create_mock_decider_proof() +template HonkProof create_mock_decider_proof(const size_t const_proof_log_n) { - using FF = typename Flavor::FF; - + using FF = Flavor::FF; + using Curve = Flavor::Curve; HonkProof proof; - // Sumcheck univariates - const size_t TOTAL_SIZE_SUMCHECK_UNIVARIATES = CONST_PROOF_SIZE_LOG_N * Flavor::BATCHED_RELATION_PARTIAL_LENGTH; - for (size_t i = 0; i < TOTAL_SIZE_SUMCHECK_UNIVARIATES; ++i) { - proof.emplace_back(FF::random_element()); + if constexpr (Flavor::HasZK) { + // Libra concatenation commitment + populate_field_elements_for_mock_commitments(proof, 1); + + // Libra sum + populate_field_elements(proof, 1); } + // Sumcheck univariates + const size_t TOTAL_SIZE_SUMCHECK_UNIVARIATES = const_proof_log_n * Flavor::BATCHED_RELATION_PARTIAL_LENGTH; + populate_field_elements(proof, TOTAL_SIZE_SUMCHECK_UNIVARIATES); + // Sumcheck multilinear evaluations - for (size_t i = 0; i < Flavor::NUM_ALL_ENTITIES; ++i) { - proof.emplace_back(FF::random_element()); + populate_field_elements(proof, Flavor::NUM_ALL_ENTITIES); + + if constexpr (Flavor::HasZK) { + // Libra claimed evaluation + populate_field_elements(proof, 1); + + // Libra grand sum commitment + populate_field_elements_for_mock_commitments(proof, 1); + + // Libra quotient commitment + populate_field_elements_for_mock_commitments(proof, 1); + + // Gemini masking commitment + populate_field_elements_for_mock_commitments(proof, 1); + + // Gemini masking evaluation + populate_field_elements(proof, 1); } // Gemini fold commitments - const size_t NUM_GEMINI_FOLD_COMMITMENTS = CONST_PROOF_SIZE_LOG_N - 1; - populate_field_elements_for_mock_commitments(proof, NUM_GEMINI_FOLD_COMMITMENTS); + const size_t NUM_GEMINI_FOLD_COMMITMENTS = const_proof_log_n - 1; + populate_field_elements_for_mock_commitments(proof, NUM_GEMINI_FOLD_COMMITMENTS); // Gemini fold evaluations - const size_t NUM_GEMINI_FOLD_EVALUATIONS = CONST_PROOF_SIZE_LOG_N; - for (size_t i = 0; i < NUM_GEMINI_FOLD_EVALUATIONS; ++i) { - proof.emplace_back(FF::random_element()); + const size_t NUM_GEMINI_FOLD_EVALUATIONS = const_proof_log_n; + populate_field_elements(proof, NUM_GEMINI_FOLD_EVALUATIONS); + + if constexpr (std::is_same_v) { + // Gemini P pos evaluation + populate_field_elements(proof, 1); + + // Gemini P neg evaluation + populate_field_elements(proof, 1); + } + + if constexpr (Flavor::HasZK) { + // NUM_SMALL_IPA_EVALUATIONS libra evals + populate_field_elements(proof, NUM_SMALL_IPA_EVALUATIONS); } // Shplonk batched quotient commitment - populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); // KZG quotient commitment - populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); return proof; } @@ -102,16 +160,22 @@ template HonkProof create_mock_decider_proof() /** * @brief Create a mock honk proof that has the correct structure but is not in general valid * + * @param inner_public_inputs_size Number of public inputs coming from the ACIR constraints */ -template HonkProof create_mock_honk_proof() +template HonkProof create_mock_honk_proof(const size_t inner_public_inputs_size) { // Construct a Honk proof as the concatenation of an Oink proof and a Decider proof - HonkProof oink_proof = create_mock_oink_proof(); + HonkProof oink_proof = create_mock_oink_proof(inner_public_inputs_size); HonkProof decider_proof = create_mock_decider_proof(); HonkProof proof; proof.reserve(oink_proof.size() + decider_proof.size()); proof.insert(proof.end(), oink_proof.begin(), oink_proof.end()); proof.insert(proof.end(), decider_proof.begin(), decider_proof.end()); + + if constexpr (HasIPAAccumulator) { + HonkProof ipa_proof = create_mock_ipa_proof(); + proof.insert(proof.end(), ipa_proof.begin(), ipa_proof.end()); + } return proof; } @@ -125,15 +189,12 @@ template HonkProof create_mock_pg_proof() HonkProof proof = create_mock_oink_proof(); // Populate mock perturbator coefficients - for (size_t idx = 1; idx <= CONST_PG_LOG_N; idx++) { - proof.emplace_back(0); - } + populate_field_elements(proof, CONST_PG_LOG_N, /*value=*/fr::zero()); // Populate mock combiner quotient coefficients - for (size_t idx = DeciderProvingKeys_::NUM; idx < DeciderProvingKeys_::BATCHED_EXTENDED_LENGTH; - idx++) { - proof.emplace_back(0); - } + size_t NUM_COEFF_COMBINER_QUOTIENT = + DeciderProvingKeys_::BATCHED_EXTENDED_LENGTH - DeciderProvingKeys_::NUM; + populate_field_elements(proof, NUM_COEFF_COMBINER_QUOTIENT, /*value=*/fr::zero()); return proof; } @@ -145,18 +206,13 @@ template HonkProof create_mock_pg_proof() */ Goblin::MergeProof create_mock_merge_proof() { - using Flavor = MegaFlavor; - using FF = Flavor::FF; - - std::vector proof; + Goblin::MergeProof proof; proof.reserve(MERGE_PROOF_SIZE); - FF mock_val(5); - auto mock_commitment = curve::BN254::AffineElement::one(); - std::vector mock_commitment_frs = field_conversion::convert_to_bn254_frs(mock_commitment); + uint32_t mock_shift_size = 5; // Must be smaller than 32, otherwise pow raises an error - // Populate mock subtable size - proof.emplace_back(mock_val); + // Populate mock shift size + populate_field_elements(proof, 1, /*value=*/fr{ mock_shift_size }); // There are 8 entities in the merge protocol (4 columns x 2 components: T_j, g_j(X) = X^{l-1} t_j(X)) // and 8 evaluations (4 columns x 2 components: g_j(kappa), t_j(1/kappa)) @@ -164,43 +220,197 @@ Goblin::MergeProof create_mock_merge_proof() const size_t NUM_TRANSCRIPT_EVALUATIONS = 8; // Transcript poly commitments - for (size_t i = 0; i < NUM_TRANSCRIPT_ENTITIES; ++i) { - for (const FF& val : mock_commitment_frs) { - proof.emplace_back(val); - } - } + populate_field_elements_for_mock_commitments(proof, NUM_TRANSCRIPT_ENTITIES); + // Transcript poly evaluations - for (size_t i = 0; i < NUM_TRANSCRIPT_EVALUATIONS; ++i) { - proof.emplace_back(mock_val); - } + populate_field_elements(proof, NUM_TRANSCRIPT_EVALUATIONS); // Shplonk proof: commitment to the quotient - for (const FF& val : mock_commitment_frs) { - proof.emplace_back(val); - } + populate_field_elements_for_mock_commitments(proof, 1); // KZG proof: commitment to W - for (const FF& val : mock_commitment_frs) { - proof.emplace_back(val); - } + populate_field_elements_for_mock_commitments(proof, 1); BB_ASSERT_EQ(proof.size(), MERGE_PROOF_SIZE); return proof; } +/** + * @brief Create a mock pre-ipa proof which has the correct structure but is not necessarily valid + * + * @details An ECCVM proof is made of a pre-ipa proof and an ipa-proof. Here we mock the pre-ipa part. + * + * @return HonkProof + */ +HonkProof create_mock_pre_ipa_proof() +{ + using FF = ECCVMFlavor::FF; + HonkProof proof; + + // 1. NUM_WITNESS_ENTITIES commitments + populate_field_elements_for_mock_commitments(proof, ECCVMFlavor::NUM_WITNESS_ENTITIES); + + // 2. Libra concatenation commitment + populate_field_elements_for_mock_commitments(proof, /*num_commitments*/ 1); + + // 3. Libra sum + populate_field_elements(proof, 1); + + // 4. Sumcheck univariates commitments + 5. Sumcheck univariate evaluations + for (size_t idx = 0; idx < CONST_ECCVM_LOG_N; idx++) { + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + populate_field_elements(proof, /*num_elements=*/2); + } + + // 6. ALL_ENTITIES sumcheck evaluations + populate_field_elements(proof, ECCVMFlavor::NUM_ALL_ENTITIES); + + // 7. Libra evaluation + populate_field_elements(proof, 1); + + // 8. Libra grand sum commitment + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // 9. Libra quotient commitment + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // 10. Gemini masking commitment + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // 11. Gemini masking evaluations + populate_field_elements(proof, 1); + + // 12. Gemini fold commitments + populate_field_elements_for_mock_commitments(proof, + /*num_commitments=*/CONST_ECCVM_LOG_N - 1); + + // 13. Gemini evaluations + populate_field_elements(proof, CONST_ECCVM_LOG_N); + + // 14. NUM_SMALL_IPA_EVALUATIONS libra evals + populate_field_elements(proof, NUM_SMALL_IPA_EVALUATIONS); + + // 15. Shplonk + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // 16. Translator concatenated masking term commitment + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // 17. Translator op evaluation + populate_field_elements(proof, 1); + + // 18. Translator Px evaluation + populate_field_elements(proof, 1); + + // 19. Translator Py evaluation + populate_field_elements(proof, 1); + + // 20. Translator z1 evaluation + populate_field_elements(proof, 1); + + // 21. Translator z2 evaluation + populate_field_elements(proof, 1); + + // 22. Translator concatenated masking term evaluation + populate_field_elements(proof, 1); + + // 23. Translator grand sum commitment + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // 24. Translator quotient commitment + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // 25. Translator concatenation evaluation + populate_field_elements(proof, 1); + + // 26. Translator grand sum shift evaluation + populate_field_elements(proof, 1); + + // 27. Translator grand sum evaluation + populate_field_elements(proof, 1); + + // 28. Translator quotient evaluation + populate_field_elements(proof, 1); + + // 29. Shplonk + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + BB_ASSERT_EQ(proof.size(), ECCVMFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS - IPA_PROOF_LENGTH); + + return proof; +} + +/** + * @brief Create a mock ipa proof which has the correct structure but is not necessarily valid + * + * @details An ECCVM proof is made of a pre-ipa proof and an ipa-proof. Here we mock the ipa part. + * + * @return HonkProof + */ +HonkProof create_mock_ipa_proof() +{ + HonkProof proof; + + // Commitments to L and R for CONST_ECCVM_LOG_N round + populate_field_elements_for_mock_commitments( + proof, /*num_commitments=*/CONST_ECCVM_LOG_N + CONST_ECCVM_LOG_N); + + // Commitment to G_0 + populate_field_elements_for_mock_commitments(proof, /*num_commitments=*/1); + + // a_0 evaluation (a_0 is in the base field of BN254) + populate_field_elements(proof, 1); + + BB_ASSERT_EQ(proof.size(), IPA_PROOF_LENGTH); + + return proof; +} + +/** + * @brief Create a mock translator proof which has the correct structure but is not necessarily valid + * + * @return HonkProof + */ +HonkProof create_mock_translator_proof() +{ + using BF = TranslatorFlavor::BF; + using Curve = TranslatorFlavor::Curve; + + HonkProof proof; + HonkProof decider_proof = create_mock_decider_proof(TranslatorFlavor::CONST_TRANSLATOR_LOG_N); + + // 1. Accumulated result + populate_field_elements(proof, 1); + + // 2. NUM_WITNESS_ENTITIES commitments + populate_field_elements_for_mock_commitments(proof, + /*num_commitments=*/TranslatorFlavor::NUM_WITNESS_ENTITIES - 4); + + // Insert decider proof + proof.insert(proof.end(), decider_proof.begin(), decider_proof.end()); + + BB_ASSERT_EQ(proof.size(), TranslatorFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS); + + return proof; +} + /** * @brief Create a mock MegaHonk VK that has the correct structure * + * @param dyadic_size Dyadic size of the circuit for which we generate a vk + * @param pub_inputs_offest Indicating whether the circuit has a first zero row + * @param inner_public_inputs_size Number of public inputs coming from the ACIR constraints */ template std::shared_ptr create_mock_honk_vk(const size_t dyadic_size, - const size_t pub_inputs_offset) + const size_t pub_inputs_offset, + const size_t inner_public_inputs_size) { // Set relevant VK metadata and commitments auto honk_verification_key = std::make_shared(); honk_verification_key->log_circuit_size = bb::numeric::get_msb(dyadic_size); - honk_verification_key->num_public_inputs = PublicInputs::PUBLIC_INPUTS_SIZE; + honk_verification_key->num_public_inputs = inner_public_inputs_size + PublicInputs::PUBLIC_INPUTS_SIZE; honk_verification_key->pub_inputs_offset = pub_inputs_offset; // must be set correctly for (auto& commitment : honk_verification_key->get_all()) { @@ -235,33 +445,71 @@ template std::shared_ptr> crea } // Explicitly instantiate template functions -template HonkProof create_mock_oink_proof(); -template HonkProof create_mock_oink_proof(); -template HonkProof create_mock_oink_proof>(); - -template HonkProof create_mock_oink_proof>(); - -template HonkProof create_mock_decider_proof(); -template HonkProof create_mock_decider_proof(); - -template HonkProof create_mock_honk_proof(); -template HonkProof create_mock_honk_proof(); -template HonkProof create_mock_honk_proof>(); - -template HonkProof create_mock_honk_proof>(); +template HonkProof create_mock_oink_proof(const size_t); +template HonkProof create_mock_oink_proof(const size_t); +template HonkProof create_mock_oink_proof>( + const size_t); + +template HonkProof create_mock_oink_proof>( + const size_t); +template HonkProof create_mock_oink_proof>( + const size_t); +template HonkProof create_mock_oink_proof>( + const size_t); +template HonkProof create_mock_oink_proof>( + const size_t); +template HonkProof create_mock_oink_proof(const size_t); + +template HonkProof create_mock_decider_proof(const size_t); +template HonkProof create_mock_decider_proof(const size_t); +template HonkProof create_mock_decider_proof(const size_t); +template HonkProof create_mock_decider_proof(const size_t); +template HonkProof create_mock_decider_proof(const size_t); + +template HonkProof create_mock_honk_proof(const size_t); +template HonkProof create_mock_honk_proof(const size_t); +template HonkProof create_mock_honk_proof>( + const size_t); + +template HonkProof create_mock_honk_proof>( + const size_t); +template HonkProof create_mock_honk_proof>( + const size_t); +template HonkProof create_mock_honk_proof>( + const size_t); +template HonkProof create_mock_honk_proof>( + const size_t); +template HonkProof create_mock_honk_proof(const size_t); template HonkProof create_mock_pg_proof(); template HonkProof create_mock_pg_proof(); template HonkProof create_mock_pg_proof>(); template std::shared_ptr create_mock_honk_vk( - const size_t, const size_t); + const size_t, const size_t, const size_t); template std::shared_ptr create_mock_honk_vk( - const size_t, const size_t); + const size_t, const size_t, const size_t); template std::shared_ptr create_mock_honk_vk< MegaFlavor, - stdlib::recursion::honk::HidingKernelIO>(const size_t, const size_t); + stdlib::recursion::honk::HidingKernelIO>(const size_t, const size_t, const size_t); + +template std::shared_ptr create_mock_honk_vk< + UltraFlavor, + stdlib::recursion::honk::DefaultIO>(const size_t, const size_t, const size_t); +template std::shared_ptr create_mock_honk_vk< + UltraZKFlavor, + stdlib::recursion::honk::DefaultIO>(const size_t, const size_t, const size_t); +template std::shared_ptr create_mock_honk_vk< + UltraFlavor, + stdlib::recursion::honk::DefaultIO>(const size_t, const size_t, const size_t); +template std::shared_ptr create_mock_honk_vk< + UltraZKFlavor, + stdlib::recursion::honk::DefaultIO>(const size_t, const size_t, const size_t); +template std::shared_ptr create_mock_honk_vk( + const size_t, const size_t, const size_t); + template std::shared_ptr> create_mock_decider_vk(); } // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.hpp index eef92550e588..61f9c77df380 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.hpp @@ -14,15 +14,22 @@ namespace acir_format { -template bb::HonkProof create_mock_oink_proof(); -template bb::HonkProof create_mock_decider_proof(); -template bb::HonkProof create_mock_honk_proof(); +template +bb::HonkProof create_mock_oink_proof(const size_t inner_public_inputs_size = 0); +template +bb::HonkProof create_mock_decider_proof(const size_t const_proof_log_n = bb::CONST_PROOF_SIZE_LOG_N); +template +bb::HonkProof create_mock_honk_proof(const size_t inner_public_inputs_size = 0); template bb::HonkProof create_mock_pg_proof(); bb::Goblin::MergeProof create_mock_merge_proof(); +bb::HonkProof create_mock_pre_ipa_proof(); +bb::HonkProof create_mock_ipa_proof(); +bb::HonkProof create_mock_translator_proof(); template std::shared_ptr create_mock_honk_vk(const size_t dyadic_size, - const size_t pub_inputs_offset); + const size_t pub_inputs_offset, + const size_t inner_public_inputs_size = 0); template std::shared_ptr> create_mock_decider_vk(); } // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.test.cpp index 4429064470f3..6b5e4fc055ae 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.test.cpp @@ -16,9 +16,12 @@ using namespace acir_format; using namespace bb; -template class MockVerifierInputsTest : public ::testing::Test {}; +template class MockVerifierInputsTest : public ::testing::Test { + public: + static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } +}; -using FlavorTypes = testing::Types; +using FlavorTypes = testing::Types; TYPED_TEST_SUITE(MockVerifierInputsTest, FlavorTypes); @@ -31,6 +34,33 @@ TEST(MockVerifierInputsTest, MockMergeProofSize) EXPECT_EQ(merge_proof.size(), MERGE_PROOF_SIZE); } +/** + * @brief Check that the size of a mock pre-ipa proof matches expectation + */ +TEST(MockVerifierInputsTest, MockPreIpaProofSize) +{ + HonkProof pre_ipa_proof = create_mock_pre_ipa_proof(); + EXPECT_EQ(pre_ipa_proof.size(), ECCVMFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS - IPA_PROOF_LENGTH); +} + +/** + * @brief Check that the size of a mock ipa proof matches expectation + */ +TEST(MockVerifierInputsTest, MockIPAProofSize) +{ + HonkProof ipa_proof = create_mock_ipa_proof(); + EXPECT_EQ(ipa_proof.size(), IPA_PROOF_LENGTH); +} + +/** + * @brief Check that the size of a mock translator proof matches expectation + */ +TEST(MockVerifierInputsTest, MockTranslatorProofSize) +{ + HonkProof translator_proof = create_mock_translator_proof(); + EXPECT_EQ(translator_proof.size(), TranslatorFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS); +} + /** * @brief Check that the size of a mock Oink proof matches expectation for MegaFlavor * @@ -63,18 +93,24 @@ TEST(MockVerifierInputsTest, MockMegaOinkProofSize) } /** - * @brief Check that the size of a mock Oink proof matches expectation for UltraFlavor + * @brief Check that the size of a mock Oink proof matches expectation for Ultra flavors * */ -TEST(MockVerifierInputsTest, MockUltraOinkProofSize) +TYPED_TEST(MockVerifierInputsTest, MockUltraOinkProofSize) { - using Flavor = UltraFlavor; - using Builder = UltraCircuitBuilder; - - // DefaultIO - const size_t NUM_PUBLIC_INPUTS = stdlib::recursion::honk::DefaultIO::PUBLIC_INPUTS_SIZE; - HonkProof honk_proof = create_mock_oink_proof>(); - EXPECT_EQ(honk_proof.size(), Flavor::OINK_PROOF_LENGTH_WITHOUT_PUB_INPUTS + NUM_PUBLIC_INPUTS); + using Flavor = TypeParam; + using Builder = Flavor::CircuitBuilder; + using IO = std::conditional_t, + stdlib::recursion::honk::RollupIO, + stdlib::recursion::honk::DefaultIO>; + + if (!std::is_same_v) { + const size_t NUM_PUBLIC_INPUTS = IO::PUBLIC_INPUTS_SIZE; + HonkProof honk_proof = create_mock_oink_proof(); + EXPECT_EQ(honk_proof.size(), Flavor::OINK_PROOF_LENGTH_WITHOUT_PUB_INPUTS + NUM_PUBLIC_INPUTS); + } else { + GTEST_SKIP(); + } } /** @@ -85,8 +121,12 @@ TYPED_TEST(MockVerifierInputsTest, MockDeciderProofSize) { using Flavor = TypeParam; - HonkProof honk_proof = create_mock_decider_proof(); - EXPECT_EQ(honk_proof.size(), Flavor::DECIDER_PROOF_LENGTH()); + if (!std::is_same_v) { + HonkProof honk_proof = create_mock_decider_proof(); + EXPECT_EQ(honk_proof.size(), Flavor::DECIDER_PROOF_LENGTH()); + } else { + GTEST_SKIP(); + } } /** @@ -121,16 +161,22 @@ TEST(MockVerifierInputsTest, MockMegaHonkProofSize) } /** - * @brief Check that the size of a mock Honk proof matches expectation for UltraFlavor + * @brief Check that the size of a mock Honk proof matches expectation for Ultra flavors * */ -TEST(MockVerifierInputsTest, MockHonkProofSize) +TYPED_TEST(MockVerifierInputsTest, MockHonkProofSize) { - using Flavor = UltraFlavor; - using Builder = UltraCircuitBuilder; - - // DefaultIO - const size_t NUM_PUBLIC_INPUTS = stdlib::recursion::honk::DefaultIO::PUBLIC_INPUTS_SIZE; - HonkProof honk_proof = create_mock_honk_proof>(); - EXPECT_EQ(honk_proof.size(), Flavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS() + NUM_PUBLIC_INPUTS); + using Flavor = TypeParam; + using Builder = Flavor::CircuitBuilder; + using IO = std::conditional_t, + stdlib::recursion::honk::RollupIO, + stdlib::recursion::honk::DefaultIO>; + + if (!std::is_same_v) { + const size_t NUM_PUBLIC_INPUTS = IO::PUBLIC_INPUTS_SIZE; + HonkProof honk_proof = create_mock_honk_proof(); + EXPECT_EQ(honk_proof.size(), Flavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS() + NUM_PUBLIC_INPUTS); + } else { + GTEST_SKIP(); + } } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/special_public_inputs/special_public_inputs.hpp b/barretenberg/cpp/src/barretenberg/stdlib/special_public_inputs/special_public_inputs.hpp index 5616092d7055..781ed73631d3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/special_public_inputs/special_public_inputs.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/special_public_inputs/special_public_inputs.hpp @@ -135,8 +135,9 @@ class KernelIO { * @brief Manages the data that is propagated on the public inputs of an application/function circuit * */ -template class DefaultIO { +template class DefaultIO { public: + using Builder = Builder_; using Curve = stdlib::bn254; // curve is always bn254 using FF = Curve::ScalarField; using PairingInputs = stdlib::recursion::PairingPoints;