p3_uni_stark/
preprocessed.rs1use p3_air::Air;
2use p3_commit::Pcs;
3use p3_field::Field;
4use p3_matrix::Matrix;
5use tracing::debug_span;
6
7use crate::{ProverConstraintFolder, StarkGenericConfig, SymbolicAirBuilder, Val};
8
9pub struct PreprocessedProverData<SC: StarkGenericConfig> {
14 pub width: usize,
16 pub degree_bits: usize,
21 pub commitment: <SC::Pcs as Pcs<SC::Challenge, SC::Challenger>>::Commitment,
23 pub prover_data: <SC::Pcs as Pcs<SC::Challenge, SC::Challenger>>::ProverData,
25}
26
27#[derive(Clone)]
32pub struct PreprocessedVerifierKey<SC: StarkGenericConfig> {
33 pub width: usize,
35 pub degree_bits: usize,
39 pub commitment: <SC::Pcs as Pcs<SC::Challenge, SC::Challenger>>::Commitment,
41}
42
43pub fn setup_preprocessed<SC, A>(
49 config: &SC,
50 air: &A,
51 degree_bits: usize,
52) -> Option<(PreprocessedProverData<SC>, PreprocessedVerifierKey<SC>)>
53where
54 SC: StarkGenericConfig,
55 Val<SC>: Field,
56 A: Air<SymbolicAirBuilder<Val<SC>>> + for<'a> Air<ProverConstraintFolder<'a, SC>>,
57{
58 let pcs = config.pcs();
59 let is_zk = config.is_zk();
60
61 let init_degree = 1 << degree_bits;
62 let degree = 1 << (degree_bits + is_zk);
63
64 let preprocessed = air.preprocessed_trace()?;
65
66 let width = preprocessed.width();
67 if width == 0 {
68 return None;
69 }
70
71 assert_eq!(
72 preprocessed.height(),
73 init_degree,
74 "preprocessed trace height must equal trace degree"
75 );
76
77 let trace_domain = pcs.natural_domain_for_degree(degree);
78 let (commitment, prover_data) = debug_span!("commit to preprocessed trace")
79 .in_scope(|| pcs.commit_preprocessing([(trace_domain, preprocessed)]));
80
81 let degree_bits = degree_bits + is_zk;
82 let prover_data = PreprocessedProverData {
83 width,
84 degree_bits,
85 commitment: commitment.clone(),
86 prover_data,
87 };
88 let vk = PreprocessedVerifierKey {
89 width,
90 degree_bits,
91 commitment,
92 };
93 Some((prover_data, vk))
94}