1mod ct;
15#[cfg(test)]
16mod test_utils;
17
18pub use ct::zeroize_slice;
19
20#[cfg(feature = "ct_profile")]
21pub use ct::{
22 ct_profile_measure_helper_costs, ct_profile_reset, ct_profile_snapshot, CtAnfHelperCostsNs,
23 CtAnfProfile,
24};
25
26pub mod ciphers;
27pub mod cprng;
28pub mod hash;
29pub mod modes;
30pub mod public_key;
31
32pub use ciphers::{
33 aes, camellia, cast128, chacha20, des, grasshopper, magma, present, rabbit, salsa20, seed,
34 serpent, simon, sm4, snow3g, speck, twofish, zuc,
35};
36
37pub trait BlockCipher {
42 const BLOCK_LEN: usize;
44 fn encrypt(&self, block: &mut [u8]);
46 fn decrypt(&self, block: &mut [u8]);
48}
49
50pub trait StreamCipher {
55 fn fill(&mut self, buf: &mut [u8]);
57
58 fn apply_keystream(&mut self, buf: &mut [u8]) {
60 self.fill(buf);
61 }
62}
63
64pub trait Aead {
66 type Tag;
68
69 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag;
71
72 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool;
74
75 fn encrypt(&self, nonce: &[u8], aad: &[u8], plaintext: &[u8]) -> (Vec<u8>, Self::Tag) {
77 let mut out = plaintext.to_vec();
78 let tag = self.encrypt_in_place(nonce, aad, &mut out);
79 (out, tag)
80 }
81
82 fn decrypt(
84 &self,
85 nonce: &[u8],
86 aad: &[u8],
87 ciphertext: &[u8],
88 tag: &Self::Tag,
89 ) -> Option<Vec<u8>> {
90 let mut out = ciphertext.to_vec();
91 if !self.decrypt_in_place(nonce, aad, &mut out, tag) {
92 return None;
93 }
94 Some(out)
95 }
96}
97
98pub trait Csprng {
100 fn fill_bytes(&mut self, out: &mut [u8]);
102
103 fn next_u64(&mut self) -> u64 {
105 let mut out = [0u8; 8];
106 self.fill_bytes(&mut out);
107 u64::from_be_bytes(out)
108 }
109}
110
111pub use ciphers::aes::{Aes128, Aes128Ct, Aes192, Aes192Ct, Aes256, Aes256Ct};
112pub use ciphers::camellia::{
113 Camellia, Camellia128, Camellia128Ct, Camellia192, Camellia192Ct, Camellia256, Camellia256Ct,
114 CamelliaCt,
115};
116pub use ciphers::cast128::{Cast128, Cast128Ct, Cast5, Cast5Ct};
117pub use ciphers::chacha20::{ChaCha20, XChaCha20};
118pub use ciphers::des::{key_schedule, Des, DesCt, KeySchedule, TDesMode, TripleDes};
119pub use ciphers::grasshopper::{Grasshopper, GrasshopperCt};
120pub use ciphers::magma::{Magma, MagmaCt};
121pub use ciphers::present::{Present, Present128, Present128Ct, Present80, Present80Ct, PresentCt};
122pub use ciphers::rabbit::Rabbit;
123pub use ciphers::salsa20::Salsa20;
124pub use ciphers::seed::{Seed, SeedCt};
125pub use ciphers::serpent::{
126 Serpent, Serpent128, Serpent128Ct, Serpent192, Serpent192Ct, Serpent256, Serpent256Ct,
127 SerpentCt,
128};
129pub use ciphers::simon::{
130 Simon128_128, Simon128_192, Simon128_256, Simon32_64, Simon48_72, Simon48_96, Simon64_128,
131 Simon64_96, Simon96_144, Simon96_96,
132};
133pub use ciphers::sm4::{Sm4, Sm4Ct, Sms4, Sms4Ct};
134pub use ciphers::snow3g::{Snow3g, Snow3gCt};
135pub use ciphers::speck::{
136 Speck128_128, Speck128_192, Speck128_256, Speck32_64, Speck48_72, Speck48_96, Speck64_128,
137 Speck64_96, Speck96_144, Speck96_96,
138};
139pub use ciphers::twofish::{
140 Twofish, Twofish128, Twofish128Ct, Twofish192, Twofish192Ct, Twofish256, Twofish256Ct,
141 TwofishCt,
142};
143pub use ciphers::zuc::{Zuc128, Zuc128Ct};
144
145pub use cprng::ctr_drbg::CtrDrbgAes256;
146pub use hash::hkdf::Hkdf;
147pub use hash::hmac::Hmac;
148pub use hash::md5::Md5;
149pub use hash::ripemd160::Ripemd160;
150pub use hash::sha1::Sha1;
151pub use hash::sha2::{Sha224, Sha256, Sha384, Sha512, Sha512_224, Sha512_256};
152pub use hash::sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256};
153pub use hash::{Digest, Xof};
154pub use modes::{
155 Aes128GcmSiv, Aes256GcmSiv, AesKeyWrap, Cbc, Ccm, Cfb, Cfb8, ChaCha20Poly1305, Cmac, Ctr, Eax,
156 Ecb, Gcm, GcmVt, Gmac, GmacVt, Ocb, Ofb, Poly1305, Siv, Xts,
157};
158
159impl StreamCipher for ChaCha20 {
160 fn fill(&mut self, buf: &mut [u8]) {
161 self.fill(buf);
162 }
163}
164
165impl StreamCipher for XChaCha20 {
166 fn fill(&mut self, buf: &mut [u8]) {
167 self.fill(buf);
168 }
169}
170
171impl StreamCipher for Salsa20 {
172 fn fill(&mut self, buf: &mut [u8]) {
173 self.fill(buf);
174 }
175}
176
177impl StreamCipher for Rabbit {
178 fn fill(&mut self, buf: &mut [u8]) {
179 self.fill(buf);
180 }
181}
182
183impl StreamCipher for Snow3g {
184 fn fill(&mut self, buf: &mut [u8]) {
185 self.fill(buf);
186 }
187}
188
189impl StreamCipher for Snow3gCt {
190 fn fill(&mut self, buf: &mut [u8]) {
191 self.fill(buf);
192 }
193}
194
195impl StreamCipher for Zuc128 {
196 fn fill(&mut self, buf: &mut [u8]) {
197 self.fill(buf);
198 }
199}
200
201impl StreamCipher for Zuc128Ct {
202 fn fill(&mut self, buf: &mut [u8]) {
203 self.fill(buf);
204 }
205}
206
207impl<C: BlockCipher> Aead for Gcm<C> {
208 type Tag = [u8; 16];
209
210 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
211 self.encrypt(nonce, aad, data)
212 }
213
214 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
215 self.decrypt(nonce, aad, data, tag)
216 }
217}
218
219impl<C: BlockCipher> Aead for GcmVt<C> {
220 type Tag = [u8; 16];
221
222 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
223 self.encrypt(nonce, aad, data)
224 }
225
226 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
227 self.decrypt(nonce, aad, data, tag)
228 }
229}
230
231impl<C: BlockCipher, const TAG_LEN: usize> Aead for Ccm<C, TAG_LEN> {
232 type Tag = [u8; TAG_LEN];
233
234 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
235 self.encrypt(nonce, aad, data)
236 }
237
238 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
239 self.decrypt(nonce, aad, data, tag)
240 }
241}
242
243impl Aead for ChaCha20Poly1305 {
244 type Tag = [u8; 16];
245
246 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
248 let nonce: &[u8; 12] = nonce
249 .try_into()
250 .expect("ChaCha20-Poly1305 nonce must be 12 bytes");
251 self.encrypt_in_place(nonce, aad, data)
252 }
253
254 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
256 let nonce: &[u8; 12] = nonce
257 .try_into()
258 .expect("ChaCha20-Poly1305 nonce must be 12 bytes");
259 self.decrypt_in_place(nonce, aad, data, tag)
260 }
261}
262
263impl<C: BlockCipher> Aead for Siv<C> {
264 type Tag = [u8; 16];
265
266 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
267 let (ciphertext, tag) = self.encrypt(nonce, aad, data);
268 data.copy_from_slice(&ciphertext);
269 tag
270 }
271
272 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
273 self.decrypt(nonce, aad, data, tag)
274 }
275}
276
277impl<C: BlockCipher> Aead for Eax<C> {
278 type Tag = [u8; 16];
279
280 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
281 self.encrypt(nonce, aad, data)
282 }
283
284 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
285 self.decrypt(nonce, aad, data, tag)
286 }
287}
288
289impl<C: BlockCipher> Aead for Ocb<C> {
290 type Tag = [u8; 16];
291
292 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
293 self.encrypt(nonce, aad, data)
294 }
295
296 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
297 self.decrypt(nonce, aad, data, tag)
298 }
299}
300
301impl Aead for Aes128GcmSiv {
302 type Tag = [u8; 16];
303
304 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
306 let nonce: &[u8; 12] = nonce
307 .try_into()
308 .expect("AES-GCM-SIV nonce must be 12 bytes");
309 self.encrypt(nonce, aad, data)
310 }
311
312 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
314 let nonce: &[u8; 12] = nonce
315 .try_into()
316 .expect("AES-GCM-SIV nonce must be 12 bytes");
317 self.decrypt(nonce, aad, data, tag)
318 }
319}
320
321impl Aead for Aes256GcmSiv {
322 type Tag = [u8; 16];
323
324 fn encrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Self::Tag {
326 let nonce: &[u8; 12] = nonce
327 .try_into()
328 .expect("AES-GCM-SIV nonce must be 12 bytes");
329 self.encrypt(nonce, aad, data)
330 }
331
332 fn decrypt_in_place(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &Self::Tag) -> bool {
334 let nonce: &[u8; 12] = nonce
335 .try_into()
336 .expect("AES-GCM-SIV nonce must be 12 bytes");
337 self.decrypt(nonce, aad, data, tag)
338 }
339}
340
341pub mod vt {
351 pub use crate::public_key::bigint::{BigInt, BigUint, MontgomeryCtx, Sign};
352 pub use crate::public_key::cocks::{Cocks, CocksPrivateKey, CocksPublicKey};
353 pub use crate::public_key::dh::{Dh, DhParams, DhPrivateKey, DhPublicKey};
354 pub use crate::public_key::dsa::{Dsa, DsaPrivateKey, DsaPublicKey, DsaSignature};
355 pub use crate::public_key::ec::{
356 b163, b233, b283, b409, b571, k163, k233, k283, k409, k571, p192, p224, p256, p384, p521,
357 secp256k1, AffinePoint, CurveParams,
358 };
359 pub use crate::public_key::ec_elgamal::{
360 EcElGamal, EcElGamalCiphertext, EcElGamalPrivateKey, EcElGamalPublicKey,
361 };
362 pub use crate::public_key::ecdh::{Ecdh, EcdhPrivateKey, EcdhPublicKey};
363 pub use crate::public_key::ecdsa::{Ecdsa, EcdsaPrivateKey, EcdsaPublicKey, EcdsaSignature};
364 pub use crate::public_key::ecies::{Ecies, EciesPrivateKey, EciesPublicKey};
365 pub use crate::public_key::ed25519::{
366 Ed25519, Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature,
367 };
368 pub use crate::public_key::eddsa::{EdDsa, EdDsaPrivateKey, EdDsaPublicKey, EdDsaSignature};
369 pub use crate::public_key::edwards_dh::{EdwardsDh, EdwardsDhPrivateKey, EdwardsDhPublicKey};
370 pub use crate::public_key::edwards_elgamal::{
371 EdwardsElGamal, EdwardsElGamalCiphertext, EdwardsElGamalPrivateKey, EdwardsElGamalPublicKey,
372 };
373 pub use crate::public_key::elgamal::{
374 ElGamal, ElGamalCiphertext, ElGamalPrivateKey, ElGamalPublicKey,
375 };
376 pub use crate::public_key::ml_dsa::{
377 MlDsa, MlDsaParameterSet, MlDsaPrivateKey, MlDsaPublicKey, MlDsaSignature,
378 };
379 pub use crate::public_key::ml_kem::{
380 MlKem, MlKemCiphertext, MlKemParameterSet, MlKemPrivateKey, MlKemPublicKey,
381 MlKemSharedSecret,
382 };
383 pub use crate::public_key::ntru_hps509::{
384 NtruHps509, NtruHps509Ciphertext, NtruHps509PrivateKey, NtruHps509PublicKey,
385 NtruHps509SharedSecret,
386 };
387 pub use crate::public_key::ntru_hps677::{
388 NtruHps677, NtruHps677Ciphertext, NtruHps677PrivateKey, NtruHps677PublicKey,
389 NtruHps677SharedSecret,
390 };
391 pub use crate::public_key::ntru_hps821::{
392 NtruHps821, NtruHps821Ciphertext, NtruHps821PrivateKey, NtruHps821PublicKey,
393 NtruHps821SharedSecret,
394 };
395 pub use crate::public_key::ntru_ees401ep1::{
396 NtruEes401Ep1, NtruEes401Ep1Ciphertext, NtruEes401Ep1PrivateKey, NtruEes401Ep1PublicKey,
397 };
398 pub use crate::public_key::ntru_ees443ep1::{
399 NtruEes443Ep1, NtruEes443Ep1Ciphertext, NtruEes443Ep1PrivateKey, NtruEes443Ep1PublicKey,
400 };
401 pub use crate::public_key::ntru_ees449ep1::{
402 NtruEes449Ep1, NtruEes449Ep1Ciphertext, NtruEes449Ep1PrivateKey, NtruEes449Ep1PublicKey,
403 };
404 pub use crate::public_key::ntru_ees541ep1::{
405 NtruEes541Ep1, NtruEes541Ep1Ciphertext, NtruEes541Ep1PrivateKey, NtruEes541Ep1PublicKey,
406 };
407 pub use crate::public_key::ntru_ees677ep1::{
408 NtruEes677Ep1, NtruEes677Ep1Ciphertext, NtruEes677Ep1PrivateKey, NtruEes677Ep1PublicKey,
409 };
410 pub use crate::public_key::ntru_ees1087ep1::{
411 NtruEes1087Ep1, NtruEes1087Ep1Ciphertext, NtruEes1087Ep1PrivateKey,
412 NtruEes1087Ep1PublicKey,
413 };
414 pub use crate::public_key::ntru_ees1087ep2::{
415 NtruEes1087Ep2, NtruEes1087Ep2Ciphertext, NtruEes1087Ep2PrivateKey,
416 NtruEes1087Ep2PublicKey,
417 };
418 pub use crate::public_key::ntru_ees1171ep1::{
419 NtruEes1171Ep1, NtruEes1171Ep1Ciphertext, NtruEes1171Ep1PrivateKey,
420 NtruEes1171Ep1PublicKey,
421 };
422 pub use crate::public_key::ntru_ees1499ep1::{
423 NtruEes1499Ep1, NtruEes1499Ep1Ciphertext, NtruEes1499Ep1PrivateKey,
424 NtruEes1499Ep1PublicKey,
425 };
426 pub use crate::public_key::ntru_ees_core::NtruEesError;
427 pub use crate::public_key::ntru_hrss701::{
428 NtruHrss701, NtruHrss701Ciphertext, NtruHrss701PrivateKey, NtruHrss701PublicKey,
429 NtruHrss701SharedSecret,
430 };
431 pub use crate::public_key::paillier::{Paillier, PaillierPrivateKey, PaillierPublicKey};
432 pub use crate::public_key::rabin::{Rabin, RabinPrivateKey, RabinPublicKey};
433 pub use crate::public_key::rsa::{Rsa, RsaPrivateKey, RsaPublicKey};
434 pub use crate::public_key::rsa_pkcs1::{RsaOaep, RsaPss};
435 pub use crate::public_key::schmidt_samoa::{
436 SchmidtSamoa, SchmidtSamoaPrivateKey, SchmidtSamoaPublicKey,
437 };
438 pub use crate::public_key::x25519::{X25519, X25519PrivateKey, X25519PublicKey};
439 pub use crate::public_key::x448::{X448, X448PrivateKey, X448PublicKey};
440}
441
442#[cfg(test)]
443mod scrub;