libcrux_aead/lib.rs
1//! This crate provides AEAD (Authenticated Encryption with Associate Data).
2//!
3//! We currently support four AEAD algorithms:
4//!
5//! - ChaCha20Poly1305
6//! - XChaCha20Poly1305
7//! - AES-GCM 128
8//! - AES-GCM 256
9//!
10//! These can either be used directly, using the [`chacha20poly1305`],
11//! [`xchacha20poly1305`], [`aesgcm128`] and [`aesgcm256`] submodules,
12//! or using the multiplexed API, which allows chosing the used
13//! algorithm dynamically at run time.
14//!
15//! ## Static API
16//!
17//! For example, to use the static API to encrypt something using ChaCha20Poly1305:
18//!
19//! ```rust
20//! # fn main(){
21//! use libcrux_aead::chacha20poly1305::*;
22//! use libcrux_traits::aead::typed_owned::Aead as _;
23//! use libcrux_secrets::{Classify, ClassifyRef, Declassify, DeclassifyRef, U8};
24//! let key_bytes = [0u8; 32].classify();
25//! let tag_bytes = [0u8; TAG_LEN].classify();
26//! let nonce_bytes = [123u8; NONCE_LEN].classify();
27//! # const MSG_LEN: usize = 19;
28//! #
29//!
30//! let msg: &[U8; MSG_LEN] = b"squeamish ossifrage".classify_ref();
31//! let mut ciphertext = [0u8; MSG_LEN];
32//! let mut tag = Tag::from(tag_bytes);
33//!
34//! let key = Key::from(key_bytes);
35//! let nonce = Nonce::from(nonce_bytes);
36//!
37//! key.encrypt(&mut ciphertext, &mut tag, &nonce, &[/* no aad */], msg)
38//! .expect("Encryption error");
39//!
40//! // Ciphertext and tag contain encrypted data
41//! assert_eq!(
42//! ciphertext,
43//! [ 181, 223, 66, 115, 105, 181, 98, 178,
44//! 247, 139, 196, 238, 169, 225, 143, 94,
45//! 174, 123, 232 ]
46//! );
47//! assert_eq!(
48//! tag.as_ref().declassify_ref(),
49//! &[ 155, 112, 155, 212, 133, 38, 145, 115,
50//! 27, 221, 245, 237, 125, 28, 22, 101 ]
51//! );
52//! # }
53//! ```
54//!
55//! And, for decrypting:
56//!
57//! ```rust
58//! # fn main(){
59//! # use libcrux_aead::chacha20poly1305::*;
60//! # use libcrux_traits::aead::typed_owned::Aead as _;
61//! # use libcrux_secrets::{Classify, ClassifyRef, Declassify, DeclassifyRef};
62//! # let nonce_bytes = [123u8; NONCE_LEN].classify();
63//! # let key_bytes = [0u8; 32].classify();
64//! # let ciphertext = [ 181, 223, 66, 115, 105, 181, 98, 178, 247, 139, 196, 238, 169, 225, 143, 94, 174, 123, 232 ];
65//! # let tag_bytes = [ 155, 112, 155, 212, 133, 38, 145, 115, 27, 221, 245, 237, 125, 28, 22, 101 ].classify();
66//! # const MSG_LEN: usize = 19;
67//! #
68//!
69//! let mut plaintext = [0u8; MSG_LEN].classify();
70//! let mut tag = Tag::from(tag_bytes);
71//!
72//! let key = Key::from(key_bytes);
73//! let nonce = Nonce::from(nonce_bytes);
74//!
75//! key.decrypt(&mut plaintext, &nonce, &[/* no aad */], &ciphertext, &tag)
76//! .expect("Decryption error");
77//!
78//! assert_eq!( plaintext.declassify_ref(), b"squeamish ossifrage");
79//! # }
80//! ```
81//!
82//! ## Multiplexed API
83//!
84//! If you need to select the AEAD algorithm at runtime, you can use the multiplexed API. Here, the
85//! algorithm is selected through an enum variant, and the methods `new_key`, `new_nonce` etc.
86//! check that the lengths match that of the algorithm.
87//!
88//! ```rust
89//! # fn main(){
90//! # use libcrux_secrets::{Classify, ClassifyRef, Declassify, DeclassifyRef, U8};
91//! # let key_bytes = [0u8; 32].classify();
92//! # let nonce_bytes = [123u8; chacha20poly1305::NONCE_LEN].classify();
93//! # const MSG_LEN: usize = 19;
94//! # extern crate libcrux_traits;
95//! #
96//! use libcrux_aead::*;
97//! use libcrux_traits::aead::typed_refs::Aead as _;
98//!
99//! let msg: &[U8; MSG_LEN] = b"squeamish ossifrage".classify_ref();
100//! let mut ciphertext = [0u8; MSG_LEN];
101//! let mut tag_bytes = [0u8; chacha20poly1305::TAG_LEN].classify();
102//!
103//! let algo = Aead::ChaCha20Poly1305;
104//! let key = algo.new_key(&key_bytes)
105//! .expect("key should have correct length");
106//! let nonce = algo.new_nonce(&nonce_bytes)
107//! .expect("nonce should have correct length");
108//! let tag = algo.new_tag_mut(&mut tag_bytes)
109//! .expect("tag should have correct length");
110//!
111//! key.encrypt(&mut ciphertext, tag, nonce, &[/* no aad */], msg)
112//! .expect("Encryption error");
113//!
114//! // Ciphertext and tag contain encrypted data
115//! assert_eq!(
116//! ciphertext,
117//! [ 181, 223, 66, 115, 105, 181, 98, 178,
118//! 247, 139, 196, 238, 169, 225, 143, 94,
119//! 174, 123, 232 ]
120//! );
121//! assert_eq!(
122//! tag_bytes.declassify(),
123//! [ 155, 112, 155, 212, 133, 38, 145, 115,
124//! 27, 221, 245, 237, 125, 28, 22, 101 ]
125//! );
126//! # }
127//! ```
128//!
129//! Decrypting works similar:
130//!
131//! ```rust
132//! # fn main(){
133//! # use libcrux_secrets::{Classify, ClassifyRef, Declassify, DeclassifyRef, U8};
134//! # let key_bytes = [0u8; 32].classify();
135//! # let nonce_bytes = [123u8; chacha20poly1305::NONCE_LEN].classify();
136//! # let ciphertext= [ 181, 223, 66, 115, 105, 181, 98, 178, 247, 139, 196, 238, 169, 225, 143, 94, 174, 123, 232 ];
137//! # let tag_bytes = [ 155, 112, 155, 212, 133, 38, 145, 115, 27, 221, 245, 237, 125, 28, 22, 101 ].classify();
138//! # const MSG_LEN: usize = 19;
139//! # extern crate libcrux_traits;
140//! #
141//! use libcrux_aead::*;
142//! use libcrux_traits::aead::typed_refs::Aead as _;
143//!
144//! let mut plaintext = [0u8; MSG_LEN].classify();
145//!
146//! let algo = Aead::ChaCha20Poly1305;
147//! let key = algo.new_key(&key_bytes)
148//! .expect("key should have correct length");
149//! let nonce = algo.new_nonce(&nonce_bytes)
150//! .expect("nonce should have correct length");
151//! let tag = algo.new_tag(& tag_bytes)
152//! .expect("tag should have correct length");
153//!
154//! key.decrypt(&mut plaintext, nonce, &[/* no aad */], &ciphertext, tag)
155//! .expect("Decryption error");
156//!
157//! // Ciphertext and tag contain encrypted data
158//! assert_eq!(plaintext.declassify_ref(), b"squeamish ossifrage");
159//! # }
160//! ```
161//!
162//!
163
164#![no_std]
165
166mod multiplexed;
167
168pub use multiplexed::*;
169
170#[cfg(feature = "chacha20poly1305")]
171pub mod chacha20poly1305 {
172 pub use libcrux_chacha20poly1305::{
173 ChaCha20Poly1305, Key, KeyRef, Nonce, NonceRef, Tag, TagMut, TagRef, KEY_LEN, NONCE_LEN,
174 TAG_LEN,
175 };
176}
177
178#[cfg(feature = "xchacha20poly1305")]
179pub mod xchacha20poly1305 {
180 pub use libcrux_chacha20poly1305::xchacha20_poly1305::{
181 Key, KeyRef, Nonce, NonceRef, Tag, TagMut, TagRef, XChaCha20Poly1305, KEY_LEN, NONCE_LEN,
182 TAG_LEN,
183 };
184}
185
186#[cfg(feature = "aesgcm128")]
187pub mod aesgcm128 {
188 pub use libcrux_aesgcm::aes_gcm_128::{KeyRef, NonceRef, TagMut, TagRef, KEY_LEN};
189 pub use libcrux_aesgcm::{
190 AesGcm128, AesGcm128Key as Key, AesGcm128Nonce as Nonce, AesGcm128Tag as Tag, NONCE_LEN,
191 TAG_LEN,
192 };
193}
194
195#[cfg(feature = "aesgcm256")]
196pub mod aesgcm256 {
197 pub use libcrux_aesgcm::aes_gcm_256::{KeyRef, NonceRef, TagMut, TagRef, KEY_LEN};
198 pub use libcrux_aesgcm::{
199 AesGcm256, AesGcm256Key as Key, AesGcm256Nonce as Nonce, AesGcm256Tag as Tag, NONCE_LEN,
200 TAG_LEN,
201 };
202}