Skip to content

Commit

Permalink
Show file tree
Hide file tree
Showing 9 changed files with 794 additions and 0 deletions.
78 changes: 78 additions & 0 deletions tachyon/zk/plonk/vanishing/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ tachyon_cc_library(
],
)

tachyon_cc_library(
name = "prover_vanishing_argument",
hdrs = ["prover_vanishing_argument.h"],
deps = [
":vanishing_committed",
":vanishing_constructed",
":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",
],
)

tachyon_cc_library(
name = "value_source",
srcs = ["value_source.cc"],
Expand Down Expand Up @@ -58,6 +74,68 @@ tachyon_cc_library(
],
)

tachyon_cc_library(
name = "vanishing_committed",
hdrs = ["vanishing_committed.h"],
deps = ["//tachyon/zk/base/entities:entity_ty"],
)

tachyon_cc_library(
name = "vanishing_constructed",
hdrs = ["vanishing_constructed.h"],
deps = [
":vanishing_committed",
"//tachyon/zk/base/entities:entity_ty",
],
)

tachyon_cc_library(
name = "vanishing_evaluated",
hdrs = ["vanishing_evaluated.h"],
deps = [
":vanishing_committed",
"//tachyon/zk/base/entities:entity_ty",
],
)

tachyon_cc_library(
name = "vanishing_partially_evaluated",
hdrs = ["vanishing_partially_evaluated.h"],
)

tachyon_cc_library(
name = "vanishing_utils",
hdrs = ["vanishing_utils.h"],
deps = ["//tachyon/base:parallelize"],
)

tachyon_cc_library(
name = "verifier_vanishing_argument",
hdrs = ["verifier_vanishing_argument.h"],
deps = [
":vanishing_committed",
":vanishing_constructed",
":vanishing_evaluated",
":vanishing_partially_evaluated",
"//tachyon/crypto/transcripts:transcript",
"//tachyon/zk/base:verifier_query",
"//tachyon/zk/plonk/keys:verifying_key",
],
)

tachyon_cc_unittest(
name = "vanishing_argument_unittests",
srcs = ["vanishing_argument_unittest.cc"],
deps = [
":prover_vanishing_argument",
":verifier_vanishing_argument",
"//tachyon/zk/base/entities:verifier",
"//tachyon/zk/base/halo2:halo2_prover_test",
"//tachyon/zk/plonk/circuit/examples:simple_circuit",
"//tachyon/zk/plonk/keys/halo2:pinned_verifying_key",
],
)

tachyon_cc_unittest(
name = "vanishing_unittests",
srcs = [
Expand Down
145 changes: 145 additions & 0 deletions tachyon/zk/plonk/vanishing/prover_vanishing_argument.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// 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.

#ifndef TACHYON_ZK_PLONK_VANISHING_PROVER_VANISHING_ARGUMENT_H_
#define TACHYON_ZK_PLONK_VANISHING_PROVER_VANISHING_ARGUMENT_H_

#include <algorithm>
#include <utility>
#include <vector>

#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.h"
#include "tachyon/zk/base/prover_query.h"
#include "tachyon/zk/plonk/vanishing/vanishing_committed.h"
#include "tachyon/zk/plonk/vanishing/vanishing_constructed.h"
#include "tachyon/zk/plonk/vanishing/vanishing_evaluated.h"
#include "tachyon/zk/plonk/vanishing/vanishing_utils.h"

namespace tachyon::zk {

template <typename PCSTy>
[[nodiscard]] bool VanishingCommit(
Prover<PCSTy>* prover, VanishingCommitted<EntityTy::kProver, PCSTy>* out) {
// Sample a random polynomial of degree n - 1
const typename PCSTy::Evals random_eval =
PCSTy::Evals::One(prover->pcs().N());
typename PCSTy::Poly random_poly = prover->domain()->IFFT(random_eval);

// Sample a random blinding factor
// TODO(TomTaehoonKim): Figure out why it is named |random_blind|.
// See
// https://github.com/kroma-network/halo2/blob/7d0a36990452c8e7ebd600de258420781a9b7917/halo2_proofs/src/plonk/vanishing/prover.rs#L55-L56
typename PCSTy::Field random_blind = PCSTy::Field::Zero();

if (!prover->Commit(random_poly)) return false;

*out = {std::move(random_poly), std::move(random_blind)};
return true;
}

template <typename PCSTy, typename ExtendedEvals>
[[nodiscard]] bool VanishingConstruct(
Prover<PCSTy>* prover,
VanishingCommitted<EntityTy::kProver, PCSTy>&& committed,
const ExtendedEvals& linear_combination_of_gates,
VanishingConstructed<EntityTy::kProver, PCSTy>* constructed_out) {
// Divide by t(X) = X^{params.n} - 1.
ExtendedEvals h_evals = DivideByVanishingPoly<typename PCSTy::Field>(
linear_combination_of_gates, prover->extended_domain(), prover->domain());

// Obtain final h(X) polynomial
typename PCSTy::ExtendedPoly h_poly =
ExtendedToCoeff<typename PCSTy::Field, typename PCSTy::ExtendedPoly>(
h_evals, prover->extended_domain());

// Truncate it to match the size of the quotient polynomial; the
// evaluation domain might be slightly larger than necessary because
// it always lies on a power-of-two boundary.
std::vector<typename PCSTy::Field> h_coeffs =
h_poly.coefficients().coefficients();
h_coeffs.resize(prover->extended_domain()->size(), PCSTy::Field::Zero());

// Compute commitments to each h(X) piece
const size_t kCommitmentNum = h_coeffs.size() / prover->pcs().N();

std::vector<bool> results = base::ParallelizeMapByChunkSize(
h_coeffs, prover->pcs().N(),
[prover](absl::Span<const typename PCSTy::Field> h_piece,
size_t chunk_index) { return prover->Commit(h_piece); });
if (std::any_of(results.begin(), results.end(),
[](bool result) { return result == false; })) {
return false;
}

// FIXME(TomTaehoonKim): Remove this if possible.
std::vector<typename PCSTy::Field> h_blinds = base::CreateVector(
kCommitmentNum, [prover]() { return prover->blinder().Generate(); });

*constructed_out = {std::move(h_poly), std::move(h_blinds),
std::move(committed)};
return true;
}

template <typename PCSTy, typename F, typename Commitment>
[[nodiscard]] bool VanishingEvaluate(
const PCSTy& pcs,
VanishingConstructed<EntityTy::kProver, PCSTy>&& constructed,
const crypto::Challenge255<F>& x, const F& x_n,
crypto::TranscriptWriter<Commitment>* writer,
VanishingEvaluated<EntityTy::kProver, PCSTy>* evaluated_out) {
typename PCSTy::Poly h_poly = PCSTy::Poly::Zero();
auto h_chunks = base::Chunked(
constructed.h_poly().coefficients().coefficients(), pcs.N());
auto h_pieces =
base::Map(h_chunks.begin(), h_chunks.end(),
[](const absl::Span<const F>& h_piece) { return h_piece; });
for (absl::Span<const F> h_piece : base::Reversed(h_pieces)) {
std::vector<F> h_vec(h_piece.begin(), h_piece.end());
h_poly = h_poly * x_n +
typename PCSTy::Poly(
typename PCSTy::Poly::Coefficients(std::move(h_vec)));
}

F h_blind = std::accumulate(constructed.h_blinds().rbegin(),
constructed.h_blinds().rend(), F::Zero(),
[&x_n](F& acc, const F& eval) {
acc *= x_n;
return acc + eval;
});

VanishingCommitted<EntityTy::kProver, PCSTy> committed =
std::move(std::move(constructed).TakeCommitted());
F random_eval = committed.random_poly().Evaluate(x.ChallengeAsScalar());
if (!writer->WriteToProof(random_eval)) return false;

*evaluated_out = {std::move(h_poly), std::move(h_blind),
std::move(committed)};
return true;
}

template <typename PCSTy, typename F>
std::vector<ProverQuery<PCSTy>> VanishingOpen(
VanishingEvaluated<EntityTy::kProver, PCSTy>&& evaluated,
const crypto::Challenge255<F>& x) {
F x_scalar = x.ChallengeAsScalar();
VanishingCommitted<EntityTy::kProver, PCSTy>&& committed =
std::move(evaluated).TakeCommitted();
return {{x_scalar, BlindedPolynomial<typename PCSTy::Poly>(
std::move(evaluated).TakeHPoly(),
std::move(evaluated).TakeHBlind())
.ToRef()},
{x_scalar, BlindedPolynomial<typename PCSTy::Poly>(
std::move(committed).TakeRandomPoly(),
std::move(committed).TakeRandomBlind())
.ToRef()}};
}

} // namespace tachyon::zk

#endif // TACHYON_ZK_PLONK_VANISHING_PROVER_VANISHING_ARGUMENT_H_
73 changes: 73 additions & 0 deletions tachyon/zk/plonk/vanishing/vanishing_argument_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// 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 "gtest/gtest.h"

#include "tachyon/zk/base/entities/verifier.h"
#include "tachyon/zk/base/halo2/halo2_prover_test.h"
#include "tachyon/zk/plonk/circuit/examples/simple_circuit.h"
#include "tachyon/zk/plonk/keys/halo2/pinned_verifying_key.h"
#include "tachyon/zk/plonk/vanishing/prover_vanishing_argument.h"
#include "tachyon/zk/plonk/vanishing/verifier_vanishing_argument.h"

namespace tachyon::zk {

namespace {

class VanishingArgumentTest : public Halo2ProverTest {};

} // namespace

TEST_F(VanishingArgumentTest, VanishingArgument) {
VanishingCommitted<EntityTy::kProver, PCS> committed_p;
ASSERT_TRUE(VanishingCommit(prover_.get(), &committed_p));

ExtendedEvals extended_evals = ExtendedEvals::One(kMaxExtendedDegree);
VanishingConstructed<EntityTy::kProver, PCS> constructed_p;
ASSERT_TRUE(VanishingConstruct(prover_.get(), std::move(committed_p),
extended_evals, &constructed_p));

crypto::Challenge255<F> x(F::One());
VanishingEvaluated<EntityTy::kProver, PCS> evaluated;
ASSERT_TRUE(VanishingEvaluate(prover_->pcs(), std::move(constructed_p), x,
F::One(), prover_->GetWriter(), &evaluated));

std::vector<ProverQuery<PCS>> h_x = VanishingOpen(std::move(evaluated), x);

base::Buffer read_buf(prover_->GetWriter()->buffer().buffer(),
prover_->GetWriter()->buffer().buffer_len());
std::unique_ptr<crypto::TranscriptReader<Commitment>> reader =
absl::WrapUnique(
new crypto::PoseidonReader<Commitment::Curve>(std::move(read_buf)));

std::unique_ptr<Verifier<PCS>> verifier = std::make_unique<Verifier<PCS>>(
Verifier<PCS>(prover_->TakePCS(), std::move(reader)));
verifier->set_domain(prover_->TakeDomain());
verifier->set_extended_domain(prover_->TakeExtendedDomain());

VanishingCommitted<EntityTy::kVerifier, PCS> committed_v;
ASSERT_TRUE(ReadCommitmentsBeforeY(verifier->GetReader(), &committed_v));

SimpleCircuit<F> circuit = SimpleCircuit<F>();
VerifyingKey<PCS> vkey;
ASSERT_TRUE(VerifyingKey<PCS>::Generate(verifier.get(), circuit, &vkey));
VanishingConstructed<EntityTy::kVerifier, PCS> constructed_v;
ASSERT_TRUE(ReadCommitmentsAfterY(std::move(committed_v), vkey,
verifier->GetReader(), &constructed_v));

VanishingPartiallyEvaluated<PCS> partially_evaluated_v;
ASSERT_TRUE(EvaluateAfterX<F>(std::move(constructed_v), verifier->GetReader(),
&partially_evaluated_v));

crypto::Challenge255<F> y(F::One());
Evals evals = Evals::One(kMaxDegree);
VanishingEvaluated<EntityTy::kVerifier, PCS> evaluated_v =
VanishingVerify(std::move(partially_evaluated_v), evals, y, F(2));

VanishingQueries(std::move(evaluated_v), x);
}

} // namespace tachyon::zk
58 changes: 58 additions & 0 deletions tachyon/zk/plonk/vanishing/vanishing_committed.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// 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.

#ifndef TACHYON_ZK_PLONK_VANISHING_VANISHING_COMMITTED_H_
#define TACHYON_ZK_PLONK_VANISHING_VANISHING_COMMITTED_H_

#include <utility>

#include "tachyon/zk/base/entities/entity_ty.h"

namespace tachyon::zk {

template <EntityTy EntityType, typename PCSTy>
class VanishingCommitted;

template <typename PCSTy>
class VanishingCommitted<EntityTy::kProver, PCSTy> {
public:
VanishingCommitted() = default;
VanishingCommitted(typename PCSTy::Poly&& random_poly,
typename PCSTy::Field&& random_blind)
: random_poly_(std::move(random_poly)),
random_blind_(std::move(random_blind)) {}

const typename PCSTy::Poly& random_poly() { return random_poly_; }

typename PCSTy::Poly&& TakeRandomPoly() && { return std::move(random_poly_); }
typename PCSTy::Field&& TakeRandomBlind() && {
return std::move(random_blind_);
}

private:
typename PCSTy::Poly random_poly_;
typename PCSTy::Field random_blind_;
};

template <typename PCSTy>
class VanishingCommitted<EntityTy::kVerifier, PCSTy> {
public:
VanishingCommitted() = default;
explicit VanishingCommitted(
typename PCSTy::Commitment&& random_poly_commitment)
: random_poly_commitment_(std::move(random_poly_commitment)) {}

typename PCSTy::Commitment&& TakeRandomPolyCommitment() && {
return std::move(random_poly_commitment_);
}

private:
typename PCSTy::Commitment random_poly_commitment_;
};

} // namespace tachyon::zk

#endif // TACHYON_ZK_PLONK_VANISHING_VANISHING_COMMITTED_H_
Loading

0 comments on commit a0c5983

Please sign in to comment.