1pub mod asymmetric;
79pub mod authentication;
80pub mod error;
81pub mod hashing;
82pub mod key_derivation;
83pub mod keys;
84pub mod quantum;
85pub mod symmetric;
86
87pub use error::{CryptoKitError, Result};
89
90pub use hashing::{
92 sha1_hash, sha256_hash, sha384_hash, sha512_hash, HashAlgorithm, HashBuilder, HashFunction,
93 Sha256, Sha384, Sha512, SHA1, SHA256, SHA384, SHA512,
94};
95
96pub use authentication::{HMAC, hmac_sha1, hmac_sha256, hmac_sha384, hmac_sha512};
98
99pub use symmetric::aes::{
101 aes_gcm_decrypt, aes_gcm_decrypt_with_aad, aes_gcm_encrypt, aes_gcm_encrypt_with_aad,
102 AESGCMNonce, AESKey, AESKeySize, AesGcm,
103};
104pub use symmetric::chacha::{
105 chacha20poly1305_decrypt, chacha20poly1305_decrypt_with_aad, chacha20poly1305_encrypt,
106 chacha20poly1305_encrypt_with_aad, ChaChaKey, ChaChaPoly, ChaChaPolyNonce,
107};
108pub use symmetric::{AuthenticatedCipher, Cipher};
109
110pub use key_derivation::{
112 hkdf_sha256_derive, hkdf_sha384_derive, hkdf_sha512_derive, KeyDerivationFunction,
113};
114
115pub use keys::{SymmetricKey, SymmetricKeySize};
117
118pub use quantum::{
120 DigitalSignatureAlgorithm, KEMPrivateKey, KEMPublicKey, KeyEncapsulationMechanism, MLDsa65,
121 MLDsa65PrivateKey, MLDsa65PublicKey, MLDsa87, MLDsa87PrivateKey, MLDsa87PublicKey, MLKem1024,
122 MLKem1024PrivateKey, MLKem1024PublicKey, MLKem768, MLKem768PrivateKey, MLKem768PublicKey,
123 QuantumSafe, SignaturePrivateKey, SignaturePublicKey, XWingMLKem768X25519,
124 XWingMLKem768X25519PrivateKey, XWingMLKem768X25519PublicKey,
125};
126
127extern "C" {
129 #[link_name = "md5_hash"]
130 fn swift_md5_hash(data: *const u8, length: i32, out_hash: *mut u8);
131}
132
133pub fn md5_hash(data: &[u8]) -> Vec<u8> {
136 unsafe {
137 let mut output_hash = [0u8; 16];
138 swift_md5_hash(data.as_ptr(), data.len() as i32, output_hash.as_mut_ptr());
139 output_hash.to_vec()
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146
147 #[test]
148 fn test_sha256_basic() {
149 let input = b"abc";
150 let expected: [u8; 32] = [
151 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
152 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
153 0xf2, 0x00, 0x15, 0xad,
154 ];
155 let hash = sha256_hash(input);
156 assert_eq!(hash, expected);
157 }
158
159 #[test]
160 fn test_sha256_trait() {
161 let input = b"abc";
162 let expected: [u8; 32] = [
163 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
164 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
165 0xf2, 0x00, 0x15, 0xad,
166 ];
167 let hash = SHA256::hash(input);
168 assert_eq!(hash, expected);
169 }
170
171 #[test]
172 fn test_sha256_streaming() {
173 let mut hasher = Sha256::new();
174 hasher.update(b"a");
175 hasher.update(b"b");
176 hasher.update(b"c");
177 let hash = hasher.finalize();
178
179 let expected: [u8; 32] = [
180 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
181 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
182 0xf2, 0x00, 0x15, 0xad,
183 ];
184 assert_eq!(hash, expected);
185 }
186
187 #[test]
188 fn test_aes_gcm_roundtrip() {
189 let key = b"0123456789abcdef0123456789abcdef"; let nonce = b"cdef01234567"; let plaintext = b"Hello, World!";
192
193 let ciphertext = aes_gcm_encrypt(key, nonce, plaintext).unwrap();
195 assert!(ciphertext.len() > plaintext.len()); let decrypted = aes_gcm_decrypt(key, nonce, &ciphertext).unwrap();
198 assert_eq!(decrypted, plaintext);
199 }
200
201 #[test]
202 fn test_chacha20poly1305_roundtrip() {
203 let key = b"0123456789abcdef0123456789abcdef"; let nonce = b"cdef01234567"; let plaintext = b"Hello, ChaCha20Poly1305!";
206
207 let ciphertext = chacha20poly1305_encrypt(key, nonce, plaintext).unwrap();
209 assert!(ciphertext.len() > plaintext.len()); let decrypted = chacha20poly1305_decrypt(key, nonce, &ciphertext).unwrap();
212 assert_eq!(decrypted, plaintext);
213 }
214
215 #[test]
216 fn test_hmac_sha256() {
217 let key = b"key";
218 let message = b"message";
219 let result = hmac_sha256(key, message).unwrap();
220 assert_eq!(result.len(), 32); let key = b"Jefe";
224 let message = b"what do ya want for nothing?";
225 let result = hmac_sha256(key, message).unwrap();
226 let expected: [u8; 32] = [
227 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95,
228 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9,
229 0x64, 0xec, 0x38, 0x43,
230 ];
231 assert_eq!(result, expected);
232 }
233
234 #[test]
235 fn test_md5_compatibility() {
236 let input = b"hello";
237 let hash = md5_hash(input);
238 let expected: [u8; 16] = [
240 0x5d, 0x41, 0x40, 0x2a, 0xbc, 0x4b, 0x2a, 0x76, 0xb9, 0x71, 0x9d, 0x91, 0x10, 0x17,
241 0xc5, 0x92,
242 ];
243 assert_eq!(hash, expected);
244 }
245}