dcrypt_api/traits/
signature.rs

1//! Digital signature traits for dcrypt
2//!
3//! This module defines the traits that all signature algorithms must implement.
4//! The design prioritizes security by not requiring mutable access to secret keys.
5
6use crate::Result;
7use rand::{CryptoRng, RngCore};
8use zeroize::{Zeroize, Zeroizing};
9
10/// Core trait for digital signature algorithms
11/// 
12/// This trait defines the minimal interface that all signature algorithms
13/// must implement. It intentionally does not require `AsRef` or `AsMut`
14/// implementations for secret keys to prevent accidental key corruption.
15/// 
16/// # Type Safety
17/// 
18/// Secret keys are opaque types that cannot be directly manipulated as bytes.
19/// This prevents common security vulnerabilities where keys are accidentally
20/// modified or exposed.
21/// 
22/// # Example Implementation
23/// 
24/// See the implementation modules for examples of how to implement this trait
25/// for specific algorithms like Ed25519, ECDSA, etc.
26pub trait Signature {
27    /// Public key type for this algorithm
28    type PublicKey: Clone;
29    
30    /// Secret key type - must be zeroizable but not byte-accessible
31    /// 
32    /// # Security Note
33    /// 
34    /// This type should not implement `AsMut<[u8]>` to prevent corruption
35    /// of key material. Use explicit serialization methods if needed.
36    type SecretKey: Zeroize + Clone;
37    
38    /// Signature data type
39    type SignatureData: Clone;
40    
41    /// Key pair type (typically a tuple of public and secret keys)
42    type KeyPair;
43
44    /// Returns the name of this signature algorithm
45    fn name() -> &'static str;
46
47    /// Generate a new key pair using the provided RNG
48    /// 
49    /// # Security Requirements
50    /// 
51    /// Implementations must use the provided cryptographically secure RNG
52    /// for all random number generation.
53    fn keypair<R: CryptoRng + RngCore>(rng: &mut R) -> Result<Self::KeyPair>;
54
55    /// Extract the public key from a key pair
56    fn public_key(keypair: &Self::KeyPair) -> Self::PublicKey;
57
58    /// Extract the secret key from a key pair
59    fn secret_key(keypair: &Self::KeyPair) -> Self::SecretKey;
60
61    /// Sign a message with the given secret key
62    /// 
63    /// # Security Requirements
64    /// 
65    /// - Implementations should be deterministic when possible (e.g., Ed25519)
66    /// - Must not leak information about the secret key through timing
67    fn sign(message: &[u8], secret_key: &Self::SecretKey) -> Result<Self::SignatureData>;
68
69    /// Verify a signature against a message and public key
70    /// 
71    /// # Security Requirements
72    /// 
73    /// - Must be constant-time with respect to the signature value
74    /// - Should validate all inputs before processing
75    fn verify(
76        message: &[u8],
77        signature: &Self::SignatureData,
78        public_key: &Self::PublicKey,
79    ) -> Result<()>;
80}
81
82/// Optional trait for signature algorithms that support key serialization
83/// 
84/// This trait should only be implemented for algorithms where key
85/// import/export is safe and well-defined.
86pub trait SignatureSerialize: Signature {
87    /// Size of serialized public keys in bytes
88    const PUBLIC_KEY_SIZE: usize;
89    
90    /// Size of serialized secret keys in bytes
91    const SECRET_KEY_SIZE: usize;
92    
93    /// Size of serialized signatures in bytes
94    const SIGNATURE_SIZE: usize;
95
96    /// Export a public key to bytes
97    fn serialize_public_key(key: &Self::PublicKey) -> Vec<u8>;
98    
99    /// Import a public key from bytes
100    /// 
101    /// # Errors
102    /// 
103    /// Returns an error if the bytes are malformed or invalid
104    fn deserialize_public_key(bytes: &[u8]) -> Result<Self::PublicKey>;
105    
106    /// Export a secret key to bytes
107    /// 
108    /// # Security Warning
109    /// 
110    /// The returned bytes contain sensitive key material and must be
111    /// handled with appropriate care. The `Zeroizing` wrapper ensures
112    /// the bytes are cleared from memory when dropped.
113    fn serialize_secret_key(key: &Self::SecretKey) -> Zeroizing<Vec<u8>>;
114    
115    /// Import a secret key from bytes
116    /// 
117    /// # Security Requirements
118    /// 
119    /// - Input bytes should be zeroized after use
120    /// - Implementation must validate the key format
121    /// 
122    /// # Errors
123    /// 
124    /// Returns an error if the bytes are malformed or invalid
125    fn deserialize_secret_key(bytes: &[u8]) -> Result<Self::SecretKey>;
126    
127    /// Export a signature to bytes
128    fn serialize_signature(sig: &Self::SignatureData) -> Vec<u8>;
129    
130    /// Import a signature from bytes
131    /// 
132    /// # Errors
133    /// 
134    /// Returns an error if the bytes are malformed or invalid
135    fn deserialize_signature(bytes: &[u8]) -> Result<Self::SignatureData>;
136}
137
138/// Optional trait for signature algorithms that support key derivation
139/// 
140/// This trait is for algorithms that can derive keys from seed material
141/// in a deterministic way.
142pub trait SignatureDerive: Signature {
143    /// Minimum seed size in bytes
144    const MIN_SEED_SIZE: usize;
145
146    /// Derive a key pair from seed material
147    /// 
148    /// # Security Requirements
149    /// 
150    /// - The seed must have sufficient entropy
151    /// - Derivation must be deterministic
152    /// - Same seed must always produce same key pair
153    /// 
154    /// # Errors
155    /// 
156    /// Returns an error if the seed is too short or invalid
157    fn derive_keypair(seed: &[u8]) -> Result<Self::KeyPair>;
158    
159    /// Derive the public key from a secret key
160    /// 
161    /// This is useful when you have a secret key and need to
162    /// recover the corresponding public key.
163    /// 
164    /// # Errors
165    /// 
166    /// Returns an error if the secret key is invalid
167    fn derive_public_key(secret_key: &Self::SecretKey) -> Result<Self::PublicKey>;
168}
169
170/// Optional trait for signature algorithms with message size limits
171/// 
172/// Some algorithms may have restrictions on message sizes or require
173/// pre-hashing for large messages.
174pub trait SignatureMessageLimits: Signature {
175    /// Maximum message size that can be signed directly (in bytes)
176    /// 
177    /// `None` indicates no limit
178    const MAX_MESSAGE_SIZE: Option<usize>;
179    
180    /// Whether this algorithm requires pre-hashing of messages
181    const REQUIRES_PREHASH: bool;
182}
183
184/// Optional trait for batch signature verification
185/// 
186/// Some algorithms (like Ed25519) support efficient batch verification
187/// of multiple signatures.
188pub trait SignatureBatchVerify: Signature {
189    /// Verify multiple signatures in a batch
190    /// 
191    /// # Parameters
192    /// 
193    /// - `messages`: Slice of messages to verify
194    /// - `signatures`: Corresponding signatures
195    /// - `public_keys`: Corresponding public keys
196    /// 
197    /// All three slices must have the same length.
198    /// 
199    /// # Returns
200    /// 
201    /// - `Ok(())` if all signatures are valid
202    /// - `Err(_)` if any signature is invalid or inputs are malformed
203    /// 
204    /// # Performance
205    /// 
206    /// This should be significantly faster than verifying each signature
207    /// individually when the batch size is large.
208    fn batch_verify(
209        messages: &[&[u8]],
210        signatures: &[Self::SignatureData],
211        public_keys: &[Self::PublicKey],
212    ) -> Result<()>;
213}
214
215/// Extension trait for convenient public key operations
216/// 
217/// This trait can be implemented for public key types that have
218/// a byte representation.
219pub trait PublicKeyBytes: Sized {
220    /// Create from byte representation
221    fn from_bytes(bytes: &[u8]) -> Result<Self>;
222    
223    /// Convert to byte representation
224    fn to_bytes(&self) -> Vec<u8>;
225}
226
227/// Extension trait for convenient signature operations
228/// 
229/// This trait can be implemented for signature types that have
230/// a byte representation.
231pub trait SignatureBytes: Sized {
232    /// Create from byte representation
233    fn from_bytes(bytes: &[u8]) -> Result<Self>;
234    
235    /// Convert to byte representation
236    fn to_bytes(&self) -> Vec<u8>;
237}