miden_lifted_stark/pcs/
proof.rs1use alloc::vec::Vec;
4
5use miden_stark_transcript::{TranscriptError, VerifierChannel};
6use p3_field::{ExtensionField, Field, TwoAdicField};
7
8use crate::{
9 lmcs::{Lmcs, tree_indices::TreeIndices},
10 pcs::{deep::proof::DeepTranscript, fri::proof::FriTranscript, params::PcsParams},
11};
12
13pub struct PcsTranscript<EF, L>
17where
18 L: Lmcs,
19 L::F: Field,
20 EF: ExtensionField<L::F>,
21{
22 pub deep_transcript: DeepTranscript<L::F, EF>,
24 pub fri_transcript: FriTranscript<L::F, EF, L::Commitment>,
26 pub query_pow_witness: L::F,
28 pub query_indices: Vec<usize>,
30 pub deep_witnesses: Vec<L::BatchProof>,
32 pub fri_witnesses: Vec<L::BatchProof>,
34}
35
36impl<EF, L> PcsTranscript<EF, L>
37where
38 L: Lmcs,
39 L::F: TwoAdicField,
40 EF: ExtensionField<L::F>,
41{
42 pub fn from_verifier_channel<Ch, const N: usize>(
54 params: &PcsParams,
55 lmcs: &L,
56 commitments: &[(L::Commitment, Vec<usize>)],
57 log_lde_height: u8,
58 eval_points: [EF; N],
59 channel: &mut Ch,
60 ) -> Result<Self, TranscriptError>
61 where
62 Ch: VerifierChannel<F = L::F, Commitment = L::Commitment>,
63 {
64 if commitments.is_empty() {
65 return Err(TranscriptError::NoMoreFields);
66 }
67
68 let deep_transcript = DeepTranscript::from_verifier_channel::<Ch>(
69 ¶ms.deep,
70 commitments,
71 eval_points.len(),
72 channel,
73 )?;
74
75 let fri_transcript =
76 FriTranscript::from_verifier_channel(¶ms.fri, log_lde_height, channel)?;
77
78 let query_pow_witness = channel.grind(params.query_pow_bits())?;
79
80 let query_indices: Vec<usize> = (0..params.num_queries())
82 .map(|_| channel.sample_bits(log_lde_height as usize))
83 .collect();
84 let tree_indices = TreeIndices::new(query_indices.iter().copied(), log_lde_height)
85 .expect("sampled indices are in range");
86
87 let deep_witnesses: Vec<_> = commitments
88 .iter()
89 .map(|(_commitment, widths)| {
90 lmcs.read_batch_proof(widths, &tree_indices, channel).map_err(|e| match e {
91 crate::lmcs::LmcsError::TranscriptError(te) => te,
92 _ => TranscriptError::NoMoreFields,
93 })
94 })
95 .collect::<Result<Vec<_>, _>>()?;
96
97 let log_arity = params.fri.fold.log_arity();
98 let arity = params.fri.fold.arity();
99 let num_rounds = params.fri.num_rounds(log_lde_height);
100
101 let mut fri_witnesses = Vec::with_capacity(num_rounds);
102 let mut round_indices = tree_indices;
103 for _round in 0..num_rounds {
104 round_indices.shrink_depth(log_arity);
105 let base_width = arity * EF::DIMENSION;
106 let round_widths = [base_width];
108 let batch = lmcs.read_batch_proof(&round_widths, &round_indices, channel).map_err(
109 |e| match e {
110 crate::lmcs::LmcsError::TranscriptError(te) => te,
111 _ => TranscriptError::NoMoreFields,
112 },
113 )?;
114 fri_witnesses.push(batch);
115 }
116
117 Ok(Self {
118 deep_transcript,
119 fri_transcript,
120 query_pow_witness,
121 query_indices,
122 deep_witnesses,
123 fri_witnesses,
124 })
125 }
126}