p3_commit/adapters/
extension_mmcs.rs1use alloc::vec::Vec;
2use core::marker::PhantomData;
3use core::ops::Deref;
4
5use p3_field::{ExtensionField, Field};
6use p3_matrix::extension::FlatMatrixView;
7use p3_matrix::{Dimensions, Matrix};
8
9use crate::{BatchOpening, BatchOpeningRef, Mmcs};
10
11#[derive(Clone, Debug)]
17pub struct ExtensionMmcs<F, EF, InnerMmcs> {
18 pub(crate) inner: InnerMmcs,
20
21 pub(crate) _phantom: PhantomData<(F, EF)>,
22}
23
24impl<F, EF, InnerMmcs> ExtensionMmcs<F, EF, InnerMmcs> {
25 pub const fn new(inner: InnerMmcs) -> Self {
26 Self {
27 inner,
28 _phantom: PhantomData,
29 }
30 }
31}
32
33impl<F, EF, InnerMmcs> Mmcs<EF> for ExtensionMmcs<F, EF, InnerMmcs>
34where
35 F: Field,
36 EF: ExtensionField<F>,
37 InnerMmcs: Mmcs<F>,
38{
39 type ProverData<M> = InnerMmcs::ProverData<FlatMatrixView<F, EF, M>>;
40 type Commitment = InnerMmcs::Commitment;
41 type Proof = InnerMmcs::Proof;
42 type MultiProof = InnerMmcs::MultiProof;
43 type Error = InnerMmcs::Error;
44
45 fn commit<M: Matrix<EF>>(&self, inputs: Vec<M>) -> (Self::Commitment, Self::ProverData<M>) {
46 self.inner
47 .commit(inputs.into_iter().map(FlatMatrixView::new).collect())
48 }
49
50 fn open_batch<M: Matrix<EF>>(
51 &self,
52 index: usize,
53 prover_data: &Self::ProverData<M>,
54 ) -> BatchOpening<EF, Self> {
55 let (inner_opened_values, inner_proof) = self.inner.open_batch(index, prover_data).unpack();
56 let opened_ext_values = inner_opened_values
57 .into_iter()
58 .map(EF::reconstitute_from_base)
59 .collect();
60 BatchOpening::new(opened_ext_values, inner_proof)
61 }
62
63 fn get_matrices<'a, M: Matrix<EF>>(&self, prover_data: &'a Self::ProverData<M>) -> Vec<&'a M> {
64 self.inner
65 .get_matrices(prover_data)
66 .into_iter()
67 .map(|mat| mat.deref())
68 .collect()
69 }
70
71 fn verify_batch(
72 &self,
73 commit: &Self::Commitment,
74 dimensions: &[Dimensions],
75 index: usize,
76 batch_opening: BatchOpeningRef<'_, EF, Self>,
77 ) -> Result<(), Self::Error> {
78 let opened_base_values: Vec<Vec<F>> = batch_opening
79 .opened_values
80 .iter()
81 .cloned()
82 .map(EF::flatten_to_base)
83 .collect();
84 let base_dimensions = dimensions
85 .iter()
86 .map(|dim| Dimensions {
87 width: dim.width * EF::DIMENSION,
88 height: dim.height,
89 })
90 .collect::<Vec<_>>();
91 self.inner.verify_batch(
92 commit,
93 &base_dimensions,
94 index,
95 BatchOpeningRef::new(&opened_base_values, batch_opening.opening_proof),
96 )
97 }
98
99 fn open_multi_batch<M: Matrix<EF>>(
100 &self,
101 indices: &[usize],
102 prover_data: &Self::ProverData<M>,
103 ) -> (Vec<Vec<Vec<EF>>>, Self::MultiProof) {
104 let (base_values, proof) = self.inner.open_multi_batch(indices, prover_data);
105 let ext_values = base_values
106 .into_iter()
107 .map(|rows| rows.into_iter().map(EF::reconstitute_from_base).collect())
108 .collect();
109 (ext_values, proof)
110 }
111
112 fn verify_multi_batch<R: AsRef<[EF]> + PartialEq>(
113 &self,
114 commit: &Self::Commitment,
115 dimensions: &[Dimensions],
116 indices: &[usize],
117 opened_values: &[Vec<R>],
118 proof: &Self::MultiProof,
119 ) -> Result<(), Self::Error> {
120 let opened_base_values: Vec<Vec<Vec<F>>> = opened_values
123 .iter()
124 .map(|rows| {
125 rows.iter()
126 .map(|row| EF::flatten_to_base(row.as_ref().to_vec()))
127 .collect()
128 })
129 .collect();
130 let base_dimensions = dimensions
131 .iter()
132 .map(|dim| Dimensions {
133 width: dim.width * EF::DIMENSION,
134 height: dim.height,
135 })
136 .collect::<Vec<_>>();
137 self.inner.verify_multi_batch(
138 commit,
139 &base_dimensions,
140 indices,
141 &opened_base_values,
142 proof,
143 )
144 }
145}