use crate::core::global_value::curve_value::CurveValue;
use curve25519_dalek::RistrettoPoint;
use sha3::{
digest::{ExtendableOutput, Update, XofReader},
Shake256,
Shake256Reader,
};
const MAX_GENERATOR_LENGTH: usize = u32::MAX as usize;
struct GeneratorsChain {
reader: Shake256Reader,
}
impl GeneratorsChain {
fn new(label: &[u8]) -> Self {
let mut shake = Shake256::default();
shake.update(b"GeneratorsChain");
shake.update(label);
GeneratorsChain {
reader: shake.finalize_xof(),
}
}
fn fast_forward(mut self, n: usize) -> Self {
for _ in 0..n {
let mut buf = [0u8; 64];
self.reader.read(&mut buf);
}
self
}
}
impl Default for GeneratorsChain {
fn default() -> Self {
Self::new(&[])
}
}
impl Iterator for GeneratorsChain {
type Item = RistrettoPoint;
fn next(&mut self) -> Option<Self::Item> {
let mut uniform_bytes = [0u8; 64];
self.reader.read(&mut uniform_bytes);
Some(RistrettoPoint::from_uniform_bytes(&uniform_bytes))
}
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
}
#[allow(non_snake_case)]
#[derive(Clone)]
pub struct RangeProofGens {
#[allow(dead_code)]
pub gens_capacity: usize,
G_vec: Vec<CurveValue>,
H_vec: Vec<CurveValue>,
}
#[allow(non_snake_case)]
impl RangeProofGens {
pub fn new(gens_capacity: usize) -> Self {
assert!(gens_capacity <= MAX_GENERATOR_LENGTH);
let mut gens = RangeProofGens {
gens_capacity: 0,
G_vec: Vec::new(),
H_vec: Vec::new(),
};
gens.increase_capacity(gens_capacity);
gens
}
pub fn increase_capacity(&mut self, new_capacity: usize) {
if self.gens_capacity >= new_capacity {
return;
}
assert!(new_capacity <= MAX_GENERATOR_LENGTH);
self.G_vec.extend(
&mut GeneratorsChain::new(b"G")
.fast_forward(self.gens_capacity)
.take(new_capacity - self.gens_capacity)
.map(CurveValue::from),
);
self.H_vec.extend(
&mut GeneratorsChain::new(b"H")
.fast_forward(self.gens_capacity)
.take(new_capacity - self.gens_capacity)
.map(CurveValue::from),
);
self.gens_capacity = new_capacity;
}
pub fn G(&self, n: usize) -> impl Iterator<Item = &CurveValue> {
self.G_vec.iter().take(n)
}
pub fn H(&self, n: usize) -> impl Iterator<Item = &CurveValue> {
self.H_vec.iter().take(n)
}
}