lib_q_aead/
duplex_aead.rs1#[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
22pub struct DuplexSpongeAead {
24 metadata: &'static AeadMetadata,
25 inner: lib_q_duplex_aead::DuplexSpongeAead,
26}
27
28impl DuplexSpongeAead {
29 pub fn new() -> Self {
30 Self {
31 metadata: crate::metadata::get_metadata(Algorithm::DuplexSpongeAead)
32 .expect("DuplexSpongeAead metadata"),
33 inner: lib_q_duplex_aead::DuplexSpongeAead::new(),
34 }
35 }
36}
37
38impl Aead for DuplexSpongeAead {
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 DuplexSpongeAead {
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 DuplexSpongeAead {
91 fn metadata(&self) -> &'static AeadMetadata {
92 self.metadata
93 }
94}
95
96impl Default for DuplexSpongeAead {
97 fn default() -> Self {
98 Self::new()
99 }
100}
101
102impl crate::plugin::AeadPlugin for DuplexSpongeAead {
103 fn algorithm(&self) -> Algorithm {
104 Algorithm::DuplexSpongeAead
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::DuplexSpongeAead)
113 .expect("DuplexSpongeAead metadata")
114 }
115
116 fn name(&self) -> &'static str {
117 "Duplex-Sponge-AEAD"
118 }
119
120 fn version(&self) -> &'static str {
121 "1.0.0"
122 }
123
124 fn description(&self) -> &'static str {
125 "Keccak-f[1600] duplex-sponge authenticated encryption"
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::metadata::AeadWithMetadata;
133
134 #[test]
135 fn metadata_matches() {
136 let a = DuplexSpongeAead::new();
137 assert_eq!(a.algorithm(), Algorithm::DuplexSpongeAead);
138 assert_eq!(a.key_size(), 32);
139 assert_eq!(a.nonce_size(), 16);
140 assert_eq!(a.tag_size(), 32);
141 assert!(a.supports_semantic_decrypt());
142 }
143}