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
use snarkvm_curves::Group;
use super::PedersenCRHParameters;
pub const BOWE_HOPWOOD_CHUNK_SIZE: usize = 3;
pub const BOWE_HOPWOOD_LOOKUP_SIZE: usize = 2usize.pow(BOWE_HOPWOOD_CHUNK_SIZE as u32);
#[cfg(feature = "parallel")]
use rayon::prelude::*;
use once_cell::sync::OnceCell;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BoweHopwoodPedersenCRHParameters<G: Group> {
base_lookup: OnceCell<Vec<Vec<[G; BOWE_HOPWOOD_LOOKUP_SIZE]>>>,
}
impl<G: Group> BoweHopwoodPedersenCRHParameters<G> {
pub fn new() -> Self {
Self {
base_lookup: OnceCell::new(),
}
}
pub fn base_lookup<const NUM_WINDOWS: usize, const WINDOW_SIZE: usize>(
&self,
input: &PedersenCRHParameters<G, NUM_WINDOWS, WINDOW_SIZE>,
) -> &Vec<Vec<[G; BOWE_HOPWOOD_LOOKUP_SIZE]>> {
self.base_lookup
.get_or_try_init::<_, ()>(|| {
Ok(cfg_iter!(input.bases)
.map(|x| {
x.iter()
.map(|g| {
let mut out = [G::zero(); BOWE_HOPWOOD_LOOKUP_SIZE];
for i in 0..BOWE_HOPWOOD_LOOKUP_SIZE {
let mut encoded = *g;
if (i & 0x01) != 0 {
encoded += g;
}
if (i & 0x02) != 0 {
encoded += g.double();
}
if (i & 0x04) != 0 {
encoded = encoded.neg();
}
out[i] = encoded;
}
out
})
.collect()
})
.collect())
})
.expect("failed to init BoweHopwoodPedersenCRHParameters")
}
}