Skip to main content

lib_q_aead/
tweak_aead.rs

1//! Tweakable CTR AEAD wrapper.
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5use alloc::vec::Vec;
6
7use lib_q_core::{
8    Aead,
9    AeadDecryptSemantic,
10    AeadKey,
11    Algorithm,
12    DecryptSemanticOutcome,
13    Nonce,
14    Result,
15};
16
17use crate::metadata::{
18    AeadMetadata,
19    AeadWithMetadata,
20};
21
22/// Tweak AEAD — registry / HPKE-facing type.
23pub struct TweakAead {
24    metadata: &'static AeadMetadata,
25    inner: lib_q_tweak_aead::TweakAead,
26}
27
28impl TweakAead {
29    pub fn new() -> Self {
30        Self {
31            metadata: crate::metadata::get_metadata(Algorithm::TweakAead)
32                .expect("TweakAead metadata"),
33            inner: lib_q_tweak_aead::TweakAead::new(),
34        }
35    }
36}
37
38impl Aead for TweakAead {
39    fn encrypt(
40        &self,
41        key: &AeadKey,
42        nonce: &Nonce,
43        plaintext: &[u8],
44        associated_data: Option<&[u8]>,
45    ) -> Result<Vec<u8>> {
46        self.validate_key(key)?;
47        self.validate_nonce(nonce)?;
48        crate::security::validation::validate_plaintext(plaintext)?;
49        let ad = associated_data.unwrap_or(&[]);
50        crate::security::validation::validate_associated_data(ad)?;
51        self.inner.encrypt(key, nonce, plaintext, Some(ad))
52    }
53
54    fn decrypt(
55        &self,
56        key: &AeadKey,
57        nonce: &Nonce,
58        ciphertext: &[u8],
59        associated_data: Option<&[u8]>,
60    ) -> Result<Vec<u8>> {
61        self.validate_key(key)?;
62        self.validate_nonce(nonce)?;
63        self.validate_ciphertext_size(ciphertext.len())?;
64        crate::security::validation::validate_ciphertext(ciphertext)?;
65        let ad = associated_data.unwrap_or(&[]);
66        crate::security::validation::validate_associated_data(ad)?;
67        self.inner.decrypt(key, nonce, ciphertext, Some(ad))
68    }
69}
70
71impl AeadDecryptSemantic for TweakAead {
72    fn decrypt_semantic(
73        &self,
74        key: &AeadKey,
75        nonce: &Nonce,
76        ciphertext: &[u8],
77        associated_data: Option<&[u8]>,
78    ) -> Result<DecryptSemanticOutcome> {
79        self.validate_key(key)?;
80        self.validate_nonce(nonce)?;
81        self.validate_ciphertext_size(ciphertext.len())?;
82        crate::security::validation::validate_ciphertext(ciphertext)?;
83        let ad = associated_data.unwrap_or(&[]);
84        crate::security::validation::validate_associated_data(ad)?;
85        self.inner
86            .decrypt_semantic(key, nonce, ciphertext, Some(ad))
87    }
88}
89
90impl AeadWithMetadata for TweakAead {
91    fn metadata(&self) -> &'static AeadMetadata {
92        self.metadata
93    }
94}
95
96impl Default for TweakAead {
97    fn default() -> Self {
98        Self::new()
99    }
100}
101
102impl crate::plugin::AeadPlugin for TweakAead {
103    fn algorithm(&self) -> Algorithm {
104        Algorithm::TweakAead
105    }
106
107    fn create(&self) -> Result<Box<dyn AeadWithMetadata>> {
108        Ok(Box::new(Self::new()))
109    }
110
111    fn metadata(&self) -> &'static AeadMetadata {
112        crate::metadata::get_metadata(Algorithm::TweakAead).expect("TweakAead metadata")
113    }
114
115    fn name(&self) -> &'static str {
116        "Tweak-AEAD"
117    }
118
119    fn version(&self) -> &'static str {
120        "1.0.0"
121    }
122
123    fn description(&self) -> &'static str {
124        "Parallel tweakable-block CTR AEAD over Keccak-f[1600]"
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131
132    #[test]
133    fn metadata_matches() {
134        let a = TweakAead::new();
135        assert_eq!(a.algorithm(), Algorithm::TweakAead);
136        assert_eq!(a.key_size(), 32);
137        assert_eq!(a.nonce_size(), 16);
138        assert_eq!(a.tag_size(), 32);
139    }
140}