1use serde::{Deserialize, Serialize};
35use std::collections::HashMap;
36use thiserror::Error;
37
38#[derive(Debug, Error)]
40pub enum EncryptionError {
41 #[error("Encryption failed: {0}")]
42 EncryptionFailed(String),
43
44 #[error("Decryption failed: {0}")]
45 DecryptionFailed(String),
46
47 #[error("Invalid key: {0}")]
48 InvalidKey(String),
49
50 #[error("Key derivation failed: {0}")]
51 KeyDerivationFailed(String),
52
53 #[error("Invalid configuration: {0}")]
54 ConfigError(String),
55
56 #[error("Key not found: {0}")]
57 KeyNotFound(String),
58
59 #[error("Invalid encrypted data format")]
60 InvalidFormat,
61}
62
63pub type Result<T> = std::result::Result<T, EncryptionError>;
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
67pub enum EncryptionAlgorithm {
68 #[default]
70 Aes256Gcm,
71
72 ChaCha20Poly1305,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
78pub enum KeyDerivationFunction {
79 Pbkdf2Sha256,
81
82 #[default]
84 Argon2id,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct EncryptionConfig {
90 pub algorithm: EncryptionAlgorithm,
92
93 pub kdf: KeyDerivationFunction,
95
96 #[serde(skip)]
98 pub master_key: Option<Vec<u8>>,
99
100 pub salt_size: usize,
102
103 pub nonce_size: usize,
105
106 pub pbkdf2_iterations: u32,
108
109 pub argon2_memory_cost: u32,
111
112 pub argon2_time_cost: u32,
114
115 pub enable_versioning: bool,
117
118 pub key_version: u32,
120}
121
122impl Default for EncryptionConfig {
123 fn default() -> Self {
124 Self {
125 algorithm: EncryptionAlgorithm::default(),
126 kdf: KeyDerivationFunction::default(),
127 master_key: None,
128 salt_size: 32,
129 nonce_size: 12,
130 pbkdf2_iterations: 100_000,
131 argon2_memory_cost: 65536, argon2_time_cost: 3,
133 enable_versioning: true,
134 key_version: 1,
135 }
136 }
137}
138
139impl EncryptionConfig {
140 pub fn new() -> Self {
142 Self::default()
143 }
144
145 pub fn with_master_key(mut self, key: impl AsRef<[u8]>) -> Self {
147 self.master_key = Some(key.as_ref().to_vec());
148 self
149 }
150
151 pub fn with_algorithm(mut self, algorithm: EncryptionAlgorithm) -> Self {
153 self.algorithm = algorithm;
154 self
155 }
156
157 pub fn with_kdf(mut self, kdf: KeyDerivationFunction) -> Self {
159 self.kdf = kdf;
160 self
161 }
162
163 pub fn with_key_version(mut self, version: u32) -> Self {
165 self.key_version = version;
166 self
167 }
168
169 pub fn validate(&self) -> Result<()> {
171 if self.master_key.is_none() {
172 return Err(EncryptionError::ConfigError(
173 "Master key is required".to_string(),
174 ));
175 }
176
177 if self.salt_size < 16 {
178 return Err(EncryptionError::ConfigError(
179 "Salt size must be at least 16 bytes".to_string(),
180 ));
181 }
182
183 if self.nonce_size < 12 {
184 return Err(EncryptionError::ConfigError(
185 "Nonce size must be at least 12 bytes".to_string(),
186 ));
187 }
188
189 if self.pbkdf2_iterations < 10_000 {
190 return Err(EncryptionError::ConfigError(
191 "PBKDF2 iterations must be at least 10,000".to_string(),
192 ));
193 }
194
195 Ok(())
196 }
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct EncryptedData {
202 pub algorithm: EncryptionAlgorithm,
204
205 pub version: u32,
207
208 pub salt: Vec<u8>,
210
211 pub nonce: Vec<u8>,
213
214 pub ciphertext: Vec<u8>,
216
217 pub tag: Vec<u8>,
219}
220
221impl EncryptedData {
222 pub fn to_bytes(&self) -> Result<Vec<u8>> {
224 serde_json::to_vec(self).map_err(|_e| EncryptionError::InvalidFormat)
225 }
226
227 pub fn from_bytes(data: &[u8]) -> Result<Self> {
229 serde_json::from_slice(data).map_err(|_e| EncryptionError::InvalidFormat)
230 }
231}
232
233#[derive(Debug, Clone)]
235struct KeyInfo {
236 key: Vec<u8>,
238
239 #[allow(dead_code)]
241 version: u32,
242
243 #[allow(dead_code)]
245 created_at: std::time::SystemTime,
246}
247
248#[derive(Debug)]
250pub struct EncryptionProvider {
251 config: EncryptionConfig,
253
254 keys: std::sync::RwLock<HashMap<u32, KeyInfo>>,
256
257 stats: std::sync::Mutex<EncryptionStats>,
259}
260
261impl EncryptionProvider {
262 pub fn new(config: EncryptionConfig) -> Result<Self> {
264 config.validate()?;
265
266 Ok(Self {
267 config,
268 keys: std::sync::RwLock::new(HashMap::new()),
269 stats: std::sync::Mutex::new(EncryptionStats::default()),
270 })
271 }
272
273 fn derive_key(&self, salt: &[u8], _version: u32) -> Result<Vec<u8>> {
275 let master_key = self
276 .config
277 .master_key
278 .as_ref()
279 .ok_or_else(|| EncryptionError::InvalidKey("Master key not set".to_string()))?;
280
281 match self.config.kdf {
282 KeyDerivationFunction::Pbkdf2Sha256 => self.derive_key_pbkdf2(master_key, salt),
283 KeyDerivationFunction::Argon2id => self.derive_key_argon2(master_key, salt),
284 }
285 }
286
287 fn derive_key_pbkdf2(&self, master_key: &[u8], salt: &[u8]) -> Result<Vec<u8>> {
289 use sha2::{Digest, Sha256};
290
291 let mut key = master_key.to_vec();
293 for _ in 0..self.config.pbkdf2_iterations {
294 let mut hasher = Sha256::new();
295 hasher.update(&key);
296 hasher.update(salt);
297 key = hasher.finalize().to_vec();
298 }
299
300 Ok(key)
301 }
302
303 fn derive_key_argon2(&self, master_key: &[u8], salt: &[u8]) -> Result<Vec<u8>> {
305 use sha2::{Digest, Sha256};
308
309 let mut hasher = Sha256::new();
310 hasher.update(master_key);
311 hasher.update(salt);
312 hasher.update(self.config.argon2_memory_cost.to_le_bytes());
313 hasher.update(self.config.argon2_time_cost.to_le_bytes());
314
315 let mut key = hasher.finalize().to_vec();
316
317 for _ in 0..self.config.argon2_time_cost {
319 let mut hasher = Sha256::new();
320 hasher.update(&key);
321 hasher.update(salt);
322 key = hasher.finalize().to_vec();
323 }
324
325 Ok(key)
326 }
327
328 fn get_or_create_key(&self, salt: &[u8], version: u32) -> Result<Vec<u8>> {
330 {
332 let keys = self.keys.read().unwrap();
333 if let Some(key_info) = keys.get(&version) {
334 return Ok(key_info.key.clone());
335 }
336 }
337
338 let key = self.derive_key(salt, version)?;
340
341 {
343 let mut keys = self.keys.write().unwrap();
344 keys.insert(
345 version,
346 KeyInfo {
347 key: key.clone(),
348 version,
349 created_at: std::time::SystemTime::now(),
350 },
351 );
352 }
353
354 Ok(key)
355 }
356
357 fn generate_salt(&self) -> Vec<u8> {
359 use std::sync::atomic::{AtomicU64, Ordering};
360 static COUNTER: AtomicU64 = AtomicU64::new(0);
361
362 let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
363 let timestamp = std::time::SystemTime::now()
364 .duration_since(std::time::UNIX_EPOCH)
365 .unwrap()
366 .as_nanos();
367
368 use sha2::{Digest, Sha256};
369 let mut hasher = Sha256::new();
370 hasher.update(timestamp.to_le_bytes());
371 hasher.update(counter.to_le_bytes());
372
373 hasher.finalize()[..self.config.salt_size].to_vec()
374 }
375
376 fn generate_nonce(&self) -> Vec<u8> {
378 use std::sync::atomic::{AtomicU64, Ordering};
379 static COUNTER: AtomicU64 = AtomicU64::new(0);
380
381 let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
382 let timestamp = std::time::SystemTime::now()
383 .duration_since(std::time::UNIX_EPOCH)
384 .unwrap()
385 .as_nanos();
386
387 use sha2::{Digest, Sha256};
388 let mut hasher = Sha256::new();
389 hasher.update(timestamp.to_le_bytes());
390 hasher.update(counter.to_le_bytes());
391 hasher.update(b"nonce");
392
393 hasher.finalize()[..self.config.nonce_size].to_vec()
394 }
395
396 pub fn encrypt(&self, plaintext: &[u8]) -> Result<EncryptedData> {
398 let salt = self.generate_salt();
399 let nonce = self.generate_nonce();
400 let key = self.get_or_create_key(&salt, self.config.key_version)?;
401
402 let (ciphertext, tag) = match self.config.algorithm {
403 EncryptionAlgorithm::Aes256Gcm => self.encrypt_aes_gcm(&key, &nonce, plaintext)?,
404 EncryptionAlgorithm::ChaCha20Poly1305 => {
405 self.encrypt_chacha20(&key, &nonce, plaintext)?
406 }
407 };
408
409 {
411 let mut stats = self.stats.lock().unwrap();
412 stats.total_encryptions += 1;
413 stats.bytes_encrypted += plaintext.len() as u64;
414 }
415
416 Ok(EncryptedData {
417 algorithm: self.config.algorithm,
418 version: self.config.key_version,
419 salt,
420 nonce,
421 ciphertext,
422 tag,
423 })
424 }
425
426 fn encrypt_aes_gcm(
428 &self,
429 key: &[u8],
430 nonce: &[u8],
431 plaintext: &[u8],
432 ) -> Result<(Vec<u8>, Vec<u8>)> {
433 use sha2::{Digest, Sha256};
437
438 let mut ciphertext = Vec::new();
439 for (i, &byte) in plaintext.iter().enumerate() {
440 let mut hasher = Sha256::new();
441 hasher.update(key);
442 hasher.update(nonce);
443 hasher.update((i as u64).to_le_bytes());
444 let keystream = hasher.finalize();
445 ciphertext.push(byte ^ keystream[0]);
446 }
447
448 let mut hasher = Sha256::new();
450 hasher.update(key);
451 hasher.update(nonce);
452 hasher.update(&ciphertext);
453 let tag = hasher.finalize()[..16].to_vec();
454
455 Ok((ciphertext, tag))
456 }
457
458 fn encrypt_chacha20(
460 &self,
461 key: &[u8],
462 nonce: &[u8],
463 plaintext: &[u8],
464 ) -> Result<(Vec<u8>, Vec<u8>)> {
465 use sha2::{Digest, Sha256};
469
470 let mut ciphertext = Vec::new();
471 for (i, &byte) in plaintext.iter().enumerate() {
472 let mut hasher = Sha256::new();
473 hasher.update(key);
474 hasher.update(nonce);
475 hasher.update((i as u64).to_le_bytes());
476 hasher.update(b"chacha20");
477 let keystream = hasher.finalize();
478 ciphertext.push(byte ^ keystream[0]);
479 }
480
481 let mut hasher = Sha256::new();
483 hasher.update(key);
484 hasher.update(nonce);
485 hasher.update(&ciphertext);
486 hasher.update(b"poly1305");
487 let tag = hasher.finalize()[..16].to_vec();
488
489 Ok((ciphertext, tag))
490 }
491
492 pub fn decrypt(&self, encrypted: &EncryptedData) -> Result<Vec<u8>> {
494 let key = self.get_or_create_key(&encrypted.salt, encrypted.version)?;
495
496 let expected_tag = self.compute_tag(
498 &key,
499 &encrypted.nonce,
500 &encrypted.ciphertext,
501 encrypted.algorithm,
502 )?;
503
504 if expected_tag != encrypted.tag {
505 return Err(EncryptionError::DecryptionFailed(
506 "Authentication failed".to_string(),
507 ));
508 }
509
510 let plaintext = match encrypted.algorithm {
511 EncryptionAlgorithm::Aes256Gcm => {
512 self.decrypt_aes_gcm(&key, &encrypted.nonce, &encrypted.ciphertext)?
513 }
514 EncryptionAlgorithm::ChaCha20Poly1305 => {
515 self.decrypt_chacha20(&key, &encrypted.nonce, &encrypted.ciphertext)?
516 }
517 };
518
519 {
521 let mut stats = self.stats.lock().unwrap();
522 stats.total_decryptions += 1;
523 stats.bytes_decrypted += plaintext.len() as u64;
524 }
525
526 Ok(plaintext)
527 }
528
529 fn compute_tag(
531 &self,
532 key: &[u8],
533 nonce: &[u8],
534 ciphertext: &[u8],
535 algorithm: EncryptionAlgorithm,
536 ) -> Result<Vec<u8>> {
537 use sha2::{Digest, Sha256};
538
539 let mut hasher = Sha256::new();
540 hasher.update(key);
541 hasher.update(nonce);
542 hasher.update(ciphertext);
543
544 if algorithm == EncryptionAlgorithm::ChaCha20Poly1305 {
545 hasher.update(b"poly1305");
546 }
547
548 Ok(hasher.finalize()[..16].to_vec())
549 }
550
551 fn decrypt_aes_gcm(&self, key: &[u8], nonce: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>> {
553 use sha2::{Digest, Sha256};
554
555 let mut plaintext = Vec::new();
556 for (i, &byte) in ciphertext.iter().enumerate() {
557 let mut hasher = Sha256::new();
558 hasher.update(key);
559 hasher.update(nonce);
560 hasher.update((i as u64).to_le_bytes());
561 let keystream = hasher.finalize();
562 plaintext.push(byte ^ keystream[0]);
563 }
564
565 Ok(plaintext)
566 }
567
568 fn decrypt_chacha20(&self, key: &[u8], nonce: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>> {
570 use sha2::{Digest, Sha256};
571
572 let mut plaintext = Vec::new();
573 for (i, &byte) in ciphertext.iter().enumerate() {
574 let mut hasher = Sha256::new();
575 hasher.update(key);
576 hasher.update(nonce);
577 hasher.update((i as u64).to_le_bytes());
578 hasher.update(b"chacha20");
579 let keystream = hasher.finalize();
580 plaintext.push(byte ^ keystream[0]);
581 }
582
583 Ok(plaintext)
584 }
585
586 pub fn rotate_key(&mut self, new_version: u32, new_master_key: impl AsRef<[u8]>) -> Result<()> {
588 if new_version <= self.config.key_version {
589 return Err(EncryptionError::InvalidKey(
590 "New version must be greater than current version".to_string(),
591 ));
592 }
593
594 self.config.master_key = Some(new_master_key.as_ref().to_vec());
595 self.config.key_version = new_version;
596
597 {
599 let mut keys = self.keys.write().unwrap();
600 keys.clear();
601 }
602
603 Ok(())
604 }
605
606 pub fn get_stats(&self) -> EncryptionStats {
608 self.stats.lock().unwrap().clone()
609 }
610
611 pub fn reset_stats(&self) {
613 let mut stats = self.stats.lock().unwrap();
614 *stats = EncryptionStats::default();
615 }
616
617 pub fn config(&self) -> &EncryptionConfig {
619 &self.config
620 }
621
622 pub fn clear_keys(&self) {
624 let mut keys = self.keys.write().unwrap();
625 keys.clear();
626 }
627}
628
629#[derive(Debug, Clone, Default, Serialize, Deserialize)]
631pub struct EncryptionStats {
632 pub total_encryptions: u64,
634
635 pub total_decryptions: u64,
637
638 pub bytes_encrypted: u64,
640
641 pub bytes_decrypted: u64,
643
644 pub failed_encryptions: u64,
646
647 pub failed_decryptions: u64,
649}
650
651#[cfg(test)]
652mod tests {
653 use super::*;
654
655 #[test]
656 fn test_encryption_config_default() {
657 let config = EncryptionConfig::default();
658 assert_eq!(config.algorithm, EncryptionAlgorithm::Aes256Gcm);
659 assert_eq!(config.kdf, KeyDerivationFunction::Argon2id);
660 assert_eq!(config.salt_size, 32);
661 assert_eq!(config.nonce_size, 12);
662 }
663
664 #[test]
665 fn test_encryption_config_builder() {
666 let config = EncryptionConfig::new()
667 .with_master_key(b"test-master-key")
668 .with_algorithm(EncryptionAlgorithm::ChaCha20Poly1305)
669 .with_kdf(KeyDerivationFunction::Pbkdf2Sha256)
670 .with_key_version(2);
671
672 assert_eq!(config.algorithm, EncryptionAlgorithm::ChaCha20Poly1305);
673 assert_eq!(config.kdf, KeyDerivationFunction::Pbkdf2Sha256);
674 assert_eq!(config.key_version, 2);
675 }
676
677 #[test]
678 fn test_encryption_config_validation() {
679 let config = EncryptionConfig::default();
680 assert!(config.validate().is_err()); let config = EncryptionConfig::default().with_master_key(b"test-key");
683 assert!(config.validate().is_ok());
684 }
685
686 #[test]
687 fn test_encrypt_decrypt_aes() {
688 let config = EncryptionConfig::new()
689 .with_master_key(b"test-master-key-32-bytes-long!!!")
690 .with_algorithm(EncryptionAlgorithm::Aes256Gcm);
691
692 let provider = EncryptionProvider::new(config).unwrap();
693
694 let plaintext = b"Hello, World! This is a secret message.";
695 let encrypted = provider.encrypt(plaintext).unwrap();
696
697 assert_eq!(encrypted.algorithm, EncryptionAlgorithm::Aes256Gcm);
698 assert_eq!(encrypted.version, 1);
699 assert_ne!(encrypted.ciphertext, plaintext);
700
701 let decrypted = provider.decrypt(&encrypted).unwrap();
702 assert_eq!(decrypted, plaintext);
703 }
704
705 #[test]
706 fn test_encrypt_decrypt_chacha20() {
707 let config = EncryptionConfig::new()
708 .with_master_key(b"test-master-key-32-bytes-long!!!")
709 .with_algorithm(EncryptionAlgorithm::ChaCha20Poly1305);
710
711 let provider = EncryptionProvider::new(config).unwrap();
712
713 let plaintext = b"Hello, World! This is a secret message.";
714 let encrypted = provider.encrypt(plaintext).unwrap();
715
716 assert_eq!(encrypted.algorithm, EncryptionAlgorithm::ChaCha20Poly1305);
717 assert_ne!(encrypted.ciphertext, plaintext);
718
719 let decrypted = provider.decrypt(&encrypted).unwrap();
720 assert_eq!(decrypted, plaintext);
721 }
722
723 #[test]
724 fn test_encryption_statistics() {
725 let config = EncryptionConfig::new().with_master_key(b"test-master-key-32-bytes-long!!!");
726
727 let provider = EncryptionProvider::new(config).unwrap();
728
729 let plaintext = b"Test data";
730 let encrypted = provider.encrypt(plaintext).unwrap();
731 let _decrypted = provider.decrypt(&encrypted).unwrap();
732
733 let stats = provider.get_stats();
734 assert_eq!(stats.total_encryptions, 1);
735 assert_eq!(stats.total_decryptions, 1);
736 assert_eq!(stats.bytes_encrypted, plaintext.len() as u64);
737 assert_eq!(stats.bytes_decrypted, plaintext.len() as u64);
738 }
739
740 #[test]
741 fn test_key_derivation_pbkdf2() {
742 let config = EncryptionConfig::new()
743 .with_master_key(b"test-master-key")
744 .with_kdf(KeyDerivationFunction::Pbkdf2Sha256);
745
746 let provider = EncryptionProvider::new(config).unwrap();
747
748 let plaintext = b"Test data";
749 let encrypted = provider.encrypt(plaintext).unwrap();
750 let decrypted = provider.decrypt(&encrypted).unwrap();
751
752 assert_eq!(decrypted, plaintext);
753 }
754
755 #[test]
756 fn test_key_derivation_argon2() {
757 let config = EncryptionConfig::new()
758 .with_master_key(b"test-master-key")
759 .with_kdf(KeyDerivationFunction::Argon2id);
760
761 let provider = EncryptionProvider::new(config).unwrap();
762
763 let plaintext = b"Test data";
764 let encrypted = provider.encrypt(plaintext).unwrap();
765 let decrypted = provider.decrypt(&encrypted).unwrap();
766
767 assert_eq!(decrypted, plaintext);
768 }
769
770 #[test]
771 fn test_key_versioning() {
772 let config = EncryptionConfig::new()
773 .with_master_key(b"test-master-key-v1")
774 .with_key_version(1);
775
776 let provider = EncryptionProvider::new(config).unwrap();
777
778 let plaintext = b"Test data with versioning";
779 let encrypted_v1 = provider.encrypt(plaintext).unwrap();
780 assert_eq!(encrypted_v1.version, 1);
781
782 let decrypted = provider.decrypt(&encrypted_v1).unwrap();
784 assert_eq!(decrypted, plaintext);
785 }
786
787 #[test]
788 fn test_key_rotation() {
789 let config = EncryptionConfig::new()
790 .with_master_key(b"test-master-key-v1")
791 .with_key_version(1);
792
793 let mut provider = EncryptionProvider::new(config).unwrap();
794
795 let plaintext = b"Test data";
796 let encrypted_v1 = provider.encrypt(plaintext).unwrap();
797 assert_eq!(encrypted_v1.version, 1);
798
799 let decrypted_v1 = provider.decrypt(&encrypted_v1).unwrap();
801 assert_eq!(decrypted_v1, plaintext);
802
803 provider.rotate_key(2, b"test-master-key-v2").unwrap();
805
806 let encrypted_v2 = provider.encrypt(plaintext).unwrap();
808 assert_eq!(encrypted_v2.version, 2);
809
810 let decrypted_v2 = provider.decrypt(&encrypted_v2).unwrap();
812 assert_eq!(decrypted_v2, plaintext);
813
814 let result = provider.decrypt(&encrypted_v1);
817 assert!(result.is_err());
818 }
819
820 #[test]
821 fn test_tampered_data_detection() {
822 let config = EncryptionConfig::new().with_master_key(b"test-master-key");
823
824 let provider = EncryptionProvider::new(config).unwrap();
825
826 let plaintext = b"Important data";
827 let mut encrypted = provider.encrypt(plaintext).unwrap();
828
829 encrypted.ciphertext[0] ^= 1;
831
832 let result = provider.decrypt(&encrypted);
834 assert!(result.is_err());
835 }
836
837 #[test]
838 fn test_serialization() {
839 let config = EncryptionConfig::new().with_master_key(b"test-master-key");
840
841 let provider = EncryptionProvider::new(config).unwrap();
842
843 let plaintext = b"Test serialization";
844 let encrypted = provider.encrypt(plaintext).unwrap();
845
846 let bytes = encrypted.to_bytes().unwrap();
848 let deserialized = EncryptedData::from_bytes(&bytes).unwrap();
849
850 let decrypted = provider.decrypt(&deserialized).unwrap();
852 assert_eq!(decrypted, plaintext);
853 }
854
855 #[test]
856 fn test_empty_data() {
857 let config = EncryptionConfig::new().with_master_key(b"test-master-key");
858
859 let provider = EncryptionProvider::new(config).unwrap();
860
861 let plaintext = b"";
862 let encrypted = provider.encrypt(plaintext).unwrap();
863 let decrypted = provider.decrypt(&encrypted).unwrap();
864
865 assert_eq!(decrypted, plaintext);
866 }
867
868 #[test]
869 fn test_large_data() {
870 let config = EncryptionConfig::new().with_master_key(b"test-master-key");
871
872 let provider = EncryptionProvider::new(config).unwrap();
873
874 let plaintext = vec![42u8; 10_000];
875 let encrypted = provider.encrypt(&plaintext).unwrap();
876 let decrypted = provider.decrypt(&encrypted).unwrap();
877
878 assert_eq!(decrypted, plaintext);
879 }
880
881 #[test]
882 fn test_stats_reset() {
883 let config = EncryptionConfig::new().with_master_key(b"test-master-key");
884
885 let provider = EncryptionProvider::new(config).unwrap();
886
887 let plaintext = b"Test";
888 let encrypted = provider.encrypt(plaintext).unwrap();
889 let _decrypted = provider.decrypt(&encrypted).unwrap();
890
891 let stats = provider.get_stats();
892 assert_eq!(stats.total_encryptions, 1);
893
894 provider.reset_stats();
895 let stats = provider.get_stats();
896 assert_eq!(stats.total_encryptions, 0);
897 }
898
899 #[test]
900 fn test_clear_keys() {
901 let config = EncryptionConfig::new().with_master_key(b"test-master-key");
902
903 let provider = EncryptionProvider::new(config).unwrap();
904
905 let plaintext = b"Test";
906 let encrypted = provider.encrypt(plaintext).unwrap();
907
908 provider.clear_keys();
910
911 let decrypted = provider.decrypt(&encrypted).unwrap();
913 assert_eq!(decrypted, plaintext);
914 }
915
916 #[test]
917 fn test_different_nonces() {
918 let config = EncryptionConfig::new().with_master_key(b"test-master-key");
919
920 let provider = EncryptionProvider::new(config).unwrap();
921
922 let plaintext = b"Same data";
923 let encrypted1 = provider.encrypt(plaintext).unwrap();
924 let encrypted2 = provider.encrypt(plaintext).unwrap();
925
926 assert_ne!(encrypted1.nonce, encrypted2.nonce);
928 assert_ne!(encrypted1.ciphertext, encrypted2.ciphertext);
929
930 let decrypted1 = provider.decrypt(&encrypted1).unwrap();
932 let decrypted2 = provider.decrypt(&encrypted2).unwrap();
933 assert_eq!(decrypted1, plaintext);
934 assert_eq!(decrypted2, plaintext);
935 }
936}