diff --git a/tachyon/crypto/commitments/kzg/BUILD.bazel b/tachyon/crypto/commitments/kzg/BUILD.bazel index 1ec1fdc6e..4e853907e 100644 --- a/tachyon/crypto/commitments/kzg/BUILD.bazel +++ b/tachyon/crypto/commitments/kzg/BUILD.bazel @@ -43,9 +43,9 @@ tachyon_cc_unittest( deps = [ ":shplonk", "//tachyon/base/buffer:vector_buffer", - "//tachyon/crypto/transcripts:poseidon_transcript", "//tachyon/math/elliptic_curves/bn/bn254:g1", "//tachyon/math/elliptic_curves/bn/bn254:g2", "//tachyon/math/polynomials/univariate:univariate_evaluation_domain_factory", + "//tachyon/zk/plonk/halo2:poseidon_transcript", ], ) diff --git a/tachyon/crypto/commitments/kzg/shplonk.h b/tachyon/crypto/commitments/kzg/shplonk.h index d63ae3355..ccb4ab6de 100644 --- a/tachyon/crypto/commitments/kzg/shplonk.h +++ b/tachyon/crypto/commitments/kzg/shplonk.h @@ -88,7 +88,7 @@ class SHPlonk : public UnivariatePolynomialCommitmentScheme< const absl::btree_set& super_point_set = grouper.super_point_set(); - Field y = writer->SqueezeChallengeAsScalar(); + Field y = writer->SqueezeChallenge(); // Create [H₀(X), H₁(X), H₂(X)]. // clang-format off @@ -107,7 +107,7 @@ class SHPlonk : public UnivariatePolynomialCommitmentScheme< y, low_degree_extensions_vec[i]); }); - Field v = writer->SqueezeChallengeAsScalar(); + Field v = writer->SqueezeChallenge(); // Create a linear combination of polynomials [H₀(X), H₁(X), H₂(X)] with // with |v|. @@ -119,7 +119,7 @@ class SHPlonk : public UnivariatePolynomialCommitmentScheme< if (!this->Commit(h_poly, &h)) return false; CHECK(writer->WriteToProof(h)); - Field u = writer->SqueezeChallengeAsScalar(); + Field u = writer->SqueezeChallenge(); // Create [L₀(X), L₁(X), L₂(X)]. // L₀(X) = z₀ * ((P₀(X) - R₀(u)) + y(P₁(X) - R₁(u)) + y²(P₂(X) - R₂(u))) diff --git a/tachyon/crypto/commitments/kzg/shplonk_unittest.cc b/tachyon/crypto/commitments/kzg/shplonk_unittest.cc index ba53cbb9d..57c738fd9 100644 --- a/tachyon/crypto/commitments/kzg/shplonk_unittest.cc +++ b/tachyon/crypto/commitments/kzg/shplonk_unittest.cc @@ -4,10 +4,10 @@ #include "gtest/gtest.h" -#include "tachyon/crypto/transcripts/poseidon_transcript.h" #include "tachyon/math/elliptic_curves/bn/bn254/g1.h" #include "tachyon/math/elliptic_curves/bn/bn254/g2.h" #include "tachyon/math/polynomials/univariate/univariate_evaluation_domain_factory.h" +#include "tachyon/zk/plonk/halo2/poseidon_transcript.h" namespace tachyon::crypto { @@ -33,7 +33,7 @@ class SHPlonkTest : public testing::Test { void SetUp() override { KZG kzg; base::VectorBuffer write_buf; - writer_ = PoseidonWriter(std::move(write_buf)); + writer_ = zk::halo2::PoseidonWriter(std::move(write_buf)); pcs_ = PCS(std::move(kzg), &writer_); ASSERT_TRUE(pcs_.UnsafeSetup(N)); @@ -79,7 +79,7 @@ class SHPlonkTest : public testing::Test { std::vector polys_; std::vector points_; std::vector> poly_openings_; - PoseidonWriter writer_; + zk::halo2::PoseidonWriter writer_; }; } // namespace diff --git a/tachyon/crypto/hashes/sponge/poseidon/BUILD.bazel b/tachyon/crypto/hashes/sponge/poseidon/BUILD.bazel index b8b58b5e9..6290e74e4 100644 --- a/tachyon/crypto/hashes/sponge/poseidon/BUILD.bazel +++ b/tachyon/crypto/hashes/sponge/poseidon/BUILD.bazel @@ -12,15 +12,6 @@ tachyon_cc_library( ], ) -tachyon_cc_library( - name = "halo2_poseidon", - hdrs = ["halo2_poseidon.h"], - deps = [ - ":poseidon", - "@local_config_gmp//:gmp", - ], -) - tachyon_cc_library( name = "poseidon_config", hdrs = ["poseidon_config.h"], diff --git a/tachyon/crypto/transcripts/BUILD.bazel b/tachyon/crypto/transcripts/BUILD.bazel index 720e414c3..55929cf61 100644 --- a/tachyon/crypto/transcripts/BUILD.bazel +++ b/tachyon/crypto/transcripts/BUILD.bazel @@ -1,59 +1,22 @@ -load("//bazel:tachyon_cc.bzl", "tachyon_cc_library", "tachyon_cc_unittest") +load("//bazel:tachyon_cc.bzl", "tachyon_cc_library") package(default_visibility = ["//visibility:public"]) -tachyon_cc_library( - name = "blake2b_transcript", - hdrs = ["blake2b_transcript.h"], - deps = [ - ":transcript", - "//tachyon/math/elliptic_curves:points", - "@com_google_boringssl//:crypto", - ], -) - -tachyon_cc_library( - name = "poseidon_transcript", - hdrs = ["poseidon_transcript.h"], - deps = [ - ":transcript", - "//tachyon/crypto/hashes/sponge/poseidon:halo2_poseidon", - "//tachyon/math/elliptic_curves:points", - ], -) - -tachyon_cc_library( - name = "sha256_transcript", - hdrs = ["sha256_transcript.h"], - deps = [ - ":transcript", - "//tachyon/base/ranges:algorithm", - "//tachyon/base/types:always_false", - "//tachyon/math/elliptic_curves:points", - "@com_google_boringssl//:crypto", - ], -) - tachyon_cc_library( name = "transcript", hdrs = ["transcript.h"], deps = [ + ":transcript_traits", "//tachyon/base/buffer:vector_buffer", "//tachyon/math/base:big_int", ], ) -tachyon_cc_unittest( - name = "transcript_unittests", - srcs = [ - "blake2b_transcript_unittest.cc", - "poseidon_transcript_unittest.cc", - "sha256_transcript_unittest.cc", - ], +tachyon_cc_library( + name = "transcript_traits", + hdrs = ["transcript_traits.h"], deps = [ - ":blake2b_transcript", - ":poseidon_transcript", - ":sha256_transcript", - "//tachyon/math/elliptic_curves/bn/bn254:g1", + "//tachyon/math/elliptic_curves:points", + "//tachyon/math/finite_fields:prime_field_base", ], ) diff --git a/tachyon/crypto/transcripts/blake2b_transcript_unittest.cc b/tachyon/crypto/transcripts/blake2b_transcript_unittest.cc deleted file mode 100644 index fe723d0f1..000000000 --- a/tachyon/crypto/transcripts/blake2b_transcript_unittest.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2020-2022 The Electric Coin Company -// Copyright 2022 The Halo2 developers -// Use of this source code is governed by a MIT/Apache-2.0 style license that -// can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 -// file. - -#include "tachyon/crypto/transcripts/blake2b_transcript.h" - -#include -#include - -#include "gtest/gtest.h" - -#include "tachyon/math/elliptic_curves/bn/bn254/g1.h" - -namespace tachyon::crypto { - -namespace { - -class Blake2bTranscriptTest : public testing::Test { - public: - static void SetUpTestSuite() { math::bn254::G1Curve::Init(); } -}; - -} // namespace - -TEST_F(Blake2bTranscriptTest, WritePoint) { - using Curve = math::bn254::G1Curve; - - base::VectorBuffer write_buf; - Blake2bWriter writer(std::move(write_buf)); - Curve::AffinePointTy expected = Curve::AffinePointTy::Random(); - ASSERT_TRUE(writer.WriteToProof(expected)); - - base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - Blake2bReader reader(std::move(read_buf)); - Curve::AffinePointTy actual; - ASSERT_TRUE(reader.ReadPoint(&actual)); - - EXPECT_EQ(expected, actual); -} - -TEST_F(Blake2bTranscriptTest, WriteScalar) { - using Curve = math::bn254::G1Curve; - - base::VectorBuffer write_buf; - Blake2bWriter writer(std::move(write_buf)); - Curve::ScalarField expected = Curve::ScalarField::Random(); - ASSERT_TRUE(writer.WriteToProof(expected)); - - base::Buffer read_buf(writer.buffer().buffer(), writer.buffer().buffer_len()); - Blake2bReader reader(std::move(read_buf)); - Curve::ScalarField actual; - ASSERT_TRUE(reader.ReadScalar(&actual)); - - EXPECT_EQ(expected, actual); -} - -TEST_F(Blake2bTranscriptTest, SqueezeChallenge) { - using Curve = math::bn254::G1Curve; - - base::VectorBuffer write_buf; - Blake2bWriter writer(std::move(write_buf)); - Curve::AffinePointTy generator = Curve::AffinePointTy::Generator(); - ASSERT_TRUE(writer.WriteToProof(generator)); - - std::vector expected_bytes = {26, 175, 9, 178, 100, 103, 8, 151, - 102, 161, 101, 61, 222, 95, 165, 141, - 175, 20, 97, 43, 214, 93, 71, 110, - 109, 175, 18, 100, 39, 250, 214, 25}; - Curve::ScalarField expected = Curve::ScalarField::FromBigInt( - math::BigInt<4>::FromBytesLE(expected_bytes)); - - Curve::ScalarField actual = writer.SqueezeChallenge().ChallengeAsScalar(); - - EXPECT_EQ(expected, actual); -} - -} // namespace tachyon::crypto diff --git a/tachyon/crypto/transcripts/transcript.h b/tachyon/crypto/transcripts/transcript.h index ff047bdd8..08303d40d 100644 --- a/tachyon/crypto/transcripts/transcript.h +++ b/tachyon/crypto/transcripts/transcript.h @@ -10,128 +10,191 @@ #include #include "tachyon/base/buffer/vector_buffer.h" -#include "tachyon/math/base/big_int.h" +#include "tachyon/crypto/transcripts/transcript_traits.h" namespace tachyon::crypto { -// A 255-bit challenge. -template -class Challenge255 { +template +class TranscriptReaderImpl; + +template +class TranscriptWriterImpl; + +template +class TranscriptImpl; + +// Generic transcript view (from either the prover or verifier's perspective) +template +class TranscriptImpl<_Commitment, false> { public: - static_assert(F::kLimbNums <= 4); + using Commitment = _Commitment; + using Field = typename TranscriptTraits::Field; - constexpr Challenge255() = default; - constexpr explicit Challenge255(const F& challenge_input) - : challenge_(math::BigInt<4>::FromBytesLE( - challenge_input.ToBigInt().ToBytesLE())) {} + virtual ~TranscriptImpl() = default; - constexpr const math::BigInt<4>& challenge() const { return challenge_; } + // Squeeze an encoded verifier challenge from the transcript. + virtual Field SqueezeChallenge() = 0; - constexpr F ChallengeAsScalar() const { return F::FromBigInt(challenge_); } + // Write a |commitment| to the transcript without writing it to the proof, + // treating it as a common input. + virtual bool WriteToTranscript(const Commitment& commitment) = 0; - private: - math::BigInt<4> challenge_; -}; + // Write a |value| to the transcript without writing it to the proof, + // treating it as a common input. + virtual bool WriteToTranscript(const Field& value) = 0; -template -class TranscriptReader; + TranscriptWriterImpl* ToWriter() { + return static_cast*>(this); + } -template -class TranscriptWriter; + TranscriptReaderImpl* ToReader() { + return static_cast*>(this); + } +}; -// Generic transcript view (from either the prover or verifier's perspective) -template -class Transcript { +template +class TranscriptImpl<_Field, true> { public: - using ScalarField = typename AffinePointTy::ScalarField; + using Field = _Field; - virtual ~Transcript() = default; + virtual ~TranscriptImpl() = default; // Squeeze an encoded verifier challenge from the transcript. - virtual Challenge255 SqueezeChallenge() = 0; - - ScalarField SqueezeChallengeAsScalar() { - return SqueezeChallenge().ChallengeAsScalar(); - } + virtual Field SqueezeChallenge() = 0; - // Write a curve |point| to the transcript without writing it to the proof, + // Write a |value| to the transcript without writing it to the proof, // treating it as a common input. - virtual bool WriteToTranscript(const AffinePointTy& point) = 0; + virtual bool WriteToTranscript(const Field& value) = 0; - // Write a curve |scalar| to the transcript without writing it to the proof, - // treating it as a common input. - virtual bool WriteToTranscript(const ScalarField& scalar) = 0; - - TranscriptWriter* ToWriter() { - return static_cast*>(this); + TranscriptWriterImpl* ToWriter() { + return static_cast*>(this); } - TranscriptReader* ToReader() { - return static_cast*>(this); + TranscriptReaderImpl* 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 TranscriptReader : public Transcript { +template +class TranscriptReaderImpl : public Transcript { public: - using ScalarField = typename AffinePointTy::ScalarField; + using Field = typename TranscriptTraits::Field; - TranscriptReader() = default; + TranscriptReaderImpl() = default; // Initialize a transcript given an input buffer. - explicit TranscriptReader(base::Buffer read_buf) + 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 curve |point| from the prover. Note that it also writes the - // |point| to the transcript by calling |WriteToTranscript()| internally. - bool ReadPoint(AffinePointTy* point) { - return buffer_.Read(point) && this->WriteToTranscript(*point); + // Read a |commitment| from the proof. Note that it also writes the + // |commitment| to the transcript by calling |WriteToTranscript()| internally. + bool ReadFromProof(Commitment* commitment) { + return buffer_.Read(commitment) && this->WriteToTranscript(*commitment); } - // Read a curve |scalar| from the prover. Note that it also writes the - // |scalar| to the transcript by calling |WriteToTranscript()| internally. - bool ReadScalar(ScalarField* scalar) { - return buffer_.Read(scalar) && this->WriteToTranscript(*scalar); + // Read a |value| from the proof. Note that it also writes the + // |value| to the transcript by calling |WriteToTranscript()| internally. + bool ReadFromProof(Field* value) { + return buffer_.Read(value) && this->WriteToTranscript(*value); } private: 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. + bool ReadFromProof(Field* value) { + return buffer_.Read(value) && this->WriteToTranscript(*value); + } + + private: + 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 TranscriptWriter : public Transcript { +template +class TranscriptWriterImpl : public Transcript { public: - using ScalarField = typename AffinePointTy::ScalarField; + using Field = typename TranscriptTraits::Field; - TranscriptWriter() = default; + TranscriptWriterImpl() = default; // Initialize a transcript given an output buffer. - explicit TranscriptWriter(base::VectorBuffer buf) : buffer_(std::move(buf)) {} + explicit TranscriptWriterImpl(base::VectorBuffer buf) + : buffer_(std::move(buf)) {} base::VectorBuffer& buffer() { return buffer_; } const base::VectorBuffer& buffer() const { return buffer_; } - // Write a curve |point| to the proof. Note that it also writes the - // |point| to the transcript by calling |WriteToTranscript()| internally. - bool WriteToProof(const AffinePointTy& point) { - return this->WriteToTranscript(point) && buffer_.Write(point); + // Write a |commitment| to the proof. Note that it also writes the + // |commitment| to the transcript by calling |WriteToTranscript()| internally. + bool WriteToProof(const Commitment& commitment) { + return this->WriteToTranscript(commitment) && buffer_.Write(commitment); } - // Write a curve |scalar| to the proof. Note that it also writes the - // |scalar| to the transcript by calling |WriteToTranscript()| internally. - bool WriteToProof(const ScalarField& scalar) { - return this->WriteToTranscript(scalar) && buffer_.Write(scalar); + // Write a |value| to the proof. Note that it also writes the + // |value| to the transcript by calling |WriteToTranscript()| internally. + bool WriteToProof(const Field& value) { + return this->WriteToTranscript(value) && buffer_.Write(value); } private: base::VectorBuffer 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::VectorBuffer buf) + : buffer_(std::move(buf)) {} + + base::VectorBuffer& buffer() { return buffer_; } + const base::VectorBuffer& buffer() const { return buffer_; } + + // Write a |value| to the proof. Note that it also writes the + // |value| to the transcript by calling |WriteToTranscript()| internally. + bool WriteToProof(const Field& value) { + return this->WriteToTranscript(value) && buffer_.Write(value); + } + + private: + base::VectorBuffer 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 new file mode 100644 index 000000000..5990fcb95 --- /dev/null +++ b/tachyon/crypto/transcripts/transcript_traits.h @@ -0,0 +1,31 @@ +#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/zk/plonk/halo2/BUILD.bazel b/tachyon/zk/plonk/halo2/BUILD.bazel index 26314cd0a..3e42b8bae 100644 --- a/tachyon/zk/plonk/halo2/BUILD.bazel +++ b/tachyon/zk/plonk/halo2/BUILD.bazel @@ -2,6 +2,17 @@ load("//bazel:tachyon_cc.bzl", "tachyon_cc_library", "tachyon_cc_unittest") package(default_visibility = ["//visibility:public"]) +tachyon_cc_library( + name = "blake2b_transcript", + hdrs = ["blake2b_transcript.h"], + deps = [ + ":constants", + "//tachyon/crypto/transcripts:transcript", + "//tachyon/math/base:big_int", + "@com_google_boringssl//:crypto", + ], +) + tachyon_cc_library( name = "constants", hdrs = ["constants.h"], @@ -47,6 +58,24 @@ tachyon_cc_library( ], ) +tachyon_cc_library( + name = "poseidon_sponge", + hdrs = ["poseidon_sponge.h"], + deps = [ + "//tachyon/crypto/hashes/sponge/poseidon", + "@local_config_gmp//:gmp", + ], +) + +tachyon_cc_library( + name = "poseidon_transcript", + hdrs = ["poseidon_transcript.h"], + deps = [ + ":poseidon_sponge", + "//tachyon/crypto/transcripts:transcript", + ], +) + tachyon_cc_library( name = "prover", hdrs = ["prover.h"], @@ -61,14 +90,13 @@ tachyon_cc_library( testonly = True, hdrs = ["prover_test.h"], deps = [ - ":constants", ":prover", - "//tachyon/crypto/transcripts:blake2b_transcript", "//tachyon/math/elliptic_curves/bn/bn254:g1", "//tachyon/math/elliptic_curves/bn/bn254:g2", "//tachyon/math/polynomials/univariate:univariate_evaluation_domain_factory", "//tachyon/zk/base:blinder", "//tachyon/zk/base/commitments:shplonk_extension", + "//tachyon/zk/plonk/halo2:blake2b_transcript", ], ) @@ -83,14 +111,32 @@ tachyon_cc_library( ], ) +tachyon_cc_library( + name = "sha256_transcript", + hdrs = ["sha256_transcript.h"], + deps = [ + ":constants", + "//tachyon/base/types:always_false", + "//tachyon/crypto/transcripts:transcript", + "//tachyon/math/base:big_int", + "@com_google_boringssl//:crypto", + ], +) + tachyon_cc_unittest( name = "halo2_unittests", srcs = [ + "blake2b_transcript_unittest.cc", "pinned_verifying_key_unittest.cc", + "poseidon_transcript_unittest.cc", "random_field_generator_unittest.cc", + "sha256_transcript_unittest.cc", ], deps = [ + ":blake2b_transcript", ":pinned_verifying_key", + ":poseidon_transcript", ":prover_test", + ":sha256_transcript", ], ) diff --git a/tachyon/crypto/transcripts/blake2b_transcript.h b/tachyon/zk/plonk/halo2/blake2b_transcript.h similarity index 59% rename from tachyon/crypto/transcripts/blake2b_transcript.h rename to tachyon/zk/plonk/halo2/blake2b_transcript.h index 4bb8ab65a..69e4fbdf4 100644 --- a/tachyon/crypto/transcripts/blake2b_transcript.h +++ b/tachyon/zk/plonk/halo2/blake2b_transcript.h @@ -4,60 +4,43 @@ // can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 // file. -#ifndef TACHYON_CRYPTO_TRANSCRIPTS_BLAKE2B_TRANSCRIPT_H_ -#define TACHYON_CRYPTO_TRANSCRIPTS_BLAKE2B_TRANSCRIPT_H_ +#ifndef TACHYON_ZK_PLONK_HALO2_BLAKE2B_TRANSCRIPT_H_ +#define TACHYON_ZK_PLONK_HALO2_BLAKE2B_TRANSCRIPT_H_ -#include #include #include "openssl/blake2.h" -#include "tachyon/base/ranges/algorithm.h" #include "tachyon/crypto/transcripts/transcript.h" #include "tachyon/math/base/big_int.h" -#include "tachyon/math/elliptic_curves/affine_point.h" +#include "tachyon/zk/plonk/halo2/constants.h" -namespace tachyon::crypto { - -// Prefix to a prover's message soliciting a challenge -constexpr uint8_t kBlake2bPrefixChallenge[1] = {0}; - -// Prefix to a prover's message containing a curve point -constexpr uint8_t kBlake2bPrefixPoint[1] = {1}; - -// Prefix to a prover's message containing a scalar -constexpr uint8_t kBlake2bPrefixScalar[1] = {2}; +namespace tachyon::zk::halo2 { // 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 TranscriptReader> { +template +class Blake2bReader : public crypto::TranscriptReader { public: - using AffinePointTy = typename Curve::AffinePointTy; - using BaseField = typename Curve::BaseField; - using ScalarField = typename Curve::ScalarField; + using BaseField = typename AffinePointTy::BaseField; + using ScalarField = typename AffinePointTy::ScalarField; Blake2bReader() = default; // Initialize a transcript given an input buffer. explicit Blake2bReader(base::Buffer read_buf) - : TranscriptReader(std::move(read_buf)) { - BLAKE2B512_Init(&state_); - } - // Initialize a transcript given an input buffer and |personal|. - explicit Blake2bReader(base::Buffer read_buf, std::string_view personal) - : TranscriptReader(std::move(read_buf)) { - BLAKE2B512_InitWithPersonal(&state_, personal.data()); + : crypto::TranscriptReader(std::move(read_buf)) { + BLAKE2B512_InitWithPersonal(&state_, kTranscriptStr); } - // Transcript methods - Challenge255 SqueezeChallenge() override { + // crypto::TranscriptReader methods + ScalarField SqueezeChallenge() override { BLAKE2B512_Update(&state_, kBlake2bPrefixChallenge, 1); BLAKE2B_CTX hasher = state_; uint8_t result[64] = {0}; BLAKE2B512_Final(result, &hasher); - return Challenge255( - ScalarField::FromAnySizedBigInt(math::BigInt<8>::FromBytesLE(result))); + return ScalarField::FromAnySizedBigInt( + math::BigInt<8>::FromBytesLE(result)); } bool WriteToTranscript(const AffinePointTy& point) override { @@ -88,33 +71,27 @@ class Blake2bReader : public TranscriptReader> { BLAKE2B_CTX state_; }; -template -class Blake2bWriter : public TranscriptWriter> { +template +class Blake2bWriter : public crypto::TranscriptWriter { public: - using AffinePointTy = typename Curve::AffinePointTy; - using BaseField = typename Curve::BaseField; - using ScalarField = typename Curve::ScalarField; + using BaseField = typename AffinePointTy::BaseField; + using ScalarField = typename AffinePointTy::ScalarField; Blake2bWriter() = default; // Initialize a transcript given an output buffer. explicit Blake2bWriter(base::VectorBuffer write_buf) - : TranscriptWriter(std::move(write_buf)) { - BLAKE2B512_Init(&state_); - } - // Initialize a transcript given an output buffer and |personal|. - Blake2bWriter(base::VectorBuffer write_buf, std::string_view personal) - : TranscriptWriter(std::move(write_buf)) { - BLAKE2B512_InitWithPersonal(&state_, personal.data()); + : crypto::TranscriptWriter(std::move(write_buf)) { + BLAKE2B512_InitWithPersonal(&state_, kTranscriptStr); } - // Transcript methods - Challenge255 SqueezeChallenge() override { + // crypto::TranscriptWriter methods + ScalarField SqueezeChallenge() override { BLAKE2B512_Update(&state_, kBlake2bPrefixChallenge, 1); BLAKE2B_CTX hasher = state_; uint8_t result[64] = {0}; BLAKE2B512_Final(result, &hasher); - return Challenge255( - ScalarField::FromAnySizedBigInt(math::BigInt<8>::FromBytesLE(result))); + return ScalarField::FromAnySizedBigInt( + math::BigInt<8>::FromBytesLE(result)); } bool WriteToTranscript(const AffinePointTy& point) override { @@ -145,6 +122,6 @@ class Blake2bWriter : public TranscriptWriter> { BLAKE2B_CTX state_; }; -} // namespace tachyon::crypto +} // namespace tachyon::zk::halo2 -#endif // TACHYON_CRYPTO_TRANSCRIPTS_BLAKE2B_TRANSCRIPT_H_ +#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 new file mode 100644 index 000000000..6f223958a --- /dev/null +++ b/tachyon/zk/plonk/halo2/blake2b_transcript_unittest.cc @@ -0,0 +1,74 @@ +// Copyright 2020-2022 The Electric Coin Company +// Copyright 2022 The Halo2 developers +// Use of this source code is governed by a MIT/Apache-2.0 style license that +// can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 +// file. + +#include "tachyon/zk/plonk/halo2/blake2b_transcript.h" + +#include +#include + +#include "gtest/gtest.h" + +#include "tachyon/math/elliptic_curves/bn/bn254/g1.h" + +namespace tachyon::zk::halo2 { + +namespace { + +using namespace math::bn254; + +class Blake2bTranscriptTest : public testing::Test { + public: + static void SetUpTestSuite() { G1Curve::Init(); } +}; + +} // namespace + +TEST_F(Blake2bTranscriptTest, WritePoint) { + base::VectorBuffer 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)); + G1AffinePoint actual; + ASSERT_TRUE(reader.ReadFromProof(&actual)); + + EXPECT_EQ(expected, actual); +} + +TEST_F(Blake2bTranscriptTest, WriteScalar) { + base::VectorBuffer 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)); + Fr actual; + ASSERT_TRUE(reader.ReadFromProof(&actual)); + + EXPECT_EQ(expected, actual); +} + +TEST_F(Blake2bTranscriptTest, SqueezeChallenge) { + base::VectorBuffer write_buf; + Blake2bWriter writer(std::move(write_buf)); + G1AffinePoint generator = G1AffinePoint::Generator(); + ASSERT_TRUE(writer.WriteToProof(generator)); + + std::vector expected_bytes = {57, 2, 118, 182, 16, 184, 59, 179, + 70, 176, 223, 71, 62, 168, 222, 171, + 85, 224, 83, 43, 148, 194, 132, 184, + 65, 25, 1, 208, 123, 166, 11, 12}; + Fr expected = Fr::FromBigInt(math::BigInt<4>::FromBytesLE(expected_bytes)); + + Fr actual = writer.SqueezeChallenge(); + + EXPECT_EQ(expected, actual); +} + +} // namespace tachyon::zk::halo2 diff --git a/tachyon/zk/plonk/halo2/constants.h b/tachyon/zk/plonk/halo2/constants.h index 3fbe85269..78e26e5bb 100644 --- a/tachyon/zk/plonk/halo2/constants.h +++ b/tachyon/zk/plonk/halo2/constants.h @@ -1,9 +1,33 @@ #ifndef TACHYON_ZK_PLONK_HALO2_CONSTANTS_H_ #define TACHYON_ZK_PLONK_HALO2_CONSTANTS_H_ +#include + namespace tachyon::zk::halo2 { constexpr char kTranscriptStr[] = "Halo2-Transcript"; + +// Prefix to a prover's message soliciting a challenge +constexpr uint8_t kBlake2bPrefixChallenge[1] = {0}; + +// Prefix to a prover's message containing a curve point +constexpr uint8_t kBlake2bPrefixPoint[1] = {1}; + +// Prefix to a prover's message containing a scalar +constexpr uint8_t kBlake2bPrefixScalar[1] = {2}; + +// Dummy zeros that come before prefix to a prover's message +constexpr uint8_t kShaPrefixZeros[31] = {0}; + +// Prefix to a prover's message soliciting a challenge +constexpr uint8_t kShaPrefixChallenge[1] = {0}; + +// Prefix to a prover's message containing a curve point +constexpr uint8_t kShaPrefixPoint[1] = {1}; + +// Prefix to a prover's message containing a scalar +constexpr uint8_t kShaPrefixScalar[1] = {2}; + constexpr char kVerifyingKeyStr[] = "Halo2-Verify-Key"; } // namespace tachyon::zk::halo2 diff --git a/tachyon/crypto/hashes/sponge/poseidon/halo2_poseidon.h b/tachyon/zk/plonk/halo2/poseidon_sponge.h similarity index 66% rename from tachyon/crypto/hashes/sponge/poseidon/halo2_poseidon.h rename to tachyon/zk/plonk/halo2/poseidon_sponge.h index a8b280d99..1ac825ee1 100644 --- a/tachyon/crypto/hashes/sponge/poseidon/halo2_poseidon.h +++ b/tachyon/zk/plonk/halo2/poseidon_sponge.h @@ -4,8 +4,8 @@ // can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 // file. -#ifndef TACHYON_CRYPTO_HASHES_SPONGE_POSEIDON_HALO2_POSEIDON_H_ -#define TACHYON_CRYPTO_HASHES_SPONGE_POSEIDON_HALO2_POSEIDON_H_ +#ifndef TACHYON_ZK_PLONK_HALO2_POSEIDON_SPONGE_H_ +#define TACHYON_ZK_PLONK_HALO2_POSEIDON_SPONGE_H_ #include @@ -13,15 +13,13 @@ #include "tachyon/crypto/hashes/sponge/poseidon/poseidon.h" -namespace tachyon::crypto { +namespace tachyon::zk::halo2 { -template -struct Halo2PoseidonSponge : public PoseidonSponge { - using F = PrimeFieldTy; - - Halo2PoseidonSponge() = default; - explicit Halo2PoseidonSponge(const PoseidonConfig& config) - : PoseidonSponge(config) { +template +struct PoseidonSponge : public crypto::PoseidonSponge { + PoseidonSponge() = default; + explicit PoseidonSponge(const crypto::PoseidonConfig& config) + : crypto::PoseidonSponge(config) { this->state.elements[0] = F::FromMpzClass(mpz_class(1) << 64); } @@ -34,12 +32,12 @@ struct Halo2PoseidonSponge : public PoseidonSponge { } this->state[squeeze_index + 1] = F::One(); switch (this->state.mode.type) { - case DuplexSpongeMode::Type::kAbsorbing: { + case crypto::DuplexSpongeMode::Type::kAbsorbing: { this->Permute(); this->SqueezeInternal(0, &ret); return ret; } - case DuplexSpongeMode::Type::kSqueezing: { + case crypto::DuplexSpongeMode::Type::kSqueezing: { size_t squeeze_index = this->state.mode.next_index; if (squeeze_index == this->config.rate) { this->Permute(); @@ -54,6 +52,6 @@ struct Halo2PoseidonSponge : public PoseidonSponge { } }; -} // namespace tachyon::crypto +} // namespace tachyon::zk::halo2 -#endif // TACHYON_CRYPTO_HASHES_SPONGE_POSEIDON_HALO2_POSEIDON_H_ +#endif // TACHYON_ZK_PLONK_HALO2_POSEIDON_SPONGE_H_ diff --git a/tachyon/crypto/transcripts/poseidon_transcript.h b/tachyon/zk/plonk/halo2/poseidon_transcript.h similarity index 51% rename from tachyon/crypto/transcripts/poseidon_transcript.h rename to tachyon/zk/plonk/halo2/poseidon_transcript.h index 6d8f20f6d..1027a4231 100644 --- a/tachyon/crypto/transcripts/poseidon_transcript.h +++ b/tachyon/zk/plonk/halo2/poseidon_transcript.h @@ -4,35 +4,34 @@ // can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 // file. -#ifndef TACHYON_CRYPTO_TRANSCRIPTS_POSEIDON_TRANSCRIPT_H_ -#define TACHYON_CRYPTO_TRANSCRIPTS_POSEIDON_TRANSCRIPT_H_ +#ifndef TACHYON_ZK_PLONK_HALO2_POSEIDON_TRANSCRIPT_H_ +#define TACHYON_ZK_PLONK_HALO2_POSEIDON_TRANSCRIPT_H_ #include #include -#include "tachyon/crypto/hashes/sponge/poseidon/halo2_poseidon.h" #include "tachyon/crypto/transcripts/transcript.h" -#include "tachyon/math/elliptic_curves/affine_point.h" +#include "tachyon/zk/plonk/halo2/poseidon_sponge.h" -namespace tachyon::crypto { +namespace tachyon::zk::halo2 { -template -class PoseidonReader : public TranscriptReader> { +template +class PoseidonReader : public crypto::TranscriptReader { public: - using AffinePointTy = typename Curve::AffinePointTy; - using ScalarField = typename Curve::ScalarField; + using ScalarField = typename AffinePointTy::ScalarField; + using Curve = typename AffinePointTy::Curve; using CurveConfig = typename Curve::Config; PoseidonReader() = default; // Initialize a transcript given an input buffer. explicit PoseidonReader(base::Buffer buffer) - : TranscriptReader(std::move(buffer)), + : crypto::TranscriptReader(std::move(buffer)), state_(crypto::PoseidonConfig::CreateCustom(8, 5, 8, 63, 0)) {} - // Transcript methods - Challenge255 SqueezeChallenge() override { - return Challenge255(state_.SqueezeNativeFieldElements(1)[0]); + // crypto::TranscriptReader methods + ScalarField SqueezeChallenge() override { + return state_.SqueezeNativeFieldElements(1)[0]; } bool WriteToTranscript(const AffinePointTy& point) override { @@ -41,31 +40,31 @@ class PoseidonReader : public TranscriptReader> { return state_.Absorb(coords); } - bool WriteToTranscript(const ScalarField& scalar) override { - return state_.Absorb(scalar); + bool WriteToTranscript(const ScalarField& value) override { + return state_.Absorb(value); } private: - crypto::Halo2PoseidonSponge state_; + PoseidonSponge state_; }; -template -class PoseidonWriter : public TranscriptWriter> { +template +class PoseidonWriter : public crypto::TranscriptWriter { public: - using AffinePointTy = typename Curve::AffinePointTy; - using ScalarField = typename Curve::ScalarField; + using ScalarField = typename AffinePointTy::ScalarField; + using Curve = typename AffinePointTy::Curve; using CurveConfig = typename Curve::Config; PoseidonWriter() = default; // Initialize a transcript given an output buffer. explicit PoseidonWriter(base::VectorBuffer buffer) - : TranscriptWriter(std::move(buffer)), + : crypto::TranscriptWriter(std::move(buffer)), state_(crypto::PoseidonConfig::CreateCustom(8, 5, 8, 63, 0)) {} - // Transcript methods - Challenge255 SqueezeChallenge() override { - return Challenge255(state_.SqueezeNativeFieldElements(1)[0]); + // crypto::TranscriptWriter methods + ScalarField SqueezeChallenge() override { + return state_.SqueezeNativeFieldElements(1)[0]; } bool WriteToTranscript(const AffinePointTy& point) override { @@ -74,14 +73,14 @@ class PoseidonWriter : public TranscriptWriter> { return state_.Absorb(coords); } - bool WriteToTranscript(const ScalarField& scalar) override { - return state_.Absorb(scalar); + bool WriteToTranscript(const ScalarField& value) override { + return state_.Absorb(value); } private: - crypto::Halo2PoseidonSponge state_; + PoseidonSponge state_; }; -} // namespace tachyon::crypto +} // namespace tachyon::zk::halo2 -#endif // TACHYON_CRYPTO_TRANSCRIPTS_POSEIDON_TRANSCRIPT_H_ +#endif // TACHYON_ZK_PLONK_HALO2_POSEIDON_TRANSCRIPT_H_ diff --git a/tachyon/crypto/transcripts/poseidon_transcript_unittest.cc b/tachyon/zk/plonk/halo2/poseidon_transcript_unittest.cc similarity index 56% rename from tachyon/crypto/transcripts/poseidon_transcript_unittest.cc rename to tachyon/zk/plonk/halo2/poseidon_transcript_unittest.cc index b0d048b71..bec390110 100644 --- a/tachyon/crypto/transcripts/poseidon_transcript_unittest.cc +++ b/tachyon/zk/plonk/halo2/poseidon_transcript_unittest.cc @@ -4,7 +4,7 @@ // can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 // file. -#include "tachyon/crypto/transcripts/poseidon_transcript.h" +#include "tachyon/zk/plonk/halo2/poseidon_transcript.h" #include #include @@ -13,67 +13,62 @@ #include "tachyon/math/elliptic_curves/bn/bn254/g1.h" -namespace tachyon::crypto { +namespace tachyon::zk::halo2 { namespace { +using namespace math::bn254; + class PoseidonTranscriptTest : public testing::Test { public: - static void SetUpTestSuite() { math::bn254::G1Curve::Init(); } + static void SetUpTestSuite() { G1Curve::Init(); } }; } // namespace TEST_F(PoseidonTranscriptTest, WritePoint) { - using Curve = math::bn254::G1Curve; - base::VectorBuffer write_buf; - PoseidonWriter writer(std::move(write_buf)); - Curve::AffinePointTy expected = Curve::AffinePointTy::Random(); + 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)); - Curve::AffinePointTy actual; - ASSERT_TRUE(reader.ReadPoint(&actual)); + PoseidonReader reader(std::move(read_buf)); + G1AffinePoint actual; + ASSERT_TRUE(reader.ReadFromProof(&actual)); EXPECT_EQ(expected, actual); } TEST_F(PoseidonTranscriptTest, WriteScalar) { - using Curve = math::bn254::G1Curve; - base::VectorBuffer write_buf; - PoseidonWriter writer(std::move(write_buf)); - Curve::ScalarField expected = Curve::ScalarField::Random(); + 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)); - Curve::ScalarField actual; - ASSERT_TRUE(reader.ReadScalar(&actual)); + PoseidonReader reader(std::move(read_buf)); + Fr actual; + ASSERT_TRUE(reader.ReadFromProof(&actual)); EXPECT_EQ(expected, actual); } TEST_F(PoseidonTranscriptTest, SqueezeChallenge) { - using Curve = math::bn254::G1Curve; - base::VectorBuffer write_buf; - PoseidonWriter writer(std::move(write_buf)); - Curve::AffinePointTy generator = Curve::AffinePointTy::Generator(); + PoseidonWriter writer(std::move(write_buf)); + G1AffinePoint generator = G1AffinePoint::Generator(); ASSERT_TRUE(writer.WriteToProof(generator)); std::vector expected_bytes = {25, 86, 205, 219, 59, 135, 187, 231, 192, 54, 23, 138, 114, 176, 9, 157, 1, 97, 110, 174, 67, 9, 89, 85, 126, 129, 216, 121, 53, 99, 227, 26}; - Curve::ScalarField expected = Curve::ScalarField::FromBigInt( - math::BigInt<4>::FromBytesLE(expected_bytes)); + Fr expected = Fr::FromBigInt(math::BigInt<4>::FromBytesLE(expected_bytes)); - Curve::ScalarField actual = writer.SqueezeChallenge().ChallengeAsScalar(); + Fr actual = writer.SqueezeChallenge(); EXPECT_EQ(expected, actual); } -} // namespace tachyon::crypto +} // namespace tachyon::zk::halo2 diff --git a/tachyon/zk/plonk/halo2/prover_test.h b/tachyon/zk/plonk/halo2/prover_test.h index 15df8160d..417cb600c 100644 --- a/tachyon/zk/plonk/halo2/prover_test.h +++ b/tachyon/zk/plonk/halo2/prover_test.h @@ -6,12 +6,11 @@ #include "gtest/gtest.h" -#include "tachyon/crypto/transcripts/blake2b_transcript.h" #include "tachyon/math/elliptic_curves/bn/bn254/g1.h" #include "tachyon/math/elliptic_curves/bn/bn254/g2.h" #include "tachyon/math/polynomials/univariate/univariate_evaluation_domain_factory.h" #include "tachyon/zk/base/commitments/shplonk_extension.h" -#include "tachyon/zk/plonk/halo2/constants.h" +#include "tachyon/zk/plonk/halo2/blake2b_transcript.h" #include "tachyon/zk/plonk/halo2/prover.h" namespace tachyon::zk::halo2 { @@ -42,9 +41,8 @@ class ProverTest : public testing::Test { ASSERT_TRUE(pcs.UnsafeSetup(kMaxDomainSize)); base::VectorBuffer write_buf; - std::unique_ptr> - writer = std::make_unique>( - std::move(write_buf), kTranscriptStr); + 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, diff --git a/tachyon/crypto/transcripts/sha256_transcript.h b/tachyon/zk/plonk/halo2/sha256_transcript.h similarity index 60% rename from tachyon/crypto/transcripts/sha256_transcript.h rename to tachyon/zk/plonk/halo2/sha256_transcript.h index 8ba2e4d35..6394abc14 100644 --- a/tachyon/crypto/transcripts/sha256_transcript.h +++ b/tachyon/zk/plonk/halo2/sha256_transcript.h @@ -4,50 +4,35 @@ // can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 // file. -#ifndef TACHYON_CRYPTO_TRANSCRIPTS_SHA256_TRANSCRIPT_H_ -#define TACHYON_CRYPTO_TRANSCRIPTS_SHA256_TRANSCRIPT_H_ +#ifndef TACHYON_ZK_PLONK_HALO2_SHA256_TRANSCRIPT_H_ +#define TACHYON_ZK_PLONK_HALO2_SHA256_TRANSCRIPT_H_ -#include #include #include "openssl/sha.h" -#include "tachyon/base/ranges/algorithm.h" #include "tachyon/base/types/always_false.h" #include "tachyon/crypto/transcripts/transcript.h" #include "tachyon/math/base/big_int.h" -#include "tachyon/math/elliptic_curves/affine_point.h" +#include "tachyon/zk/plonk/halo2/constants.h" -namespace tachyon::crypto { +namespace tachyon::zk::halo2 { -// Dummy zeros that come before prefix to a prover's message -constexpr uint8_t kShaPrefixZeros[31] = {0}; - -// Prefix to a prover's message soliciting a challenge -constexpr uint8_t kShaPrefixChallenge[1] = {0}; - -// Prefix to a prover's message containing a curve point -constexpr uint8_t kShaPrefixPoint[1] = {1}; - -// Prefix to a prover's message containing a scalar -constexpr uint8_t kShaPrefixScalar[1] = {2}; - -template -class Sha256Reader : public TranscriptReader> { +template +class Sha256Reader : public crypto::TranscriptReader { public: - using AffinePointTy = typename Curve::AffinePointTy; - using BaseField = typename Curve::BaseField; - using ScalarField = typename Curve::ScalarField; + using BaseField = typename AffinePointTy::BaseField; + using ScalarField = typename AffinePointTy::ScalarField; Sha256Reader() = default; // Initialize a transcript given an input buffer. explicit Sha256Reader(base::Buffer read_buf) - : TranscriptReader(std::move(read_buf)) { + : crypto::TranscriptReader(std::move(read_buf)) { SHA256_Init(&state_); } - // Transcript methods - Challenge255 SqueezeChallenge() override { + // crypto::TranscriptReader methods + ScalarField SqueezeChallenge() override { SHA256_Update(&state_, kShaPrefixChallenge, 1); SHA256_CTX hasher = state_; uint8_t result[32] = {0}; @@ -57,10 +42,10 @@ class Sha256Reader : public TranscriptReader> { SHA256_Update(&state_, result, 32); if constexpr (ScalarField::N <= 4) { - return Challenge255(ScalarField::FromAnySizedBigInt( - math::BigInt<4>::FromBytesLE(result))); + return ScalarField::FromAnySizedBigInt( + math::BigInt<4>::FromBytesLE(result)); } else { - base::AlwaysFalse(); + base::AlwaysFalse(); } } @@ -86,22 +71,21 @@ class Sha256Reader : public TranscriptReader> { SHA256_CTX state_; }; -template -class Sha256Writer : public TranscriptWriter> { +template +class Sha256Writer : public crypto::TranscriptWriter { public: - using AffinePointTy = typename Curve::AffinePointTy; - using BaseField = typename Curve::BaseField; - using ScalarField = typename Curve::ScalarField; + using BaseField = typename AffinePointTy::BaseField; + using ScalarField = typename AffinePointTy::ScalarField; Sha256Writer() = default; // Initialize a transcript given an output buffer. explicit Sha256Writer(base::VectorBuffer write_buf) - : TranscriptWriter(std::move(write_buf)) { + : crypto::TranscriptWriter(std::move(write_buf)) { SHA256_Init(&state_); } - // Transcript methods - Challenge255 SqueezeChallenge() override { + // crypto::TranscriptWriter methods + ScalarField SqueezeChallenge() override { SHA256_Update(&state_, kShaPrefixChallenge, 1); SHA256_CTX hasher = state_; uint8_t result[32] = {0}; @@ -111,10 +95,10 @@ class Sha256Writer : public TranscriptWriter> { SHA256_Update(&state_, result, 32); if constexpr (ScalarField::N <= 4) { - return Challenge255(ScalarField::FromAnySizedBigInt( - math::BigInt<4>::FromBytesLE(result))); + return ScalarField::FromAnySizedBigInt( + math::BigInt<4>::FromBytesLE(result)); } else { - base::AlwaysFalse(); + base::AlwaysFalse(); } } @@ -140,6 +124,6 @@ class Sha256Writer : public TranscriptWriter> { SHA256_CTX state_; }; -} // namespace tachyon::crypto +} // namespace tachyon::zk::halo2 -#endif // TACHYON_CRYPTO_TRANSCRIPTS_SHA256_TRANSCRIPT_H_ +#endif // TACHYON_ZK_PLONK_HALO2_SHA256_TRANSCRIPT_H_ diff --git a/tachyon/crypto/transcripts/sha256_transcript_unittest.cc b/tachyon/zk/plonk/halo2/sha256_transcript_unittest.cc similarity index 56% rename from tachyon/crypto/transcripts/sha256_transcript_unittest.cc rename to tachyon/zk/plonk/halo2/sha256_transcript_unittest.cc index a76074e1a..1ae491ef9 100644 --- a/tachyon/crypto/transcripts/sha256_transcript_unittest.cc +++ b/tachyon/zk/plonk/halo2/sha256_transcript_unittest.cc @@ -4,7 +4,7 @@ // can be found in the LICENSE-MIT.halo2 and the LICENCE-APACHE.halo2 // file. -#include "tachyon/crypto/transcripts/sha256_transcript.h" +#include "tachyon/zk/plonk/halo2/sha256_transcript.h" #include #include @@ -13,67 +13,62 @@ #include "tachyon/math/elliptic_curves/bn/bn254/g1.h" -namespace tachyon::crypto { +namespace tachyon::zk::halo2 { namespace { +using namespace math::bn254; + class Sha256TranscriptTest : public testing::Test { public: - static void SetUpTestSuite() { math::bn254::G1Curve::Init(); } + static void SetUpTestSuite() { G1Curve::Init(); } }; } // namespace TEST_F(Sha256TranscriptTest, WritePoint) { - using Curve = math::bn254::G1Curve; - base::VectorBuffer write_buf; - Sha256Writer writer(std::move(write_buf)); - Curve::AffinePointTy expected = Curve::AffinePointTy::Random(); + 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)); - Curve::AffinePointTy actual; - ASSERT_TRUE(reader.ReadPoint(&actual)); + Sha256Reader reader(std::move(read_buf)); + G1AffinePoint actual; + ASSERT_TRUE(reader.ReadFromProof(&actual)); EXPECT_EQ(expected, actual); } TEST_F(Sha256TranscriptTest, WriteScalar) { - using Curve = math::bn254::G1Curve; - base::VectorBuffer write_buf; - Sha256Writer writer(std::move(write_buf)); - Curve::ScalarField expected = Curve::ScalarField::Random(); + 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)); - Curve::ScalarField actual; - ASSERT_TRUE(reader.ReadScalar(&actual)); + Sha256Reader reader(std::move(read_buf)); + Fr actual; + ASSERT_TRUE(reader.ReadFromProof(&actual)); EXPECT_EQ(expected, actual); } TEST_F(Sha256TranscriptTest, SqueezeChallenge) { - using Curve = math::bn254::G1Curve; - base::VectorBuffer write_buf; - Sha256Writer writer(std::move(write_buf)); - Curve::AffinePointTy generator = Curve::AffinePointTy::Generator(); + Sha256Writer writer(std::move(write_buf)); + G1AffinePoint generator = G1AffinePoint::Generator(); ASSERT_TRUE(writer.WriteToProof(generator)); std::vector expected_bytes = {144, 70, 170, 43, 125, 191, 116, 100, 115, 242, 37, 247, 43, 227, 23, 192, 153, 176, 105, 131, 142, 165, 91, 3, 218, 85, 31, 89, 176, 94, 171, 5}; - Curve::ScalarField expected = Curve::ScalarField::FromBigInt( - math::BigInt<4>::FromBytesLE(expected_bytes)); + Fr expected = Fr::FromBigInt(math::BigInt<4>::FromBytesLE(expected_bytes)); - Curve::ScalarField actual = writer.SqueezeChallenge().ChallengeAsScalar(); + Fr actual = writer.SqueezeChallenge(); EXPECT_EQ(expected, actual); } -} // namespace tachyon::crypto +} // namespace tachyon::zk::halo2 diff --git a/tachyon/zk/plonk/prover/synthesizer.h b/tachyon/zk/plonk/prover/synthesizer.h index c144db7e1..3dd37ccec 100644 --- a/tachyon/zk/plonk/prover/synthesizer.h +++ b/tachyon/zk/plonk/prover/synthesizer.h @@ -121,8 +121,8 @@ class Synthesizer { const std::vector& phases = constraint_system_->challenge_phases(); for (size_t i = 0; i < phases.size(); ++i) { if (phase == phases[i]) { - auto it = challenges_.try_emplace( - i, prover->GetWriter()->SqueezeChallengeAsScalar()); + auto it = + challenges_.try_emplace(i, prover->GetWriter()->SqueezeChallenge()); CHECK(it.second); } } diff --git a/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h b/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h index 81b920546..dde3d70c3 100644 --- a/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h +++ b/tachyon/zk/plonk/vanishing/prover_vanishing_argument.h @@ -107,9 +107,8 @@ template template [[nodiscard]] bool CommitRandomEval( const PCSTy& pcs, - VanishingConstructed&& constructed, - const crypto::Challenge255& x, const F& x_n, - crypto::TranscriptWriter* writer, + VanishingConstructed&& constructed, const F& x, + const F& x_n, crypto::TranscriptWriter* writer, VanishingEvaluated* evaluated_out) { using Poly = typename PCSTy::Poly; using Coeffs = typename Poly::Coefficients; @@ -120,7 +119,7 @@ template VanishingCommitted committed = std::move(constructed).TakeCommitted(); - F random_eval = committed.random_poly().Evaluate(x.ChallengeAsScalar()); + F random_eval = committed.random_poly().Evaluate(x); if (!writer->WriteToProof(random_eval)) return false; *evaluated_out = {std::move(h_poly), std::move(h_blind), @@ -130,20 +129,17 @@ template template std::vector> OpenVanishingArgument( - VanishingEvaluated&& evaluated, - const crypto::Challenge255& x) { + VanishingEvaluated&& evaluated, const F& x) { using Poly = typename PCSTy::Poly; - F x_scalar = x.ChallengeAsScalar(); VanishingCommitted&& committed = std::move(evaluated).TakeCommitted(); - return { - {x_scalar, BlindedPolynomial(std::move(evaluated).TakeHPoly(), - std::move(evaluated).TakeHBlind()) - .ToRef()}, - {x_scalar, BlindedPolynomial(std::move(committed).TakeRandomPoly(), - std::move(committed).TakeRandomBlind()) - .ToRef()}}; + return {{x, BlindedPolynomial(std::move(evaluated).TakeHPoly(), + std::move(evaluated).TakeHBlind()) + .ToRef()}, + {x, BlindedPolynomial(std::move(committed).TakeRandomPoly(), + std::move(committed).TakeRandomBlind()) + .ToRef()}}; } } // namespace tachyon::zk diff --git a/tachyon/zk/plonk/vanishing/vanishing_argument_unittest.cc b/tachyon/zk/plonk/vanishing/vanishing_argument_unittest.cc index fe864225d..6427a5d56 100644 --- a/tachyon/zk/plonk/vanishing/vanishing_argument_unittest.cc +++ b/tachyon/zk/plonk/vanishing/vanishing_argument_unittest.cc @@ -35,7 +35,7 @@ TEST_F(VanishingArgumentTest, VanishingArgument) { ASSERT_TRUE(CommitFinalHPoly(prover_.get(), std::move(committed_p), vkey, extended_evals, &constructed_p)); - crypto::Challenge255 x(F::One()); + F x = F::One(); VanishingEvaluated evaluated; ASSERT_TRUE(CommitRandomEval(prover_->pcs(), std::move(constructed_p), x, F::One(), prover_->GetWriter(), &evaluated)); @@ -47,7 +47,7 @@ TEST_F(VanishingArgumentTest, VanishingArgument) { prover_->GetWriter()->buffer().buffer_len()); std::unique_ptr> reader = absl::WrapUnique( - new crypto::Blake2bReader(std::move(read_buf))); + new halo2::Blake2bReader(std::move(read_buf))); std::unique_ptr> verifier = std::make_unique>( @@ -66,7 +66,7 @@ TEST_F(VanishingArgumentTest, VanishingArgument) { ASSERT_TRUE(EvaluateAfterX(std::move(constructed_v), verifier->GetReader(), &partially_evaluated_v)); - crypto::Challenge255 y(F::One()); + F y = F::One(); Evals evals = Evals::One(kMaxDegree); VanishingEvaluated evaluated_v = VerifyVanishingArgument(std::move(partially_evaluated_v), evals, y, F(2)); diff --git a/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h b/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h index e21c5ddb6..8d49ec3e4 100644 --- a/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h +++ b/tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h @@ -28,7 +28,7 @@ template crypto::TranscriptReader* transcript, VanishingCommitted* committed_out) { Commitment c; - if (!transcript->ReadPoint(&c)) return false; + if (!transcript->ReadFromProof(&c)) return false; *committed_out = VanishingCommitted(std::move(c)); return true; @@ -46,7 +46,7 @@ template size_t quotient_poly_degree = vk.constraint_system().ComputeDegree() - 1; h_commitments.resize(quotient_poly_degree); for (Commitment& commitment : h_commitments) { - if (!transcript->ReadPoint(&commitment)) return false; + if (!transcript->ReadFromProof(&commitment)) return false; } *constructed_out = {std::move(h_commitments), @@ -60,7 +60,7 @@ template crypto::TranscriptReader* transcript, VanishingPartiallyEvaluated* partially_evaluated_out) { F random_eval; - if (!transcript->ReadScalar(&random_eval)) return false; + if (!transcript->ReadFromProof(&random_eval)) return false; *partially_evaluated_out = {std::move(constructed).TakeHCommitments(), std::move(constructed).TakeRandomPolyCommitment(), @@ -71,18 +71,17 @@ template template VanishingEvaluated VerifyVanishingArgument( VanishingPartiallyEvaluated&& partially_evaluated, - const Evals& expressions, const crypto::Challenge255& y, const F& x_n) { + const Evals& expressions, const F& y, const F& x_n) { using Commitment = typename PCSTy::Commitment; using AdditiveResultTy = typename math::internal::AdditiveSemigroupTraits::ReturnTy; - F y_scalar = y.ChallengeAsScalar(); - F expected_h_eval = std::accumulate( - expressions.evaluations().begin(), expressions.evaluations().end(), - F::Zero(), [y_scalar](F& h_eval, const F& v) { - h_eval *= y_scalar; - return h_eval += v; - }); + F expected_h_eval = std::accumulate(expressions.evaluations().begin(), + expressions.evaluations().end(), + F::Zero(), [&y](F& h_eval, const F& v) { + h_eval *= y; + return h_eval += v; + }); expected_h_eval /= x_n - F::One(); Commitment h_commitment = @@ -103,16 +102,12 @@ VanishingEvaluated VerifyVanishingArgument( template std::vector> QueryVanishingArgument( - VanishingEvaluated&& evaluated, - const crypto::Challenge255& x) { + VanishingEvaluated&& evaluated, const F& x) { using Commitment = typename PCSTy::Commitment; - F x_scalar = x.ChallengeAsScalar(); - - return {{x_scalar, base::Ref(&evaluated.h_commitment()), + return {{x, base::Ref(&evaluated.h_commitment()), std::move(evaluated).TakeExpectedHEval()}, - {std::move(x_scalar), - base::Ref(&evaluated.random_poly_commitment()), + {x, base::Ref(&evaluated.random_poly_commitment()), std::move(evaluated).TakeRandomEval()}}; }