From 6a228790b4a46b76efe583e2d466cd7c08d292ad Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 18 Aug 2023 16:35:34 +0000 Subject: [PATCH] lots of comment and naming updates based on review --- .../honk/flavor/ultra_recursive.hpp | 9 ++++ .../barretenberg/honk/pcs/shplonk/shplonk.hpp | 6 ++- .../sumcheck/polynomials/barycentric_data.hpp | 8 ++-- .../polynomials/barycentric_data.test.cpp | 3 +- .../barretenberg/honk/sumcheck/sumcheck.hpp | 2 +- .../recursion/honk/transcript/transcript.hpp | 2 +- .../honk/transcript/transcript.test.cpp | 3 +- .../verifier/ultra_recursive_verifier.cpp | 43 +++++++++---------- .../barretenberg/stdlib/utility/utility.hpp | 12 +++--- 9 files changed, 50 insertions(+), 38 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp index 47c306df840..3162b860482 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp @@ -28,6 +28,15 @@ namespace proof_system::honk::flavor { +/** + * @brief The recursive counterpart to the "native" Ultra flavor. + * @details This flavor can be used to instantiate a recursive Ultra Honk verifier for a proof created using the + * conventional Ultra flavor. It is similar in structure to its native counterpart with two main differences: 1) the + * curve types are stdlib types (e.g. field_t instead of field) and 2) it does not specify any Prover related types + * (e.g. Polynomial, ExtendedEdges, etc.) since we do not emulate prover computation in circuits, i.e. it only makes + * sense to instantiate a Verifier with this flavor. + * + */ class UltraRecursive { public: using CircuitBuilder = UltraCircuitBuilder; diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp index 428bacd068e..f4b11815c43 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp @@ -192,7 +192,9 @@ template class ShplonkVerifier_ { for (const auto& claim : claims) { vanishing_evals.emplace_back(z_challenge - claim.opening_pair.challenge); } - // If recursion, invert elements individually, otherwise batch invert + // If recursion, invert elements individually, otherwise batch invert. (Inversion is cheap in circuits since we + // need only prove the correctness of a known inverse, we do not emulate its computation. Hence no need for + // batch inversion). std::vector inverse_vanishing_evals; if constexpr (Curve::is_stdlib_type) { for (const auto& val : vanishing_evals) { @@ -234,7 +236,7 @@ template class ShplonkVerifier_ { } // [G] += G₀⋅[1] = [G] + (∑ⱼ ρʲ ⋅ vⱼ / ( r − xⱼ ))⋅[1] - Fr evaluation_zero; // 0 \in Fr + Fr evaluation_zero; // 0 \in Fr GroupElement group_one; // [1] if constexpr (Curve::is_stdlib_type) { auto ctx = transcript.builder; diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp index ce1d458b093..319ba0f287a 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.hpp @@ -3,10 +3,10 @@ #include #include -// TODO(#674): We need the functionality of BarycentricData for both field and field_t. The former is "literal" i.e. is -// compatible with constexpr operations, and the former is not. The functions for computing the pre-computable arrays in -// BarycentricData need to be constexpr and it takes some trickery to share these functions with the non-constexpr -// setting. Right now everything is more or less duplicated across BarycentricDataCompileTime and +// TODO(#674): We need the functionality of BarycentricData for both field (native) and field_t (stdlib). The former is +// is compatible with constexpr operations, and the former is not. The functions for computing the +// pre-computable arrays in BarycentricData need to be constexpr and it takes some trickery to share these functions +// with the non-constexpr setting. Right now everything is more or less duplicated across BarycentricDataCompileTime and // BarycentricDataRunTime. There should be a way to share more of the logic. /* IMPROVEMENT(Cody): This could or should be improved in various ways. In no particular order: diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.test.cpp index 68d3834f1e0..91d67db9c4f 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.test.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/polynomials/barycentric_data.test.cpp @@ -15,7 +15,8 @@ TYPED_TEST_SUITE(BarycentricDataTests, FieldTypes); #define BARYCENTIC_DATA_TESTS_TYPE_ALIASES using FF = TypeParam; /** - * @brief Ensure auxilliary arrays (e.g. big_domain) are computed at compile time if possible (i.e. if FF is literal) + * @brief Ensure auxilliary arrays (e.g. big_domain) are computed at compile time if possible (i.e. if FF is a native + * field) * */ TYPED_TEST(BarycentricDataTests, CompileTimeComputation) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp index 912ef990a4f..7d21b09d001 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp @@ -165,7 +165,7 @@ template class SumcheckVerifier { const size_t multivariate_d; SumcheckVerifierRound round; - // verifier instantiates sumcheck with circuit size and a verifier transcript + // verifier instantiates sumcheck with circuit size explicit SumcheckVerifier(size_t multivariate_n) : multivariate_d(numeric::get_msb(multivariate_n)) , round(){}; diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp index 662ff5d36d5..c26809d4353 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp @@ -91,7 +91,7 @@ template class Transcript { template auto receive_from_prover(const std::string& label) { // Get native type corresponding to input type - using NativeType = typename StdlibTypes::template CorrespondingNativeType::type; + using NativeType = typename StdlibTypes::template NativeType::type; // Extract the native element from the native transcript NativeType element = native_transcript.template receive_from_prover(label); diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp index f176d46fc66..f32032e499b 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp @@ -114,7 +114,8 @@ TEST(RecursiveHonkTranscript, InterfacesMatch) // Confirm that the native and stdlib verifier transcripts have generated the same manifest EXPECT_EQ(transcript.get_manifest(), native_transcript.get_manifest()); - // TODO(luke): This doesn't check much of anything until hashing is constrained in the stdlib transcript + // TODO(#1351): The Honk stdlib transcript does not currently lay down contraints for fiat-shamir hashing so + // check_circuit has limited value. EXPECT_TRUE(builder.check_circuit()); } diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp index 6c21e728c95..df9e8a199f0 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp @@ -31,10 +31,11 @@ UltraRecursiveVerifier_& UltraRecursiveVerifier_::operator=(Ultr } /** - * @brief This function verifies an Ultra Honk proof for given program settings. + * @brief This function constructs a recursive verifier circuit for an Ultra Honk proof of a given flavor. * */ -template std::array UltraRecursiveVerifier_::verify_proof(const plonk::proof& proof) +template +std::array UltraRecursiveVerifier_::verify_proof(const plonk::proof& proof) { using FF = typename Flavor::FF; using GroupElement = typename Flavor::GroupElement; @@ -53,7 +54,7 @@ template std::array UltraRec size_t prev_num_gates = builder->get_num_gates(); transcript = Transcript{ builder, proof.proof_data }; - + auto commitments = VerifierCommitments(key); auto commitment_labels = CommitmentLabels(); @@ -61,17 +62,12 @@ template std::array UltraRec const auto public_input_size = transcript.template receive_from_prover("public_input_size"); const auto pub_inputs_offset = transcript.template receive_from_prover("pub_inputs_offset"); - // Extract native integer types for these basic quantities for use in subsequent operations - auto circuit_size_native = static_cast(circuit_size.get_value()); - auto public_input_size_native = static_cast(public_input_size.get_value()); - auto pub_inputs_offset_native = static_cast(pub_inputs_offset.get_value()); - // For debugging purposes only - ASSERT(circuit_size_native == key->circuit_size); - ASSERT(public_input_size_native == key->num_public_inputs); + ASSERT(static_cast(circuit_size.get_value()) == key->circuit_size); + ASSERT(static_cast(public_input_size.get_value()) == key->num_public_inputs); std::vector public_inputs; - for (size_t i = 0; i < public_input_size_native; ++i) { + for (size_t i = 0; i < static_cast(public_input_size.get_value()); ++i) { auto public_input_i = transcript.template receive_from_prover("public_input_" + std::to_string(i)); public_inputs.emplace_back(public_input_i); } @@ -105,7 +101,7 @@ template std::array UltraRec auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); const FF public_input_delta = proof_system::honk::compute_public_input_delta( - public_inputs, beta, gamma, circuit_size, pub_inputs_offset_native); + public_inputs, beta, gamma, circuit_size, static_cast(pub_inputs_offset.get_value())); const FF lookup_grand_product_delta = proof_system::honk::compute_lookup_grand_product_delta(beta, gamma, circuit_size); @@ -119,7 +115,7 @@ template std::array UltraRec commitments.z_lookup = transcript.template receive_from_prover(commitment_labels.z_lookup); // Execute Sumcheck Verifier - auto sumcheck = Sumcheck(circuit_size_native); + auto sumcheck = Sumcheck(static_cast(circuit_size.get_value())); std::optional sumcheck_output = sumcheck.verify(relation_parameters, transcript); @@ -147,7 +143,10 @@ template std::array UltraRec info("Batched eval: num gates = ", builder->get_num_gates() - prev_num_gates); prev_num_gates = builder->get_num_gates(); - // Construct vectors of scalars for batched unshifted and to-be-shifted commitments + // Compute batched commitments needed for input to Gemini. + // Note: For efficiency in emulating the construction of the batched commitments, we want to perform a batch mul + // rather than naively accumulate the points one by one. To do this, we collect the points and scalars required for + // each MSM then perform the two batch muls. const size_t NUM_UNSHIFTED = commitments.get_unshifted().size(); const size_t NUM_TO_BE_SHIFTED = commitments.get_to_be_shifted().size(); std::vector scalars_unshifted; @@ -159,8 +158,8 @@ template std::array UltraRec for (size_t i = 0; i < NUM_TO_BE_SHIFTED; ++i) { scalars_to_be_shifted.emplace_back(rhos[idx++]); } - // TODO(luke): The powers_of_rho fctn does not set the context of rhos[0] = FF(1) so we do it explicitly here. Can we - // do something silly like set it to rho.pow(0) in the fctn to make it work both native and stdlib? + // TODO(luke): The powers_of_rho fctn does not set the context of rhos[0] = FF(1) so we do it explicitly here. Can + // we do something silly like set it to rho.pow(0) in the fctn to make it work both native and stdlib? scalars_unshifted[0] = FF::from_witness(builder, 1); // Batch the commitments to the unshifted and to-be-shifted polynomials using powers of rho @@ -179,17 +178,17 @@ template std::array UltraRec // - d+1 commitments [Fold_{r}^(0)], [Fold_{-r}^(0)], and [Fold^(l)], l = 1:d-1 // - d+1 evaluations a_0_pos, and a_l, l = 0:d-1 auto gemini_claim = Gemini::reduce_verification(multivariate_challenge, - batched_evaluation, - batched_commitment_unshifted, - batched_commitment_to_be_shifted, - transcript); + batched_evaluation, + batched_commitment_unshifted, + batched_commitment_to_be_shifted, + transcript); info("Gemini: num gates = ", builder->get_num_gates() - prev_num_gates); prev_num_gates = builder->get_num_gates(); // Produce a Shplonk claim: commitment [Q] - [Q_z], evaluation zero (at random challenge z) auto shplonk_claim = Shplonk::reduce_verification(pcs_verification_key, gemini_claim, transcript); - + info("Shplonk: num gates = ", builder->get_num_gates() - prev_num_gates); prev_num_gates = builder->get_num_gates(); @@ -197,7 +196,7 @@ template std::array UltraRec // Constuct the inputs to the final KZG pairing check auto pairing_points = PCS::compute_pairing_points(shplonk_claim, transcript); - + return pairing_points; } diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp index 5d53d2692b1..0031ef3231a 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp @@ -107,27 +107,27 @@ template class StdlibTypesUtility { * @tparam T * @tparam LENGTH (used only for containers which specify a length, e.g. array/Univariate) */ - template struct CorrespondingNativeType { + template struct NativeType { using type = void; }; - template struct CorrespondingNativeType { + template struct NativeType { using type = uint32_t; }; - template struct CorrespondingNativeType { + template struct NativeType { using type = FF; }; - template struct CorrespondingNativeType { + template struct NativeType { using type = Commitment; }; - template struct CorrespondingNativeType, 0> { + template struct NativeType, 0> { using type = std::array; }; - template struct CorrespondingNativeType, 0> { + template struct NativeType, 0> { using type = Univariate; }; };