Skip to content

Commit

Permalink
chore: rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
Al-Kindi-0 committed Aug 27, 2024
1 parent f57cda9 commit fb29cbe
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 137 deletions.
2 changes: 1 addition & 1 deletion air/src/air/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ impl<B: StarkField, P> AirContext<B, P> {
/// Returns the index of the auxiliary column which implements the Lagrange kernel, if any
pub fn lagrange_kernel_aux_column_idx(&self) -> Option<usize> {
if self.logup_gkr_enabled() {
Some(self.trace_info().aux_segment_width() - 1)
Some(self.trace_info().aux_segment_width() - LAGRANGE_KERNEL_OFFSET)
} else {
None
}
Expand Down
5 changes: 5 additions & 0 deletions air/src/air/logup_gkr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ use math::{ExtensionOf, FieldElement, StarkField, ToElements};

use super::EvaluationFrame;

// CONSTANTS
// ===============================================================================================
pub const LAGRANGE_KERNEL_OFFSET: usize = 1;
pub const S_COLUMN_OFFSET: usize = 2;

/// A trait containing the necessary information in order to run the LogUp-GKR protocol of [1].
///
/// The trait contains useful information for running the GKR protocol as well as for implementing
Expand Down
6 changes: 4 additions & 2 deletions air/src/air/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ pub use lagrange::{
};

mod logup_gkr;
pub use logup_gkr::{LogUpGkrEvaluator, LogUpGkrOracle, PhantomLogUpGkrEval, LAGRANGE_KERNEL_OFFSET, S_COLUMN_OFFSET};
pub use logup_gkr::{
LogUpGkrEvaluator, LogUpGkrOracle, PhantomLogUpGkrEval, LAGRANGE_KERNEL_OFFSET, S_COLUMN_OFFSET,
};

mod coefficients;
pub use coefficients::{
Expand Down Expand Up @@ -599,7 +601,7 @@ pub trait Air: Send + Sync {
None
};

let s_col = if self.context().logup_gkr_enabled() {
let s_col_cc = if self.context().logup_gkr_enabled() {
Some(public_coin.draw()?)
} else {
None
Expand Down
3 changes: 2 additions & 1 deletion air/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ pub use air::{
LagrangeConstraintsCompositionCoefficients, LagrangeKernelBoundaryConstraint,
LagrangeKernelConstraints, LagrangeKernelEvaluationFrame, LagrangeKernelRandElements,
LagrangeKernelTransitionConstraints, LogUpGkrEvaluator, LogUpGkrOracle, PhantomLogUpGkrEval,
TraceInfo, TransitionConstraintDegree, TransitionConstraints,
TraceInfo, TransitionConstraintDegree, TransitionConstraints, LAGRANGE_KERNEL_OFFSET,
S_COLUMN_OFFSET,
};
2 changes: 1 addition & 1 deletion prover/src/constraints/evaluator/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ where
&composition_coefficients.boundary,
);

let lagrange_constraints_evaluator = if air.context().logup_gkr_enabled() {
let logup_gkr_constraints_evaluator = if air.context().logup_gkr_enabled() {
let aux_rand_elements =
aux_rand_elements.as_ref().expect("expected aux rand elements to be present");

Expand Down
4 changes: 2 additions & 2 deletions prover/src/constraints/evaluator/logup_gkr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ where

let mut lagrange_frame = LagrangeKernelEvaluationFrame::new_empty();

let evaluator = self.air.get_logup_gkr_evaluator::<E>();
let evaluator = self.air.get_logup_gkr_evaluator::<E::BaseField>();
let s_col_constraint_divisor =
compute_s_col_divisor::<E>(domain.ce_domain_size(), domain, self.air.trace_length());
let s_col_idx = trace.trace_info().aux_segment_width() - S_COLUMN_OFFSET;
let l_col_idx = trace.trace_info().aux_segment_width() - LAGRANGE_KERNEL_OFFSET;
let mut main_frame = EvaluationFrame::new(trace.trace_info().main_trace_width());
let mut main_frame = EvaluationFrame::new(trace.trace_info().main_segment_width());
let mut aux_frame = EvaluationFrame::new(trace.trace_info().aux_segment_width());

let c = self.gkr_data.compute_batched_claim();
Expand Down
3 changes: 0 additions & 3 deletions sumcheck/src/prover/high_degree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ use crate::{
MultiLinearPoly, RoundProof, SumCheckProof, SumCheckRoundClaim,
};

#[cfg(feature = "concurrent")]
pub use rayon::prelude::*;

/// A sum-check prover for the input layer which can accommodate non-linear expressions in
/// the numerators of the LogUp relation.
///
Expand Down
216 changes: 216 additions & 0 deletions sumcheck/src/prover/plain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

use crypto::{ElementHasher, RandomCoin};
use math::FieldElement;
#[cfg(feature = "concurrent")]
pub use rayon::prelude::*;
use smallvec::smallvec;

use super::SumCheckProverError;
use crate::{
comb_func, CompressedUnivariatePolyEvals, FinalOpeningClaim, MultiLinearPoly, RoundProof,
SumCheckProof,
};

/// Sum-check prover for non-linear multivariate polynomial of the simple LogUp-GKR.
///
/// More specifically, the following function implements the logic of the sum-check prover as
/// described in Section 3.2 in [1], that is, given verifier challenges , the following implements
/// the sum-check prover for the following two statements
/// $$
/// p_{\nu - \kappa}\left(v_{\kappa+1}, \cdots, v_{\nu}\right) = \sum_{w_i}
/// EQ\left(\left(v_{\kappa+1}, \cdots, v_{\nu}\right), \left(w_{\kappa+1}, \cdots,
/// w_{\nu}\right)\right) \cdot
/// \left( p_{\nu-\kappa+1}\left(1, w_{\kappa+1}, \cdots, w_{\nu}\right) \cdot
/// q_{\nu-\kappa+1}\left(0, w_{\kappa+1}, \cdots, w_{\nu}\right) +
/// p_{\nu-\kappa+1}\left(0, w_{\kappa+1}, \cdots, w_{\nu}\right) \cdot
/// q_{\nu-\kappa+1}\left(1, w_{\kappa+1}, \cdots, w_{\nu}\right)\right)
/// $$
///
/// and
///
/// $$
/// q_{\nu -k}\left(v_{\kappa+1}, \cdots, v_{\nu}\right) = \sum_{w_i}EQ\left(\left(v_{\kappa+1},
/// \cdots, v_{\nu}\right), \left(w_{\kappa+1}, \cdots, w_{\nu }\right)\right) \cdot
/// \left( q_{\nu-\kappa+1}\left(1, w_{\kappa+1}, \cdots, w_{\nu}\right) \cdot
/// q_{\nu-\kappa+1}\left(0, w_{\kappa+1}, \cdots, w_{\nu}\right)\right)
/// $$
///
/// for $k = 1, \cdots, \nu - 1$
///
/// Instead of executing two runs of the sum-check protocol, a batching randomness `r_batch` is
/// sent by the verifier at the outset in order to batch the two statments.
///
/// Note that the degree of the non-linear composition polynomial is 3.
///
/// [1]: https://eprint.iacr.org/2023/1284
#[allow(clippy::too_many_arguments)]
pub fn sumcheck_prove_plain<E: FieldElement, H: ElementHasher<BaseField = E::BaseField>>(
mut claim: E,
r_batch: E,
p: MultiLinearPoly<E>,
q: MultiLinearPoly<E>,
eq: &mut MultiLinearPoly<E>,
transcript: &mut impl RandomCoin<Hasher = H, BaseField = E::BaseField>,
) -> Result<SumCheckProof<E>, SumCheckProverError> {
let mut round_proofs = vec![];

let mut challenges = vec![];

// construct the vector of multi-linear polynomials
let (mut p0, mut p1) = p.project_least_significant_variable();
let (mut q0, mut q1) = q.project_least_significant_variable();

for _ in 0..p0.num_variables() {
let len = p0.num_evaluations() / 2;

#[cfg(not(feature = "concurrent"))]
let (round_poly_eval_at_1, round_poly_eval_at_2, round_poly_eval_at_3) = (0..len).fold(
(E::ZERO, E::ZERO, E::ZERO),
|(acc_point_1, acc_point_2, acc_point_3), i| {
let round_poly_eval_at_1 = comb_func(
p0[2 * i + 1],
p1[2 * i + 1],
q0[2 * i + 1],
q1[2 * i + 1],
eq[2 * i + 1],
r_batch,
);

let p0_delta = p0[2 * i + 1] - p0[2 * i];
let p1_delta = p1[2 * i + 1] - p1[2 * i];
let q0_delta = q0[2 * i + 1] - q0[2 * i];
let q1_delta = q1[2 * i + 1] - q1[2 * i];
let eq_delta = eq[2 * i + 1] - eq[2 * i];

let mut p0_eval_at_x = p0[2 * i + 1] + p0_delta;
let mut p1_eval_at_x = p1[2 * i + 1] + p1_delta;
let mut q0_eval_at_x = q0[2 * i + 1] + q0_delta;
let mut q1_eval_at_x = q1[2 * i + 1] + q1_delta;
let mut eq_evx = eq[2 * i + 1] + eq_delta;
let round_poly_eval_at_2 = comb_func(
p0_eval_at_x,
p1_eval_at_x,
q0_eval_at_x,
q1_eval_at_x,
eq_evx,
r_batch,
);

p0_eval_at_x += p0_delta;
p1_eval_at_x += p1_delta;
q0_eval_at_x += q0_delta;
q1_eval_at_x += q1_delta;
eq_evx += eq_delta;
let round_poly_eval_at_3 = comb_func(
p0_eval_at_x,
p1_eval_at_x,
q0_eval_at_x,
q1_eval_at_x,
eq_evx,
r_batch,
);

(
round_poly_eval_at_1 + acc_point_1,
round_poly_eval_at_2 + acc_point_2,
round_poly_eval_at_3 + acc_point_3,
)
},
);

#[cfg(feature = "concurrent")]
let (round_poly_eval_at_1, round_poly_eval_at_2, round_poly_eval_at_3) = (0..len)
.into_par_iter()
.fold(
|| (E::ZERO, E::ZERO, E::ZERO),
|(a, b, c), i| {
let round_poly_eval_at_1 = comb_func(
p0[2 * i + 1],
p1[2 * i + 1],
q0[2 * i + 1],
q1[2 * i + 1],
eq[2 * i + 1],
r_batch,
);

let p0_delta = p0[2 * i + 1] - p0[2 * i];
let p1_delta = p1[2 * i + 1] - p1[2 * i];
let q0_delta = q0[2 * i + 1] - q0[2 * i];
let q1_delta = q1[2 * i + 1] - q1[2 * i];
let eq_delta = eq[2 * i + 1] - eq[2 * i];

let mut p0_eval_at_x = p0[2 * i + 1] + p0_delta;
let mut p1_eval_at_x = p1[2 * i + 1] + p1_delta;
let mut q0_eval_at_x = q0[2 * i + 1] + q0_delta;
let mut q1_eval_at_x = q1[2 * i + 1] + q1_delta;
let mut eq_evx = eq[2 * i + 1] + eq_delta;
let round_poly_eval_at_2 = comb_func(
p0_eval_at_x,
p1_eval_at_x,
q0_eval_at_x,
q1_eval_at_x,
eq_evx,
r_batch,
);

p0_eval_at_x += p0_delta;
p1_eval_at_x += p1_delta;
q0_eval_at_x += q0_delta;
q1_eval_at_x += q1_delta;
eq_evx += eq_delta;
let round_poly_eval_at_3 = comb_func(
p0_eval_at_x,
p1_eval_at_x,
q0_eval_at_x,
q1_eval_at_x,
eq_evx,
r_batch,
);

(round_poly_eval_at_1 + a, round_poly_eval_at_2 + b, round_poly_eval_at_3 + c)
},
)
.reduce(
|| (E::ZERO, E::ZERO, E::ZERO),
|(a0, b0, c0), (a1, b1, c1)| (a0 + a1, b0 + b1, c0 + c1),
);

let evals = smallvec![round_poly_eval_at_1, round_poly_eval_at_2, round_poly_eval_at_3];
let compressed_round_poly_evals = CompressedUnivariatePolyEvals(evals);
let compressed_round_poly = compressed_round_poly_evals.to_poly(claim);

// reseed with the s_i polynomial
transcript.reseed(H::hash_elements(&compressed_round_poly.0));
let round_proof = RoundProof {
round_poly_coefs: compressed_round_poly.clone(),
};

let round_challenge =
transcript.draw().map_err(|_| SumCheckProverError::FailedToGenerateChallenge)?;

// fold each multi-linear using the round challenge
p0.bind_least_significant_variable(round_challenge);
p1.bind_least_significant_variable(round_challenge);
q0.bind_least_significant_variable(round_challenge);
q1.bind_least_significant_variable(round_challenge);
eq.bind_least_significant_variable(round_challenge);

// compute the new reduced round claim
claim = compressed_round_poly.evaluate_using_claim(&claim, &round_challenge);

round_proofs.push(round_proof);
challenges.push(round_challenge);
}

Ok(SumCheckProof {
openings_claim: FinalOpeningClaim {
eval_point: challenges,
openings: vec![p0[0], p1[0], q0[0], q1[0]],
},
round_proofs,
})
}
Loading

0 comments on commit fb29cbe

Please sign in to comment.