Shape check in starky

This commit is contained in:
Daniel Lubarov 2022-09-19 21:41:24 -07:00
parent f8e0b6f6a3
commit 5d4d81c29f
4 changed files with 67 additions and 6 deletions

View File

@ -111,7 +111,7 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
num_permutation_batches..num_permutation_batches + num_ctl_zs,
);
let num_quotient_polys = self.quotient_degree_factor() * config.num_challenges;
let num_quotient_polys = self.num_quotient_polys(config);
let quotient_oracle = FriOracleInfo {
num_polys: num_quotient_polys,
blinding: false,
@ -174,7 +174,7 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
num_permutation_batches..num_permutation_batches + num_ctl_zs,
);
let num_quotient_polys = self.quotient_degree_factor() * inner_config.num_challenges;
let num_quotient_polys = self.num_quotient_polys(inner_config);
let quotient_oracle = FriOracleInfo {
num_polys: num_quotient_polys,
blinding: false,

View File

@ -241,8 +241,7 @@ where
ensure!(openings.permutation_ctl_zs.len() == num_zs);
ensure!(openings.permutation_ctl_zs_next.len() == num_zs);
ensure!(openings.ctl_zs_last.len() == num_ctl_zs);
let num_quotient_polys = stark.num_quotient_polys(config);
ensure!(openings.quotient_polys.len() == num_quotient_polys);
ensure!(openings.quotient_polys.len() == stark.num_quotient_polys(config));
Ok(())
}

View File

@ -78,6 +78,10 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
1.max(self.constraint_degree() - 1)
}
fn num_quotient_polys(&self, config: &StarkConfig) -> usize {
self.quotient_degree_factor() * config.num_challenges
}
/// Computes the FRI instance used to prove this Stark.
fn fri_instance(
&self,

View File

@ -1,6 +1,6 @@
use std::iter::once;
use anyhow::{ensure, Result};
use anyhow::{anyhow, ensure, Result};
use itertools::Itertools;
use plonky2::field::extension::{Extendable, FieldExtension};
use plonky2::field::types::Field;
@ -12,7 +12,7 @@ use plonky2::plonk::plonk_common::reduce_with_powers;
use crate::config::StarkConfig;
use crate::constraint_consumer::ConstraintConsumer;
use crate::permutation::PermutationCheckVars;
use crate::proof::{StarkOpeningSet, StarkProofChallenges, StarkProofWithPublicInputs};
use crate::proof::{StarkOpeningSet, StarkProof, StarkProofChallenges, StarkProofWithPublicInputs};
use crate::stark::Stark;
use crate::vanishing_poly::eval_vanishing_poly;
use crate::vars::StarkEvaluationVars;
@ -144,6 +144,64 @@ where
Ok(())
}
fn validate_proof_shape<F, C, S, const D: usize>(
stark: &S,
proof_with_pis: StarkProofWithPublicInputs<F, C, D>,
config: &StarkConfig,
) -> anyhow::Result<()>
where
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
[(); S::COLUMNS]:,
[(); C::Hasher::HASH_SIZE]:,
{
let degree_bits = proof_with_pis.proof.recover_degree_bits(config);
let StarkProofWithPublicInputs {
proof:
StarkProof {
trace_cap,
permutation_zs_cap,
quotient_polys_cap,
openings,
// The shape of the opening proof will be checked in the FRI verifier (see
// validate_fri_proof_shape), so we ignore it here.
opening_proof: _,
},
public_inputs,
} = proof_with_pis;
ensure!(public_inputs.len() == S::PUBLIC_INPUTS);
let fri_params = config.fri_params(degree_bits);
let cap_height = fri_params.config.cap_height;
let num_zs = stark.num_permutation_batches(config);
ensure!(trace_cap.height() == cap_height);
ensure!(quotient_polys_cap.height() == cap_height);
ensure!(openings.local_values.len() == S::COLUMNS);
ensure!(openings.next_values.len() == S::COLUMNS);
ensure!(openings.quotient_polys.len() == stark.num_quotient_polys(config));
if stark.uses_permutation_args() {
let permutation_zs_cap = permutation_zs_cap.ok_or_else(|| anyhow!("Missing Zs cap"))?;
let permutation_zs = openings
.permutation_zs
.ok_or_else(|| anyhow!("Missing permutation_zs"))?;
let permutation_zs_next = openings
.permutation_zs_next
.ok_or_else(|| anyhow!("Missing permutation_zs_next"))?;
ensure!(permutation_zs_cap.height() == cap_height);
ensure!(permutation_zs.len() == num_zs);
ensure!(permutation_zs_next.len() == num_zs);
}
Ok(())
}
/// Evaluate the Lagrange polynomials `L_0` and `L_(n-1)` at a point `x`.
/// `L_0(x) = (x^n - 1)/(n * (x - 1))`
/// `L_(n-1)(x) = (x^n - 1)/(n * (g * x - 1))`, with `g` the first element of the subgroup.