1use p3_challenger::CanObserve;
4use p3_commit::Mmcs;
5use p3_dft::TwoAdicSubgroupDft;
6use p3_field::TwoAdicField;
7use p3_matrix::Matrix;
8use p3_matrix::dense::{DenseMatrix, RowMajorMatrix, RowMajorMatrixView, RowMajorMatrixViewMut};
9use p3_multilinear_util::poly::Poly;
10use tracing::info_span;
11
12use crate::strategy::VariableOrder;
13
14pub fn commit_base<F, Dft, MT, Challenger>(
25 order: VariableOrder,
26 dft: &Dft,
27 mmcs: &MT,
28 challenger: &mut Challenger,
29 poly: &Poly<F>,
30 folding: usize,
31 starting_log_inv_rate: usize,
32) -> (MT::Commitment, MT::ProverData<DenseMatrix<F>>)
33where
34 F: TwoAdicField,
35 Dft: TwoAdicSubgroupDft<F>,
36 MT: Mmcs<F>,
37 Challenger: CanObserve<MT::Commitment>,
38{
39 let num_variables = poly.num_variables();
40 let height = 1 << (num_variables + starting_log_inv_rate - folding);
41
42 let encoded = match order {
43 VariableOrder::Prefix => {
44 let padded = info_span!("transpose & pad").in_scope(|| {
45 let width = 1 << folding;
46
47 let mut values = F::zero_vec(height * width);
50
51 let folded =
54 RowMajorMatrixView::new(poly.as_slice(), 1 << (num_variables - folding));
55 folded.transpose_into(&mut RowMajorMatrixViewMut::new(
56 &mut values[..1 << num_variables],
57 width,
58 ));
59
60 RowMajorMatrix::new(values, width)
61 });
62 info_span!("dft", height = padded.height(), width = padded.width())
63 .in_scope(|| dft.dft_batch(padded).to_row_major_matrix())
64 }
65 VariableOrder::Suffix => {
66 let padded = info_span!("pad").in_scope(|| {
67 let width = 1 << folding;
68 let src = poly.as_slice();
69
70 let mut values = F::zero_vec(height * width);
73 values[..src.len()].copy_from_slice(src);
74 RowMajorMatrix::new(values, width)
75 });
76 info_span!("dft", height = padded.height(), width = padded.width())
77 .in_scope(|| dft.dft_batch(padded).to_row_major_matrix())
78 }
79 };
80
81 let (root, prover_data) = info_span!("commit_matrix").in_scope(|| mmcs.commit_matrix(encoded));
82 challenger.observe(root.clone());
83 (root, prover_data)
84}