1use lazy_static::lazy_static;
6
7use sha3::{Digest, Keccak256};
8
9use curve25519_dalek::{
10 constants::ED25519_BASEPOINT_POINT,
11 edwards::{EdwardsPoint as DalekPoint, CompressedEdwardsY},
12};
13
14use group::Group;
15use dalek_ff_group::EdwardsPoint;
16
17mod varint;
18use varint::write_varint;
19
20mod hash_to_point;
21pub use hash_to_point::hash_to_point;
22
23fn hash(data: &[u8]) -> [u8; 32] {
24 Keccak256::digest(data).into()
25}
26
27lazy_static! {
28 pub static ref H: DalekPoint =
30 CompressedEdwardsY(hash(&ED25519_BASEPOINT_POINT.compress().to_bytes()))
31 .decompress()
32 .unwrap()
33 .mul_by_cofactor();
34}
35
36const MAX_M: usize = 16;
37const N: usize = 64;
38const MAX_MN: usize = MAX_M * N;
39
40#[allow(non_snake_case)]
42pub struct Generators {
43 pub G: [EdwardsPoint; MAX_MN],
44 pub H: [EdwardsPoint; MAX_MN],
45}
46
47pub fn bulletproofs_generators(dst: &'static [u8]) -> Generators {
49 let mut res =
50 Generators { G: [EdwardsPoint::identity(); MAX_MN], H: [EdwardsPoint::identity(); MAX_MN] };
51 for i in 0 .. MAX_MN {
52 let i = 2 * i;
53
54 let mut even = H.compress().to_bytes().to_vec();
55 even.extend(dst);
56 let mut odd = even.clone();
57
58 write_varint(&i.try_into().unwrap(), &mut even).unwrap();
59 write_varint(&(i + 1).try_into().unwrap(), &mut odd).unwrap();
60 res.H[i / 2] = EdwardsPoint(hash_to_point(hash(&even)));
61 res.G[i / 2] = EdwardsPoint(hash_to_point(hash(&odd)));
62 }
63 res
64}