1#![allow(dead_code)]
2#![allow(unused_imports)]
3
4extern crate secrecy;
5
6use secrecy::{Secret, SecretString};
7
8pub mod encryption;
9pub mod hash;
10pub mod rand;
11
12#[cfg(test)]
13mod tests {
14 use secrecy::ExposeSecret;
15 use secrecy::Secret;
16 use secrecy::SecretString;
17
18 use crate::encryption;
19 use crate::encryption::Encryption;
20 use crate::encryption::StreamEncryption;
21 use crate::hash::Hash;
22 use crate::hash::Hkdf;
23 use crate::hash::Hmac;
24 use crate::hash::PasswordHash;
25
26 use super::*;
27
28 #[test]
29 fn test_aes_encryption() {
30 let key = Secret::new(b"32_bytes_master_key_of_AES-256!!".to_vec());
31 let plaintext = b"yellow_submarine";
32 let mut aes = Encryption::new(&key);
33 let ciphertext = aes.encrypt(plaintext.to_vec(), 1).unwrap();
34
35 let decrypted = aes.decrypt(ciphertext.nonce, ciphertext.data, 1).unwrap();
36 assert_eq!(decrypted.data, plaintext);
37 }
38
39 #[test]
40 fn test_chacha_encryption() {
41 let key = Secret::new(b"32_bytes_master_key_of_ChaCha20!".to_vec());
42 let plaintext = b"yellow_submarine";
43 let mut aes = Encryption::new(&key);
44 let ciphertext = aes.encrypt(plaintext.to_vec(), 2).unwrap();
45
46 let decrypted = aes.decrypt(ciphertext.nonce, ciphertext.data, 2).unwrap();
47 assert_eq!(decrypted.data, plaintext);
48 }
49
50 #[test]
51 fn test_failed_decryption() {
52 let key = Secret::new(b"32_bytes_master_key_of_AES-256!!".to_vec());
53 let plaintext = b"yellow_submarine";
54 let mut aes = Encryption::new(&key);
55 let ciphertext = aes.encrypt(plaintext.to_vec(), 1).unwrap();
56
57 let incorrect_key = Secret::new(b"32_bytes_master_key_of_AES-256??".to_vec());
58 aes = Encryption::new(&incorrect_key);
59 let decrypted = aes.decrypt(ciphertext.nonce, ciphertext.data, 1);
60
61 assert!(decrypted.is_err());
62 }
63
64 #[test]
65 fn test_stream_encryption() {
66 let key = Secret::new(b"32_bytes_master_key_of_ChaCha8!!".to_vec());
67 let plaintext = b"yellow_submarine";
68 let ciphertext = StreamEncryption::encrypt(&key, plaintext.as_ref());
69
70 let decrypted = StreamEncryption::decrypt(&key, &ciphertext);
71 assert_eq!(decrypted, plaintext);
72 }
73
74 #[test]
75 fn test_hash() {
76 let message = b"yellow_submarine";
77 let digest = Hash::sha256(&message.to_vec());
78
79 assert_eq!(
80 "482ea0629467352543559ecbc2ce0c2010c2d0fac069ffc304f5cf15af0ff85e",
81 hex::encode(digest)
82 );
83 }
84
85 #[test]
86 fn test_hmac() {
87 let secret = Secret::new(b"some_secret!!".to_vec());
88 let digest_to_compare =
89 hex::decode("aa504f4e415b461fd97296b18ed12514e389743a4cb2599511d55557afa6729d")
90 .unwrap();
91 let mut mac = Hmac::new(&secret);
92 mac.update(b"test".as_ref());
93
94 assert!(mac.verify(&digest_to_compare).is_ok());
95 }
96
97 #[test]
98 fn test_key_derivation() {
99 let password: SecretString = SecretString::new("yellow_submarine".to_string());
100 let key_material =
101 PasswordHash::argon2d(password, "yellow_submarine".as_bytes(), 2, 1, 19 * 1024);
102
103 assert_eq!(key_material.expose_secret().len(), 32);
104 let output_key_material = Hkdf::expand(key_material);
105
106 let expected = hex::decode(
107 "\
108 a6956358323fb84f92b0e0ef12f6df793423e76589b89da56d0f0ed018d6dc54\
109 8735c1432cda528f981f25fc374fd6609cec138a56264c20f002d34a77b652c6",
110 )
111 .unwrap();
112
113 assert_eq!(output_key_material.expose_secret().to_vec(), expected);
114 }
115
116 #[test]
117 fn test_check_aes_reused_nonce() {
118 let key = Secret::new(b"32_bytes_master_key_of_AES-256!!".to_vec());
119 let plaintext = b"yellow_submarine";
120 let mut aes = Encryption::new(&key);
121 let ciphertext1 = aes.encrypt(plaintext.to_vec(), 1).unwrap();
122 let ciphertext2 = aes.encrypt(plaintext.to_vec(), 1).unwrap();
123
124 assert_ne!(ciphertext1.nonce, ciphertext2.nonce);
125 }
126
127 #[test]
128 fn test_check_chacha_reused_nonce() {
129 let key = Secret::new(b"32_bytes_master_key_of_ChaCha20!".to_vec());
130 let plaintext = b"yellow_submarine";
131 let mut aes = Encryption::new(&key);
132 let ciphertext1 = aes.encrypt(plaintext.to_vec(), 2).unwrap();
133 let ciphertext2 = aes.encrypt(plaintext.to_vec(), 2).unwrap();
134
135 assert_ne!(ciphertext1.nonce, ciphertext2.nonce);
136 }
137
138 #[test]
139 fn test_check_aes_tamper_resistant() {
140 let key = Secret::new(b"32_bytes_master_key_of_AES-256!!".to_vec());
141 let plaintext = b"yellow_submarine";
142 let mut aes = Encryption::new(&key);
143 let mut ciphertext = aes.encrypt(plaintext.to_vec(), 1).unwrap();
144
145 ciphertext.data[0] ^= 1;
146 let decryption1 = aes.decrypt(ciphertext.nonce, ciphertext.data.clone(), 1);
147
148 ciphertext.nonce[0] ^= 1;
149 let decryption2 = aes.decrypt(ciphertext.nonce, ciphertext.data, 1);
150
151 assert!(decryption1.is_err());
152 assert!(decryption2.is_err());
153 }
154
155 #[test]
156 fn test_check_chacha_tamper_resistant() {
157 let key = Secret::new(b"32_bytes_master_key_of_AES-256!!".to_vec());
158 let plaintext = b"yellow_submarine";
159 let mut aes = Encryption::new(&key);
160 let mut ciphertext = aes.encrypt(plaintext.to_vec(), 2).unwrap();
161
162 ciphertext.data[0] ^= 1;
163 let decryption1 = aes.decrypt(ciphertext.nonce, ciphertext.data.clone(), 2);
164
165 ciphertext.nonce[0] ^= 1;
166 let decryption2 = aes.decrypt(ciphertext.nonce, ciphertext.data, 2);
167
168 assert!(decryption1.is_err());
169 assert!(decryption2.is_err());
170 }
171}