use crate::params::SntrupParameters;
use crate::{r3, utils, zx};
use rand::CryptoRng;
use zeroize::Zeroize;
#[cfg(feature = "kgen")]
pub(crate) fn keygen(params: &SntrupParameters, rng: &mut impl CryptoRng) -> (Vec<u8>, Vec<u8>) {
let p = params.p;
let mut g = vec![0i8; p];
let gr = loop {
zx::random::random_small(&mut g, rng);
let (mask, gr) = r3::reciprocal(&g, p);
if mask == 0 {
break gr;
}
};
let mut f = vec![0i8; p];
zx::random::random_tsmall(&mut f, p, params.w, rng);
let mut rho = vec![0u8; params.small_encode_size];
rng.fill_bytes(&mut rho);
let result = utils::derive_key(&f, &g, &gr, &rho, params);
f.zeroize();
g.zeroize();
rho.zeroize();
result
}
#[cfg(feature = "ecap")]
pub(crate) fn encaps(
pk: &[u8],
params: &SntrupParameters,
rng: &mut impl CryptoRng,
) -> (Vec<u8>, Vec<u8>) {
let p = params.p;
let mut r = vec![0i8; p];
zx::random::random_tsmall(&mut r, p, params.w, rng);
let (ct, ss) = utils::create_cipher(&r, pk, params);
r.zeroize();
(ct, ss.to_vec())
}
#[cfg(feature = "dcap")]
pub(crate) fn decaps(sk: &[u8], ct: &[u8], params: &SntrupParameters) -> Vec<u8> {
let ss = utils::decapsulate_inner(ct, sk, params);
ss.to_vec()
}