1use std::{borrow::BorrowMut, marker::PhantomData};
16
17use binius_core::word::Word;
18use binius_field::{BinaryField, Field};
19use binius_hash::HashSuite;
20use binius_ip::channel::{IPVerifierChannel, WordIPVerifierChannel};
21use binius_transcript::{VerifierTranscript, fiat_shamir::Challenger};
22use binius_utils::{DeserializeBytes, FixedSizeSerializeBytes};
23use digest::Output;
24
25use crate::{
26 channel::grinding::GrindingVerifierChannel,
27 merkle_tree::{BinaryMerkleTreeScheme, Commitment, MerkleTreeScheme},
28};
29
30pub trait MerkleIPVerifierChannel<F: Field>: WordIPVerifierChannel<F> {
36 type Commitment: Clone;
38
39 fn recv_merkle_commitment(
43 &mut self,
44 leaf_size: usize,
45 depth: usize,
46 ) -> Result<Self::Commitment, Error>;
47
48 fn recv_openings(
56 &mut self,
57 commitment: &Self::Commitment,
58 indices: &[Self::Word],
59 ) -> Result<Vec<Self::Elem>, Error>;
60
61 fn recv_committed_vector(
65 &mut self,
66 commitment: &Self::Commitment,
67 ) -> Result<Vec<Self::Elem>, Error>;
68}
69
70pub struct VerifierMerkleTranscriptChannel<T, Challenger_, F, H: HashSuite> {
76 transcript: T,
77 scheme: BinaryMerkleTreeScheme<F, H>,
78 _challenger_marker: PhantomData<Challenger_>,
79}
80
81impl<T, Challenger_, F, H: HashSuite> VerifierMerkleTranscriptChannel<T, Challenger_, F, H> {
82 pub fn new(transcript: T) -> Self {
84 Self::with_scheme(transcript, BinaryMerkleTreeScheme::new())
85 }
86
87 pub const fn with_scheme(transcript: T, scheme: BinaryMerkleTreeScheme<F, H>) -> Self {
89 Self {
90 transcript,
91 scheme,
92 _challenger_marker: PhantomData,
93 }
94 }
95
96 pub fn into_transcript(self) -> T {
98 self.transcript
99 }
100}
101
102#[derive(Debug, Clone)]
104pub struct TranscriptMerkleCommitment<Digest> {
105 pub commitment: Commitment<Digest>,
107 pub leaf_size: usize,
109}
110
111impl<F, T, Challenger_, H> IPVerifierChannel<F>
112 for VerifierMerkleTranscriptChannel<T, Challenger_, F, H>
113where
114 F: Field,
115 T: BorrowMut<VerifierTranscript<Challenger_>>,
116 Challenger_: Challenger,
117 H: HashSuite,
118{
119 type Elem = F;
120
121 fn recv_one(&mut self) -> Result<F, binius_ip::channel::Error> {
122 self.transcript.borrow_mut().recv_one()
123 }
124
125 fn recv_many(&mut self, n: usize) -> Result<Vec<F>, binius_ip::channel::Error> {
126 self.transcript.borrow_mut().recv_many(n)
127 }
128
129 fn recv_array<const N: usize>(&mut self) -> Result<[F; N], binius_ip::channel::Error> {
130 self.transcript.borrow_mut().recv_array()
131 }
132
133 fn sample(&mut self) -> F {
134 IPVerifierChannel::sample(self.transcript.borrow_mut())
135 }
136
137 fn observe_one(&mut self, val: F) -> F {
138 self.transcript.borrow_mut().observe_one(val)
139 }
140
141 fn observe_many(&mut self, vals: &[F]) -> Vec<F> {
142 self.transcript.borrow_mut().observe_many(vals)
143 }
144
145 fn assert_zero(&mut self, val: F) -> Result<(), binius_ip::channel::Error> {
146 self.transcript.borrow_mut().assert_zero(val)
147 }
148}
149
150impl<F, T, Challenger_, H> WordIPVerifierChannel<F>
151 for VerifierMerkleTranscriptChannel<T, Challenger_, F, H>
152where
153 F: BinaryField,
154 T: BorrowMut<VerifierTranscript<Challenger_>>,
155 Challenger_: Challenger,
156 H: HashSuite,
157{
158 type Word = Word;
159
160 fn observe_words(&mut self, words: &[Word]) -> Vec<Word> {
161 WordIPVerifierChannel::<F>::observe_words(self.transcript.borrow_mut(), words)
162 }
163
164 fn subset_sum(&mut self, elems: &[F], word: &Word) -> F {
165 WordIPVerifierChannel::<F>::subset_sum(self.transcript.borrow_mut(), elems, word)
166 }
167
168 fn select(&mut self, elems: &[F], word: &Word) -> F {
169 WordIPVerifierChannel::<F>::select(self.transcript.borrow_mut(), elems, word)
170 }
171
172 fn sample_bits(&mut self, bits: usize) -> Word {
173 WordIPVerifierChannel::<F>::sample_bits(self.transcript.borrow_mut(), bits)
174 }
175
176 fn pack_words(&mut self, words: &[Word]) -> Vec<F> {
177 WordIPVerifierChannel::<F>::pack_words(self.transcript.borrow_mut(), words)
178 }
179}
180
181impl<T, Challenger_, F, H: HashSuite> GrindingVerifierChannel
182 for VerifierMerkleTranscriptChannel<T, Challenger_, F, H>
183where
184 T: BorrowMut<VerifierTranscript<Challenger_>>,
185 Challenger_: Challenger,
186{
187 fn verify_grind(&mut self, bits: usize) -> Result<(), binius_transcript::Error> {
188 if bits == 0 {
190 return Ok(());
191 }
192 self.transcript.borrow_mut().verify_grind(bits)?;
193 Ok(())
194 }
195}
196
197impl<F, T, Challenger_, H> MerkleIPVerifierChannel<F>
198 for VerifierMerkleTranscriptChannel<T, Challenger_, F, H>
199where
200 F: BinaryField + FixedSizeSerializeBytes,
201 T: BorrowMut<VerifierTranscript<Challenger_>>,
202 Challenger_: Challenger,
203 H: HashSuite,
204 Output<H::LeafHash>: DeserializeBytes,
205{
206 type Commitment = TranscriptMerkleCommitment<Output<H::LeafHash>>;
207
208 fn recv_merkle_commitment(
209 &mut self,
210 leaf_size: usize,
211 depth: usize,
212 ) -> Result<Self::Commitment, Error> {
213 let root = self.transcript.borrow_mut().message().read()?;
214 Ok(TranscriptMerkleCommitment {
215 commitment: Commitment { root, depth },
216 leaf_size,
217 })
218 }
219
220 fn recv_openings(
221 &mut self,
222 commitment: &Self::Commitment,
223 indices: &[Word],
224 ) -> Result<Vec<F>, Error> {
225 let tree_depth = commitment.commitment.depth;
226 let indices = indices
227 .iter()
228 .map(|index| index.as_u64() as usize)
229 .collect::<Vec<_>>();
230 assert!(indices.iter().all(|&index| index < 1 << tree_depth)); let layer_depth = self.scheme.optimal_verify_layer(indices.len(), tree_depth);
234 let mut advice = self.transcript.borrow_mut().decommitment();
235 let layer_digests = advice.read_vec(1 << layer_depth)?;
236 self.scheme
237 .verify_layer(&commitment.commitment.root, layer_depth, &layer_digests)?;
238
239 let mut values = Vec::with_capacity(indices.len() * commitment.leaf_size);
240 for &index in &indices {
241 let leaf = advice.read_scalar_slice::<F>(commitment.leaf_size)?;
242 self.scheme.verify_opening(
243 index,
244 &leaf,
245 layer_depth,
246 tree_depth,
247 &layer_digests,
248 &mut advice,
249 )?;
250 values.extend_from_slice(&leaf);
251 }
252 Ok(values)
253 }
254
255 fn recv_committed_vector(&mut self, commitment: &Self::Commitment) -> Result<Vec<F>, Error> {
256 let len = commitment.leaf_size << commitment.commitment.depth;
257 let data = self
258 .transcript
259 .borrow_mut()
260 .decommitment()
261 .read_scalar_slice::<F>(len)?;
262 self.scheme
263 .verify_vector(&commitment.commitment.root, &data, commitment.leaf_size)?;
264 Ok(data)
265 }
266}
267
268#[derive(Debug, thiserror::Error)]
270pub enum Error {
271 #[error("IP channel error: {0}")]
272 IPChannel(#[from] binius_ip::channel::Error),
273 #[error("Merkle tree error: {0}")]
274 MerkleTree(#[from] crate::merkle_tree::Error),
275 #[error("transcript error: {0}")]
276 Transcript(#[from] binius_transcript::Error),
277}