From ae68e7e2480e6240b50f8d26b921dd4fd7d38487 Mon Sep 17 00:00:00 2001 From: M <149858635+mm9942@users.noreply.github.com> Date: Wed, 17 Apr 2024 19:12:11 +0200 Subject: [PATCH] V1.2.6 The versions 1.2.4 and 1.2.5 had errors which is why they weren't uploaded --- Cargo.toml | 2 +- README.md | 156 +++++++++++++++++++++-- examples/encrypt_aes.rs | 7 +- examples/macro_example.rs | 35 ++++++ src/Core/cipher_aes.rs | 10 +- src/Core/cipher_xchacha.rs | 9 +- src/Core/kyber/KeyControler.rs | 1 + src/Core/kyber/kyber_crypto.rs | 142 ++++++++++++++++++++- src/Core/kyber/mod.rs | 143 +++++++++++++++++---- src/Core/mod.rs | 2 +- src/cryptography/hmac_sign/sign.rs | 6 +- src/lib.rs | 194 ++++++++++++++++++++++++++--- src/log.rs | 2 +- src/tests/KyberKeyTest.rs | 6 +- src/tests/kyber_tests.rs | 186 +++++++++++++++++++++++---- 15 files changed, 806 insertions(+), 95 deletions(-) create mode 100644 examples/macro_example.rs diff --git a/Cargo.toml b/Cargo.toml index d77e970..0c3ddea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypt_guard" -version = "1.2.3" +version = "1.2.6" 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 47049ab..e8c5d86 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,43 @@ An additional layer of security is provided through the appending of a HMAC (Has ### Current Release -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. +The present version, **1.2.6**, 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. + +### Simplifying Encryption and Decryption with Macros + +We've introduced new macros to make the encryption and decryption processes more straightforward since we only separate into encryption of bytes and automated encryption of files, thus providing an alternative to the need of manually invoking specific functions such as `encrypt_msg`, `encrypt_file`, `encrypt_data`, and their decryption equivalents. Here’s a guide on how to effectively utilize these macros: + +- **Encryption Macro**: Use the `encrypt!` macro for seamless encryption tasks. Provide it with an instance of Kyber configured for encryption, the data you want to encrypt (as a `Vec`), and a passphrase (as a string slice `&str`). + + **Syntax**: + ```rust + encrypt!(kyber_encryption_instance, data: Vec, passphrase) + ``` + +- **Decryption Macro**: The `decrypt!` macro simplifies the decryption process. Supply it with an instance of Kyber configured for decryption, the encrypted data (as `Vec`), the passphrase, and the ciphertext. + + **Syntax**: + ```rust + decrypt!(kyber_decryption_instance, data: Vec, passphrase, cipher) + ``` + +- **File Encryption Macro**: We've also implemented a macro specifically for file encryption, `encrypt_file!()`. This macro is similar to `encrypt!` but takes a `PathBuf` for file paths instead of `Vec`. + + **Syntax**: + ```rust + encrypt_file!(kyber_encryption_instance, data: PathBuf, passphrase) + ``` + +- **File Decryption Macro**: Corresponding to the file encryption macro, the `decrypt_file!()` macro is designed for file decryption, accepting a `PathBuf` instead of `Vec`. + + **Syntax**: + ```rust + decrypt_file!(kyber_decryption_instance, data: PathBuf, passphrase, cipher) + ``` + +These macros are intended to make your cryptographic operations more intuitive and less prone to errors, by removing the complexities associated with selecting the appropriate function for different data types. Note that with these macros, it is necessary to convert messages into `Vec` before encryption. + +#### Other Changes - **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. @@ -49,6 +85,92 @@ The present version, **1.2.3**, emphasizes detailed cryptographic operations. Th ## Usage Examples +### New encryption and decryption macros + +```rust +use crypt_guard::{ + encrypt, + decrypt, + KyberFunctions, + KeyControKyber1024, + KyberKeyFunctions, + error::*, + Encryption, + Decryption, + Kyber1024, + Message, + AES, + Kyber, +}; + +// Since we only allow encryption/ decryption of Vec or files through selecting a path as &str, please use +let message = "Hey, how are you doing?".as_bytes().to_owned(); +let passphrase = "Test Passphrase"; + +// Generate key pair +let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); + +// Instantiate Kyber for encryption with Kyber1024 +let mut encryptor = Kyber::::new(public_key.clone(), None)?; + +// Encrypt message with new encryption macro +// Provide it with an instance of Kyber configured for encryption, the data you want to encrypt (this can be a `PathBuf`, a string slice `&str`, or a byte vector `Vec`), a passphrase (as a string slice `&str`) and boolean checking if it is a file +let (encrypt_message, cipher) = encrypt!(encryptor, message, passphrase)?; + +// Instantiate Kyber for decryption with Kyber1024 +let mut decryptor = Kyber::::new(secret_key, None)?; + +// Decrypt message with new decryption macro +// Provide it with an instance of Kyber configured for decryption, the data you want to decrypt (this can be a `PathBuf`, a string slice `&str`, or a byte vector `Vec`), a passphrase (as a string slice `&str`) as well as a ciphertext and boolean checking if it is a file +let decrypt_message = decrypt!(decryptor, encrypt_message, passphrase, cipher); +println!("{}", String::from_utf8(decrypt_message?).expect("Failed to convert decrypted message to string")); +Ok(()) + +``` + +#### Usage of the new macros with a file + +```rust +use crypt_guard::{ + encrypt, + decrypt, + KyberFunctions, + KeyControKyber1024, + KyberKeyFunctions, + error::*, + Encryption, + Decryption, + Kyber1024, + Message, + AES, + Kyber, +}; + +// Since we only allow encryption/ decryption of Vec or files through selecting a path as &str +let path = "./message.txt"; +let passphrase = "Test Passphrase"; + +// Generate key pair +let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); + +// Instantiate Kyber for encryption with Kyber1024 +let mut encryptor = Kyber::::new(public_key.clone(), None)?; + +// Encrypt message with new encryption macro +// Provide it with an instance of Kyber configured for encryption, the data you want to encrypt (this can be a `PathBuf`, a string slice `&str`, or a byte vector `Vec`), a passphrase (as a string slice `&str`) and boolean checking if it is a file +let (encrypt_message, cipher) = encrypt_file!(encryptor, PathBuf::from(&path), passphrase)?; + +// Instantiate Kyber for decryption with Kyber1024 +let mut decryptor = Kyber::::new(secret_key, None)?; + +// Decrypt message with new decryption macro +// Provide it with an instance of Kyber configured for decryption, the data you want to decrypt (this can be a `PathBuf`, a string slice `&str`, or a byte vector `Vec`), a passphrase (as a string slice `&str`) as well as a ciphertext and boolean checking if it is a file +let decrypt_message = decrypt_file!(decryptor, PathBuf::from(format!("{}.enc", path)), passphrase, cipher); +println!("{}", String::from_utf8(decrypt_message?).expect("Failed to convert decrypted message to string")); +Ok(()) + +``` + ### The new Logging feature CryptGuard's latest release introduces a logging feature, meticulously designed to offer comprehensive insights into cryptographic operations while prioritizing security and privacy. @@ -71,13 +193,13 @@ let passphrase = "Test Passphrase"; let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber1024 -let mut encryptor = Kyber::::new(public_key.clone(), None)?; +let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; // Instantiate Kyber for decryption with Kyber1024 -let mut decryptor = Kyber::::new(secret_key, None)?; +let mut decryptor = Kyber::::new(secret_key, None)?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -150,7 +272,7 @@ keycontrol.set_secret_key(secret_key.clone()).unwrap(); keycontrol.save(KeyTypes::SecretKey, "./key".into()).unwrap(); ``` -### Encryption of a File using AES +### Encryption of a Message using AES ```rust let message = "Hey, how are you doing?"; @@ -168,6 +290,24 @@ key_control.set_ciphertext(cipher.clone()).unwrap(); key_control.save(KeyTypes::Ciphertext, "./key".into()).unwrap(); ``` +### Encryption of a Data using AES + +```rust +let message = "Hey, how are you doing?".as_bytes().to_owned(); +let passphrase = "Test Passphrase"; + +// Instantiate Kyber for encryption of a message with Kyber1024 and AES +// Fails when not using either of these properties since it would be the wrong type of algorithm, data, keysize or process! +let mut encryptor = Kyber::::new(public_key.clone(), None)?; + +// Encrypt message +let (encrypt_message, cipher) = encryptor.encrypt_data(message.clone(), passphrase.clone())?; + +// Save the ciphertext for decryption in folder ./key +key_control.set_ciphertext(cipher.clone()).unwrap(); +key_control.save(KeyTypes::Ciphertext, "./key".into()).unwrap(); +``` + ### Decryption of a File using AES ```rust @@ -176,7 +316,7 @@ let secret_key = key_control.load(KeyTypes::SecretKey, Path::new("./key/secret_k // Instantiate Kyber for decryption of a message with Kyber1024 and AES // Fails when not using either of these properties since it would be the wrong type of algorithm, data, keysize or process! -let mut decryptor = Kyber::::new(secret_key, None)?; +let mut decryptor = Kyber::::new(secret_key, None)?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -205,7 +345,7 @@ let (public_key, secret_key) = KeyControKyber768::keypair().expect("Failed to ge // Instantiate Kyber for encryption of a file with Kyber768 and XChaCha20 // Fails when not using either of these properties since it would be the wrong type of algorithm, data, keysize or process! -let mut encryptor = Kyber::::new(public_key.clone(), None)?; +let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone())?; @@ -216,7 +356,7 @@ fs::remove_file(enc_path.clone()); // Instantiate Kyber for decryption of a file with Kyber768 and XChaCha20 // Fails when not using either of these properties since it would be the wrong type of algorithm, data, keysize or process! -let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; +let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; // Decrypt message let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?; @@ -229,4 +369,4 @@ We appreciate your engagement with our cryptographic library. As we strive to im Thank you for your support and for making security a priority in your projects. ## License -CryptGuard is licensed under the MIT LICENSE. The full license text is available in the `LICENSE` file in the repository. +CryptGuard is licensed under the MIT LICENSE. The full license text is available in the `LICENSE` file in the repository. \ No newline at end of file diff --git a/examples/encrypt_aes.rs b/examples/encrypt_aes.rs index 44d81e9..4a115dc 100644 --- a/examples/encrypt_aes.rs +++ b/examples/encrypt_aes.rs @@ -1,4 +1,4 @@ -//use crypt_guard::KeyKyber::KeyControl; +use crypt_guard::KeyControler::KeyControl; use crypt_guard::{*, error::*}; use std::{ fs::{self, File}, @@ -13,6 +13,8 @@ fn main() -> Result<(), Box> { let message = "Hey, how are you doing?"; let passphrase = "Test Passphrase"; + let mut key_control = KeyControl::::new(); + // Generate key pair let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); @@ -23,6 +25,9 @@ fn main() -> Result<(), Box> { // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; + key_control.set_ciphertext(cipher.clone()).unwrap(); + key_control.save(KeyTypes::Ciphertext, "./key".into()).unwrap(); + // Instantiate Kyber for decryption of a message with Kyber1024 and AES // Fails when not using either of these properties since it would be the wrong type of algorithm, data, keysize or process! let mut decryptor = Kyber::::new(secret_key, None)?; diff --git a/examples/macro_example.rs b/examples/macro_example.rs new file mode 100644 index 0000000..f0ff35d --- /dev/null +++ b/examples/macro_example.rs @@ -0,0 +1,35 @@ +use crypt_guard::{ + encrypt, + decrypt, + KyberFunctions, + KeyControKyber1024, + KyberKeyFunctions, + error::*, + Encryption, + Decryption, + Kyber1024, + Message, + AES, + Kyber, +}; +fn main() -> Result<(), Box> { + let message = "Hey, how are you doing?".as_bytes().to_owned(); + let passphrase = "Test Passphrase"; + + // Generate key pair + let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); + + // Instantiate Kyber for encryption with Kyber1024 + let mut encryptor = Kyber::::new(public_key.clone(), None)?; + + // Encrypt message + let (encrypt_message, cipher) = encrypt!(encryptor, message, passphrase)?; + + // Instantiate Kyber for decryption with Kyber1024 + let mut decryptor = Kyber::::new(secret_key, None)?; + + // Decrypt message + let decrypt_message = decrypt!(decryptor, encrypt_message, passphrase, cipher); + println!("{}", String::from_utf8(decrypt_message?).expect("Failed to convert decrypted message to string")); + Ok(()) +} \ No newline at end of file diff --git a/src/Core/cipher_aes.rs b/src/Core/cipher_aes.rs index 2817d5d..191ad95 100644 --- a/src/Core/cipher_aes.rs +++ b/src/Core/cipher_aes.rs @@ -1,9 +1,13 @@ +use super::*; use crate::{ *, error::CryptError, - hmac_sign::*, + cryptography::{ + CryptographicInformation, + CipherAES, + hmac_sign::*, + }, Core::{ - CryptographicFunctions, KeyControl, KeyControKyber512, KeyControKyber768, @@ -166,7 +170,7 @@ impl CipherAES { let verified_data = verifier.hmac(); self.infos.set_data(&verified_data)?; - //println!("{:?}", verified_data); + // println!("{:?}", verified_data); let data = self.decrypt_aes()?; if self.infos.safe()? { let _ = self.infos.set_data(&data)?; diff --git a/src/Core/cipher_xchacha.rs b/src/Core/cipher_xchacha.rs index 147d650..4a1ee44 100644 --- a/src/Core/cipher_xchacha.rs +++ b/src/Core/cipher_xchacha.rs @@ -1,10 +1,13 @@ +use super::*; use crate::{ *, - cryptography::*, + cryptography::{ + CryptographicInformation, + CipherChaCha, + hmac_sign::*, + }, error::*, - hmac_sign::*, Core::{ - CryptographicFunctions, KeyControl, KeyControKyber512, KeyControKyber768, diff --git a/src/Core/kyber/KeyControler.rs b/src/Core/kyber/KeyControler.rs index 1cc26f7..57c55d1 100644 --- a/src/Core/kyber/KeyControler.rs +++ b/src/Core/kyber/KeyControler.rs @@ -11,6 +11,7 @@ pub trait KyberKeyFunctions { /// 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{ diff --git a/src/Core/kyber/kyber_crypto.rs b/src/Core/kyber/kyber_crypto.rs index 44105ee..a3a1f6a 100644 --- a/src/Core/kyber/kyber_crypto.rs +++ b/src/Core/kyber/kyber_crypto.rs @@ -71,6 +71,36 @@ where write_log!(); Ok((data, cipher)) } + /// Encrypts a data with AES algorithm, given the data and a passphrase. + /// Returns the encrypted data and cipher. + fn encrypt_data(&mut self, data: Vec, passphrase: &str) -> Result<(Vec, Vec), CryptError> { + let (key_encap_mechanism, kybersize) = match KyberSize::variant() { + KyberVariant::Kyber512 => { + (KeyEncapMechanism::kyber512(), 512 as usize) + }, + KyberVariant::Kyber768 => { + (KeyEncapMechanism::kyber768(), 768 as usize) + }, + KyberVariant::Kyber1024 => { + (KeyEncapMechanism::kyber1024(), 1024 as usize) + }, + }; + let crypt_metadata = CryptographicMetadata::from( + Process::encryption(), + CryptographicMechanism::aes(), + key_encap_mechanism, + ContentType::message(), + ); + let infos = CryptographicInformation::from(data, passphrase.as_bytes().to_vec(), crypt_metadata, false, None); + let mut aes = CipherAES::new(infos); + log_activity!("Creating a new cipher instance of AES.", ""); + + let (data, cipher) = aes.encrypt(self.kyber_data.key()?).unwrap(); + log_activity!("Finished:\n\t\tAlgorithm:\t\tAES,\n\t\tContent Type:\tMessage\n\t\tProcess:\t\tEncryption\n\t\tKEM:\t\t\t", format!("Kyber{}", kybersize).as_str()); + + write_log!(); + Ok((data, cipher)) + } /// Placeholder for decrypt_file, indicating operation not allowed in encryption mode. fn decrypt_file(&self, path: PathBuf, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { Err(CryptError::new("You're currently in the process state of encryption. Decryption of files isn't allowed!")) @@ -79,6 +109,10 @@ where fn decrypt_msg(&self, message: Vec, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { Err(CryptError::new("You're currently in the process state of encryption. Decryption of messanges isn't allowed!")) } + /// Placeholder for decrypt_data, indicating operation not allowed in encryption mode. + fn decrypt_data(&self, data: Vec, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { + Err(CryptError::new("You're currently in the process state of encryption. Decryption of data isn't allowed!")) + } } @@ -95,7 +129,10 @@ where fn encrypt_msg(&mut self, message: &str, passphrase: &str) -> Result<(Vec, Vec), CryptError> { Err(CryptError::new("You're currently in the process state of encryption. Decryption of messanges isn't allowed!")) } - + /// Placeholder for encrypt_msg, indicating operation not allowed in decryption mode. + fn encrypt_data(&mut self, data: Vec, passphrase: &str) -> Result<(Vec, Vec), CryptError> { + Err(CryptError::new("You're currently in the process state of encryption. Decryption of data isn't allowed!")) + } /// Decrypts a file with AES algorithm, given a path, passphrase, and ciphertext. fn decrypt_file(&self, path: PathBuf, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { if !Path::new(&path).exists() { @@ -157,6 +194,35 @@ where let data = aes.decrypt(self.kyber_data.key()?, ciphertext).unwrap(); log_activity!("Finished:\n\t\tAlgorithm:\t\tAES,\n\t\tContent Type:\tMessage\n\t\tProcess:\t\tDecryption\n\t\tKEM:\t\t\t", format!("Kyber{}", kybersize).as_str()); + write_log!(); + Ok(data) + } + /// Decrypts data with AES algorithm, given the message, passphrase, and ciphertext. + fn decrypt_data(&self, data: Vec, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { + let (key_encap_mechanism, kybersize) = match KyberSize::variant() { + KyberVariant::Kyber512 => { + (KeyEncapMechanism::kyber512(), 512 as usize) + }, + KyberVariant::Kyber768 => { + (KeyEncapMechanism::kyber768(), 768 as usize) + }, + KyberVariant::Kyber1024 => { + (KeyEncapMechanism::kyber1024(), 1024 as usize) + }, + }; + let crypt_metadata = CryptographicMetadata::from( + Process::decryption(), + CryptographicMechanism::aes(), + key_encap_mechanism, + ContentType::message(), + ); + let infos = CryptographicInformation::from(data, passphrase.as_bytes().to_vec(), crypt_metadata, false, None); + let mut aes = CipherAES::new(infos); + log_activity!("Creating a new cipher instance of AES.", ""); + + let data = aes.decrypt(self.kyber_data.key()?, ciphertext).unwrap(); + log_activity!("Finished:\n\t\tAlgorithm:\t\tAES,\n\t\tContent Type:\tMessage\n\t\tProcess:\t\tDecryption\n\t\tKEM:\t\t\t", format!("Kyber{}", kybersize).as_str()); + write_log!(); Ok(data) } @@ -206,7 +272,6 @@ where write_log!(); Ok((data, cipher)) } - /// Encrypts a message with XChaCha20 algorithm, given the message and a passphrase. /// Returns the encrypted data and cipher. fn encrypt_msg(&mut self, message: &str, passphrase: &str) -> Result<(Vec, Vec), CryptError> { @@ -239,7 +304,38 @@ where write_log!(); Ok((data, cipher)) } + /// Encrypts a data with XChaCha20 algorithm, given the data and a passphrase. + /// Returns the encrypted data and cipher. + fn encrypt_data(&mut self, data: Vec, passphrase: &str) -> Result<(Vec, Vec), CryptError> { + let (key_encap_mechanism, kybersize) = match KyberSize::variant() { + KyberVariant::Kyber512 => { + (KeyEncapMechanism::kyber512(), 512 as usize) + }, + KyberVariant::Kyber768 => { + (KeyEncapMechanism::kyber768(), 768 as usize) + }, + KyberVariant::Kyber1024 => { + (KeyEncapMechanism::kyber1024(), 1024 as usize) + }, + }; + let crypt_metadata = CryptographicMetadata::from( + Process::encryption(), + CryptographicMechanism::xchacha20(), + key_encap_mechanism, + ContentType::message(), + ); + let infos = CryptographicInformation::from(data, passphrase.as_bytes().to_vec(), crypt_metadata, false, None); + let mut xchacha = CipherChaCha::new(infos, None); + log_activity!("Creating a new cipher instance of XChaCha20.", ""); + let _ = self.kyber_data.set_nonce(hex::encode(xchacha.nonce())); + + let (data, cipher) = xchacha.encrypt(self.kyber_data.key()?).unwrap(); + log_activity!("Finished:\n\t\tAlgorithm:\t\tXChaCha20,\n\t\tContent Type:\tMessage\n\t\tProcess:\t\tEncryption\n\t\tKEM:\t\t\t", format!("Kyber{}", kybersize).as_str()); + + write_log!(); + Ok((data, cipher)) + } /// Placeholder for decrypt_file, indicating operation not allowed in encryption mode. fn decrypt_file(&self, path: PathBuf, passphrase: &str, ciphertext:Vec) -> Result, CryptError> { Err(CryptError::new("You're currently in the process state of encryption. Decryption of files isn't allowed!")) @@ -248,6 +344,10 @@ where fn decrypt_msg(&self, message: Vec, passphrase: &str, ciphertext:Vec) -> Result, CryptError> { Err(CryptError::new("You're currently in the process state of encryption. Decryption of messanges isn't allowed!")) } + /// Placeholder for decrypt_data, indicating operation not allowed in encryption mode. + fn decrypt_data(&self, data: Vec, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { + Err(CryptError::new("You're currently in the process state of encryption. Decryption of data isn't allowed!")) + } } @@ -264,7 +364,10 @@ where fn encrypt_msg(&mut self, message: &str, passphrase: &str) -> Result<(Vec, Vec), CryptError> { Err(CryptError::new("You're currently in the process state of encryption. Decryption of messanges isn't allowed!")) } - + /// Placeholder for encrypt_data, indicating operation not allowed in decryption mode. + fn encrypt_data(&mut self, data: Vec, passphrase: &str) -> Result<(Vec, Vec), CryptError> { + Err(CryptError::new("You're currently in the process state of encryption. Decryption of messanges isn't allowed!")) + } /// Decrypts a file with XChaCha20 algorithm, given a path, passphrase, and ciphertext. /// Returns the decrypted data. fn decrypt_file(&self, path: PathBuf, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { @@ -328,7 +431,38 @@ where let data = xchacha.decrypt(self.kyber_data.key()?, ciphertext).unwrap(); log_activity!("Finished:\n\t\tAlgorithm:\t\tXChaCha20,\n\t\tContent Type:\tMessage\n\t\tProcess:\t\tDecryption\n\t\tKEM:\t\t\t", format!("Kyber{}", kybersize).as_str()); - println!("data: {:?}", data); + // println!("data: {:?}", data); + write_log!(); + Ok(data) + } + /// Decrypts a message with XChaCha20 algorithm, given the message, passphrase, and ciphertext. + /// Returns the decrypted data. + fn decrypt_data(&self, data: Vec, passphrase: &str, ciphertext: Vec) -> Result, CryptError> { + let (key_encap_mechanism, kybersize) = match KyberSize::variant() { + KyberVariant::Kyber512 => { + (KeyEncapMechanism::kyber512(), 512 as usize) + }, + KyberVariant::Kyber768 => { + (KeyEncapMechanism::kyber768(), 768 as usize) + }, + KyberVariant::Kyber1024 => { + (KeyEncapMechanism::kyber1024(), 1024 as usize) + }, + }; + let crypt_metadata = CryptographicMetadata::from( + Process::decryption(), + CryptographicMechanism::xchacha20(), + key_encap_mechanism, + ContentType::message(), + ); + let infos = CryptographicInformation::from(data, passphrase.as_bytes().to_vec(), crypt_metadata, false, None); + let mut xchacha = CipherChaCha::new(infos, Some(self.kyber_data.nonce()?.to_string())); + log_activity!("Creating a new cipher instance of XChaCha20.", ""); + + let data = xchacha.decrypt(self.kyber_data.key()?, ciphertext).unwrap(); + log_activity!("Finished:\n\t\tAlgorithm:\t\tXChaCha20,\n\t\tContent Type:\tMessage\n\t\tProcess:\t\tDecryption\n\t\tKEM:\t\t\t", format!("Kyber{}", kybersize).as_str()); + + // println!("data: {:?}", data); write_log!(); Ok(data) } diff --git a/src/Core/kyber/mod.rs b/src/Core/kyber/mod.rs index 72d0d27..be9a278 100644 --- a/src/Core/kyber/mod.rs +++ b/src/Core/kyber/mod.rs @@ -10,7 +10,7 @@ use crate::{ log_activity, cryptography::*, error::CryptError, - hmac_sign::*, + //hmac_sign::*, FileTypes, FileState, FileMetadata, @@ -29,15 +29,18 @@ use std::{ /// Trait for Kyber cryptographic functions. pub trait KyberFunctions { - /// Encrypts a file at a given path with a passphrase, returning the encrypted data and nonce. + /// Encrypts a files at a given path with a passphrase, returning the encrypted data and nonce. fn encrypt_file(&mut self, path: PathBuf, passphrase: &str) -> Result<(Vec, Vec), CryptError>; /// Encrypts a message with a passphrase, returning the encrypted data and nonce. fn encrypt_msg(&mut self, message: &str, passphrase: &str) -> Result<(Vec, Vec), CryptError>; - - /// Decrypts a file at a given path with a passphrase and ciphertext, returning the decrypted data. + /// Encrypts data with a passphrase, returning the encrypted data and nonce. + fn encrypt_data(&mut self, data: Vec, passphrase: &str) -> Result<(Vec, Vec), CryptError>; + /// Decrypts a files at a given path with a passphrase and ciphertext, returning the decrypted data. fn decrypt_file(&self, path: PathBuf, passphrase: &str, ciphertext: Vec) -> Result, CryptError>; /// Decrypts a message with a passphrase and ciphertext, returning the decrypted data. fn decrypt_msg(&self, message: Vec, passphrase: &str, ciphertext: Vec) -> Result, CryptError>; + /// Decrypts data with a passphrase and ciphertext, returning the decrypted data. + fn decrypt_data(&self, data: Vec, passphrase: &str, ciphertext: Vec) -> Result, CryptError>; } @@ -66,18 +69,29 @@ impl KyberSizeVariant for Kyber1024 { fn variant() -> KyberVariant { KyberVariant::Kyber1024 } } +/// Kyber512: Kyber pub struct Kyber512; +/// Kyber768: Kyber pub struct Kyber768; +/// Kyber1024: Kyber pub struct Kyber1024; +/// AES: Kyber pub struct AES; +/// XChaCha20: Kyber pub struct XChaCha20; +/// Encryption: Kyber<**ProcessStatus: (used here)**, KeySize, ContentStatus, AlgorithmParam> pub struct Encryption; +/// Decryption: Kyber<**ProcessStatus: (used here)**, KeySize, ContentStatus, AlgorithmParam> pub struct Decryption; -pub struct File; +/// Files: Kyber +pub struct Files; +/// Message: Kyber pub struct Message; +/// Data: Kyber +pub struct Data; /// Represents the data structure for Kyber algorithm, including key and nonce. @@ -112,7 +126,7 @@ impl KyberData { } /// Represents a generic Kyber structure with templated parameters for process status, Kyber size, content status, and algorithm parameter. -pub struct Kyber +pub struct Kyber where KyberSize: KyberSizeVariant, { @@ -155,32 +169,32 @@ impl } /// Usable when KyberSize = Kyber1024 -impl Kyber { - pub fn kyber768(self) -> Result, CryptError> { - Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) +impl Kyber { + pub fn kyber768(self) -> Result, CryptError> { + Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) } - pub fn kyber512(self) -> Result, CryptError> { - Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) + pub fn kyber512(self) -> Result, CryptError> { + Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) } } /// Usable when KyberSize = Kyber768 -impl Kyber { - pub fn kyber1024(self) -> Result, CryptError> { - Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) +impl Kyber { + pub fn kyber1024(self) -> Result, CryptError> { + Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) } - pub fn kyber512(self) -> Result, CryptError> { - Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) + pub fn kyber512(self) -> Result, CryptError> { + Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) } } /// Usable when KyberSize = Kyber512 -impl Kyber { - pub fn kyber1024(self) -> Result, CryptError> { - Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) +impl Kyber { + pub fn kyber1024(self) -> Result, CryptError> { + Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) } - pub fn kyber768(self) -> Result, CryptError> { - Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) + pub fn kyber768(self) -> Result, CryptError> { + Ok(Kyber:: {kyber_data: self.kyber_data, hmac_size: self.hmac_size, process_state: self.process_state, kyber_state: PhantomData::, content_state: self.content_state, algorithm_state: self.algorithm_state}) } } @@ -211,8 +225,8 @@ impl Kyber Kyber { +/// Usable when ContentStatus = Files +impl Kyber { pub fn message(self) -> Kyber { Kyber { kyber_data: self.kyber_data, @@ -223,11 +237,78 @@ impl Kyber Kyber { + Kyber { + kyber_data: self.kyber_data, + hmac_size: self.hmac_size, + content_state: PhantomData, + kyber_state: PhantomData, + algorithm_state: PhantomData, + process_state: PhantomData, + } + } + pub fn is_file(self) -> bool { + true + } + + pub fn is_message(self) -> bool { + false + } + + pub fn is_data(self) -> bool { + false + } + } /// Usable when ContentStatus = Message impl Kyber { - pub fn file(self) -> Kyber { + pub fn file(self) -> Kyber { + Kyber { + kyber_data: self.kyber_data, + hmac_size: self.hmac_size, + content_state: PhantomData, + kyber_state: PhantomData, + algorithm_state: PhantomData, + process_state: PhantomData, + } + } + pub fn data(self) -> Kyber { + Kyber { + kyber_data: self.kyber_data, + hmac_size: self.hmac_size, + content_state: PhantomData, + kyber_state: PhantomData, + algorithm_state: PhantomData, + process_state: PhantomData, + } + } + pub fn is_file(self) -> bool { + false + } + + pub fn is_message(self) -> bool { + true + } + + pub fn is_data(self) -> bool { + false + } + +} +/// Usable when ContentStatus = Message +impl Kyber { + pub fn file(self) -> Kyber { + Kyber { + kyber_data: self.kyber_data, + hmac_size: self.hmac_size, + content_state: PhantomData, + kyber_state: PhantomData, + algorithm_state: PhantomData, + process_state: PhantomData, + } + } + pub fn message(self) -> Kyber { Kyber { kyber_data: self.kyber_data, hmac_size: self.hmac_size, @@ -237,6 +318,18 @@ impl Kyber bool { + false + } + + pub fn is_message(self) -> bool { + false + } + + pub fn is_data(self) -> bool { + true + } + } /// Usable when ProcessStatus = Encryption @@ -255,7 +348,7 @@ impl Kyber Kyber { - pub fn encryption(self) -> Kyber { + pub fn encryption(self) -> Kyber { Kyber { kyber_data: self.kyber_data, hmac_size: self.hmac_size, diff --git a/src/Core/mod.rs b/src/Core/mod.rs index 4bbeb79..b1de5b0 100644 --- a/src/Core/mod.rs +++ b/src/Core/mod.rs @@ -1,4 +1,4 @@ -use crate::{cryptography::*, error::CryptError, hmac_sign::*}; +use crate::{cryptography::*, error::CryptError, cryptography::hmac_sign::*}; /// Functions for usage of falcon and dilithium pub mod KDF; /// Functions for usage of kyber for key generation diff --git a/src/cryptography/hmac_sign/sign.rs b/src/cryptography/hmac_sign/sign.rs index 8665166..f9d2746 100644 --- a/src/cryptography/hmac_sign/sign.rs +++ b/src/cryptography/hmac_sign/sign.rs @@ -70,9 +70,9 @@ impl Sign { .expect("HMAC can take key of any size"); mac.update(&data); let hmac = mac.finalize().into_bytes().to_vec(); - println!("HMAC: {:?}", hmac); + // println!("HMAC: {:?}", hmac); let concat_data = [&self.data.data, hmac.as_slice()].concat(); - println!("Concated data: {:?}", concat_data); + // println!("Concated data: {:?}", concat_data); concat_data }, _ => vec![], @@ -130,7 +130,7 @@ impl Sign { }; if verification_success { - println!("splittet data: {:?}", data); + // println!("splittet data: {:?}", data); Ok(data.to_owned()) } else { Err("HMAC verification failed") diff --git a/src/lib.rs b/src/lib.rs index d583f3d..8fae0d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,147 @@ +//! # CryptGuard Programming Library +//! +//! [![Crates.io][crates-badge]][crates-url] +//! [![MIT licensed][mit-badge]][mit-url] +//! [![Documentation][doc-badge]][doc-url] +//! [![Hashnode Blog][blog-badge]][blog-url] +//! [![GitHub Library][lib-badge]][lib-link] +//! +//! [blog-badge]: https://img.shields.io/badge/blog-hashnode-lightblue.svg?style=for-the-badge +//! [blog-url]: https://blog.mm29942.com/ +//! [crates-badge]: https://img.shields.io/badge/crates.io-v1.2-blue.svg?style=for-the-badge +//! [crates-url]: https://crates.io/crates/crypt_guard +//! [mit-badge]: https://img.shields.io/badge/license-MIT-green.svg?style=for-the-badge +//! [mit-url]: https://github.com/mm9942/CryptGuardLib/blob/main/LICENSE +//! [doc-badge]: https://img.shields.io/badge/docs-v1.2-yellow.svg?style=for-the-badge +//! [doc-url]: https://docs.rs/crypt_guard/ +//! [lib-badge]: https://img.shields.io/badge/github-lib-black.svg?style=for-the-badge +//! [lib-link]: https://github.com/mm9942/CryptGuardLib +//! +//! ## Introduction +//! +//! CryptGuard is a comprehensive cryptographic library, offering robust encryption and decryption capabilities. It integrates traditional cryptography with post-quantum algorithms, ensuring resilience against quantum computing threats. Designed for developers, CryptGuard empowers applications to withstand future digital security challenges. Embrace CryptGuard as your trusted ally in safeguarding privacy in the digital realm. +//! +//! ## Key Features and Capabilities +//! +//! This library supports AES-256 and XChaCha20 encryption algorithms, providing a secure means to protect data. To cater to a variety of security requirements and operational contexts, CryptGuard integrates seamlessly with Kyber512, Kyber768, and Kyber1024 for encryption, ensuring compatibility with post-quantum cryptography standards. +//! +//! For developers who require digital signing capabilities, CryptGuard incorporates Falcon and Dilithium algorithms, offering robust options for creating and verifying digital signatures. This feature is particularly crucial for applications that necessitate authenticity and integrity of data, ensuring that digital communications remain secure and verifiable. +//! +//! An additional layer of security is provided through the appending of a HMAC (Hash-Based Message Authentication Code) to encrypted data. This critical feature enables the authentication of encrypted information, ensuring that any tampering with the data can be reliably detected. This HMAC attachment underscores CryptGuard's commitment to comprehensive data integrity and security, offering developers and end-users peace of mind regarding the authenticity and safety of their data. +//! +//! # Examples +//! +//! ### Encryption: +//! +//! The encryption functions `encrypt_msg`, `encrypt_data`, and `encrypt_file` are specifically tailored for different types of data. Using distinct functions ensures that the correct methods and optimizations are applied depending on whether you're encrypting raw bytes, structured data, or files. Each encryption function requires a new instance of the Kyber object, tailored for the type of encryption (Message, Data, Files), to guarantee that the cryptographic parameters are initialized correctly and securely for each session. +//! +//! ```rust +//! use crypt_guard::*; +//! +//! let message = "Hey, how are you doing?"; +//! let passphrase = "Test Passphrase"; +//! +//! let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); +//! +//! // Creating new Kyber AES message instance +//! let mut encryptor = Kyber::::new(public_key.clone(), None).unwrap(); +//! +//! // Now are multiple options available: +//! // Using the Macro +//! let (encrypt_message, cipher) = encrypt!(encryptor, message.clone(), passphrase.clone()).unwrap(); +//! +//! // Using the encrypt_ functions: +//! +//! // Message: +//! let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone()).unwrap(); +//! +//! // Data: +//! // Creating new Kyber AES data instance +//! let mut encryptor = Kyber::::new(public_key.clone(), None).unwrap(); +//! let (encrypt_message, cipher) = encryptor.encrypt_data(message.clone().as_bytes().to_owned(), passphrase.clone()).unwrap(); +//! +//! // Last but not least the encryption function for files: +//! fs::write(PathBuf::from("message.txt"), message.clone().as_bytes()).unwrap(); +//! +//! // Creating new Kyber AES file instance +//! let mut encryptor = Kyber::::new(public_key.clone(), None).unwrap(); +//! +//! // Encrypt file macro: +//! let (encrypt_message, cipher) = encrypt_file!(encryptor, PathBuf::from("message.txt"), passphrase.clone()).unwrap(); +//! +//! // Encrypt file function: +//! let (encrypt_message, cipher) = encryptor.encrypt_file(PathBuf::from("message.txt"), passphrase.clone()).unwrap(); +//! ``` +//! +//! #### Infos about XChaCha20 differences +//! +//! XChaCha20, unlike AES, requires handling of a nonce (number used once) which must be generated during encryption and subsequently used during decryption. This introduces additional steps in the cryptographic process when using XChaCha20 compared to AES, which does not explicitly require nonce management by the user. +//! +//! ```rust +//! use crypt_guard::*; +//! +//! // You need to save the nonce when not using AES but XChaCha20 instead: +//! // Creating new Kyber XChaCha20 file encryption instance +//! let mut encryptor = Kyber::::new(public_key.clone(), None).unwrap(); +//! +//! // Encrypt file +//! let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone()).unwrap(); +//! +//! // Should be executed after encryption is already done, since doing it before that would trigger an error. +//! let nonce = encryptor.get_nonce(); +//! +//! // Creating new Kyber XChaCha20 file decryption instance (this time also adding the nonce beside the key) +//! let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string())).unwrap(); +//! +//! // Decrypt message +//! let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher).unwrap(); +//! ``` +//! +//! ### Decryption: +//! +//! Decryption functions work similarly to encryption but in reverse, designed to safely convert encrypted data back into its original form. Each type of data (Message, Data, Files) requires a specific decryption function to correctly handle the format and details of the encrypted content. Like encryption, every decryption session uses a fresh Kyber object to ensure isolation between sessions, enhancing security by preventing potential leakage or reuse of cryptographic parameters. +//! +//! ```rust +//! use crypt_guard::*; +//! +//! // Creating new Kyber AES message instance for decryption +//! let mut decryptor = Kyber::::new(secret_key, None).unwrap(); +//! let decrypt_message = decrypt!(decryptor, encrypt_message.clone(), passphrase.clone(), cipher).unwrap(); +//! +//! // Using the decrypt_ functions: +//! +//! // Message: +//! let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher).unwrap(); +//! +//! // Data: +//! // Creating new Kyber AES data instance for decryption +//! let mut decryptor = Kyber::::new(secret_key, None).unwrap(); +//! let decrypt_message = decryptor.decrypt_data(encrypt_message.clone(), passphrase.clone(), cipher).unwrap(); +//! +//! // Last but not least the decryption function for files: +//! let file_path = PathBuf::from("message.txt"); +//! let encrypted_file_path = PathBuf::from("message.txt.enc"); +//! +//! // Creating new Kyber AES file instance for decryption +//! let mut decryptor = Kyber::::new(secret_key, None).unwrap(); +//! +//! // Decrypt file macro +//! let decrypt_message = decrypt!(decryptor, encrypted_file_path, passphrase.clone(), cipher).unwrap(); +//! +//! // Decrypt file function +//! let decrypt_message = decryptor.decrypt_file(encrypted_file_path, passphrase.clone(), cipher).unwrap(); +//! ``` + #[macro_use] extern crate lazy_static; + /// Core functionalitys for control of Kyber keys as well as encryption and decryption mod Core; /// Cryptographic related functionalitys, enums structs and modules -mod cryptography; +pub mod cryptography; /// File and Key related functionalitys, enums structs and modules -mod KeyControl; +pub mod KeyControl; /// Logging related functionalitys pub mod log; /// Error types @@ -17,28 +152,18 @@ mod tests; pub use crate::{ log::*, - Core::KDF, KeyControl::{ *, - file::*, + file, }, Core::{ *, - kyber::{ - *, - KeyControler::{self, *}, - }, + KDF, + kyber::*, }, - cryptography::{ - *, - }, - }; use KeyControl::*; -use cryptography::*; - - use pqcrypto_falcon::falcon1024::{self, *}; use pqcrypto_kyber::kyber1024::{self, *}; use std::{ @@ -53,6 +178,7 @@ use std::{ fs }; + lazy_static! { static ref LOGGER: Mutex = Mutex::new(Log { activated: false, @@ -61,24 +187,58 @@ lazy_static! { }); } +/// Function activating the log, it takes one arg: `&str` which represents the location of the logfile pub fn activate_log>(log_file: P) { let mut logger = LOGGER.lock().unwrap(); logger.activated = true; logger.location = Some(log_file.as_ref().to_path_buf()); } +/// Macro for encryption of data, taking a Kyber encryption instance, a `Vec` as well as a passphrase and ciphertext as arguments +#[macro_export] +macro_rules! encrypt { + ($kyber:expr, $data:expr, $passphrase:expr) => {{ + $kyber.encrypt_data($data, $passphrase) + }}; +} +/// Macro for encryption of a file, taking a Kyber decryption instance, a `PathBuf` as well as a passphrase and ciphertext as arguments +#[macro_export] +macro_rules! encrypt_file { + ($kyber:expr, $path:expr, $passphrase:expr) => {{ + $kyber.encrypt_file($path, $passphrase) + }}; +} + +/// Macro for decryption of data, taking a Kyber decryption instance, a `Vec` as well as a passphrase and ciphertext as arguments +#[macro_export] +macro_rules! decrypt { + ($kyber:expr, $encrypted_data:expr, $passphrase:expr, $cipher:expr) => {{ + $kyber.decrypt_data($encrypted_data, $passphrase, $cipher) + }}; +} + +/// Macro for decryption of a file, taking a Kyber decryption instance, a `PathBuf` as well as a passphrase and ciphertext as arguments +#[macro_export] +macro_rules! decrypt_file { + ($kyber:expr, $path:expr, $passphrase:expr, $cipher:expr) => {{ + $kyber.decrypt_file($path, $passphrase, $cipher) + }}; +} + + #[macro_export] macro_rules! log_activity { - ($process:expr, $kyber_size:expr) => { + ($process:expr, $detail:expr) => { match LOGGER.lock() { Ok(mut logger) => { - let _ = logger.append_log($process, $kyber_size); + let _ = logger.append_log($process, $detail); }, Err(e) => eprintln!("Logger lock error: {}", e), } }; } +/// Macro commanding to write the current in a string stored log into a logfile #[macro_export] macro_rules! write_log { () => { diff --git a/src/log.rs b/src/log.rs index 5d76371..96552af 100644 --- a/src/log.rs +++ b/src/log.rs @@ -59,7 +59,7 @@ impl Log { /// Create a new splitted log file pub fn write_log_file(&mut self) -> Result<(), CryptError> { if !self.activated { - return Err(CryptError::CustomError("Logger is not activated.".to_string())); + return Ok(()); } if let Some(ref location) = self.location { let parent_dir = location.parent().unwrap_or_else(|| Path::new("")); diff --git a/src/tests/KyberKeyTest.rs b/src/tests/KyberKeyTest.rs index 58e5c42..848dbca 100644 --- a/src/tests/KyberKeyTest.rs +++ b/src/tests/KyberKeyTest.rs @@ -6,7 +6,11 @@ use std::{ path::{PathBuf, Path}, }; use crate::{ - hmac_sign::*, + cryptography::{ + CryptographicInformation, + CipherAES, + hmac_sign::*, + }, KeyControKyber1024, KeyControKyber512, KeyControKyber768, diff --git a/src/tests/kyber_tests.rs b/src/tests/kyber_tests.rs index 9a2c627..e9cbf10 100644 --- a/src/tests/kyber_tests.rs +++ b/src/tests/kyber_tests.rs @@ -3,11 +3,116 @@ use std::io::{Read, Write}; use tempfile::{TempDir, Builder}; use std::fs::{self, File}; use std::marker::PhantomData; +use std::path::{Path, PathBuf}; use crate::{ + encrypt, + decrypt, + encrypt_file, + decrypt_file, Core::{kyber::{KyberFunctions, *}, *}, error::* }; +#[test] +fn encrypt_decrypt_msg_macro_AES_Kyber1024() -> Result<(), Box> { + let message = "Hey, how are you doing?"; + let passphrase = "Test Passphrase"; + + // Generate key pair + let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); + + // Instantiate Kyber for encryption with Kyber1024 + let mut encryptor = Kyber::::new(public_key.clone(), None)?; + + // Encrypt message + let (encrypt_message, cipher) = encrypt!(encryptor, message.as_bytes().to_owned(), passphrase)?; + + // Instantiate Kyber for decryption with Kyber1024 + let mut decryptor = Kyber::::new(secret_key, None)?; + + // Decrypt message + let decrypt_message = decrypt!(decryptor, encrypt_message, passphrase, cipher); + + // Convert Vec to String for comparison + let decrypted_text = String::from_utf8(decrypt_message?).expect("Failed to convert decrypted message to string"); + + // Assert that the decrypted message matches the original message + assert_eq!(decrypted_text, message); + + Ok(()) +} + +#[test] +fn encrypt_decrypt_data_macro_AES_Kyber1024() -> Result<(), Box> { + let data = "Hey, how are you doing?".as_bytes().to_owned(); + let passphrase = "Test Passphrase"; + + // Generate key pair + let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); + + // Instantiate Kyber for encryption with Kyber1024 + let mut encryptor = Kyber::::new(public_key.clone(), None)?; + + // Encrypt message + let (encrypt_message, cipher) = encrypt!(encryptor, data.clone(), passphrase)?; + + // Instantiate Kyber for decryption with Kyber1024 + let mut decryptor = Kyber::::new(secret_key, None)?; + + // Decrypt message + let decrypt_message = decrypt!(decryptor, encrypt_message, passphrase, cipher); + + // Assert that the decrypted message matches the original message + assert_eq!(decrypt_message?, data); + + Ok(()) +} + +#[test] +fn encrypt_decrypt_file_macro_AES_Kyber1024() -> Result<(), Box> { + let message = "Hey, how are you doing?"; + + let tmp_dir = TempDir::new().map_err(|e| CryptError::from(e))?; + let tmp_dir = Builder::new().prefix("messages").tempdir().map_err(|e| CryptError::from(e))?; + + let enc_path = tmp_dir.path().clone().join("message.txt"); + let dec_path = tmp_dir.path().clone().join("message.txt.enc"); + + fs::write(&enc_path, message.as_bytes())?; + + let passphrase = "Test Passphrase"; + + // Generate key pair + let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); + + // Instantiate Kyber for encryption with Kyber1024 + let mut encryptor = Kyber::::new(public_key.clone(), None)?; + + // Encrypt message + let (encrypt_message, cipher) = encrypt_file!(encryptor, enc_path.clone(), passphrase)?; + + fs::remove_file(enc_path.clone()); + + // Instantiate Kyber for decryption with Kyber1024 + let mut decryptor = Kyber::::new(secret_key, None)?; + + // Decrypt message + let decrypt_message = decrypt_file!(decryptor, dec_path.clone(), passphrase, cipher); + + // Convert Vec to String for comparison + let decrypted_text = String::from_utf8(decrypt_message?).expect("Failed to convert decrypted message to string"); + + // Assert that the decrypted message matches the original message + assert_eq!(decrypted_text, message.clone()); + + assert!(enc_path.exists(), "Decrypted file should exist after decryption."); + let decrypted_message = fs::read_to_string(&enc_path)?; + assert_eq!(decrypted_message, message, "Decrypted message should match the original message."); + + Ok(()) +} + + #[test] fn encrypt_message_AES_Kyber1024() -> Result<(), Box> { let message = "Hey, how are you doing?"; @@ -17,13 +122,13 @@ fn encrypt_message_AES_Kyber1024() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber1024 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; // Instantiate Kyber for decryption with Kyber1024 - let mut decryptor = Kyber::::new(secret_key, None)?; + let mut decryptor = Kyber::::new(secret_key, None)?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -37,6 +142,33 @@ fn encrypt_message_AES_Kyber1024() -> Result<(), Box> { Ok(()) } +#[test] +fn encrypt_data_AES_Kyber1024() -> Result<(), Box> { + let message = "Hey, how are you doing?".as_bytes().to_owned(); + let passphrase = "Test Passphrase"; + + // Generate key pair + let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); + + // Instantiate Kyber for encryption with Kyber1024 + let mut encryptor = Kyber::::new(public_key.clone(), None)?; + + // Encrypt message + let (encrypt_message, cipher) = encryptor.encrypt_data(message.clone(), passphrase.clone())?; + + // Instantiate Kyber for decryption with Kyber1024 + let mut decryptor = Kyber::::new(secret_key, None)?; + + // Decrypt message + let decrypt_message = decryptor.decrypt_data(encrypt_message.clone(), passphrase.clone(), cipher)?; + + // Assert that the decrypted message matches the original message + assert_eq!(decrypt_message, message); + + Ok(()) +} + + #[test] fn encrypt_message_AES_Kyber768() -> Result<(), Box> { let message = "Hey, how are you doing?"; @@ -46,13 +178,13 @@ fn encrypt_message_AES_Kyber768() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber768::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber768 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; // Instantiate Kyber for decryption with Kyber768 - let mut decryptor = Kyber::::new(secret_key, None)?; + let mut decryptor = Kyber::::new(secret_key, None)?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -74,13 +206,13 @@ fn encrypt_message_AES_Kyber512() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber512::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber512 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; // Instantiate Kyber for decryption with Kyber512 - let mut decryptor = Kyber::::new(secret_key, None)?; + let mut decryptor = Kyber::::new(secret_key, None)?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -112,7 +244,7 @@ fn encrypt_file_AES_Kyber1024() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber1024 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone())?; @@ -120,7 +252,7 @@ fn encrypt_file_AES_Kyber1024() -> Result<(), Box> { fs::remove_file(enc_path.clone()); // Instantiate Kyber for decryption with Kyber1024 - let mut decryptor = Kyber::::new(secret_key, None)?; + let mut decryptor = Kyber::::new(secret_key, None)?; // Decrypt message let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?; @@ -156,7 +288,7 @@ fn encrypt_file_AES_Kyber768() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber768::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber1024 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone())?; @@ -164,13 +296,13 @@ fn encrypt_file_AES_Kyber768() -> Result<(), Box> { fs::remove_file(enc_path.clone()); // Instantiate Kyber for decryption with Kyber1024 - let mut decryptor = Kyber::::new(secret_key, None)?; + let mut decryptor = Kyber::::new(secret_key, None)?; - // Decrypt message - let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?; + // Decrypt file + let decrypt_file = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?; // Convert Vec to String for comparison - let decrypted_text = String::from_utf8(decrypt_message).expect("Failed to convert decrypted message to string"); + let decrypted_text = String::from_utf8(decrypt_file).expect("Failed to convert decrypted message to string"); // Assert that the decrypted message matches the original message assert_eq!(decrypted_text, message.clone()); @@ -201,7 +333,7 @@ fn encrypt_file_AES_Kyber512() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber512::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber512 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone())?; @@ -209,7 +341,7 @@ fn encrypt_file_AES_Kyber512() -> Result<(), Box> { fs::remove_file(enc_path.clone()); // Instantiate Kyber for decryption with Kyber512 - let mut decryptor = Kyber::::new(secret_key, None)?; + let mut decryptor = Kyber::::new(secret_key, None)?; // Decrypt message let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?; @@ -236,7 +368,7 @@ fn encrypt_message_XChaCha20_Kyber1024() -> Result<(), Box::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; @@ -244,7 +376,7 @@ fn encrypt_message_XChaCha20_Kyber1024() -> Result<(), Box::new(secret_key, Some(nonce?.to_string()))?; + let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -264,7 +396,7 @@ fn encrypt_message_XChaCha20_Kyber768() -> Result<(), Box let (public_key, secret_key) = KeyControKyber768::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber768 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; @@ -272,7 +404,7 @@ fn encrypt_message_XChaCha20_Kyber768() -> Result<(), Box let nonce = encryptor.get_nonce(); // Instantiate Kyber for decryption with Kyber768 - let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; + let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -292,7 +424,7 @@ fn encrypt_message_XChaCha20_Kyber512() -> Result<(), Box let (public_key, secret_key) = KeyControKyber512::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber512 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_msg(message.clone(), passphrase.clone())?; @@ -300,7 +432,7 @@ fn encrypt_message_XChaCha20_Kyber512() -> Result<(), Box let nonce = encryptor.get_nonce(); // Instantiate Kyber for decryption with Kyber512 - let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; + let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; // Decrypt message let decrypt_message = decryptor.decrypt_msg(encrypt_message.clone(), passphrase.clone(), cipher)?; @@ -329,7 +461,7 @@ fn encrypt_file_XChaCha20_Kyber1024() -> Result<(), Box> let (public_key, secret_key) = KeyControKyber1024::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber1024 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone())?; @@ -339,7 +471,7 @@ fn encrypt_file_XChaCha20_Kyber1024() -> Result<(), Box> fs::remove_file(enc_path.clone()); // Instantiate Kyber for decryption with Kyber1024 - let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; + let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; // Decrypt message let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?; @@ -375,7 +507,7 @@ fn encrypt_file_XChaCha20_Kyber768() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber768::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber768 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone())?; @@ -385,7 +517,7 @@ fn encrypt_file_XChaCha20_Kyber768() -> Result<(), Box> { fs::remove_file(enc_path.clone()); // Instantiate Kyber for decryption with Kyber768 - let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; + let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; // Decrypt message let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?; @@ -421,7 +553,7 @@ fn encrypt_file_XChaCha20_Kyber512() -> Result<(), Box> { let (public_key, secret_key) = KeyControKyber512::keypair().expect("Failed to generate keypair"); // Instantiate Kyber for encryption with Kyber512 - let mut encryptor = Kyber::::new(public_key.clone(), None)?; + let mut encryptor = Kyber::::new(public_key.clone(), None)?; // Encrypt message let (encrypt_message, cipher) = encryptor.encrypt_file(enc_path.clone(), passphrase.clone())?; @@ -431,7 +563,7 @@ fn encrypt_file_XChaCha20_Kyber512() -> Result<(), Box> { fs::remove_file(enc_path.clone()); // Instantiate Kyber for decryption with Kyber512 - let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; + let mut decryptor = Kyber::::new(secret_key, Some(nonce?.to_string()))?; // Decrypt message let decrypt_message = decryptor.decrypt_file(dec_path.clone(), passphrase.clone(), cipher)?;