use super::{Point, Scalar};
use purecrypto::hash::{Digest, Keccak256};
#[derive(Clone)]
pub struct HashHelper {
h: Keccak256,
}
impl Default for HashHelper {
fn default() -> Self {
Self::new()
}
}
impl HashHelper {
pub fn new() -> HashHelper {
HashHelper {
h: Keccak256::new(),
}
}
pub fn add_bytes(&mut self, b: &[u8]) {
assert_eq!(b.len(), 32, "add_bytes expects 32 bytes");
self.h.update(b);
}
pub fn add_bytes_mod_l(&mut self, b: &[u8]) {
assert_eq!(b.len(), 32, "add_bytes_mod_l expects 32 bytes");
let s = super::scalar_from_wide(b);
self.add_scalar(&s);
}
pub fn add_point(&mut self, p: &Point) {
self.h.update(&p.compress());
}
pub fn add_points(&mut self, ps: &[Point]) {
for p in ps {
self.add_point(p);
}
}
pub fn add_scalar(&mut self, s: &Scalar) {
self.h.update(&s.to_bytes());
}
pub fn add_scalars(&mut self, ss: &[Scalar]) {
for s in ss {
self.add_scalar(s);
}
}
pub fn add_raw(&mut self, b: &[u8]) {
self.h.update(b);
}
pub fn calc_hash(&mut self) -> Scalar {
let s = self.calc_hash_keep();
self.h = Keccak256::new();
s
}
pub fn calc_hash_keep(&mut self) -> Scalar {
let sum = self.h.clone().finalize();
super::scalar_from_wide(&sum)
}
pub fn calc_raw_hash(&mut self) -> [u8; 32] {
let sum = self.h.clone().finalize();
self.h = Keccak256::new();
sum
}
}
pub fn hash_to_scalar(data: &[u8]) -> Scalar {
super::scalar_from_wide(&Keccak256::digest(data))
}
pub fn hs_bytes(chunks: &[&[u8]]) -> Scalar {
let mut h = Keccak256::new();
for c in chunks {
h.update(c);
}
super::scalar_from_wide(&h.finalize())
}
pub fn keccak_concat(chunks: &[&[u8]]) -> [u8; 32] {
let mut h = Keccak256::new();
for c in chunks {
h.update(c);
}
h.finalize()
}