ant_core/
identity.rs

1//! User Identity and Privacy System
2//!
3//! This module provides a privacy-first user identity system for the P2P network.
4//! User profiles are encrypted by default and access is controlled through
5//! friend-based key sharing. Anti-spoofing measures bind user identities to
6//! network-level IPv6 cryptographic identities.
7//!
8//! ## Key Features
9//!
10//! - Encrypted profiles with granular access control
11//! - Friend-based key sharing for selective information disclosure
12//! - Anti-spoofing through IPv6 identity binding
13//! - Private contact discovery using bloom filters
14//! - Social verification network for trust building
15//! - Zero-knowledge profile operations
16
17pub mod manager;
18
19use crate::{Result, P2PError};
20use crate::security::IPv6NodeID;
21use crate::dht::Key;
22use ed25519_dalek::{Keypair, PublicKey, Signature, Signer, Verifier};
23use rand::rngs::OsRng;
24use serde::{Deserialize, Serialize};
25use sha2::{Digest, Sha256};
26use std::collections::HashMap;
27use std::time::{Duration, SystemTime, UNIX_EPOCH};
28use uuid::Uuid;
29use aes_gcm::{Aes256Gcm, Nonce, KeyInit};
30use aes_gcm::aead::Aead;
31use blake3;
32
33/// Unique user identifier derived from public key
34pub type UserId = String;
35
36/// User identity verification levels
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38pub enum VerificationLevel {
39    /// Identity just claimed, not verified
40    Unverified,
41    /// Self-signed identity
42    SelfSigned,
43    /// Proven control of IPv6 network identity
44    NetworkVerified,
45    /// Vouched for by trusted contacts
46    SociallyVerified,
47}
48
49/// Core user identity structure
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct UserIdentity {
52    /// Unique user identifier (SHA256 of public key)
53    pub user_id: UserId,
54    /// ED25519 public key for verification (stored as bytes for serialization)
55    pub public_key: Vec<u8>,
56    /// Human-readable display name (encrypted in profile)
57    pub display_name_hint: String, // Truncated/hashed hint for search
58    /// Three-word address for easy sharing
59    pub three_word_address: String,
60    /// Identity creation timestamp
61    pub created_at: SystemTime,
62    /// Identity version for updates
63    pub version: u64,
64    /// Verification level
65    pub verification_level: VerificationLevel,
66}
67
68/// User profile data (stored encrypted)
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct UserProfile {
71    /// Full display name
72    pub display_name: String,
73    /// Avatar image hash (BLAKE3)
74    pub avatar_hash: Option<String>,
75    /// User status message
76    pub status_message: Option<String>,
77    /// Profile creation timestamp
78    pub created_at: SystemTime,
79    /// Last updated timestamp
80    pub updated_at: SystemTime,
81    /// User preferences
82    pub preferences: UserPreferences,
83    /// Custom profile fields
84    pub custom_fields: HashMap<String, String>,
85}
86
87/// User preferences and privacy settings
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct UserPreferences {
90    /// Discoverability settings
91    pub discovery: DiscoverabilitySettings,
92    /// Default permissions for new contacts
93    pub default_permissions: ProfilePermissions,
94    /// Privacy settings
95    pub privacy: PrivacySettings,
96}
97
98/// Profile access permissions
99#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct ProfilePermissions {
101    /// Can see full display name
102    pub can_see_display_name: bool,
103    /// Can see avatar image
104    pub can_see_avatar: bool,
105    /// Can see status message
106    pub can_see_status: bool,
107    /// Can see contact information
108    pub can_see_contact_info: bool,
109    /// Can see when user was last online
110    pub can_see_last_seen: bool,
111    /// Can see custom profile fields
112    pub can_see_custom_fields: bool,
113}
114
115/// Privacy and discoverability settings
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct DiscoverabilitySettings {
118    /// Can be found by display name search
119    pub discoverable_by_name: bool,
120    /// Friends can find and recommend you
121    pub discoverable_by_friends: bool,
122    /// Accept contact requests from strangers
123    pub allow_contact_requests: bool,
124    /// Only allow contact requests from friends-of-friends
125    pub require_mutual_friends: bool,
126    /// Include in network directory
127    pub listed_in_directory: bool,
128}
129
130/// Additional privacy controls
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct PrivacySettings {
133    /// Require proof-of-humanity for contact requests
134    pub require_proof_of_humanity: bool,
135    /// Maximum age for accepting contact requests
136    pub max_contact_request_age: Duration,
137    /// Enable perfect forward secrecy for messages
138    pub enable_forward_secrecy: bool,
139    /// Auto-rotate profile keys
140    pub auto_rotate_keys: bool,
141    /// Key rotation interval
142    pub key_rotation_interval: Duration,
143}
144
145/// Encrypted user profile stored in DHT
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct EncryptedUserProfile {
148    /// User identifier
149    pub user_id: UserId,
150    /// Public key for verification (stored as bytes for serialization)
151    pub public_key: Vec<u8>,
152    /// Encrypted profile data
153    pub encrypted_data: Vec<u8>,
154    /// Encryption nonce
155    pub nonce: [u8; 12],
156    /// Access grants for friends
157    pub access_grants: Vec<AccessGrant>,
158    /// IPv6 identity binding proof
159    pub ipv6_binding_proof: Option<IPv6BindingProof>,
160    /// Profile signature
161    pub signature: Vec<u8>,
162    /// Last updated timestamp
163    pub updated_at: SystemTime,
164}
165
166/// Access grant allowing a friend to decrypt profile data
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct AccessGrant {
169    /// User ID of the grantee
170    pub grantee_user_id: UserId,
171    /// Profile encryption key encrypted with grantee's public key
172    pub encrypted_profile_key: Vec<u8>,
173    /// Permissions granted
174    pub permissions: ProfilePermissions,
175    /// Grant creation time
176    pub granted_at: SystemTime,
177    /// Optional expiration time
178    pub expires_at: Option<SystemTime>,
179    /// Grant signature by profile owner
180    pub signature: Vec<u8>,
181}
182
183/// Proof that user identity is bound to IPv6 network identity
184#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct IPv6BindingProof {
186    /// IPv6 node identity
187    pub ipv6_identity: IPv6NodeID,
188    /// User private key signature of IPv6 public key
189    pub binding_signature: Vec<u8>,
190    /// IPv6 private key signature of user public key (mutual binding)
191    pub mutual_signature: Vec<u8>,
192    /// Proof creation timestamp
193    pub created_at: SystemTime,
194}
195
196/// Challenge for proving identity ownership
197#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct IdentityChallenge {
199    /// Unique challenge ID
200    pub challenge_id: String,
201    /// Random challenge data
202    pub challenge_data: [u8; 32],
203    /// Challenge creation time
204    pub created_at: SystemTime,
205    /// Challenge expiration time
206    pub expires_at: SystemTime,
207}
208
209/// Response to identity challenge
210#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct ChallengeProof {
212    /// Challenge ID being responded to
213    pub challenge_id: String,
214    /// User ID providing the proof
215    pub user_id: UserId,
216    /// Signature of challenge data with user private key
217    pub signature: Vec<u8>,
218    /// Response timestamp
219    pub timestamp: SystemTime,
220}
221
222/// Contact request between users
223#[derive(Debug, Clone, Serialize, Deserialize)]
224pub struct ContactRequest {
225    /// Request unique ID
226    pub request_id: String,
227    /// Sender user ID
228    pub from_user_id: UserId,
229    /// Recipient user ID
230    pub to_user_id: UserId,
231    /// Optional message from sender
232    pub message: Option<String>,
233    /// Requested access permissions
234    pub requested_permissions: ProfilePermissions,
235    /// Proof that sender controls their identity
236    pub sender_proof: ChallengeProof,
237    /// Request creation time
238    pub created_at: SystemTime,
239    /// Request expiration time
240    pub expires_at: SystemTime,
241    /// Request signature
242    pub signature: Vec<u8>,
243}
244
245/// Social verification voucher
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct VerificationVoucher {
248    /// Voucher unique ID
249    pub voucher_id: String,
250    /// User being vouched for
251    pub subject_user_id: UserId,
252    /// User providing the voucher
253    pub voucher_user_id: UserId,
254    /// Type of relationship
255    pub relationship_type: RelationshipType,
256    /// Confidence level (0.0 to 1.0)
257    pub confidence: f64,
258    /// Optional verification message
259    pub message: Option<String>,
260    /// Voucher creation time
261    pub created_at: SystemTime,
262    /// Voucher expiration (if any)
263    pub expires_at: Option<SystemTime>,
264    /// Voucher signature
265    pub signature: Vec<u8>,
266}
267
268/// Types of relationships for social verification
269#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
270pub enum RelationshipType {
271    /// Close personal friend
272    PersonalFriend,
273    /// Professional colleague
274    Professional,
275    /// Family member
276    Family,
277    /// Community member (shared group/organization)
278    Community,
279    /// Online acquaintance
280    OnlineAcquaintance,
281    /// Verified through external system
282    ExternalVerification,
283}
284
285impl Default for UserPreferences {
286    fn default() -> Self {
287        Self {
288            discovery: DiscoverabilitySettings {
289                discoverable_by_name: true,
290                discoverable_by_friends: true,
291                allow_contact_requests: true,
292                require_mutual_friends: false,
293                listed_in_directory: false, // Private by default
294            },
295            default_permissions: ProfilePermissions {
296                can_see_display_name: true,
297                can_see_avatar: true,
298                can_see_status: false,
299                can_see_contact_info: false,
300                can_see_last_seen: false,
301                can_see_custom_fields: false,
302            },
303            privacy: PrivacySettings {
304                require_proof_of_humanity: false,
305                max_contact_request_age: Duration::from_secs(7 * 24 * 3600), // 1 week
306                enable_forward_secrecy: true,
307                auto_rotate_keys: false,
308                key_rotation_interval: Duration::from_secs(30 * 24 * 3600), // 30 days
309            },
310        }
311    }
312}
313
314impl Default for ProfilePermissions {
315    fn default() -> Self {
316        Self {
317            can_see_display_name: true,
318            can_see_avatar: true,
319            can_see_status: false,
320            can_see_contact_info: false,
321            can_see_last_seen: false,
322            can_see_custom_fields: false,
323        }
324    }
325}
326
327impl UserIdentity {
328    /// Create a new user identity
329    pub fn new(display_name: String, three_word_address: String) -> Result<(Self, Keypair)> {
330        let mut csprng = OsRng {};
331        let keypair = Keypair::generate(&mut csprng);
332        
333        let user_id = Self::derive_user_id(&keypair.public);
334        let display_name_hint = Self::create_display_name_hint(&display_name);
335        
336        let identity = Self {
337            user_id,
338            public_key: keypair.public.as_bytes().to_vec(),
339            display_name_hint,
340            three_word_address,
341            created_at: SystemTime::now(),
342            version: 1,
343            verification_level: VerificationLevel::SelfSigned,
344        };
345        
346        Ok((identity, keypair))
347    }
348    
349    /// Derive user ID from public key
350    pub fn derive_user_id(public_key: &PublicKey) -> UserId {
351        let hash = Sha256::digest(public_key.as_bytes());
352        hex::encode(hash)
353    }
354    
355    /// Derive user ID from public key bytes
356    pub fn derive_user_id_from_bytes(public_key_bytes: &[u8]) -> UserId {
357        let hash = Sha256::digest(public_key_bytes);
358        hex::encode(hash)
359    }
360    
361    /// Create a search hint from display name (first 4 chars + hash)
362    fn create_display_name_hint(display_name: &str) -> String {
363        let prefix = display_name.chars().take(4).collect::<String>();
364        let hash = blake3::hash(display_name.as_bytes());
365        let hash_suffix = hex::encode(&hash.as_bytes()[..4]);
366        format!("{}:{}", prefix, hash_suffix)
367    }
368    
369    /// Verify a signature against this identity
370    pub fn verify_signature(&self, message: &[u8], signature: &Signature) -> Result<bool> {
371        let public_key = PublicKey::from_bytes(&self.public_key)
372            .map_err(|e| P2PError::Cryptography(format!("Invalid public key: {}", e)))?;
373        Ok(public_key.verify(message, signature).is_ok())
374    }
375    
376    /// Get DHT key for storing this user's profile
377    pub fn get_profile_dht_key(&self) -> Key {
378        let key_data = format!("user_profile:{}", self.user_id);
379        Key::new(key_data.as_bytes())
380    }
381    
382    /// Get DHT key for name resolution
383    pub fn get_name_resolution_dht_key(display_name: &str) -> Key {
384        let key_data = format!("user_name:{}", display_name.to_lowercase());
385        Key::new(key_data.as_bytes())
386    }
387}
388
389impl UserProfile {
390    /// Create a new user profile
391    pub fn new(display_name: String) -> Self {
392        let now = SystemTime::now();
393        Self {
394            display_name,
395            avatar_hash: None,
396            status_message: None,
397            created_at: now,
398            updated_at: now,
399            preferences: UserPreferences::default(),
400            custom_fields: HashMap::new(),
401        }
402    }
403    
404    /// Update the profile
405    pub fn update(&mut self) {
406        self.updated_at = SystemTime::now();
407    }
408    
409    /// Set avatar from image data
410    pub fn set_avatar(&mut self, image_data: &[u8]) {
411        self.avatar_hash = Some(hex::encode(blake3::hash(image_data).as_bytes()));
412        self.update();
413    }
414    
415    /// Apply permissions filter to profile
416    pub fn apply_permissions(&self, permissions: &ProfilePermissions) -> Self {
417        let mut filtered = self.clone();
418        
419        if !permissions.can_see_display_name {
420            filtered.display_name = "Hidden".to_string();
421        }
422        
423        if !permissions.can_see_avatar {
424            filtered.avatar_hash = None;
425        }
426        
427        if !permissions.can_see_status {
428            filtered.status_message = None;
429        }
430        
431        if !permissions.can_see_custom_fields {
432            filtered.custom_fields.clear();
433        }
434        
435        filtered
436    }
437}
438
439impl EncryptedUserProfile {
440    /// Create a new encrypted user profile
441    pub fn new(
442        identity: &UserIdentity,
443        profile: &UserProfile,
444        keypair: &Keypair,
445        ipv6_binding: Option<IPv6BindingProof>,
446    ) -> Result<Self> {
447        // Generate random profile encryption key
448        let profile_key = Self::generate_profile_key();
449        
450        // Serialize and encrypt profile data
451        let profile_data = serde_json::to_vec(profile)
452            .map_err(P2PError::Serialization)?;
453        
454        let (encrypted_data, nonce) = Self::encrypt_data(&profile_data, &profile_key)?;
455        
456        // Create signature of encrypted data
457        let signature = keypair.sign(&encrypted_data).to_bytes().to_vec();
458        
459        Ok(Self {
460            user_id: identity.user_id.clone(),
461            public_key: identity.public_key.clone(),
462            encrypted_data,
463            nonce,
464            access_grants: Vec::new(),
465            ipv6_binding_proof: ipv6_binding,
466            signature,
467            updated_at: SystemTime::now(),
468        })
469    }
470    
471    /// Generate a random 256-bit encryption key
472    fn generate_profile_key() -> [u8; 32] {
473        let mut key = [0u8; 32];
474        use rand::RngCore;
475        OsRng.fill_bytes(&mut key);
476        key
477    }
478    
479    /// Encrypt data with AES-256-GCM
480    fn encrypt_data(data: &[u8], key: &[u8; 32]) -> Result<(Vec<u8>, [u8; 12])> {
481        let cipher = Aes256Gcm::new_from_slice(key)
482            .map_err(|e| P2PError::Cryptography(format!("Cipher initialization failed: {}", e)))?;
483        
484        // Generate random nonce
485        let mut nonce_bytes = [0u8; 12];
486        use rand::RngCore;
487        OsRng.fill_bytes(&mut nonce_bytes);
488        let nonce = Nonce::from_slice(&nonce_bytes);
489        
490        let ciphertext = cipher.encrypt(nonce, data)
491            .map_err(|e| P2PError::Cryptography(format!("Profile encryption failed: {}", e)))?;
492        
493        Ok((ciphertext, nonce_bytes))
494    }
495    
496    /// Decrypt data with AES-256-GCM
497    fn decrypt_data(ciphertext: &[u8], key: &[u8; 32], nonce: &[u8; 12]) -> Result<Vec<u8>> {
498        let cipher = Aes256Gcm::new_from_slice(key)
499            .map_err(|e| P2PError::Cryptography(format!("Cipher initialization failed: {}", e)))?;
500        let nonce = Nonce::from_slice(nonce);
501        
502        cipher.decrypt(nonce, ciphertext)
503            .map_err(|e| P2PError::Cryptography(format!("Profile decryption failed: {}", e)))
504    }
505    
506    /// Grant access to another user
507    pub fn grant_access(
508        &mut self,
509        grantee_user_id: UserId,
510        grantee_public_key_bytes: &[u8],
511        permissions: ProfilePermissions,
512        profile_key: &[u8; 32],
513        granter_keypair: &Keypair,
514    ) -> Result<()> {
515        // Encrypt profile key with grantee's public key
516        let encrypted_key = self.encrypt_key_for_user(profile_key, grantee_public_key_bytes)?;
517        
518        // Create grant data for signature
519        let grant_data = format!("{}:{}:{}", 
520            grantee_user_id, 
521            serde_json::to_string(&permissions).unwrap_or_default(),
522            SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs()
523        );
524        
525        let signature = granter_keypair.sign(grant_data.as_bytes()).to_bytes().to_vec();
526        
527        let grant = AccessGrant {
528            grantee_user_id,
529            encrypted_profile_key: encrypted_key,
530            permissions,
531            granted_at: SystemTime::now(),
532            expires_at: None,
533            signature,
534        };
535        
536        // Remove any existing grant for this user
537        self.access_grants.retain(|g| g.grantee_user_id != grant.grantee_user_id);
538        self.access_grants.push(grant);
539        
540        self.updated_at = SystemTime::now();
541        Ok(())
542    }
543    
544    /// Revoke access from a user
545    pub fn revoke_access(&mut self, user_id: &UserId) {
546        self.access_grants.retain(|grant| grant.grantee_user_id != *user_id);
547        self.updated_at = SystemTime::now();
548    }
549    
550    /// Decrypt profile data with provided key
551    pub fn decrypt_profile(&self, profile_key: &[u8; 32]) -> Result<UserProfile> {
552        let decrypted_data = Self::decrypt_data(&self.encrypted_data, profile_key, &self.nonce)?;
553        
554        serde_json::from_slice(&decrypted_data)
555            .map_err(|e| P2PError::Serialization(e))
556    }
557    
558    /// Get access grant for a specific user
559    pub fn get_access_grant(&self, user_id: &UserId) -> Option<&AccessGrant> {
560        self.access_grants.iter().find(|grant| grant.grantee_user_id == *user_id)
561    }
562    
563    /// Check if access grant is still valid
564    pub fn is_grant_valid(grant: &AccessGrant) -> bool {
565        if let Some(expires_at) = grant.expires_at {
566            SystemTime::now() < expires_at
567        } else {
568            true // No expiration
569        }
570    }
571    
572    /// Verify the profile signature
573    pub fn verify_signature(&self) -> Result<bool> {
574        if let (Ok(signature), Ok(public_key)) = (
575            ed25519_dalek::Signature::from_bytes(&self.signature),
576            PublicKey::from_bytes(&self.public_key)
577        ) {
578            Ok(public_key.verify(&self.encrypted_data, &signature).is_ok())
579        } else {
580            Ok(false)
581        }
582    }
583    
584    /// Encrypt a key for a specific user using their public key
585    fn encrypt_key_for_user(&self, key: &[u8; 32], recipient_public_key_bytes: &[u8]) -> Result<Vec<u8>> {
586        // For now, we'll use a simple approach - in a real implementation,
587        // you'd use X25519 key exchange + ChaCha20-Poly1305 or similar
588        // Here we'll just XOR with the public key hash as a placeholder
589        let mut encrypted_key = key.to_vec();
590        let public_key_hash = Sha256::digest(recipient_public_key_bytes);
591        
592        for (i, byte) in encrypted_key.iter_mut().enumerate() {
593            *byte ^= public_key_hash[i % public_key_hash.len()];
594        }
595        
596        Ok(encrypted_key)
597    }
598}
599
600impl IPv6BindingProof {
601    /// Create a new IPv6 binding proof
602    pub fn new(
603        ipv6_identity: IPv6NodeID,
604        user_keypair: &Keypair,
605        ipv6_keypair: &ed25519_dalek::Keypair,
606    ) -> Result<Self> {
607        // User private key signs IPv6 public key
608        let binding_signature = user_keypair.sign(&ipv6_identity.public_key).to_bytes().to_vec();
609        
610        // IPv6 private key signs user public key (mutual binding)
611        let mutual_signature = ipv6_keypair.sign(user_keypair.public.as_bytes()).to_bytes().to_vec();
612        
613        Ok(Self {
614            ipv6_identity,
615            binding_signature,
616            mutual_signature,
617            created_at: SystemTime::now(),
618        })
619    }
620    
621    /// Verify the binding proof
622    pub fn verify(&self, user_public_key_bytes: &[u8]) -> Result<bool> {
623        // Verify user signature of IPv6 public key
624        let user_sig_valid = if let (Ok(signature), Ok(user_public_key)) = (
625            ed25519_dalek::Signature::from_bytes(&self.binding_signature),
626            PublicKey::from_bytes(user_public_key_bytes)
627        ) {
628            user_public_key
629                .verify(&self.ipv6_identity.public_key, &signature)
630                .is_ok()
631        } else {
632            false
633        };
634        
635        // Verify IPv6 signature of user public key
636        // Note: IPv6 signature verification would need proper key reconstruction from Vec<u8>
637        // For now, we'll just check if the signature exists
638        let ipv6_sig_valid = !self.mutual_signature.is_empty();
639        
640        Ok(user_sig_valid && ipv6_sig_valid)
641    }
642}
643
644impl IdentityChallenge {
645    /// Create a new identity challenge
646    pub fn new(duration: Duration) -> Self {
647        let mut challenge_data = [0u8; 32];
648        use rand::RngCore;
649        OsRng.fill_bytes(&mut challenge_data);
650        
651        let now = SystemTime::now();
652        Self {
653            challenge_id: Uuid::new_v4().to_string(),
654            challenge_data,
655            created_at: now,
656            expires_at: now + duration,
657        }
658    }
659    
660    /// Check if challenge is still valid
661    pub fn is_valid(&self) -> bool {
662        SystemTime::now() < self.expires_at
663    }
664    
665    /// Create a response to this challenge
666    pub fn create_response(&self, user_id: UserId, keypair: &Keypair) -> Result<ChallengeProof> {
667        if !self.is_valid() {
668            return Err(P2PError::InvalidState("Challenge expired".to_string()));
669        }
670        
671        let signature = keypair.sign(&self.challenge_data).to_bytes().to_vec();
672        
673        Ok(ChallengeProof {
674            challenge_id: self.challenge_id.clone(),
675            user_id,
676            signature,
677            timestamp: SystemTime::now(),
678        })
679    }
680}
681
682impl ChallengeProof {
683    /// Verify this proof against a challenge and public key
684    pub fn verify(&self, challenge: &IdentityChallenge, public_key_bytes: &[u8]) -> Result<bool> {
685        if self.challenge_id != challenge.challenge_id {
686            return Ok(false);
687        }
688        
689        if !challenge.is_valid() {
690            return Ok(false);
691        }
692        
693        if let (Ok(signature), Ok(public_key)) = (
694            ed25519_dalek::Signature::from_bytes(&self.signature),
695            PublicKey::from_bytes(public_key_bytes)
696        ) {
697            Ok(public_key.verify(&challenge.challenge_data, &signature).is_ok())
698        } else {
699            Ok(false)
700        }
701    }
702}
703
704#[cfg(test)]
705mod tests {
706    use super::*;
707    use std::str::FromStr;
708    
709    fn create_test_identity() -> (UserIdentity, Keypair) {
710        UserIdentity::new(
711            "TestUser".to_string(),
712            "test.user.example".to_string(),
713        ).unwrap()
714    }
715    
716    #[test]
717    fn test_user_identity_creation() {
718        let (identity, keypair) = create_test_identity();
719        
720        assert_eq!(identity.display_name_hint, "Test:a665a45920");
721        assert_eq!(identity.three_word_address, "test.user.example");
722        assert_eq!(identity.verification_level, VerificationLevel::SelfSigned);
723        assert_eq!(identity.version, 1);
724        assert_eq!(identity.user_id, UserIdentity::derive_user_id(&keypair.public));
725    }
726    
727    #[test]
728    fn test_user_profile_creation() {
729        let profile = UserProfile::new("Test User".to_string());
730        
731        assert_eq!(profile.display_name, "Test User");
732        assert!(profile.avatar_hash.is_none());
733        assert!(profile.status_message.is_none());
734        assert_eq!(profile.preferences.discovery.discoverable_by_name, true);
735        assert_eq!(profile.preferences.default_permissions.can_see_display_name, true);
736    }
737    
738    #[test]
739    fn test_encrypted_profile_creation() {
740        let (identity, keypair) = create_test_identity();
741        let profile = UserProfile::new("Test User".to_string());
742        
743        let encrypted_profile = EncryptedUserProfile::new(
744            &identity,
745            &profile,
746            &keypair,
747            None,
748        ).unwrap();
749        
750        assert_eq!(encrypted_profile.user_id, identity.user_id);
751        assert_eq!(encrypted_profile.public_key, identity.public_key);
752        assert!(!encrypted_profile.encrypted_data.is_empty());
753        assert!(encrypted_profile.verify_signature().unwrap());
754    }
755    
756    #[test]
757    fn test_access_grant_system() {
758        let (identity1, keypair1) = create_test_identity();
759        let (identity2, _keypair2) = create_test_identity();
760        let profile = UserProfile::new("Test User".to_string());
761        
762        let mut encrypted_profile = EncryptedUserProfile::new(
763            &identity1,
764            &profile,
765            &keypair1,
766            None,
767        ).unwrap();
768        
769        let profile_key = EncryptedUserProfile::generate_profile_key();
770        let permissions = ProfilePermissions::default();
771        
772        // Grant access to second user
773        encrypted_profile.grant_access(
774            identity2.user_id.clone(),
775            &identity2.public_key,
776            permissions.clone(),
777            &profile_key,
778            &keypair1,
779        ).unwrap();
780        
781        // Check grant exists
782        let grant = encrypted_profile.get_access_grant(&identity2.user_id);
783        assert!(grant.is_some());
784        assert_eq!(grant.unwrap().permissions.can_see_display_name, permissions.can_see_display_name);
785        
786        // Revoke access
787        encrypted_profile.revoke_access(&identity2.user_id);
788        assert!(encrypted_profile.get_access_grant(&identity2.user_id).is_none());
789    }
790    
791    #[test]
792    fn test_identity_challenge() {
793        let challenge = IdentityChallenge::new(Duration::from_secs(300));
794        let (identity, keypair) = create_test_identity();
795        
796        assert!(challenge.is_valid());
797        
798        let proof = challenge.create_response(
799            identity.user_id.clone(),
800            &keypair,
801        ).unwrap();
802        
803        assert_eq!(proof.challenge_id, challenge.challenge_id);
804        assert_eq!(proof.user_id, identity.user_id);
805        assert!(proof.verify(&challenge, &identity.public_key).unwrap());
806    }
807    
808    #[test]
809    fn test_profile_permissions_filtering() {
810        let mut profile = UserProfile::new("Test User".to_string());
811        profile.status_message = Some("Hello world".to_string());
812        profile.set_avatar(b"fake_image_data");
813        
814        let restricted_permissions = ProfilePermissions {
815            can_see_display_name: false,
816            can_see_avatar: false,
817            can_see_status: false,
818            ..Default::default()
819        };
820        
821        let filtered_profile = profile.apply_permissions(&restricted_permissions);
822        
823        assert_eq!(filtered_profile.display_name, "Hidden");
824        assert!(filtered_profile.avatar_hash.is_none());
825        assert!(filtered_profile.status_message.is_none());
826    }
827    
828    #[test]
829    fn test_user_id_derivation() {
830        let (identity1, keypair1) = create_test_identity();
831        let (identity2, keypair2) = create_test_identity();
832        
833        // Same public key should give same user ID
834        let derived_id1 = UserIdentity::derive_user_id(&keypair1.public);
835        assert_eq!(identity1.user_id, derived_id1);
836        
837        // Different public keys should give different user IDs
838        assert_ne!(identity1.user_id, identity2.user_id);
839        assert_ne!(derived_id1, UserIdentity::derive_user_id(&keypair2.public));
840    }
841    
842    #[test]
843    fn test_dht_key_generation() {
844        let (identity, _keypair) = create_test_identity();
845        
846        let profile_key = identity.get_profile_dht_key();
847        let name_key = UserIdentity::get_name_resolution_dht_key("TestUser");
848        
849        // Keys should be deterministic
850        assert_eq!(profile_key, identity.get_profile_dht_key());
851        assert_eq!(name_key, UserIdentity::get_name_resolution_dht_key("TestUser"));
852        
853        // Different inputs should give different keys
854        assert_ne!(profile_key, name_key);
855    }
856}