Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions kimchi/src/circuits/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1890,16 +1890,18 @@ impl<F: FftField, Column: PartialEq + Copy, ChallengeTerm: Copy>
/// respective values using `evaluate_constants` and will after evaluate the
/// monomials with the corresponding column values using the method
/// `evaluations`.
/// This function always evaluate on D8
pub fn evaluations_d8<
/// This function evaluates on a user defined domain.
pub fn evaluations_with_domain<
'a,
Challenge: Index<ChallengeTerm, Output = F>,
Environment: ColumnEnvironment<'a, F, ChallengeTerm, Challenge, Column = Column>,
>(
&self,
env: &Environment,
domain: Domain,
) -> Evaluations<F, D<F>> {
self.evaluate_constants(env).evaluations_d8(env)
self.evaluate_constants(env)
.evaluations_with_domain(env, domain)
}
}

Expand Down Expand Up @@ -1967,7 +1969,7 @@ impl<F: FftField, Column: Copy> Expr<F, Column> {

/// Helper function to compute the polynomial corresponding
/// to this expression, in evaluation form.
/// Compute the smallest domain or uses D8 depending on compute_domain.
/// Compute the smallest domain or uses the given one depending on domain_opt.
fn evaluations_conditional<
'a,
ChallengeTerm,
Expand All @@ -1976,13 +1978,12 @@ impl<F: FftField, Column: Copy> Expr<F, Column> {
>(
&self,
env: &Environment,
compute_domain: bool,
domain_opt: Option<Domain>,
) -> Evaluations<F, D<F>> {
let mut cache = HashMap::new();
let d = if compute_domain {
self.get_domain(env)
} else {
Domain::D8
let d = match domain_opt {
None => self.get_domain(env),
Some(d) => d,
};
let evals = match self.evaluations_helper(&mut cache, d, env) {
Either::Left(x) => x,
Expand Down Expand Up @@ -2027,6 +2028,8 @@ impl<F: FftField, Column: Copy> Expr<F, Column> {
let deg = self.degree(d1_size, env.get_constants().zk_rows);
if deg <= d1_size {
Domain::D1
} else if deg <= 2 * d1_size {
Domain::D2
} else if deg <= 4 * d1_size {
Domain::D4
} else if deg <= 8 * d1_size {
Expand All @@ -2048,22 +2051,23 @@ impl<F: FftField, Column: Copy> Expr<F, Column> {
&self,
env: &Environment,
) -> Evaluations<F, D<F>> {
self.evaluations_conditional(env, true)
self.evaluations_conditional(env, None)
}

/// Compute the polynomial corresponding
/// to this expression, in evaluation form.
/// Uses D8, regardless of the degree of the expression.
pub fn evaluations_d8<
/// Uses user defined given domain, regardless of the degree of the expression.
pub fn evaluations_with_domain<
'a,
ChallengeTerm,
Challenge: Index<ChallengeTerm, Output = F>,
Environment: ColumnEnvironment<'a, F, ChallengeTerm, Challenge, Column = Column>,
>(
&self,
env: &Environment,
domain: Domain,
) -> Evaluations<F, D<F>> {
self.evaluations_conditional(env, false)
self.evaluations_conditional(env, Some(domain))
}

fn evaluations_helper<
Expand Down
15 changes: 12 additions & 3 deletions kimchi/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,11 @@ where
(perm, bnd)
};

let mut t2 = Evaluations::from_vec_and_domain(
vec![G::ScalarField::zero(); index.cs.domain.d2.size.try_into().unwrap()],
index.cs.domain.d2,
);

{
use crate::circuits::argument::DynArgument;

Expand Down Expand Up @@ -820,7 +825,9 @@ where
{
let constraint = gate.combined_constraints(&all_alphas, &mut cache);
let eval = constraint.evaluations(&env);
if eval.domain().size == t4.domain().size {
if eval.domain().size == t2.domain().size {
t2 += &eval;
} else if eval.domain().size == t4.domain().size {
t4 += &eval;
} else if eval.domain().size == t8.domain().size {
t8 += &eval;
Expand Down Expand Up @@ -848,7 +855,9 @@ where
let mut eval = constraint.evaluations(&env);
eval.evals.par_iter_mut().for_each(|x| *x *= alpha_pow);

if eval.domain().size == t4.domain().size {
if eval.domain().size == t2.domain().size {
t2 += &eval;
} else if eval.domain().size == t4.domain().size {
t4 += &eval;
} else if eval.domain().size == t8.domain().size {
t8 += &eval;
Expand All @@ -864,7 +873,7 @@ where
}

// public polynomial
let mut f = t4.interpolate() + t8.interpolate();
let mut f = t2.interpolate() + t4.interpolate() + t8.interpolate();
f += &public_poly;

// divide contributions with vanishing polynomial
Expand Down
5 changes: 3 additions & 2 deletions o1vm/src/pickles/lookup_columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ pub enum LookupChallengeTerm {
Alpha,
}

#[derive(Clone)]
pub struct LookupChallenges<F> {
pub beta: F,
pub gamma: F,
Expand Down Expand Up @@ -222,9 +223,9 @@ impl<'a, F: FftField> ColumnEnvironment<'a, F, LookupChallengeTerm, LookupChalle
Domain::D8 => self.domain.d8,
}
}
// TODO verify this

fn column_domain(&self, _col: &Self::Column) -> Domain {
Domain::D8
Domain::D4
}
// We do not have constants here
fn get_constants(&self) -> &Constants<F> {
Expand Down
47 changes: 27 additions & 20 deletions o1vm/src/pickles/lookup_prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ark_ff::{One, PrimeField, Zero};
use ark_poly::{univariate::DensePolynomial, Evaluations, Polynomial, Radix2EvaluationDomain};
use kimchi::{
circuits::{
domains::EvaluationDomains,
domains::{Domain, EvaluationDomains},
expr::{l0_1, Constants},
},
curve::KimchiCurve,
Expand Down Expand Up @@ -130,8 +130,6 @@ where
RNG: RngCore + CryptoRng,
{
let LookupProverState { inverses, acc } = state;
// TODO check that
let num_chunk = 8;
let LookupProofInput {
wires,
arity: _,
Expand All @@ -146,6 +144,8 @@ where
acc,
dynamicselectors,
};

////// Commit and squeeze the constraint combiner alpha
//interpolating
let interpolate_col = |evals: Vec<G::ScalarField>| {
Evaluations::<G::ScalarField, Radix2EvaluationDomain<G::ScalarField>>::from_vec_and_domain(
Expand Down Expand Up @@ -173,12 +173,6 @@ where
.collect(),
};

// eval on d8
// TODO: check the degree
// TODO: avoid cloning
let columns_eval_d8 = columns_poly
.clone()
.map(|poly| poly.evaluate_over_domain_by_ref(domain.d8));
// abosrbing commit
// TODO don't absorb the wires which already have been
// TODO avoid cloning
Expand All @@ -190,14 +184,22 @@ where
// Constraints combiner
let alpha: G::ScalarField = fq_sponge.challenge();

////// Compute the quotient polynomial T

// eval on d4
// TODO: avoid cloning
let columns_eval_d4 = columns_poly
.clone()
.map(|poly| poly.evaluate_over_domain_by_ref(domain.d4));
let challenges = LookupChallenges {
alpha,
beta: beta_challenge,
gamma: gamma_challenge,
};

let eval_env = LookupEvalEnvironment {
challenges,
columns: &columns_eval_d8,
columns: &columns_eval_d4,
domain: &domain,
constants: Constants {
endo_coefficient: G::ScalarField::zero(),
Expand All @@ -207,16 +209,21 @@ where

l0_1: l0_1(domain.d1),
};

let (t_numerator_evaluation, _) = constraints.iter().fold(
(
Evaluations::from_vec_and_domain(
vec![G::ScalarField::zero(); domain.d8.size as usize],
domain.d8,
vec![G::ScalarField::zero(); domain.d4.size as usize],
domain.d4,
),
G::ScalarField::one(),
),
// TODO use horner
|(mut acc, alpha_pow), cst| {
acc.add_assign(&cst.evaluations_d8(&eval_env).mul(alpha_pow));
acc.add_assign(
&cst.evaluations_with_domain(&eval_env, Domain::D4)
.mul(alpha_pow),
);
(acc, alpha_pow * alpha)
},
);
Expand All @@ -225,20 +232,18 @@ where
.divide_by_vanishing_poly(domain.d1)
.unwrap();
assert!(rem.is_zero());
let t_commitment = srs.commit_non_hiding(
// TODO: change the nb of chunks later
// For now we use this because the constraints null
&t, num_chunk,
);

//////// Squeeze the evaluation point zeta
// The constraint is of degree 3
let num_chunk = 2;
let t_commitment = srs.commit_non_hiding(&t, num_chunk);
// TODO avoid cloning
let commitments = AllColumns {
cols: columns_com,
quotient_chunks: t_commitment.chunks.clone(),
};
// Absorb t
absorb_commitment(&mut fq_sponge, &t_commitment);
// evaluate and prepare for IPA proof
// TODO check num_chunks and srs length
let t_chunks = t.to_chunked_polynomial(num_chunk, srs.size());
// squeeze zeta
// TODO: understand why we use the endo here and for IPA ,
Expand All @@ -247,6 +252,8 @@ where
let zeta_chal = ScalarChallenge(fq_sponge.challenge());
let zeta: G::ScalarField = zeta_chal.to_field(endo_r);
let zeta_omega = zeta * domain.d1.group_gen;

/////// evaluate create the IPA proof
let eval =
|x,
cols_poly: ColumnEnv<DensePolynomial<_>>,
Expand Down
4 changes: 3 additions & 1 deletion o1vm/src/pickles/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ pub fn cannon_main(args: cli::cannon::RunArgs) {
instruction_set = HashSet::new();
}
}
if curr_proof_inputs.evaluations.instruction_counter.len() < domain_size {
if curr_proof_inputs.evaluations.instruction_counter.len() < domain_size
&& !curr_proof_inputs.evaluations.instruction_counter.is_empty()
{
debug!("Padding witness for proof generation");
pad(&mips_wit_env, &mut curr_proof_inputs, &mut rng);
prove_and_verify(
Expand Down
10 changes: 6 additions & 4 deletions o1vm/src/pickles/multiplicities_columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,9 @@ impl<'a, F: FftField>
Domain::D8 => self.domain.d8,
}
}
// TODO verify this

fn column_domain(&self, _col: &Self::Column) -> Domain {
Domain::D8
Domain::D2
}
// We do not have constants here
fn get_constants(&self) -> &Constants<F> {
Expand Down Expand Up @@ -331,7 +331,7 @@ pub fn get_multiplicities_constraints<F: PrimeField>(
domain: &Radix2EvaluationDomain<F>,
acc_init: F,
acc_final: F,
) -> Vec<EMultiplicities<F>> {
) -> EMultiplicities<F> {
// Constraint the inverse wires
let mut res = inverses_constraint();

Expand Down Expand Up @@ -378,5 +378,7 @@ pub fn get_multiplicities_constraints<F: PrimeField>(
res.push(acc_recursion);
res.push(acc_init);
res.push(acc_final);
res

let alphas = 0..(res.len() as u32);
Expr::combine_constraints(alphas, res)
}
Loading
Loading