mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 00:33:06 +00:00
Working prover
This commit is contained in:
parent
3e0cb36063
commit
4a2681034e
@ -127,7 +127,7 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
}
|
||||
|
||||
/// Produces a batch opening proof.
|
||||
pub(crate) fn prove_openings(
|
||||
pub fn prove_openings(
|
||||
instance: &FriInstanceInfo<F, D>,
|
||||
oracles: &[&Self],
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
|
||||
@ -9,34 +9,37 @@ use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer
|
||||
use crate::stark::Stark;
|
||||
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
|
||||
|
||||
pub struct JuliaStark<F: RichField + Extendable<D>, const D: usize> {
|
||||
c: F,
|
||||
pub struct FibonacciStark<F: RichField + Extendable<D>, const D: usize> {
|
||||
x0: F,
|
||||
x1: F,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> JuliaStark<F, D> {
|
||||
const NUM_COLUMNS: usize = 1;
|
||||
const NUM_ROWS: usize = 1 << 10;
|
||||
impl<F: RichField + Extendable<D>, const D: usize> FibonacciStark<F, D> {
|
||||
const NUM_COLUMNS: usize = 2;
|
||||
const NUM_ROWS: usize = 1 << 5;
|
||||
|
||||
fn new(c: F) -> Self {
|
||||
fn new(x0: F, x1: F) -> Self {
|
||||
Self {
|
||||
c,
|
||||
x0,
|
||||
x1,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_trace(&self) -> Vec<[F; Self::NUM_COLUMNS]> {
|
||||
(0..Self::NUM_ROWS)
|
||||
.scan([F::ZERO; Self::NUM_COLUMNS], |acc, _| {
|
||||
.scan([self.x0, self.x1], |acc, _| {
|
||||
let tmp = *acc;
|
||||
acc[0] = acc[0] * acc[0] + self.c;
|
||||
acc[0] = tmp[1];
|
||||
acc[1] = tmp[0] + tmp[1];
|
||||
Some(tmp)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for JuliaStark<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for FibonacciStark<F, D> {
|
||||
const COLUMNS: usize = Self::NUM_COLUMNS;
|
||||
const PUBLIC_INPUTS: usize = 0;
|
||||
|
||||
@ -48,11 +51,8 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for JuliaStark<F,
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
P: PackedField<Scalar = FE>,
|
||||
{
|
||||
yield_constr.one(
|
||||
vars.next_values[0]
|
||||
- vars.local_values[0] * vars.local_values[0]
|
||||
- FE::from_basefield(self.c),
|
||||
);
|
||||
yield_constr.one(vars.next_values[0] - vars.local_values[1]);
|
||||
yield_constr.one(vars.next_values[1] - vars.local_values[0] - vars.local_values[1]);
|
||||
}
|
||||
|
||||
fn eval_ext_recursively(
|
||||
@ -67,25 +67,28 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for JuliaStark<F,
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
use plonky2::field::field_types::Field;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
|
||||
use plonky2::util::timing::TimingTree;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::julia_stark::JuliaStark;
|
||||
use crate::fibonacci_stark::FibonacciStark;
|
||||
use crate::prover::prove;
|
||||
|
||||
#[test]
|
||||
fn test_julia_stark() {
|
||||
fn test_fibonacci_stark() -> Result<()> {
|
||||
const D: usize = 2;
|
||||
type C = PoseidonGoldilocksConfig;
|
||||
type F = <C as GenericConfig<D>>::F;
|
||||
type S = JuliaStark<F, D>;
|
||||
type S = FibonacciStark<F, D>;
|
||||
|
||||
let config = StarkConfig::standard_fast_config();
|
||||
let stark = S::new(F::NEG_ONE);
|
||||
let stark = S::new(F::ZERO, F::ONE);
|
||||
let trace = stark.generate_trace();
|
||||
prove::<F, C, S, D>(stark, config, trace, &mut TimingTree::default());
|
||||
prove::<F, C, S, D>(stark, config, trace, &mut TimingTree::default())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -14,4 +14,4 @@ pub mod stark;
|
||||
pub mod vars;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod julia_stark;
|
||||
pub mod fibonacci_stark;
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
use plonky2::field::extension_field::Extendable;
|
||||
use plonky2::fri::oracle::PolynomialBatch;
|
||||
use plonky2::fri::proof::{CompressedFriProof, FriProof};
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::hash::merkle_tree::MerkleCap;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use rayon::prelude::*;
|
||||
|
||||
pub struct StarkProof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> {
|
||||
/// Merkle cap of LDEs of trace values.
|
||||
@ -33,3 +35,25 @@ pub struct StarkOpeningSet<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub permutation_zs: Vec<F::Extension>,
|
||||
pub quotient_polys: Vec<F::Extension>,
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> StarkOpeningSet<F, D> {
|
||||
pub fn new<C: GenericConfig<D, F = F>>(
|
||||
zeta: F::Extension,
|
||||
g: F::Extension,
|
||||
trace_commitment: &PolynomialBatch<F, C, D>,
|
||||
quotient_commitment: &PolynomialBatch<F, C, D>,
|
||||
) -> Self {
|
||||
let eval_commitment = |z: F::Extension, c: &PolynomialBatch<F, C, D>| {
|
||||
c.polynomials
|
||||
.par_iter()
|
||||
.map(|p| p.to_extension().eval(z))
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
Self {
|
||||
local_values: eval_commitment(zeta, trace_commitment),
|
||||
next_values: eval_commitment(zeta * g, trace_commitment),
|
||||
permutation_zs: vec![],
|
||||
quotient_polys: eval_commitment(zeta, quotient_commitment),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use anyhow::{ensure, Result};
|
||||
use itertools::Itertools;
|
||||
use plonky2::field::extension_field::Extendable;
|
||||
use plonky2::field::field_types::Field;
|
||||
use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues};
|
||||
use plonky2::field::zero_poly_coset::ZeroPolyOnCoset;
|
||||
use plonky2::fri::oracle::PolynomialBatch;
|
||||
@ -16,7 +18,7 @@ use rayon::prelude::*;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::constraint_consumer::ConstraintConsumer;
|
||||
use crate::proof::StarkProof;
|
||||
use crate::proof::{StarkOpeningSet, StarkProof};
|
||||
use crate::stark::Stark;
|
||||
use crate::vars::StarkEvaluationVars;
|
||||
|
||||
@ -25,7 +27,7 @@ pub fn prove<F, C, S, const D: usize>(
|
||||
config: StarkConfig,
|
||||
trace: Vec<[F; S::COLUMNS]>,
|
||||
timing: &mut TimingTree,
|
||||
) -> StarkProof<F, C, D>
|
||||
) -> Result<StarkProof<F, C, D>>
|
||||
where
|
||||
F: RichField + Extendable<D>,
|
||||
C: GenericConfig<D, F = F>,
|
||||
@ -33,7 +35,8 @@ where
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let degree_bits = log2_strict(trace.len());
|
||||
let degree = trace.len();
|
||||
let degree_bits = log2_strict(degree);
|
||||
|
||||
let trace_vecs = trace.into_iter().map(|row| row.to_vec()).collect_vec();
|
||||
let trace_col_major: Vec<Vec<F>> = transpose(&trace_vecs);
|
||||
@ -67,34 +70,70 @@ where
|
||||
challenger.observe_cap(&trace_cap);
|
||||
|
||||
let alphas = challenger.get_n_challenges(config.num_challenges);
|
||||
let quotient = compute_quotient_polys::<F, C, S, D>(
|
||||
let quotient_polys = compute_quotient_polys::<F, C, S, D>(
|
||||
&stark,
|
||||
&trace_commitment,
|
||||
&alphas,
|
||||
degree_bits,
|
||||
rate_bits,
|
||||
);
|
||||
let openings = todo!();
|
||||
let all_quotient_chunks = quotient_polys
|
||||
.into_par_iter()
|
||||
.flat_map(|mut quotient_poly| {
|
||||
quotient_poly.trim();
|
||||
quotient_poly
|
||||
.pad(degree << rate_bits)
|
||||
.expect("Quotient has failed, the vanishing polynomial is not divisible by `Z_H");
|
||||
// Split t into degree-n chunks.
|
||||
quotient_poly.chunks(degree)
|
||||
})
|
||||
.collect();
|
||||
let quotient_commitment = timed!(
|
||||
timing,
|
||||
"compute quotient commitment",
|
||||
PolynomialBatch::from_coeffs(
|
||||
all_quotient_chunks,
|
||||
rate_bits,
|
||||
false,
|
||||
config.fri_config.cap_height,
|
||||
timing,
|
||||
None,
|
||||
)
|
||||
);
|
||||
challenger.observe_cap("ient_commitment.merkle_tree.cap);
|
||||
|
||||
let initial_merkle_trees = todo!();
|
||||
let lde_polynomial_coeffs = todo!();
|
||||
let lde_polynomial_values = todo!();
|
||||
let zeta = challenger.get_extension_challenge::<D>();
|
||||
// To avoid leaking witness data, we want to ensure that our opening locations, `zeta` and
|
||||
// `g * zeta`, are not in our subgroup `H`. It suffices to check `zeta` only, since
|
||||
// `(g * zeta)^n = zeta^n`, where `n` is the order of `g`.
|
||||
let g = F::Extension::primitive_root_of_unity(degree_bits);
|
||||
ensure!(
|
||||
zeta.exp_power_of_2(degree_bits) != F::Extension::ONE,
|
||||
"Opening point is in the subgroup."
|
||||
);
|
||||
let openings = StarkOpeningSet::new(zeta, g, &trace_commitment, "ient_commitment);
|
||||
|
||||
// TODO: Add permuation checks
|
||||
let initial_merkle_trees = &[&trace_commitment, "ient_commitment];
|
||||
let fri_params = config.fri_params(degree_bits);
|
||||
|
||||
let opening_proof = fri_proof::<F, C, D>(
|
||||
initial_merkle_trees,
|
||||
lde_polynomial_coeffs,
|
||||
lde_polynomial_values,
|
||||
&mut challenger,
|
||||
&fri_params,
|
||||
let opening_proof = timed!(
|
||||
timing,
|
||||
"compute openings proof",
|
||||
PolynomialBatch::prove_openings(
|
||||
&S::fri_instance(zeta, g, rate_bits),
|
||||
initial_merkle_trees,
|
||||
&mut challenger,
|
||||
&fri_params,
|
||||
timing,
|
||||
)
|
||||
);
|
||||
|
||||
StarkProof {
|
||||
Ok(StarkProof {
|
||||
trace_cap,
|
||||
openings,
|
||||
opening_proof,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn compute_quotient_polys<F, C, S, const D: usize>(
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use plonky2::field::extension_field::{Extendable, FieldExtension};
|
||||
use plonky2::field::packed_field::PackedField;
|
||||
use plonky2::fri::structure::{FriBatchInfo, FriInstanceInfo, FriOracleInfo, FriPolynomialInfo};
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
@ -59,4 +60,26 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
|
||||
vars: StarkEvaluationTargets<D, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
);
|
||||
|
||||
fn fri_instance(
|
||||
zeta: F::Extension,
|
||||
g: F::Extension,
|
||||
rate_bits: usize,
|
||||
) -> FriInstanceInfo<F, D> {
|
||||
let no_blinding_oracle = FriOracleInfo { blinding: false };
|
||||
let trace_info = FriPolynomialInfo::from_range(0, 0..Self::COLUMNS);
|
||||
let quotient_info = FriPolynomialInfo::from_range(1, 0..1 << rate_bits);
|
||||
let zeta_batch = FriBatchInfo {
|
||||
point: zeta,
|
||||
polynomials: [trace_info.clone(), quotient_info].concat(),
|
||||
};
|
||||
let zeta_right_batch = FriBatchInfo::<F, D> {
|
||||
point: zeta * g,
|
||||
polynomials: trace_info,
|
||||
};
|
||||
FriInstanceInfo {
|
||||
oracles: vec![no_blinding_oracle; 3],
|
||||
batches: vec![zeta_batch],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user