use pqcrypto_traits::kem::{PublicKey, SecretKey, SharedSecret, Ciphertext};
use crate::{
*,
log_activity,
error::CryptError,
FileTypes,
FileState,
FileMetadata,
KeyTypes,
Key,
};
use std::{
path::{PathBuf, Path},
marker::PhantomData,
result::Result,
};
pub trait KyberKeyFunctions {
fn keypair() -> Result<(Vec<u8>, Vec<u8>), CryptError>;
fn encap(public_key: &[u8]) -> Result<(Vec<u8>, Vec<u8>), CryptError>;
fn decap(secret_key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, CryptError>;
}
pub struct KeyControKyber1024;
impl KyberKeyFunctions for KeyControKyber1024{
fn keypair() -> Result<(Vec<u8>,Vec<u8>), CryptError> {
use pqcrypto_kyber::kyber1024::*;
log_activity!("Generating a new keypair.\n\tThe used KEM: ", format!("Kyber{}", 1024).as_str());
let (pk, sk) = keypair();
let public_key = pk.as_bytes().to_owned();
let secret_key = sk.as_bytes().to_owned();
log_activity!("A new keypair was created.\n\tThe used KEM: ", format!("Kyber{}", 1024).as_str());
Ok((public_key, secret_key))
}
fn encap(public: &[u8]) -> Result<(Vec<u8>,Vec<u8>), CryptError> {
use pqcrypto_kyber::kyber1024::*;
log_activity!("Generating shared_secret and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 1024).as_str());
let pk = PublicKey::from_bytes(public).unwrap();
let (ss, ct) = encapsulate(&pk);
let ciphertext = ct.as_bytes().to_vec();
let shared_secret = ss.as_bytes().to_vec();
log_activity!("Finished generating shared_secret and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 1024).as_str());
Ok((shared_secret, ciphertext))
}
fn decap(sec: &[u8], cipher: &[u8]) -> Result<Vec<u8>, CryptError> {
use pqcrypto_kyber::kyber1024::*;
log_activity!("Starting decapsulation of shared_secret using secret_key and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 1024).as_str());
let ct = Ciphertext::from_bytes(cipher).unwrap();
let sk = SecretKey::from_bytes(sec).unwrap();
let ss2 = decapsulate(&ct, &sk);
let shared_secret = ss2.as_bytes().to_vec();
log_activity!("Decapsulated the shared_secret using secret_key and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 1024).as_str());
Ok(shared_secret)
}
}
impl KeyControKyber1024 {
pub fn keypair() -> Result<(Vec<u8>, Vec<u8>), CryptError> {
<Self as KyberKeyFunctions>::keypair()
}
pub fn encap(public_key: &[u8]) -> Result<(Vec<u8>, Vec<u8>), CryptError> {
<Self as KyberKeyFunctions>::encap(public_key)
}
pub fn decap(secret_key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, CryptError> {
<Self as KyberKeyFunctions>::decap(secret_key, ciphertext)
}
}
pub struct KeyControKyber768;
impl KyberKeyFunctions for KeyControKyber768 {
fn keypair() -> Result<(Vec<u8>,Vec<u8>), CryptError> {
use pqcrypto_kyber::kyber768::*;
log_activity!("Generating a new keypair.\n\tThe used KEM: ", format!("Kyber{}", 768).as_str());
let (pk, sk) = keypair();
let public_key = pk.as_bytes().to_vec();
let secret_key = sk.as_bytes().to_vec();
log_activity!("A new keypair was created.\n\tThe used KEM: ", format!("Kyber{}", 768).as_str());
Ok((public_key, secret_key))
}
fn encap(public: &[u8]) -> Result<(Vec<u8>,Vec<u8>), CryptError> {
use pqcrypto_kyber::kyber768::*;
log_activity!("Generating shared_secret and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 768).as_str());
let pk = PublicKey::from_bytes(public).unwrap();
let (ss, ct) = encapsulate(&pk);
let ciphertext = ct.as_bytes().to_vec();
let shared_secret = ss.as_bytes().to_vec();
log_activity!("Finished generating shared_secret and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 768).as_str());
Ok((shared_secret, ciphertext))
}
fn decap(sec: &[u8], cipher: &[u8]) -> Result<Vec<u8>, CryptError> {
use pqcrypto_kyber::kyber768::*;
log_activity!("Starting decapsulation of shared_secret using secret_key and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 768).as_str());
let ct = Ciphertext::from_bytes(cipher).unwrap();
let sk = SecretKey::from_bytes(sec).unwrap();
let ss2 = decapsulate(&ct, &sk);
let shared_secret = ss2.as_bytes().to_vec();
log_activity!("Decapsulated the shared_secret using secret_key and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 768).as_str());
Ok(shared_secret)
}
}
impl KeyControKyber768 {
pub fn keypair() -> Result<(Vec<u8>, Vec<u8>), CryptError> {
<Self as KyberKeyFunctions>::keypair()
}
pub fn encap(public_key: &[u8]) -> Result<(Vec<u8>, Vec<u8>), CryptError> {
<Self as KyberKeyFunctions>::encap(public_key)
}
pub fn decap(secret_key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, CryptError> {
<Self as KyberKeyFunctions>::decap(secret_key, ciphertext)
}
}
pub struct KeyControKyber512;
impl KyberKeyFunctions for KeyControKyber512 {
fn keypair() -> Result<(Vec<u8>,Vec<u8>), CryptError> {
use pqcrypto_kyber::kyber512::*;
log_activity!("Generating a new keypair.\n\tThe used KEM: ", format!("Kyber{}", 512).as_str());
let (pk, sk) = keypair();
let public_key = pk.as_bytes().to_vec();
let secret_key = sk.as_bytes().to_vec();
log_activity!("A new keypair was created.\n\tThe used KEM: ", format!("Kyber{}", 512).as_str());
Ok((public_key, secret_key))
}
fn encap(public: &[u8]) -> Result<(Vec<u8>,Vec<u8>), CryptError> {
use pqcrypto_kyber::kyber512::*;
log_activity!("Generating shared_secret and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 512).as_str());
let pk = PublicKey::from_bytes(public).unwrap();
let (ss, ct) = encapsulate(&pk);
let ciphertext = ct.as_bytes().to_vec();
let shared_secret = ss.as_bytes().to_vec();
log_activity!("Finished generating shared_secret and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 512).as_str());
Ok((shared_secret, ciphertext))
}
fn decap(sec: &[u8], cipher: &[u8]) -> Result<Vec<u8>, CryptError> {
use pqcrypto_kyber::kyber512::*;
log_activity!("Starting decapsulation of shared_secret using secret_key and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 512).as_str());
let ct = Ciphertext::from_bytes(cipher).unwrap();
let sk = SecretKey::from_bytes(sec).unwrap();
let ss2 = decapsulate(&ct, &sk);
let shared_secret = ss2.as_bytes().to_vec();
log_activity!("Decapsulated the shared_secret using secret_key and ciphertext.\n\tThe used KEM: ", format!("Kyber{}", 512).as_str());
Ok(shared_secret)
}
}
impl KeyControKyber512 {
pub fn keypair() -> Result<(Vec<u8>, Vec<u8>), CryptError> {
<Self as KyberKeyFunctions>::keypair()
}
pub fn encap(public_key: &[u8]) -> Result<(Vec<u8>, Vec<u8>), CryptError> {
<Self as KyberKeyFunctions>::encap(public_key)
}
pub fn decap(secret_key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, CryptError> {
<Self as KyberKeyFunctions>::decap(secret_key, ciphertext)
}
}
pub struct KeyControl<T: KyberKeyFunctions> {
pub public_key: Vec<u8>,
pub secret_key: Vec<u8>,
pub ciphertext: Vec<u8>,
pub shared_secret: Vec<u8>,
_marker: std::marker::PhantomData<T>,
}
impl<T: KyberKeyFunctions> KeyControl<T> {
pub fn new() -> Self {
KeyControl {
public_key: Vec::new(),
secret_key: Vec::new(),
ciphertext: Vec::new(),
shared_secret: Vec::new(),
_marker: PhantomData,
}
}
pub fn set_ciphertext(&mut self, cipher: Vec<u8>) -> Result<(), CryptError> {
self.ciphertext = cipher;
Ok(())
}
pub fn set_public_key(&mut self, public: Vec<u8>) -> Result<(), CryptError> {
self.public_key = public;
Ok(())
}
pub fn set_secret_key(&mut self, sec: Vec<u8>) -> Result<(), CryptError> {
self.secret_key = sec;
Ok(())
}
pub fn get_key(&self, key: KeyTypes) -> Result<Key, CryptError> {
let key = match key {
KeyTypes::None => unimplemented!(),
KeyTypes::PublicKey => {
Key::new(KeyTypes::PublicKey, self.public_key.to_vec())
}
KeyTypes::SecretKey => {
Key::new(KeyTypes::SecretKey, self.secret_key.to_vec())
}
KeyTypes::Ciphertext => {
Key::new(KeyTypes::Ciphertext, self.ciphertext.to_vec())
}
KeyTypes::SharedSecret => {
Key::new(KeyTypes::SharedSecret, self.shared_secret.to_vec())
}
};
Ok(key)
}
pub fn save(&self, key: KeyTypes, base_path: PathBuf) -> Result<(), CryptError> {
let key = match key {
KeyTypes::None => unimplemented!(),
KeyTypes::PublicKey => {
Key::new(KeyTypes::PublicKey, self.public_key.to_vec())
}
KeyTypes::SecretKey => {
Key::new(KeyTypes::SecretKey, self.secret_key.to_vec())
}
KeyTypes::Ciphertext => {
Key::new(KeyTypes::Ciphertext, self.ciphertext.to_vec())
}
KeyTypes::SharedSecret => unimplemented!(),
};
key.save(base_path)
}
pub fn load(&self, key: KeyTypes, path: &Path) -> Result<Vec<u8>, CryptError> {
let key = match key {
KeyTypes::None => unimplemented!(),
KeyTypes::PublicKey => {
FileMetadata::from(
PathBuf::from(path),
FileTypes::PublicKey,
FileState::Other
)
}
KeyTypes::SecretKey => {
FileMetadata::from(
PathBuf::from(path),
FileTypes::SecretKey,
FileState::Other
)
}
KeyTypes::Ciphertext => {
FileMetadata::from(
PathBuf::from(path),
FileTypes::Ciphertext,
FileState::Other
)
}
KeyTypes::SharedSecret => unimplemented!(),
};
Ok(key.load().unwrap())
}
pub fn public_key(&self) -> Result<Vec<u8>, CryptError> {
let key = &self.public_key;
Ok(key.to_vec())
}
pub fn secret_key(&self) -> Result<Vec<u8>, CryptError> {
let key = &self.secret_key;
Ok(key.to_vec())
}
pub fn ciphertext(&self) -> Result<Vec<u8>, CryptError> {
let key = &self.ciphertext;
Ok(key.to_vec())
}
pub fn shared_secret(&self) -> Result<Vec<u8>, CryptError> {
let key = &self.shared_secret;
Ok(key.to_vec())
}
pub fn encap(&self, public: &[u8]) -> Result<(Vec<u8>,Vec<u8>), CryptError> {
T::encap(public)
}
pub fn decap(&self, secret_key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, CryptError> {
T::decap(secret_key, ciphertext)
}
}
impl<T: KyberKeyFunctions> Default for KeyControl<T> {
fn default() -> Self { Self::new() }
}