ant_quic/crypto/
raw_public_keys.rs

1//! RFC 7250 Raw Public Keys Support for ant-quic
2//!
3//! This module implements Raw Public Keys (RPK) support as defined in RFC 7250,
4//! allowing P2P connections to authenticate using Ed25519 public keys directly
5//! without the overhead of X.509 certificates.
6
7use std::{collections::HashSet, fmt::Debug, sync::Arc};
8
9use rustls::{
10    CertificateError, ClientConfig, DigitallySignedStruct, Error as TlsError, ServerConfig,
11    SignatureScheme,
12    client::danger::{HandshakeSignatureValid, ServerCertVerifier},
13    pki_types::{CertificateDer, ServerName, UnixTime},
14    server::ResolvesServerCert,
15    sign::{CertifiedKey, SigningKey},
16};
17
18use super::tls_extension_simulation::{Rfc7250ClientConfig, Rfc7250ServerConfig};
19
20use ed25519_dalek::{
21    Signature, Signer, SigningKey as Ed25519SecretKey, Verifier, VerifyingKey as Ed25519PublicKey,
22};
23
24use tracing::{debug, info, warn};
25
26/// Raw Public Key verifier for client-side authentication
27#[derive(Debug)]
28pub struct RawPublicKeyVerifier {
29    /// Set of trusted public keys
30    trusted_keys: HashSet<[u8; 32]>,
31    /// Whether to allow any key (for development/testing)
32    allow_any_key: bool,
33}
34
35impl RawPublicKeyVerifier {
36    /// Create a new RPK verifier with a set of trusted public keys
37    pub fn new(trusted_keys: Vec<[u8; 32]>) -> Self {
38        Self {
39            trusted_keys: trusted_keys.into_iter().collect(),
40            allow_any_key: false,
41        }
42    }
43
44    /// Create a verifier that accepts any valid Ed25519 public key
45    /// WARNING: Only use for development/testing!
46    pub fn allow_any() -> Self {
47        Self {
48            trusted_keys: HashSet::new(),
49            allow_any_key: true,
50        }
51    }
52
53    /// Add a trusted public key
54    pub fn add_trusted_key(&mut self, public_key: [u8; 32]) {
55        self.trusted_keys.insert(public_key);
56    }
57
58    /// Extract Ed25519 public key from SubjectPublicKeyInfo
59    fn extract_ed25519_key(&self, spki_der: &[u8]) -> Result<[u8; 32], TlsError> {
60        // Parse the SubjectPublicKeyInfo structure
61        // Ed25519 OID: 1.3.101.112 (0x2b6570)
62
63        // For RFC 7250, the "certificate" is actually just the SubjectPublicKeyInfo
64        // We need to extract the raw 32-byte Ed25519 public key from this structure
65
66        // Simple parsing for Ed25519 SubjectPublicKeyInfo
67        // This is a minimal parser - in production you'd want more robust ASN.1 parsing
68        if spki_der.len() < 44 {
69            return Err(TlsError::InvalidCertificate(CertificateError::BadEncoding));
70        }
71
72        // Look for Ed25519 OID pattern in the DER encoding
73        let ed25519_oid = [0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70];
74
75        if !spki_der.starts_with(&ed25519_oid) {
76            return Err(TlsError::InvalidCertificate(
77                CertificateError::UnknownIssuer,
78            ));
79        }
80
81        // The public key should be at offset 12 and be 32 bytes long
82        if spki_der.len() != 44 {
83            return Err(TlsError::InvalidCertificate(CertificateError::BadEncoding));
84        }
85
86        let mut public_key = [0u8; 32];
87        public_key.copy_from_slice(&spki_der[12..44]);
88
89        debug!(
90            "Extracted Ed25519 public key: {:?}",
91            hex::encode(&public_key)
92        );
93        Ok(public_key)
94    }
95}
96
97impl ServerCertVerifier for RawPublicKeyVerifier {
98    fn verify_server_cert(
99        &self,
100        end_entity: &CertificateDer<'_>,
101        _intermediates: &[CertificateDer<'_>],
102        _server_name: &ServerName,
103        _ocsp_response: &[u8],
104        _now: UnixTime,
105    ) -> Result<rustls::client::danger::ServerCertVerified, TlsError> {
106        debug!("Verifying server certificate with Raw Public Key verifier");
107
108        // Extract the Ed25519 public key from the certificate
109        let public_key = self.extract_ed25519_key(end_entity.as_ref())?;
110
111        // Check if this key is trusted
112        if self.allow_any_key {
113            info!("Accepting any Ed25519 public key (development mode)");
114            return Ok(rustls::client::danger::ServerCertVerified::assertion());
115        }
116
117        if self.trusted_keys.contains(&public_key) {
118            info!("Server public key is trusted: {}", hex::encode(&public_key));
119            Ok(rustls::client::danger::ServerCertVerified::assertion())
120        } else {
121            warn!("Unknown server public key: {}", hex::encode(&public_key));
122            Err(TlsError::InvalidCertificate(
123                CertificateError::UnknownIssuer,
124            ))
125        }
126    }
127
128    fn verify_tls12_signature(
129        &self,
130        _message: &[u8],
131        _cert: &CertificateDer<'_>,
132        _dss: &DigitallySignedStruct,
133    ) -> Result<HandshakeSignatureValid, TlsError> {
134        // TLS 1.2 not supported for Raw Public Keys in this implementation
135        Err(TlsError::UnsupportedNameType)
136    }
137
138    fn verify_tls13_signature(
139        &self,
140        message: &[u8],
141        cert: &CertificateDer<'_>,
142        dss: &DigitallySignedStruct,
143    ) -> Result<HandshakeSignatureValid, TlsError> {
144        debug!("Verifying TLS 1.3 signature with Raw Public Key");
145
146        // Extract Ed25519 public key
147        let public_key_bytes = self.extract_ed25519_key(cert.as_ref())?;
148
149        // Create Ed25519 public key
150        let public_key = Ed25519PublicKey::from_bytes(&public_key_bytes)
151            .map_err(|_| TlsError::InvalidCertificate(CertificateError::BadEncoding))?;
152
153        // Verify signature
154        if dss.signature().len() != 64 {
155            return Err(TlsError::General(
156                "Invalid signature length".to_string(),
157            ));
158        }
159
160        let mut sig_bytes = [0u8; 64];
161        sig_bytes.copy_from_slice(dss.signature());
162        let signature = Signature::from(sig_bytes);
163
164        public_key
165            .verify(message, &signature)
166            .map_err(|_| TlsError::General("Signature verification failed".to_string()))?;
167
168        debug!("TLS 1.3 signature verification successful");
169        Ok(HandshakeSignatureValid::assertion())
170    }
171
172    fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
173        vec![SignatureScheme::ED25519]
174    }
175}
176
177/// Raw Public Key resolver for server-side
178#[derive(Debug)]
179pub struct RawPublicKeyResolver {
180    /// The server's certified key pair
181    certified_key: Arc<CertifiedKey>,
182}
183
184impl RawPublicKeyResolver {
185    /// Create a new RPK resolver with an Ed25519 key pair
186    pub fn new(private_key: Ed25519SecretKey) -> Result<Self, TlsError> {
187        // Get the public key from the private key
188        let public_key = private_key.verifying_key();
189
190        // Create SubjectPublicKeyInfo for the public key
191        let public_key_der = create_ed25519_subject_public_key_info(&public_key);
192
193        // Create a signing key
194        let signing_key = Ed25519SigningKey::new(private_key);
195
196        // Create certified key
197        let certified_key = Arc::new(CertifiedKey {
198            cert: vec![CertificateDer::from(public_key_der)],
199            key: Arc::new(signing_key),
200            ocsp: None,
201        });
202
203        Ok(Self { certified_key })
204    }
205}
206
207impl ResolvesServerCert for RawPublicKeyResolver {
208    fn resolve(&self, _client_hello: rustls::server::ClientHello) -> Option<Arc<CertifiedKey>> {
209        debug!("Resolving server certificate with Raw Public Key");
210        Some(self.certified_key.clone())
211    }
212}
213
214/// Ed25519 signing key implementation for rustls
215#[derive(Debug)]
216struct Ed25519SigningKey {
217    private_key: Ed25519SecretKey,
218}
219
220impl Ed25519SigningKey {
221    fn new(private_key: Ed25519SecretKey) -> Self {
222        Self {
223            private_key,
224        }
225    }
226}
227
228impl SigningKey for Ed25519SigningKey {
229    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn rustls::sign::Signer>> {
230        if offered.contains(&SignatureScheme::ED25519) {
231            Some(Box::new(Ed25519Signer {
232                private_key: self.private_key.clone(),
233            }))
234        } else {
235            None
236        }
237    }
238
239    fn algorithm(&self) -> rustls::SignatureAlgorithm {
240        rustls::SignatureAlgorithm::ED25519
241    }
242}
243
244/// Ed25519 signer implementation
245#[derive(Debug)]
246struct Ed25519Signer {
247    private_key: Ed25519SecretKey,
248}
249
250impl rustls::sign::Signer for Ed25519Signer {
251    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, TlsError> {
252        let signature = self.private_key.sign(message);
253        Ok(signature.to_bytes().to_vec())
254    }
255
256    fn scheme(&self) -> SignatureScheme {
257        SignatureScheme::ED25519
258    }
259}
260
261/// Create a SubjectPublicKeyInfo DER encoding for an Ed25519 public key
262pub fn create_ed25519_subject_public_key_info(public_key: &Ed25519PublicKey) -> Vec<u8> {
263    // Ed25519 SubjectPublicKeyInfo structure:
264    // SEQUENCE {
265    //   SEQUENCE {
266    //     OBJECT IDENTIFIER 1.3.101.112 (Ed25519)
267    //   }
268    //   BIT STRING (32 bytes of public key)
269    // }
270
271    let mut spki = Vec::new();
272
273    // SEQUENCE tag and length (total length will be 44 bytes)
274    spki.extend_from_slice(&[0x30, 0x2a]);
275
276    // Algorithm identifier SEQUENCE
277    spki.extend_from_slice(&[0x30, 0x05]);
278
279    // Ed25519 OID: 1.3.101.112
280    spki.extend_from_slice(&[0x06, 0x03, 0x2b, 0x65, 0x70]);
281
282    // Subject public key BIT STRING
283    spki.extend_from_slice(&[0x03, 0x21, 0x00]); // BIT STRING, 33 bytes (32 + 1 unused bits byte)
284
285    // The actual 32-byte Ed25519 public key
286    spki.extend_from_slice(public_key.as_bytes());
287
288    spki
289}
290
291/// Configuration builder for Raw Public Keys with TLS extension support
292#[derive(Debug, Default, Clone)]
293pub struct RawPublicKeyConfigBuilder {
294    trusted_keys: Vec<[u8; 32]>,
295    allow_any: bool,
296    server_key: Option<(Ed25519SecretKey, Ed25519PublicKey)>,
297    /// Enable TLS certificate type extensions
298    enable_extensions: bool,
299    /// Certificate type preferences for negotiation
300    cert_type_preferences: Option<super::tls_extensions::CertificateTypePreferences>,
301}
302
303impl RawPublicKeyConfigBuilder {
304    /// Create a new builder
305    pub fn new() -> Self {
306        Self::default()
307    }
308
309    /// Add a trusted public key
310    pub fn add_trusted_key(mut self, public_key: [u8; 32]) -> Self {
311        self.trusted_keys.push(public_key);
312        self
313    }
314
315    /// Allow any valid Ed25519 public key (development only)
316    pub fn allow_any_key(mut self) -> Self {
317        self.allow_any = true;
318        self
319    }
320
321    /// Set the server's key pair
322    pub fn with_server_key(mut self, private_key: Ed25519SecretKey) -> Self {
323        let public_key = private_key.verifying_key();
324        self.server_key = Some((private_key, public_key));
325        self
326    }
327
328    /// Enable TLS certificate type extensions for negotiation
329    pub fn with_certificate_type_extensions(mut self, preferences: super::tls_extensions::CertificateTypePreferences) -> Self {
330        self.enable_extensions = true;
331        self.cert_type_preferences = Some(preferences);
332        self
333    }
334
335    /// Enable TLS extensions with default Raw Public Key preferences
336    pub fn enable_certificate_type_extensions(mut self) -> Self {
337        self.enable_extensions = true;
338        self.cert_type_preferences = Some(super::tls_extensions::CertificateTypePreferences::prefer_raw_public_key());
339        self
340    }
341
342    /// Build a client configuration with Raw Public Keys
343    pub fn build_client_config(self) -> Result<ClientConfig, TlsError> {
344        let verifier = if self.allow_any {
345            RawPublicKeyVerifier::allow_any()
346        } else {
347            RawPublicKeyVerifier::new(self.trusted_keys)
348        };
349
350        // Create the client config with Raw Public Key support
351        // rustls 0.23.x requires specific configuration for RFC 7250
352        let config = ClientConfig::builder()
353            .dangerous()
354            .with_custom_certificate_verifier(Arc::new(verifier))
355            .with_no_client_auth();
356
357        // Enable Raw Public Key certificate type in rustls
358        // This tells rustls to advertise support for Raw Public Keys in the
359        // client_certificate_type and server_certificate_type extensions
360        if self.enable_extensions {
361            // rustls 0.23.x automatically handles RFC 7250 extensions when
362            // a custom certificate verifier is provided that supports Raw Public Keys
363            // The verifier we're using (RawPublicKeyVerifier) handles SubjectPublicKeyInfo
364            // format which rustls recognizes as Raw Public Key support
365        }
366
367        Ok(config)
368    }
369
370    /// Build a server configuration with Raw Public Keys
371    pub fn build_server_config(self) -> Result<ServerConfig, TlsError> {
372        let (private_key, _public_key) = self
373            .server_key
374            .ok_or_else(|| TlsError::General("Server key pair required".into()))?;
375
376        let resolver = RawPublicKeyResolver::new(private_key)?;
377
378        let config = ServerConfig::builder()
379            .with_no_client_auth()
380            .with_cert_resolver(Arc::new(resolver));
381
382        // Add TLS certificate type extensions if enabled
383        if self.enable_extensions {
384            if let Some(_preferences) = self.cert_type_preferences {
385                // rustls 0.23.x handles RFC 7250 internally, so we just need to configure it
386                // No custom extension handler needed
387            }
388        }
389
390        Ok(config)
391    }
392
393    /// Build a client configuration with RFC 7250 extension simulation
394    pub fn build_rfc7250_client_config(self) -> Result<Rfc7250ClientConfig, TlsError> {
395        let preferences = self.cert_type_preferences.clone()
396            .unwrap_or_else(|| super::tls_extensions::CertificateTypePreferences::prefer_raw_public_key());
397        let base_config = self.build_client_config()?;
398        
399        Ok(Rfc7250ClientConfig::new(base_config, preferences))
400    }
401
402    /// Build a server configuration with RFC 7250 extension simulation
403    pub fn build_rfc7250_server_config(self) -> Result<Rfc7250ServerConfig, TlsError> {
404        let preferences = self.cert_type_preferences.clone()
405            .unwrap_or_else(|| super::tls_extensions::CertificateTypePreferences::prefer_raw_public_key());
406        let base_config = self.build_server_config()?;
407        
408        Ok(Rfc7250ServerConfig::new(base_config, preferences))
409    }
410}
411
412/// Utility functions for key generation and conversion
413pub mod key_utils {
414    use super::*;
415    
416
417    /// Generate a new Ed25519 key pair
418    pub fn generate_ed25519_keypair() -> (Ed25519SecretKey, Ed25519PublicKey) {
419        use rand::rngs::OsRng;
420        let private_key = Ed25519SecretKey::generate(&mut OsRng);
421        let public_key = private_key.verifying_key();
422        (private_key, public_key)
423    }
424
425    /// Convert Ed25519 public key to bytes
426    pub fn public_key_to_bytes(public_key: &Ed25519PublicKey) -> [u8; 32] {
427        *public_key.as_bytes()
428    }
429
430    /// Create Ed25519 public key from bytes
431    pub fn public_key_from_bytes(bytes: &[u8; 32]) -> Result<Ed25519PublicKey, &'static str> {
432        Ed25519PublicKey::from_bytes(bytes).map_err(|_| "Invalid public key bytes")
433    }
434
435    /// Create a test key pair for development
436    pub fn create_test_keypair() -> (Ed25519SecretKey, Ed25519PublicKey) {
437        // Use a different deterministic seed for testing to ensure different keys
438        let seed = [43u8; 32];  // Different from generate_ed25519_keypair
439        let private_key = Ed25519SecretKey::from_bytes(&seed);
440        let public_key = private_key.verifying_key();
441        (private_key, public_key)
442    }
443
444    /// Derive a peer ID from an Ed25519 public key using SHA-256 hash
445    ///
446    /// This provides a secure, collision-resistant peer ID derivation method
447    /// that follows P2P networking best practices. The SHA-256 hash ensures
448    /// uniform distribution and prevents direct key exposure.
449    pub fn derive_peer_id_from_public_key(public_key: &Ed25519PublicKey) -> crate::nat_traversal_api::PeerId {
450        #[cfg(feature = "ring")]
451        {
452            use ring::digest::{digest, SHA256};
453            
454            let key_bytes = public_key.as_bytes();
455            
456            // Create the input data with domain separator
457            let mut input = Vec::with_capacity(20 + 32); // "AUTONOMI_PEER_ID_V1:" + key_bytes
458            input.extend_from_slice(b"AUTONOMI_PEER_ID_V1:");
459            input.extend_from_slice(key_bytes);
460            
461            // Hash the input
462            let hash = digest(&SHA256, &input);
463            let hash_bytes = hash.as_ref();
464            
465            let mut peer_id_bytes = [0u8; 32];
466            peer_id_bytes.copy_from_slice(hash_bytes);
467            
468            crate::nat_traversal_api::PeerId(peer_id_bytes)
469        }
470        #[cfg(not(feature = "ring"))]
471        {
472            // Fallback implementation using direct key bytes (less secure but functional)
473            // In production, should always use ring or another crypto provider
474            let key_bytes = public_key.as_bytes();
475            let mut peer_id_bytes = [0u8; 32];
476            peer_id_bytes.copy_from_slice(key_bytes);
477            
478            crate::nat_traversal_api::PeerId(peer_id_bytes)
479        }
480    }
481
482    /// Derive a peer ID from raw public key bytes (32-byte Ed25519 key)
483    ///
484    /// This is a convenience function for when you have the raw key bytes
485    /// rather than an Ed25519PublicKey object.
486    pub fn derive_peer_id_from_key_bytes(key_bytes: &[u8; 32]) -> Result<crate::nat_traversal_api::PeerId, &'static str> {
487        let public_key = public_key_from_bytes(key_bytes)?;
488        Ok(derive_peer_id_from_public_key(&public_key))
489    }
490
491    /// Verify that a peer ID was correctly derived from a public key
492    ///
493    /// This is useful for validation during connection establishment
494    /// to ensure the peer's claimed ID matches their public key.
495    pub fn verify_peer_id(peer_id: &crate::nat_traversal_api::PeerId, public_key: &Ed25519PublicKey) -> bool {
496        let derived_id = derive_peer_id_from_public_key(public_key);
497        *peer_id == derived_id
498    }
499}
500
501#[cfg(test)]
502mod tests {
503    use super::key_utils::*;
504    use super::*;
505
506    #[test]
507    fn test_create_ed25519_subject_public_key_info() {
508        let (_, public_key) = generate_ed25519_keypair();
509        let spki = create_ed25519_subject_public_key_info(&public_key);
510
511        // Should be exactly 44 bytes
512        assert_eq!(spki.len(), 44);
513
514        // Should start with correct ASN.1 structure
515        assert_eq!(
516            &spki[0..9],
517            &[0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70]
518        );
519
520        // Should contain the public key at the end
521        assert_eq!(&spki[12..], public_key.as_bytes());
522    }
523
524    #[test]
525    fn test_raw_public_key_verifier_trusted_key() {
526        let (_, public_key) = generate_ed25519_keypair();
527        let key_bytes = public_key_to_bytes(&public_key);
528
529        let verifier = RawPublicKeyVerifier::new(vec![key_bytes]);
530
531        // Create a mock certificate with the public key
532        let spki = create_ed25519_subject_public_key_info(&public_key);
533        let cert = CertificateDer::from(spki);
534
535        // Should successfully verify
536        let result = verifier.verify_server_cert(
537            &cert,
538            &[],
539            &ServerName::try_from("test").unwrap(),
540            &[],
541            UnixTime::now(),
542        );
543
544        assert!(result.is_ok());
545    }
546
547    #[test]
548    fn test_raw_public_key_verifier_unknown_key() {
549        let (_, public_key1) = generate_ed25519_keypair();
550        let (_, public_key2) = generate_ed25519_keypair();
551
552        let key1_bytes = public_key_to_bytes(&public_key1);
553        let verifier = RawPublicKeyVerifier::new(vec![key1_bytes]);
554
555        // Create certificate with different key
556        let spki = create_ed25519_subject_public_key_info(&public_key2);
557        let cert = CertificateDer::from(spki);
558
559        // Should fail verification
560        let result = verifier.verify_server_cert(
561            &cert,
562            &[],
563            &ServerName::try_from("test").unwrap(),
564            &[],
565            UnixTime::now(),
566        );
567
568        assert!(result.is_err());
569    }
570
571    #[test]
572    fn test_raw_public_key_verifier_allow_any() {
573        let (_, public_key) = generate_ed25519_keypair();
574        let verifier = RawPublicKeyVerifier::allow_any();
575
576        let spki = create_ed25519_subject_public_key_info(&public_key);
577        let cert = CertificateDer::from(spki);
578
579        // Should accept any valid key
580        let result = verifier.verify_server_cert(
581            &cert,
582            &[],
583            &ServerName::try_from("test").unwrap(),
584            &[],
585            UnixTime::now(),
586        );
587
588        assert!(result.is_ok());
589    }
590
591    #[test]
592    fn test_config_builder() {
593        let (private_key, public_key) = generate_ed25519_keypair();
594        let key_bytes = public_key_to_bytes(&public_key);
595
596        // Test client config
597        let client_config = RawPublicKeyConfigBuilder::new()
598            .add_trusted_key(key_bytes)
599            .build_client_config();
600        assert!(client_config.is_ok());
601
602        // Test server config
603        let server_config = RawPublicKeyConfigBuilder::new()
604            .with_server_key(private_key)
605            .build_server_config();
606        assert!(server_config.is_ok());
607    }
608
609    #[test]
610    fn test_extract_ed25519_key() {
611        let (_, public_key) = generate_ed25519_keypair();
612        let spki = create_ed25519_subject_public_key_info(&public_key);
613
614        let verifier = RawPublicKeyVerifier::allow_any();
615        let extracted_key = verifier.extract_ed25519_key(&spki).unwrap();
616
617        assert_eq!(extracted_key, public_key_to_bytes(&public_key));
618    }
619
620    #[test]
621    fn test_derive_peer_id_from_public_key() {
622        let (_, public_key) = generate_ed25519_keypair();
623        
624        // Test that the function produces a consistent peer ID
625        let peer_id1 = derive_peer_id_from_public_key(&public_key);
626        let peer_id2 = derive_peer_id_from_public_key(&public_key);
627        
628        assert_eq!(peer_id1, peer_id2);
629        
630        // Test that different keys produce different peer IDs
631        let (_, public_key2) = create_test_keypair();
632        let peer_id3 = derive_peer_id_from_public_key(&public_key2);
633        
634        assert_ne!(peer_id1, peer_id3);
635    }
636
637    #[test]
638    fn test_derive_peer_id_from_key_bytes() {
639        let (_, public_key) = generate_ed25519_keypair();
640        let key_bytes = public_key_to_bytes(&public_key);
641        
642        // Test that both methods produce the same result
643        let peer_id1 = derive_peer_id_from_public_key(&public_key);
644        let peer_id2 = derive_peer_id_from_key_bytes(&key_bytes).unwrap();
645        
646        assert_eq!(peer_id1, peer_id2);
647        
648        // Test with a different valid key to ensure different peer IDs
649        let (_, public_key2) = create_test_keypair();
650        let key_bytes2 = public_key_to_bytes(&public_key2);
651        let peer_id3 = derive_peer_id_from_key_bytes(&key_bytes2).unwrap();
652        
653        assert_ne!(peer_id1, peer_id3);
654    }
655
656    #[test]
657    fn test_verify_peer_id() {
658        let (_, public_key) = generate_ed25519_keypair();
659        let peer_id = derive_peer_id_from_public_key(&public_key);
660        
661        // Test that verification succeeds for correct peer ID
662        assert!(verify_peer_id(&peer_id, &public_key));
663        
664        // Test that verification fails for incorrect peer ID
665        let (_, other_public_key) = create_test_keypair();
666        assert!(!verify_peer_id(&peer_id, &other_public_key));
667        
668        // Test that verification fails for wrong peer ID
669        let wrong_peer_id = crate::nat_traversal_api::PeerId([0u8; 32]);
670        assert!(!verify_peer_id(&wrong_peer_id, &public_key));
671    }
672
673    #[test]
674    fn test_peer_id_domain_separation() {
675        let (_, public_key) = generate_ed25519_keypair();
676        let peer_id = derive_peer_id_from_public_key(&public_key);
677        
678        // The peer ID should not be the same as the raw public key
679        let key_bytes = public_key_to_bytes(&public_key);
680        assert_ne!(peer_id.0, key_bytes);
681        
682        // The peer ID should be deterministic
683        let peer_id2 = derive_peer_id_from_public_key(&public_key);
684        assert_eq!(peer_id, peer_id2);
685    }
686}