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