use aes_gcm::{Aes256Gcm, Key, Nonce, KeyInit}; use aes_gcm::aead::Aead;
use crate::error::RabeError;
use std::convert::TryInto;
use rand::thread_rng;
use rand::Rng;
pub fn encrypt_symmetric<G: std::convert::Into<Vec<u8>>>(msg: G, data: &Vec<u8>) -> Result<Vec<u8>, RabeError> {
let mut rng = thread_rng();
let kdf = kdf(msg);
let key = Key::<Aes256Gcm>::from_slice(kdf.as_slice());
let cipher = Aes256Gcm::new(key);
let nonce_vec: Vec<u8> = (0..12).into_iter().map(|_| rng.gen()).collect(); let nonce = Nonce::from_slice(nonce_vec.as_ref());
match cipher.encrypt(nonce, data.as_ref()) {
Ok(mut ct) => {
ct.splice(0..0, nonce.iter().cloned()); Ok(ct)
}
Err(e) => Err(RabeError::new(&format!("encryption error: {:?}", e.to_string())))
}
}
pub fn decrypt_symmetric<G: std::convert::Into<Vec<u8>>>(msg: G, _nonce_ct: &Vec<u8>) -> Result<Vec<u8>, RabeError> {
let ciphertext = _nonce_ct.clone().split_off(12); let nonce_vec: [u8; 12] = match _nonce_ct[..12].try_into() { Ok(iv) => iv,
Err(_) => return Err(RabeError::new("Error extracting IV from ciphertext: Expected an IV of 16 bytes")), };
let kdf = kdf(msg);
let key = Key::<Aes256Gcm>::from_slice(kdf.as_slice());
let cipher = Aes256Gcm::new(key);
let nonce = Nonce::from_slice(nonce_vec.as_ref());
match cipher.decrypt(nonce, ciphertext.as_ref()) {
Ok(data) => Ok(data),
Err(e) => Err(RabeError::new(&format!("decryption error: {:?}", e.to_string())))
}
}
fn kdf<T: std::convert::Into<Vec<u8>>>(data: T) -> Vec<u8> {
use sha3::{
Digest,
Sha3_256
};
let mut hasher = Sha3_256::new();
hasher.update(data.into());
hasher.finalize().to_vec()
}
mod tests {
#[test]
fn correctness_test1() {
use crate::utils::aes::{encrypt_symmetric, decrypt_symmetric};
let key = "7h15 15 4 v3ry 53cr37 k3ysdfsfsdfsdfdsfdsf1896957848";
let plaintext =
String::from("dance like no one's watching, encrypt like everyone is!");
let ciphertext = encrypt_symmetric(key, &plaintext.clone().into_bytes()).unwrap();
let reconstruct = decrypt_symmetric(key, &ciphertext).unwrap();
assert_eq!(plaintext.into_bytes(), reconstruct);
}
}