From 645d42734cd8c698f8225d2e85c92cbc64814207 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 26 Jul 2023 22:39:07 +0000 Subject: [PATCH 01/11] transcript file --- .../recursion/transcript/honk_trancript.hpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp new file mode 100644 index 00000000000..31df942a38d --- /dev/null +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/transcript/transcript.hpp" + +#include "../../commitment/pedersen/pedersen.hpp" +#include "../../commitment/pedersen/pedersen_plookup.hpp" +#include "../../hash/blake3s/blake3s.hpp" +#include "../../primitives/bigfield/bigfield.hpp" +#include "../../primitives/biggroup/biggroup.hpp" +#include "../../primitives/bool/bool.hpp" +#include "../../primitives/curves/bn254.hpp" +#include "../../primitives/field/field.hpp" +#include "../../primitives/witness/witness.hpp" +#include "../verification_key/verification_key.hpp" + +namespace proof_system::plonk::stdlib::recursion::honk { +template class Transcript { + public: + using field_pt = field_t; + using witness_pt = witness_t; + using fq_pt = bigfield; + using group_pt = element; + using Key = verification_key>; +}; +} // namespace proof_system::plonk::stdlib::recursion::honk From a81c9428207a8562f1d4d7601161f18058d16980 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 27 Jul 2023 15:59:31 +0000 Subject: [PATCH 02/11] initial structures and test in place --- .../recursion/transcript/honk_trancript.hpp | 44 +++++++++-- .../transcript/honk_transcript.test.cpp | 78 +++++++++++++++++++ 2 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp index 31df942a38d..bb42b61506e 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp @@ -3,7 +3,8 @@ #include "barretenberg/ecc/curves/bn254/fq.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/transcript/transcript.hpp" +// #include "barretenberg/transcript/transcript.hpp" +#include "barretenberg/honk/transcript/transcript.hpp" #include "../../commitment/pedersen/pedersen.hpp" #include "../../commitment/pedersen/pedersen_plookup.hpp" @@ -17,12 +18,41 @@ #include "../verification_key/verification_key.hpp" namespace proof_system::plonk::stdlib::recursion::honk { -template class Transcript { +template class Transcript { public: - using field_pt = field_t; - using witness_pt = witness_t; - using fq_pt = bigfield; - using group_pt = element; - using Key = verification_key>; + using field_pt = field_t; + using witness_pt = witness_t; + using fq_pt = bigfield; + using group_pt = element; + using Key = verification_key>; + using FF = barretenberg::fr; + using VerifierTranscript = proof_system::honk::VerifierTranscript; + + VerifierTranscript native_transcript; + + Transcript(auto proof_data) + : native_transcript(proof_data){}; + + auto get_manifest() const { return native_transcript.get_manifest(); }; + + template std::array get_challenges(const Strings&... labels) + { + constexpr size_t num_challenges = sizeof...(Strings); + std::array challenges{}; + challenges = native_transcript.get_challenges(labels...); + return challenges; + } + + FF get_challenge(const std::string& label) + { + auto challenge = native_transcript.get_challenge(label); + return challenge; + } + + template T receive_from_prover(const std::string& label) + { + T element = native_transcript.template receive_from_prover(label); + return element; + } }; } // namespace proof_system::plonk::stdlib::recursion::honk diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp new file mode 100644 index 00000000000..eedd0e0879e --- /dev/null +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp @@ -0,0 +1,78 @@ +#include + +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/honk/transcript/transcript.hpp" +#include "barretenberg/stdlib/recursion/transcript/honk_trancript.hpp" + +namespace proof_system::plonk::stdlib::recursion::honk { + +// TODO(Cody): Testing only one circuit type. +using Builder = UltraCircuitBuilder; + +using field_t = stdlib::field_t; +using bool_t = stdlib::bool_t; +using uint32 = stdlib::uint; +using witness_t = stdlib::witness_t; +using byte_array = stdlib::byte_array; +using fq_t = stdlib::bigfield; +using group_t = stdlib::element; +using transcript_ct = Transcript; +using FF = barretenberg::fr; +using Commitment = barretenberg::g1::affine_element; +using Point = barretenberg::g1::element; +using ProverTranscript = ::proof_system::honk::ProverTranscript; +using VerifierTranscript = ::proof_system::honk::VerifierTranscript; + +auto generate_mock_proof_data(auto prover_transcript) +{ + uint32_t data = 25; + auto scalar = FF::random_element(); + auto commitment = Commitment::one(); + // auto univariate = Univariate(evaluations); + + // round 0 + prover_transcript.send_to_verifier("data", data); + prover_transcript.get_challenge("alpha"); + + // round 1 + prover_transcript.send_to_verifier("scalar", scalar); + prover_transcript.send_to_verifier("commitment", commitment); + prover_transcript.get_challenges("beta, gamma"); + + return prover_transcript.proof_data; +} + +void perform_mock_transcript_operations(auto transcript) +{ + transcript.template receive_from_prover("data"); + transcript.get_challenge("alpha"); + + transcript.template receive_from_prover("scalar"); + transcript.template receive_from_prover("commitment"); + transcript.get_challenges("beta, gamma"); +} + +TEST(stdlib_honk_transcript, basic_transcript_operations) +{ + // Instantiate a Prover Transcript and use it to generate some proof data + ProverTranscript prover_transcript; + auto proof_data = generate_mock_proof_data(prover_transcript); + + // Instantiate a (native) Verifier Transcript the proof data and perform some mock transcript operations + VerifierTranscript native_transcript(proof_data); + perform_mock_transcript_operations(native_transcript); + + // Confirm that Prover and Verifier transcripts have generated the same manifest via the operations performed + EXPECT_EQ(prover_transcript.get_manifest(), native_transcript.get_manifest()); + + // Instantiate a stdlib Transcript and perform the same operations + Builder builder; + Transcript transcript{proof_data}; + perform_mock_transcript_operations(transcript); + + // Confirm that the native and stdlib transcripts have generated the same manifest + EXPECT_EQ(transcript.get_manifest(), native_transcript.get_manifest()); + +} +} // namespace proof_system::plonk::stdlib::recursion::honk \ No newline at end of file From ef2e87988d3d3bfb4c47ed12a6ada8336b0bfc4f Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 27 Jul 2023 18:27:28 +0000 Subject: [PATCH 03/11] transcript fctns return corresp stdlib types --- .../recursion/transcript/honk_trancript.hpp | 86 +++++++++++++++++-- .../transcript/honk_transcript.test.cpp | 11 ++- 2 files changed, 86 insertions(+), 11 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp index bb42b61506e..66ece1a1838 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp @@ -26,33 +26,105 @@ template class Transcript { using group_pt = element; using Key = verification_key>; using FF = barretenberg::fr; + using Commitment = barretenberg::g1::affine_element; using VerifierTranscript = proof_system::honk::VerifierTranscript; VerifierTranscript native_transcript; + Builder* builder; - Transcript(auto proof_data) - : native_transcript(proof_data){}; + Transcript(Builder* builder, auto proof_data) + : native_transcript(proof_data) + , builder(builder){}; + /** + * @brief Get the underlying native transcript manifest (primarily for debugging) + * + */ auto get_manifest() const { return native_transcript.get_manifest(); }; + /** + * @brief Compute the challenges (more than 1) indicated by labels + * + * @tparam Strings + * @param labels Names of the challenges to be computed + * @return std::array Array of challenges + */ template std::array get_challenges(const Strings&... labels) { + // Compute the indicated challenges from the native transcript constexpr size_t num_challenges = sizeof...(Strings); std::array challenges{}; challenges = native_transcript.get_challenges(labels...); + + // Do stdlib version of fiat-shamir here.. + return challenges; } - FF get_challenge(const std::string& label) + /** + * @brief Compute the single challenge indicated by the input label + * + * @param label Name of challenge + * @return FF Challenge + */ + FF get_challenge(const std::string& label) { - auto challenge = native_transcript.get_challenge(label); - return challenge; + // Compute the indicated challenge from the native transcript + auto challenge = native_transcript.get_challenge(label); + + // Do stdlib version of fiat-shamir here.. + + return challenge; } - template T receive_from_prover(const std::string& label) + /** + * @brief Extract a native element from the transcript and return a corresponding stdlib type + * + * @tparam T Type of the native element to be extracted + * @param label Name of the element + * @return The corresponding element of appropriate stdlib type + */ + template auto receive_from_prover(const std::string& label) { + // Extract the native element from the native transcript T element = native_transcript.template receive_from_prover(label); - return element; + + // Add variables corresponding to the witness element and return the corresponding stdlib type + return stdlib_type_from_witness(element); + } + + /** + * @brief Construct stdlib field from uint32_t + * + * @param element + * @return field_pt + */ + field_pt stdlib_type_from_witness(uint32_t element) + { + return witness_pt(builder, element); } + + /** + * @brief Construct stdlib field from native field type + * + * @param element + * @return field_pt + */ + field_pt stdlib_type_from_witness(FF element) + { + return witness_pt(builder, element); + } + + /** + * @brief Construct stdlib group from native affine group element type + * + * @param element + * @return field_pt + */ + group_pt stdlib_type_from_witness(Commitment element) + { + return group_pt::from_witness(builder, element); + } + }; } // namespace proof_system::plonk::stdlib::recursion::honk diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp index eedd0e0879e..1f136ed9af8 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp @@ -55,11 +55,13 @@ void perform_mock_transcript_operations(auto transcript) TEST(stdlib_honk_transcript, basic_transcript_operations) { - // Instantiate a Prover Transcript and use it to generate some proof data + Builder builder; + + // Instantiate a Prover Transcript and use it to generate some mock proof data ProverTranscript prover_transcript; auto proof_data = generate_mock_proof_data(prover_transcript); - // Instantiate a (native) Verifier Transcript the proof data and perform some mock transcript operations + // Instantiate a (native) Verifier Transcript with the proof data and perform some mock transcript operations VerifierTranscript native_transcript(proof_data); perform_mock_transcript_operations(native_transcript); @@ -67,12 +69,13 @@ TEST(stdlib_honk_transcript, basic_transcript_operations) EXPECT_EQ(prover_transcript.get_manifest(), native_transcript.get_manifest()); // Instantiate a stdlib Transcript and perform the same operations - Builder builder; - Transcript transcript{proof_data}; + Transcript transcript{&builder, proof_data}; perform_mock_transcript_operations(transcript); // Confirm that the native and stdlib transcripts have generated the same manifest EXPECT_EQ(transcript.get_manifest(), native_transcript.get_manifest()); + EXPECT_TRUE(builder.check_circuit()); + } } // namespace proof_system::plonk::stdlib::recursion::honk \ No newline at end of file From 52f5ae49439219398523b562c31f59730dc1126a Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 27 Jul 2023 20:29:20 +0000 Subject: [PATCH 04/11] basic circuity fiat shamir in place --- .../recursion/transcript/honk_trancript.hpp | 90 ++++++++++++++++--- .../verification_key/verification_key.hpp | 7 ++ 2 files changed, 84 insertions(+), 13 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp index 66ece1a1838..a18e1574514 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp @@ -24,17 +24,26 @@ template class Transcript { using witness_pt = witness_t; using fq_pt = bigfield; using group_pt = element; + using byte_array = byte_array; using Key = verification_key>; using FF = barretenberg::fr; using Commitment = barretenberg::g1::affine_element; using VerifierTranscript = proof_system::honk::VerifierTranscript; + static constexpr size_t HASH_OUTPUT_SIZE = 32; // WORKTODO: Duplicated from native transcript + VerifierTranscript native_transcript; Builder* builder; + // maximum number of bytes we can store in a field element w/o wrapping modulus is 31. + // while we could store more *bits*, we want `preimage_buffer` to mirror how data is formatted + // when we serialize field/group elements natively (i.e. a byte array) + static constexpr size_t NUM_BITS_PER_PREIMAGE_ELEMENT = 31UL * 8UL; + PedersenPreimageBuilder preimage_buffer; Transcript(Builder* builder, auto proof_data) : native_transcript(proof_data) - , builder(builder){}; + , builder(builder) + , preimage_buffer(builder){}; /** * @brief Get the underlying native transcript manifest (primarily for debugging) @@ -67,14 +76,28 @@ template class Transcript { * @param label Name of challenge * @return FF Challenge */ - FF get_challenge(const std::string& label) + field_pt get_challenge(const std::string& label) { // Compute the indicated challenge from the native transcript - auto challenge = native_transcript.get_challenge(label); + // WORKTODO: need to call this to update native transcript but maybe dont need the native challenge itself + [[maybe_unused]] auto native_challenge = native_transcript.get_challenge(label); + + // Stdlib Fiat-Shamir + // Compress buffer via pedersen then hash the result using Blake3s + field_pt compressed_buffer = preimage_buffer.compress(0); + auto buffer_bytes = byte_array(compressed_buffer); + auto challenge_buffer = blake3s(buffer_bytes); + + auto current_challenge = field_pt(challenge_buffer.slice(0, HASH_OUTPUT_SIZE)); + + info("native_challenge = ", native_challenge); + info("current_challenge = ", current_challenge.get_value()); - // Do stdlib version of fiat-shamir here.. - return challenge; + preimage_buffer.clear(); + preimage_buffer.add_element(current_challenge); + + return current_challenge; } /** @@ -99,31 +122,72 @@ template class Transcript { * @param element * @return field_pt */ - field_pt stdlib_type_from_witness(uint32_t element) + field_pt stdlib_type_from_witness(uint32_t native_element) { - return witness_pt(builder, element); + auto element = witness_pt(builder, native_element); + + // WORKTODO: do something special here for the uint32_t? + preimage_buffer.add_element(element); + + return element; } /** * @brief Construct stdlib field from native field type * - * @param element + * @param native_element * @return field_pt */ - field_pt stdlib_type_from_witness(FF element) + field_pt stdlib_type_from_witness(FF native_element) { - return witness_pt(builder, element); + auto element = witness_pt(builder, native_element); + + preimage_buffer.add_element(element); + + return element; } /** * @brief Construct stdlib group from native affine group element type * - * @param element + * @param native_element * @return field_pt */ - group_pt stdlib_type_from_witness(Commitment element) + group_pt stdlib_type_from_witness(Commitment native_element) + { + auto element = group_pt::from_witness(builder, native_element); + + add_commitment_to_preimage_buffer(element); + + return element; + } + + /** + * @brief Add an EC point / commitment to the pedersen preimage buffer + * + * @param point + */ + void add_commitment_to_preimage_buffer(group_pt& point) { - return group_pt::from_witness(builder, element); + const auto& x = point.x; + const auto& y = point.y; + constexpr size_t last_limb_bits = 256 - (fq_pt::NUM_LIMB_BITS * 3); + preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[3].element, + last_limb_bits); + preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[2].element, + fq_pt::NUM_LIMB_BITS); + preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[1].element, + fq_pt::NUM_LIMB_BITS); + preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[0].element, + fq_pt::NUM_LIMB_BITS); + preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[3].element, + last_limb_bits); + preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[2].element, + fq_pt::NUM_LIMB_BITS); + preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[1].element, + fq_pt::NUM_LIMB_BITS); + preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[0].element, + fq_pt::NUM_LIMB_BITS); } }; diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp index aa990dce7dd..e04b896905a 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp @@ -81,6 +81,13 @@ template struct PedersenPreimage size_t current_bit_counter = 0; + void clear() + { + preimage_data.clear(); + work_element.clear(); + current_bit_counter = 0; + } + void add_element(const field_pt& element) { slice_element(element, 256); } void add_element_with_existing_range_constraint(const field_pt& element, const size_t num_bits) From d943bd56d7aca78a2af431a1b7fe8e199793708c Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 28 Jul 2023 19:33:28 +0000 Subject: [PATCH 05/11] removing stdlib hashing for now --- .../recursion/transcript/honk_trancript.hpp | 115 ++++++------------ 1 file changed, 34 insertions(+), 81 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp index a18e1574514..9cbc744fffb 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp @@ -34,75 +34,64 @@ template class Transcript { VerifierTranscript native_transcript; Builder* builder; - // maximum number of bytes we can store in a field element w/o wrapping modulus is 31. - // while we could store more *bits*, we want `preimage_buffer` to mirror how data is formatted - // when we serialize field/group elements natively (i.e. a byte array) - static constexpr size_t NUM_BITS_PER_PREIMAGE_ELEMENT = 31UL * 8UL; - PedersenPreimageBuilder preimage_buffer; Transcript(Builder* builder, auto proof_data) : native_transcript(proof_data) - , builder(builder) - , preimage_buffer(builder){}; + , builder(builder){}; /** * @brief Get the underlying native transcript manifest (primarily for debugging) - * + * */ auto get_manifest() const { return native_transcript.get_manifest(); }; /** * @brief Compute the challenges (more than 1) indicated by labels - * - * @tparam Strings + * + * @tparam Strings * @param labels Names of the challenges to be computed * @return std::array Array of challenges */ - template std::array get_challenges(const Strings&... labels) + template std::array get_challenges(const Strings&... labels) { // Compute the indicated challenges from the native transcript constexpr size_t num_challenges = sizeof...(Strings); - std::array challenges{}; - challenges = native_transcript.get_challenges(labels...); - - // Do stdlib version of fiat-shamir here.. + std::array native_challenges{}; + native_challenges = native_transcript.get_challenges(labels...); + + /* + * TODO(luke): Do stdlib hashing here. E.g., for the current pedersen/blake setup, we could write data into a + * byte_array as it is received from prover, then compress via pedersen and apply blake3s. Not doing this now + * since it's a pain and we'll be revamping our hashing anyway. For now, simply convert the native hashes to + * stdlib types without adding any hashing constraints. + */ + std::array challenges; + for (size_t i = 0; i < num_challenges; ++i) { + challenges[i] = native_challenges[i]; + } return challenges; } /** * @brief Compute the single challenge indicated by the input label - * + * * @param label Name of challenge - * @return FF Challenge + * @return field_pt Challenge */ field_pt get_challenge(const std::string& label) { // Compute the indicated challenge from the native transcript - // WORKTODO: need to call this to update native transcript but maybe dont need the native challenge itself - [[maybe_unused]] auto native_challenge = native_transcript.get_challenge(label); - - // Stdlib Fiat-Shamir - // Compress buffer via pedersen then hash the result using Blake3s - field_pt compressed_buffer = preimage_buffer.compress(0); - auto buffer_bytes = byte_array(compressed_buffer); - auto challenge_buffer = blake3s(buffer_bytes); - - auto current_challenge = field_pt(challenge_buffer.slice(0, HASH_OUTPUT_SIZE)); - - info("native_challenge = ", native_challenge); - info("current_challenge = ", current_challenge.get_value()); + auto native_challenge = native_transcript.get_challenge(label); + // TODO(luke): Stdlib hashing here... - preimage_buffer.clear(); - preimage_buffer.add_element(current_challenge); - - return current_challenge; + return field_pt(native_challenge); } /** * @brief Extract a native element from the transcript and return a corresponding stdlib type - * + * * @tparam T Type of the native element to be extracted * @param label Name of the element * @return The corresponding element of appropriate stdlib type @@ -118,77 +107,41 @@ template class Transcript { /** * @brief Construct stdlib field from uint32_t - * - * @param element - * @return field_pt + * + * @param element + * @return field_pt */ field_pt stdlib_type_from_witness(uint32_t native_element) { auto element = witness_pt(builder, native_element); - // WORKTODO: do something special here for the uint32_t? - preimage_buffer.add_element(element); - return element; } /** * @brief Construct stdlib field from native field type - * - * @param native_element - * @return field_pt + * + * @param native_element + * @return field_pt */ field_pt stdlib_type_from_witness(FF native_element) { auto element = witness_pt(builder, native_element); - preimage_buffer.add_element(element); - return element; } /** * @brief Construct stdlib group from native affine group element type - * - * @param native_element - * @return field_pt + * + * @param native_element + * @return field_pt */ group_pt stdlib_type_from_witness(Commitment native_element) { auto element = group_pt::from_witness(builder, native_element); - add_commitment_to_preimage_buffer(element); - - return element; - } - - /** - * @brief Add an EC point / commitment to the pedersen preimage buffer - * - * @param point - */ - void add_commitment_to_preimage_buffer(group_pt& point) - { - const auto& x = point.x; - const auto& y = point.y; - constexpr size_t last_limb_bits = 256 - (fq_pt::NUM_LIMB_BITS * 3); - preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[3].element, - last_limb_bits); - preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[2].element, - fq_pt::NUM_LIMB_BITS); - preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[1].element, - fq_pt::NUM_LIMB_BITS); - preimage_buffer.add_element_with_existing_range_constraint(y.binary_basis_limbs[0].element, - fq_pt::NUM_LIMB_BITS); - preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[3].element, - last_limb_bits); - preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[2].element, - fq_pt::NUM_LIMB_BITS); - preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[1].element, - fq_pt::NUM_LIMB_BITS); - preimage_buffer.add_element_with_existing_range_constraint(x.binary_basis_limbs[0].element, - fq_pt::NUM_LIMB_BITS); + return element; } - }; } // namespace proof_system::plonk::stdlib::recursion::honk From 0758babab65920dcc7281151f6d019deeb7563aa Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 28 Jul 2023 21:49:20 +0000 Subject: [PATCH 06/11] add univariate and array plus test --- .../recursion/transcript/honk_trancript.hpp | 46 ++++++-- .../transcript/honk_transcript.test.cpp | 101 +++++++++++++++--- .../verification_key/verification_key.hpp | 7 -- 3 files changed, 124 insertions(+), 30 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp index 9cbc744fffb..5133904631a 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp @@ -3,19 +3,12 @@ #include "barretenberg/ecc/curves/bn254/fq.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" -// #include "barretenberg/transcript/transcript.hpp" +#include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/honk/transcript/transcript.hpp" -#include "../../commitment/pedersen/pedersen.hpp" -#include "../../commitment/pedersen/pedersen_plookup.hpp" -#include "../../hash/blake3s/blake3s.hpp" #include "../../primitives/bigfield/bigfield.hpp" #include "../../primitives/biggroup/biggroup.hpp" -#include "../../primitives/bool/bool.hpp" -#include "../../primitives/curves/bn254.hpp" #include "../../primitives/field/field.hpp" -#include "../../primitives/witness/witness.hpp" -#include "../verification_key/verification_key.hpp" namespace proof_system::plonk::stdlib::recursion::honk { template class Transcript { @@ -24,11 +17,10 @@ template class Transcript { using witness_pt = witness_t; using fq_pt = bigfield; using group_pt = element; - using byte_array = byte_array; - using Key = verification_key>; using FF = barretenberg::fr; using Commitment = barretenberg::g1::affine_element; using VerifierTranscript = proof_system::honk::VerifierTranscript; + template using Univariate = proof_system::honk::sumcheck::Univariate; static constexpr size_t HASH_OUTPUT_SIZE = 32; // WORKTODO: Duplicated from native transcript @@ -105,6 +97,11 @@ template class Transcript { return stdlib_type_from_witness(element); } + private: + // Series of overloaded methods for converting native types extracted from the native transcript to the + // corresponding stdlib type for output. + // TODO(luke): Eventually these can also add data to a buffer (byte_array) to be hashed. + /** * @brief Construct stdlib field from uint32_t * @@ -143,5 +140,34 @@ template class Transcript { return element; } + + /** + * @brief Construct field_t array from native field array + * @param native_element Array of FF + * @return std::array + */ + template std::array stdlib_type_from_witness(std::array native_element) + { + std::array element; + for (size_t i = 0; i < LENGTH; ++i) { + element[i] = witness_pt(builder, native_element[i]); + } + return element; + } + + /** + * @brief Construct field_t array from native Univariate type + * TODO(luke): do we need a stdlib Univariate or is std::array good enough? + * @param native_element + * @return std::array + */ + template std::array stdlib_type_from_witness(Univariate native_element) + { + std::array element; + for (size_t i = 0; i < LENGTH; ++i) { + element[i] = witness_pt(builder, native_element.value_at(i)); + } + return element; + } }; } // namespace proof_system::plonk::stdlib::recursion::honk diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp index 1f136ed9af8..983b4c74a71 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp @@ -2,6 +2,7 @@ #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/stdlib/recursion/transcript/honk_trancript.hpp" @@ -10,26 +11,31 @@ namespace proof_system::plonk::stdlib::recursion::honk { // TODO(Cody): Testing only one circuit type. using Builder = UltraCircuitBuilder; -using field_t = stdlib::field_t; -using bool_t = stdlib::bool_t; -using uint32 = stdlib::uint; -using witness_t = stdlib::witness_t; -using byte_array = stdlib::byte_array; -using fq_t = stdlib::bigfield; -using group_t = stdlib::element; -using transcript_ct = Transcript; using FF = barretenberg::fr; using Commitment = barretenberg::g1::affine_element; using Point = barretenberg::g1::element; +constexpr size_t LENGTH = 8; // arbitrary +using Univariate = proof_system::honk::sumcheck::Univariate; using ProverTranscript = ::proof_system::honk::ProverTranscript; using VerifierTranscript = ::proof_system::honk::VerifierTranscript; +/** + * @brief Create some mock data and then add it to the transcript in various mock rounds + * + * @param prover_transcript + * @return auto proof_data + */ auto generate_mock_proof_data(auto prover_transcript) { uint32_t data = 25; auto scalar = FF::random_element(); auto commitment = Commitment::one(); - // auto univariate = Univariate(evaluations); + + std::array evaluations; + for (auto& eval : evaluations) { + eval = FF::random_element(); + } + auto univariate = Univariate(evaluations); // round 0 prover_transcript.send_to_verifier("data", data); @@ -40,17 +46,34 @@ auto generate_mock_proof_data(auto prover_transcript) prover_transcript.send_to_verifier("commitment", commitment); prover_transcript.get_challenges("beta, gamma"); + // round 2 + prover_transcript.send_to_verifier("univariate", univariate); + prover_transcript.get_challenges("gamma", "delta"); + return prover_transcript.proof_data; } -void perform_mock_transcript_operations(auto transcript) +/** + * @brief Perform series of verifier transcript operations + * @details Operations are designed to correspond to those performed by a prover transcript from which the verifier + * transcript was initialized. + * + * @param transcript Either a native or stdlib verifier transcript + */ +void perform_mock_verifier_transcript_operations(auto transcript) { + // round 0 transcript.template receive_from_prover("data"); transcript.get_challenge("alpha"); + // round 1 transcript.template receive_from_prover("scalar"); transcript.template receive_from_prover("commitment"); transcript.get_challenges("beta, gamma"); + + // round 2 + transcript.template receive_from_prover("univariate"); + transcript.get_challenges("gamma", "delta"); } TEST(stdlib_honk_transcript, basic_transcript_operations) @@ -63,19 +86,71 @@ TEST(stdlib_honk_transcript, basic_transcript_operations) // Instantiate a (native) Verifier Transcript with the proof data and perform some mock transcript operations VerifierTranscript native_transcript(proof_data); - perform_mock_transcript_operations(native_transcript); + perform_mock_verifier_transcript_operations(native_transcript); // Confirm that Prover and Verifier transcripts have generated the same manifest via the operations performed EXPECT_EQ(prover_transcript.get_manifest(), native_transcript.get_manifest()); // Instantiate a stdlib Transcript and perform the same operations - Transcript transcript{&builder, proof_data}; - perform_mock_transcript_operations(transcript); + Transcript transcript{ &builder, proof_data }; + perform_mock_verifier_transcript_operations(transcript); // Confirm that the native and stdlib 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 EXPECT_TRUE(builder.check_circuit()); +} + +TEST(stdlib_honk_transcript, return_values) +{ + Builder builder; + // Define some mock data for a mock proof + uint32_t data = 25; + auto scalar = FF::random_element(); + auto commitment = Commitment::one(); + + const size_t LENGTH = 10; // arbitrary + std::array evaluations; + for (auto& eval : evaluations) { + eval = FF::random_element(); + } + + // Construct a mock proof via the prover transcript + ProverTranscript prover_transcript; + prover_transcript.send_to_verifier("data", data); + prover_transcript.send_to_verifier("scalar", scalar); + prover_transcript.send_to_verifier("commitment", commitment); + prover_transcript.send_to_verifier("evaluations", evaluations); + prover_transcript.get_challenges("alpha, beta"); + auto proof_data = prover_transcript.proof_data; + + // Perform the corresponding operations with the native verifier transcript + VerifierTranscript native_transcript(proof_data); + auto native_data = native_transcript.template receive_from_prover("data"); + auto native_scalar = native_transcript.template receive_from_prover("scalar"); + auto native_commitment = native_transcript.template receive_from_prover("commitment"); + auto native_evaluations = native_transcript.template receive_from_prover>("evaluations"); + auto [native_alpha, native_beta] = native_transcript.get_challenges("alpha", "beta"); + + // Perform the corresponding operations with the stdlib verifier transcript + Transcript stdlib_transcript{ &builder, proof_data }; + auto stdlib_data = stdlib_transcript.template receive_from_prover("data"); + auto stdlib_scalar = stdlib_transcript.template receive_from_prover("scalar"); + auto stdlib_commitment = stdlib_transcript.template receive_from_prover("commitment"); + auto stdlib_evaluations = stdlib_transcript.template receive_from_prover>("evaluations"); + auto [stdlib_alpha, stdlib_beta] = stdlib_transcript.get_challenges("alpha", "beta"); + + // Confirm that return values are equivalent + EXPECT_EQ(native_data, stdlib_data.get_value()); + EXPECT_EQ(native_scalar, stdlib_scalar.get_value()); + EXPECT_EQ(native_commitment, stdlib_commitment.get_value()); + for (size_t i = 0; i < LENGTH; ++i) { + EXPECT_EQ(native_evaluations[i], stdlib_evaluations[i].get_value()); + } + EXPECT_EQ(native_alpha, stdlib_alpha.get_value()); + EXPECT_EQ(native_beta, stdlib_beta.get_value()); } + } // namespace proof_system::plonk::stdlib::recursion::honk \ No newline at end of file diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp index e04b896905a..aa990dce7dd 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/verification_key/verification_key.hpp @@ -81,13 +81,6 @@ template struct PedersenPreimage size_t current_bit_counter = 0; - void clear() - { - preimage_data.clear(); - work_element.clear(); - current_bit_counter = 0; - } - void add_element(const field_pt& element) { slice_element(element, 256); } void add_element_with_existing_range_constraint(const field_pt& element, const size_t num_bits) From 62f59ce09f4e72642651741fcb659bb9c3b022ba Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 28 Jul 2023 21:59:12 +0000 Subject: [PATCH 07/11] fix build --- .../transcript/honk_transcript.test.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp index 983b4c74a71..db47fe7da52 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp @@ -62,16 +62,16 @@ auto generate_mock_proof_data(auto prover_transcript) */ void perform_mock_verifier_transcript_operations(auto transcript) { - // round 0 + // round 0 transcript.template receive_from_prover("data"); transcript.get_challenge("alpha"); - // round 1 + // round 1 transcript.template receive_from_prover("scalar"); transcript.template receive_from_prover("commitment"); transcript.get_challenges("beta, gamma"); - // round 2 + // round 2 transcript.template receive_from_prover("univariate"); transcript.get_challenges("gamma", "delta"); } @@ -107,9 +107,8 @@ TEST(stdlib_honk_transcript, return_values) Builder builder; // Define some mock data for a mock proof - uint32_t data = 25; auto scalar = FF::random_element(); - auto commitment = Commitment::one(); + auto commitment = Commitment::one() * FF::random_element(); const size_t LENGTH = 10; // arbitrary std::array evaluations; @@ -119,7 +118,6 @@ TEST(stdlib_honk_transcript, return_values) // Construct a mock proof via the prover transcript ProverTranscript prover_transcript; - prover_transcript.send_to_verifier("data", data); prover_transcript.send_to_verifier("scalar", scalar); prover_transcript.send_to_verifier("commitment", commitment); prover_transcript.send_to_verifier("evaluations", evaluations); @@ -128,22 +126,19 @@ TEST(stdlib_honk_transcript, return_values) // Perform the corresponding operations with the native verifier transcript VerifierTranscript native_transcript(proof_data); - auto native_data = native_transcript.template receive_from_prover("data"); auto native_scalar = native_transcript.template receive_from_prover("scalar"); auto native_commitment = native_transcript.template receive_from_prover("commitment"); auto native_evaluations = native_transcript.template receive_from_prover>("evaluations"); auto [native_alpha, native_beta] = native_transcript.get_challenges("alpha", "beta"); - + // Perform the corresponding operations with the stdlib verifier transcript Transcript stdlib_transcript{ &builder, proof_data }; - auto stdlib_data = stdlib_transcript.template receive_from_prover("data"); auto stdlib_scalar = stdlib_transcript.template receive_from_prover("scalar"); auto stdlib_commitment = stdlib_transcript.template receive_from_prover("commitment"); auto stdlib_evaluations = stdlib_transcript.template receive_from_prover>("evaluations"); auto [stdlib_alpha, stdlib_beta] = stdlib_transcript.get_challenges("alpha", "beta"); - // Confirm that return values are equivalent - EXPECT_EQ(native_data, stdlib_data.get_value()); + // Confirm that return values are equivalent EXPECT_EQ(native_scalar, stdlib_scalar.get_value()); EXPECT_EQ(native_commitment, stdlib_commitment.get_value()); for (size_t i = 0; i < LENGTH; ++i) { From 8c3d4d464a16d980a4570a1dab66bbfcf0742b34 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 28 Jul 2023 23:05:04 +0000 Subject: [PATCH 08/11] comment update --- .../stdlib/recursion/transcript/honk_trancript.hpp | 1 + .../recursion/transcript/honk_transcript.test.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp index 5133904631a..0c02a725d81 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp @@ -10,6 +10,7 @@ #include "../../primitives/biggroup/biggroup.hpp" #include "../../primitives/field/field.hpp" +//TODO(luke): this namespace will be sensible once stdlib is moved out of the plonk namespace namespace proof_system::plonk::stdlib::recursion::honk { template class Transcript { public: diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp index db47fe7da52..4bf817aaae0 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp @@ -8,7 +8,6 @@ namespace proof_system::plonk::stdlib::recursion::honk { -// TODO(Cody): Testing only one circuit type. using Builder = UltraCircuitBuilder; using FF = barretenberg::fr; @@ -76,6 +75,11 @@ void perform_mock_verifier_transcript_operations(auto transcript) transcript.get_challenges("gamma", "delta"); } +/** + * @brief Test basic transcript functionality and check circuit + * @details Implicitly ensures stdlib interface is identical to native + * @todo(luke): Underlying circuit is nearly trivial until transcript implements hashing constraints + */ TEST(stdlib_honk_transcript, basic_transcript_operations) { Builder builder; @@ -102,6 +106,10 @@ TEST(stdlib_honk_transcript, basic_transcript_operations) EXPECT_TRUE(builder.check_circuit()); } +/** + * @brief Check that native and stdlib verifier transcript functions produce equivalent outputs + * + */ TEST(stdlib_honk_transcript, return_values) { Builder builder; From 7d95e29a9530fd498f0dbf958c2fa07389510575 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 31 Jul 2023 11:41:30 +0000 Subject: [PATCH 09/11] move to honk dir within recursion --- .../honk_trancript.hpp => honk/transcript/trancript.hpp} | 6 +++--- .../transcript/transcript.test.cpp} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/{transcript/honk_trancript.hpp => honk/transcript/trancript.hpp} (97%) rename circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/{transcript/honk_transcript.test.cpp => honk/transcript/transcript.test.cpp} (99%) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp similarity index 97% rename from circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp rename to circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp index 0c02a725d81..95ad753b727 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp @@ -6,9 +6,9 @@ #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/honk/transcript/transcript.hpp" -#include "../../primitives/bigfield/bigfield.hpp" -#include "../../primitives/biggroup/biggroup.hpp" -#include "../../primitives/field/field.hpp" +#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" +#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" //TODO(luke): this namespace will be sensible once stdlib is moved out of the plonk namespace namespace proof_system::plonk::stdlib::recursion::honk { diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp similarity index 99% rename from circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp rename to circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp index 4bf817aaae0..33f70306c3a 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/transcript/honk_transcript.test.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp @@ -4,7 +4,7 @@ #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/honk/transcript/transcript.hpp" -#include "barretenberg/stdlib/recursion/transcript/honk_trancript.hpp" +#include "barretenberg/stdlib/recursion/honk/transcript/trancript.hpp" namespace proof_system::plonk::stdlib::recursion::honk { From 058231d3793821b8d2a53f7d08a24985e8ab91f6 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 1 Aug 2023 18:40:01 +0000 Subject: [PATCH 10/11] addressing some pr comments --- .../honk/transcript/transcript.hpp | 2 + .../recursion/honk/transcript/trancript.hpp | 90 ++--------------- .../barretenberg/stdlib/utility/utility.hpp | 99 +++++++++++++++++++ 3 files changed, 108 insertions(+), 83 deletions(-) create mode 100644 circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp index 1ee7a101af8..b503bd49e8d 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp @@ -65,7 +65,9 @@ class TranscriptManifest { */ template class BaseTranscript { // TODO(Adrian): Make these tweakable + public: static constexpr size_t HASH_OUTPUT_SIZE = 32; + private: static constexpr size_t MIN_BYTES_PER_CHALLENGE = 128 / 8; // 128 bit challenges size_t round_number = 0; diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp index 95ad753b727..c180e9afda4 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp @@ -9,21 +9,18 @@ #include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" #include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" #include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib/utility/utility.hpp" //TODO(luke): this namespace will be sensible once stdlib is moved out of the plonk namespace namespace proof_system::plonk::stdlib::recursion::honk { template class Transcript { public: using field_pt = field_t; - using witness_pt = witness_t; - using fq_pt = bigfield; - using group_pt = element; using FF = barretenberg::fr; - using Commitment = barretenberg::g1::affine_element; using VerifierTranscript = proof_system::honk::VerifierTranscript; - template using Univariate = proof_system::honk::sumcheck::Univariate; + using Utility = utility::StdlibUtility; - static constexpr size_t HASH_OUTPUT_SIZE = 32; // WORKTODO: Duplicated from native transcript + static constexpr size_t HASH_OUTPUT_SIZE = VerifierTranscript::HASH_OUTPUT_SIZE; VerifierTranscript native_transcript; Builder* builder; @@ -53,7 +50,7 @@ template class Transcript { native_challenges = native_transcript.get_challenges(labels...); /* - * TODO(luke): Do stdlib hashing here. E.g., for the current pedersen/blake setup, we could write data into a + * TODO(#1351): Do stdlib hashing here. E.g., for the current pedersen/blake setup, we could write data into a * byte_array as it is received from prover, then compress via pedersen and apply blake3s. Not doing this now * since it's a pain and we'll be revamping our hashing anyway. For now, simply convert the native hashes to * stdlib types without adding any hashing constraints. @@ -77,7 +74,7 @@ template class Transcript { // Compute the indicated challenge from the native transcript auto native_challenge = native_transcript.get_challenge(label); - // TODO(luke): Stdlib hashing here... + // TODO(1351): Stdlib hashing here... return field_pt(native_challenge); } @@ -94,81 +91,8 @@ template class Transcript { // Extract the native element from the native transcript T element = native_transcript.template receive_from_prover(label); - // Add variables corresponding to the witness element and return the corresponding stdlib type - return stdlib_type_from_witness(element); - } - - private: - // Series of overloaded methods for converting native types extracted from the native transcript to the - // corresponding stdlib type for output. - // TODO(luke): Eventually these can also add data to a buffer (byte_array) to be hashed. - - /** - * @brief Construct stdlib field from uint32_t - * - * @param element - * @return field_pt - */ - field_pt stdlib_type_from_witness(uint32_t native_element) - { - auto element = witness_pt(builder, native_element); - - return element; - } - - /** - * @brief Construct stdlib field from native field type - * - * @param native_element - * @return field_pt - */ - field_pt stdlib_type_from_witness(FF native_element) - { - auto element = witness_pt(builder, native_element); - - return element; - } - - /** - * @brief Construct stdlib group from native affine group element type - * - * @param native_element - * @return field_pt - */ - group_pt stdlib_type_from_witness(Commitment native_element) - { - auto element = group_pt::from_witness(builder, native_element); - - return element; - } - - /** - * @brief Construct field_t array from native field array - * @param native_element Array of FF - * @return std::array - */ - template std::array stdlib_type_from_witness(std::array native_element) - { - std::array element; - for (size_t i = 0; i < LENGTH; ++i) { - element[i] = witness_pt(builder, native_element[i]); - } - return element; - } - - /** - * @brief Construct field_t array from native Univariate type - * TODO(luke): do we need a stdlib Univariate or is std::array good enough? - * @param native_element - * @return std::array - */ - template std::array stdlib_type_from_witness(Univariate native_element) - { - std::array element; - for (size_t i = 0; i < LENGTH; ++i) { - element[i] = witness_pt(builder, native_element.value_at(i)); - } - return element; + // Return the corresponding stdlib type + return Utility::from_witness(builder, element); } }; } // namespace proof_system::plonk::stdlib::recursion::honk diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp new file mode 100644 index 00000000000..717672689fa --- /dev/null +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp @@ -0,0 +1,99 @@ +#pragma once + +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" +#include "barretenberg/honk/transcript/transcript.hpp" + +#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" +#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" + +namespace proof_system::plonk::stdlib::recursion::utility { + +/** + * @brief Utility class for converting native types to corresponding stdlib types + * + * @details Used to facilitate conversion of various native types (uint32_t, field, group, Univarite, etc.) to + * corresponding stdlib types. Useful for example for obtaining stdlib types in the recursive trancript from native + * types upon deserialization from the native transcript. + * + * @todo Eliminate the need for these somehow? + * @tparam Builder + */ +template class StdlibUtility { + using field_ct = field_t; + using witness_ct = witness_t; + using fq_ct = bigfield; + using group_ct = element; + using FF = barretenberg::fr; + using Commitment = barretenberg::g1::affine_element; + template using Univariate = proof_system::honk::sumcheck::Univariate; + + public: + /** + * @brief Construct stdlib field from uint32_t + * + * @param element + * @return field_ct + */ + static field_ct from_witness(Builder* builder, uint32_t native_element) + { + return field_ct::from_witness(builder, native_element); + } + + /** + * @brief Construct stdlib field from native field type + * + * @param native_element + * @return field_ct + */ + static field_ct from_witness(Builder* builder, FF native_element) + { + return field_ct::from_witness(builder, native_element); + } + + /** + * @brief Construct stdlib group from native affine group element type + * + * @param native_element + * @return field_ct + */ + static group_ct from_witness(Builder* builder, Commitment native_element) + { + return group_ct::from_witness(builder, native_element); + } + + /** + * @brief Construct field_t array from native field array + * @param native_element Array of FF + * @return std::array + */ + template + static std::array from_witness(Builder* builder, std::array native_element) + { + std::array element; + for (size_t i = 0; i < LENGTH; ++i) { + element[i] = field_ct::from_witness(builder, native_element[i]); + } + return element; + } + + /** + * @brief Construct field_t array from native Univariate type + * TODO(luke): do we need a stdlib Univariate or is std::array good enough? + * @param native_element + * @return std::array + */ + template + static std::array from_witness(Builder* builder, Univariate native_element) + { + std::array element; + for (size_t i = 0; i < LENGTH; ++i) { + element[i] = field_ct::from_witness(builder, native_element.value_at(i)); + } + return element; + } +}; +} // namespace proof_system::plonk::stdlib::recursion::utility \ No newline at end of file From 8cdcb5a79ee583f6e4c8b5d51ecc92c80e77d19d Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 2 Aug 2023 15:09:22 +0000 Subject: [PATCH 11/11] naming improvements --- .../stdlib/recursion/honk/transcript/trancript.hpp | 4 ++-- .../cpp/src/barretenberg/stdlib/utility/utility.hpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp index c180e9afda4..be4707af4a5 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/trancript.hpp @@ -18,7 +18,7 @@ template class Transcript { using field_pt = field_t; using FF = barretenberg::fr; using VerifierTranscript = proof_system::honk::VerifierTranscript; - using Utility = utility::StdlibUtility; + using StdlibTypes = utility::StdlibTypesUtility; static constexpr size_t HASH_OUTPUT_SIZE = VerifierTranscript::HASH_OUTPUT_SIZE; @@ -92,7 +92,7 @@ template class Transcript { T element = native_transcript.template receive_from_prover(label); // Return the corresponding stdlib type - return Utility::from_witness(builder, element); + return StdlibTypes::from_witness(builder, element); } }; } // namespace proof_system::plonk::stdlib::recursion::honk 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 717672689fa..c7bca963fc4 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/utility/utility.hpp @@ -22,11 +22,11 @@ namespace proof_system::plonk::stdlib::recursion::utility { * @todo Eliminate the need for these somehow? * @tparam Builder */ -template class StdlibUtility { +template class StdlibTypesUtility { using field_ct = field_t; using witness_ct = witness_t; using fq_ct = bigfield; - using group_ct = element; + using element_ct = element; using FF = barretenberg::fr; using Commitment = barretenberg::g1::affine_element; template using Univariate = proof_system::honk::sumcheck::Univariate; @@ -60,9 +60,9 @@ template class StdlibUtility { * @param native_element * @return field_ct */ - static group_ct from_witness(Builder* builder, Commitment native_element) + static element_ct from_witness(Builder* builder, Commitment native_element) { - return group_ct::from_witness(builder, native_element); + return element_ct::from_witness(builder, native_element); } /**