Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
21 changes: 9 additions & 12 deletions starky/src/cross_table_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use crate::lookup::{
eval_helper_columns, eval_helper_columns_circuit, get_grand_product_challenge_set,
get_helper_cols, Column, ColumnFilter, Filter, GrandProductChallenge, GrandProductChallengeSet,
};
use crate::proof::{StarkProof, StarkProofTarget};
use crate::proof::{StarkOpeningSet, StarkOpeningSetTarget};
use crate::stark::Stark;

/// An alias for `usize`, to represent the index of a STARK table in a multi-STARK setting.
Expand Down Expand Up @@ -440,9 +440,9 @@ impl<'a, F: RichField + Extendable<D>, const D: usize>
CtlCheckVars<'a, F, F::Extension, F::Extension, D>
{
/// Extracts the `CtlCheckVars` from a single proof.
pub fn from_proof<C: GenericConfig<D, F = F>>(
pub fn from_opening_set<C: GenericConfig<D, F = F>>(
table_idx: TableIdx,
proof: &StarkProof<F, C, D>,
stark_opening_set: &StarkOpeningSet<F, D>,
cross_table_lookups: &'a [CrossTableLookup<F>],
ctl_challenges: &'a GrandProductChallengeSet<F>,
num_lookup_columns: usize,
Expand All @@ -451,13 +451,11 @@ impl<'a, F: RichField + Extendable<D>, const D: usize>
) -> Vec<Self> {
// Get all cross-table lookup polynomial openings for the provided STARK proof.
let ctl_zs = {
let auxiliary_polys = proof
.openings
let auxiliary_polys = stark_opening_set
.auxiliary_polys
.as_ref()
.expect("We cannot have CTLs without auxiliary polynomials.");
let auxiliary_polys_next = proof
.openings
let auxiliary_polys_next = stark_opening_set
.auxiliary_polys_next
.as_ref()
.expect("We cannot have CTLs without auxiliary polynomials.");
Expand Down Expand Up @@ -648,9 +646,9 @@ pub struct CtlCheckVarsTarget<F: Field, const D: usize> {

impl<'a, F: Field, const D: usize> CtlCheckVarsTarget<F, D> {
/// Circuit version of `from_proofs`, for a single STARK.
pub fn from_proof(
pub fn from_opening_set(
table: TableIdx,
proof: &StarkProofTarget<D>,
stark_opening_set: &StarkOpeningSetTarget<D>,
cross_table_lookups: &'a [CrossTableLookup<F>],
ctl_challenges: &'a GrandProductChallengeSet<Target>,
num_lookup_columns: usize,
Expand All @@ -659,14 +657,13 @@ impl<'a, F: Field, const D: usize> CtlCheckVarsTarget<F, D> {
) -> Vec<Self> {
// Get all cross-table lookup polynomial openings for each STARK proof.
let ctl_zs = {
let openings = &proof.openings;
let ctl_zs = openings
let ctl_zs = stark_opening_set
.auxiliary_polys
.as_ref()
.expect("We cannot have CTls without auxiliary polynomials.")
.iter()
.skip(num_lookup_columns);
let ctl_zs_next = openings
let ctl_zs_next = stark_opening_set
.auxiliary_polys_next
.as_ref()
.expect("We cannot have CTls without auxiliary polynomials.")
Expand Down
142 changes: 131 additions & 11 deletions starky/src/get_challenges.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

use plonky2::field::extension::Extendable;
use plonky2::field::polynomial::PolynomialCoeffs;
use plonky2::fri::proof::{FriProof, FriProofTarget};
Expand All @@ -12,11 +15,14 @@ use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};

use crate::config::StarkConfig;
use crate::cross_table_lookup::{CtlCheckVars, CtlCheckVarsTarget};
use crate::lookup::{
get_grand_product_challenge_set, get_grand_product_challenge_set_target,
GrandProductChallengeSet,
};
use crate::proof::*;
use crate::stark::Stark;
use crate::vanishing_poly::{compute_eval_vanishing_poly, compute_eval_vanishing_poly_circuit};

/// Generates challenges for a STARK proof from a challenger and given
/// all the arguments needed to update the challenger state.
Expand All @@ -25,12 +31,16 @@ use crate::proof::*;
/// or not by the challenger. Observing it here could be redundant in a
/// multi-STARK system where trace caps would have already been observed
/// before proving individually each STARK.
fn get_challenges<F, C, const D: usize>(
fn get_challenges<F, C, S: Stark<F, D>, const D: usize>(
stark: &S,
public_inputs: &[F],
challenger: &mut Challenger<F, C::Hasher>,
challenges: Option<&GrandProductChallengeSet<F>>,
trace_cap: Option<&MerkleCap<F, C::Hasher>>,
auxiliary_polys_cap: Option<&MerkleCap<F, C::Hasher>>,
quotient_polys_cap: Option<&MerkleCap<F, C::Hasher>>,
ctl_vars: Option<&[CtlCheckVars<F, F::Extension, F::Extension, D>]>,
poly_evals: &StarkOpeningSet<F, D>,
openings: &StarkOpeningSet<F, D>,
commit_phase_merkle_caps: &[MerkleCap<F, C::Hasher>],
final_poly: &PolynomialCoeffs<F::Extension>,
Expand Down Expand Up @@ -61,6 +71,40 @@ where
challenger.observe_cap(cap);
}

let num_lookup_columns = stark.num_lookup_helper_columns(config);
let lookup_challenges = if stark.uses_lookups() {
Some(
lookup_challenge_set
.as_ref()
.unwrap()
.challenges
.iter()
.map(|ch| ch.beta)
.collect::<Vec<_>>(),
)
} else {
None
};

let stark_alphas_prime = challenger.get_n_challenges(num_challenges);
let zeta_prime = challenger.get_extension_challenge();

// Bind constraints.
let constraints = compute_eval_vanishing_poly::<F, C, S, D>(
stark,
&poly_evals,
ctl_vars,
lookup_challenges.as_ref(),
&stark.lookups(),
public_inputs,
stark_alphas_prime.clone(),
zeta_prime,
degree_bits,
num_lookup_columns,
);

challenger.observe_extension_elements(&constraints);

let stark_alphas = challenger.get_n_challenges(num_challenges);

if let Some(quotient_polys_cap) = quotient_polys_cap {
Expand Down Expand Up @@ -111,10 +155,13 @@ where
/// Multi-STARK systems may already observe individual trace caps
/// ahead of proving each table, and hence may ignore observing
/// again the cap when generating individual challenges.
pub fn get_challenges(
pub fn get_challenges<S: Stark<F, D>>(
&self,
stark: &S,
public_inputs: &[F],
challenger: &mut Challenger<F, C::Hasher>,
challenges: Option<&GrandProductChallengeSet<F>>,
ctl_vars: Option<&[CtlCheckVars<F, F::Extension, F::Extension, D>]>,
ignore_trace_cap: bool,
config: &StarkConfig,
verifier_circuit_fri_params: Option<FriParams>,
Expand All @@ -125,6 +172,7 @@ where
trace_cap,
auxiliary_polys_cap,
quotient_polys_cap,
poly_evals,
openings,
opening_proof:
FriProof {
Expand All @@ -141,12 +189,16 @@ where
Some(trace_cap)
};

get_challenges::<F, C, D>(
get_challenges::<F, C, S, D>(
stark,
public_inputs,
challenger,
challenges,
trace_cap,
auxiliary_polys_cap.as_ref(),
quotient_polys_cap.as_ref(),
ctl_vars,
poly_evals,
openings,
commit_phase_merkle_caps,
final_poly,
Expand All @@ -170,18 +222,23 @@ where
/// Multi-STARK systems may already observe individual trace caps
/// ahead of proving each table, and hence may ignore observing
/// again the cap when generating individual challenges.
pub fn get_challenges(
pub fn get_challenges<S: Stark<F, D>>(
&self,
stark: &S,
challenger: &mut Challenger<F, C::Hasher>,
challenges: Option<&GrandProductChallengeSet<F>>,
ctl_vars: Option<&[CtlCheckVars<F, F::Extension, F::Extension, D>]>,
ignore_trace_cap: bool,
config: &StarkConfig,
verifier_circuit_fri_params: Option<FriParams>,
) -> StarkProofChallenges<F, D> {
challenger.observe_elements(&self.public_inputs);
self.proof.get_challenges(
self.proof.get_challenges::<S>(
stark,
&self.public_inputs,
challenger,
challenges,
ctl_vars,
ignore_trace_cap,
config,
verifier_circuit_fri_params,
Expand All @@ -191,17 +248,23 @@ where

/// Circuit version of `get_challenges`, with the same flexibility around
/// `trace_cap` being passed as an `Option`.
fn get_challenges_target<F, C, const D: usize>(
fn get_challenges_target<F, C, S: Stark<F, D>, const D: usize>(
builder: &mut CircuitBuilder<F, D>,
stark: &S,
public_inputs: &[Target],
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
challenges: Option<&GrandProductChallengeSet<Target>>,
trace_cap: Option<&MerkleCapTarget>,
auxiliary_polys_cap: Option<&MerkleCapTarget>,
quotient_polys_cap: Option<&MerkleCapTarget>,
ctl_vars: Option<&[CtlCheckVarsTarget<F, D>]>,
poly_evals: &StarkOpeningSetTarget<D>,
openings: &StarkOpeningSetTarget<D>,
commit_phase_merkle_caps: &[MerkleCapTarget],
final_poly: &PolynomialCoeffsExtTarget<D>,
pow_witness: Target,
degree_bits: usize,
degree_bits_target: Target,
config: &StarkConfig,
) -> StarkProofChallengesTarget<D>
where
Expand All @@ -227,6 +290,37 @@ where
challenger.observe_cap(cap);
}

let num_lookup_columns = stark.num_lookup_helper_columns(config);
let lookup_challenges = stark.uses_lookups().then(|| {
lookup_challenge_set
.as_ref()
.unwrap()
.challenges
.iter()
.map(|ch| ch.beta)
.collect::<Vec<_>>()
});

let stark_alphas_prime = challenger.get_n_challenges(builder, num_challenges);
let zeta_prime = challenger.get_extension_challenge(builder);

// Bind constraints.
let constraints = compute_eval_vanishing_poly_circuit::<F, S, D>(
builder,
stark,
poly_evals,
ctl_vars,
lookup_challenges.as_ref(),
public_inputs,
stark_alphas_prime.clone(),
zeta_prime,
degree_bits,
degree_bits_target,
num_lookup_columns,
);

challenger.observe_extension_elements(&constraints);

let stark_alphas = challenger.get_n_challenges(builder, num_challenges);

if let Some(cap) = quotient_polys_cap {
Expand Down Expand Up @@ -259,11 +353,16 @@ impl<const D: usize> StarkProofTarget<D> {
/// Multi-STARK systems may already observe individual trace caps
/// ahead of proving each table, and hence may ignore observing
/// again the cap when generating individual challenges.
pub fn get_challenges<F, C>(
pub fn get_challenges<F, C, S: Stark<F, D>>(
&self,
builder: &mut CircuitBuilder<F, D>,
stark: &S,
public_inputs: &[Target],
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
challenges: Option<&GrandProductChallengeSet<Target>>,
ctl_vars: Option<&[CtlCheckVarsTarget<F, D>]>,
degree_bits: usize,
degree_bits_target: Target,
ignore_trace_cap: bool,
config: &StarkConfig,
) -> StarkProofChallengesTarget<D>
Expand All @@ -276,6 +375,7 @@ impl<const D: usize> StarkProofTarget<D> {
trace_cap,
auxiliary_polys_cap,
quotient_polys_cap,
poly_evals,
openings,
opening_proof:
FriProofTarget {
Expand All @@ -293,17 +393,23 @@ impl<const D: usize> StarkProofTarget<D> {
Some(trace_cap)
};

get_challenges_target::<F, C, D>(
get_challenges_target::<F, C, S, D>(
builder,
stark,
public_inputs,
challenger,
challenges,
trace_cap,
auxiliary_polys_cap.as_ref(),
quotient_polys_cap.as_ref(),
ctl_vars,
poly_evals,
openings,
commit_phase_merkle_caps,
final_poly,
*pow_witness,
degree_bits,
degree_bits_target,
config,
)
}
Expand All @@ -317,11 +423,15 @@ impl<const D: usize> StarkProofWithPublicInputsTarget<D> {
/// Multi-STARK systems may already observe individual trace caps
/// ahead of proving each table, and hence may ignore observing
/// again the cap when generating individual challenges.
pub fn get_challenges<F, C>(
pub fn get_challenges<F, C, S: Stark<F, D>>(
&self,
stark: &S,
builder: &mut CircuitBuilder<F, D>,
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
challenges: Option<&GrandProductChallengeSet<Target>>,
ctl_vars: Option<&[CtlCheckVarsTarget<F, D>]>,
degree_bits: usize,
degre_bits_target: Target,
ignore_trace_cap: bool,
config: &StarkConfig,
) -> StarkProofChallengesTarget<D>
Expand All @@ -331,7 +441,17 @@ impl<const D: usize> StarkProofWithPublicInputsTarget<D> {
C::Hasher: AlgebraicHasher<F>,
{
challenger.observe_elements(&self.public_inputs);
self.proof
.get_challenges::<F, C>(builder, challenger, challenges, ignore_trace_cap, config)
self.proof.get_challenges::<F, C, S>(
builder,
stark,
&self.public_inputs,
challenger,
challenges,
ctl_vars,
degree_bits,
degre_bits_target,
ignore_trace_cap,
config,
)
}
}
Loading
Loading