Skip to content

Commit

Permalink
batch mul in kzg
Browse files Browse the repository at this point in the history
  • Loading branch information
ledwards2225 committed Aug 28, 2023
1 parent 90c3b19 commit 5012bf8
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class UltraRecursive {
public:
using CircuitBuilder = UltraCircuitBuilder;
using Curve = plonk::stdlib::bn254<CircuitBuilder>;
using PCS = pcs::kzg::KZG<Curve>;
using GroupElement = Curve::Element;
using Commitment = Curve::Element;
using CommitmentHandle = Curve::Element;
Expand Down
34 changes: 21 additions & 13 deletions circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/kzg/kzg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace proof_system::honk::pcs::kzg {

template <typename Curve> class KZG {
template <typename Curve, bool goblin_flag = false> class KZG {
using CK = CommitmentKey<Curve>;
using VK = VerifierCommitmentKey<Curve>;
using Fr = typename Curve::ScalarField;
Expand Down Expand Up @@ -72,31 +72,39 @@ template <typename Curve> class KZG {
*
* @param claim OpeningClaim ({r, v}, C)
* @return {P₀, P₁} where
* - P₀ = C − v⋅[1]₁ + r⋅[x]₁
* - P₁ = [Q(x)]₁
* - P₀ = C − v⋅[1]₁ + r⋅[W(x)]₁
* - P₁ = [W(x)]₁
*/
static std::array<GroupElement, 2> compute_pairing_points(const OpeningClaim<Curve>& claim,
auto& verifier_transcript)
{
auto quotient_commitment = verifier_transcript.template receive_from_prover<Commitment>("KZG:W");

auto lhs = claim.commitment + (quotient_commitment * claim.opening_pair.challenge);
// Add the evaluation point contribution v⋅[1]₁.
GroupElement P_0;
// Note: In the recursive setting, we only add the contribution if it is not the point at infinity (i.e. if the
// evaluation is not equal to zero).
// TODO(luke): What is the proper way to handle this? Contraints to show scalar (evaluation) is zero?
if constexpr (Curve::is_stdlib_type) {
if (!claim.opening_pair.evaluation.get_value().is_zero()) {
auto ctx = verifier_transcript.builder;
lhs -= GroupElement::one(ctx) * claim.opening_pair.evaluation;
}
auto builder = verifier_transcript.builder;
auto one = Fr::from_witness(builder, 1);
std::vector<GroupElement> commitments = { claim.commitment, quotient_commitment };
std::vector<Fr> scalars = { one, claim.opening_pair.challenge };
P_0 = GroupElement::template batch_mul<goblin_flag>(commitments, scalars);
// WORKTODO(luke): The evaluation is always zero due to the nature of shplonk. What is the proper way to
// handle this? Contraints to show scalar (evaluation) is zero? Or simply dont add anything and ensure this
// function is only used in the current context?
// if (!claim.opening_pair.evaluation.get_value().is_zero()) {
// auto ctx = verifier_transcript.builder;
// lhs -= GroupElement::one(ctx) * claim.opening_pair.evaluation;
// }
} else {
lhs -= GroupElement::one() * claim.opening_pair.evaluation;
P_0 = claim.commitment;
P_0 += quotient_commitment * claim.opening_pair.challenge;
P_0 -= GroupElement::one() * claim.opening_pair.evaluation;
}

auto rhs = -quotient_commitment;
auto P_1 = -quotient_commitment;

return { lhs, rhs };
return { P_0, P_1 };
};
};
} // namespace proof_system::honk::pcs::kzg
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ ecc_op_tuple UltraCircuitBuilder_<FF>::queue_ecc_add_accum(const barretenberg::g
*/
template <typename FF>
ecc_op_tuple UltraCircuitBuilder_<FF>::queue_ecc_mul_accum(const barretenberg::g1::affine_element& point,
const barretenberg::fr& scalar)
const barretenberg::fr& scalar)
{
// Add raw op to op queue
op_queue.mul_accumulate(point, scalar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -705,13 +705,12 @@ template <typename FF> class UltraCircuitBuilder_ : public CircuitBuilderBase<ar

/**
* ** Goblin Methods ** (methods for add ecc op queue gates)
* TODO(#705): Consider isolating/modularizing the goblin builder functionality
**/
// WORKTODO: could we turn this into a class somehow? maybe it has a pointer to variables or something? maybe not
ecc_op_tuple queue_ecc_add_accum(const g1::affine_element& point);
ecc_op_tuple queue_ecc_mul_accum(const g1::affine_element& point, const fr& scalar);
ecc_op_tuple queue_ecc_eq();


private:
void populate_ecc_op_wires(const ecc_op_tuple& in);
ecc_op_tuple make_ecc_op_tuple(uint32_t op, const g1::affine_element& point, const fr& scalar = fr::zero());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ std::array<typename Flavor::GroupElement, 2> UltraRecursiveVerifier_<Flavor, gob
using Curve = typename Flavor::Curve;
using Gemini = ::proof_system::honk::pcs::gemini::GeminiVerifier_<Curve, goblin_flag>;
using Shplonk = ::proof_system::honk::pcs::shplonk::ShplonkVerifier_<Curve, goblin_flag>;
using PCS = typename Flavor::PCS; // note: This can only be KZG
using KZG = ::proof_system::honk::pcs::kzg::KZG<Curve, goblin_flag>; // note: This can only be KZG
using VerifierCommitments = typename Flavor::VerifierCommitments;
using CommitmentLabels = typename Flavor::CommitmentLabels;
using RelationParams = ::proof_system::honk::sumcheck::RelationParameters<FF>;

RelationParams relation_parameters;

info("Initial: num gates = ", builder->get_num_gates());
size_t prev_num_gates = builder->get_num_gates();

transcript = Transcript<Builder>{ builder, proof.proof_data };
Expand Down Expand Up @@ -177,7 +178,7 @@ std::array<typename Flavor::GroupElement, 2> UltraRecursiveVerifier_<Flavor, gob
prev_num_gates = builder->get_num_gates();

// Constuct the inputs to the final KZG pairing check
auto pairing_points = PCS::compute_pairing_points(shplonk_claim, transcript);
auto pairing_points = KZG::compute_pairing_points(shplonk_claim, transcript);

info("KZG: num gates = ", builder->get_num_gates() - prev_num_gates);

Expand Down

0 comments on commit 5012bf8

Please sign in to comment.