libq/sig/
mod.rs

1//! Digital Signatures for lib-Q
2//!
3//! This module provides post-quantum digital signature schemes.
4
5use crate::error::Result;
6use zeroize::{Zeroize, ZeroizeOnDrop};
7
8/// Trait for digital signatures
9pub trait Signature {
10    /// Generate a keypair
11    fn generate_keypair(&self) -> Result<SigKeypair>;
12
13    /// Sign a message
14    fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>>;
15
16    /// Verify a signature
17    fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool>;
18}
19
20/// Signature keypair with automatic memory zeroization
21pub struct SigKeypair {
22    pub public_key: SigPublicKey,
23    pub secret_key: SigSecretKey,
24}
25
26/// Signature public key
27#[derive(Clone, Debug, PartialEq, Eq)]
28pub struct SigPublicKey {
29    pub data: Vec<u8>,
30}
31
32/// Signature secret key with automatic memory zeroization
33#[derive(Zeroize, ZeroizeOnDrop)]
34pub struct SigSecretKey {
35    pub data: Vec<u8>,
36}
37
38impl SigKeypair {
39    /// Create a new signature keypair
40    ///
41    /// # Arguments
42    ///
43    /// * `public_key` - The public key data
44    /// * `secret_key` - The secret key data (will be zeroized on drop)
45    ///
46    /// # Returns
47    ///
48    /// A new signature keypair
49    pub fn new(public_key: Vec<u8>, secret_key: Vec<u8>) -> Self {
50        Self {
51            public_key: SigPublicKey { data: public_key },
52            secret_key: SigSecretKey { data: secret_key },
53        }
54    }
55
56    /// Get the public key
57    pub fn public_key(&self) -> &SigPublicKey {
58        &self.public_key
59    }
60
61    /// Get the secret key (use with caution)
62    pub fn secret_key(&self) -> &SigSecretKey {
63        &self.secret_key
64    }
65}
66
67impl SigPublicKey {
68    /// Create a new public key
69    pub fn new(data: Vec<u8>) -> Self {
70        Self { data }
71    }
72
73    /// Get the key data
74    pub fn data(&self) -> &[u8] {
75        &self.data
76    }
77
78    /// Get the key size
79    pub fn size(&self) -> usize {
80        self.data.len()
81    }
82}
83
84impl SigSecretKey {
85    /// Create a new secret key
86    pub fn new(data: Vec<u8>) -> Self {
87        Self { data }
88    }
89
90    /// Get the key data (use with caution)
91    pub fn data(&self) -> &[u8] {
92        &self.data
93    }
94
95    /// Get the key size
96    pub fn size(&self) -> usize {
97        self.data.len()
98    }
99}
100
101// Implement Debug for SigSecretKey (but don't show the actual data)
102impl std::fmt::Debug for SigSecretKey {
103    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104        f.debug_struct("SigSecretKey")
105            .field("data", &"[REDACTED]")
106            .field("size", &self.data.len())
107            .finish()
108    }
109}
110
111// Implement PartialEq and Eq for SigSecretKey (constant-time comparison)
112impl PartialEq for SigSecretKey {
113    fn eq(&self, other: &Self) -> bool {
114        if self.data.len() != other.data.len() {
115            return false;
116        }
117
118        // Constant-time comparison
119        let mut result = 0u8;
120        for (a, b) in self.data.iter().zip(other.data.iter()) {
121            result |= a ^ b;
122        }
123        result == 0
124    }
125}
126
127impl Eq for SigSecretKey {}
128
129// Implement Zeroize for SigKeypair to zeroize the secret key
130impl Zeroize for SigKeypair {
131    fn zeroize(&mut self) {
132        self.secret_key.zeroize();
133    }
134}
135
136// Implement ZeroizeOnDrop for SigKeypair
137impl Drop for SigKeypair {
138    fn drop(&mut self) {
139        self.zeroize();
140    }
141}
142
143#[cfg(test)]
144mod tests {
145    use super::*;
146
147    #[test]
148    fn test_sig_keypair_creation() {
149        let public_key = vec![1, 2, 3, 4];
150        let secret_key = vec![5, 6, 7, 8];
151
152        let keypair = SigKeypair::new(public_key.clone(), secret_key.clone());
153
154        assert_eq!(keypair.public_key.data, public_key);
155        assert_eq!(keypair.secret_key.data, secret_key);
156    }
157
158    #[test]
159    fn test_sig_public_key() {
160        let data = vec![1, 2, 3, 4];
161        let public_key = SigPublicKey::new(data.clone());
162
163        assert_eq!(public_key.data(), &data);
164        assert_eq!(public_key.size(), 4);
165    }
166
167    #[test]
168    fn test_sig_secret_key() {
169        let data = vec![1, 2, 3, 4];
170        let secret_key = SigSecretKey::new(data.clone());
171
172        assert_eq!(secret_key.data(), &data);
173        assert_eq!(secret_key.size(), 4);
174    }
175
176    #[test]
177    fn test_secret_key_constant_time_comparison() {
178        let key1 = SigSecretKey::new(vec![1, 2, 3, 4]);
179        let key2 = SigSecretKey::new(vec![1, 2, 3, 4]);
180        let key3 = SigSecretKey::new(vec![1, 2, 3, 5]);
181
182        assert_eq!(key1, key2);
183        assert_ne!(key1, key3);
184    }
185}