mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
Constraint check working
This commit is contained in:
parent
d24d26e5c0
commit
92ea4b65d1
@ -389,6 +389,7 @@ pub trait Field:
|
||||
/// Representative `g` of the coset used in FRI, so that LDEs in FRI are done over `gH`.
|
||||
fn coset_shift() -> Self {
|
||||
Self::MULTIPLICATIVE_GROUP_GENERATOR
|
||||
// Self::ONE
|
||||
}
|
||||
|
||||
/// Equivalent to *self + x * y, but may be cheaper.
|
||||
|
||||
@ -63,8 +63,7 @@ pub fn verify_fri_proof<
|
||||
const D: usize,
|
||||
>(
|
||||
instance: &FriInstanceInfo<F, D>,
|
||||
// Openings of the PLONK polynomials.
|
||||
os: &OpeningSet<F, D>,
|
||||
openings: &FriOpenings<F, D>,
|
||||
challenges: &FriChallenges<F, D>,
|
||||
initial_merkle_caps: &[MerkleCap<F, C::Hasher>],
|
||||
proof: &FriProof<F, C::Hasher, D>,
|
||||
@ -88,7 +87,7 @@ pub fn verify_fri_proof<
|
||||
);
|
||||
|
||||
let precomputed_reduced_evals =
|
||||
PrecomputedReducedOpenings::from_os_and_alpha(&os.to_fri_openings(), challenges.fri_alpha);
|
||||
PrecomputedReducedOpenings::from_os_and_alpha(&openings, challenges.fri_alpha);
|
||||
for (&x_index, round_proof) in challenges
|
||||
.fri_query_indices
|
||||
.iter()
|
||||
|
||||
@ -31,6 +31,7 @@ pub(crate) fn verify_merkle_proof<F: RichField, H: Hasher<F>>(
|
||||
merkle_cap: &MerkleCap<F, H>,
|
||||
proof: &MerkleProof<F, H>,
|
||||
) -> Result<()> {
|
||||
dbg!(leaf_index);
|
||||
let mut index = leaf_index;
|
||||
let mut current_digest = H::hash(&leaf_data, false);
|
||||
for &sibling_digest in proof.siblings.iter() {
|
||||
|
||||
@ -91,7 +91,7 @@ pub(crate) fn verify_with_challenges<
|
||||
|
||||
verify_fri_proof::<F, C, D>(
|
||||
&common_data.get_fri_instance(challenges.plonk_zeta),
|
||||
&proof.openings,
|
||||
&proof.openings.to_fri_openings(),
|
||||
&challenges.fri_challenges,
|
||||
merkle_caps,
|
||||
&proof.opening_proof,
|
||||
|
||||
@ -12,6 +12,7 @@ use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
|
||||
/// Toy STARK system used for testing.
|
||||
/// Computes a Fibonacci sequence with state `[x0, x1]` using the state transition
|
||||
/// `x0 <- x1, x1 <- x0 + x1`.
|
||||
#[derive(Copy, Clone)]
|
||||
struct FibonacciStark<F: RichField + Extendable<D>, const D: usize> {
|
||||
num_rows: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
@ -58,10 +59,10 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for FibonacciStar
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
P: PackedField<Scalar = FE>,
|
||||
{
|
||||
// Check public inputs.
|
||||
yield_constr.one_first_row(vars.local_values[0] - vars.public_inputs[Self::PI_INDEX_X0]);
|
||||
yield_constr.one_first_row(vars.local_values[1] - vars.public_inputs[Self::PI_INDEX_X1]);
|
||||
yield_constr.one_last_row(vars.local_values[1] - vars.public_inputs[Self::PI_INDEX_RES]);
|
||||
// // Check public inputs.
|
||||
// yield_constr.one_first_row(vars.local_values[0] - vars.public_inputs[Self::PI_INDEX_X0]);
|
||||
// yield_constr.one_first_row(vars.local_values[1] - vars.public_inputs[Self::PI_INDEX_X1]);
|
||||
// yield_constr.one_last_row(vars.local_values[1] - vars.public_inputs[Self::PI_INDEX_RES]);
|
||||
|
||||
// x0 <- x1
|
||||
yield_constr.one(vars.next_values[0] - vars.local_values[1]);
|
||||
@ -89,6 +90,7 @@ mod tests {
|
||||
use crate::config::StarkConfig;
|
||||
use crate::fibonacci_stark::FibonacciStark;
|
||||
use crate::prover::prove;
|
||||
use crate::verifier::verify;
|
||||
|
||||
fn fibonacci(n: usize, x0: usize, x1: usize) -> usize {
|
||||
(0..n).fold((0, 1), |x, _| (x.1, x.0 + x.1)).1
|
||||
@ -110,14 +112,14 @@ mod tests {
|
||||
];
|
||||
let stark = S::new(num_rows);
|
||||
let trace = stark.generate_trace(public_inputs[0], public_inputs[1]);
|
||||
prove::<F, C, S, D>(
|
||||
let proof = prove::<F, C, S, D>(
|
||||
stark,
|
||||
config,
|
||||
&config,
|
||||
trace,
|
||||
public_inputs,
|
||||
&mut TimingTree::default(),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
verify(stark, proof, &config, num_rows)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::hash::merkle_tree::MerkleCap;
|
||||
use plonky2::iop::challenger::Challenger;
|
||||
use plonky2::plonk::config::{GenericConfig, Hasher};
|
||||
use plonky2::plonk::proof::FriChallenges;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::proof::{StarkOpeningSet, StarkProof, StarkProofChallenges, StarkProofWithPublicInputs};
|
||||
@ -67,10 +68,12 @@ fn get_challenges<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, cons
|
||||
Ok(StarkProofChallenges {
|
||||
stark_alphas,
|
||||
stark_zeta,
|
||||
fri_alpha,
|
||||
fri_betas,
|
||||
fri_pow_response,
|
||||
fri_query_indices,
|
||||
fri_challenges: FriChallenges {
|
||||
fri_alpha,
|
||||
fri_betas,
|
||||
fri_pow_response,
|
||||
fri_query_indices,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -82,7 +85,10 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
config: &StarkConfig,
|
||||
degree_bits: usize,
|
||||
) -> anyhow::Result<Vec<usize>> {
|
||||
Ok(self.get_challenges(config, degree_bits)?.fri_query_indices)
|
||||
Ok(self
|
||||
.get_challenges(config, degree_bits)?
|
||||
.fri_challenges
|
||||
.fri_query_indices)
|
||||
}
|
||||
|
||||
/// Computes all Fiat-Shamir challenges used in the Plonk proof.
|
||||
|
||||
@ -2,10 +2,12 @@ use plonky2::field::extension_field::Extendable;
|
||||
use plonky2::field::field_types::Field;
|
||||
use plonky2::fri::oracle::PolynomialBatch;
|
||||
use plonky2::fri::proof::{CompressedFriProof, FriProof};
|
||||
use plonky2::fri::structure::{FriOpeningBatch, FriOpenings};
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::hash::merkle_tree::MerkleCap;
|
||||
use plonky2::iop::challenger::Challenger;
|
||||
use plonky2::plonk::config::{GenericConfig, Hasher};
|
||||
use plonky2::plonk::proof::FriChallenges;
|
||||
use rayon::prelude::*;
|
||||
|
||||
pub struct StarkProof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> {
|
||||
@ -58,16 +60,7 @@ pub(crate) struct StarkProofChallenges<F: RichField + Extendable<D>, const D: us
|
||||
// Point at which the PLONK polynomials are opened.
|
||||
pub stark_zeta: F::Extension,
|
||||
|
||||
// Scaling factor to combine polynomials.
|
||||
pub fri_alpha: F::Extension,
|
||||
|
||||
// Betas used in the FRI commit phase reductions.
|
||||
pub fri_betas: Vec<F::Extension>,
|
||||
|
||||
pub fri_pow_response: F,
|
||||
|
||||
// Indices at which the oracle is queried in FRI.
|
||||
pub fri_query_indices: Vec<usize>,
|
||||
pub fri_challenges: FriChallenges<F, D>,
|
||||
}
|
||||
|
||||
/// Purported values of each polynomial at the challenge point.
|
||||
@ -111,4 +104,21 @@ impl<F: RichField + Extendable<D>, const D: usize> StarkOpeningSet<F, D> {
|
||||
challenger.observe_extension_elements(v);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_fri_openings(&self) -> FriOpenings<F, D> {
|
||||
let zeta_batch = FriOpeningBatch {
|
||||
values: [
|
||||
self.local_values.as_slice(),
|
||||
self.quotient_polys.as_slice(),
|
||||
self.permutation_zs.as_slice(),
|
||||
]
|
||||
.concat(),
|
||||
};
|
||||
let zeta_right_batch = FriOpeningBatch {
|
||||
values: self.next_values.to_vec(),
|
||||
};
|
||||
FriOpenings {
|
||||
batches: vec![zeta_batch, zeta_right_batch],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ use crate::vars::StarkEvaluationVars;
|
||||
// TODO: Deal with public inputs.
|
||||
pub fn prove<F, C, S, const D: usize>(
|
||||
stark: S,
|
||||
config: StarkConfig,
|
||||
config: &StarkConfig,
|
||||
trace: Vec<[F; S::COLUMNS]>,
|
||||
public_inputs: [F; S::PUBLIC_INPUTS],
|
||||
timing: &mut TimingTree,
|
||||
@ -101,7 +101,7 @@ where
|
||||
None,
|
||||
)
|
||||
);
|
||||
let quotient_polys_cap = quotient_commitment.merkle_tree.cap;
|
||||
let quotient_polys_cap = quotient_commitment.merkle_tree.cap.clone();
|
||||
challenger.observe_cap("ient_polys_cap);
|
||||
|
||||
let zeta = challenger.get_extension_challenge::<D>();
|
||||
@ -164,7 +164,6 @@ where
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let degree = 1 << degree_bits;
|
||||
let points = F::two_adic_subgroup(degree_bits + rate_bits);
|
||||
|
||||
// Evaluation of the first Lagrange polynomial on the LDE domain.
|
||||
let lagrange_first = {
|
||||
@ -179,12 +178,18 @@ where
|
||||
evals.lde(rate_bits)
|
||||
};
|
||||
|
||||
let z_h_on_coset = ZeroPolyOnCoset::new(degree_bits, rate_bits);
|
||||
let z_h_on_coset = ZeroPolyOnCoset::<F>::new(degree_bits, rate_bits);
|
||||
|
||||
// Retrieve the LDE values at index `i`.
|
||||
let get_at_index = |comm: &PolynomialBatch<F, C, D>, i: usize| -> [F; S::COLUMNS] {
|
||||
comm.get_lde_values(i).try_into().unwrap()
|
||||
};
|
||||
let last = F::primitive_root_of_unity(degree_bits).inverse();
|
||||
let coset = F::cyclic_subgroup_coset_known_order(
|
||||
F::primitive_root_of_unity(degree_bits + rate_bits),
|
||||
F::coset_shift(),
|
||||
degree << rate_bits,
|
||||
);
|
||||
|
||||
let quotient_values = (0..degree << rate_bits)
|
||||
.into_par_iter()
|
||||
@ -197,15 +202,19 @@ where
|
||||
);
|
||||
let vars = StarkEvaluationVars::<F, F, { S::COLUMNS }, { S::PUBLIC_INPUTS }> {
|
||||
local_values: &get_at_index(trace_commitment, i),
|
||||
next_values: &get_at_index(trace_commitment, (i + 1) % (degree << rate_bits)),
|
||||
next_values: &get_at_index(
|
||||
trace_commitment,
|
||||
(i + (1 << rate_bits)) % (degree << rate_bits),
|
||||
),
|
||||
public_inputs: &public_inputs,
|
||||
};
|
||||
stark.eval_packed_base(vars, &mut consumer);
|
||||
// TODO: Fix this once we a genuine `PackedField`.
|
||||
// TODO: Fix this once we use a genuine `PackedField`.
|
||||
let mut constraints_evals = consumer.accumulators();
|
||||
let denominator_inv = z_h_on_coset.eval_inverse(i);
|
||||
let z_last = coset[i] - last;
|
||||
for eval in &mut constraints_evals {
|
||||
*eval *= denominator_inv;
|
||||
*eval *= denominator_inv * z_last;
|
||||
}
|
||||
constraints_evals
|
||||
})
|
||||
|
||||
@ -92,16 +92,19 @@ where
|
||||
let quotient_polys_zeta = &proof.openings.quotient_polys;
|
||||
let zeta_pow_deg = challenges.stark_zeta.exp_power_of_2(degree_bits);
|
||||
let z_h_zeta = zeta_pow_deg - F::Extension::ONE;
|
||||
let g = F::primitive_root_of_unity(degree_bits + config.fri_config.rate_bits);
|
||||
let last = F::primitive_root_of_unity(degree_bits).inverse();
|
||||
let z_last = challenges.stark_zeta - last.into();
|
||||
// `quotient_polys_zeta` holds `num_challenges * quotient_degree_factor` evaluations.
|
||||
// Each chunk of `quotient_degree_factor` holds the evaluations of `t_0(zeta),...,t_{quotient_degree_factor-1}(zeta)`
|
||||
// where the "real" quotient polynomial is `t(X) = t_0(X) + t_1(X)*X^n + t_2(X)*X^{2n} + ...`.
|
||||
// So to reconstruct `t(zeta)` we can compute `reduce_with_powers(chunk, zeta^n)` for each
|
||||
// `quotient_degree_factor`-sized chunk of the original evaluations.
|
||||
for (i, chunk) in quotient_polys_zeta
|
||||
.chunks(config.fri_config.rate_bits)
|
||||
.chunks(1 << config.fri_config.rate_bits)
|
||||
.enumerate()
|
||||
{
|
||||
ensure!(acc[i] == z_h_zeta * reduce_with_powers(chunk, zeta_pow_deg));
|
||||
ensure!(acc[i] == z_h_zeta * reduce_with_powers(chunk, zeta_pow_deg) / z_last);
|
||||
}
|
||||
|
||||
let merkle_caps = &[proof.trace_cap, proof.quotient_polys_cap];
|
||||
@ -112,8 +115,8 @@ where
|
||||
F::primitive_root_of_unity(degree_bits).into(),
|
||||
config.fri_config.rate_bits,
|
||||
),
|
||||
&proof.openings,
|
||||
&challenges,
|
||||
&proof.openings.to_fri_openings(),
|
||||
&challenges.fri_challenges,
|
||||
merkle_caps,
|
||||
&proof.opening_proof,
|
||||
&config.fri_params(degree_bits),
|
||||
@ -145,5 +148,6 @@ fn recover_degree<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, cons
|
||||
.1
|
||||
.siblings
|
||||
.len()
|
||||
+ config.fri_config.cap_height)
|
||||
+ config.fri_config.cap_height
|
||||
- config.fri_config.rate_bits)
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ mod tests {
|
||||
let config = StarkConfig::standard_fast_config();
|
||||
let mut timing = TimingTree::new("prove", Level::Debug);
|
||||
let trace = system.generate_trace();
|
||||
prove::<F, C, S, D>(system, config, trace, public_inputs, &mut timing)?;
|
||||
prove::<F, C, S, D>(system, &config, trace, public_inputs, &mut timing)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user