From 105b71f2e7913e4a28f05e5b5601320e4742962d Mon Sep 17 00:00:00 2001 From: M <149858635+mm9942@users.noreply.github.com> Date: Mon, 15 Apr 2024 14:18:35 +0200 Subject: [PATCH] V1.2.3 --- Cargo.toml | 2 +- README.md | 17 +- examples/signed_message.rs | 20 +++ src/Core/KDF.rs | 105 +++++++++++- src/Core/kyber/KeyControler.rs | 288 +++++++++++++++++++++++++++++++++ src/Core/kyber/mod.rs | 3 +- src/Core/mod.rs | 2 +- src/KeyControl/mod.rs | 2 +- src/error.rs | 40 +++-- src/lib.rs | 2 +- src/log.rs | 5 +- src/tests/KyberKeyTest.rs | 6 +- src/tests/SignatureTests.rs | 81 ++++++++++ src/tests/mod.rs | 7 + 14 files changed, 554 insertions(+), 26 deletions(-) create mode 100644 examples/signed_message.rs create mode 100644 src/Core/kyber/KeyControler.rs diff --git a/Cargo.toml b/Cargo.toml index 259c468..d77e970 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypt_guard" -version = "1.2.2" +version = "1.2.3" edition = "2021" description = "CryptGuardLib is a comprehensive Rust library designed for strong encryption and decryption, incorporating post-quantum cryptography to safeguard against quantum threats. It's geared towards developers who need to embed advanced cryptographic capabilities in their Rust applications." license = "MIT" diff --git a/README.md b/README.md index 3f0f94d..f361683 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ An additional layer of security is provided through the appending of a HMAC (Has ### Current Release -The present version, **1.2.2**, emphasizes detailed cryptographic operations. This version is ideal for those who want a fast but not too complicated, elaborate approach to cryptography and don't want to use asynchronous code. Asynchronous capabilities will be reimplemented in a later update (but this time as a feature). For those who prefer using async implementation, use version 1.0.3 until a later update is released. This version's syntax is more user-friendly and does not require the definition of too many structs like in 1.1.X or 1.1.0 but allows for precise control over the encryption and decryption algorithm as well as the Kyber key size. It allows the usage of Kyber1024, Kyber768, and Kyber512. Now you also can use logging cappabilitys. +The present version, **1.2.3**, emphasizes detailed cryptographic operations. This version is ideal for those who want a fast but not too complicated, elaborate approach to cryptography and don't want to use asynchronous code. Asynchronous capabilities will be reimplemented in a later update (but this time as a feature). For those who prefer using async implementation, use version 1.0.3 until a later update is released. This version's syntax is more user-friendly and does not require the definition of too many structs like in 1.1.X or 1.1.0 but allows for precise control over the encryption and decryption algorithm as well as the Kyber key size. It allows the usage of Kyber1024, Kyber768, and Kyber512. Now you also can use logging cappabilitys. - **Simplified Syntax**: We've re-engineered the use of Dilithium and Falcon, adopting a straightforward, modular, and flexible approach akin to our encryption and decryption syntax. This enhancement aims to streamline operations for developers. @@ -84,13 +84,18 @@ println!("{}", decrypted_text); ### New signature syntax for dilithium and falcon -#### Signing and opening with Falcon +#### Signing and opening from "messages" with Falcon ```rust use crypt_guard::KDF::*; // Create a new keypair let (public_key, secret_key) = Falcon1024::keypair(); + +// Save the keys, in the case of Falcon1024, they are saved in the folder ./Falcon1024/key(.pub & .sec) +let _ = Falcon1024::save_public(&public_key); +let _ = Falcon1024::save_secret(&secret_key); + let data = b"Hello, world!".to_vec(); let sign = Signature::::new(); // Sign the message @@ -100,13 +105,15 @@ let signed_message = sign.signature(data.clone(), secret_key); let opened_message = sign.open(signed_message, public_key); ``` -#### Signing and verifying detached with Dilithium +#### Creating and verifying detached signature with Dilithium 5 ```rust use crypt_guard::KDF::*; -// Create a new keypair -let (public_key, secret_key) = Dilithium5::keypair(); +// Load the public and secret dilithium 5 key +let public_key = Dilithium5::load(&PathBuf::from("./Dilithium5/key.pub"))?; +let secret_key = Dilithium5::load(&PathBuf::from("./Dilithium5/key.sec"))?; + let data = b"Hello, world!".to_vec(); let sign = Signature::::new(); diff --git a/examples/signed_message.rs b/examples/signed_message.rs new file mode 100644 index 0000000..b0a9662 --- /dev/null +++ b/examples/signed_message.rs @@ -0,0 +1,20 @@ +use crypt_guard::KDF::*; + +fn main() -> Result<(), Box> { + let (public_key, secret_key) = Falcon1024::keypair()?; + let _ = Falcon1024::save_public(&public_key); + let _ = Falcon1024::save_secret(&secret_key); + + let data = b"Hello, world!".to_vec(); + let sign = Signature::::new(); + + // Sign the message + let signed_message = sign.signature(data.clone(), secret_key)?; + + // Open the message + let opened_message = sign.open(signed_message, public_key)?; + + let message = String::from_utf8(opened_message).expect("Failed to convert decrypted message to string"); + println!("{:?}", message); + Ok(()) +} \ No newline at end of file diff --git a/src/Core/KDF.rs b/src/Core/KDF.rs index 22f9b7f..fc8b73f 100644 --- a/src/Core/KDF.rs +++ b/src/Core/KDF.rs @@ -12,6 +12,11 @@ use std::{ }; use pqcrypto_traits::sign::{PublicKey, SecretKey, SignedMessage, DetachedSignature}; use crate::{ + FileMetadata, + FileTypes, + FileState, + KeyTypes, + Key, error::SigningErr, log_activity, LOGGER, @@ -41,6 +46,9 @@ pub trait SignatureFunctions { pub trait KeyOperations { /// Generates a public and secret key pair. fn keypair() -> Result<(Vec, Vec), SigningErr>; + fn save_public(public_key: &[u8]) -> Result<(), SigningErr>; + fn save_secret(secret_key: &[u8]) -> Result<(), SigningErr>; + fn load(path: &PathBuf) -> Result, SigningErr>; } /// Implements Falcon1024 algorithm operations. @@ -51,6 +59,25 @@ impl KeyOperations for Falcon1024 { let (public_key, secret_key) = falcon1024::keypair(); Ok((public_key.as_bytes().to_owned(), secret_key.as_bytes().to_owned())) } + fn save_public(public_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Falcon1024/key.pub"), FileTypes::public_key(), FileState::not_encrypted()); + let _ = file.save(public_key); + Ok(()) + } + fn save_secret(secret_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Falcon1024/key.sec"), FileTypes::secret_key(), FileState::not_encrypted()); + let _ = file.save(secret_key); + Ok(()) + } + fn load(path: &PathBuf) -> Result, SigningErr> { + let file = match path.extension().and_then(|s| s.to_str()) { + Some("pub") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::public_key(), FileState::not_encrypted()), + Some("sec") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::secret_key(), FileState::not_encrypted()), + _ => FileMetadata::new(), + }; + let key = file.load().map_err(|e| SigningErr::UnsupportedFileType(path.extension().unwrap().to_str().unwrap().to_string()))?; + Ok(key) + } } impl SignatureFunctions for Falcon1024 { /// Signs a given message with the provided key. @@ -103,6 +130,25 @@ impl KeyOperations for Falcon512 { let (public_key, secret_key) = falcon512::keypair(); Ok((public_key.as_bytes().to_owned(), secret_key.as_bytes().to_owned())) } + fn save_public(public_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Falcon512/key.pub"), FileTypes::public_key(), FileState::not_encrypted()); + let _ = file.save(public_key); + Ok(()) + } + fn save_secret(secret_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Falcon512/key.sec"), FileTypes::secret_key(), FileState::not_encrypted()); + let _ = file.save(secret_key); + Ok(()) + } + fn load(path: &PathBuf) -> Result, SigningErr> { + let file = match path.extension().and_then(|s| s.to_str()) { + Some("pub") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::public_key(), FileState::not_encrypted()), + Some("sec") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::secret_key(), FileState::not_encrypted()), + _ => FileMetadata::new(), + }; + let key = file.load().map_err(|e| SigningErr::UnsupportedFileType(path.extension().unwrap().to_str().unwrap().to_string()))?; + Ok(key) + } } impl SignatureFunctions for Falcon512 { /// Signs a given message with the provided key. @@ -156,6 +202,26 @@ impl KeyOperations for Dilithium2 { let (public_key, secret_key) = dilithium2::keypair(); Ok((public_key.as_bytes().to_owned(), secret_key.as_bytes().to_owned())) } + + fn save_public(public_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Dilithium2/key.pub"), FileTypes::public_key(), FileState::not_encrypted()); + let _ = file.save(public_key); + Ok(()) + } + fn save_secret(secret_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Dilithium2/key.sec"), FileTypes::secret_key(), FileState::not_encrypted()); + let _ = file.save(secret_key); + Ok(()) + } + fn load(path: &PathBuf) -> Result, SigningErr> { + let file = match path.extension().and_then(|s| s.to_str()) { + Some("pub") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::public_key(), FileState::not_encrypted()), + Some("sec") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::secret_key(), FileState::not_encrypted()), + _ => FileMetadata::new(), + }; + let key = file.load().map_err(|e| SigningErr::UnsupportedFileType(path.extension().unwrap().to_str().unwrap().to_string()))?; + Ok(key) + } } impl SignatureFunctions for Dilithium2 { /// Signs a given message with the provided key. @@ -208,6 +274,25 @@ impl KeyOperations for Dilithium3 { let (public_key, secret_key) = dilithium3::keypair(); Ok((public_key.as_bytes().to_owned(), secret_key.as_bytes().to_owned())) } + fn save_public(public_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Dilithium3/key.pub"), FileTypes::public_key(), FileState::not_encrypted()); + let _ = file.save(public_key); + Ok(()) + } + fn save_secret(secret_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Dilithium3/key.sec"), FileTypes::secret_key(), FileState::not_encrypted()); + let _ = file.save(secret_key); + Ok(()) + } + fn load(path: &PathBuf) -> Result, SigningErr> { + let file = match path.extension().and_then(|s| s.to_str()) { + Some("pub") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::public_key(), FileState::not_encrypted()), + Some("sec") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::secret_key(), FileState::not_encrypted()), + _ => FileMetadata::new(), + }; + let key = file.load().map_err(|e| SigningErr::UnsupportedFileType(path.extension().unwrap().to_str().unwrap().to_string()))?; + Ok(key) + } } impl SignatureFunctions for Dilithium3 { /// Signs a given message with the provided key. @@ -228,7 +313,6 @@ impl SignatureFunctions for Dilithium3 { } /// Opens (or verifies) a signed message with the provided key. fn open_message(signed_data: Vec, key: Vec) -> Result, SigningErr> { - log_activity!("Starting with signing of the message.", "\nUsed key: Dilithium3"); let key = dilithium3::PublicKey::from_bytes(&key).unwrap(); let signed_message = dilithium3::SignedMessage::from_bytes(&signed_data).unwrap(); @@ -262,6 +346,25 @@ impl KeyOperations for Dilithium5 { let (public_key, secret_key) = dilithium5::keypair(); Ok((public_key.as_bytes().to_owned(), secret_key.as_bytes().to_owned())) } + fn save_public(public_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Dilithium5/key.pub"), FileTypes::public_key(), FileState::not_encrypted()); + let _ = file.save(public_key); + Ok(()) + } + fn save_secret(secret_key: &[u8]) -> Result<(), SigningErr> { + let file = FileMetadata::from(PathBuf::from("./Dilithium5/key.sec"), FileTypes::secret_key(), FileState::not_encrypted()); + let _ = file.save(secret_key); + Ok(()) + } + fn load(path: &PathBuf) -> Result, SigningErr> { + let file = match path.extension().and_then(|s| s.to_str()) { + Some("pub") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::public_key(), FileState::not_encrypted()), + Some("sec") => FileMetadata::from(PathBuf::from(path.as_os_str().to_str().unwrap()), FileTypes::secret_key(), FileState::not_encrypted()), + _ => FileMetadata::new(), + }; + let key = file.load().map_err(|e| SigningErr::UnsupportedFileType(path.extension().unwrap().to_str().unwrap().to_string()))?; + Ok(key) + } } impl SignatureFunctions for Dilithium5 { /// Signs a given message with the provided key. diff --git a/src/Core/kyber/KeyControler.rs b/src/Core/kyber/KeyControler.rs new file mode 100644 index 0000000..1cc26f7 --- /dev/null +++ b/src/Core/kyber/KeyControler.rs @@ -0,0 +1,288 @@ +use super::*; + +/// Trait for implementing key management functions. This trait provides +/// an interface for key pair generation, encapsulation/decapsulation of secrets, +/// and key manipulation (such as setting and getting key values). +pub trait KyberKeyFunctions { + /// Generates a new key pair. + fn keypair() -> Result<(Vec, Vec), CryptError>; + /// Encapsulates a secret using a public key. + fn encap(public_key: &[u8]) -> Result<(Vec, Vec), CryptError>; + /// Decapsulates a secret using a secret key and a ciphertext. + fn decap(secret_key: &[u8], ciphertext: &[u8]) -> Result, CryptError>; +} +/// Implementation for Kyber 1024 variant. +pub struct KeyControKyber1024; +impl KyberKeyFunctions for KeyControKyber1024{ + /// Generates a public and secret key pair using the Kyber1024 algorithm. + fn keypair() -> Result<(Vec,Vec), 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)) + } + + /// Encapsulates a secret using a public key to produce a shared secret and a ciphertext. + fn encap(public: &[u8]) -> Result<(Vec,Vec), 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)) + } + + /// Decapsulates the ciphertext using a secret key to retrieve the shared secret. + fn decap(sec: &[u8], cipher: &[u8]) -> Result, 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) + } +} + +/// Implementation for Kyber 768 variant. +pub struct KeyControKyber768; +impl KyberKeyFunctions for KeyControKyber768 { + /// Generates a public and secret key pair using the Kyber768 algorithm. + fn keypair() -> Result<(Vec,Vec), 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)) + } + + /// Encapsulates a secret using a public key to produce a shared secret and a ciphertext. + fn encap(public: &[u8]) -> Result<(Vec,Vec), 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)) + } + + /// Decapsulates the ciphertext using a secret key to retrieve the shared secret. + fn decap(sec: &[u8], cipher: &[u8]) -> Result, 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) + } +} + +/// Implementation for Kyber 512 variant. +pub struct KeyControKyber512; +impl KyberKeyFunctions for KeyControKyber512 { + /// Generates a public and secret key pair using the Kyber512 algorithm. + fn keypair() -> Result<(Vec,Vec), 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)) + } + + /// Encapsulates a secret using a public key to produce a shared secret and a ciphertext. + fn encap(public: &[u8]) -> Result<(Vec,Vec), 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)) + } + + /// Decapsulates the ciphertext using a secret key to retrieve the shared secret. + fn decap(sec: &[u8], cipher: &[u8]) -> Result, 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) + } +} + +/// A structure to manage cryptographic keys and operations for the Kyber algorithm. +/// It encapsulates the public key, secret key, ciphertext, and shared secret. +pub struct KeyControl { + pub public_key: Vec, + pub secret_key: Vec, + pub ciphertext: Vec, + pub shared_secret: Vec, + _marker: std::marker::PhantomData, +} + +impl KeyControl { + /// Constructs a new instance of `KeyControl`. + pub fn new() -> Self { + KeyControl { + public_key: Vec::new(), + secret_key: Vec::new(), + ciphertext: Vec::new(), + shared_secret: Vec::new(), + _marker: PhantomData, + } + } + /// Sets the ciphertext for the `KeyControl` instance. + pub fn set_ciphertext(&mut self, cipher: Vec) -> Result<(), CryptError> { + Ok(self.ciphertext = cipher) + } + + /// Sets the public key for the `KeyControl` instance. + pub fn set_public_key(&mut self, public: Vec) -> Result<(), CryptError> { + Ok(self.public_key = public) + + } + + /// Sets the secret key for the `KeyControl` instance. + pub fn set_secret_key(&mut self, sec: Vec) -> Result<(), CryptError> { + Ok(self.secret_key = sec) + + } + + /// Retrieves a specified key based on `KeyTypes`. + pub fn get_key(&self, key: KeyTypes) -> Result { + 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) + } + + /// Saves a specified key to a file at the given base path. + 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) + } + /// Loads a specified key from a file. + pub fn load(&self, key: KeyTypes, path: &Path) -> Result, 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()) + } + + + /// Getter methods for public_key, secret_key, ciphertext, and shared_secret. + + pub fn public_key(&self) -> Result, CryptError> { + let key = &self.public_key; + Ok(key.to_vec()) + } + pub fn secret_key(&self) -> Result, CryptError> { + let key = &self.secret_key; + Ok(key.to_vec()) + } + pub fn ciphertext(&self) -> Result, CryptError> { + let key = &self.ciphertext; + Ok(key.to_vec()) + } + pub fn shared_secret(&self) -> Result, CryptError> { + let key = &self.shared_secret; + Ok(key.to_vec()) + } + + /// Encapsulates a secret using a public key. + pub fn encap(&self, public: &[u8]) -> Result<(Vec,Vec), CryptError> { + T::encap(public) + } + /// Decapsulates the ciphertext using a secret key to retrieve the shared secret. + pub fn decap(&self, secret_key: &[u8], ciphertext: &[u8]) -> Result, CryptError> { + // Call the `decap` method on the type `T` that `KeyControl` wraps around + T::decap(secret_key, ciphertext) + } + +} \ No newline at end of file diff --git a/src/Core/kyber/mod.rs b/src/Core/kyber/mod.rs index 4565c79..72d0d27 100644 --- a/src/Core/kyber/mod.rs +++ b/src/Core/kyber/mod.rs @@ -1,8 +1,9 @@ /// Kyber key functionalitys -pub mod KeyKyber; +pub mod KeyControler; mod kyber_crypto; /// Cryptographic kyber functionalitys pub use kyber_crypto::*; +use KeyControler::*; use pqcrypto_traits::kem::{PublicKey, SecretKey, SharedSecret, Ciphertext}; use crate::{ *, diff --git a/src/Core/mod.rs b/src/Core/mod.rs index 372f033..4bbeb79 100644 --- a/src/Core/mod.rs +++ b/src/Core/mod.rs @@ -3,7 +3,7 @@ use crate::{cryptography::*, error::CryptError, hmac_sign::*}; pub mod KDF; /// Functions for usage of kyber for key generation pub mod kyber; -pub use kyber::KeyKyber::*; +pub use kyber::KeyControler::*; /// The `cipher_aes` module implements the AES (Advanced Encryption Standard) algorithm for secure data encryption and decryption, providing a robust symmetric key cryptography solution. pub mod cipher_aes; diff --git a/src/KeyControl/mod.rs b/src/KeyControl/mod.rs index d545ba9..89dc408 100644 --- a/src/KeyControl/mod.rs +++ b/src/KeyControl/mod.rs @@ -76,7 +76,7 @@ impl FileTypes { Self::PublicKey } /// Represents a file containing a secret (private) key. - pub fn Secret_key() -> Self { + pub fn secret_key() -> Self { Self::SecretKey } /// Represents a file containing ciphertext. diff --git a/src/error.rs b/src/error.rs index ad9dc39..4157f95 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,8 +1,8 @@ -use std::{fmt::{self, Display, Formatter}, error::Error, io, }; +use std::{fmt::{self, Display, Formatter}, error::Error, io, sync::Arc}; -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum CryptError { - IOError(String), + IOError(Arc), MessageExtractionError, InvalidMessageFormat, HexError(hex::FromHexError), @@ -37,7 +37,7 @@ pub enum CryptError { impl fmt::Display for CryptError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - CryptError::IOError(message) => write!(f, "IO error: {:?}", message), + CryptError::IOError(message) => write!(f, "IO error: {}", message), CryptError::MessageExtractionError => write!(f, "Error extracting message"), CryptError::InvalidMessageFormat => write!(f, "Invalid message format"), CryptError::HexError(err) => write!(f, "Hex error: {}", err), @@ -71,6 +71,16 @@ impl fmt::Display for CryptError { } } +impl Clone for CryptError { + fn clone(&self) -> Self { + match self { + CryptError::IOError(e) => CryptError::IOError(Arc::clone(e)), + _ => todo!(), + } + } +} + + impl CryptError { // `new` method for creating a CryptError with a custom message pub fn new(msg: &str) -> Self { @@ -78,12 +88,9 @@ impl CryptError { } } -impl From for CryptError { - fn from(error: std::io::Error) -> Self { - // Here, you might want to match on the error kind to provide more specific error variants if applicable - // For a simple catch-all conversion, you can use a general error variant from your CryptError enum - // Assume CryptError has a variant like IOError(String) for holding io::Error descriptions - CryptError::IOError(error.to_string()) +impl From for CryptError { + fn from(error: io::Error) -> Self { + CryptError::IOError(Arc::new(error)) } } @@ -104,9 +111,20 @@ pub enum SigningErr { SignatureMissing, FileCreationFailed, FileWriteFailed, + UnsupportedFileType(String), + CustomError(String), IOError(io::Error), } + +impl SigningErr { + // `new` method for creating a CryptError with a custom message + pub fn new(msg: &str) -> Self { + SigningErr::CustomError(msg.to_owned()) + } +} + + impl Display for SigningErr { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { @@ -117,6 +135,8 @@ impl Display for SigningErr { SigningErr::SignatureMissing => write!(f, "Signature is missing"), SigningErr::FileCreationFailed => write!(f, "Failed to create file"), SigningErr::FileWriteFailed => write!(f, "Failed to write to file"), + SigningErr::UnsupportedFileType(ext) => write!(f, "Unsupported file extension: .{}", ext), + SigningErr::CustomError(message) => write!(f, "{}", message), SigningErr::IOError(err) => write!(f, "IOError occurred: {}", err), } } diff --git a/src/lib.rs b/src/lib.rs index 3bbfd67..d583f3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,7 @@ pub use crate::{ *, kyber::{ *, - KeyKyber::{self, *}, + KeyControler::{self, *}, }, }, cryptography::{ diff --git a/src/log.rs b/src/log.rs index 79bb681..5d76371 100644 --- a/src/log.rs +++ b/src/log.rs @@ -3,7 +3,8 @@ use std::{ marker::PhantomData, result::Result, io::{Read, Write}, - fs::{self, OpenOptions} + fs::{self, OpenOptions}, + sync::Arc }; use chrono::{Local, NaiveDateTime}; use crate::error::CryptError; @@ -67,7 +68,7 @@ impl Log { let log_dir = parent_dir.join(file_stem); if !log_dir.exists() { - fs::create_dir_all(&log_dir).map_err(|e| CryptError::IOError(e.to_string()))?; + fs::create_dir_all(&log_dir).map_err(|e| CryptError::IOError(Arc::new(e)))?; } let mut file_path = log_dir.join(format!("{}.{}", file_stem, extension)); diff --git a/src/tests/KyberKeyTest.rs b/src/tests/KyberKeyTest.rs index dc7e758..58e5c42 100644 --- a/src/tests/KyberKeyTest.rs +++ b/src/tests/KyberKeyTest.rs @@ -123,7 +123,7 @@ fn test_key_control_safe_functionality() -> Result<(), Box Result<(), Box> { + let (public_key, secret_key) = Falcon1024::keypair().unwrap(); + let _ = Falcon1024::save_public(&public_key); + let _ = Falcon1024::save_secret(&secret_key); + + let loaded_pub = Falcon1024::load(&PathBuf::from("./Falcon1024/key.pub"))?; + let loaded_sec = Falcon1024::load(&PathBuf::from("./Falcon1024/key.sec"))?; + assert_eq!(public_key, loaded_pub); + assert!(Path::new("./Falcon1024/key.pub").exists(), "File does not exist: {}", "./Falcon1024/key.pub"); + assert!(Path::new("./Falcon1024/key.sec").exists(), "File does not exist: {}", "./Falcon1024/key.sec"); + + let _ = fs::remove_dir_all("./Falcon1024")?; + Ok(()) +} +#[test] +fn test_save_Falcon512_keys() -> Result<(), Box> { + let (public_key, secret_key) = Falcon512::keypair().unwrap(); + let _ = Falcon512::save_public(&public_key); + let _ = Falcon512::save_secret(&secret_key); + + let loaded_pub = Falcon512::load(&PathBuf::from("./Falcon512/key.pub"))?; + let loaded_sec = Falcon512::load(&PathBuf::from("./Falcon512/key.sec"))?; + assert_eq!(public_key, loaded_pub); + assert!(Path::new("./Falcon512/key.pub").exists(), "File does not exist: {}", "./Falcon512/key.pub"); + assert!(Path::new("./Falcon512/key.sec").exists(), "File does not exist: {}", "./Falcon512/key.sec"); + + let _ = fs::remove_dir_all("./Falcon512")?; + Ok(()) +} +#[test] +fn test_save_Dilithium2_keys() -> Result<(), Box> { + let (public_key, secret_key) = Dilithium2::keypair().unwrap(); + let _ = Dilithium2::save_public(&public_key); + let _ = Dilithium2::save_secret(&secret_key); + + let loaded_pub = Dilithium2::load(&PathBuf::from("./Dilithium2/key.pub"))?; + let loaded_sec = Dilithium2::load(&PathBuf::from("./Dilithium2/key.sec"))?; + assert_eq!(public_key, loaded_pub); + assert!(Path::new("./Dilithium2/key.pub").exists(), "File does not exist: {}", "./Dilithium2/key.pub"); + assert!(Path::new("./Dilithium2/key.sec").exists(), "File does not exist: {}", "./Dilithium2/key.sec"); + + let _ = fs::remove_dir_all("./Dilithium2")?; + Ok(()) +} +#[test] +fn test_save_Dilithium3_keys() -> Result<(), Box> { + let (public_key, secret_key) = Dilithium3::keypair().unwrap(); + let _ = Dilithium3::save_public(&public_key); + let _ = Dilithium3::save_secret(&secret_key); + + let loaded_pub = Dilithium3::load(&PathBuf::from("./Dilithium3/key.pub"))?; + let loaded_sec = Dilithium3::load(&PathBuf::from("./Dilithium3/key.sec"))?; + assert_eq!(public_key, loaded_pub); + assert!(Path::new("./Dilithium3/key.pub").exists(), "File does not exist: {}", "./Dilithium3/key.pub"); + assert!(Path::new("./Dilithium3/key.sec").exists(), "File does not exist: {}", "./Dilithium3/key.sec"); + + let _ = fs::remove_dir_all("./Dilithium3")?; + Ok(()) +} +#[test] +fn test_save_Dilithium5_keys() -> Result<(), Box> { + let (public_key, secret_key) = Dilithium5::keypair().unwrap(); + let _ = Dilithium5::save_public(&public_key); + let _ = Dilithium5::save_secret(&secret_key); + + let loaded_pub = Dilithium5::load(&PathBuf::from("./Dilithium5/key.pub"))?; + let loaded_sec = Dilithium5::load(&PathBuf::from("./Dilithium5/key.sec"))?; + assert_eq!(public_key, loaded_pub); + assert!(Path::new("./Dilithium5/key.pub").exists(), "File does not exist: {}", "./Dilithium5/key.pub"); + assert!(Path::new("./Dilithium5/key.sec").exists(), "File does not exist: {}", "./Dilithium5/key.sec"); + + let _ = fs::remove_dir_all("./Dilithium5")?; + Ok(()) +} #[test] fn test_falcon1024_signature_message() -> Result<(), Box> { let (public_key, secret_key) = Falcon1024::keypair().unwrap(); @@ -21,6 +100,7 @@ fn test_falcon1024_signature_message() -> Result<(), Box> #[test] fn test_falcon1024_detached_signature() -> Result<(), Box> { let (public_key, secret_key) = Falcon1024::keypair().unwrap(); + let data = b"Hello, world!".to_vec(); let sign = Signature::::new(); @@ -38,6 +118,7 @@ fn test_falcon1024_detached_signature() -> Result<(), Box #[test] fn test_falcon512_signature_message() -> Result<(), Box> { let (public_key, secret_key) = Falcon512::keypair().unwrap(); + let data = b"Hello, world!".to_vec(); let sign = Signature::::new(); // Sign the message diff --git a/src/tests/mod.rs b/src/tests/mod.rs index de7415a..4e6525d 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -18,3 +18,10 @@ mod SignatureTests; #[cfg(test)] mod LoggingTests; +#[cfg(test)] +#[test] +fn end() { + use std::fs; + let _ = fs::remove_file("crypt_tests.log"); + let _ = fs::remove_dir_all("./crypt_tests"); +} \ No newline at end of file