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}
1604
1605#[cfg(feature = "post-quantum")]
1606/// SLH-DSA-128f key pair for post-quantum hash-based signatures.
1607///
1608/// SLH-DSA-128f provides 128-bit security with faster signing but larger signatures
1609/// compared to the "s" (small) variant.
1610pub struct SlhDsa128fKey {
1611    public_key: pqcrypto_sphincsplus::sphincsshake256128frobust::PublicKey,
1612    secret_key: pqcrypto_sphincsplus::sphincsshake256128frobust::SecretKey,
1613}
1614
1615#[cfg(feature = "post-quantum")]
1616impl SlhDsa128fKey {
1617    /// Generate a new SLH-DSA-128f key pair.
1618    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1619        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincsshake256128frobust::keypair();
1620        Self {
1621            public_key,
1622            secret_key,
1623        }
1624    }
1625
1626    /// Get the public key bytes.
1627    pub fn public_key_bytes(&self) -> Vec<u8> {
1628        <pqcrypto_sphincsplus::sphincsshake256128frobust::PublicKey as PqcPublicKey>::as_bytes(
1629            &self.public_key,
1630        )
1631        .to_vec()
1632    }
1633
1634    /// Get the private key bytes.
1635    pub fn private_key_bytes(&self) -> Vec<u8> {
1636        <pqcrypto_sphincsplus::sphincsshake256128frobust::SecretKey as PqcSecretKey>::as_bytes(
1637            &self.secret_key,
1638        )
1639        .to_vec()
1640    }
1641
1642    /// Create from private key bytes.
1643    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1644        let _secret_key = <pqcrypto_sphincsplus::sphincsshake256128frobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1645            .map_err(|_| BottleError::InvalidKeyType)?;
1646        // Cannot derive public key from secret key in this API
1647        Err(BottleError::InvalidKeyType)
1648    }
1649}
1650
1651#[cfg(feature = "post-quantum")]
1652impl Sign for SlhDsa128fKey {
1653    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1654        let detached_sig = pqcrypto_sphincsplus::sphincsshake256128frobust::detached_sign(
1655            message,
1656            &self.secret_key,
1657        );
1658        Ok(<pqcrypto_sphincsplus::sphincsshake256128frobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1659    }
1660}
1661
1662#[cfg(feature = "post-quantum")]
1663impl Verify for SlhDsa128fKey {
1664    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1665        let detached_sig = <pqcrypto_sphincsplus::sphincsshake256128frobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1666            .map_err(|_| BottleError::VerifyFailed)?;
1667        pqcrypto_sphincsplus::sphincsshake256128frobust::verify_detached_signature(
1668            &detached_sig,
1669            message,
1670            &self.public_key,
1671        )
1672        .map_err(|_| BottleError::VerifyFailed)?;
1673        Ok(())
1674    }
1675}
1676
1677#[cfg(feature = "post-quantum")]
1678impl SignerKey for SlhDsa128fKey {
1679    fn fingerprint(&self) -> Vec<u8> {
1680        crate::hash::sha256(&self.public_key_bytes())
1681    }
1682
1683    fn public_key(&self) -> Vec<u8> {
1684        self.public_key_bytes()
1685    }
1686}
1687
1688#[cfg(feature = "post-quantum")]
1689/// SLH-DSA-192f key pair for post-quantum hash-based signatures.
1690///
1691/// SLH-DSA-192f provides 192-bit security with faster signing but larger signatures.
1692pub struct SlhDsa192fKey {
1693    public_key: pqcrypto_sphincsplus::sphincsshake256192frobust::PublicKey,
1694    secret_key: pqcrypto_sphincsplus::sphincsshake256192frobust::SecretKey,
1695}
1696
1697#[cfg(feature = "post-quantum")]
1698impl SlhDsa192fKey {
1699    /// Generate a new SLH-DSA-192f key pair.
1700    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1701        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincsshake256192frobust::keypair();
1702        Self {
1703            public_key,
1704            secret_key,
1705        }
1706    }
1707
1708    /// Get the public key bytes.
1709    pub fn public_key_bytes(&self) -> Vec<u8> {
1710        <pqcrypto_sphincsplus::sphincsshake256192frobust::PublicKey as PqcPublicKey>::as_bytes(
1711            &self.public_key,
1712        )
1713        .to_vec()
1714    }
1715
1716    /// Get the private key bytes.
1717    pub fn private_key_bytes(&self) -> Vec<u8> {
1718        <pqcrypto_sphincsplus::sphincsshake256192frobust::SecretKey as PqcSecretKey>::as_bytes(
1719            &self.secret_key,
1720        )
1721        .to_vec()
1722    }
1723
1724    /// Create from private key bytes.
1725    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1726        let _secret_key = <pqcrypto_sphincsplus::sphincsshake256192frobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1727            .map_err(|_| BottleError::InvalidKeyType)?;
1728        // Cannot derive public key from secret key in this API
1729        Err(BottleError::InvalidKeyType)
1730    }
1731}
1732
1733#[cfg(feature = "post-quantum")]
1734impl Sign for SlhDsa192fKey {
1735    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1736        let detached_sig = pqcrypto_sphincsplus::sphincsshake256192frobust::detached_sign(
1737            message,
1738            &self.secret_key,
1739        );
1740        Ok(<pqcrypto_sphincsplus::sphincsshake256192frobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1741    }
1742}
1743
1744#[cfg(feature = "post-quantum")]
1745impl Verify for SlhDsa192fKey {
1746    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1747        let detached_sig = <pqcrypto_sphincsplus::sphincsshake256192frobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1748            .map_err(|_| BottleError::VerifyFailed)?;
1749        pqcrypto_sphincsplus::sphincsshake256192frobust::verify_detached_signature(
1750            &detached_sig,
1751            message,
1752            &self.public_key,
1753        )
1754        .map_err(|_| BottleError::VerifyFailed)?;
1755        Ok(())
1756    }
1757}
1758
1759#[cfg(feature = "post-quantum")]
1760impl SignerKey for SlhDsa192fKey {
1761    fn fingerprint(&self) -> Vec<u8> {
1762        crate::hash::sha256(&self.public_key_bytes())
1763    }
1764
1765    fn public_key(&self) -> Vec<u8> {
1766        self.public_key_bytes()
1767    }
1768}
1769
1770#[cfg(feature = "post-quantum")]
1771/// SLH-DSA-256f key pair for post-quantum hash-based signatures.
1772///
1773/// SLH-DSA-256f provides 256-bit security with faster signing but larger signatures.
1774pub struct SlhDsa256fKey {
1775    public_key: pqcrypto_sphincsplus::sphincsshake256256frobust::PublicKey,
1776    secret_key: pqcrypto_sphincsplus::sphincsshake256256frobust::SecretKey,
1777}
1778
1779#[cfg(feature = "post-quantum")]
1780impl SlhDsa256fKey {
1781    /// Generate a new SLH-DSA-256f key pair.
1782    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1783        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincsshake256256frobust::keypair();
1784        Self {
1785            public_key,
1786            secret_key,
1787        }
1788    }
1789
1790    /// Get the public key bytes.
1791    pub fn public_key_bytes(&self) -> Vec<u8> {
1792        <pqcrypto_sphincsplus::sphincsshake256256frobust::PublicKey as PqcPublicKey>::as_bytes(
1793            &self.public_key,
1794        )
1795        .to_vec()
1796    }
1797
1798    /// Get the private key bytes.
1799    pub fn private_key_bytes(&self) -> Vec<u8> {
1800        <pqcrypto_sphincsplus::sphincsshake256256frobust::SecretKey as PqcSecretKey>::as_bytes(
1801            &self.secret_key,
1802        )
1803        .to_vec()
1804    }
1805
1806    /// Create from private key bytes.
1807    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1808        let _secret_key = <pqcrypto_sphincsplus::sphincsshake256256frobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1809            .map_err(|_| BottleError::InvalidKeyType)?;
1810        // Cannot derive public key from secret key in this API
1811        Err(BottleError::InvalidKeyType)
1812    }
1813}
1814
1815#[cfg(feature = "post-quantum")]
1816impl Sign for SlhDsa256fKey {
1817    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1818        let detached_sig = pqcrypto_sphincsplus::sphincsshake256256frobust::detached_sign(
1819            message,
1820            &self.secret_key,
1821        );
1822        Ok(<pqcrypto_sphincsplus::sphincsshake256256frobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1823    }
1824}
1825
1826#[cfg(feature = "post-quantum")]
1827impl Verify for SlhDsa256fKey {
1828    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1829        let detached_sig = <pqcrypto_sphincsplus::sphincsshake256256frobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1830            .map_err(|_| BottleError::VerifyFailed)?;
1831        pqcrypto_sphincsplus::sphincsshake256256frobust::verify_detached_signature(
1832            &detached_sig,
1833            message,
1834            &self.public_key,
1835        )
1836        .map_err(|_| BottleError::VerifyFailed)?;
1837        Ok(())
1838    }
1839}
1840
1841#[cfg(feature = "post-quantum")]
1842impl SignerKey for SlhDsa256fKey {
1843    fn fingerprint(&self) -> Vec<u8> {
1844        crate::hash::sha256(&self.public_key_bytes())
1845    }
1846
1847    fn public_key(&self) -> Vec<u8> {
1848        self.public_key_bytes()
1849    }
1850}
1851
1852// SHA-2 based SLH-DSA variants
1853
1854#[cfg(feature = "post-quantum")]
1855/// SLH-DSA-SHA2-128s key pair for post-quantum hash-based signatures.
1856///
1857/// SLH-DSA-SHA2-128s provides 128-bit security using SHA-2 hash function
1858/// with smaller signatures but slower signing compared to the "f" variant.
1859pub struct SlhDsaSha2_128sKey {
1860    public_key: pqcrypto_sphincsplus::sphincssha256128srobust::PublicKey,
1861    secret_key: pqcrypto_sphincsplus::sphincssha256128srobust::SecretKey,
1862}
1863
1864#[cfg(feature = "post-quantum")]
1865impl SlhDsaSha2_128sKey {
1866    /// Generate a new SLH-DSA-SHA2-128s key pair.
1867    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1868        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincssha256128srobust::keypair();
1869        Self {
1870            public_key,
1871            secret_key,
1872        }
1873    }
1874
1875    /// Get the public key bytes.
1876    pub fn public_key_bytes(&self) -> Vec<u8> {
1877        <pqcrypto_sphincsplus::sphincssha256128srobust::PublicKey as PqcPublicKey>::as_bytes(
1878            &self.public_key,
1879        )
1880        .to_vec()
1881    }
1882
1883    /// Get the private key bytes.
1884    pub fn private_key_bytes(&self) -> Vec<u8> {
1885        <pqcrypto_sphincsplus::sphincssha256128srobust::SecretKey as PqcSecretKey>::as_bytes(
1886            &self.secret_key,
1887        )
1888        .to_vec()
1889    }
1890
1891    /// Create from private key bytes.
1892    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1893        let _secret_key = <pqcrypto_sphincsplus::sphincssha256128srobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1894            .map_err(|_| BottleError::InvalidKeyType)?;
1895        // Cannot derive public key from secret key in this API
1896        Err(BottleError::InvalidKeyType)
1897    }
1898}
1899
1900#[cfg(feature = "post-quantum")]
1901impl Sign for SlhDsaSha2_128sKey {
1902    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1903        let detached_sig = pqcrypto_sphincsplus::sphincssha256128srobust::detached_sign(
1904            message,
1905            &self.secret_key,
1906        );
1907        Ok(<pqcrypto_sphincsplus::sphincssha256128srobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1908    }
1909}
1910
1911#[cfg(feature = "post-quantum")]
1912impl Verify for SlhDsaSha2_128sKey {
1913    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1914        let detached_sig = <pqcrypto_sphincsplus::sphincssha256128srobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1915            .map_err(|_| BottleError::VerifyFailed)?;
1916        pqcrypto_sphincsplus::sphincssha256128srobust::verify_detached_signature(
1917            &detached_sig,
1918            message,
1919            &self.public_key,
1920        )
1921        .map_err(|_| BottleError::VerifyFailed)?;
1922        Ok(())
1923    }
1924}
1925
1926#[cfg(feature = "post-quantum")]
1927impl SignerKey for SlhDsaSha2_128sKey {
1928    fn fingerprint(&self) -> Vec<u8> {
1929        crate::hash::sha256(&self.public_key_bytes())
1930    }
1931
1932    fn public_key(&self) -> Vec<u8> {
1933        self.public_key_bytes()
1934    }
1935}
1936
1937#[cfg(feature = "post-quantum")]
1938/// SLH-DSA-SHA2-128f key pair for post-quantum hash-based signatures.
1939///
1940/// SLH-DSA-SHA2-128f provides 128-bit security using SHA-2 hash function
1941/// with faster signing but larger signatures.
1942pub struct SlhDsaSha2_128fKey {
1943    public_key: pqcrypto_sphincsplus::sphincssha256128frobust::PublicKey,
1944    secret_key: pqcrypto_sphincsplus::sphincssha256128frobust::SecretKey,
1945}
1946
1947#[cfg(feature = "post-quantum")]
1948impl SlhDsaSha2_128fKey {
1949    /// Generate a new SLH-DSA-SHA2-128f key pair.
1950    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
1951        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincssha256128frobust::keypair();
1952        Self {
1953            public_key,
1954            secret_key,
1955        }
1956    }
1957
1958    /// Get the public key bytes.
1959    pub fn public_key_bytes(&self) -> Vec<u8> {
1960        <pqcrypto_sphincsplus::sphincssha256128frobust::PublicKey as PqcPublicKey>::as_bytes(
1961            &self.public_key,
1962        )
1963        .to_vec()
1964    }
1965
1966    /// Get the private key bytes.
1967    pub fn private_key_bytes(&self) -> Vec<u8> {
1968        <pqcrypto_sphincsplus::sphincssha256128frobust::SecretKey as PqcSecretKey>::as_bytes(
1969            &self.secret_key,
1970        )
1971        .to_vec()
1972    }
1973
1974    /// Create from private key bytes.
1975    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
1976        let _secret_key = <pqcrypto_sphincsplus::sphincssha256128frobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
1977            .map_err(|_| BottleError::InvalidKeyType)?;
1978        // Cannot derive public key from secret key in this API
1979        Err(BottleError::InvalidKeyType)
1980    }
1981}
1982
1983#[cfg(feature = "post-quantum")]
1984impl Sign for SlhDsaSha2_128fKey {
1985    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
1986        let detached_sig = pqcrypto_sphincsplus::sphincssha256128frobust::detached_sign(
1987            message,
1988            &self.secret_key,
1989        );
1990        Ok(<pqcrypto_sphincsplus::sphincssha256128frobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
1991    }
1992}
1993
1994#[cfg(feature = "post-quantum")]
1995impl Verify for SlhDsaSha2_128fKey {
1996    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
1997        let detached_sig = <pqcrypto_sphincsplus::sphincssha256128frobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
1998            .map_err(|_| BottleError::VerifyFailed)?;
1999        pqcrypto_sphincsplus::sphincssha256128frobust::verify_detached_signature(
2000            &detached_sig,
2001            message,
2002            &self.public_key,
2003        )
2004        .map_err(|_| BottleError::VerifyFailed)?;
2005        Ok(())
2006    }
2007}
2008
2009#[cfg(feature = "post-quantum")]
2010impl SignerKey for SlhDsaSha2_128fKey {
2011    fn fingerprint(&self) -> Vec<u8> {
2012        crate::hash::sha256(&self.public_key_bytes())
2013    }
2014
2015    fn public_key(&self) -> Vec<u8> {
2016        self.public_key_bytes()
2017    }
2018}
2019
2020#[cfg(feature = "post-quantum")]
2021/// SLH-DSA-SHA2-192s key pair for post-quantum hash-based signatures.
2022///
2023/// SLH-DSA-SHA2-192s provides 192-bit security using SHA-2 hash function.
2024pub struct SlhDsaSha2_192sKey {
2025    public_key: pqcrypto_sphincsplus::sphincssha256192srobust::PublicKey,
2026    secret_key: pqcrypto_sphincsplus::sphincssha256192srobust::SecretKey,
2027}
2028
2029#[cfg(feature = "post-quantum")]
2030impl SlhDsaSha2_192sKey {
2031    /// Generate a new SLH-DSA-SHA2-192s key pair.
2032    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
2033        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincssha256192srobust::keypair();
2034        Self {
2035            public_key,
2036            secret_key,
2037        }
2038    }
2039
2040    /// Get the public key bytes.
2041    pub fn public_key_bytes(&self) -> Vec<u8> {
2042        <pqcrypto_sphincsplus::sphincssha256192srobust::PublicKey as PqcPublicKey>::as_bytes(
2043            &self.public_key,
2044        )
2045        .to_vec()
2046    }
2047
2048    /// Get the private key bytes.
2049    pub fn private_key_bytes(&self) -> Vec<u8> {
2050        <pqcrypto_sphincsplus::sphincssha256192srobust::SecretKey as PqcSecretKey>::as_bytes(
2051            &self.secret_key,
2052        )
2053        .to_vec()
2054    }
2055
2056    /// Create from private key bytes.
2057    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
2058        let _secret_key = <pqcrypto_sphincsplus::sphincssha256192srobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
2059            .map_err(|_| BottleError::InvalidKeyType)?;
2060        // Cannot derive public key from secret key in this API
2061        Err(BottleError::InvalidKeyType)
2062    }
2063}
2064
2065#[cfg(feature = "post-quantum")]
2066impl Sign for SlhDsaSha2_192sKey {
2067    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
2068        let detached_sig = pqcrypto_sphincsplus::sphincssha256192srobust::detached_sign(
2069            message,
2070            &self.secret_key,
2071        );
2072        Ok(<pqcrypto_sphincsplus::sphincssha256192srobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
2073    }
2074}
2075
2076#[cfg(feature = "post-quantum")]
2077impl Verify for SlhDsaSha2_192sKey {
2078    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
2079        let detached_sig = <pqcrypto_sphincsplus::sphincssha256192srobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
2080            .map_err(|_| BottleError::VerifyFailed)?;
2081        pqcrypto_sphincsplus::sphincssha256192srobust::verify_detached_signature(
2082            &detached_sig,
2083            message,
2084            &self.public_key,
2085        )
2086        .map_err(|_| BottleError::VerifyFailed)?;
2087        Ok(())
2088    }
2089}
2090
2091#[cfg(feature = "post-quantum")]
2092impl SignerKey for SlhDsaSha2_192sKey {
2093    fn fingerprint(&self) -> Vec<u8> {
2094        crate::hash::sha256(&self.public_key_bytes())
2095    }
2096
2097    fn public_key(&self) -> Vec<u8> {
2098        self.public_key_bytes()
2099    }
2100}
2101
2102#[cfg(feature = "post-quantum")]
2103/// SLH-DSA-SHA2-192f key pair for post-quantum hash-based signatures.
2104///
2105/// SLH-DSA-SHA2-192f provides 192-bit security using SHA-2 hash function.
2106pub struct SlhDsaSha2_192fKey {
2107    public_key: pqcrypto_sphincsplus::sphincssha256192frobust::PublicKey,
2108    secret_key: pqcrypto_sphincsplus::sphincssha256192frobust::SecretKey,
2109}
2110
2111#[cfg(feature = "post-quantum")]
2112impl SlhDsaSha2_192fKey {
2113    /// Generate a new SLH-DSA-SHA2-192f key pair.
2114    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
2115        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincssha256192frobust::keypair();
2116        Self {
2117            public_key,
2118            secret_key,
2119        }
2120    }
2121
2122    /// Get the public key bytes.
2123    pub fn public_key_bytes(&self) -> Vec<u8> {
2124        <pqcrypto_sphincsplus::sphincssha256192frobust::PublicKey as PqcPublicKey>::as_bytes(
2125            &self.public_key,
2126        )
2127        .to_vec()
2128    }
2129
2130    /// Get the private key bytes.
2131    pub fn private_key_bytes(&self) -> Vec<u8> {
2132        <pqcrypto_sphincsplus::sphincssha256192frobust::SecretKey as PqcSecretKey>::as_bytes(
2133            &self.secret_key,
2134        )
2135        .to_vec()
2136    }
2137
2138    /// Create from private key bytes.
2139    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
2140        let _secret_key = <pqcrypto_sphincsplus::sphincssha256192frobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
2141            .map_err(|_| BottleError::InvalidKeyType)?;
2142        // Cannot derive public key from secret key in this API
2143        Err(BottleError::InvalidKeyType)
2144    }
2145}
2146
2147#[cfg(feature = "post-quantum")]
2148impl Sign for SlhDsaSha2_192fKey {
2149    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
2150        let detached_sig = pqcrypto_sphincsplus::sphincssha256192frobust::detached_sign(
2151            message,
2152            &self.secret_key,
2153        );
2154        Ok(<pqcrypto_sphincsplus::sphincssha256192frobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
2155    }
2156}
2157
2158#[cfg(feature = "post-quantum")]
2159impl Verify for SlhDsaSha2_192fKey {
2160    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
2161        let detached_sig = <pqcrypto_sphincsplus::sphincssha256192frobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
2162            .map_err(|_| BottleError::VerifyFailed)?;
2163        pqcrypto_sphincsplus::sphincssha256192frobust::verify_detached_signature(
2164            &detached_sig,
2165            message,
2166            &self.public_key,
2167        )
2168        .map_err(|_| BottleError::VerifyFailed)?;
2169        Ok(())
2170    }
2171}
2172
2173#[cfg(feature = "post-quantum")]
2174impl SignerKey for SlhDsaSha2_192fKey {
2175    fn fingerprint(&self) -> Vec<u8> {
2176        crate::hash::sha256(&self.public_key_bytes())
2177    }
2178
2179    fn public_key(&self) -> Vec<u8> {
2180        self.public_key_bytes()
2181    }
2182}
2183
2184#[cfg(feature = "post-quantum")]
2185/// SLH-DSA-SHA2-256s key pair for post-quantum hash-based signatures.
2186///
2187/// SLH-DSA-SHA2-256s provides 256-bit security using SHA-2 hash function.
2188pub struct SlhDsaSha2_256sKey {
2189    public_key: pqcrypto_sphincsplus::sphincssha256256srobust::PublicKey,
2190    secret_key: pqcrypto_sphincsplus::sphincssha256256srobust::SecretKey,
2191}
2192
2193#[cfg(feature = "post-quantum")]
2194impl SlhDsaSha2_256sKey {
2195    /// Generate a new SLH-DSA-SHA2-256s key pair.
2196    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
2197        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincssha256256srobust::keypair();
2198        Self {
2199            public_key,
2200            secret_key,
2201        }
2202    }
2203
2204    /// Get the public key bytes.
2205    pub fn public_key_bytes(&self) -> Vec<u8> {
2206        <pqcrypto_sphincsplus::sphincssha256256srobust::PublicKey as PqcPublicKey>::as_bytes(
2207            &self.public_key,
2208        )
2209        .to_vec()
2210    }
2211
2212    /// Get the private key bytes.
2213    pub fn private_key_bytes(&self) -> Vec<u8> {
2214        <pqcrypto_sphincsplus::sphincssha256256srobust::SecretKey as PqcSecretKey>::as_bytes(
2215            &self.secret_key,
2216        )
2217        .to_vec()
2218    }
2219
2220    /// Create from private key bytes.
2221    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
2222        let _secret_key = <pqcrypto_sphincsplus::sphincssha256256srobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
2223            .map_err(|_| BottleError::InvalidKeyType)?;
2224        // Cannot derive public key from secret key in this API
2225        Err(BottleError::InvalidKeyType)
2226    }
2227}
2228
2229#[cfg(feature = "post-quantum")]
2230impl Sign for SlhDsaSha2_256sKey {
2231    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
2232        let detached_sig = pqcrypto_sphincsplus::sphincssha256256srobust::detached_sign(
2233            message,
2234            &self.secret_key,
2235        );
2236        Ok(<pqcrypto_sphincsplus::sphincssha256256srobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
2237    }
2238}
2239
2240#[cfg(feature = "post-quantum")]
2241impl Verify for SlhDsaSha2_256sKey {
2242    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
2243        let detached_sig = <pqcrypto_sphincsplus::sphincssha256256srobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
2244            .map_err(|_| BottleError::VerifyFailed)?;
2245        pqcrypto_sphincsplus::sphincssha256256srobust::verify_detached_signature(
2246            &detached_sig,
2247            message,
2248            &self.public_key,
2249        )
2250        .map_err(|_| BottleError::VerifyFailed)?;
2251        Ok(())
2252    }
2253}
2254
2255#[cfg(feature = "post-quantum")]
2256impl SignerKey for SlhDsaSha2_256sKey {
2257    fn fingerprint(&self) -> Vec<u8> {
2258        crate::hash::sha256(&self.public_key_bytes())
2259    }
2260
2261    fn public_key(&self) -> Vec<u8> {
2262        self.public_key_bytes()
2263    }
2264}
2265
2266#[cfg(feature = "post-quantum")]
2267/// SLH-DSA-SHA2-256f key pair for post-quantum hash-based signatures.
2268///
2269/// SLH-DSA-SHA2-256f provides 256-bit security using SHA-2 hash function.
2270pub struct SlhDsaSha2_256fKey {
2271    public_key: pqcrypto_sphincsplus::sphincssha256256frobust::PublicKey,
2272    secret_key: pqcrypto_sphincsplus::sphincssha256256frobust::SecretKey,
2273}
2274
2275#[cfg(feature = "post-quantum")]
2276impl SlhDsaSha2_256fKey {
2277    /// Generate a new SLH-DSA-SHA2-256f key pair.
2278    pub fn generate<R: RngCore + CryptoRng>(_rng: &mut R) -> Self {
2279        let (public_key, secret_key) = pqcrypto_sphincsplus::sphincssha256256frobust::keypair();
2280        Self {
2281            public_key,
2282            secret_key,
2283        }
2284    }
2285
2286    /// Get the public key bytes.
2287    pub fn public_key_bytes(&self) -> Vec<u8> {
2288        <pqcrypto_sphincsplus::sphincssha256256frobust::PublicKey as PqcPublicKey>::as_bytes(
2289            &self.public_key,
2290        )
2291        .to_vec()
2292    }
2293
2294    /// Get the private key bytes.
2295    pub fn private_key_bytes(&self) -> Vec<u8> {
2296        <pqcrypto_sphincsplus::sphincssha256256frobust::SecretKey as PqcSecretKey>::as_bytes(
2297            &self.secret_key,
2298        )
2299        .to_vec()
2300    }
2301
2302    /// Create from private key bytes.
2303    pub fn from_private_key_bytes(bytes: &[u8]) -> Result<Self> {
2304        let _secret_key = <pqcrypto_sphincsplus::sphincssha256256frobust::SecretKey as PqcSecretKey>::from_bytes(bytes)
2305            .map_err(|_| BottleError::InvalidKeyType)?;
2306        // Cannot derive public key from secret key in this API
2307        Err(BottleError::InvalidKeyType)
2308    }
2309}
2310
2311#[cfg(feature = "post-quantum")]
2312impl Sign for SlhDsaSha2_256fKey {
2313    fn sign(&self, _rng: &mut dyn RngCore, message: &[u8]) -> Result<Vec<u8>> {
2314        let detached_sig = pqcrypto_sphincsplus::sphincssha256256frobust::detached_sign(
2315            message,
2316            &self.secret_key,
2317        );
2318        Ok(<pqcrypto_sphincsplus::sphincssha256256frobust::DetachedSignature as PqcDetachedSignature>::as_bytes(&detached_sig).to_vec())
2319    }
2320}
2321
2322#[cfg(feature = "post-quantum")]
2323impl Verify for SlhDsaSha2_256fKey {
2324    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
2325        let detached_sig = <pqcrypto_sphincsplus::sphincssha256256frobust::DetachedSignature as PqcDetachedSignature>::from_bytes(signature)
2326            .map_err(|_| BottleError::VerifyFailed)?;
2327        pqcrypto_sphincsplus::sphincssha256256frobust::verify_detached_signature(
2328            &detached_sig,
2329            message,
2330            &self.public_key,
2331        )
2332        .map_err(|_| BottleError::VerifyFailed)?;
2333        Ok(())
2334    }
2335}
2336
2337#[cfg(feature = "post-quantum")]
2338impl SignerKey for SlhDsaSha2_256fKey {
2339    fn fingerprint(&self) -> Vec<u8> {
2340        crate::hash::sha256(&self.public_key_bytes())
2341    }
2342
2343    fn public_key(&self) -> Vec<u8> {
2344        self.public_key_bytes()
2345    }
2346}