use crate::{
params::*,
error::KyberError,
RngCore, CryptoRng,
kem::*,
kex::{PublicKey, SecretKey, Encapsulated, Decapsulated}
};
pub fn keypair<R>(rng: &mut R) -> Result<Keypair, KyberError>
where R: RngCore + CryptoRng
{
let mut public = [0u8; KYBER_PUBLICKEYBYTES];
let mut secret = [0u8; KYBER_SECRETKEYBYTES];
crypto_kem_keypair(&mut public, &mut secret, rng, None)?;
Ok(Keypair { public, secret })
}
pub fn encapsulate<R>(pk: &[u8], rng: &mut R) -> Encapsulated
where R: CryptoRng + RngCore
{
if pk.len() != KYBER_PUBLICKEYBYTES {
return Err(KyberError::InvalidInput)
}
let mut ct = [0u8; KYBER_CIPHERTEXTBYTES];
let mut ss = [0u8; KYBER_SSBYTES];
crypto_kem_enc(&mut ct, &mut ss, pk, rng, None)?;
Ok((ct, ss))
}
pub fn decapsulate(ct: &[u8], sk: &[u8]) -> Decapsulated
{
if ct.len() != KYBER_CIPHERTEXTBYTES || sk.len() != KYBER_SECRETKEYBYTES {
return Err(KyberError::InvalidInput)
}
let mut ss = [0u8; KYBER_SSBYTES];
crypto_kem_dec(&mut ss, ct, sk);
Ok(ss)
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Keypair {
pub public: PublicKey,
pub secret: SecretKey
}
impl Keypair {
pub fn generate<R: CryptoRng + RngCore>(rng: &mut R) -> Result<Keypair, KyberError> {
keypair(rng)
}
}
struct DummyRng{}
impl CryptoRng for DummyRng{}
impl RngCore for DummyRng{
fn next_u32(&mut self) -> u32 { panic!() }
fn next_u64(&mut self) -> u64 { panic!() }
fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), rand_core::Error> { panic!() }
fn fill_bytes(&mut self, _dest: &mut [u8]) { panic!() }
}
pub fn derive(seed: &[u8]) -> Result<Keypair, KyberError>
{
let mut public = [0u8; KYBER_PUBLICKEYBYTES];
let mut secret = [0u8; KYBER_SECRETKEYBYTES];
let mut _rng = DummyRng{};
if seed.len() != 64 {
return Err(KyberError::InvalidInput)
}
crypto_kem_keypair(&mut public, &mut secret, &mut _rng, Some((&seed[..32], &seed[32..])))?;
Ok(Keypair { public, secret })
}
pub fn public(sk: &[u8]) -> PublicKey
{
let mut pk = [0u8; KYBER_INDCPA_PUBLICKEYBYTES];
pk.copy_from_slice(
&sk[KYBER_INDCPA_SECRETKEYBYTES
..KYBER_INDCPA_SECRETKEYBYTES+KYBER_INDCPA_PUBLICKEYBYTES]
);
pk
}