1use alloc::vec::Vec;
2use core::marker::PhantomData;
3
4use p3_field::{BasedVectorSpace, PrimeField32, PrimeField64};
5use p3_maybe_rayon::prelude::*;
6use p3_symmetric::{CryptographicHasher, Hash, MerkleCap};
7use p3_util::log2_ceil_u64;
8use tracing::instrument;
9
10use crate::{
11 CanFinalizeDigest, CanObserve, CanSample, CanSampleBits, FieldChallenger, GrindingChallenger,
12 HashChallenger,
13};
14
15#[derive(Clone, Debug)]
25pub struct SerializingChallenger32<F, Inner> {
26 inner: Inner,
27 _marker: PhantomData<F>,
28}
29
30#[derive(Clone, Debug)]
40pub struct SerializingChallenger64<F, Inner> {
41 inner: Inner,
42 _marker: PhantomData<F>,
43}
44
45impl<F: PrimeField32, Inner: CanObserve<u8>> SerializingChallenger32<F, Inner> {
46 pub const fn new(inner: Inner) -> Self {
47 Self {
48 inner,
49 _marker: PhantomData,
50 }
51 }
52}
53
54impl<F, H> SerializingChallenger32<F, HashChallenger<u8, H, 32>>
55where
56 F: PrimeField32,
57 H: CryptographicHasher<u8, [u8; 32]>,
58{
59 pub const fn from_hasher(initial_state: Vec<u8>, hasher: H) -> Self {
60 Self::new(HashChallenger::new(initial_state, hasher))
61 }
62}
63
64impl<F: PrimeField32, Inner: CanObserve<u8>> CanObserve<F> for SerializingChallenger32<F, Inner> {
65 fn observe(&mut self, value: F) {
66 self.inner
67 .observe_slice(&value.to_unique_u32().to_le_bytes());
68 }
69}
70
71impl<F: PrimeField32, const N: usize, Inner: CanObserve<u8>> CanObserve<Hash<F, u8, N>>
72 for SerializingChallenger32<F, Inner>
73{
74 fn observe(&mut self, values: Hash<F, u8, N>) {
75 for value in values {
76 self.inner.observe(value);
77 }
78 }
79}
80
81impl<F: PrimeField32, const N: usize, Inner: CanObserve<u8>> CanObserve<Hash<F, u64, N>>
82 for SerializingChallenger32<F, Inner>
83{
84 fn observe(&mut self, values: Hash<F, u64, N>) {
85 for value in values {
86 self.inner.observe_slice(&value.to_le_bytes());
87 }
88 }
89}
90
91impl<F: PrimeField32, const N: usize, Inner: CanObserve<u8>> CanObserve<&MerkleCap<F, [u8; N]>>
92 for SerializingChallenger32<F, Inner>
93{
94 fn observe(&mut self, cap: &MerkleCap<F, [u8; N]>) {
95 for digest in cap.roots() {
96 for value in digest {
97 self.inner.observe(*value);
98 }
99 }
100 }
101}
102
103impl<F: PrimeField32, const N: usize, Inner: CanObserve<u8>> CanObserve<MerkleCap<F, [u8; N]>>
104 for SerializingChallenger32<F, Inner>
105{
106 fn observe(&mut self, cap: MerkleCap<F, [u8; N]>) {
107 self.observe(&cap);
108 }
109}
110
111impl<F: PrimeField32, const N: usize, Inner: CanObserve<u8>> CanObserve<&MerkleCap<F, [u64; N]>>
112 for SerializingChallenger32<F, Inner>
113{
114 fn observe(&mut self, cap: &MerkleCap<F, [u64; N]>) {
115 for digest in cap.roots() {
116 for value in digest {
117 self.inner.observe_slice(&value.to_le_bytes());
118 }
119 }
120 }
121}
122
123impl<F: PrimeField32, const N: usize, Inner: CanObserve<u8>> CanObserve<MerkleCap<F, [u64; N]>>
124 for SerializingChallenger32<F, Inner>
125{
126 fn observe(&mut self, cap: MerkleCap<F, [u64; N]>) {
127 self.observe(&cap);
128 }
129}
130
131impl<F, EF, Inner> CanSample<EF> for SerializingChallenger32<F, Inner>
132where
133 F: PrimeField32,
134 EF: BasedVectorSpace<F>,
135 Inner: CanSample<u8>,
136{
137 fn sample(&mut self) -> EF {
138 let modulus = F::ORDER_U32;
139 let log_size = log2_ceil_u64(F::ORDER_U64);
140 let pow_of_two_bound = ((1u64 << log_size) - 1) as u32;
142 let sample_base = |inner: &mut Inner| loop {
144 let value = u32::from_le_bytes(inner.sample_array());
145 let value = value & pow_of_two_bound;
146 if value < modulus {
147 return unsafe {
148 F::from_canonical_unchecked(value)
150 };
151 }
152 };
153 EF::from_basis_coefficients_fn(|_| sample_base(&mut self.inner))
154 }
155}
156
157impl<F, Inner> CanSampleBits<usize> for SerializingChallenger32<F, Inner>
158where
159 F: PrimeField32,
160 Inner: CanSample<u8>,
161{
162 fn sample_bits(&mut self, bits: usize) -> usize {
163 assert!(bits < (usize::BITS as usize));
164 assert!((1 << bits) <= F::ORDER_U64 as usize);
166 let rand_usize = u32::from_le_bytes(self.inner.sample_array()) as usize;
167 rand_usize & ((1 << bits) - 1)
168 }
169}
170
171impl<F, Inner> GrindingChallenger for SerializingChallenger32<F, Inner>
172where
173 F: PrimeField32,
174 Inner: CanSample<u8> + CanObserve<u8> + Clone + Send + Sync,
175{
176 type Witness = F;
177
178 #[instrument(name = "grind for proof-of-work witness", skip_all)]
179 fn grind(&mut self, bits: usize) -> Self::Witness {
180 assert!(bits < (usize::BITS as usize));
181 assert!((1 << bits) < F::ORDER_U32);
182 let witness = (0..F::ORDER_U32)
183 .into_par_iter()
184 .map(|i| unsafe {
185 F::from_canonical_unchecked(i)
187 })
188 .find_any(|witness| self.clone().check_witness(bits, *witness))
189 .expect("failed to find witness");
190 assert!(self.check_witness(bits, witness));
191 witness
192 }
193}
194
195impl<F, Inner> FieldChallenger<F> for SerializingChallenger32<F, Inner>
196where
197 F: PrimeField32,
198 Inner: CanSample<u8> + CanObserve<u8> + Clone + Send + Sync,
199{
200}
201
202impl<F: PrimeField64, Inner: CanObserve<u8>> SerializingChallenger64<F, Inner> {
203 pub const fn new(inner: Inner) -> Self {
204 Self {
205 inner,
206 _marker: PhantomData,
207 }
208 }
209}
210
211impl<F, H> SerializingChallenger64<F, HashChallenger<u8, H, 32>>
212where
213 F: PrimeField64,
214 H: CryptographicHasher<u8, [u8; 32]>,
215{
216 pub const fn from_hasher(initial_state: Vec<u8>, hasher: H) -> Self {
217 Self::new(HashChallenger::new(initial_state, hasher))
218 }
219}
220
221impl<F: PrimeField64, Inner: CanObserve<u8>> CanObserve<F> for SerializingChallenger64<F, Inner> {
222 fn observe(&mut self, value: F) {
223 self.inner
224 .observe_slice(&value.to_unique_u64().to_le_bytes());
225 }
226}
227
228impl<F: PrimeField64, const N: usize, Inner: CanObserve<u8>> CanObserve<Hash<F, u8, N>>
229 for SerializingChallenger64<F, Inner>
230{
231 fn observe(&mut self, values: Hash<F, u8, N>) {
232 for value in values {
233 self.inner.observe(value);
234 }
235 }
236}
237
238impl<F: PrimeField64, const N: usize, Inner: CanObserve<u8>> CanObserve<Hash<F, u64, N>>
239 for SerializingChallenger64<F, Inner>
240{
241 fn observe(&mut self, values: Hash<F, u64, N>) {
242 for value in values {
243 self.inner.observe_slice(&value.to_le_bytes());
244 }
245 }
246}
247
248impl<F: PrimeField64, const N: usize, Inner: CanObserve<u8>> CanObserve<&MerkleCap<F, [u8; N]>>
249 for SerializingChallenger64<F, Inner>
250{
251 fn observe(&mut self, cap: &MerkleCap<F, [u8; N]>) {
252 for digest in cap.roots() {
253 for value in digest {
254 self.inner.observe(*value);
255 }
256 }
257 }
258}
259
260impl<F: PrimeField64, const N: usize, Inner: CanObserve<u8>> CanObserve<MerkleCap<F, [u8; N]>>
261 for SerializingChallenger64<F, Inner>
262{
263 fn observe(&mut self, cap: MerkleCap<F, [u8; N]>) {
264 self.observe(&cap);
265 }
266}
267
268impl<F: PrimeField64, const N: usize, Inner: CanObserve<u8>> CanObserve<&MerkleCap<F, [u64; N]>>
269 for SerializingChallenger64<F, Inner>
270{
271 fn observe(&mut self, cap: &MerkleCap<F, [u64; N]>) {
272 for digest in cap.roots() {
273 for value in digest {
274 self.inner.observe_slice(&value.to_le_bytes());
275 }
276 }
277 }
278}
279
280impl<F: PrimeField64, const N: usize, Inner: CanObserve<u8>> CanObserve<MerkleCap<F, [u64; N]>>
281 for SerializingChallenger64<F, Inner>
282{
283 fn observe(&mut self, cap: MerkleCap<F, [u64; N]>) {
284 self.observe(&cap);
285 }
286}
287
288impl<F, EF, Inner> CanSample<EF> for SerializingChallenger64<F, Inner>
289where
290 F: PrimeField64,
291 EF: BasedVectorSpace<F>,
292 Inner: CanSample<u8>,
293{
294 fn sample(&mut self) -> EF {
295 let modulus = F::ORDER_U64;
296 let log_size = log2_ceil_u64(F::ORDER_U64) as u32;
297 let pow_of_two_bound = ((1u128 << log_size) - 1) as u64;
299
300 let sample_base = |inner: &mut Inner| loop {
302 let value = u64::from_le_bytes(inner.sample_array());
303 let value = value & pow_of_two_bound;
304 if value < modulus {
305 return unsafe {
306 F::from_canonical_unchecked(value)
308 };
309 }
310 };
311 EF::from_basis_coefficients_fn(|_| sample_base(&mut self.inner))
312 }
313}
314
315impl<F, Inner> CanSampleBits<usize> for SerializingChallenger64<F, Inner>
316where
317 F: PrimeField64,
318 Inner: CanSample<u8>,
319{
320 fn sample_bits(&mut self, bits: usize) -> usize {
321 assert!(bits < (usize::BITS as usize));
322 assert!((1u64 << bits) <= F::ORDER_U64);
323 let rand_u64 = u64::from_le_bytes(self.inner.sample_array());
324 (rand_u64 & ((1u64 << bits) - 1)) as usize
325 }
326}
327
328impl<F, Inner> GrindingChallenger for SerializingChallenger64<F, Inner>
329where
330 F: PrimeField64,
331 Inner: CanSample<u8> + CanObserve<u8> + Clone + Send + Sync,
332{
333 type Witness = F;
334
335 #[instrument(name = "grind for proof-of-work witness", skip_all)]
336 fn grind(&mut self, bits: usize) -> Self::Witness {
337 assert!(bits < 64);
338 assert!((1u64 << bits) < F::ORDER_U64);
339 let witness = (0..F::ORDER_U64)
340 .into_par_iter()
341 .map(|i| unsafe {
342 F::from_canonical_unchecked(i)
344 })
345 .find_any(|witness| self.clone().check_witness(bits, *witness))
346 .expect("failed to find witness");
347 assert!(self.check_witness(bits, witness));
348 witness
349 }
350}
351
352impl<F, Inner> FieldChallenger<F> for SerializingChallenger64<F, Inner>
353where
354 F: PrimeField64,
355 Inner: CanSample<u8> + CanObserve<u8> + Clone + Send + Sync,
356{
357}
358
359impl<F, Inner> CanFinalizeDigest for SerializingChallenger32<F, Inner>
360where
361 Inner: CanFinalizeDigest,
362{
363 type Digest = Inner::Digest;
364
365 fn finalize(self) -> Self::Digest {
366 self.inner.finalize()
367 }
368}
369
370impl<F, Inner> CanFinalizeDigest for SerializingChallenger64<F, Inner>
371where
372 Inner: CanFinalizeDigest,
373{
374 type Digest = Inner::Digest;
375
376 fn finalize(self) -> Self::Digest {
377 self.inner.finalize()
378 }
379}