-
Notifications
You must be signed in to change notification settings - Fork 138
/
Copy pathchallenge.rs
57 lines (51 loc) · 2.02 KB
/
challenge.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
use ark_ff::PrimeField;
use ark_sponge::CryptographicSponge;
/// Challenge Generator (todo doc)
/// TODO: move it to sponge
/// Note that mutable reference cannot be cloned.
pub enum ChallengeGenerator<'a, F: PrimeField, S: 'a + CryptographicSponge> {
/// Each challenge is freshly squeezed from a sponge.
Multivariate(&'a mut S),
/// Each challenge is a power of one squeezed element from sponge.
///
/// `Univariate(generator, next_element)`
Univariate(F, F),
}
impl<'a, F: PrimeField, S: 'a + CryptographicSponge> ChallengeGenerator<'a, F, S> {
/// Returns a challenge generator with multivariate strategy. Each challenge is freshly squeezed
/// from a sponge.
pub fn new_multivariate(sponge: &'a mut S) -> Self {
Self::Multivariate(sponge)
}
/// Returns a challenge generator with univariate strategy. Each challenge is a power of one
/// squeezed element from sponge.
pub fn new_univariate(sponge: &mut S) -> Self {
let gen = sponge.squeeze_field_elements(1)[0];
Self::Univariate(gen, gen)
}
/// Returns the next challenge generated.
pub fn next_challenge(&mut self) -> F {
match self {
Self::Multivariate(s) => s.squeeze_field_elements(1)[0],
Self::Univariate(gen, next) => {
let result = next.clone();
*next *= *gen;
result
}
}
}
/// Returns the next challenge generated where next challenge has `size` bits. Only works for
/// multivariate generator.
///
/// ## Panics
/// This function will panic if `self` is univariate.
pub fn next_challenge_of_size(&mut self, size: ark_sponge::FieldElementSize) -> F {
match self {
Self::Multivariate(s) => s.squeeze_field_elements_with_sizes(&[size])[0],
Self::Univariate(_, _) => {
panic!("`next_challenge_of_size` only supports multivariate generator.")
}
}
}
// TODO: pub fn next_challenge_with_bit_size -> Option<F>
}