p3_challenger/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! Utilities for generating Fiat-Shamir challenges based on an IOP's transcript.

#![no_std]

extern crate alloc;

mod duplex_challenger;
mod grinding_challenger;
mod hash_challenger;
mod multi_field_challenger;
mod serializing_challenger;

use alloc::vec::Vec;
use core::array;

pub use duplex_challenger::*;
pub use grinding_challenger::*;
pub use hash_challenger::*;
pub use multi_field_challenger::*;
use p3_field::{AbstractExtensionField, Field};
pub use serializing_challenger::*;

pub trait CanObserve<T> {
    fn observe(&mut self, value: T);

    fn observe_slice(&mut self, values: &[T])
    where
        T: Clone,
    {
        for value in values {
            self.observe(value.clone());
        }
    }
}

pub trait CanSample<T> {
    fn sample(&mut self) -> T;

    fn sample_array<const N: usize>(&mut self) -> [T; N] {
        array::from_fn(|_| self.sample())
    }

    fn sample_vec(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.sample()).collect()
    }
}

pub trait CanSampleBits<T> {
    fn sample_bits(&mut self, bits: usize) -> T;
}

pub trait FieldChallenger<F: Field>:
    CanObserve<F> + CanSample<F> + CanSampleBits<usize> + Sync
{
    fn observe_ext_element<EF: AbstractExtensionField<F>>(&mut self, ext: EF) {
        self.observe_slice(ext.as_base_slice());
    }

    fn sample_ext_element<EF: AbstractExtensionField<F>>(&mut self) -> EF {
        let vec = self.sample_vec(EF::D);
        EF::from_base_slice(&vec)
    }
}

impl<'a, C, T> CanObserve<T> for &'a mut C
where
    C: CanObserve<T>,
{
    #[inline(always)]
    fn observe(&mut self, value: T) {
        (**self).observe(value)
    }

    #[inline(always)]
    fn observe_slice(&mut self, values: &[T])
    where
        T: Clone,
    {
        (**self).observe_slice(values)
    }
}

impl<'a, C, T> CanSample<T> for &'a mut C
where
    C: CanSample<T>,
{
    #[inline(always)]
    fn sample(&mut self) -> T {
        (**self).sample()
    }

    #[inline(always)]
    fn sample_array<const N: usize>(&mut self) -> [T; N] {
        (**self).sample_array()
    }

    #[inline(always)]
    fn sample_vec(&mut self, n: usize) -> Vec<T> {
        (**self).sample_vec(n)
    }
}

impl<'a, C, T> CanSampleBits<T> for &'a mut C
where
    C: CanSampleBits<T>,
{
    #[inline(always)]
    fn sample_bits(&mut self, bits: usize) -> T {
        (**self).sample_bits(bits)
    }
}

impl<'a, C, F: Field> FieldChallenger<F> for &'a mut C
where
    C: FieldChallenger<F>,
{
    #[inline(always)]
    fn observe_ext_element<EF: AbstractExtensionField<F>>(&mut self, ext: EF) {
        (**self).observe_ext_element(ext)
    }

    #[inline(always)]
    fn sample_ext_element<EF: AbstractExtensionField<F>>(&mut self) -> EF {
        (**self).sample_ext_element()
    }
}