p3_commit/
testing.rs
1use alloc::vec;
2use alloc::vec::Vec;
3use core::marker::PhantomData;
4
5use p3_challenger::CanSample;
6use p3_dft::TwoAdicSubgroupDft;
7use p3_field::{ExtensionField, Field, TwoAdicField};
8use p3_matrix::dense::RowMajorMatrix;
9use p3_matrix::Matrix;
10use p3_util::log2_strict_usize;
11use p3_util::zip_eq::zip_eq;
12use serde::{Deserialize, Serialize};
13
14use crate::{OpenedValues, Pcs, PolynomialSpace, TwoAdicMultiplicativeCoset};
15
16#[derive(Debug)]
18pub struct TrivialPcs<Val: TwoAdicField, Dft: TwoAdicSubgroupDft<Val>> {
19 pub dft: Dft,
20 pub log_n: usize,
22 pub _phantom: PhantomData<Val>,
23}
24
25pub fn eval_coeffs_at_pt<F: Field, EF: ExtensionField<F>>(
26 coeffs: &RowMajorMatrix<F>,
27 x: EF,
28) -> Vec<EF> {
29 let mut acc = vec![EF::ZERO; coeffs.width()];
30 for r in (0..coeffs.height()).rev() {
31 let row = coeffs.row_slice(r);
32 for (acc_c, row_c) in acc.iter_mut().zip(row.as_ref().iter()) {
33 *acc_c *= x;
34 *acc_c += *row_c;
35 }
36 }
37 acc
38}
39
40impl<Val, Dft, Challenge, Challenger> Pcs<Challenge, Challenger> for TrivialPcs<Val, Dft>
41where
42 Val: TwoAdicField,
43 Challenge: ExtensionField<Val>,
44 Challenger: CanSample<Challenge>,
45
46 Dft: TwoAdicSubgroupDft<Val>,
47
48 Vec<Vec<Val>>: Serialize + for<'de> Deserialize<'de>,
49{
50 type Domain = TwoAdicMultiplicativeCoset<Val>;
51 type Commitment = Vec<Vec<Val>>;
52 type ProverData = Vec<RowMajorMatrix<Val>>;
53 type EvaluationsOnDomain<'a> = Dft::Evaluations;
54 type Proof = ();
55 type Error = ();
56
57 fn natural_domain_for_degree(&self, degree: usize) -> Self::Domain {
58 TwoAdicMultiplicativeCoset {
59 log_n: log2_strict_usize(degree),
60 shift: Val::ONE,
61 }
62 }
63
64 fn commit(
65 &self,
66 evaluations: Vec<(Self::Domain, RowMajorMatrix<Val>)>,
67 ) -> (Self::Commitment, Self::ProverData) {
68 let coeffs: Vec<_> = evaluations
69 .into_iter()
70 .map(|(domain, evals)| {
71 let log_domain_size = log2_strict_usize(domain.size());
72 assert!(log_domain_size >= self.log_n);
74 assert_eq!(domain.size(), evals.height());
75 let mut coeffs = self.dft.idft_batch(evals);
77 coeffs
78 .rows_mut()
79 .zip(domain.shift.inverse().powers())
80 .for_each(|(row, weight)| {
81 row.iter_mut().for_each(|coeff| {
82 *coeff *= weight;
83 })
84 });
85 coeffs
86 })
87 .collect();
88 (
89 coeffs.clone().into_iter().map(|m| m.values).collect(),
90 coeffs,
91 )
92 }
93
94 fn get_evaluations_on_domain<'a>(
95 &self,
96 prover_data: &'a Self::ProverData,
97 idx: usize,
98 domain: Self::Domain,
99 ) -> Self::EvaluationsOnDomain<'a> {
100 let mut coeffs = prover_data[idx].clone();
101 assert!(domain.log_n >= self.log_n);
102 coeffs.values.resize(
103 coeffs.values.len() << (domain.log_n - self.log_n),
104 Val::ZERO,
105 );
106 self.dft.coset_dft_batch(coeffs, domain.shift)
107 }
108
109 fn open(
110 &self,
111 rounds: Vec<(
113 &Self::ProverData,
114 Vec<
116 Vec<Challenge>,
118 >,
119 )>,
120 _challenger: &mut Challenger,
121 ) -> (OpenedValues<Challenge>, Self::Proof) {
122 (
123 rounds
124 .into_iter()
125 .map(|(coeffs_for_round, points_for_round)| {
126 debug_assert_eq!(coeffs_for_round.len(), points_for_round.len());
128 coeffs_for_round
129 .iter()
130 .zip(points_for_round)
131 .map(|(coeffs_for_mat, points_for_mat)| {
132 points_for_mat
133 .into_iter()
134 .map(|pt| eval_coeffs_at_pt(coeffs_for_mat, pt))
135 .collect()
136 })
137 .collect()
138 })
139 .collect(),
140 (),
141 )
142 }
143
144 #[allow(clippy::panic_in_result_fn)]
146 fn verify(
147 &self,
148 rounds: Vec<(
150 Self::Commitment,
151 Vec<(
153 Self::Domain,
155 Vec<(
157 Challenge,
158 Vec<Challenge>,
160 )>,
161 )>,
162 )>,
163 _proof: &Self::Proof,
164 _challenger: &mut Challenger,
165 ) -> Result<(), Self::Error> {
166 for (comm, round_opening) in rounds {
167 for (coeff_vec, (domain, points_and_values)) in zip_eq(comm, round_opening, ())? {
168 let width = coeff_vec.len() / domain.size();
169 assert_eq!(width * domain.size(), coeff_vec.len());
170 let coeffs = RowMajorMatrix::new(coeff_vec, width);
171 for (pt, values) in points_and_values {
172 assert_eq!(eval_coeffs_at_pt(&coeffs, pt), values);
173 }
174 }
175 }
176 Ok(())
177 }
178}