p3_challenger/
lib.rs

1//! Utilities for generating Fiat-Shamir challenges based on an IOP's transcript.
2
3#![no_std]
4
5extern crate alloc;
6
7mod duplex_challenger;
8mod grinding_challenger;
9mod hash_challenger;
10mod multi_field_challenger;
11mod serializing_challenger;
12
13use alloc::vec::Vec;
14use core::array;
15
16pub use duplex_challenger::*;
17pub use grinding_challenger::*;
18pub use hash_challenger::*;
19pub use multi_field_challenger::*;
20use p3_field::{Field, FieldExtensionAlgebra};
21pub use serializing_challenger::*;
22
23pub trait CanObserve<T> {
24    fn observe(&mut self, value: T);
25
26    fn observe_slice(&mut self, values: &[T])
27    where
28        T: Clone,
29    {
30        for value in values {
31            self.observe(value.clone());
32        }
33    }
34}
35
36pub trait CanSample<T> {
37    fn sample(&mut self) -> T;
38
39    fn sample_array<const N: usize>(&mut self) -> [T; N] {
40        array::from_fn(|_| self.sample())
41    }
42
43    fn sample_vec(&mut self, n: usize) -> Vec<T> {
44        (0..n).map(|_| self.sample()).collect()
45    }
46}
47
48pub trait CanSampleBits<T> {
49    fn sample_bits(&mut self, bits: usize) -> T;
50}
51
52pub trait FieldChallenger<F: Field>:
53    CanObserve<F> + CanSample<F> + CanSampleBits<usize> + Sync
54{
55    fn observe_ext_element<EF: FieldExtensionAlgebra<F>>(&mut self, ext: EF) {
56        self.observe_slice(ext.as_base_slice());
57    }
58
59    fn sample_ext_element<EF: FieldExtensionAlgebra<F>>(&mut self) -> EF {
60        let vec = self.sample_vec(EF::D);
61        EF::from_base_slice(&vec)
62    }
63}
64
65impl<C, T> CanObserve<T> for &mut C
66where
67    C: CanObserve<T>,
68{
69    #[inline(always)]
70    fn observe(&mut self, value: T) {
71        (*self).observe(value)
72    }
73
74    #[inline(always)]
75    fn observe_slice(&mut self, values: &[T])
76    where
77        T: Clone,
78    {
79        (*self).observe_slice(values)
80    }
81}
82
83impl<C, T> CanSample<T> for &mut C
84where
85    C: CanSample<T>,
86{
87    #[inline(always)]
88    fn sample(&mut self) -> T {
89        (*self).sample()
90    }
91
92    #[inline(always)]
93    fn sample_array<const N: usize>(&mut self) -> [T; N] {
94        (*self).sample_array()
95    }
96
97    #[inline(always)]
98    fn sample_vec(&mut self, n: usize) -> Vec<T> {
99        (*self).sample_vec(n)
100    }
101}
102
103impl<C, T> CanSampleBits<T> for &mut C
104where
105    C: CanSampleBits<T>,
106{
107    #[inline(always)]
108    fn sample_bits(&mut self, bits: usize) -> T {
109        (*self).sample_bits(bits)
110    }
111}
112
113impl<C, F: Field> FieldChallenger<F> for &mut C
114where
115    C: FieldChallenger<F>,
116{
117    #[inline(always)]
118    fn observe_ext_element<EF: FieldExtensionAlgebra<F>>(&mut self, ext: EF) {
119        (*self).observe_ext_element(ext)
120    }
121
122    #[inline(always)]
123    fn sample_ext_element<EF: FieldExtensionAlgebra<F>>(&mut self) -> EF {
124        (*self).sample_ext_element()
125    }
126}