mod r5_cpa_kem;
use crate::parameters::Parameters;
use crate::kem::r5_cpa_kem::{r5_cpa_kem_keygen, r5_cpa_kem_encapsulate, r5_cpa_kem_decapsulate};
use crate::types::Random;
#[cfg(feature="support-snow")]
use crate::types::Kem;
pub struct R5Kem {
params: Parameters,
pk: Option<Vec<u8>>,
sk: Option<Vec<u8>>
}
impl R5Kem {
pub fn new(params: Parameters) -> R5Kem {
R5Kem { params, pk: None, sk: None }
}
pub fn default() -> R5Kem {
let params = Parameters::r5n1_1_kem_0d();
R5Kem { params, pk: None, sk: None }
}
pub fn public(&self) -> &[u8] {
self.pk.as_ref().expect("You should call .keypair() before you take the pubkey")
}
pub fn keypair(&mut self, rng: &mut dyn Random) {
self.pk = Some(vec![0u8; self.params.c_pk]);
self.sk = Some(vec![0u8; self.params.c_sk]);
r5_cpa_kem_keygen(self.pk.as_mut().unwrap(), self.sk.as_mut().unwrap(), rng, &self.params);
}
pub fn enc(&self, pubkey: &[u8], rng: &mut dyn Random) -> (Vec<u8>, Vec<u8>) {
r5_cpa_kem_encapsulate(pubkey, rng, &self.params)
}
pub fn dec(&self, ciphertext: &[u8]) -> Vec<u8> {
r5_cpa_kem_decapsulate(ciphertext, self.sk.as_ref().unwrap(), &self.params)
}
}
#[cfg(feature = "support-snow")]
impl Kem for R5Kem {
fn name(&self) -> &'static str {
self.params.name
}
fn pub_len(&self) -> usize {
self.params.pk_size as usize
}
fn ciphertext_len(&self) -> usize {
self.params.ct_size as usize
}
fn shared_secret_len(&self) -> usize {
self.params.c_b
}
fn generate(&mut self, rng: &mut dyn Random) {
self.keypair(rng);
}
fn pubkey(&self) -> &[u8] {
self.public()
}
fn encapsulate(
&self,
pubkey: &[u8],
shared_secret_out: &mut [u8],
ciphertext_out: &mut [u8],
rng: &mut dyn Random
) -> Result<(usize, usize), ()> {
let (shared_secret, ciphertext) = self.enc(pubkey, rng);
shared_secret_out.copy_from_slice(shared_secret.as_slice());
ciphertext_out.copy_from_slice(ciphertext.as_slice());
Ok((shared_secret.len(), ciphertext.len()))
}
fn decapsulate(&self, ciphertext: &[u8], shared_secret_out: &mut [u8]) -> Result<usize, ()> {
let shared_secret = self.dec(ciphertext);
shared_secret_out.copy_from_slice(shared_secret.as_slice());
Ok(shared_secret.len())
}
}