diff --git a/tachyon/crypto/commitments/fri/fri.h b/tachyon/crypto/commitments/fri/fri.h index b5b796333b..b924d06a3e 100644 --- a/tachyon/crypto/commitments/fri/fri.h +++ b/tachyon/crypto/commitments/fri/fri.h @@ -18,11 +18,13 @@ namespace tachyon::crypto { -template -class FRI final - : public UnivariatePolynomialCommitmentScheme> { +template +class FRI final : public UnivariatePolynomialCommitmentScheme< + FRI> { public: - using Base = UnivariatePolynomialCommitmentScheme>; + using Base = UnivariatePolynomialCommitmentScheme< + FRI>; using Poly = typename Base::Poly; using Evals = typename Base::Evals; using Domain = typename Base::Domain; @@ -45,14 +47,14 @@ class FRI final // UnivariatePolynomialCommitmentScheme methods size_t N() const { return domain_->size(); } - [[nodiscard]] bool Commit(const Poly& poly, Transcript* transcript) const { + [[nodiscard]] bool Commit(const Poly& poly, TranscriptWriter* writer, + std::vector* roots) const { size_t num_layers = domain_->log_size_of_group(); - TranscriptWriter* writer = transcript->ToWriter(); BinaryMerkleTree tree(storage_->GetLayer(0), hasher_); Evals evals = domain_->FFT(poly); - F root; - if (!tree.Commit(evals.evaluations(), &root)) return false; - if (!writer->WriteToProof(root)) return false; + roots->resize(num_layers + 1); + if (!tree.Commit(evals.evaluations(), &(*roots)[0])) return false; + if (!writer->WriteToProof((*roots)[0])) return false; const Poly* cur_poly = &poly; F beta; @@ -66,8 +68,8 @@ class FRI final BinaryMerkleTree tree(storage_->GetLayer(i), hasher_); evals = sub_domains_[i - 1]->FFT(folded_poly); - if (!tree.Commit(evals.evaluations(), &root)) return false; - if (!writer->WriteToProof(root)) return false; + if (!tree.Commit(evals.evaluations(), &(*roots)[i])) return false; + if (!writer->WriteToProof((*roots)[i])) return false; cur_poly = &folded_poly; } } @@ -75,8 +77,8 @@ class FRI final beta = writer->SqueezeChallenge(); folded_poly = cur_poly->template Fold(beta); const F* constant = folded_poly[0]; - root = constant ? *constant : F::Zero(); - return writer->WriteToProof(root); + (*roots)[num_layers] = constant ? *constant : F::Zero(); + return writer->WriteToProof((*roots)[num_layers]); } [[nodiscard]] bool DoCreateOpeningProof(size_t index, @@ -110,10 +112,9 @@ class FRI final return true; } - [[nodiscard]] bool DoVerifyOpeningProof(Transcript& transcript, + [[nodiscard]] bool DoVerifyOpeningProof(TranscriptReader& reader, size_t index, const FRIProof& proof) const { - TranscriptReader* reader = transcript.ToReader(); size_t domain_size = domain_->size(); size_t num_layers = domain_->log_size_of_group(); F root; @@ -126,7 +127,7 @@ class FRI final BinaryMerkleTreeStorage* layer = storage_->GetLayer(i); BinaryMerkleTree tree(layer, hasher_); - if (!reader->ReadFromProof(&root)) return false; + if (!reader.ReadFromProof(&root)) return false; if (!tree.VerifyOpeningProof(root, proof.evaluations[i], proof.paths[i])) return false; @@ -175,7 +176,7 @@ class FRI final evaluation_sym = proof.evaluations_sym[i]; x = sub_domains_[i - 1]->GetElement(leaf_index); } - beta = reader->SqueezeChallenge(); + beta = reader.SqueezeChallenge(); beta *= x.Inverse(); domain_size = domain_size >> 1; } @@ -185,7 +186,7 @@ class FRI final evaluation += evaluation_sym; evaluation *= two_inv; - if (!reader->ReadFromProof(&root)) return false; + if (!reader.ReadFromProof(&root)) return false; if (root != evaluation) { LOG(ERROR) << "Root doesn't match with expected evaluation"; return false; @@ -200,19 +201,24 @@ class FRI final mutable FRIStorage* storage_ = nullptr; // not owned BinaryMerkleHasher* hasher_ = nullptr; - // not owned - Transcript* transcript_ = nullptr; std::vector> sub_domains_; }; -template -struct VectorCommitmentSchemeTraits> { +template +struct VectorCommitmentSchemeTraits< + FRI> { public: constexpr static size_t kMaxSize = MaxDegree + 1; constexpr static bool kIsTransparent = true; + constexpr static bool kIsCommitInteractive = true; + constexpr static bool kIsOpenInteractive = false; using Field = F; - using Commitment = Transcript; + using Commitment = std::vector; + using TranscriptReader = _TranscriptReader; + using TranscriptWriter = _TranscriptWriter; + using Proof = FRIProof; }; } // namespace tachyon::crypto diff --git a/tachyon/crypto/commitments/fri/fri_unittest.cc b/tachyon/crypto/commitments/fri/fri_unittest.cc index 07c88e387f..bccd31b1c4 100644 --- a/tachyon/crypto/commitments/fri/fri_unittest.cc +++ b/tachyon/crypto/commitments/fri/fri_unittest.cc @@ -33,9 +33,13 @@ class SimpleHasher class SimpleFRIStorage : public FRIStorage { public: - const std::vector>& layers() - const { - return layers_; + using Layer = SimpleBinaryMerkleTreeStorage; + + const std::vector& layers() const { return layers_; } + + std::vector GetRoots() const { + return base::Map(layers_, + [](const Layer& layer) { return layer.GetRoot(); }); } // FRIStorage methods @@ -54,11 +58,14 @@ class FRITest : public testing::Test { constexpr static size_t N = size_t{1} << K; constexpr static size_t kMaxDegree = N - 1; - using PCS = FRI; + using PCS = FRI, + SimpleTranscriptWriter>; using F = PCS::Field; using Poly = PCS::Poly; - using Commitment = PCS::Commitment; using Domain = PCS::Domain; + using TranscriptReader = PCS::TranscriptReader; + using TranscriptWriter = PCS::TranscriptWriter; static void SetUpTestSuite() { math::Goldilocks::Init(); } @@ -79,14 +86,17 @@ class FRITest : public testing::Test { TEST_F(FRITest, CommitAndVerify) { Poly poly = Poly::Random(kMaxDegree); base::Uint8VectorBuffer write_buffer; - SimpleTranscriptWriter writer(std::move(write_buffer)); - ASSERT_TRUE(pcs_.Commit(poly, &writer)); + TranscriptWriter writer(std::move(write_buffer)); + std::vector roots; + ASSERT_TRUE(pcs_.Commit(poly, &writer, &roots)); + roots.pop_back(); + EXPECT_EQ(roots, storage_.GetRoots()); size_t index = base::Uniform(base::Range::Until(kMaxDegree + 1)); FRIProof proof; ASSERT_TRUE(pcs_.CreateOpeningProof(index, &proof)); - SimpleTranscriptReader reader(std::move(writer).TakeBuffer()); + TranscriptReader reader(std::move(writer).TakeBuffer()); reader.buffer().set_buffer_offset(0); ASSERT_TRUE(pcs_.VerifyOpeningProof(reader, index, proof)); } diff --git a/tachyon/crypto/commitments/kzg/shplonk.h b/tachyon/crypto/commitments/kzg/shplonk.h index d0cd3e7382..09a54fdb1e 100644 --- a/tachyon/crypto/commitments/kzg/shplonk.h +++ b/tachyon/crypto/commitments/kzg/shplonk.h @@ -20,24 +20,24 @@ namespace tachyon { namespace zk { template ::Bucket> + typename Commitment, typename TranscriptReader, + typename TranscriptWriter> class SHPlonkExtension; } // namespace zk namespace crypto { -template ::Bucket> -class SHPlonk final : public UnivariatePolynomialCommitmentScheme< - SHPlonk>, - public KZGFamily { +template +class SHPlonk final + : public UnivariatePolynomialCommitmentScheme>, + public KZGFamily { public: - using Base = UnivariatePolynomialCommitmentScheme< - SHPlonk>; + using Base = UnivariatePolynomialCommitmentScheme>; using G1Point = typename Curve::G1Curve::AffinePoint; using G2Point = typename Curve::G2Curve::AffinePoint; using Fp12 = typename Curve::Fp12; @@ -51,10 +51,11 @@ class SHPlonk final : public UnivariatePolynomialCommitmentScheme< : KZGFamily(std::move(kzg)) {} private: - friend class VectorCommitmentScheme>; - friend class UnivariatePolynomialCommitmentScheme< - SHPlonk>; - template + friend class VectorCommitmentScheme>; + friend class UnivariatePolynomialCommitmentScheme>; + template friend class zk::SHPlonkExtension; // Set šœGā‚‚ @@ -62,9 +63,8 @@ class SHPlonk final : public UnivariatePolynomialCommitmentScheme< // UnivariatePolynomialCommitmentScheme methods template - [[nodiscard]] bool DoCreateOpeningProof( - const Container& poly_openings, - TranscriptWriter* writer) const { + [[nodiscard]] bool DoCreateOpeningProof(const Container& poly_openings, + TranscriptWriter* writer) const { PolynomialOpeningGrouper grouper; grouper.GroupByPolyOracleAndPoints(poly_openings); @@ -196,20 +196,19 @@ class SHPlonk final : public UnivariatePolynomialCommitmentScheme< template [[nodiscard]] bool DoVerifyOpeningProof( - const Container& poly_openings, - TranscriptReader* reader) const { + TranscriptReader& reader, const Container& poly_openings) const { using G1JacobianPoint = math::JacobianPoint; - Field y = reader->SqueezeChallenge(); - Field v = reader->SqueezeChallenge(); + Field y = reader.SqueezeChallenge(); + Field v = reader.SqueezeChallenge(); Commitment h; - if (!reader->ReadFromProof(&h)) return false; + if (!reader.ReadFromProof(&h)) return false; - Field u = reader->SqueezeChallenge(); + Field u = reader.SqueezeChallenge(); Commitment q; - if (!reader->ReadFromProof(&q)) return false; + if (!reader.ReadFromProof(&q)) return false; PolynomialOpeningGrouper grouper; grouper.GroupByPolyOracleAndPoints(poly_openings); @@ -350,15 +349,23 @@ class SHPlonk final : public UnivariatePolynomialCommitmentScheme< G2Point tau_g2_; }; -template -struct VectorCommitmentSchemeTraits> { +template +struct VectorCommitmentSchemeTraits> { public: constexpr static size_t kMaxSize = MaxDegree + 1; constexpr static bool kIsTransparent = false; + constexpr static bool kIsCommitInteractive = false; + constexpr static bool kIsOpenInteractive = true; using G1Point = typename Curve::G1Curve::AffinePoint; using Field = typename G1Point::ScalarField; using Commitment = _Commitment; + using TranscriptReader = _TranscriptReader; + using TranscriptWriter = _TranscriptWriter; + // not used since all of the proof needed is recorded in transcript. + using Proof = void*; }; } // namespace crypto diff --git a/tachyon/crypto/commitments/kzg/shplonk_unittest.cc b/tachyon/crypto/commitments/kzg/shplonk_unittest.cc index dd71308abd..0f39eab812 100644 --- a/tachyon/crypto/commitments/kzg/shplonk_unittest.cc +++ b/tachyon/crypto/commitments/kzg/shplonk_unittest.cc @@ -21,11 +21,15 @@ class SHPlonkTest : public testing::Test { constexpr static size_t kMaxDegree = N - 1; using PCS = - SHPlonk; + SHPlonk, + SimpleTranscriptWriter>; using F = PCS::Field; using Poly = PCS::Poly; using Commitment = PCS::Commitment; using Point = Poly::Point; + using TranscriptReader = PCS::TranscriptReader; + using TranscriptWriter = PCS::TranscriptWriter; using PolyRef = base::DeepRef; using PointRef = base::DeepRef; using CommitmentRef = base::DeepRef; @@ -36,8 +40,6 @@ class SHPlonkTest : public testing::Test { math::bn254::G2Curve::Init(); } - SHPlonkTest() : writer_(base::Uint8VectorBuffer()) {} - void SetUp() override { KZG kzg; pcs_ = PCS(std::move(kzg)); @@ -103,18 +105,18 @@ class SHPlonkTest : public testing::Test { std::vector commitments_; std::vector> prover_openings_; std::vector> verifier_openings_; - SimpleTranscriptWriter writer_; }; } // namespace TEST_F(SHPlonkTest, CreateAndVerifyProof) { - ASSERT_TRUE(pcs_.CreateOpeningProof(prover_openings_, &writer_)); + base::Uint8VectorBuffer write_buffer; + TranscriptWriter writer(std::move(write_buffer)); + ASSERT_TRUE(pcs_.CreateOpeningProof(prover_openings_, &writer)); - base::Buffer read_buf(writer_.buffer().buffer(), - writer_.buffer().buffer_len()); - SimpleTranscriptReader reader(std::move(read_buf)); - EXPECT_TRUE((pcs_.VerifyOpeningProof(verifier_openings_, &reader))); + base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); + TranscriptReader reader(std::move(read_buf)); + EXPECT_TRUE((pcs_.VerifyOpeningProof(reader, verifier_openings_))); } } // namespace tachyon::crypto diff --git a/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree.h b/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree.h index 89c63eef5f..5f1a3fcd5a 100644 --- a/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree.h +++ b/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree.h @@ -164,11 +164,18 @@ struct VectorCommitmentSchemeTraits> { public: constexpr static size_t kMaxSize = MaxSize; constexpr static bool kIsTransparent = true; + constexpr static bool kIsCommitInteractive = false; + constexpr static bool kIsOpenInteractive = false; // TODO(chokobole): The result of Keccak256 is not a field. How can we handle // this? using Field = Hash; using Commitment = Hash; + // not used + using TranscriptReader = void*; + // not used + using TranscriptWriter = void*; + using Proof = BinaryMerkleProof; }; } // namespace tachyon::crypto diff --git a/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree_storage.h b/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree_storage.h index 7f1f95217d..649df93a03 100644 --- a/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree_storage.h +++ b/tachyon/crypto/commitments/merkle_tree/binary_merkle_tree/binary_merkle_tree_storage.h @@ -17,6 +17,8 @@ class BinaryMerkleTreeStorage { virtual size_t GetSize() const = 0; virtual const Hash& GetHash(size_t i) const = 0; virtual void SetHash(size_t i, const Hash& hash) = 0; + + Hash GetRoot() const { return GetHash(0); } }; } // namespace tachyon::crypto diff --git a/tachyon/crypto/commitments/pedersen/pedersen.h b/tachyon/crypto/commitments/pedersen/pedersen.h index c10d906a42..f2ad8f1584 100644 --- a/tachyon/crypto/commitments/pedersen/pedersen.h +++ b/tachyon/crypto/commitments/pedersen/pedersen.h @@ -98,9 +98,16 @@ struct VectorCommitmentSchemeTraits> { public: constexpr static size_t kMaxSize = MaxSize; constexpr static bool kIsTransparent = true; + constexpr static bool kIsCommitInteractive = false; using Field = typename Point::ScalarField; using Commitment = _Commitment; + // not used + using TranscriptReader = void*; + // not used + using TranscriptWriter = void*; + // not used + using Proof = void*; }; } // namespace crypto diff --git a/tachyon/crypto/commitments/univariate_polynomial_commitment_scheme.h b/tachyon/crypto/commitments/univariate_polynomial_commitment_scheme.h index 8a2d4e9a0b..cc5bfdc0d7 100644 --- a/tachyon/crypto/commitments/univariate_polynomial_commitment_scheme.h +++ b/tachyon/crypto/commitments/univariate_polynomial_commitment_scheme.h @@ -18,6 +18,10 @@ class UnivariatePolynomialCommitmentScheme using Field = typename VectorCommitmentScheme::Field; using Commitment = typename VectorCommitmentScheme::Commitment; + using TranscriptReader = + typename VectorCommitmentSchemeTraits::TranscriptReader; + using TranscriptWriter = + typename VectorCommitmentSchemeTraits::TranscriptWriter; using Poly = math::UnivariateDensePolynomial; using Evals = math::UnivariateEvaluations; using Domain = math::UnivariateEvaluationDomain; @@ -27,19 +31,47 @@ class UnivariatePolynomialCommitmentScheme return derived->N() - 1; } - // Commit to |poly| and populates |result| with the commitment. + // Commit to |poly| and populates |commitment|. // Return false if the degree of |poly| exceeds |kMaxDegree|. - [[nodiscard]] bool Commit(const Poly& poly, Commitment* result) const { + template ::kIsCommitInteractive>* = nullptr> + [[nodiscard]] bool Commit(const Poly& poly, Commitment* commitment) const { const Derived* derived = static_cast(this); - return derived->DoCommit(poly, result); + return derived->DoCommit(poly, commitment); } - // Commit to |poly| and populates |result| with the commitment. + // Commit to |poly| with a |transcript_writer| and populates |commitment|. // Return false if the degree of |poly| exceeds |kMaxDegree|. + template ::IsCommitInteractive>* = nullptr> + [[nodiscard]] bool Commit(const Poly& poly, + TranscriptWriter* transcript_writer, + Commitment* commitment) const { + const Derived* derived = static_cast(this); + return derived->DoCommit(poly, transcript_writer, commitment); + } + + // Commit to |evals| and populates |commitment|. + // Return false if the degree of |evals| exceeds |kMaxDegree|. + template ::kIsCommitInteractive>* = nullptr> + [[nodiscard]] bool CommitLagrange(const Evals& evals, + Commitment* commitment) const { + const Derived* derived = static_cast(this); + return derived->DoCommitLagrange(evals, commitment); + } + + // Commit to |evals| with a |transcript_writer| and populates |commitment|. + // Return false if the degree of |evals| exceeds |kMaxDegree|. + template ::kIsCommitInteractive>* = nullptr> [[nodiscard]] bool CommitLagrange(const Evals& evals, - Commitment* result) const { + TranscriptWriter* transcript_writer, + Commitment* commitment) const { const Derived* derived = static_cast(this); - return derived->DoCommitLagrange(evals, result); + return derived->DoCommitLagrange(evals, transcript_writer, commitment); } }; diff --git a/tachyon/crypto/commitments/vector_commitment_scheme.h b/tachyon/crypto/commitments/vector_commitment_scheme.h index 72a7dec1e1..b236946e13 100644 --- a/tachyon/crypto/commitments/vector_commitment_scheme.h +++ b/tachyon/crypto/commitments/vector_commitment_scheme.h @@ -16,6 +16,11 @@ class VectorCommitmentScheme { using Field = typename VectorCommitmentSchemeTraits::Field; using Commitment = typename VectorCommitmentSchemeTraits::Commitment; + using TranscriptReader = + typename VectorCommitmentSchemeTraits::TranscriptReader; + using TranscriptWriter = + typename VectorCommitmentSchemeTraits::TranscriptWriter; + using Proof = typename VectorCommitmentSchemeTraits::Proof; size_t K() const { const Derived* derived = static_cast(this); @@ -62,54 +67,117 @@ class VectorCommitmentScheme { return derived->DoUnsafeSetup(size, params); } - // Commit to |container| and populates |result| with the commitment. + // Commit to |container| and populates |commitment|. // Return false if the size of |container| doesn't match with the size of // parameters. - template + template ::kIsCommitInteractive>* = nullptr> [[nodiscard]] bool Commit(const Container& container, - Commitment* result) const { + Commitment* commitment) const { const Derived* derived = static_cast(this); - return derived->DoCommit(container, result); + return derived->DoCommit(container, commitment); } - // Commit to |container| with a |random_value| and populates |result| with the - // commitment. Return false if the size of |container| doesn't match with the - // size of parameters. - template + // Commit to |container| with a |random_value| and populates |commitment|. + // Return false if the size of |container| doesn't match with the size of + // parameters. e.g, Pedersen commitment. + template ::kIsCommitInteractive>* = nullptr> [[nodiscard]] bool Commit(const Container& container, const Field& random_value, - Commitment* result) const { + Commitment* commitment) const { const Derived* derived = static_cast(this); - return derived->DoCommit(container, random_value, result); + return derived->DoCommit(container, random_value, commitment); } - // Create an opening proof that proves that |members| belong to a + // Commit to |container| with a |transcript_writer| and populates + // |commitment|. Return false if the size of |container| doesn't match with + // the size of parameters. + template < + typename Container, typename T = Derived, + std::enable_if_t::IsCommitInteractive>* = + nullptr> + [[nodiscard]] bool Commit(const Container& container, + TranscriptWriter* transcript_writer, + Commitment* commitment) const { + const Derived* derived = static_cast(this); + return derived->DoCommit(container, transcript_writer, commitment); + } + + // Create an opening |proof| that proves that |members| belong to a // commitment. - template + template < + typename Container, typename T = Derived, + std::enable_if_t::kIsOpenInteractive>* = + nullptr> [[nodiscard]] bool CreateOpeningProof(const Container& members, Proof* proof) const { const Derived* derived = static_cast(this); return derived->DoCreateOpeningProof(members, proof); } + // Create an opening |proof| with a |transcript_writer| that proves that + // |members| belong to a commitment. + template < + typename Container, typename T = Derived, + std::enable_if_t::kIsOpenInteractive && + !std::is_same_v>* = nullptr> + [[nodiscard]] bool CreateOpeningProof(const Container& members, + TranscriptWriter* transcript_writer, + Proof* proof) const { + const Derived* derived = static_cast(this); + return derived->DoCreateOpeningProof(members, transcript_writer, proof); + } + + // Create an opening proof and a |transcript_writer| that proves that + // |members| belong to a commitment. + template < + typename Container, typename T = Derived, + std::enable_if_t::kIsOpenInteractive && + std::is_same_v>* = nullptr> + [[nodiscard]] bool CreateOpeningProof( + const Container& members, TranscriptWriter* transcript_writer) const { + const Derived* derived = static_cast(this); + return derived->DoCreateOpeningProof(members, transcript_writer); + } + // Verify an opening |proof| that proves that |members| belong to a - // |commitment|. - // NOTE(chokobole): const was removed from |Commitment| since it can be a - // |Transcript|. At this moment, |WriteToTranscript()| is not a const method. - template - [[nodiscard]] bool VerifyOpeningProof(Commitment& commitment, + // |commitment|. e.g, BinaryMerkleTree commitment. + template + [[nodiscard]] bool VerifyOpeningProof(const Commitment& commitment, const Container& members, const Proof& proof) const { const Derived* derived = static_cast(this); return derived->DoVerifyOpeningProof(commitment, members, proof); } - // Verify multi-openings |proof|. - template - [[nodiscard]] bool VerifyOpeningProof(const Container& members, - Proof* proof) const { + // Verify an opening |proof| with a |transcript_reader| that proves that + // |members| belong to a commitment. e.g, FRI commitment. + template < + typename Container, typename T = Derived, + std::enable_if_t<(VectorCommitmentSchemeTraits::kIsCommitInteractive || + VectorCommitmentSchemeTraits::kIsOpenInteractive) && + !std::is_same_v>* = nullptr> + [[nodiscard]] bool VerifyOpeningProof(TranscriptReader& transcript_reader, + const Container& members, + const Proof& proof) const { + const Derived* derived = static_cast(this); + return derived->DoVerifyOpeningProof(transcript_reader, members, proof); + } + + // Verify an opening proof that is recorded in a |transcript_reader| that + // proves that |members| belong to a commitment. e.g, SHPlonk commitment. + template < + typename Container, typename T = Derived, + std::enable_if_t<(VectorCommitmentSchemeTraits::kIsCommitInteractive || + VectorCommitmentSchemeTraits::kIsOpenInteractive) && + std::is_same_v>* = nullptr> + [[nodiscard]] bool VerifyOpeningProof(TranscriptReader& transcript_reader, + const Container& members) const { const Derived* derived = static_cast(this); - return derived->DoVerifyOpeningProof(members, proof); + return derived->DoVerifyOpeningProof(transcript_reader, members); } }; diff --git a/tachyon/crypto/transcripts/BUILD.bazel b/tachyon/crypto/transcripts/BUILD.bazel index 1a848e2e77..8610eb4582 100644 --- a/tachyon/crypto/transcripts/BUILD.bazel +++ b/tachyon/crypto/transcripts/BUILD.bazel @@ -6,24 +6,24 @@ tachyon_cc_library( name = "simple_transcript", testonly = True, hdrs = ["simple_transcript.h"], - deps = [":transcript"], + deps = [ + ":transcript", + "//tachyon/math/elliptic_curves:points", + "//tachyon/math/finite_fields:prime_field_base", + ], ) tachyon_cc_library( name = "transcript", hdrs = ["transcript.h"], deps = [ - ":transcript_traits", + ":transcript_traits_forward", "//tachyon/base/buffer:vector_buffer", "//tachyon/math/base:big_int", ], ) tachyon_cc_library( - name = "transcript_traits", - hdrs = ["transcript_traits.h"], - deps = [ - "//tachyon/math/elliptic_curves:points", - "//tachyon/math/finite_fields:prime_field_base", - ], + name = "transcript_traits_forward", + hdrs = ["transcript_traits_forward.h"], ) diff --git a/tachyon/crypto/transcripts/simple_transcript.h b/tachyon/crypto/transcripts/simple_transcript.h index b0af288030..bbe9acc1c7 100644 --- a/tachyon/crypto/transcripts/simple_transcript.h +++ b/tachyon/crypto/transcripts/simple_transcript.h @@ -1,11 +1,21 @@ #ifndef TACHYON_CRYPTO_TRANSCRIPTS_SIMPLE_TRANSCRIPT_H_ #define TACHYON_CRYPTO_TRANSCRIPTS_SIMPLE_TRANSCRIPT_H_ +#include #include #include "tachyon/crypto/transcripts/transcript.h" +#include "tachyon/math/elliptic_curves/affine_point.h" +#include "tachyon/math/finite_fields/prime_field_base.h" namespace tachyon::crypto { + +template +class SimpleTranscriptReader; + +template +class SimpleTranscriptWriter; + namespace internal { template @@ -15,6 +25,9 @@ template class SimpleTranscript< F, std::enable_if_t, F>>> { protected: + friend class Transcript>; + friend class Transcript>; + F DoSqueezeChallenge() { return state_.DoubleInPlace(); } bool DoWriteToTranscript(const F& value) { @@ -29,7 +42,10 @@ class SimpleTranscript< template class SimpleTranscript> { protected: - using F = typename TranscriptTraits>::Field; + friend class Transcript>>; + friend class Transcript>>; + + using F = typename math::AffinePoint::ScalarField; using CurveConfig = typename Curve::Config; F DoSqueezeChallenge() { return state_.DoubleInPlace(); } @@ -51,116 +67,104 @@ class SimpleTranscript> { } // namespace internal -template -class SimpleTranscriptReader; - template class SimpleTranscriptReader< F, std::enable_if_t, F>>> - : public TranscriptReader, protected internal::SimpleTranscript { + final : public TranscriptReader>, + public internal::SimpleTranscript { public: explicit SimpleTranscriptReader(base::Buffer read_buf) - : TranscriptReader(std::move(read_buf)) {} - - // TranscriptReader methods - F SqueezeChallenge() override { return this->DoSqueezeChallenge(); } - - bool WriteToTranscript(const F& value) override { - return this->DoWriteToTranscript(value); - } + : TranscriptReader>(std::move(read_buf)) {} private: - bool DoReadFromProof(F* value) const override { + friend class TranscriptReader>; + + template + bool DoReadFromProof(T* value) const { return this->buffer_.Read(value); } }; +template +struct TranscriptTraits, F>>>> { + using Field = F; +}; + template -class SimpleTranscriptReader> - : public TranscriptReader>, - protected internal::SimpleTranscript> { +class SimpleTranscriptReader> final + : public TranscriptReader>>, + public internal::SimpleTranscript> { public: - using F = typename TranscriptTraits>::Field; - explicit SimpleTranscriptReader(base::Buffer read_buf) - : TranscriptReader>(std::move(read_buf)) {} - - // TranscriptReader methods - F SqueezeChallenge() override { return this->DoSqueezeChallenge(); } - - bool WriteToTranscript(const math::AffinePoint& point) override { - return this->DoWriteToTranscript(point); - } - - bool WriteToTranscript(const F& scalar) override { - return this->DoWriteToTranscript(scalar); - } + : TranscriptReader>>( + std::move(read_buf)) {} private: - bool DoReadFromProof(math::AffinePoint* point) const override { - return this->buffer_.Read(point); - } + friend class TranscriptReader< + SimpleTranscriptReader>>; - bool DoReadFromProof(F* scalar) const override { - return this->buffer_.Read(scalar); + template + bool DoReadFromProof(T* value) const { + return this->buffer_.Read(value); } }; -template -class SimpleTranscriptWriter; +template +struct TranscriptTraits>> { + using Field = typename math::AffinePoint::ScalarField; +}; template class SimpleTranscriptWriter< F, std::enable_if_t, F>>> - : public TranscriptWriter, protected internal::SimpleTranscript { + : public TranscriptWriter>, + public internal::SimpleTranscript { public: - explicit SimpleTranscriptWriter(base::Uint8VectorBuffer write_buf) - : TranscriptWriter(std::move(write_buf)) {} + using Field = F; - // TranscriptWriter methods - F SqueezeChallenge() override { return this->DoSqueezeChallenge(); } - - bool WriteToTranscript(const F& value) override { - return this->DoWriteToTranscript(value); - } + explicit SimpleTranscriptWriter(base::Uint8VectorBuffer write_buf) + : TranscriptWriter>(std::move(write_buf)) {} private: - bool DoWriteToProof(const F& value) override { + friend class TranscriptWriter>; + + template + bool DoWriteToProof(const T& value) { return this->buffer_.Write(value); } }; +template +struct TranscriptTraits, F>>>> { + using Field = F; +}; + template class SimpleTranscriptWriter> - : public TranscriptWriter>, - protected internal::SimpleTranscript> { + : public TranscriptWriter>>, + public internal::SimpleTranscript> { public: - using F = typename TranscriptTraits>::Field; - explicit SimpleTranscriptWriter(base::Uint8VectorBuffer write_buf) - : TranscriptWriter>(std::move(write_buf)) {} - - // TranscriptWriter methods - F SqueezeChallenge() override { return this->DoSqueezeChallenge(); } - - bool WriteToTranscript(const math::AffinePoint& point) override { - return this->DoWriteToTranscript(point); - } - - bool WriteToTranscript(const F& scalar) override { - return this->DoWriteToTranscript(scalar); - } + : TranscriptWriter>>( + std::move(write_buf)) {} private: - bool DoWriteToProof(const math::AffinePoint& point) override { - return this->buffer_.Write(point); - } + friend class TranscriptWriter< + SimpleTranscriptWriter>>; - bool DoWriteToProof(const F& scalar) override { - return this->buffer_.Write(scalar); + template + bool DoWriteToProof(const T& value) { + return this->buffer_.Write(value); } }; +template +struct TranscriptTraits>> { + using Field = typename math::AffinePoint::ScalarField; +}; + } // namespace tachyon::crypto #endif // TACHYON_CRYPTO_TRANSCRIPTS_SIMPLE_TRANSCRIPT_H_ diff --git a/tachyon/crypto/transcripts/transcript.h b/tachyon/crypto/transcripts/transcript.h index cb9c6f937a..1c778d3cef 100644 --- a/tachyon/crypto/transcripts/transcript.h +++ b/tachyon/crypto/transcripts/transcript.h @@ -10,86 +10,53 @@ #include #include "tachyon/base/buffer/vector_buffer.h" -#include "tachyon/crypto/transcripts/transcript_traits.h" +#include "tachyon/crypto/transcripts/transcript_traits_forward.h" namespace tachyon::crypto { -template -class TranscriptReaderImpl; +template +class TranscriptReader; -template -class TranscriptWriterImpl; - -template -class TranscriptImpl; +template +class TranscriptWriter; // Generic transcript view (from either the prover or verifier's perspective) -template -class TranscriptImpl<_Commitment, false> { +template +class Transcript { public: - using Commitment = _Commitment; - using Field = typename TranscriptTraits::Field; - - virtual ~TranscriptImpl() = default; + using Field = typename TranscriptTraits::Field; // Squeeze an encoded verifier challenge from the transcript. - virtual Field SqueezeChallenge() = 0; + Field SqueezeChallenge() { + Derived* derived = static_cast(this); + return derived->DoSqueezeChallenge(); + } // Write a |commitment| to the transcript without writing it to the proof, // treating it as a common input. - [[nodiscard]] virtual bool WriteToTranscript( - const Commitment& commitment) = 0; - - // Write a |value| to the transcript without writing it to the proof, - // treating it as a common input. - [[nodiscard]] virtual bool WriteToTranscript(const Field& value) = 0; - - TranscriptWriterImpl* ToWriter() { - return static_cast*>(this); - } - - TranscriptReaderImpl* ToReader() { - return static_cast*>(this); + template + [[nodiscard]] bool WriteToTranscript(const T& value) { + Derived* derived = static_cast(this); + return derived->DoWriteToTranscript(value); } -}; - -template -class TranscriptImpl<_Field, true> { - public: - using Field = _Field; - - virtual ~TranscriptImpl() = default; - - // Squeeze an encoded verifier challenge from the transcript. - virtual Field SqueezeChallenge() = 0; - - // Write a |value| to the transcript without writing it to the proof, - // treating it as a common input. - [[nodiscard]] virtual bool WriteToTranscript(const Field& value) = 0; - TranscriptWriterImpl* ToWriter() { - return static_cast*>(this); + TranscriptWriter* ToWriter() { + return static_cast*>(this); } - TranscriptReaderImpl* ToReader() { - return static_cast*>(this); + TranscriptReader* ToReader() { + return static_cast*>(this); } }; -template -using Transcript = - TranscriptImpl::kFieldAndCommitmentAreSameType>; - // Transcript view from the perspective of a verifier that has access to an // input stream of data from the prover to the verifier. -template -class TranscriptReaderImpl : public Transcript { +template +class TranscriptReader : public Transcript { public: - using Field = typename TranscriptTraits::Field; - - TranscriptReaderImpl() = default; + TranscriptReader() = default; // Initialize a transcript given an input buffer. - explicit TranscriptReaderImpl(base::Buffer read_buf) + explicit TranscriptReader(base::Buffer read_buf) : buffer_(std::move(read_buf)) {} base::Buffer& buffer() { return buffer_; } @@ -97,65 +64,24 @@ class TranscriptReaderImpl : public Transcript { // Read a |commitment| from the proof. Note that it also writes the // |commitment| to the transcript by calling |WriteToTranscript()| internally. - [[nodiscard]] bool ReadFromProof(Commitment* commitment) { - return DoReadFromProof(commitment) && this->WriteToTranscript(*commitment); - } - - // Read a |value| from the proof. Note that it also writes the - // |value| to the transcript by calling |WriteToTranscript()| internally. - [[nodiscard]] bool ReadFromProof(Field* value) { - return DoReadFromProof(value) && this->WriteToTranscript(*value); + template + [[nodiscard]] bool ReadFromProof(T* value) { + Derived* derived = static_cast(this); + return derived->DoReadFromProof(value) && this->WriteToTranscript(*value); } protected: - // Read a |commitment| from the proof. - [[nodiscard]] virtual bool DoReadFromProof(Commitment* commitment) const = 0; - - // Read a |value| from the proof. - [[nodiscard]] virtual bool DoReadFromProof(Field* value) const = 0; - base::Buffer buffer_; }; -template -class TranscriptReaderImpl : public Transcript { - public: - TranscriptReaderImpl() = default; - // Initialize a transcript given an input buffer. - explicit TranscriptReaderImpl(base::Buffer read_buf) - : buffer_(std::move(read_buf)) {} - - base::Buffer& buffer() { return buffer_; } - const base::Buffer& buffer() const { return buffer_; } - - // Read a |value| from the proof. Note that it also writes the - // |value| to the transcript by calling |WriteToTranscript()| internally. - [[nodiscard]] bool ReadFromProof(Field* value) { - return DoReadFromProof(value) && this->WriteToTranscript(*value); - } - - protected: - // Read a |value| from the proof. - [[nodiscard]] virtual bool DoReadFromProof(Field* value) const = 0; - - base::Buffer buffer_; -}; - -template -using TranscriptReader = - TranscriptReaderImpl::kFieldAndCommitmentAreSameType>; - // Transcript view from the perspective of a prover that has access to an output // stream of messages from the prover to the verifier. -template -class TranscriptWriterImpl : public Transcript { +template +class TranscriptWriter : public Transcript { public: - using Field = typename TranscriptTraits::Field; - - TranscriptWriterImpl() = default; + TranscriptWriter() = default; // Initialize a transcript given an output buffer. - explicit TranscriptWriterImpl(base::Uint8VectorBuffer buf) + explicit TranscriptWriter(base::Uint8VectorBuffer buf) : buffer_(std::move(buf)) {} base::Uint8VectorBuffer& buffer() { return buffer_; } @@ -165,59 +91,16 @@ class TranscriptWriterImpl : public Transcript { // Write a |commitment| to the proof. Note that it also writes the // |commitment| to the transcript by calling |WriteToTranscript()| internally. - [[nodiscard]] bool WriteToProof(const Commitment& commitment) { - return this->WriteToTranscript(commitment) && DoWriteToProof(commitment); - } - - // Write a |value| to the proof. Note that it also writes the - // |value| to the transcript by calling |WriteToTranscript()| internally. - [[nodiscard]] bool WriteToProof(const Field& value) { - return this->WriteToTranscript(value) && DoWriteToProof(value); - } - - protected: - // Write a |commitment| to the proof. - [[nodiscard]] virtual bool DoWriteToProof(const Commitment& commitment) = 0; - - // Write a |value| to the proof. - [[nodiscard]] virtual bool DoWriteToProof(const Field& value) = 0; - - base::Uint8VectorBuffer buffer_; -}; - -// Transcript view from the perspective of a prover that has access to an output -// stream of messages from the prover to the verifier. -template -class TranscriptWriterImpl : public Transcript { - public: - TranscriptWriterImpl() = default; - // Initialize a transcript given an output buffer. - explicit TranscriptWriterImpl(base::Uint8VectorBuffer buf) - : buffer_(std::move(buf)) {} - - base::Uint8VectorBuffer& buffer() { return buffer_; } - const base::Uint8VectorBuffer& buffer() const { return buffer_; } - - base::Uint8VectorBuffer&& TakeBuffer() && { return std::move(buffer_); } - - // Write a |value| to the proof. Note that it also writes the - // |value| to the transcript by calling |WriteToTranscript()| internally. - [[nodiscard]] bool WriteToProof(const Field& value) { - return this->WriteToTranscript(value) && DoWriteToProof(value); + template + [[nodiscard]] bool WriteToProof(const T& value) { + Derived* derived = static_cast(this); + return this->WriteToTranscript(value) && derived->DoWriteToProof(value); } protected: - // Write a |value| to the proof. - [[nodiscard]] virtual bool DoWriteToProof(const Field& value) = 0; - base::Uint8VectorBuffer buffer_; }; -template -using TranscriptWriter = - TranscriptWriterImpl::kFieldAndCommitmentAreSameType>; - } // namespace tachyon::crypto #endif // TACHYON_CRYPTO_TRANSCRIPTS_TRANSCRIPT_H_ diff --git a/tachyon/crypto/transcripts/transcript_traits.h b/tachyon/crypto/transcripts/transcript_traits.h deleted file mode 100644 index 5990fcb95d..0000000000 --- a/tachyon/crypto/transcripts/transcript_traits.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TACHYON_CRYPTO_TRANSCRIPTS_TRANSCRIPT_TRAITS_H_ -#define TACHYON_CRYPTO_TRANSCRIPTS_TRANSCRIPT_TRAITS_H_ - -#include - -#include "tachyon/math/elliptic_curves/affine_point.h" -#include "tachyon/math/finite_fields/prime_field_base.h" - -namespace tachyon::crypto { - -template -struct TranscriptTraits; - -template -struct TranscriptTraits> { - constexpr static bool kFieldAndCommitmentAreSameType = false; - - using Field = typename math::AffinePoint::ScalarField; -}; - -template -struct TranscriptTraits< - F, std::enable_if_t, F>>> { - constexpr static bool kFieldAndCommitmentAreSameType = true; - - using Field = F; -}; - -} // namespace tachyon::crypto - -#endif // TACHYON_CRYPTO_TRANSCRIPTS_TRANSCRIPT_TRAITS_H_ diff --git a/tachyon/crypto/transcripts/transcript_traits_forward.h b/tachyon/crypto/transcripts/transcript_traits_forward.h new file mode 100644 index 0000000000..c872f63c7a --- /dev/null +++ b/tachyon/crypto/transcripts/transcript_traits_forward.h @@ -0,0 +1,11 @@ +#ifndef TACHYON_CRYPTO_TRANSCRIPTS_TRANSCRIPT_TRAITS_FORWARD_H_ +#define TACHYON_CRYPTO_TRANSCRIPTS_TRANSCRIPT_TRAITS_FORWARD_H_ + +namespace tachyon::crypto { + +template +struct TranscriptTraits; + +} // namespace tachyon::crypto + +#endif // TACHYON_CRYPTO_TRANSCRIPTS_TRANSCRIPT_TRAITS_FORWARD_H_ diff --git a/tachyon/zk/base/commitments/shplonk_extension.h b/tachyon/zk/base/commitments/shplonk_extension.h index dc4417a4cf..75d466e138 100644 --- a/tachyon/zk/base/commitments/shplonk_extension.h +++ b/tachyon/zk/base/commitments/shplonk_extension.h @@ -16,10 +16,12 @@ namespace tachyon { namespace zk { template + typename Commitment, typename TranscriptReader, + typename TranscriptWriter> class SHPlonkExtension final : public UnivariatePolynomialCommitmentSchemeExtension< - SHPlonkExtension> { + SHPlonkExtension> { public: // NOTE(dongchangYoo): The following value are pre-determined according to // the Commitment Opening Scheme. @@ -28,14 +30,16 @@ class SHPlonkExtension final constexpr static bool kQueryInstance = false; using Base = UnivariatePolynomialCommitmentSchemeExtension< - SHPlonkExtension>; + SHPlonkExtension>; using Field = typename Base::Field; using Poly = typename Base::Poly; using Evals = typename Base::Evals; SHPlonkExtension() = default; explicit SHPlonkExtension( - crypto::SHPlonk&& shplonk) + crypto::SHPlonk&& shplonk) : shplonk_(std::move(shplonk)) {} size_t N() const { return shplonk_.N(); } @@ -70,20 +74,24 @@ class SHPlonkExtension final return shplonk_.DoCommitLagrange(v, out); } - template + template [[nodiscard]] bool DoCreateOpeningProof(const Container& poly_openings, - Proof* proof) const { - return shplonk_.DoCreateOpeningProof(poly_openings, proof); + TranscriptWriter* writer) const { + return shplonk_.DoCreateOpeningProof(poly_openings, writer); } private: - crypto::SHPlonk shplonk_; + crypto::SHPlonk + shplonk_; }; template + typename Commitment, typename TranscriptReader, + typename TranscriptWriter> struct UnivariatePolynomialCommitmentSchemeExtensionTraits< - SHPlonkExtension> { + SHPlonkExtension> { public: constexpr static size_t kMaxExtendedDegree = MaxExtendedDegree; constexpr static size_t kMaxExtendedSize = kMaxExtendedDegree + 1; @@ -94,16 +102,24 @@ struct UnivariatePolynomialCommitmentSchemeExtensionTraits< namespace crypto { template + typename _Commitment, typename _TranscriptReader, + typename _TranscriptWriter> struct VectorCommitmentSchemeTraits< - zk::SHPlonkExtension> { + zk::SHPlonkExtension> { public: + constexpr static size_t kMaxSize = MaxDegree + 1; + constexpr static bool kIsTransparent = false; + constexpr static bool kIsCommitInteractive = false; + constexpr static bool kIsOpenInteractive = true; + using G1Point = typename Curve::G1Curve::AffinePoint; using Field = typename G1Point::ScalarField; using Commitment = _Commitment; - - constexpr static size_t kMaxSize = MaxDegree + 1; - constexpr static bool kIsTransparent = false; + using TranscriptReader = _TranscriptReader; + using TranscriptWriter = _TranscriptWriter; + // not used since all of the proof needed is recorded in transcript. + using Proof = void*; }; } // namespace crypto diff --git a/tachyon/zk/base/entities/BUILD.bazel b/tachyon/zk/base/entities/BUILD.bazel index 7d055128e7..f03ceb6e02 100644 --- a/tachyon/zk/base/entities/BUILD.bazel +++ b/tachyon/zk/base/entities/BUILD.bazel @@ -5,7 +5,6 @@ package(default_visibility = ["//visibility:public"]) tachyon_cc_library( name = "entity", hdrs = ["entity.h"], - deps = ["//tachyon/crypto/transcripts:transcript"], ) tachyon_cc_library( @@ -27,7 +26,10 @@ tachyon_cc_library( tachyon_cc_library( name = "verifier_base", hdrs = ["verifier_base.h"], - deps = [":entity"], + deps = [ + ":entity", + "//tachyon/base:logging", + ], ) tachyon_cc_unittest( diff --git a/tachyon/zk/base/entities/entity.h b/tachyon/zk/base/entities/entity.h index 9633d4af36..3946441568 100644 --- a/tachyon/zk/base/entities/entity.h +++ b/tachyon/zk/base/entities/entity.h @@ -10,8 +10,6 @@ #include #include -#include "tachyon/crypto/transcripts/transcript.h" - namespace tachyon::zk { // |Entity| class is a parent class of |Prover| and |Verifier|. @@ -29,10 +27,11 @@ class Entity { using ExtendedDomain = typename PCS::ExtendedDomain; using Evals = typename PCS::Evals; using Poly = typename PCS::Poly; - using Commitment = typename PCS::Commitment; + using TranscriptReader = typename PCS::TranscriptReader; + using TranscriptWriter = typename PCS::TranscriptWriter; - Entity(PCS&& pcs, std::unique_ptr> transcript) - : pcs_(std::move(pcs)), transcript_(std::move(transcript)) {} + explicit Entity(PCS&& pcs) : pcs_(std::move(pcs)) {} + virtual ~Entity() = default; const PCS& pcs() const { return pcs_; } PCS& pcs() { return pcs_; } @@ -46,13 +45,14 @@ class Entity { const ExtendedDomain* extended_domain() const { return extended_domain_.get(); } - crypto::Transcript* transcript() { return transcript_.get(); } + + virtual TranscriptReader* GetReader() const = 0; + virtual TranscriptWriter* GetWriter() const = 0; protected: PCS pcs_; std::unique_ptr domain_; std::unique_ptr extended_domain_; - std::unique_ptr> transcript_; }; } // namespace tachyon::zk diff --git a/tachyon/zk/base/entities/prover_base.h b/tachyon/zk/base/entities/prover_base.h index 639fbc9306..42dabc1b79 100644 --- a/tachyon/zk/base/entities/prover_base.h +++ b/tachyon/zk/base/entities/prover_base.h @@ -24,19 +24,24 @@ class ProverBase : public Entity { using Evals = typename PCS::Evals; using Poly = typename PCS::Poly; using Commitment = typename PCS::Commitment; + using TranscriptReader = typename PCS::TranscriptReader; + using TranscriptWriter = typename PCS::TranscriptWriter; - ProverBase(PCS&& pcs, - std::unique_ptr> writer, + ProverBase(PCS&& pcs, std::unique_ptr writer, Blinder&& blinder) - : Entity(std::move(pcs), std::move(writer)), + : Entity(std::move(pcs)), + writer_(std::move(writer)), blinder_(std::move(blinder)) {} Blinder& blinder() { return blinder_; } - crypto::TranscriptWriter* GetWriter() { - return this->transcript()->ToWriter(); + TranscriptReader* GetReader() const override { + NOTREACHED(); + return nullptr; } + TranscriptWriter* GetWriter() const override { return writer_.get(); } + size_t GetUsableRows() const { return this->domain_->size() - (blinder_.blinding_factors() + 1); } @@ -44,14 +49,14 @@ class ProverBase : public Entity { [[nodiscard]] bool Commit(const Poly& poly) { Commitment commitment; if (!this->pcs_.Commit(poly, &commitment)) return false; - return GetWriter()->WriteToProof(commitment); + return writer_->WriteToProof(commitment); } template [[nodiscard]] bool Commit(const Container& coeffs) { Commitment commitment; if (!this->pcs_.DoCommit(coeffs, &commitment)) return false; - return GetWriter()->WriteToProof(commitment); + return writer_->WriteToProof(commitment); } [[nodiscard]] bool CommitEvals(const Evals& evals) { @@ -59,7 +64,7 @@ class ProverBase : public Entity { Commitment commitment; if (!this->pcs_.CommitLagrange(evals, &commitment)) return false; - return GetWriter()->WriteToProof(commitment); + return writer_->WriteToProof(commitment); } [[nodiscard]] bool CommitEvalsWithBlind(const Evals& evals, @@ -71,10 +76,11 @@ class ProverBase : public Entity { [[nodiscard]] bool Evaluate(const Poly& poly, const F& x) { F result = poly.Evaluate(x); - return GetWriter()->WriteToProof(result); + return writer_->WriteToProof(result); } protected: + std::unique_ptr writer_; Blinder blinder_; }; diff --git a/tachyon/zk/base/entities/verifier_base.h b/tachyon/zk/base/entities/verifier_base.h index f19ee6a31d..59df3d0ee9 100644 --- a/tachyon/zk/base/entities/verifier_base.h +++ b/tachyon/zk/base/entities/verifier_base.h @@ -10,6 +10,7 @@ #include #include +#include "tachyon/base/logging.h" #include "tachyon/zk/base/entities/entity.h" namespace tachyon::zk { @@ -17,15 +18,21 @@ namespace tachyon::zk { template class VerifierBase : public Entity { public: - using Commitment = typename PCS::Commitment; + using TranscriptReader = typename PCS::TranscriptReader; + using TranscriptWriter = typename PCS::TranscriptWriter; - VerifierBase(PCS&& pcs, - std::unique_ptr> transcript) - : Entity(std::move(pcs), std::move(transcript)) {} + VerifierBase(PCS&& pcs, std::unique_ptr reader) + : Entity(std::move(pcs)), reader_(std::move(reader)) {} - crypto::TranscriptReader* GetReader() { - return this->transcript()->ToReader(); + TranscriptReader* GetReader() const override { return reader_.get(); } + + TranscriptWriter* GetWriter() const override { + NOTREACHED(); + return nullptr; } + + protected: + std::unique_ptr reader_; }; } // namespace tachyon::zk diff --git a/tachyon/zk/plonk/halo2/BUILD.bazel b/tachyon/zk/plonk/halo2/BUILD.bazel index 087291f4fa..93dcd4ee63 100644 --- a/tachyon/zk/plonk/halo2/BUILD.bazel +++ b/tachyon/zk/plonk/halo2/BUILD.bazel @@ -95,7 +95,6 @@ tachyon_cc_library( deps = [ ":proof", "//tachyon/base:logging", - "//tachyon/crypto/transcripts:transcript", "//tachyon/zk/plonk/keys:verifying_key", "//tachyon/zk/plonk/permutation:permutation_utils", ], @@ -118,6 +117,7 @@ tachyon_cc_library( ":random_field_generator", ":verifier", "//tachyon/zk/base/entities:prover_base", + "@com_google_absl//absl/memory", ], ) diff --git a/tachyon/zk/plonk/halo2/blake2b_transcript.h b/tachyon/zk/plonk/halo2/blake2b_transcript.h index 29eb80a3c3..36398d31bb 100644 --- a/tachyon/zk/plonk/halo2/blake2b_transcript.h +++ b/tachyon/zk/plonk/halo2/blake2b_transcript.h @@ -16,14 +16,26 @@ #include "tachyon/zk/plonk/halo2/constants.h" #include "tachyon/zk/plonk/halo2/proof_serializer.h" -namespace tachyon::zk::halo2 { +namespace tachyon { +namespace zk::halo2 { + +template +class Blake2bReader; + +template +class Blake2bWriter; + namespace internal { -template +template class Blake2bBase { protected: - using BaseField = typename AffinePoint::BaseField; - using ScalarField = typename AffinePoint::ScalarField; + friend class crypto::Transcript>; + friend class crypto::Transcript>; + + using Point = math::AffinePoint; + using BaseField = typename Point::BaseField; + using ScalarField = typename Point::ScalarField; Blake2bBase() { BLAKE2B512_InitWithPersonal(&state_, kTranscriptStr); } @@ -36,7 +48,7 @@ class Blake2bBase { math::BigInt<8>::FromBytesLE(result)); } - bool DoWriteToTranscript(const AffinePoint& point) { + bool DoWriteToTranscript(const Point& point) { BLAKE2B512_Update(&state_, kBlake2bPrefixPoint, 1); if (point.infinity()) { BLAKE2B512_Update(&state_, BaseField::BigIntTy::Zero().ToBytesLE().data(), @@ -68,68 +80,57 @@ class Blake2bBase { // TODO(TomTaehoonKim): We will replace Blake2b with an algebraic hash function // in a later version. See // https://github.com/kroma-network/halo2/blob/7d0a36990452c8e7ebd600de258420781a9b7917/halo2_proofs/src/transcript/blake2b.rs#L25 -template -class Blake2bReader : public crypto::TranscriptReader, - protected internal::Blake2bBase { +template +class Blake2bReader final + : public crypto::TranscriptReader>, + public internal::Blake2bBase { public: - using ScalarField = typename AffinePoint::ScalarField; - // Initialize a transcript given an input buffer. explicit Blake2bReader(base::Buffer read_buf) - : crypto::TranscriptReader(std::move(read_buf)) {} - - // crypto::TranscriptReader methods - ScalarField SqueezeChallenge() override { return this->DoSqueezeChallenge(); } - - bool WriteToTranscript(const AffinePoint& point) override { - return this->DoWriteToTranscript(point); - } - - bool WriteToTranscript(const ScalarField& scalar) override { - return this->DoWriteToTranscript(scalar); - } + : crypto::TranscriptReader>(std::move(read_buf)) {} private: - bool DoReadFromProof(AffinePoint* point) const override { - return ProofSerializer::ReadFromProof(this->buffer_, point); - } + friend class crypto::TranscriptReader>; - bool DoReadFromProof(ScalarField* scalar) const override { - return ProofSerializer::ReadFromProof(this->buffer_, scalar); + template + bool DoReadFromProof(T* value) const { + return ProofSerializer::ReadFromProof(this->buffer_, value); } }; -template -class Blake2bWriter : public crypto::TranscriptWriter, - protected internal::Blake2bBase { +template +class Blake2bWriter final + : public crypto::TranscriptWriter>, + public internal::Blake2bBase { public: - using ScalarField = typename AffinePoint::ScalarField; - // Initialize a transcript given an output buffer. explicit Blake2bWriter(base::Uint8VectorBuffer write_buf) - : crypto::TranscriptWriter(std::move(write_buf)) {} + : crypto::TranscriptWriter>(std::move(write_buf)) {} - // crypto::TranscriptWriter methods - ScalarField SqueezeChallenge() override { return this->DoSqueezeChallenge(); } + private: + friend class crypto::TranscriptWriter>; - bool WriteToTranscript(const AffinePoint& point) override { - return this->DoWriteToTranscript(point); + template + bool DoWriteToProof(const T& value) { + return ProofSerializer::WriteToProof(value, this->buffer_); } +}; - bool WriteToTranscript(const ScalarField& scalar) override { - return this->DoWriteToTranscript(scalar); - } +} // namespace zk::halo2 - private: - bool DoWriteToProof(const AffinePoint& point) override { - return ProofSerializer::WriteToProof(point, this->buffer_); - } +namespace crypto { - bool DoWriteToProof(const ScalarField& scalar) override { - return ProofSerializer::WriteToProof(scalar, this->buffer_); - } +template +struct TranscriptTraits> { + using Field = typename math::AffinePoint::ScalarField; +}; + +template +struct TranscriptTraits> { + using Field = typename math::AffinePoint::ScalarField; }; -} // namespace tachyon::zk::halo2 +} // namespace crypto +} // namespace tachyon #endif // TACHYON_ZK_PLONK_HALO2_BLAKE2B_TRANSCRIPT_H_ diff --git a/tachyon/zk/plonk/halo2/blake2b_transcript_unittest.cc b/tachyon/zk/plonk/halo2/blake2b_transcript_unittest.cc index 7563c36ad8..c5b4eb1ac0 100644 --- a/tachyon/zk/plonk/halo2/blake2b_transcript_unittest.cc +++ b/tachyon/zk/plonk/halo2/blake2b_transcript_unittest.cc @@ -28,12 +28,12 @@ class Blake2bTranscriptTest : public testing::Test { TEST_F(Blake2bTranscriptTest, WritePoint) { base::Uint8VectorBuffer write_buf; - Blake2bWriter writer(std::move(write_buf)); + Blake2bWriter writer(std::move(write_buf)); G1AffinePoint expected = G1AffinePoint::Random(); ASSERT_TRUE(writer.WriteToProof(expected)); base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - Blake2bReader reader(std::move(read_buf)); + Blake2bReader reader(std::move(read_buf)); G1AffinePoint actual; ASSERT_TRUE(reader.ReadFromProof(&actual)); @@ -42,12 +42,12 @@ TEST_F(Blake2bTranscriptTest, WritePoint) { TEST_F(Blake2bTranscriptTest, WriteScalar) { base::Uint8VectorBuffer write_buf; - Blake2bWriter writer(std::move(write_buf)); + Blake2bWriter writer(std::move(write_buf)); Fr expected = Fr::Random(); ASSERT_TRUE(writer.WriteToProof(expected)); base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - Blake2bReader reader(std::move(read_buf)); + Blake2bReader reader(std::move(read_buf)); Fr actual; ASSERT_TRUE(reader.ReadFromProof(&actual)); @@ -56,7 +56,7 @@ TEST_F(Blake2bTranscriptTest, WriteScalar) { TEST_F(Blake2bTranscriptTest, SqueezeChallenge) { base::Uint8VectorBuffer write_buf; - Blake2bWriter writer(std::move(write_buf)); + Blake2bWriter writer(std::move(write_buf)); G1AffinePoint generator = G1AffinePoint::Generator(); ASSERT_TRUE(writer.WriteToProof(generator)); diff --git a/tachyon/zk/plonk/halo2/poseidon_transcript.h b/tachyon/zk/plonk/halo2/poseidon_transcript.h index b448bb2606..cb59cc05ea 100644 --- a/tachyon/zk/plonk/halo2/poseidon_transcript.h +++ b/tachyon/zk/plonk/halo2/poseidon_transcript.h @@ -14,15 +14,26 @@ #include "tachyon/zk/plonk/halo2/poseidon_sponge.h" #include "tachyon/zk/plonk/halo2/proof_serializer.h" -namespace tachyon::zk::halo2 { +namespace tachyon { +namespace zk::halo2 { + +template +class PoseidonReader; + +template +class PoseidonWriter; + namespace internal { -template +template class PoseidonBase { protected: - using ScalarField = typename AffinePoint::ScalarField; - using Curve = typename AffinePoint::Curve; - using CurveConfig = typename Curve::Config; + friend class crypto::Transcript>; + friend class crypto::Transcript>; + + using Point = math::AffinePoint; + using BaseField = typename Point::BaseField; + using ScalarField = typename Point::ScalarField; PoseidonBase() : state_(crypto::PoseidonConfig::CreateCustom(8, 5, 8, 63, @@ -32,9 +43,10 @@ class PoseidonBase { return state_.SqueezeNativeFieldElements(1)[0]; } - bool DoWriteToTranscript(const AffinePoint& point) { - std::array coords = {CurveConfig::BaseToScalar(point.x()), - CurveConfig::BaseToScalar(point.y())}; + bool DoWriteToTranscript(const Point& point) { + std::array coords = { + Curve::Config::BaseToScalar(point.x()), + Curve::Config::BaseToScalar(point.y())}; return state_.Absorb(coords); } @@ -47,68 +59,57 @@ class PoseidonBase { } // namespace internal -template -class PoseidonReader : public crypto::TranscriptReader, - protected internal::PoseidonBase { +template +class PoseidonReader final + : public crypto::TranscriptReader>, + public internal::PoseidonBase { public: - using ScalarField = typename AffinePoint::ScalarField; - // Initialize a transcript given an input buffer. explicit PoseidonReader(base::Buffer buffer) - : crypto::TranscriptReader(std::move(buffer)) {} - - // crypto::TranscriptReader methods - ScalarField SqueezeChallenge() override { return this->DoSqueezeChallenge(); } - - bool WriteToTranscript(const AffinePoint& point) override { - return this->DoWriteToTranscript(point); - } - - bool WriteToTranscript(const ScalarField& scalar) override { - return this->DoWriteToTranscript(scalar); - } + : crypto::TranscriptReader>(std::move(buffer)) {} private: - bool DoReadFromProof(AffinePoint* point) const override { - return ProofSerializer::ReadFromProof(this->buffer_, point); - } + friend class crypto::TranscriptReader>; - bool DoReadFromProof(ScalarField* scalar) const override { - return ProofSerializer::ReadFromProof(this->buffer_, scalar); + template + bool DoReadFromProof(T* value) const { + return ProofSerializer::ReadFromProof(this->buffer_, value); } }; -template -class PoseidonWriter : public crypto::TranscriptWriter, - protected internal::PoseidonBase { +template +class PoseidonWriter final + : public crypto::TranscriptWriter>, + public internal::PoseidonBase { public: - using ScalarField = typename AffinePoint::ScalarField; - // Initialize a transcript given an output buffer. explicit PoseidonWriter(base::Uint8VectorBuffer buffer) - : crypto::TranscriptWriter(std::move(buffer)) {} + : crypto::TranscriptWriter>(std::move(buffer)) {} - // crypto::TranscriptWriter methods - ScalarField SqueezeChallenge() override { return this->DoSqueezeChallenge(); } + private: + friend class crypto::TranscriptWriter>; - bool WriteToTranscript(const AffinePoint& point) override { - return this->DoWriteToTranscript(point); + template + bool DoWriteToProof(const T& value) { + return ProofSerializer::WriteToProof(value, this->buffer_); } +}; - bool WriteToTranscript(const ScalarField& scalar) override { - return this->DoWriteToTranscript(scalar); - } +} // namespace zk::halo2 - private: - bool DoWriteToProof(const AffinePoint& point) override { - return ProofSerializer::WriteToProof(point, this->buffer_); - } +namespace crypto { - bool DoWriteToProof(const ScalarField& scalar) override { - return ProofSerializer::WriteToProof(scalar, this->buffer_); - } +template +struct TranscriptTraits> { + using Field = typename math::AffinePoint::ScalarField; +}; + +template +struct TranscriptTraits> { + using Field = typename math::AffinePoint::ScalarField; }; -} // namespace tachyon::zk::halo2 +} // namespace crypto +} // namespace tachyon #endif // TACHYON_ZK_PLONK_HALO2_POSEIDON_TRANSCRIPT_H_ diff --git a/tachyon/zk/plonk/halo2/poseidon_transcript_unittest.cc b/tachyon/zk/plonk/halo2/poseidon_transcript_unittest.cc index 9452eb934d..bec081e863 100644 --- a/tachyon/zk/plonk/halo2/poseidon_transcript_unittest.cc +++ b/tachyon/zk/plonk/halo2/poseidon_transcript_unittest.cc @@ -28,12 +28,12 @@ class PoseidonTranscriptTest : public testing::Test { TEST_F(PoseidonTranscriptTest, WritePoint) { base::Uint8VectorBuffer write_buf; - PoseidonWriter writer(std::move(write_buf)); + PoseidonWriter writer(std::move(write_buf)); G1AffinePoint expected = G1AffinePoint::Random(); ASSERT_TRUE(writer.WriteToProof(expected)); base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - PoseidonReader reader(std::move(read_buf)); + PoseidonReader reader(std::move(read_buf)); G1AffinePoint actual; ASSERT_TRUE(reader.ReadFromProof(&actual)); @@ -42,12 +42,12 @@ TEST_F(PoseidonTranscriptTest, WritePoint) { TEST_F(PoseidonTranscriptTest, WriteScalar) { base::Uint8VectorBuffer write_buf; - PoseidonWriter writer(std::move(write_buf)); + PoseidonWriter writer(std::move(write_buf)); Fr expected = Fr::Random(); ASSERT_TRUE(writer.WriteToProof(expected)); base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - PoseidonReader reader(std::move(read_buf)); + PoseidonReader reader(std::move(read_buf)); Fr actual; ASSERT_TRUE(reader.ReadFromProof(&actual)); @@ -56,7 +56,7 @@ TEST_F(PoseidonTranscriptTest, WriteScalar) { TEST_F(PoseidonTranscriptTest, SqueezeChallenge) { base::Uint8VectorBuffer write_buf; - PoseidonWriter writer(std::move(write_buf)); + PoseidonWriter writer(std::move(write_buf)); G1AffinePoint generator = G1AffinePoint::Generator(); ASSERT_TRUE(writer.WriteToProof(generator)); diff --git a/tachyon/zk/plonk/halo2/proof_reader.h b/tachyon/zk/plonk/halo2/proof_reader.h index 67704233ff..4124e70598 100644 --- a/tachyon/zk/plonk/halo2/proof_reader.h +++ b/tachyon/zk/plonk/halo2/proof_reader.h @@ -5,7 +5,6 @@ #include #include "tachyon/base/logging.h" -#include "tachyon/crypto/transcripts/transcript.h" #include "tachyon/zk/plonk/halo2/proof.h" #include "tachyon/zk/plonk/keys/verifying_key.h" #include "tachyon/zk/plonk/permutation/permutation_utils.h" @@ -38,9 +37,10 @@ class ProofReader { public: using F = typename PCS::Field; using C = typename PCS::Commitment; + using TranscriptReader = typename PCS::TranscriptReader; ProofReader(const VerifyingKey& verifying_key, - crypto::TranscriptReader* transcript, size_t num_circuits) + TranscriptReader* transcript, size_t num_circuits) : verifying_key_(verifying_key), transcript_(transcript), num_circuits_(num_circuits) {} @@ -255,7 +255,7 @@ class ProofReader { const VerifyingKey& verifying_key_; // not owned - crypto::TranscriptReader* const transcript_ = nullptr; + TranscriptReader* const transcript_ = nullptr; size_t num_circuits_ = 0; Proof proof_; ProofCursor cursor_ = ProofCursor::kAdviceCommitmentsVecAndChallenges; diff --git a/tachyon/zk/plonk/halo2/prover.h b/tachyon/zk/plonk/halo2/prover.h index 307f4f6f43..c1402f92f7 100644 --- a/tachyon/zk/plonk/halo2/prover.h +++ b/tachyon/zk/plonk/halo2/prover.h @@ -10,6 +10,8 @@ #include #include +#include "absl/memory/memory.h" + #include "tachyon/zk/base/entities/prover_base.h" #include "tachyon/zk/plonk/halo2/random_field_generator.h" #include "tachyon/zk/plonk/halo2/verifier.h" @@ -22,9 +24,11 @@ class Prover : public ProverBase { using F = typename PCS::Field; using Evals = typename PCS::Evals; using Commitment = typename PCS::Commitment; + using TranscriptReader = typename PCS::TranscriptReader; + using TranscriptWriter = typename PCS::TranscriptWriter; - static Prover CreateFromRandomSeed( - PCS&& pcs, std::unique_ptr> writer, + static std::unique_ptr CreateFromRandomSeed( + PCS&& pcs, std::unique_ptr writer, size_t blinding_factors) { auto rng = std::make_unique( crypto::XORShiftRNG::FromRandomSeed()); @@ -32,8 +36,8 @@ class Prover : public ProverBase { blinding_factors); } - static Prover CreateFromSeed( - PCS&& pcs, std::unique_ptr> writer, + static std::unique_ptr CreateFromSeed( + PCS&& pcs, std::unique_ptr writer, const uint8_t seed[16], size_t blinding_factors) { auto rng = std::make_unique( crypto::XORShiftRNG::FromSeed(seed)); @@ -41,20 +45,21 @@ class Prover : public ProverBase { blinding_factors); } - static Prover CreateFromRNG( - PCS&& pcs, std::unique_ptr> writer, + static std::unique_ptr CreateFromRNG( + PCS&& pcs, std::unique_ptr writer, std::unique_ptr rng, size_t blinding_factors) { auto generator = std::make_unique>(rng.get()); Blinder blinder(generator.get(), blinding_factors); - return {std::move(pcs), std::move(writer), std::move(blinder), - std::move(rng), std::move(generator)}; + return absl::WrapUnique(new Prover(std::move(pcs), std::move(writer), + std::move(blinder), std::move(rng), + std::move(generator))); } crypto::XORShiftRNG* rng() { return rng_.get(); } RandomFieldGenerator* generator() { return generator_.get(); } std::unique_ptr> ToVerifier( - std::unique_ptr> reader) { + std::unique_ptr reader) { std::unique_ptr> ret = std::make_unique>( std::move(this->pcs_), std::move(reader)); ret->set_domain(std::move(this->domain_)); @@ -63,8 +68,7 @@ class Prover : public ProverBase { } private: - Prover(PCS&& pcs, - std::unique_ptr> writer, + Prover(PCS&& pcs, std::unique_ptr writer, Blinder&& blinder, std::unique_ptr rng, std::unique_ptr> generator) : ProverBase(std::move(pcs), std::move(writer), std::move(blinder)), diff --git a/tachyon/zk/plonk/halo2/prover_test.h b/tachyon/zk/plonk/halo2/prover_test.h index ecf59d6784..248eb0ae62 100644 --- a/tachyon/zk/plonk/halo2/prover_test.h +++ b/tachyon/zk/plonk/halo2/prover_test.h @@ -22,7 +22,9 @@ class ProverTest : public testing::Test { constexpr static size_t kMaxExtendedDomainSize = kMaxExtendedDegree + 1; using PCS = SHPlonkExtension; + kMaxExtendedDegree, math::bn254::G1AffinePoint, + Blake2bReader, + Blake2bWriter>; using F = PCS::Field; using Commitment = PCS::Commitment; using Poly = PCS::Poly; @@ -39,15 +41,16 @@ class ProverTest : public testing::Test { ASSERT_TRUE(pcs.UnsafeSetup(kMaxDomainSize)); base::Uint8VectorBuffer write_buf; - std::unique_ptr> writer = - std::make_unique>(std::move(write_buf)); + std::unique_ptr> writer = + std::make_unique>( + std::move(write_buf)); constexpr uint8_t kSeed[] = {0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5}; - prover_ = std::make_unique>(Prover::CreateFromSeed( - std::move(pcs), std::move(writer), kSeed, /*blinding_factors=*/0)); + prover_ = Prover::CreateFromSeed(std::move(pcs), std::move(writer), + kSeed, /*blinding_factors=*/0); prover_->set_domain(Domain::Create(kMaxDomainSize)); prover_->set_extended_domain( ExtendedDomain::Create(kMaxExtendedDomainSize)); @@ -55,8 +58,9 @@ class ProverTest : public testing::Test { protected: std::unique_ptr> CreateVerifier(base::Buffer read_buf) { - std::unique_ptr> reader = - std::make_unique>(std::move(read_buf)); + std::unique_ptr> reader = + std::make_unique>( + std::move(read_buf)); return prover_->ToVerifier(std::move(reader)); } diff --git a/tachyon/zk/plonk/halo2/sha256_transcript.h b/tachyon/zk/plonk/halo2/sha256_transcript.h index f611f4fac9..a9fd3b0a59 100644 --- a/tachyon/zk/plonk/halo2/sha256_transcript.h +++ b/tachyon/zk/plonk/halo2/sha256_transcript.h @@ -17,14 +17,26 @@ #include "tachyon/zk/plonk/halo2/constants.h" #include "tachyon/zk/plonk/halo2/proof_serializer.h" -namespace tachyon::zk::halo2 { +namespace tachyon { +namespace zk::halo2 { + +template +class Sha256Reader; + +template +class Sha256Writer; + namespace internal { -template +template class Sha256Base { protected: - using BaseField = typename AffinePoint::BaseField; - using ScalarField = typename AffinePoint::ScalarField; + friend class crypto::Transcript>; + friend class crypto::Transcript>; + + using Point = math::AffinePoint; + using BaseField = typename Point::BaseField; + using ScalarField = typename Point::ScalarField; Sha256Base() { SHA256_Init(&state_); } @@ -41,11 +53,11 @@ class Sha256Base { return ScalarField::FromAnySizedBigInt( math::BigInt<4>::FromBytesLE(result)); } else { - base::AlwaysFalse(); + base::AlwaysFalse(); } } - bool DoWriteToTranscript(const AffinePoint& point) { + bool DoWriteToTranscript(const Point& point) { SHA256_Update(&state_, kShaPrefixZeros, 31); SHA256_Update(&state_, kShaPrefixPoint, 1); SHA256_Update(&state_, point.x().ToBigInt().ToBytesBE().data(), @@ -68,72 +80,59 @@ class Sha256Base { } // namespace internal -template -class Sha256Reader : public crypto::TranscriptReader, - protected internal::Sha256Base { +template +class Sha256Reader final : public crypto::TranscriptReader>, + public internal::Sha256Base { public: - using ScalarField = typename AffinePoint::ScalarField; - // Initialize a transcript given an input buffer. explicit Sha256Reader(base::Buffer read_buf) - : crypto::TranscriptReader(std::move(read_buf)) {} - - // crypto::TranscriptReader methods - ScalarField SqueezeChallenge() override { return this->DoSqueezeChallenge(); } - - bool WriteToTranscript(const AffinePoint& point) override { - return this->DoWriteToTranscript(point); - } - - bool WriteToTranscript(const ScalarField& scalar) override { - return this->DoWriteToTranscript(scalar); - } + : crypto::TranscriptReader>(std::move(read_buf)) {} private: - bool DoReadFromProof(AffinePoint* point) const override { - return ProofSerializer::ReadFromProof(this->buffer_, point); - } + friend class crypto::TranscriptReader>; - bool DoReadFromProof(ScalarField* scalar) const override { - return ProofSerializer::ReadFromProof(this->buffer_, scalar); + template + bool DoReadFromProof(T* value) const { + return ProofSerializer::ReadFromProof(this->buffer_, value); } }; -template -class Sha256Writer : public crypto::TranscriptWriter, - protected internal::Sha256Base { +template +class Sha256Writer final : public crypto::TranscriptWriter>, + public internal::Sha256Base { public: - using ScalarField = typename AffinePoint::ScalarField; - // Initialize a transcript given an output buffer. explicit Sha256Writer(base::Uint8VectorBuffer write_buf) - : crypto::TranscriptWriter(std::move(write_buf)) { + : crypto::TranscriptWriter>(std::move(write_buf)) { SHA256_Init(&state_); } - // crypto::TranscriptWriter methods - ScalarField SqueezeChallenge() override { return this->DoSqueezeChallenge(); } + private: + friend class crypto::TranscriptWriter>; - bool WriteToTranscript(const AffinePoint& point) override { - return this->DoWriteToTranscript(point); + template + bool DoWriteToProof(const T& value) { + return ProofSerializer::WriteToProof(value, this->buffer_); } - bool WriteToTranscript(const ScalarField& scalar) override { - return this->DoWriteToTranscript(scalar); - } + SHA256_CTX state_; +}; - private: - bool DoWriteToProof(const AffinePoint& point) override { - return ProofSerializer::WriteToProof(point, this->buffer_); - } +} // namespace zk::halo2 - bool DoWriteToProof(const ScalarField& scalar) override { - return ProofSerializer::WriteToProof(scalar, this->buffer_); - } +namespace crypto { - SHA256_CTX state_; +template +struct TranscriptTraits> { + using Field = typename math::AffinePoint::ScalarField; +}; + +template +struct TranscriptTraits> { + using Field = typename math::AffinePoint::ScalarField; }; -} // namespace tachyon::zk::halo2 +} // namespace crypto +} // namespace tachyon #endif // TACHYON_ZK_PLONK_HALO2_SHA256_TRANSCRIPT_H_ diff --git a/tachyon/zk/plonk/halo2/sha256_transcript_unittest.cc b/tachyon/zk/plonk/halo2/sha256_transcript_unittest.cc index bf0dd95d11..448be7d33c 100644 --- a/tachyon/zk/plonk/halo2/sha256_transcript_unittest.cc +++ b/tachyon/zk/plonk/halo2/sha256_transcript_unittest.cc @@ -28,12 +28,12 @@ class Sha256TranscriptTest : public testing::Test { TEST_F(Sha256TranscriptTest, WritePoint) { base::Uint8VectorBuffer write_buf; - Sha256Writer writer(std::move(write_buf)); + Sha256Writer writer(std::move(write_buf)); G1AffinePoint expected = G1AffinePoint::Random(); ASSERT_TRUE(writer.WriteToProof(expected)); base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - Sha256Reader reader(std::move(read_buf)); + Sha256Reader reader(std::move(read_buf)); G1AffinePoint actual; ASSERT_TRUE(reader.ReadFromProof(&actual)); @@ -42,12 +42,12 @@ TEST_F(Sha256TranscriptTest, WritePoint) { TEST_F(Sha256TranscriptTest, WriteScalar) { base::Uint8VectorBuffer write_buf; - Sha256Writer writer(std::move(write_buf)); + Sha256Writer writer(std::move(write_buf)); Fr expected = Fr::Random(); ASSERT_TRUE(writer.WriteToProof(expected)); base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - Sha256Reader reader(std::move(read_buf)); + Sha256Reader reader(std::move(read_buf)); Fr actual; ASSERT_TRUE(reader.ReadFromProof(&actual)); @@ -56,7 +56,7 @@ TEST_F(Sha256TranscriptTest, WriteScalar) { TEST_F(Sha256TranscriptTest, SqueezeChallenge) { base::Uint8VectorBuffer write_buf; - Sha256Writer writer(std::move(write_buf)); + Sha256Writer writer(std::move(write_buf)); G1AffinePoint generator = G1AffinePoint::Generator(); ASSERT_TRUE(writer.WriteToProof(generator)); diff --git a/tachyon/zk/plonk/halo2/verifier.h b/tachyon/zk/plonk/halo2/verifier.h index 01ad6bafe6..3878935ad5 100644 --- a/tachyon/zk/plonk/halo2/verifier.h +++ b/tachyon/zk/plonk/halo2/verifier.h @@ -32,6 +32,7 @@ class Verifier : public VerifierBase { using Commitment = typename PCS::Commitment; using Evals = typename PCS::Evals; using Poly = typename PCS::Poly; + using TranscriptReader = typename PCS::TranscriptReader; using Coefficients = typename Poly::Coefficients; using VerifierBase::VerifierBase; @@ -59,7 +60,7 @@ class Verifier : public VerifierBase { instance_commitments_vec.resize(instance_columns_vec.size()); } - crypto::TranscriptReader* transcript = this->GetReader(); + TranscriptReader* transcript = this->GetReader(); CHECK(transcript->WriteToTranscript(vkey.transcript_repr())); if constexpr (PCS::kQueryInstance) { @@ -158,7 +159,7 @@ class Verifier : public VerifierBase { } static void WriteCommitmentsVecToTranscript( - crypto::TranscriptReader* transcript, + TranscriptReader* transcript, const std::vector>& commitments_vec) { for (const std::vector& commitments : commitments_vec) { for (const Commitment& commitment : commitments) { @@ -168,7 +169,7 @@ class Verifier : public VerifierBase { } static void WriteColumnsVecToTranscript( - crypto::TranscriptReader* transcript, + TranscriptReader* transcript, const std::vector>& columns_vec) { for (const std::vector& columns : columns_vec) { for (const Evals& column : columns) { diff --git a/tachyon/zk/plonk/vanishing/BUILD.bazel b/tachyon/zk/plonk/vanishing/BUILD.bazel index 640b967223..d943bfd561 100644 --- a/tachyon/zk/plonk/vanishing/BUILD.bazel +++ b/tachyon/zk/plonk/vanishing/BUILD.bazel @@ -68,7 +68,6 @@ tachyon_cc_library( ":vanishing_evaluated", ":vanishing_utils", "//tachyon/base:parallelize", - "//tachyon/crypto/transcripts:transcript", "//tachyon/zk/base:prover_query", "//tachyon/zk/base/entities:entity_ty", "//tachyon/zk/base/entities:prover_base", @@ -148,7 +147,6 @@ tachyon_cc_library( ":vanishing_constructed", ":vanishing_evaluated", ":vanishing_partially_evaluated", - "//tachyon/crypto/transcripts:transcript", "//tachyon/math/elliptic_curves:points", "//tachyon/zk/base:verifier_query", "//tachyon/zk/plonk/keys:verifying_key", diff --git a/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h b/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h index ef57e100b4..f42a2022a0 100644 --- a/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h +++ b/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h @@ -12,7 +12,6 @@ #include #include "tachyon/base/parallelize.h" -#include "tachyon/crypto/transcripts/transcript.h" #include "tachyon/zk/base/entities/entity_ty.h" #include "tachyon/zk/base/entities/prover_base.h" #include "tachyon/zk/base/prover_query.h" @@ -103,10 +102,10 @@ template return true; } -template +template [[nodiscard]] bool CommitRandomEval( const PCS& pcs, VanishingConstructed&& constructed, - const F& x, const F& x_n, crypto::TranscriptWriter* writer, + const F& x, const F& x_n, TranscriptWriter* writer, VanishingEvaluated* evaluated_out) { using Poly = typename PCS::Poly; using Coeffs = typename Poly::Coefficients; diff --git a/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h b/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h index 19d8c179e5..5b70846739 100644 --- a/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h +++ b/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h @@ -11,7 +11,6 @@ #include #include "tachyon/base/ref.h" -#include "tachyon/crypto/transcripts/transcript.h" #include "tachyon/math/elliptic_curves/semigroups.h" #include "tachyon/zk/base/entities/entity_ty.h" #include "tachyon/zk/base/verifier_query.h" @@ -23,10 +22,12 @@ namespace tachyon::zk { -template +template [[nodiscard]] bool ReadCommitmentsBeforeY( - crypto::TranscriptReader* transcript, + TranscriptReader* transcript, VanishingCommitted* committed_out) { + using Commitment = typename PCS::Commitment; + Commitment c; if (!transcript->ReadFromProof(&c)) return false; @@ -34,12 +35,13 @@ template return true; } -template +template [[nodiscard]] bool ReadCommitmentsAfterY( VanishingCommitted&& committed, - const VerifyingKey& vk, - crypto::TranscriptReader* transcript, + const VerifyingKey& vk, TranscriptReader* transcript, VanishingConstructed* constructed_out) { + using Commitment = typename PCS::Commitment; + // Obtain a commitment to h(X) in the form of multiple pieces of degree // n - 1 std::vector h_commitments; @@ -54,10 +56,10 @@ template return true; } -template +template [[nodiscard]] bool EvaluateAfterX( VanishingConstructed&& constructed, - crypto::TranscriptReader* transcript, + TranscriptReader* transcript, VanishingPartiallyEvaluated* partially_evaluated_out) { F random_eval; if (!transcript->ReadFromProof(&random_eval)) return false;