use super::address::Adrs;
use super::params::Params;
use super::sha3::{KeccakState, SHAKE256_RATE};
use alloc::vec::Vec;
#[inline(always)]
fn shake256_pk_adrs(pk_seed: &[u8], adrs: &Adrs) -> KeccakState {
let mut ctx = KeccakState::new(SHAKE256_RATE, 0x1f);
ctx.absorb(pk_seed);
ctx.absorb(adrs.as_bytes());
ctx
}
pub fn h_msg_into<P: Params>(r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[u8], out: &mut [u8]) {
let mut ctx = KeccakState::new(SHAKE256_RATE, 0x1f);
ctx.absorb(r);
ctx.absorb(pk_seed);
ctx.absorb(pk_root);
ctx.absorb(m);
ctx.squeeze(out);
}
pub fn h_msg<P: Params>(r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[u8]) -> Vec<u8> {
let mut out = vec![0u8; P::M];
h_msg_into::<P>(r, pk_seed, pk_root, m, &mut out);
out
}
pub fn prf_into<P: Params>(pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs, out: &mut [u8]) {
let mut ctx = shake256_pk_adrs(pk_seed, adrs);
ctx.absorb(sk_seed);
ctx.squeeze(out);
}
pub fn prf<P: Params>(pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs) -> Vec<u8> {
let mut out = vec![0u8; P::N];
prf_into::<P>(pk_seed, sk_seed, adrs, &mut out);
out
}
pub fn prf_msg_into<P: Params>(sk_prf: &[u8], opt_rand: &[u8], m: &[u8], out: &mut [u8]) {
let mut ctx = KeccakState::new(SHAKE256_RATE, 0x1f);
ctx.absorb(sk_prf);
ctx.absorb(opt_rand);
ctx.absorb(m);
ctx.squeeze(out);
}
pub fn prf_msg<P: Params>(sk_prf: &[u8], opt_rand: &[u8], m: &[u8]) -> Vec<u8> {
let mut out = vec![0u8; P::N];
prf_msg_into::<P>(sk_prf, opt_rand, m, &mut out);
out
}
pub fn t_l_into<P: Params>(pk_seed: &[u8], adrs: &Adrs, m: &[u8], out: &mut [u8]) {
let mut ctx = shake256_pk_adrs(pk_seed, adrs);
ctx.absorb(m);
ctx.squeeze(out);
}
pub fn t_l<P: Params>(pk_seed: &[u8], adrs: &Adrs, m: &[u8]) -> Vec<u8> {
let mut out = vec![0u8; P::N];
t_l_into::<P>(pk_seed, adrs, m, &mut out);
out
}
pub fn hash_h_into<P: Params>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8], m2: &[u8], out: &mut [u8]) {
let mut ctx = shake256_pk_adrs(pk_seed, adrs);
ctx.absorb(m1);
ctx.absorb(m2);
ctx.squeeze(out);
}
pub fn hash_h<P: Params>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8], m2: &[u8]) -> Vec<u8> {
let mut out = vec![0u8; P::N];
hash_h_into::<P>(pk_seed, adrs, m1, m2, &mut out);
out
}
pub fn f_hash_into<P: Params>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8], out: &mut [u8]) {
let mut ctx = shake256_pk_adrs(pk_seed, adrs);
ctx.absorb(m1);
ctx.squeeze(out);
}
pub fn f_hash<P: Params>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8]) -> Vec<u8> {
let mut out = vec![0u8; P::N];
f_hash_into::<P>(pk_seed, adrs, m1, &mut out);
out
}