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}