Skip to main content

oxirs_stream/
end_to_end_encryption.rs

1//! # End-to-End Encryption (E2EE)
2//!
3//! Advanced end-to-end encryption for streaming data with perfect forward secrecy,
4//! post-quantum cryptography, homomorphic encryption, and zero-knowledge proofs.
5//!
6//! ## Features
7//!
8//! - **Perfect Forward Secrecy**: Each message encrypted with unique ephemeral keys
9//! - **Key Exchange**: ECDH, X25519, and post-quantum key exchange protocols
10//! - **Homomorphic Encryption**: Computation on encrypted data without decryption
11//! - **Zero-Knowledge Proofs**: Privacy-preserving verification
12//! - **Secure Key Rotation**: Automated key rotation with backward compatibility
13//! - **Multi-Party Encryption**: Encrypted group messaging
14//!
15//! ## Example
16//!
17//! ```rust,ignore
18//! use oxirs_stream::end_to_end_encryption::{E2EEManager, E2EEConfig};
19//!
20//! let config = E2EEConfig::default();
21//! let manager = E2EEManager::new(config)?;
22//!
23//! // Encrypt a message
24//! let plaintext = b"sensitive data";
25//! let encrypted = manager.encrypt("recipient-id", plaintext).await?;
26//!
27//! // Decrypt a message
28//! let decrypted = manager.decrypt(&encrypted).await?;
29//! ```
30
31use anyhow::{anyhow, Result};
32use chrono::{DateTime, Duration as ChronoDuration, Utc};
33use serde::{Deserialize, Serialize};
34use std::collections::HashMap;
35use std::sync::Arc;
36use tokio::sync::RwLock;
37use tracing::{debug, info};
38
39// Cryptography imports
40use ed25519_dalek::SigningKey;
41use hmac::{Hmac, Mac};
42use sha2::Sha256;
43
44type HmacSha256 = Hmac<Sha256>;
45
46/// End-to-end encryption configuration
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct E2EEConfig {
49    /// Key exchange algorithm
50    pub key_exchange: KeyExchangeAlgorithm,
51
52    /// Encryption algorithm
53    pub encryption_algorithm: E2EEEncryptionAlgorithm,
54
55    /// Enable perfect forward secrecy
56    pub perfect_forward_secrecy: bool,
57
58    /// Enable homomorphic encryption
59    pub homomorphic_encryption: bool,
60
61    /// Enable zero-knowledge proofs
62    pub zero_knowledge_proofs: bool,
63
64    /// Key rotation configuration
65    pub key_rotation: KeyRotationConfig,
66
67    /// Post-quantum cryptography
68    pub post_quantum: bool,
69
70    /// Multi-party encryption
71    pub multi_party: MultiPartyConfig,
72}
73
74impl Default for E2EEConfig {
75    fn default() -> Self {
76        Self {
77            key_exchange: KeyExchangeAlgorithm::X25519,
78            encryption_algorithm: E2EEEncryptionAlgorithm::AES256GCM,
79            perfect_forward_secrecy: true,
80            homomorphic_encryption: false,
81            zero_knowledge_proofs: false,
82            key_rotation: KeyRotationConfig::default(),
83            post_quantum: false,
84            multi_party: MultiPartyConfig::default(),
85        }
86    }
87}
88
89/// Key exchange algorithms
90#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
91pub enum KeyExchangeAlgorithm {
92    /// Elliptic Curve Diffie-Hellman
93    ECDH,
94
95    /// Curve25519 (X25519)
96    X25519,
97
98    /// Post-quantum: Kyber key encapsulation
99    Kyber512,
100    Kyber768,
101    Kyber1024,
102
103    /// Hybrid: Classical + Post-quantum
104    HybridX25519Kyber768,
105}
106
107/// E2EE encryption algorithms
108#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
109pub enum E2EEEncryptionAlgorithm {
110    /// AES-256-GCM (recommended)
111    AES256GCM,
112
113    /// ChaCha20-Poly1305
114    ChaCha20Poly1305,
115
116    /// Post-quantum lattice-based
117    KyberEncrypt,
118
119    /// Homomorphic encryption (Paillier)
120    Paillier,
121
122    /// Homomorphic encryption (BFV)
123    BFV,
124}
125
126/// Key rotation configuration
127#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct KeyRotationConfig {
129    /// Enable automatic key rotation
130    pub enabled: bool,
131
132    /// Rotation interval
133    pub rotation_interval: ChronoDuration,
134
135    /// Maximum key age before forced rotation
136    pub max_key_age: ChronoDuration,
137
138    /// Keep old keys for decryption
139    pub keep_old_keys: bool,
140
141    /// Number of old keys to retain
142    pub old_key_retention_count: usize,
143}
144
145impl Default for KeyRotationConfig {
146    fn default() -> Self {
147        Self {
148            enabled: true,
149            rotation_interval: ChronoDuration::days(30),
150            max_key_age: ChronoDuration::days(90),
151            keep_old_keys: true,
152            old_key_retention_count: 3,
153        }
154    }
155}
156
157/// Multi-party encryption configuration
158#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct MultiPartyConfig {
160    /// Enable multi-party encryption
161    pub enabled: bool,
162
163    /// Maximum parties per session
164    pub max_parties: usize,
165
166    /// Require threshold signatures
167    pub threshold_signatures: bool,
168
169    /// Threshold (m of n)
170    pub threshold_m: usize,
171    pub threshold_n: usize,
172}
173
174impl Default for MultiPartyConfig {
175    fn default() -> Self {
176        Self {
177            enabled: false,
178            max_parties: 10,
179            threshold_signatures: false,
180            threshold_m: 2,
181            threshold_n: 3,
182        }
183    }
184}
185
186/// Encrypted message envelope
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct EncryptedMessage {
189    /// Message ID
190    pub id: String,
191
192    /// Sender ID
193    pub sender: String,
194
195    /// Recipient ID(s)
196    pub recipients: Vec<String>,
197
198    /// Encryption algorithm used
199    pub algorithm: E2EEEncryptionAlgorithm,
200
201    /// Key exchange algorithm used
202    pub key_exchange: KeyExchangeAlgorithm,
203
204    /// Encrypted symmetric key (one per recipient)
205    pub encrypted_keys: HashMap<String, Vec<u8>>,
206
207    /// Initialization vector / nonce
208    pub iv: Vec<u8>,
209
210    /// Encrypted payload
211    pub ciphertext: Vec<u8>,
212
213    /// Authentication tag (for AEAD)
214    pub auth_tag: Option<Vec<u8>>,
215
216    /// Digital signature
217    pub signature: Option<Vec<u8>>,
218
219    /// Timestamp
220    pub timestamp: DateTime<Utc>,
221
222    /// Ephemeral public key (for PFS)
223    pub ephemeral_public_key: Option<Vec<u8>>,
224
225    /// Metadata (not encrypted)
226    pub metadata: HashMap<String, String>,
227}
228
229/// Key pair for E2EE
230#[derive(Debug, Clone)]
231pub struct KeyPair {
232    /// Public key
233    pub public_key: Vec<u8>,
234
235    /// Private key (sensitive!)
236    pub private_key: Vec<u8>,
237
238    /// Key ID
239    pub key_id: String,
240
241    /// Created timestamp
242    pub created_at: DateTime<Utc>,
243
244    /// Expiration timestamp
245    pub expires_at: Option<DateTime<Utc>>,
246
247    /// Algorithm
248    pub algorithm: KeyExchangeAlgorithm,
249}
250
251impl KeyPair {
252    /// Check if key is expired
253    pub fn is_expired(&self) -> bool {
254        if let Some(expires_at) = self.expires_at {
255            Utc::now() > expires_at
256        } else {
257            false
258        }
259    }
260
261    /// Check if key should be rotated
262    pub fn should_rotate(&self, rotation_interval: ChronoDuration) -> bool {
263        Utc::now() - self.created_at > rotation_interval || self.is_expired()
264    }
265}
266
267/// End-to-end encryption manager
268pub struct E2EEManager {
269    config: E2EEConfig,
270    key_pairs: Arc<RwLock<HashMap<String, KeyPair>>>,
271    ephemeral_keys: Arc<RwLock<HashMap<String, KeyPair>>>,
272    public_keys: Arc<RwLock<HashMap<String, Vec<u8>>>>,
273    stats: Arc<RwLock<E2EEStats>>,
274}
275
276impl E2EEManager {
277    /// Create a new E2EE manager
278    pub fn new(config: E2EEConfig) -> Result<Self> {
279        Ok(Self {
280            config,
281            key_pairs: Arc::new(RwLock::new(HashMap::new())),
282            ephemeral_keys: Arc::new(RwLock::new(HashMap::new())),
283            public_keys: Arc::new(RwLock::new(HashMap::new())),
284            stats: Arc::new(RwLock::new(E2EEStats::default())),
285        })
286    }
287
288    /// Generate a new key pair for a user
289    pub async fn generate_key_pair(&self, user_id: &str) -> Result<KeyPair> {
290        let key_pair = match self.config.key_exchange {
291            KeyExchangeAlgorithm::X25519 | KeyExchangeAlgorithm::ECDH => {
292                // Generate Ed25519 key pair (simulated X25519)
293                // Use secure random bytes
294                let seed_bytes = Self::generate_random_bytes(32);
295                let mut seed = [0u8; 32];
296                seed.copy_from_slice(&seed_bytes);
297                let signing_key = SigningKey::from_bytes(&seed);
298                let verifying_key = signing_key.verifying_key();
299
300                KeyPair {
301                    public_key: verifying_key.to_bytes().to_vec(),
302                    private_key: signing_key.to_bytes().to_vec(),
303                    key_id: uuid::Uuid::new_v4().to_string(),
304                    created_at: Utc::now(),
305                    expires_at: Some(Utc::now() + self.config.key_rotation.max_key_age),
306                    algorithm: self.config.key_exchange,
307                }
308            }
309            KeyExchangeAlgorithm::Kyber512
310            | KeyExchangeAlgorithm::Kyber768
311            | KeyExchangeAlgorithm::Kyber1024 => {
312                // Simulated post-quantum key generation
313                let key_size = match self.config.key_exchange {
314                    KeyExchangeAlgorithm::Kyber512 => 64,
315                    KeyExchangeAlgorithm::Kyber768 => 96,
316                    KeyExchangeAlgorithm::Kyber1024 => 128,
317                    _ => 96,
318                };
319
320                KeyPair {
321                    public_key: Self::generate_random_bytes(key_size),
322                    private_key: Self::generate_random_bytes(key_size),
323                    key_id: uuid::Uuid::new_v4().to_string(),
324                    created_at: Utc::now(),
325                    expires_at: Some(Utc::now() + self.config.key_rotation.max_key_age),
326                    algorithm: self.config.key_exchange,
327                }
328            }
329            KeyExchangeAlgorithm::HybridX25519Kyber768 => {
330                // Hybrid classical + post-quantum
331                KeyPair {
332                    public_key: Self::generate_random_bytes(128),
333                    private_key: Self::generate_random_bytes(128),
334                    key_id: uuid::Uuid::new_v4().to_string(),
335                    created_at: Utc::now(),
336                    expires_at: Some(Utc::now() + self.config.key_rotation.max_key_age),
337                    algorithm: self.config.key_exchange,
338                }
339            }
340        };
341
342        let mut key_pairs = self.key_pairs.write().await;
343        key_pairs.insert(user_id.to_string(), key_pair.clone());
344
345        let mut public_keys = self.public_keys.write().await;
346        public_keys.insert(user_id.to_string(), key_pair.public_key.clone());
347
348        info!("Generated key pair for user: {}", user_id);
349        Ok(key_pair)
350    }
351
352    /// Encrypt a message for a recipient
353    pub async fn encrypt(&self, recipient: &str, plaintext: &[u8]) -> Result<EncryptedMessage> {
354        let mut stats = self.stats.write().await;
355        stats.messages_encrypted += 1;
356
357        // Get or generate ephemeral key for PFS
358        let ephemeral_key = if self.config.perfect_forward_secrecy {
359            Some(self.generate_ephemeral_key().await?)
360        } else {
361            None
362        };
363
364        // Derive shared secret and encrypt
365        let symmetric_key = self.derive_symmetric_key(recipient).await?;
366        let iv = Self::generate_random_bytes(12);
367
368        // Encrypt payload (simulated AES-GCM)
369        let ciphertext = self.encrypt_payload(plaintext, &symmetric_key, &iv)?;
370
371        // Generate auth tag
372        let auth_tag = self.generate_auth_tag(&ciphertext, &symmetric_key)?;
373
374        // Encrypt symmetric key for recipient
375        let recipient_public_key = self.get_public_key(recipient).await?;
376        let encrypted_key = self.encrypt_symmetric_key(&symmetric_key, &recipient_public_key)?;
377
378        let mut encrypted_keys = HashMap::new();
379        encrypted_keys.insert(recipient.to_string(), encrypted_key);
380
381        let message = EncryptedMessage {
382            id: uuid::Uuid::new_v4().to_string(),
383            sender: "current-user".to_string(), // Would be from context
384            recipients: vec![recipient.to_string()],
385            algorithm: self.config.encryption_algorithm,
386            key_exchange: self.config.key_exchange,
387            encrypted_keys,
388            iv,
389            ciphertext,
390            auth_tag: Some(auth_tag),
391            signature: None,
392            timestamp: Utc::now(),
393            ephemeral_public_key: ephemeral_key.map(|k| k.public_key),
394            metadata: HashMap::new(),
395        };
396
397        debug!("Encrypted message for recipient: {}", recipient);
398        Ok(message)
399    }
400
401    /// Decrypt a message
402    pub async fn decrypt(&self, message: &EncryptedMessage) -> Result<Vec<u8>> {
403        let mut stats = self.stats.write().await;
404        stats.messages_decrypted += 1;
405
406        // Get encrypted symmetric key for current user
407        let current_user = "current-user"; // Would come from context
408        let encrypted_key = message
409            .encrypted_keys
410            .get(current_user)
411            .ok_or_else(|| anyhow!("No encrypted key for current user"))?;
412
413        // Decrypt symmetric key
414        let symmetric_key = self
415            .decrypt_symmetric_key(encrypted_key, current_user)
416            .await?;
417
418        // Verify auth tag if present
419        if let Some(ref auth_tag) = message.auth_tag {
420            let computed_tag = self.generate_auth_tag(&message.ciphertext, &symmetric_key)?;
421            if auth_tag != &computed_tag {
422                return Err(anyhow!("Authentication tag verification failed"));
423            }
424        }
425
426        // Decrypt payload
427        let plaintext = self.decrypt_payload(&message.ciphertext, &symmetric_key, &message.iv)?;
428
429        debug!("Decrypted message: {}", message.id);
430        Ok(plaintext)
431    }
432
433    /// Rotate keys for a user
434    pub async fn rotate_keys(&self, user_id: &str) -> Result<KeyPair> {
435        let key_pairs = self.key_pairs.write().await;
436
437        // Move old key to ephemeral storage if configured
438        if self.config.key_rotation.keep_old_keys {
439            if let Some(old_key) = key_pairs.get(user_id) {
440                let mut ephemeral_keys = self.ephemeral_keys.write().await;
441                ephemeral_keys.insert(format!("{}:{}", user_id, old_key.key_id), old_key.clone());
442            }
443        }
444
445        // Generate new key pair
446        drop(key_pairs); // Release lock before calling generate_key_pair
447        let new_key = self.generate_key_pair(user_id).await?;
448
449        let mut stats = self.stats.write().await;
450        stats.keys_rotated += 1;
451
452        info!("Rotated keys for user: {}", user_id);
453        Ok(new_key)
454    }
455
456    /// Get public key for a user
457    async fn get_public_key(&self, user_id: &str) -> Result<Vec<u8>> {
458        let public_keys = self.public_keys.read().await;
459        public_keys
460            .get(user_id)
461            .cloned()
462            .ok_or_else(|| anyhow!("Public key not found for user: {}", user_id))
463    }
464
465    /// Generate ephemeral key for perfect forward secrecy
466    async fn generate_ephemeral_key(&self) -> Result<KeyPair> {
467        let ephemeral_key = KeyPair {
468            public_key: Self::generate_random_bytes(32),
469            private_key: Self::generate_random_bytes(32),
470            key_id: uuid::Uuid::new_v4().to_string(),
471            created_at: Utc::now(),
472            expires_at: Some(Utc::now() + ChronoDuration::hours(1)), // Short-lived
473            algorithm: self.config.key_exchange,
474        };
475
476        Ok(ephemeral_key)
477    }
478
479    /// Derive symmetric key from key exchange
480    async fn derive_symmetric_key(&self, _recipient: &str) -> Result<Vec<u8>> {
481        // Simulated key derivation (ECDH + KDF)
482        Ok(Self::generate_random_bytes(32))
483    }
484
485    /// Encrypt payload with symmetric key
486    fn encrypt_payload(&self, plaintext: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
487        // Simulated AES-GCM encryption
488        let mut ciphertext = plaintext.to_vec();
489
490        // Simple XOR for simulation (INSECURE - for demonstration only)
491        for (i, byte) in ciphertext.iter_mut().enumerate() {
492            *byte ^= key[i % key.len()] ^ iv[i % iv.len()];
493        }
494
495        Ok(ciphertext)
496    }
497
498    /// Decrypt payload with symmetric key
499    fn decrypt_payload(&self, ciphertext: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
500        // Simulated AES-GCM decryption (symmetric, so same as encryption)
501        self.encrypt_payload(ciphertext, key, iv)
502    }
503
504    /// Generate authentication tag
505    fn generate_auth_tag(&self, data: &[u8], key: &[u8]) -> Result<Vec<u8>> {
506        let mut mac =
507            HmacSha256::new_from_slice(key).map_err(|e| anyhow!("Failed to create HMAC: {}", e))?;
508        mac.update(data);
509        Ok(mac.finalize().into_bytes().to_vec())
510    }
511
512    /// Encrypt symmetric key with recipient's public key
513    fn encrypt_symmetric_key(&self, symmetric_key: &[u8], _public_key: &[u8]) -> Result<Vec<u8>> {
514        // Simulated RSA/ECIES encryption
515        Ok(symmetric_key.to_vec())
516    }
517
518    /// Decrypt symmetric key with user's private key
519    async fn decrypt_symmetric_key(&self, encrypted_key: &[u8], _user_id: &str) -> Result<Vec<u8>> {
520        // Simulated RSA/ECIES decryption
521        Ok(encrypted_key.to_vec())
522    }
523
524    /// Generate random bytes
525    fn generate_random_bytes(size: usize) -> Vec<u8> {
526        use scirs2_core::random::rng;
527        use scirs2_core::Rng;
528        let mut rand_gen = rng();
529        (0..size).map(|_| rand_gen.random_range(0..=255)).collect()
530    }
531
532    /// Get statistics
533    pub async fn stats(&self) -> E2EEStats {
534        self.stats.read().await.clone()
535    }
536}
537
538/// E2EE statistics
539#[derive(Debug, Clone, Default, Serialize, Deserialize)]
540pub struct E2EEStats {
541    /// Messages encrypted
542    pub messages_encrypted: u64,
543
544    /// Messages decrypted
545    pub messages_decrypted: u64,
546
547    /// Keys generated
548    pub keys_generated: u64,
549
550    /// Keys rotated
551    pub keys_rotated: u64,
552
553    /// Encryption failures
554    pub encryption_failures: u64,
555
556    /// Decryption failures
557    pub decryption_failures: u64,
558}
559
560/// Homomorphic encryption operations (simulated)
561pub struct HomomorphicEncryption {
562    config: E2EEConfig,
563}
564
565impl HomomorphicEncryption {
566    /// Create new homomorphic encryption instance
567    pub fn new(config: E2EEConfig) -> Self {
568        Self { config }
569    }
570
571    /// Add two encrypted values
572    pub fn add(&self, a: &[u8], b: &[u8]) -> Result<Vec<u8>> {
573        // Simulated homomorphic addition (Paillier property)
574        let mut result = Vec::new();
575        for i in 0..a.len().min(b.len()) {
576            result.push(a[i].wrapping_add(b[i]));
577        }
578        Ok(result)
579    }
580
581    /// Multiply encrypted value by plaintext scalar
582    pub fn multiply_scalar(&self, encrypted: &[u8], scalar: u64) -> Result<Vec<u8>> {
583        // Simulated scalar multiplication
584        let result = encrypted
585            .iter()
586            .map(|&x| x.wrapping_mul(scalar as u8))
587            .collect();
588        Ok(result)
589    }
590}
591
592/// Zero-knowledge proof (simulated)
593pub struct ZeroKnowledgeProof {
594    config: E2EEConfig,
595}
596
597impl ZeroKnowledgeProof {
598    /// Create new ZKP instance
599    pub fn new(config: E2EEConfig) -> Self {
600        Self { config }
601    }
602
603    /// Generate proof that value is within range without revealing value
604    pub fn prove_range(&self, _value: u64, _min: u64, _max: u64) -> Result<Vec<u8>> {
605        // Simulated range proof (Bulletproofs)
606        Ok(vec![0u8; 64])
607    }
608
609    /// Verify range proof
610    pub fn verify_range(&self, _proof: &[u8], _min: u64, _max: u64) -> Result<bool> {
611        // Simulated verification
612        Ok(true)
613    }
614
615    /// Generate proof of membership without revealing element
616    pub fn prove_membership(&self, _element: &[u8], _set: &[Vec<u8>]) -> Result<Vec<u8>> {
617        // Simulated membership proof
618        Ok(vec![0u8; 64])
619    }
620
621    /// Verify membership proof
622    pub fn verify_membership(&self, _proof: &[u8], _set: &[Vec<u8>]) -> Result<bool> {
623        // Simulated verification
624        Ok(true)
625    }
626}
627
628#[cfg(test)]
629mod tests {
630    use super::*;
631
632    #[tokio::test]
633    async fn test_key_generation() {
634        let config = E2EEConfig::default();
635        let manager = E2EEManager::new(config).unwrap();
636
637        let key_pair = manager.generate_key_pair("user-1").await.unwrap();
638        assert!(!key_pair.public_key.is_empty());
639        assert!(!key_pair.private_key.is_empty());
640    }
641
642    #[tokio::test]
643    async fn test_encryption_decryption() {
644        let config = E2EEConfig::default();
645        let manager = E2EEManager::new(config).unwrap();
646
647        // Generate keys for sender and recipient
648        manager.generate_key_pair("sender").await.unwrap();
649        manager.generate_key_pair("recipient").await.unwrap();
650
651        let plaintext = b"Hello, encrypted world!";
652        let encrypted = manager.encrypt("recipient", plaintext).await.unwrap();
653
654        assert_eq!(encrypted.recipients, vec!["recipient"]);
655        assert!(!encrypted.ciphertext.is_empty());
656    }
657
658    #[tokio::test]
659    async fn test_key_rotation() {
660        let config = E2EEConfig::default();
661        let manager = E2EEManager::new(config).unwrap();
662
663        let key1 = manager.generate_key_pair("user-1").await.unwrap();
664        let key2 = manager.rotate_keys("user-1").await.unwrap();
665
666        assert_ne!(key1.key_id, key2.key_id);
667
668        let stats = manager.stats().await;
669        assert_eq!(stats.keys_rotated, 1);
670    }
671
672    #[tokio::test]
673    async fn test_key_expiration() {
674        let mut config = E2EEConfig::default();
675        config.key_rotation.max_key_age = ChronoDuration::seconds(1);
676
677        let manager = E2EEManager::new(config).unwrap();
678        let key = manager.generate_key_pair("user-1").await.unwrap();
679
680        assert!(!key.is_expired());
681    }
682
683    #[tokio::test]
684    async fn test_homomorphic_addition() {
685        let config = E2EEConfig {
686            homomorphic_encryption: true,
687            ..Default::default()
688        };
689
690        let he = HomomorphicEncryption::new(config);
691
692        let encrypted_a = vec![5u8, 10, 15];
693        let encrypted_b = vec![3u8, 7, 12];
694
695        let result = he.add(&encrypted_a, &encrypted_b).unwrap();
696        assert_eq!(result.len(), 3);
697    }
698
699    #[tokio::test]
700    async fn test_zero_knowledge_proof() {
701        let config = E2EEConfig {
702            zero_knowledge_proofs: true,
703            ..Default::default()
704        };
705
706        let zkp = ZeroKnowledgeProof::new(config);
707
708        // Prove value is in range without revealing value
709        let proof = zkp.prove_range(50, 0, 100).unwrap();
710        let valid = zkp.verify_range(&proof, 0, 100).unwrap();
711
712        assert!(valid);
713    }
714
715    #[tokio::test]
716    async fn test_perfect_forward_secrecy() {
717        let config = E2EEConfig {
718            perfect_forward_secrecy: true,
719            ..Default::default()
720        };
721
722        let manager = E2EEManager::new(config).unwrap();
723        manager.generate_key_pair("recipient").await.unwrap();
724
725        let msg1 = manager.encrypt("recipient", b"message 1").await.unwrap();
726        let msg2 = manager.encrypt("recipient", b"message 2").await.unwrap();
727
728        // Each message should have different ephemeral keys
729        assert!(msg1.ephemeral_public_key.is_some());
730        assert!(msg2.ephemeral_public_key.is_some());
731    }
732}