openvm_stark_backend/prover/
trace.rsuse std::sync::Arc;
use derivative::Derivative;
use itertools::{izip, Itertools};
use p3_commit::Pcs;
use p3_matrix::{
dense::{RowMajorMatrix, RowMajorMatrixView},
Matrix,
};
use serde::{Deserialize, Serialize};
use tracing::info_span;
use crate::{
commit::CommittedSingleMatrixView,
config::{Com, Domain, PcsProverData, StarkGenericConfig, Val},
keygen::view::MultiStarkProvingKeyView,
prover::quotient::{helper::QuotientVkDataHelper, ProverQuotientData, QuotientCommitter},
rap::AnyRap,
};
#[allow(clippy::too_many_arguments)]
pub(super) fn commit_quotient_traces<'a, SC: StarkGenericConfig>(
pcs: &SC::Pcs,
mpk: &MultiStarkProvingKeyView<SC>,
alpha: SC::Challenge,
challenges: &[Vec<SC::Challenge>],
raps: Vec<impl AsRef<dyn AnyRap<SC>>>,
public_values_per_air: &[Vec<Val<SC>>],
domain_per_air: Vec<Domain<SC>>,
cached_mains_pdata_per_air: &'a [Vec<ProverTraceData<SC>>],
common_main_prover_data: &'a ProverTraceData<SC>,
perm_prover_data: &'a Option<ProverTraceData<SC>>,
exposed_values_after_challenge: Vec<Vec<Vec<SC::Challenge>>>,
) -> ProverQuotientData<SC> {
let trace_views = create_trace_view_per_air(
domain_per_air,
cached_mains_pdata_per_air,
mpk,
exposed_values_after_challenge,
common_main_prover_data,
perm_prover_data,
);
let quotient_committer = QuotientCommitter::new(pcs, challenges, alpha);
let qvks = mpk
.per_air
.iter()
.map(|pk| pk.get_quotient_vk_data())
.collect_vec();
let quotient_values =
quotient_committer.quotient_values(raps, &qvks, &trace_views, public_values_per_air);
quotient_committer.commit(quotient_values)
}
fn create_trace_view_per_air<'a, SC: StarkGenericConfig>(
domain_per_air: Vec<Domain<SC>>,
cached_mains_pdata_per_air: &'a [Vec<ProverTraceData<SC>>],
mpk: &'a MultiStarkProvingKeyView<SC>,
exposed_values_after_challenge: Vec<Vec<Vec<SC::Challenge>>>,
common_main_prover_data: &'a ProverTraceData<SC>,
perm_prover_data: &'a Option<ProverTraceData<SC>>,
) -> Vec<SingleRapCommittedTraceView<'a, SC>> {
let mut common_main_idx = 0;
let mut after_challenge_idx = 0;
izip!(
domain_per_air,
cached_mains_pdata_per_air,
&mpk.per_air,
exposed_values_after_challenge,
).map(|(domain, cached_mains_pdata, pk, exposed_values)| {
let preprocessed = pk.preprocessed_data.as_ref().map(|p| {
CommittedSingleMatrixView::<SC>::new(p.data.as_ref(), 0)
});
let mut partitioned_main: Vec<_> = cached_mains_pdata
.iter()
.map(|pdata| CommittedSingleMatrixView::new(pdata.data.as_ref(), 0))
.collect();
if pk.vk.has_common_main() {
partitioned_main.push(CommittedSingleMatrixView::new(
common_main_prover_data.data.as_ref(),
common_main_idx,
));
common_main_idx += 1;
}
let after_challenge = exposed_values
.into_iter()
.map(|exposed_values| {
let matrix = CommittedSingleMatrixView::new(
perm_prover_data
.as_ref()
.expect("AIR exposes after_challenge values but has no permutation trace commitment")
.data
.as_ref(),
after_challenge_idx,
);
after_challenge_idx += 1;
(matrix, exposed_values)
})
.collect();
SingleRapCommittedTraceView {
domain,
preprocessed,
partitioned_main,
after_challenge,
}
}).collect()
}
pub struct TraceCommitter<'pcs, SC: StarkGenericConfig> {
pcs: &'pcs SC::Pcs,
}
impl<SC: StarkGenericConfig> Clone for TraceCommitter<'_, SC> {
fn clone(&self) -> Self {
Self { pcs: self.pcs }
}
}
impl<'pcs, SC: StarkGenericConfig> TraceCommitter<'pcs, SC> {
pub fn new(pcs: &'pcs SC::Pcs) -> Self {
Self { pcs }
}
pub fn commit(&self, traces: Vec<RowMajorMatrix<Val<SC>>>) -> ProverTraceData<SC> {
info_span!("commit to trace data").in_scope(|| {
let traces_with_domains: Vec<_> = traces
.into_iter()
.map(|matrix| {
let height = matrix.height();
let domain = self.pcs.natural_domain_for_degree(height);
(domain, matrix)
})
.collect();
let (commit, data) = self.pcs.commit(traces_with_domains);
ProverTraceData {
commit,
data: Arc::new(data),
}
})
}
}
#[derive(Derivative, Serialize, Deserialize)]
#[derivative(Clone(bound = "Com<SC>: Clone"))]
#[serde(bound(
serialize = "Com<SC>: Serialize, PcsProverData<SC>: Serialize",
deserialize = "Com<SC>: Deserialize<'de>, PcsProverData<SC>: Deserialize<'de>"
))]
pub struct ProverTraceData<SC: StarkGenericConfig> {
pub commit: Com<SC>,
pub data: Arc<PcsProverData<SC>>,
}
pub struct PairTraceView<'a, F> {
pub preprocessed: &'a Option<RowMajorMatrixView<'a, F>>,
pub partitioned_main: &'a [RowMajorMatrixView<'a, F>],
pub public_values: &'a [F],
}
#[derive(Derivative)]
#[derivative(Clone(bound = ""))]
pub struct SingleRapCommittedTraceView<'a, SC: StarkGenericConfig> {
pub domain: Domain<SC>,
pub preprocessed: Option<CommittedSingleMatrixView<'a, SC>>,
pub partitioned_main: Vec<CommittedSingleMatrixView<'a, SC>>,
pub after_challenge: Vec<(CommittedSingleMatrixView<'a, SC>, Vec<SC::Challenge>)>,
}