rust_bottle/
keys.rs

1use crate::errors::{BottleError, Result};
2use crate::keychain::SignerKey;
3use crate::signing::{Sign, Verify};
4use ed25519_dalek::{
5    Signature, SigningKey as Ed25519SigningKey, VerifyingKey as Ed25519VerifyingKey,
6};
7use p256::ecdsa::{SigningKey as P256SigningKey, VerifyingKey as P256VerifyingKey};
8use rand::{CryptoRng, RngCore};
9use rsa::{Pkcs1v15Sign, RsaPrivateKey, RsaPublicKey};
10use sha2::{Digest, Sha256};
11
12// Post-quantum cryptography imports
13#[cfg(feature = "ml-kem")]
14use ml_kem::{kem::Kem, EncodedSizeUser, KemCore, MlKem1024Params, MlKem768Params};
15#[cfg(feature = "post-quantum")]
16use pqcrypto_dilithium;
17#[cfg(feature = "post-quantum")]
18use pqcrypto_sphincsplus;
19#[cfg(feature = "post-quantum")]
20use pqcrypto_traits::sign::{
21    DetachedSignature as PqcDetachedSignature, PublicKey as PqcPublicKey, SecretKey as PqcSecretKey,
22};
23
24/// ECDSA P-256 key pair for digital signatures.
25///
26/// This key type uses the P-256 (secp256r1) elliptic curve for signing.
27/// ECDSA signatures are deterministic (RFC 6979) and provide strong security
28/// with 128-bit security level.
29///
30/// # Example
31///
32/// ```rust
33/// use rust_bottle::keys::EcdsaP256Key;
34/// use rand::rngs::OsRng;
35///
36/// let rng = &mut OsRng;
37/// let key = EcdsaP256Key::generate(rng);
38/// let pub_key = key.public_key_bytes();
39/// let priv_key = key.private_key_bytes();
40/// ```
41pub struct EcdsaP256Key {
42    signing_key: P256SigningKey,
43    verifying_key: P256VerifyingKey,
44}
45
46impl EcdsaP256Key {
47    /// Generate a new ECDSA P-256 key pair.
48    ///
49    /// This function generates a cryptographically secure key pair using
50    /// the provided random number generator.
51    ///
52    /// # Arguments
53    ///
54    /// * `rng` - A cryptographically secure random number generator
55    ///
56    /// # Returns
57    ///
58    /// A new `EcdsaP256Key` instance with a randomly generated key pair
59    ///
60    /// # Example
61    ///
62    /// ```rust
63    /// use rust_bottle::keys::EcdsaP256Key;
64    /// use rand::rngs::OsRng;
65    ///
66    /// let rng = &mut OsRng;
67    /// let key = EcdsaP256Key::generate(rng);
68    /// ```
69    pub fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
70        let signing_key = P256SigningKey::random(rng);
71        let verifying_key = *signing_key.verifying_key();
72        Self {
73            signing_key,
74            verifying_key,
75        }
76    }
77
78    /// Get the public key in SEC1 uncompressed format.
79    ///
80    /// The public key is returned as a 65-byte array in SEC1 uncompressed
81    /// format (0x04 prefix + 32-byte x-coordinate + 32-byte y-coordinate).
82    ///
83    /// # Returns
84    ///
85    /// Public key bytes in SEC1 format
86    pub fn public_key_bytes(&self) -> Vec<u8> {
87        self.verifying_key.to_sec1_bytes().to_vec()
88    }
89
90    /// Get the private key bytes.
91    ///
92    /// The private key is returned as a 32-byte array. This is sensitive
93    /// data and should be handled securely.
94    ///
95    /// # Returns
96    ///
97    /// Private key bytes (32 bytes)
98    ///
99    /// # Security Warning
100    ///
101    /// Private keys are sensitive cryptographic material. They should be
102    /// stored securely and cleared from memory when no longer needed.
103    pub fn private_key_bytes(&self) -> Vec<u8> {
104        self.signing_key.to_bytes().to_vec()
105    }
106
107    /// Create an ECDSA P-256 key pair from private key bytes.
108    ///
109    /// This function reconstructs a key pair from a previously saved private
110    /// key. The public key is automatically derived from the private key.
111    ///
112    /// # Arguments
113    ///
114    /// * `bytes` - Private key bytes (32 bytes)
115    ///
116    /// # Returns
117    ///
118    /// * `Ok(EcdsaP256Key)` - Reconstructed key pair
119    /// * `Err(BottleError::InvalidKeyType)` - If the key format is invalid
120    ///
121    /// # Example
122    ///
123    /// ```rust
124    /// use rust_bottle::keys::EcdsaP256Key;
125    /// use rand::rngs::OsRng;
126    ///
127    /// let rng = &mut OsRng;
128    /// let original = EcdsaP256Key::generate(rng);
129    /// let priv_bytes = original.private_key_bytes();
130    ///
131    /// let restored = EcdsaP256Key::from_private_key_bytes(&priv_bytes).unwrap();
132    /// assert_eq!(original.public_key_bytes(), restored.public_key_bytes());
133    /// ```
134    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
135        let signing_key =
136            P256SigningKey::from_bytes(bytes.into()).map_err(|_| BottleError::InvalidKeyType)?;
137        let verifying_key = *signing_key.verifying_key();
138        Ok(Self {
139            signing_key,
140            verifying_key,
141        })
142    }
143}
144
145impl Sign for EcdsaP256Key {
146    /// Sign a message using ECDSA P-256.
147    ///
148    /// The message is hashed with SHA-256 before signing. The signature
149    /// is deterministic (RFC 6979), meaning the same message and key will
150    /// always produce the same signature.
151    ///
152    /// # Arguments
153    ///
154    /// * `_rng` - Random number generator (not used for deterministic signing)
155    /// * `message` - The message to sign
156    ///
157    /// # Returns
158    ///
159    /// * `Ok(Vec<u8>)` - Signature bytes (64 bytes: r + s values)
160    /// * `Err(BottleError::VerifyFailed)` - If signing fails
161    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
162        use ecdsa::signature::Signer;
163        use sha2::Digest;
164        // Hash the message first
165        let digest = sha2::Sha256::digest(message);
166        // Use regular sign method (deterministic with RFC6979)
167        let signature: ecdsa::Signature<p256::NistP256> = self.signing_key.sign(&digest);
168        Ok(signature.to_bytes().to_vec())
169    }
170}
171
172impl Verify for EcdsaP256Key {
173    /// Verify an ECDSA P-256 signature.
174    ///
175    /// The message is hashed with SHA-256 before verification. The signature
176    /// must match the format produced by `sign`.
177    ///
178    /// # Arguments
179    ///
180    /// * `message` - The original message
181    /// * `signature` - The signature to verify (64 bytes: r + s values)
182    ///
183    /// # Returns
184    ///
185    /// * `Ok(())` - Signature is valid
186    /// * `Err(BottleError::VerifyFailed)` - If signature verification fails
187    ///
188    /// # Example
189    ///
190    /// ```rust
191    /// use rust_bottle::keys::EcdsaP256Key;
192    /// use rust_bottle::signing::{Sign, Verify};
193    /// use rand::rngs::OsRng;
194    ///
195    /// let rng = &mut OsRng;
196    /// let key = EcdsaP256Key::generate(rng);
197    /// let message = b"Test message";
198    ///
199    /// let signature = key.sign(rng, message).unwrap();
200    /// assert!(key.verify(message, &signature).is_ok());
201    /// ```
202    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
203        use ecdsa::signature::Verifier;
204        use sha2::Digest;
205        // Hash the message first
206        let digest = sha2::Sha256::digest(message);
207        let sig = ecdsa::Signature::from_bytes(signature.into())
208            .map_err(|_| BottleError::VerifyFailed)?;
209        self.verifying_key
210            .verify(&digest, &sig)
211            .map_err(|_| BottleError::VerifyFailed)?;
212        Ok(())
213    }
214}
215
216impl SignerKey for EcdsaP256Key {
217    /// Get the public key fingerprint (SHA-256 hash).
218    ///
219    /// The fingerprint is used to identify keys in keychains and IDCards.
220    ///
221    /// # Returns
222    ///
223    /// SHA-256 hash of the public key bytes
224    fn fingerprint(&self) -> Vec<u8> {
225        crate::hash::sha256(&self.public_key_bytes())
226    }
227
228    /// Get the public key bytes.
229    ///
230    /// # Returns
231    ///
232    /// Public key bytes in SEC1 format
233    fn public_key(&self) -> Vec<u8> {
234        self.public_key_bytes()
235    }
236}
237
238/// Ed25519 key pair for digital signatures.
239///
240/// Ed25519 is a modern elliptic curve signature scheme based on Curve25519.
241/// It provides 128-bit security with fast signing and verification, and
242/// deterministic signatures. Ed25519 keys are 32 bytes for both private and
243/// public keys.
244///
245/// # Example
246///
247/// ```rust
248/// use rust_bottle::keys::Ed25519Key;
249/// use rand::rngs::OsRng;
250///
251/// let rng = &mut OsRng;
252/// let key = Ed25519Key::generate(rng);
253/// let pub_key = key.public_key_bytes();
254/// let priv_key = key.private_key_bytes();
255/// ```
256#[derive(Clone)]
257pub struct Ed25519Key {
258    signing_key: Ed25519SigningKey,
259    verifying_key: Ed25519VerifyingKey,
260}
261
262impl Ed25519Key {
263    /// Generate a new Ed25519 key pair.
264    ///
265    /// This function generates a cryptographically secure key pair using
266    /// the provided random number generator.
267    ///
268    /// # Arguments
269    ///
270    /// * `rng` - A cryptographically secure random number generator
271    ///
272    /// # Returns
273    ///
274    /// A new `Ed25519Key` instance with a randomly generated key pair
275    ///
276    /// # Example
277    ///
278    /// ```rust
279    /// use rust_bottle::keys::Ed25519Key;
280    /// use rand::rngs::OsRng;
281    ///
282    /// let rng = &mut OsRng;
283    /// let key = Ed25519Key::generate(rng);
284    /// ```
285    pub fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
286        let signing_key = Ed25519SigningKey::generate(rng);
287        let verifying_key = signing_key.verifying_key();
288        Self {
289            signing_key,
290            verifying_key,
291        }
292    }
293
294    /// Get the public key bytes.
295    ///
296    /// Ed25519 public keys are 32 bytes.
297    ///
298    /// # Returns
299    ///
300    /// Public key bytes (32 bytes)
301    pub fn public_key_bytes(&self) -> Vec<u8> {
302        self.verifying_key.to_bytes().to_vec()
303    }
304
305    /// Get the private key bytes.
306    ///
307    /// Ed25519 private keys are 32 bytes. This is sensitive data and should
308    /// be handled securely.
309    ///
310    /// # Returns
311    ///
312    /// Private key bytes (32 bytes)
313    ///
314    /// # Security Warning
315    ///
316    /// Private keys are sensitive cryptographic material. They should be
317    /// stored securely and cleared from memory when no longer needed.
318    pub fn private_key_bytes(&self) -> Vec<u8> {
319        self.signing_key.to_bytes().to_vec()
320    }
321
322    /// Create an Ed25519 key pair from private key bytes.
323    ///
324    /// This function reconstructs a key pair from a previously saved private
325    /// key. The public key is automatically derived from the private key.
326    ///
327    /// # Arguments
328    ///
329    /// * `bytes` - Private key bytes (32 bytes)
330    ///
331    /// # Returns
332    ///
333    /// * `Ok(Ed25519Key)` - Reconstructed key pair
334    /// * `Err(BottleError::InvalidKeyType)` - If the key format is invalid
335    ///
336    /// # Example
337    ///
338    /// ```rust
339    /// use rust_bottle::keys::Ed25519Key;
340    /// use rand::rngs::OsRng;
341    ///
342    /// let rng = &mut OsRng;
343    /// let original = Ed25519Key::generate(rng);
344    /// let priv_bytes = original.private_key_bytes();
345    ///
346    /// let restored = Ed25519Key::from_private_key_bytes(&priv_bytes).unwrap();
347    /// assert_eq!(original.public_key_bytes(), restored.public_key_bytes());
348    /// ```
349    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
350        let signing_key = Ed25519SigningKey::from_bytes(
351            bytes.try_into().map_err(|_| BottleError::InvalidKeyType)?,
352        );
353        let verifying_key = signing_key.verifying_key();
354        Ok(Self {
355            signing_key,
356            verifying_key,
357        })
358    }
359}
360
361impl Sign for Ed25519Key {
362    /// Sign a message using Ed25519.
363    ///
364    /// Ed25519 signs messages directly without pre-hashing. The signature
365    /// is deterministic and always 64 bytes.
366    ///
367    /// # Arguments
368    ///
369    /// * `_rng` - Random number generator (not used for deterministic signing)
370    /// * `message` - The message to sign
371    ///
372    /// # Returns
373    ///
374    /// * `Ok(Vec<u8>)` - Signature bytes (64 bytes)
375    /// * `Err(BottleError::VerifyFailed)` - If signing fails
376    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
377        use ed25519_dalek::Signer;
378        let signature = self.signing_key.sign(message);
379        Ok(signature.to_bytes().to_vec())
380    }
381}
382
383impl Verify for Ed25519Key {
384    /// Verify an Ed25519 signature.
385    ///
386    /// The message is verified directly without pre-hashing. The signature
387    /// must be 64 bytes.
388    ///
389    /// # Arguments
390    ///
391    /// * `message` - The original message
392    /// * `signature` - The signature to verify (64 bytes)
393    ///
394    /// # Returns
395    ///
396    /// * `Ok(())` - Signature is valid
397    /// * `Err(BottleError::VerifyFailed)` - If signature verification fails
398    ///
399    /// # Example
400    ///
401    /// ```rust
402    /// use rust_bottle::keys::Ed25519Key;
403    /// use rust_bottle::signing::{Sign, Verify};
404    /// use rand::rngs::OsRng;
405    ///
406    /// let rng = &mut OsRng;
407    /// let key = Ed25519Key::generate(rng);
408    /// let message = b"Test message";
409    ///
410    /// let signature = key.sign(rng, message).unwrap();
411    /// assert!(key.verify(message, &signature).is_ok());
412    /// ```
413    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
414        use ed25519_dalek::Verifier;
415        let sig = Signature::from_bytes(
416            signature
417                .try_into()
418                .map_err(|_| BottleError::VerifyFailed)?,
419        );
420        self.verifying_key
421            .verify(message, &sig)
422            .map_err(|_| BottleError::VerifyFailed)?;
423        Ok(())
424    }
425}
426
427impl SignerKey for Ed25519Key {
428    /// Get the public key fingerprint (SHA-256 hash).
429    ///
430    /// The fingerprint is used to identify keys in keychains and IDCards.
431    ///
432    /// # Returns
433    ///
434    /// SHA-256 hash of the public key bytes
435    fn fingerprint(&self) -> Vec<u8> {
436        crate::hash::sha256(&self.public_key_bytes())
437    }
438
439    /// Get the public key bytes.
440    ///
441    /// # Returns
442    ///
443    /// Public key bytes (32 bytes)
444    fn public_key(&self) -> Vec<u8> {
445        self.public_key_bytes()
446    }
447}
448
449/// X25519 key pair for ECDH encryption.
450///
451/// X25519 is the Diffie-Hellman function over Curve25519. It is used for
452/// key exchange and encryption, not for signing. X25519 keys are 32 bytes
453/// for both private and public keys.
454///
455/// # Example
456///
457/// ```rust
458/// use rust_bottle::keys::X25519Key;
459/// use rand::rngs::OsRng;
460///
461/// let rng = &mut OsRng;
462/// let key = X25519Key::generate(rng);
463/// let pub_key = key.public_key_bytes();
464/// let priv_key = key.private_key_bytes();
465/// ```
466pub struct X25519Key {
467    secret: [u8; 32], // Store as bytes since StaticSecret doesn't exist in 2.0
468    public: x25519_dalek::PublicKey,
469}
470
471impl X25519Key {
472    /// Generate a new X25519 key pair.
473    ///
474    /// This function generates a cryptographically secure key pair using
475    /// the provided random number generator.
476    ///
477    /// # Arguments
478    ///
479    /// * `rng` - A random number generator
480    ///
481    /// # Returns
482    ///
483    /// A new `X25519Key` instance with a randomly generated key pair
484    ///
485    /// # Example
486    ///
487    /// ```rust
488    /// use rust_bottle::keys::X25519Key;
489    /// use rand::rngs::OsRng;
490    ///
491    /// let rng = &mut OsRng;
492    /// let key = X25519Key::generate(rng);
493    /// ```
494    pub fn generate<R: RngCore>(rng: &mut R) -> Self {
495        use x25519_dalek::StaticSecret;
496        // Generate random secret key
497        let mut secret_bytes = [0u8; 32];
498        rng.fill_bytes(&mut secret_bytes);
499        // Create StaticSecret and derive public key
500        let secret = StaticSecret::from(secret_bytes);
501        let public = x25519_dalek::PublicKey::from(&secret);
502        Self {
503            secret: secret_bytes,
504            public,
505        }
506    }
507
508    /// Get the public key bytes.
509    ///
510    /// X25519 public keys are 32 bytes.
511    ///
512    /// # Returns
513    ///
514    /// Public key bytes (32 bytes)
515    pub fn public_key_bytes(&self) -> Vec<u8> {
516        self.public.as_bytes().to_vec()
517    }
518
519    /// Get the private key bytes.
520    ///
521    /// X25519 private keys are 32 bytes. This is sensitive data and should
522    /// be handled securely.
523    ///
524    /// # Returns
525    ///
526    /// Private key bytes (32 bytes)
527    ///
528    /// # Security Warning
529    ///
530    /// Private keys are sensitive cryptographic material. They should be
531    /// stored securely and cleared from memory when no longer needed.
532    pub fn private_key_bytes(&self) -> Vec<u8> {
533        self.secret.to_vec()
534    }
535
536    /// Create an X25519 key pair from private key bytes.
537    ///
538    /// This function reconstructs a key pair from a previously saved private
539    /// key. The public key is automatically derived from the private key.
540    ///
541    /// # Arguments
542    ///
543    /// * `bytes` - Private key bytes (32 bytes)
544    ///
545    /// # Returns
546    ///
547    /// * `Ok(X25519Key)` - Reconstructed key pair
548    /// * `Err(BottleError::InvalidKeyType)` - If the key format is invalid
549    ///
550    /// # Example
551    ///
552    /// ```rust
553    /// use rust_bottle::keys::X25519Key;
554    /// use rand::rngs::OsRng;
555    ///
556    /// let rng = &mut OsRng;
557    /// let original = X25519Key::generate(rng);
558    /// let priv_bytes = original.private_key_bytes();
559    ///
560    /// let restored = X25519Key::from_private_key_bytes(&priv_bytes).unwrap();
561    /// assert_eq!(original.public_key_bytes(), restored.public_key_bytes());
562    /// ```
563    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
564        use x25519_dalek::StaticSecret;
565        let secret_bytes: [u8; 32] = bytes.try_into().map_err(|_| BottleError::InvalidKeyType)?;
566        // Create StaticSecret and derive public key
567        let secret = StaticSecret::from(secret_bytes);
568        let public = x25519_dalek::PublicKey::from(&secret);
569        Ok(Self {
570            secret: secret_bytes,
571            public,
572        })
573    }
574}
575
576/// RSA key pair for encryption and digital signatures.
577///
578/// RSA (Rivest-Shamir-Adleman) is a widely-used public-key cryptosystem. This
579/// implementation supports RSA-2048 and RSA-4096 key sizes. RSA can be used for
580/// both encryption/decryption and signing/verification.
581///
582/// # Security Note
583///
584/// RSA-2048 provides 112-bit security, while RSA-4096 provides 192-bit security.
585/// For new applications, consider using ECDSA or Ed25519 for signatures, and
586/// X25519 or post-quantum algorithms for encryption.
587///
588/// # Example
589///
590/// ```rust
591/// use rust_bottle::keys::RsaKey;
592/// use rand::rngs::OsRng;
593///
594/// let rng = &mut OsRng;
595/// let key = RsaKey::generate(rng, 2048).unwrap();
596/// let pub_key = key.public_key_bytes();
597/// let priv_key = key.private_key_bytes();
598/// ```
599pub struct RsaKey {
600    private_key: RsaPrivateKey,
601    public_key: RsaPublicKey,
602    key_size: usize,
603}
604
605impl RsaKey {
606    /// Generate a new RSA key pair.
607    ///
608    /// This function generates a cryptographically secure RSA key pair with
609    /// the specified key size. Common key sizes are 2048 (112-bit security)
610    /// and 4096 (192-bit security).
611    ///
612    /// # Arguments
613    ///
614    /// * `rng` - A cryptographically secure random number generator
615    /// * `bits` - Key size in bits (must be a multiple of 8 and at least 512)
616    ///
617    /// # Returns
618    ///
619    /// * `Ok(RsaKey)` - A new RSA key pair
620    /// * `Err(BottleError::InvalidKeyType)` - If key size is invalid
621    ///
622    /// # Example
623    ///
624    /// ```rust
625    /// use rust_bottle::keys::RsaKey;
626    /// use rand::rngs::OsRng;
627    ///
628    /// let rng = &mut OsRng;
629    /// let key = RsaKey::generate(rng, 2048).unwrap();
630    /// ```
631    pub fn generate<R: RngCore + CryptoRng>(rng: &mut R, bits: usize) -> Result<Self> {
632        if bits < 512 || !bits.is_multiple_of(8) {
633            return Err(BottleError::InvalidKeyType);
634        }
635        let private_key = RsaPrivateKey::new(rng, bits).map_err(|_| BottleError::InvalidKeyType)?;
636        let public_key = RsaPublicKey::from(&private_key);
637        Ok(Self {
638            private_key,
639            public_key,
640            key_size: bits / 8,
641        })
642    }
643
644    /// Get the public key bytes.
645    ///
646    /// The public key is returned as raw bytes (n and e components).
647    /// For standard formats, use PKCS#8 serialization via the pkix module.
648    ///
649    /// # Returns
650    ///
651    /// Public key bytes (serialized n and e)
652    pub fn public_key_bytes(&self) -> Vec<u8> {
653        // Note: For proper PKCS#8/PKIX serialization, use the pkix module
654        // This is a placeholder that returns the key size as a marker
655        // TODO: Implement proper PKCS#8 serialization via pkix module
656        vec![]
657    }
658
659    /// Get the private key bytes.
660    ///
661    /// The private key is returned as raw bytes. This is sensitive
662    /// data and should be handled securely.
663    /// For standard formats, use PKCS#8 serialization via the pkix module.
664    ///
665    /// # Returns
666    ///
667    /// Private key bytes (serialized key components)
668    ///
669    /// # Security Warning
670    ///
671    /// Private keys are sensitive cryptographic material. They should be
672    /// stored securely and cleared from memory when no longer needed.
673    pub fn private_key_bytes(&self) -> Vec<u8> {
674        // Note: For proper PKCS#8 serialization, use the pkix module
675        // This is a placeholder
676        // TODO: Implement proper PKCS#8 serialization via pkix module
677        vec![]
678    }
679
680    /// Create an RSA key pair from private key bytes.
681    ///
682    /// This function reconstructs a key pair from a previously saved private
683    /// key in PKCS#1 DER format. The public key is automatically derived.
684    ///
685    /// # Arguments
686    ///
687    /// * `bytes` - Private key bytes in PKCS#1 DER format
688    ///
689    /// # Returns
690    ///
691    /// * `Ok(RsaKey)` - Reconstructed key pair
692    /// * `Err(BottleError::InvalidKeyType)` - If the key format is invalid
693    ///
694    /// # Example
695    ///
696    /// ```rust,no_run
697    /// use rust_bottle::keys::RsaKey;
698    /// use rand::rngs::OsRng;
699    ///
700    /// let rng = &mut OsRng;
701    /// let original = RsaKey::generate(rng, 2048).unwrap();
702    /// // Note: from_private_key_bytes is a placeholder and not yet implemented
703    /// // For now, use PKCS#8 serialization via the pkix module for key persistence
704    /// ```
705    pub fn from_private_key_bytes(_bytes: &[u8]) -> Result<Self> {
706        // Note: For proper PKCS#8 deserialization, use the pkix module
707        // This is a placeholder
708        // TODO: Implement proper PKCS#8 deserialization via pkix module
709        Err(BottleError::InvalidKeyType)
710    }
711
712    /// Encrypt data using RSA-OAEP.
713    ///
714    /// This function encrypts data using RSA-OAEP (Optimal Asymmetric Encryption
715    /// Padding) with SHA-256. OAEP is more secure than PKCS#1 v1.5 padding.
716    ///
717    /// # Arguments
718    ///
719    /// * `rng` - A random number generator
720    /// * `data` - The data to encrypt (must be smaller than key size - 42 bytes)
721    ///
722    /// # Returns
723    ///
724    /// * `Ok(Vec<u8>)` - Encrypted ciphertext
725    /// * `Err(BottleError::Encryption)` - If encryption fails
726    pub fn encrypt<R: RngCore + CryptoRng>(&self, rng: &mut R, data: &[u8]) -> Result<Vec<u8>> {
727        use rsa::Oaep;
728        // OAEP with SHA-256
729        let padding = Oaep::new::<Sha256>();
730        self.public_key
731            .encrypt(rng, padding, data)
732            .map_err(|e| BottleError::Encryption(format!("RSA encryption failed: {}", e)))
733    }
734
735    /// Decrypt data using RSA-OAEP.
736    ///
737    /// This function decrypts data encrypted with RSA-OAEP.
738    ///
739    /// # Arguments
740    ///
741    /// * `ciphertext` - The encrypted data
742    ///
743    /// # Returns
744    ///
745    /// * `Ok(Vec<u8>)` - Decrypted plaintext
746    /// * `Err(BottleError::Decryption)` - If decryption fails
747    pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>> {
748        use rsa::Oaep;
749        // OAEP with SHA-256
750        let padding = Oaep::new::<Sha256>();
751        self.private_key
752            .decrypt(padding, ciphertext)
753            .map_err(|e| BottleError::Decryption(format!("RSA decryption failed: {}", e)))
754    }
755
756    /// Get the public key reference (for encryption operations).
757    pub fn public_key(&self) -> &RsaPublicKey {
758        &self.public_key
759    }
760
761    /// Get the private key reference (for decryption operations).
762    pub fn private_key(&self) -> &RsaPrivateKey {
763        &self.private_key
764    }
765
766    /// Get the key size in bytes.
767    pub fn key_size(&self) -> usize {
768        self.key_size
769    }
770}
771
772impl Sign for RsaKey {
773    /// Sign a message using RSA-PKCS#1 v1.5 with SHA-256.
774    ///
775    /// The message is hashed with SHA-256 before signing. This is the standard
776    /// approach for RSA signatures.
777    ///
778    /// # Arguments
779    ///
780    /// * `rng` - A random number generator (not used for deterministic signing)
781    /// * `message` - The message to sign
782    ///
783    /// # Returns
784    ///
785    /// * `Ok(Vec<u8>)` - Signature bytes
786    /// * `Err(BottleError::VerifyFailed)` - If signing fails
787    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
788        let mut hasher = Sha256::new();
789        hasher.update(message);
790        let hashed = hasher.finalize();
791
792        self.private_key
793            .sign(Pkcs1v15Sign::new::<Sha256>(), &hashed)
794            .map_err(|_| BottleError::VerifyFailed)
795    }
796}
797
798impl Verify for RsaKey {
799    /// Verify an RSA-PKCS#1 v1.5 signature with SHA-256.
800    ///
801    /// The message is hashed with SHA-256 before verification.
802    ///
803    /// # Arguments
804    ///
805    /// * `message` - The original message
806    /// * `signature` - The signature to verify
807    ///
808    /// # Returns
809    ///
810    /// * `Ok(())` - Signature is valid
811    /// * `Err(BottleError::VerifyFailed)` - If signature verification fails
812    ///
813    /// # Example
814    ///
815    /// ```rust
816    /// use rust_bottle::keys::RsaKey;
817    /// use rust_bottle::signing::{Sign, Verify};
818    /// use rand::rngs::OsRng;
819    ///
820    /// let rng = &mut OsRng;
821    /// let key = RsaKey::generate(rng, 2048).unwrap();
822    /// let message = b"Test message";
823    ///
824    /// let signature = key.sign(rng, message).unwrap();
825    /// assert!(key.verify(message, &signature).is_ok());
826    /// ```
827    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
828        let mut hasher = Sha256::new();
829        hasher.update(message);
830        let hashed = hasher.finalize();
831
832        self.public_key
833            .verify(Pkcs1v15Sign::new::<Sha256>(), &hashed, signature)
834            .map_err(|_| BottleError::VerifyFailed)?;
835        Ok(())
836    }
837}
838
839impl SignerKey for RsaKey {
840    /// Get the public key fingerprint (SHA-256 hash).
841    ///
842    /// The fingerprint is used to identify keys in keychains and IDCards.
843    ///
844    /// # Returns
845    ///
846    /// SHA-256 hash of the public key bytes
847    fn fingerprint(&self) -> Vec<u8> {
848        crate::hash::sha256(&self.public_key_bytes())
849    }
850
851    /// Get the public key bytes.
852    ///
853    /// # Returns
854    ///
855    /// Public key bytes in PKCS#1 DER format
856    fn public_key(&self) -> Vec<u8> {
857        self.public_key_bytes()
858    }
859}
860
861// Post-Quantum Cryptography Key Types
862
863#[cfg(feature = "ml-kem")]
864/// ML-KEM-768 key pair for post-quantum encryption.
865///
866/// ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism) is a post-quantum
867/// encryption algorithm standardized by NIST. ML-KEM-768 provides 192-bit
868/// security level.
869///
870/// # Example
871///
872/// ```rust
873/// #[cfg(feature = "post-quantum")]
874/// use rust_bottle::keys::MlKem768Key;
875/// use rand::rngs::OsRng;
876///
877/// #[cfg(feature = "post-quantum")]
878/// {
879///     let rng = &mut OsRng;
880///     let key = MlKem768Key::generate(rng);
881///     let pub_key = key.public_key_bytes();
882///     let priv_key = key.private_key_bytes();
883/// }
884/// ```
885pub struct MlKem768Key {
886    decaps_key: <Kem<MlKem768Params> as KemCore>::DecapsulationKey,
887    encaps_key: <Kem<MlKem768Params> as KemCore>::EncapsulationKey,
888}
889
890#[cfg(feature = "ml-kem")]
891impl MlKem768Key {
892    /// Generate a new ML-KEM-768 key pair.
893    ///
894    /// # Arguments
895    ///
896    /// * `rng` - A cryptographically secure random number generator
897    ///
898    /// # Returns
899    ///
900    /// A new `MlKem768Key` instance
901    pub fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
902        // ml-kem uses rand_core 0.9, but rand 0.8 uses rand_core 0.6
903        // Create an adapter that implements rand_core 0.9 traits
904        use rand_core_09::{CryptoRng as CryptoRng09, RngCore as RngCore09};
905
906        struct RngAdapter<'a, R: RngCore + CryptoRng>(&'a mut R);
907        impl<'a, R: RngCore + CryptoRng> RngCore09 for RngAdapter<'a, R> {
908            fn next_u32(&mut self) -> u32 {
909                self.0.next_u32()
910            }
911            fn next_u64(&mut self) -> u64 {
912                self.0.next_u64()
913            }
914            fn fill_bytes(&mut self, dest: &mut [u8]) {
915                self.0.fill_bytes(dest)
916            }
917            // try_fill_bytes has a default implementation that calls fill_bytes, so we don't need to implement it
918        }
919        impl<'a, R: RngCore + CryptoRng> CryptoRng09 for RngAdapter<'a, R> {}
920
921        let mut adapter = RngAdapter(rng);
922        let (dk, ek) = <Kem<MlKem768Params> as KemCore>::generate(&mut adapter);
923        Self {
924            decaps_key: dk,
925            encaps_key: ek,
926        }
927    }
928
929    /// Get the public key bytes.
930    ///
931    /// # Returns
932    ///
933    /// Public key bytes (1184 bytes for ML-KEM-768)
934    pub fn public_key_bytes(&self) -> Vec<u8> {
935        self.encaps_key.as_bytes().to_vec()
936    }
937
938    /// Get the private key bytes.
939    ///
940    /// # Returns
941    ///
942    /// Private key bytes (3584 bytes for ML-KEM-768: 2400 bytes decapsulation key + 1184 bytes encapsulation key)
943    ///
944    /// # Security Warning
945    ///
946    /// Private keys are sensitive cryptographic material.
947    pub fn private_key_bytes(&self) -> Vec<u8> {
948        let mut result = self.decaps_key.as_bytes().to_vec();
949        result.extend_from_slice(&self.encaps_key.as_bytes());
950        result
951    }
952
953    /// Create from private key bytes.
954    ///
955    /// # Arguments
956    ///
957    /// * `bytes` - Private key bytes (3584 bytes: 2400 bytes decapsulation key + 1184 bytes encapsulation key)
958    ///
959    /// # Returns
960    ///
961    /// * `Ok(MlKem768Key)` - Reconstructed key pair
962    /// * `Err(BottleError::InvalidKeyType)` - If the key format is invalid
963    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
964        const DK_SIZE: usize = 2400;
965        const PK_SIZE: usize = 1184;
966        const TOTAL_SIZE: usize = DK_SIZE + PK_SIZE;
967        if bytes.len() != TOTAL_SIZE {
968            return Err(BottleError::InvalidKeyType);
969        }
970        // Extract decapsulation key (first 2400 bytes)
971        let decaps_key_bytes: [u8; DK_SIZE] = bytes[..DK_SIZE]
972            .try_into()
973            .map_err(|_| BottleError::InvalidKeyType)?;
974        let decaps_key = <Kem<MlKem768Params> as KemCore>::DecapsulationKey::from_bytes(
975            (&decaps_key_bytes).into(),
976        );
977        // Extract encapsulation key (last 1184 bytes)
978        let encaps_key_bytes: [u8; PK_SIZE] = bytes[DK_SIZE..]
979            .try_into()
980            .map_err(|_| BottleError::InvalidKeyType)?;
981        let encaps_key = <Kem<MlKem768Params> as KemCore>::EncapsulationKey::from_bytes(
982            (&encaps_key_bytes).into(),
983        );
984        Ok(Self {
985            decaps_key,
986            encaps_key,
987        })
988    }
989
990    /// Get the encapsulation key reference (for encryption operations).
991    pub fn encapsulation_key(&self) -> &<Kem<MlKem768Params> as KemCore>::EncapsulationKey {
992        &self.encaps_key
993    }
994
995    /// Get the decapsulation key reference (for decryption operations).
996    pub fn decapsulation_key(&self) -> &<Kem<MlKem768Params> as KemCore>::DecapsulationKey {
997        &self.decaps_key
998    }
999}
1000
1001// Note: ML-KEM keys are for encryption, not signing, so they don't implement SignerKey
1002
1003#[cfg(feature = "ml-kem")]
1004/// ML-KEM-1024 key pair for post-quantum encryption.
1005///
1006/// ML-KEM-1024 provides 256-bit security level.
1007pub struct MlKem1024Key {
1008    decaps_key: <Kem<MlKem1024Params> as KemCore>::DecapsulationKey,
1009    encaps_key: <Kem<MlKem1024Params> as KemCore>::EncapsulationKey,
1010}
1011
1012#[cfg(feature = "ml-kem")]
1013impl MlKem1024Key {
1014    /// Generate a new ML-KEM-1024 key pair.
1015    pub fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
1016        // ml-kem uses rand_core 0.9, but rand 0.8 uses rand_core 0.6
1017        // Create an adapter that implements rand_core 0.9 traits
1018        use rand_core_09::{CryptoRng as CryptoRng09, RngCore as RngCore09};
1019
1020        struct RngAdapter<'a, R: RngCore + CryptoRng>(&'a mut R);
1021        impl<'a, R: RngCore + CryptoRng> RngCore09 for RngAdapter<'a, R> {
1022            fn next_u32(&mut self) -> u32 {
1023                self.0.next_u32()
1024            }
1025            fn next_u64(&mut self) -> u64 {
1026                self.0.next_u64()
1027            }
1028            fn fill_bytes(&mut self, dest: &mut [u8]) {
1029                self.0.fill_bytes(dest)
1030            }
1031            // try_fill_bytes has a default implementation that calls fill_bytes, so we don't need to implement it
1032        }
1033        impl<'a, R: RngCore + CryptoRng> CryptoRng09 for RngAdapter<'a, R> {}
1034
1035        let mut adapter = RngAdapter(rng);
1036        let (dk, ek) = <Kem<MlKem1024Params> as KemCore>::generate(&mut adapter);
1037        Self {
1038            decaps_key: dk,
1039            encaps_key: ek,
1040        }
1041    }
1042
1043    /// Get the public key bytes.
1044    pub fn public_key_bytes(&self) -> Vec<u8> {
1045        self.encaps_key.as_bytes().to_vec()
1046    }
1047
1048    /// Get the private key bytes.
1049    ///
1050    /// # Returns
1051    ///
1052    /// Private key bytes (4736 bytes for ML-KEM-1024: 3168 bytes decapsulation key + 1568 bytes encapsulation key)
1053    pub fn private_key_bytes(&self) -> Vec<u8> {
1054        let mut result = self.decaps_key.as_bytes().to_vec();
1055        result.extend_from_slice(&self.encaps_key.as_bytes());
1056        result
1057    }
1058
1059    /// Create from private key bytes.
1060    ///
1061    /// # Arguments
1062    ///
1063    /// * `bytes` - Private key bytes (4736 bytes: 3168 bytes decapsulation key + 1568 bytes encapsulation key)
1064    ///
1065    /// # Returns
1066    ///
1067    /// * `Ok(MlKem1024Key)` - Reconstructed key pair
1068    /// * `Err(BottleError::InvalidKeyType)` - If the key format is invalid
1069    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1070        const DK_SIZE: usize = 3168;
1071        const PK_SIZE: usize = 1568;
1072        const TOTAL_SIZE: usize = DK_SIZE + PK_SIZE;
1073        if bytes.len() != TOTAL_SIZE {
1074            return Err(BottleError::InvalidKeyType);
1075        }
1076        // Extract decapsulation key (first 3168 bytes)
1077        let decaps_key_bytes: [u8; DK_SIZE] = bytes[..DK_SIZE]
1078            .try_into()
1079            .map_err(|_| BottleError::InvalidKeyType)?;
1080        let decaps_key = <Kem<MlKem1024Params> as KemCore>::DecapsulationKey::from_bytes(
1081            (&decaps_key_bytes).into(),
1082        );
1083        // Extract encapsulation key (last 1568 bytes)
1084        let encaps_key_bytes: [u8; PK_SIZE] = bytes[DK_SIZE..]
1085            .try_into()
1086            .map_err(|_| BottleError::InvalidKeyType)?;
1087        let encaps_key = <Kem<MlKem1024Params> as KemCore>::EncapsulationKey::from_bytes(
1088            (&encaps_key_bytes).into(),
1089        );
1090        Ok(Self {
1091            decaps_key,
1092            encaps_key,
1093        })
1094    }
1095
1096    /// Get the encapsulation key reference (for encryption operations).
1097    pub fn encapsulation_key(&self) -> &<Kem<MlKem1024Params> as KemCore>::EncapsulationKey {
1098        &self.encaps_key
1099    }
1100
1101    /// Get the decapsulation key reference (for decryption operations).
1102    pub fn decapsulation_key(&self) -> &<Kem<MlKem1024Params> as KemCore>::DecapsulationKey {
1103        &self.decaps_key
1104    }
1105}
1106
1107// Note: ML-KEM keys are for encryption, not signing, so they don't implement SignerKey
1108
1109#[cfg(feature = "post-quantum")]
1110/// ML-DSA-44 key pair for post-quantum signatures.
1111///
1112/// ML-DSA (Module-Lattice-Based Digital Signature Algorithm) is a post-quantum
1113/// signature algorithm standardized by NIST. ML-DSA-44 provides 128-bit security level.
1114/// This uses dilithium2 from the pqcrypto-dilithium crate.
1115pub struct MlDsa44Key {
1116    public_key: pqcrypto_dilithium::dilithium2::PublicKey,
1117    secret_key: pqcrypto_dilithium::dilithium2::SecretKey,
1118}
1119
1120#[cfg(feature = "post-quantum")]
1121impl MlDsa44Key {
1122    /// Generate a new ML-DSA-44 key pair.
1123    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1124        let (public_key, secret_key) = pqcrypto_dilithium::dilithium2::keypair();
1125        Self {
1126            public_key,
1127            secret_key,
1128        }
1129    }
1130
1131    /// Get the public key bytes.
1132    pub fn public_key_bytes(&self) -> Vec<u8> {
1133        self.public_key.as_bytes().to_vec()
1134    }
1135
1136    /// Get the private key bytes.
1137    pub fn private_key_bytes(&self) -> Vec<u8> {
1138        self.secret_key.as_bytes().to_vec()
1139    }
1140
1141    /// Create from private key bytes.
1142    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1143        let _secret_key = pqcrypto_dilithium::dilithium2::SecretKey::from_bytes(bytes)
1144            .map_err(|_| BottleError::InvalidKeyType)?;
1145        // Generate public key from secret key by creating a new keypair
1146        // Note: pqcrypto-dilithium doesn't have a direct public_key_from_secret_key function
1147        // So we need to derive it by creating a temporary keypair
1148        let (_public_key, _) = pqcrypto_dilithium::dilithium2::keypair();
1149        // Actually, we can't derive public key from secret key directly in this API
1150        // So we'll need to store both or use a different approach
1151        // For now, let's require both keys to be provided
1152        Err(BottleError::InvalidKeyType)
1153    }
1154}
1155
1156#[cfg(feature = "post-quantum")]
1157impl Sign for MlDsa44Key {
1158    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1159        let detached_sig = pqcrypto_dilithium::dilithium2::detached_sign(message, &self.secret_key);
1160        Ok(
1161            <pqcrypto_dilithium::dilithium2::DetachedSignature as PqcDetachedSignature>::as_bytes(
1162                &detached_sig,
1163            )
1164            .to_vec(),
1165        )
1166    }
1167}
1168
1169#[cfg(feature = "post-quantum")]
1170impl Verify for MlDsa44Key {
1171    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1172        let detached_sig = <pqcrypto_dilithium::dilithium2::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1173            .map_err(|_| BottleError::VerifyFailed)?;
1174        pqcrypto_dilithium::dilithium2::verify_detached_signature(
1175            &detached_sig,
1176            message,
1177            &self.public_key,
1178        )
1179        .map_err(|_| BottleError::VerifyFailed)?;
1180        Ok(())
1181    }
1182}
1183
1184#[cfg(feature = "post-quantum")]
1185impl SignerKey for MlDsa44Key {
1186    fn fingerprint(&self) -> Vec<u8> {
1187        crate::hash::sha256(&self.public_key_bytes())
1188    }
1189
1190    fn public_key(&self) -> Vec<u8> {
1191        self.public_key_bytes()
1192    }
1193}
1194
1195#[cfg(feature = "post-quantum")]
1196/// ML-DSA-65 key pair for post-quantum signatures.
1197///
1198/// ML-DSA-65 provides 192-bit security level.
1199/// This uses dilithium3 from the pqcrypto-dilithium crate.
1200pub struct MlDsa65Key {
1201    public_key: pqcrypto_dilithium::dilithium3::PublicKey,
1202    secret_key: pqcrypto_dilithium::dilithium3::SecretKey,
1203}
1204
1205#[cfg(feature = "post-quantum")]
1206impl MlDsa65Key {
1207    /// Generate a new ML-DSA-65 key pair.
1208    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1209        let (public_key, secret_key) = pqcrypto_dilithium::dilithium3::keypair();
1210        Self {
1211            public_key,
1212            secret_key,
1213        }
1214    }
1215
1216    /// Get the public key bytes.
1217    pub fn public_key_bytes(&self) -> Vec<u8> {
1218        <pqcrypto_dilithium::dilithium3::PublicKey as PqcPublicKey>::as_bytes(&self.public_key)
1219            .to_vec()
1220    }
1221
1222    /// Get the private key bytes.
1223    pub fn private_key_bytes(&self) -> Vec<u8> {
1224        <pqcrypto_dilithium::dilithium3::SecretKey as PqcSecretKey>::as_bytes(&self.secret_key)
1225            .to_vec()
1226    }
1227
1228    /// Create from private key bytes.
1229    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1230        let _secret_key =
1231            <pqcrypto_dilithium::dilithium3::SecretKey as PqcSecretKey>::from_bytes(bytes)
1232                .map_err(|_| BottleError::InvalidKeyType)?;
1233        // Cannot derive public key from secret key in this API
1234        Err(BottleError::InvalidKeyType)
1235    }
1236}
1237
1238#[cfg(feature = "post-quantum")]
1239impl Sign for MlDsa65Key {
1240    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1241        let detached_sig = pqcrypto_dilithium::dilithium3::detached_sign(message, &self.secret_key);
1242        Ok(
1243            <pqcrypto_dilithium::dilithium3::DetachedSignature as PqcDetachedSignature>::as_bytes(
1244                &detached_sig,
1245            )
1246            .to_vec(),
1247        )
1248    }
1249}
1250
1251#[cfg(feature = "post-quantum")]
1252impl Verify for MlDsa65Key {
1253    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1254        let detached_sig = <pqcrypto_dilithium::dilithium3::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1255            .map_err(|_| BottleError::VerifyFailed)?;
1256        pqcrypto_dilithium::dilithium3::verify_detached_signature(
1257            &detached_sig,
1258            message,
1259            &self.public_key,
1260        )
1261        .map_err(|_| BottleError::VerifyFailed)?;
1262        Ok(())
1263    }
1264}
1265
1266#[cfg(feature = "post-quantum")]
1267impl SignerKey for MlDsa65Key {
1268    fn fingerprint(&self) -> Vec<u8> {
1269        crate::hash::sha256(&self.public_key_bytes())
1270    }
1271
1272    fn public_key(&self) -> Vec<u8> {
1273        self.public_key_bytes()
1274    }
1275}
1276
1277#[cfg(feature = "post-quantum")]
1278/// ML-DSA-87 key pair for post-quantum signatures.
1279///
1280/// ML-DSA-87 provides 256-bit security level.
1281pub struct MlDsa87Key {
1282    public_key: pqcrypto_dilithium::dilithium5::PublicKey,
1283    secret_key: pqcrypto_dilithium::dilithium5::SecretKey,
1284}
1285
1286#[cfg(feature = "post-quantum")]
1287impl MlDsa87Key {
1288    /// Generate a new ML-DSA-87 key pair.
1289    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1290        let (public_key, secret_key) = pqcrypto_dilithium::dilithium5::keypair();
1291        Self {
1292            public_key,
1293            secret_key,
1294        }
1295    }
1296
1297    /// Get the public key bytes.
1298    pub fn public_key_bytes(&self) -> Vec<u8> {
1299        <pqcrypto_dilithium::dilithium5::PublicKey as PqcPublicKey>::as_bytes(&self.public_key)
1300            .to_vec()
1301    }
1302
1303    /// Get the private key bytes.
1304    pub fn private_key_bytes(&self) -> Vec<u8> {
1305        <pqcrypto_dilithium::dilithium5::SecretKey as PqcSecretKey>::as_bytes(&self.secret_key)
1306            .to_vec()
1307    }
1308
1309    /// Create from private key bytes.
1310    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1311        let _secret_key =
1312            <pqcrypto_dilithium::dilithium5::SecretKey as PqcSecretKey>::from_bytes(bytes)
1313                .map_err(|_| BottleError::InvalidKeyType)?;
1314        // Cannot derive public key from secret key in this API
1315        Err(BottleError::InvalidKeyType)
1316    }
1317}
1318
1319#[cfg(feature = "post-quantum")]
1320impl Sign for MlDsa87Key {
1321    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1322        let detached_sig = pqcrypto_dilithium::dilithium5::detached_sign(message, &self.secret_key);
1323        Ok(
1324            <pqcrypto_dilithium::dilithium5::DetachedSignature as PqcDetachedSignature>::as_bytes(
1325                &detached_sig,
1326            )
1327            .to_vec(),
1328        )
1329    }
1330}
1331
1332#[cfg(feature = "post-quantum")]
1333impl Verify for MlDsa87Key {
1334    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1335        let detached_sig = <pqcrypto_dilithium::dilithium5::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1336            .map_err(|_| BottleError::VerifyFailed)?;
1337        pqcrypto_dilithium::dilithium5::verify_detached_signature(
1338            &detached_sig,
1339            message,
1340            &self.public_key,
1341        )
1342        .map_err(|_| BottleError::VerifyFailed)?;
1343        Ok(())
1344    }
1345}
1346
1347#[cfg(feature = "post-quantum")]
1348impl SignerKey for MlDsa87Key {
1349    fn fingerprint(&self) -> Vec<u8> {
1350        crate::hash::sha256(&self.public_key_bytes())
1351    }
1352
1353    fn public_key(&self) -> Vec<u8> {
1354        self.public_key_bytes()
1355    }
1356}
1357
1358#[cfg(feature = "post-quantum")]
1359/// SLH-DSA-128s key pair for post-quantum hash-based signatures.
1360///
1361/// SLH-DSA (Stateless Hash-Based Digital Signature Algorithm) is a post-quantum
1362/// signature algorithm based on hash functions. SLH-DSA-128s provides 128-bit security.
1363pub struct SlhDsa128sKey {
1364    public_key: pqcrypto_sphincsplus::sphincsshake256128srobust::PublicKey,
1365    secret_key: pqcrypto_sphincsplus::sphincsshake256128srobust::SecretKey,
1366}
1367
1368#[cfg(feature = "post-quantum")]
1369impl SlhDsa128sKey {
1370    /// Generate a new SLH-DSA-128s key pair.
1371    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1372        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincsshake256128srobust::keypair();
1373        Self {
1374            public_key,
1375            secret_key,
1376        }
1377    }
1378
1379    /// Get the public key bytes.
1380    pub fn public_key_bytes(&self) -> Vec<u8> {
1381        <pqcrypto_sphincsplus::sphincsshake256128srobust::PublicKey as PqcPublicKey>::as_bytes(
1382            &self.public_key,
1383        )
1384        .to_vec()
1385    }
1386
1387    /// Get the private key bytes.
1388    pub fn private_key_bytes(&self) -> Vec<u8> {
1389        <pqcrypto_sphincsplus::sphincsshake256128srobust::SecretKey as PqcSecretKey>::as_bytes(
1390            &self.secret_key,
1391        )
1392        .to_vec()
1393    }
1394
1395    /// Create from private key bytes.
1396    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1397        let _secret_key = <pqcrypto_sphincsplus::sphincsshake256128srobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1398            .map_err(|_| BottleError::InvalidKeyType)?;
1399        // Cannot derive public key from secret key in this API
1400        Err(BottleError::InvalidKeyType)
1401    }
1402}
1403
1404#[cfg(feature = "post-quantum")]
1405impl Sign for SlhDsa128sKey {
1406    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1407        let detached_sig = pqcrypto_sphincsplus::sphincsshake256128srobust::detached_sign(
1408            message,
1409            &self.secret_key,
1410        );
1411        Ok(<pqcrypto_sphincsplus::sphincsshake256128srobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1412    }
1413}
1414
1415#[cfg(feature = "post-quantum")]
1416impl Verify for SlhDsa128sKey {
1417    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1418        let detached_sig = <pqcrypto_sphincsplus::sphincsshake256128srobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1419            .map_err(|_| BottleError::VerifyFailed)?;
1420        pqcrypto_sphincsplus::sphincsshake256128srobust::verify_detached_signature(
1421            &detached_sig,
1422            message,
1423            &self.public_key,
1424        )
1425        .map_err(|_| BottleError::VerifyFailed)?;
1426        Ok(())
1427    }
1428}
1429
1430#[cfg(feature = "post-quantum")]
1431impl SignerKey for SlhDsa128sKey {
1432    fn fingerprint(&self) -> Vec<u8> {
1433        crate::hash::sha256(&self.public_key_bytes())
1434    }
1435
1436    fn public_key(&self) -> Vec<u8> {
1437        self.public_key_bytes()
1438    }
1439}
1440
1441#[cfg(feature = "post-quantum")]
1442/// SLH-DSA-192s key pair for post-quantum hash-based signatures.
1443///
1444/// SLH-DSA-192s provides 192-bit security.
1445pub struct SlhDsa192sKey {
1446    public_key: pqcrypto_sphincsplus::sphincsshake256192srobust::PublicKey,
1447    secret_key: pqcrypto_sphincsplus::sphincsshake256192srobust::SecretKey,
1448}
1449
1450#[cfg(feature = "post-quantum")]
1451impl SlhDsa192sKey {
1452    /// Generate a new SLH-DSA-192s key pair.
1453    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1454        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincsshake256192srobust::keypair();
1455        Self {
1456            public_key,
1457            secret_key,
1458        }
1459    }
1460
1461    /// Get the public key bytes.
1462    pub fn public_key_bytes(&self) -> Vec<u8> {
1463        <pqcrypto_sphincsplus::sphincsshake256192srobust::PublicKey as PqcPublicKey>::as_bytes(
1464            &self.public_key,
1465        )
1466        .to_vec()
1467    }
1468
1469    /// Get the private key bytes.
1470    pub fn private_key_bytes(&self) -> Vec<u8> {
1471        <pqcrypto_sphincsplus::sphincsshake256192srobust::SecretKey as PqcSecretKey>::as_bytes(
1472            &self.secret_key,
1473        )
1474        .to_vec()
1475    }
1476
1477    /// Create from private key bytes.
1478    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1479        let _secret_key = <pqcrypto_sphincsplus::sphincsshake256192srobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1480            .map_err(|_| BottleError::InvalidKeyType)?;
1481        // Cannot derive public key from secret key in this API
1482        Err(BottleError::InvalidKeyType)
1483    }
1484}
1485
1486#[cfg(feature = "post-quantum")]
1487impl Sign for SlhDsa192sKey {
1488    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1489        let detached_sig = pqcrypto_sphincsplus::sphincsshake256192srobust::detached_sign(
1490            message,
1491            &self.secret_key,
1492        );
1493        Ok(<pqcrypto_sphincsplus::sphincsshake256192srobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1494    }
1495}
1496
1497#[cfg(feature = "post-quantum")]
1498impl Verify for SlhDsa192sKey {
1499    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1500        let detached_sig = <pqcrypto_sphincsplus::sphincsshake256192srobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1501            .map_err(|_| BottleError::VerifyFailed)?;
1502        pqcrypto_sphincsplus::sphincsshake256192srobust::verify_detached_signature(
1503            &detached_sig,
1504            message,
1505            &self.public_key,
1506        )
1507        .map_err(|_| BottleError::VerifyFailed)?;
1508        Ok(())
1509    }
1510}
1511
1512#[cfg(feature = "post-quantum")]
1513impl SignerKey for SlhDsa192sKey {
1514    fn fingerprint(&self) -> Vec<u8> {
1515        crate::hash::sha256(&self.public_key_bytes())
1516    }
1517
1518    fn public_key(&self) -> Vec<u8> {
1519        self.public_key_bytes()
1520    }
1521}
1522
1523#[cfg(feature = "post-quantum")]
1524/// SLH-DSA-256s key pair for post-quantum hash-based signatures.
1525///
1526/// SLH-DSA-256s provides 256-bit security.
1527pub struct SlhDsa256sKey {
1528    public_key: pqcrypto_sphincsplus::sphincsshake256256srobust::PublicKey,
1529    secret_key: pqcrypto_sphincsplus::sphincsshake256256srobust::SecretKey,
1530}
1531
1532#[cfg(feature = "post-quantum")]
1533impl SlhDsa256sKey {
1534    /// Generate a new SLH-DSA-256s key pair.
1535    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1536        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincsshake256256srobust::keypair();
1537        Self {
1538            public_key,
1539            secret_key,
1540        }
1541    }
1542
1543    /// Get the public key bytes.
1544    pub fn public_key_bytes(&self) -> Vec<u8> {
1545        <pqcrypto_sphincsplus::sphincsshake256256srobust::PublicKey as PqcPublicKey>::as_bytes(
1546            &self.public_key,
1547        )
1548        .to_vec()
1549    }
1550
1551    /// Get the private key bytes.
1552    pub fn private_key_bytes(&self) -> Vec<u8> {
1553        <pqcrypto_sphincsplus::sphincsshake256256srobust::SecretKey as PqcSecretKey>::as_bytes(
1554            &self.secret_key,
1555        )
1556        .to_vec()
1557    }
1558
1559    /// Create from private key bytes.
1560    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1561        let _secret_key = <pqcrypto_sphincsplus::sphincsshake256256srobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1562            .map_err(|_| BottleError::InvalidKeyType)?;
1563        // Cannot derive public key from secret key in this API
1564        Err(BottleError::InvalidKeyType)
1565    }
1566}
1567
1568#[cfg(feature = "post-quantum")]
1569impl Sign for SlhDsa256sKey {
1570    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1571        let detached_sig = pqcrypto_sphincsplus::sphincsshake256256srobust::detached_sign(
1572            message,
1573            &self.secret_key,
1574        );
1575        Ok(<pqcrypto_sphincsplus::sphincsshake256256srobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1576    }
1577}
1578
1579#[cfg(feature = "post-quantum")]
1580impl Verify for SlhDsa256sKey {
1581    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1582        let detached_sig = <pqcrypto_sphincsplus::sphincsshake256256srobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1583            .map_err(|_| BottleError::VerifyFailed)?;
1584        pqcrypto_sphincsplus::sphincsshake256256srobust::verify_detached_signature(
1585            &detached_sig,
1586            message,
1587            &self.public_key,
1588        )
1589        .map_err(|_| BottleError::VerifyFailed)?;
1590        Ok(())
1591    }
1592}
1593
1594#[cfg(feature = "post-quantum")]
1595impl SignerKey for SlhDsa256sKey {
1596    fn fingerprint(&self) -> Vec<u8> {
1597        crate::hash::sha256(&self.public_key_bytes())
1598    }
1599
1600    fn public_key(&self) -> Vec<u8> {
1601        self.public_key_bytes()
1602    }
1603}