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