pq_msg/signatures/
keypair.rs

1use pqcrypto_falcon::{
2    falconpadded1024, falconpadded1024_keypair,
3    ffi::{
4        PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_BYTES,
5        PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES,
6        PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_SECRETKEYBYTES,
7    },
8};
9use pqcrypto_traits::sign::{PublicKey, SecretKey, SignedMessage};
10
11use crate::errors::CryptoError;
12
13/// Type alias for a public key byte array
14pub type PublicKeyBytes = [u8; PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES];
15/// Type alias for a secret key byte array
16pub type SecretKeyBytes = [u8; PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_SECRETKEYBYTES];
17
18/// Common operations for verifying signatures
19///
20/// This trait provides methods for accessing public keys and verifying
21/// signed messages with post-quantum cryptographic algorithms.
22pub trait ViewOperations {
23    /// Gets a reference to the public key
24    fn pub_key(&self) -> &falconpadded1024::PublicKey;
25
26    /// Gets a reference to the public key as a byte array
27    fn pub_key_bytes(&self) -> &[u8; PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES] {
28        let id = unsafe {
29            &*(self.pub_key().as_bytes().as_ptr()
30                as *const [u8; PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES])
31        };
32        id
33    }
34
35    /// Verifies if a signature is valid for the provided message
36    ///
37    /// # Arguments
38    /// * `msg` - The message that was signed
39    /// * `sig` - The signature to verify
40    ///
41    /// # Returns
42    /// - `Result<bool, CryptoError>`: True if signature is valid, false if invalid,
43    ///   or an error if verification couldn't be completed
44    fn verify_comp(&self, msg: &[u8], sig: &[u8]) -> Result<bool, CryptoError> {
45        if sig.len() != PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_BYTES + msg.len() {
46            return Err(CryptoError::InvalidSignature);
47        }
48
49        let sm = falconpadded1024::SignedMessage::from_bytes(sig)?;
50        let v_result = falconpadded1024::open(&sm, self.pub_key());
51        if let Err(e) = v_result {
52            if e.to_string().contains("verification failed") {
53                return Ok(false);
54            }
55
56            return Err(CryptoError::UnknownVerificationError);
57        }
58
59        // Where v_result is the message
60        Ok(v_result.unwrap() == msg)
61    }
62
63    /// Verifies a signature and returns the original message bytes
64    ///
65    /// # Arguments
66    /// * `sig` - The signature bytes to verify
67    ///
68    /// # Returns
69    /// - `Result<Vec<u8>, CryptoError>`: The verified message or an error
70    fn verify_message_bytes(&self, sig: &[u8]) -> Result<Vec<u8>, CryptoError> {
71        if sig.len() < PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_BYTES {
72            return Err(CryptoError::InvalidSignature);
73        }
74
75        let sm = falconpadded1024::SignedMessage::from_bytes(sig)?;
76        match falconpadded1024::open(&sm, self.pub_key()) {
77            Ok(msg) => Ok(msg),
78            Err(e) => {
79                if e.to_string().contains("verification failed") {
80                    return Err(CryptoError::InvalidSignature);
81                }
82                return Err(CryptoError::UnknownVerificationError);
83            }
84        }
85    }
86
87    /// Verifies a signature and returns the original message bytes
88    ///
89    /// # Arguments
90    /// * `sm` - The signed message to verify
91    ///
92    /// # Returns
93    /// - `Result<Vec<u8>, CryptoError>`: The verified message or an error
94    fn verify_message(&self, sm: &falconpadded1024::SignedMessage) -> Result<Vec<u8>, CryptoError> {
95        match falconpadded1024::open(&sm, self.pub_key()) {
96            Ok(msg) => Ok(msg),
97            Err(e) => {
98                if e.to_string().contains("verification failed") {
99                    return Err(CryptoError::InvalidSignature);
100                }
101                return Err(CryptoError::UnknownVerificationError);
102            }
103        }
104    }
105}
106
107/// A key pair used only for signature verification
108///
109/// This struct represents a post-quantum cryptography key pair used only
110/// for verifying signatures. It contains just the public key component.
111pub struct VerifierPair {
112    pub_key: falconpadded1024::PublicKey,
113}
114
115impl VerifierPair {
116    /// Creates a new verifier pair from public key bytes
117    ///
118    /// # Arguments
119    /// * `pub_key` - The public key bytes
120    ///
121    /// # Returns
122    /// - `Result<VerifierPair, CryptoError>`: The constructed verifier or an error
123    #[must_use]
124    pub fn new(pub_key: &[u8]) -> Result<Self, CryptoError> {
125        let pub_key = falconpadded1024::PublicKey::from_bytes(pub_key)?;
126        Ok(Self { pub_key })
127    }
128
129    /// Creates a new verifier pair from public key bytes (alias for new)
130    ///
131    /// # Arguments
132    /// * `pub_key` - The public key bytes
133    ///
134    /// # Returns
135    /// - `Result<VerifierPair, CryptoError>`: The constructed verifier or an error
136    pub fn from_bytes(pub_key: &[u8]) -> Result<Self, CryptoError> {
137        let pub_key = falconpadded1024::PublicKey::from_bytes(pub_key)?;
138        Ok(Self { pub_key })
139    }
140
141    /// Converts the public key to bytes
142    ///
143    /// # Returns
144    /// A vector containing the public key bytes
145    pub fn to_bytes(&self) -> Vec<u8> {
146        self.pub_key.as_bytes().to_vec()
147    }
148}
149
150impl ViewOperations for VerifierPair {
151    fn pub_key(&self) -> &falconpadded1024::PublicKey {
152        &self.pub_key
153    }
154}
155
156/// A complete key pair used for both signing and verification
157///
158/// This struct represents a post-quantum cryptography key pair used for
159/// creating digital signatures and verifying them. It contains both
160/// public and secret key components using the Falcon-padded-1024 algorithm.
161#[derive(Clone)]
162pub struct SignerPair {
163    pub_key: falconpadded1024::PublicKey,
164    sec_key: falconpadded1024::SecretKey,
165}
166
167impl SignerPair {
168    /// Creates a new random signer pair
169    ///
170    /// # Returns
171    /// A new SignerPair with generated public and secret keys
172    pub fn create() -> Self {
173        let (pk, sk) = falconpadded1024_keypair();
174        Self {
175            pub_key: pk,
176            sec_key: sk,
177        }
178    }
179
180    /// Signs a message using this pair's secret key
181    ///
182    /// # Arguments
183    /// * `msg` - The message to sign
184    ///
185    /// # Returns
186    /// A signed message that can be verified by others
187    pub fn sign(&self, msg: &[u8]) -> falconpadded1024::SignedMessage {
188        falconpadded1024::sign(msg, &self.sec_key)
189    }
190
191    /// Creates a signer pair from separate public and secret key bytes
192    ///
193    /// # Arguments
194    /// * `pub_key` - The public key bytes
195    /// * `sec_key` - The secret key bytes
196    ///
197    /// # Returns
198    /// - `Result<SignerPair, CryptoError>`: The constructed signer pair or an error
199    pub fn from_bytes(pub_key: &[u8], sec_key: &[u8]) -> Result<Self, CryptoError> {
200        let pub_key = falconpadded1024::PublicKey::from_bytes(pub_key)?;
201        let sec_key = falconpadded1024::SecretKey::from_bytes(sec_key)?;
202        Ok(Self { pub_key, sec_key })
203    }
204
205    /// Converts the key pair to raw byte arrays
206    ///
207    /// # Returns
208    /// - `Result<([u8; PUBLICKEYBYTES], [u8; SECRETKEYBYTES]), CryptoError>`:
209    ///   A tuple containing the public and secret keys as byte arrays
210    pub fn to_bytes(
211        &self,
212    ) -> Result<
213        (
214            [u8; PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES],
215            [u8; PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_SECRETKEYBYTES],
216        ),
217        CryptoError,
218    > {
219        Ok((
220            self.pub_key.as_bytes().try_into()?,
221            self.sec_key.as_bytes().try_into()?,
222        ))
223    }
224
225    /// Converts the key pair to a single byte vector with public key followed by secret key
226    ///
227    /// # Returns
228    /// A vector containing the concatenated public and secret key bytes
229    pub fn to_bytes_uniform(&self) -> Vec<u8> {
230        let mut bytes = Vec::new();
231        bytes.extend_from_slice(self.pub_key.as_bytes());
232        bytes.extend_from_slice(self.sec_key.as_bytes());
233        bytes
234    }
235
236    /// Creates a signer pair from a single byte slice containing both public and secret keys
237    ///
238    /// # Arguments
239    /// * `bytes` - The concatenated public and secret key bytes
240    ///
241    /// # Returns
242    /// - `Result<SignerPair, CryptoError>`: The constructed signer pair or an error
243    pub fn from_bytes_uniform(bytes: &[u8]) -> Result<Self, CryptoError> {
244        if bytes.len()
245            != PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES
246                + PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_SECRETKEYBYTES
247        {
248            return Err(CryptoError::IncongruentLength(
249                PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES
250                    + PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_SECRETKEYBYTES,
251                bytes.len(),
252            ));
253        }
254        let pub_key = falconpadded1024::PublicKey::from_bytes(
255            &bytes[..PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES],
256        )?;
257        let sec_key = falconpadded1024::SecretKey::from_bytes(
258            &bytes[PQCLEAN_FALCONPADDED1024_CLEAN_CRYPTO_PUBLICKEYBYTES..],
259        )?;
260        Ok(Self { pub_key, sec_key })
261    }
262}
263
264impl ViewOperations for SignerPair {
265    fn pub_key(&self) -> &falconpadded1024::PublicKey {
266        &self.pub_key
267    }
268}
269
270#[cfg(test)]
271mod tests {
272    use super::*;
273
274    #[test]
275    fn test_signer_sign() {
276        let signer = SignerPair::create();
277        let msg = b"Hello, World!";
278        let sig = signer.sign(msg);
279
280        assert!(signer.verify_comp(msg, &sig.as_bytes().to_vec()).unwrap());
281    }
282
283    #[test]
284    fn test_verifier_verify() {
285        let signer = SignerPair::create();
286        let msg = b"Hello, World!";
287        let sig = signer.sign(msg);
288
289        let verifier = VerifierPair::new(signer.pub_key().as_bytes()).unwrap();
290        assert!(verifier.verify_comp(msg, &sig.as_bytes().to_vec()).unwrap());
291    }
292
293    #[test]
294    fn test_verify_message() {
295        let signer = SignerPair::create();
296        let msg = b"Hello, World!";
297        let sig = signer.sign(msg);
298
299        let verifier = VerifierPair::new(signer.pub_key().as_bytes()).unwrap();
300        let verified_msg = verifier.verify_message(&sig).unwrap();
301
302        assert_eq!(msg.to_vec(), verified_msg);
303    }
304
305    #[test]
306    fn test_signer_bytes() {
307        let signer = SignerPair::create();
308        let (pub_key, sec_key) = signer.to_bytes().unwrap();
309
310        let signer2 = SignerPair::from_bytes(&pub_key, &sec_key).unwrap();
311        assert_eq!(signer.pub_key().as_bytes(), signer2.pub_key().as_bytes());
312    }
313
314    #[test]
315    fn test_verifier_bytes() {
316        let signer = SignerPair::create();
317        let verifier = VerifierPair::new(signer.pub_key().as_bytes()).unwrap();
318        let pub_key = verifier.to_bytes();
319
320        let verifier2 = VerifierPair::from_bytes(&pub_key).unwrap();
321        assert_eq!(
322            verifier.pub_key().as_bytes(),
323            verifier2.pub_key().as_bytes()
324        );
325    }
326}