sentinel_crypto/encrypt/
ascon128.rs1use ascon_aead::{
2 aead::{Aead, KeyInit},
3 AsconAead128 as Ascon128,
4 Key,
5 Nonce,
6};
7use rand::RngCore;
8
9use crate::{encrypt_trait::EncryptionAlgorithm, error::CryptoError};
10
11pub struct Ascon128Encryptor;
19
20impl EncryptionAlgorithm for Ascon128Encryptor {
21 fn encrypt_data(data: &[u8], key: &[u8; 32]) -> Result<String, CryptoError> {
22 let key_16: &[u8; 16] = key[.. 16].try_into().unwrap();
24 let cipher = Ascon128::new(Key::<Ascon128>::from_slice(key_16));
25 let mut nonce_bytes = [0u8; 16]; rand::rng().fill_bytes(&mut nonce_bytes);
27 let nonce = Nonce::<Ascon128>::from_slice(&nonce_bytes);
28
29 let ciphertext = cipher
30 .encrypt(nonce, data)
31 .map_err(|_| CryptoError::Encryption)?;
32 let mut result = nonce_bytes.to_vec();
33 result.extend_from_slice(&ciphertext);
34 Ok(hex::encode(result))
35 }
36
37 fn decrypt_data(encrypted_data: &str, key: &[u8; 32]) -> Result<Vec<u8>, CryptoError> {
38 let data = hex::decode(encrypted_data).map_err(|_| CryptoError::Decryption)?;
39 if data.len() < 16 {
40 return Err(CryptoError::Decryption);
41 }
42 let (nonce_bytes, ciphertext) = data.split_at(16);
43 let key_16: &[u8; 16] = key[.. 16].try_into().unwrap();
45 let cipher = Ascon128::new(Key::<Ascon128>::from_slice(key_16));
46 let nonce = Nonce::<Ascon128>::from_slice(nonce_bytes);
47 cipher
48 .decrypt(nonce, ciphertext)
49 .map_err(|_| CryptoError::Decryption)
50 }
51}
52
53impl crate::encrypt_trait::private::Sealed for Ascon128Encryptor {}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_encrypt_decrypt() {
61 let key = [0u8; 32];
62 let data = b"Hello, world!";
63 let encrypted = Ascon128Encryptor::encrypt_data(data, &key).unwrap();
64 let decrypted = Ascon128Encryptor::decrypt_data(&encrypted, &key).unwrap();
65 assert_eq!(decrypted, data);
66 }
67
68 #[test]
69 fn test_decrypt_invalid_length() {
70 let key = [0u8; 32];
71 let short_hex = hex::encode(&[0u8; 14]); let result = Ascon128Encryptor::decrypt_data(&short_hex, &key);
74 assert!(result.is_err());
75 }
76}