Skip to main content

lib_q_fn_dsa/
lib.rs

1//! lib-Q FN-DSA - Post-Quantum Digital Signatures
2//!
3//! This crate provides a libQ-compatible wrapper around the FN-DSA (FIPS 206)
4//! post-quantum digital signature algorithm, which is based on FALCON with
5//! enhanced performance and compact signature sizes.
6
7// Suppress clippy warnings in reference implementation code
8// These are external implementations that shouldn't be modified
9#![allow(
10    clippy::too_many_arguments,
11    clippy::needless_range_loop,
12    clippy::uninlined_format_args,
13    clippy::must_use_candidate,
14    clippy::cast_precision_loss,
15    clippy::cast_lossless,
16    clippy::manual_clamp,
17    clippy::unused_self,
18    clippy::unnecessary_wraps,
19    clippy::let_and_return,
20    clippy::identity_op,
21    clippy::erasing_op,
22    clippy::struct_excessive_bools,
23    clippy::doc_markdown
24)]
25//!
26//! # Features
27//!
28//! - **NIST-Approved**: Implements NIST FIPS 206 (FN-DSA)
29//! - **High Performance**: Optimized for both x86_64 and ARM64 architectures
30//! - **Compact Signatures**: Smaller signature sizes compared to other post-quantum schemes
31//! - **Security Levels**: Supports Level 1 (128-bit) and Level 5 (256-bit) security
32//! - **Memory Safe**: Zero unsafe code, automatic memory zeroization
33//! - **Constant-Time**: Operations designed to prevent timing attacks
34//!
35//! # Security Levels
36//!
37//! FN-DSA provides two main security levels:
38//!
39//! - **Level 1 (128-bit security)**: n=512, suitable for most applications
40//! - **Level 5 (256-bit security)**: n=1024, for high-security applications
41//!
42//! # Example Usage
43//!
44//! ```rust,no_run
45//! use lib_q_core::{
46//!     SigKeypair,
47//!     SigPublicKey,
48//!     SigSecretKey,
49//!     Signature,
50//! };
51//! use lib_q_fn_dsa::{
52//!     FnDsa,
53//!     FnDsa512,
54//!     FnDsa1024,
55//! };
56//!
57//! fn main() -> Result<(), Box<dyn std::error::Error>> {
58//!     // Create an FN-DSA instance
59//!     let fn_dsa = FnDsa512::new();
60//!
61//!     // Generate a keypair
62//!     let keypair = fn_dsa.generate_keypair()?;
63//!
64//!     // Sign a message
65//!     let message = b"Hello, FN-DSA!";
66//!     let signature = fn_dsa.sign(&keypair.secret_key, message)?;
67//!
68//!     // Verify the signature
69//!     let is_valid =
70//!         fn_dsa.verify(&keypair.public_key, message, &signature)?;
71//!     assert!(is_valid);
72//!
73//!     Ok(())
74//! }
75//! ```
76
77#![cfg_attr(not(feature = "std"), no_std)]
78#![deny(unsafe_code)]
79#![deny(unused_qualifications)]
80
81extern crate alloc;
82
83#[cfg(not(feature = "std"))]
84use alloc::vec;
85// Re-export core types for public use
86#[cfg(feature = "alloc")]
87use alloc::vec::Vec;
88use core::marker::PhantomData;
89
90// Re-export FN-DSA types and constants
91pub use fn_dsa::{
92    DOMAIN_NONE,
93    FN_DSA_LOGN_512,
94    FN_DSA_LOGN_1024,
95    HASH_ID_RAW,
96    KeyPairGenerator,
97    KeyPairGeneratorStandard,
98    SigningKey,
99    SigningKeyStandard,
100    VerifyingKey,
101    VerifyingKeyStandard,
102    sign_key_size,
103    signature_size,
104    vrfy_key_size,
105};
106pub use lib_q_core::{
107    Error,
108    Result,
109    SigKeypair,
110    SigPublicKey,
111    SigSecretKey,
112    Signature,
113};
114// Import RNG traits and implementations
115use rand_core::CryptoRng;
116
117/// Get an appropriate RNG for the current environment
118fn get_rng() -> impl CryptoRng {
119    lib_q_random::FnDsaRng::new()
120}
121
122/// FN-DSA security level enumeration
123#[derive(Debug, Clone, Copy, PartialEq, Eq)]
124pub enum FnDsaSecurityLevel {
125    /// Level 1: 128-bit security (n=512)
126    Level1,
127    /// Level 5: 256-bit security (n=1024)
128    Level5,
129}
130
131impl FnDsaSecurityLevel {
132    /// Get the logn value for this security level
133    pub fn logn(&self) -> u32 {
134        match self {
135            FnDsaSecurityLevel::Level1 => FN_DSA_LOGN_512,
136            FnDsaSecurityLevel::Level5 => FN_DSA_LOGN_1024,
137        }
138    }
139
140    /// Get the key sizes for this security level
141    pub fn key_sizes(&self) -> (usize, usize, usize) {
142        let logn = self.logn();
143        (
144            sign_key_size(logn),
145            vrfy_key_size(logn),
146            signature_size(logn),
147        )
148    }
149}
150
151/// Base FN-DSA implementation trait
152pub trait FnDsaImpl {
153    /// Get the security level
154    fn security_level(&self) -> FnDsaSecurityLevel;
155
156    /// Get the logn value
157    fn logn(&self) -> u32;
158}
159
160/// FN-DSA Level 1 (128-bit security) implementation
161pub struct FnDsa512 {
162    _phantom: PhantomData<()>,
163}
164
165impl FnDsa512 {
166    /// Create a new FN-DSA Level 1 instance
167    pub fn new() -> Self {
168        Self {
169            _phantom: PhantomData,
170        }
171    }
172}
173
174impl FnDsaImpl for FnDsa512 {
175    fn security_level(&self) -> FnDsaSecurityLevel {
176        FnDsaSecurityLevel::Level1
177    }
178
179    fn logn(&self) -> u32 {
180        FN_DSA_LOGN_512
181    }
182}
183
184impl Signature for FnDsa512 {
185    fn generate_keypair(&self) -> Result<SigKeypair> {
186        // Generate keypair using the underlying FN-DSA implementation
187        let mut kg = KeyPairGeneratorStandard::default();
188        let mut sign_key = {
189            let v = vec![0; sign_key_size(self.logn())];
190            v
191        };
192        let mut vrfy_key = {
193            let v = vec![0; vrfy_key_size(self.logn())];
194            v
195        };
196
197        // Use a secure random number generator
198        let mut rng = get_rng();
199
200        kg.keygen(self.logn(), &mut rng, &mut sign_key, &mut vrfy_key);
201
202        Ok(SigKeypair::new(vrfy_key, sign_key))
203    }
204
205    fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>> {
206        // Decode the signing key
207        let mut sk = SigningKeyStandard::decode(secret_key.as_bytes()).ok_or_else(|| {
208            Error::InvalidKeySize {
209                expected: sign_key_size(self.logn()),
210                actual: secret_key.as_bytes().len(),
211            }
212        })?;
213
214        // Create signature buffer
215        let mut signature = {
216            let v = vec![0; signature_size(self.logn())];
217            v
218        };
219
220        // Use a secure random number generator
221        let mut rng = get_rng();
222
223        // Sign the message
224        sk.sign(
225            &mut rng,
226            &DOMAIN_NONE,
227            &HASH_ID_RAW,
228            message,
229            &mut signature,
230        );
231
232        Ok(signature)
233    }
234
235    fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool> {
236        // Validate signature size first
237        let expected_sig_size = signature_size(self.logn());
238        if signature.len() != expected_sig_size {
239            return Err(Error::InvalidSignatureSize {
240                expected: expected_sig_size,
241                actual: signature.len(),
242            });
243        }
244
245        // Decode the verifying key
246        let vk = VerifyingKeyStandard::decode(public_key.as_bytes()).ok_or_else(|| {
247            Error::InvalidKeySize {
248                expected: vrfy_key_size(self.logn()),
249                actual: public_key.as_bytes().len(),
250            }
251        })?;
252
253        // Verify the signature
254        let is_valid = vk.verify(signature, &DOMAIN_NONE, &HASH_ID_RAW, message);
255
256        Ok(is_valid)
257    }
258}
259
260impl Default for FnDsa512 {
261    fn default() -> Self {
262        Self::new()
263    }
264}
265
266/// FN-DSA Level 5 (256-bit security) implementation
267pub struct FnDsa1024 {
268    _phantom: PhantomData<()>,
269}
270
271impl FnDsa1024 {
272    /// Create a new FN-DSA Level 5 instance
273    pub fn new() -> Self {
274        Self {
275            _phantom: PhantomData,
276        }
277    }
278}
279
280impl FnDsaImpl for FnDsa1024 {
281    fn security_level(&self) -> FnDsaSecurityLevel {
282        FnDsaSecurityLevel::Level5
283    }
284
285    fn logn(&self) -> u32 {
286        FN_DSA_LOGN_1024
287    }
288}
289
290impl Signature for FnDsa1024 {
291    fn generate_keypair(&self) -> Result<SigKeypair> {
292        // Generate keypair using the underlying FN-DSA implementation
293        let mut kg = KeyPairGeneratorStandard::default();
294        let mut sign_key = {
295            let v = vec![0; sign_key_size(self.logn())];
296            v
297        };
298        let mut vrfy_key = {
299            let v = vec![0; vrfy_key_size(self.logn())];
300            v
301        };
302
303        // Use a secure random number generator
304        let mut rng = get_rng();
305
306        kg.keygen(self.logn(), &mut rng, &mut sign_key, &mut vrfy_key);
307
308        Ok(SigKeypair::new(vrfy_key, sign_key))
309    }
310
311    fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>> {
312        // Decode the signing key
313        let mut sk = SigningKeyStandard::decode(secret_key.as_bytes()).ok_or_else(|| {
314            Error::InvalidKeySize {
315                expected: sign_key_size(self.logn()),
316                actual: secret_key.as_bytes().len(),
317            }
318        })?;
319
320        // Create signature buffer
321        let mut signature = {
322            let v = vec![0; signature_size(self.logn())];
323            v
324        };
325
326        // Use a secure random number generator
327        let mut rng = get_rng();
328
329        // Sign the message
330        sk.sign(
331            &mut rng,
332            &DOMAIN_NONE,
333            &HASH_ID_RAW,
334            message,
335            &mut signature,
336        );
337
338        Ok(signature)
339    }
340
341    fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool> {
342        // Validate signature size first
343        let expected_sig_size = signature_size(self.logn());
344        if signature.len() != expected_sig_size {
345            return Err(Error::InvalidSignatureSize {
346                expected: expected_sig_size,
347                actual: signature.len(),
348            });
349        }
350
351        // Decode the verifying key
352        let vk = VerifyingKeyStandard::decode(public_key.as_bytes()).ok_or_else(|| {
353            Error::InvalidKeySize {
354                expected: vrfy_key_size(self.logn()),
355                actual: public_key.as_bytes().len(),
356            }
357        })?;
358
359        // Verify the signature
360        let is_valid = vk.verify(signature, &DOMAIN_NONE, &HASH_ID_RAW, message);
361
362        Ok(is_valid)
363    }
364}
365
366impl Default for FnDsa1024 {
367    fn default() -> Self {
368        Self::new()
369    }
370}
371
372/// Generic FN-DSA implementation that can work with any security level
373pub struct FnDsa {
374    security_level: FnDsaSecurityLevel,
375}
376
377impl FnDsa {
378    /// Create a new FN-DSA instance with the specified security level
379    pub fn new(security_level: FnDsaSecurityLevel) -> Self {
380        Self { security_level }
381    }
382
383    /// Create a new FN-DSA Level 1 instance
384    pub fn level1() -> Self {
385        Self::new(FnDsaSecurityLevel::Level1)
386    }
387
388    /// Create a new FN-DSA Level 5 instance
389    pub fn level5() -> Self {
390        Self::new(FnDsaSecurityLevel::Level5)
391    }
392
393    /// Get the security level
394    pub fn security_level(&self) -> FnDsaSecurityLevel {
395        self.security_level
396    }
397
398    /// Get the logn value
399    pub fn logn(&self) -> u32 {
400        self.security_level.logn()
401    }
402}
403
404impl Signature for FnDsa {
405    fn generate_keypair(&self) -> Result<SigKeypair> {
406        // Generate keypair using the underlying FN-DSA implementation
407        let mut kg = KeyPairGeneratorStandard::default();
408        let mut sign_key = {
409            let v = vec![0; sign_key_size(self.logn())];
410            v
411        };
412        let mut vrfy_key = {
413            let v = vec![0; vrfy_key_size(self.logn())];
414            v
415        };
416
417        // Use a secure random number generator
418        let mut rng = get_rng();
419
420        kg.keygen(self.logn(), &mut rng, &mut sign_key, &mut vrfy_key);
421
422        Ok(SigKeypair::new(vrfy_key, sign_key))
423    }
424
425    fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>> {
426        // Decode the signing key
427        let mut sk = SigningKeyStandard::decode(secret_key.as_bytes()).ok_or_else(|| {
428            Error::InvalidKeySize {
429                expected: sign_key_size(self.logn()),
430                actual: secret_key.as_bytes().len(),
431            }
432        })?;
433
434        // Create signature buffer
435        let mut signature = {
436            let v = vec![0; signature_size(self.logn())];
437            v
438        };
439
440        // Use a secure random number generator
441        let mut rng = get_rng();
442
443        // Sign the message
444        sk.sign(
445            &mut rng,
446            &DOMAIN_NONE,
447            &HASH_ID_RAW,
448            message,
449            &mut signature,
450        );
451
452        Ok(signature)
453    }
454
455    fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool> {
456        // Validate signature size first
457        let expected_sig_size = signature_size(self.logn());
458        if signature.len() != expected_sig_size {
459            return Err(Error::InvalidSignatureSize {
460                expected: expected_sig_size,
461                actual: signature.len(),
462            });
463        }
464
465        // Decode the verifying key
466        let vk = VerifyingKeyStandard::decode(public_key.as_bytes()).ok_or_else(|| {
467            Error::InvalidKeySize {
468                expected: vrfy_key_size(self.logn()),
469                actual: public_key.as_bytes().len(),
470            }
471        })?;
472
473        // Verify the signature
474        let is_valid = vk.verify(signature, &DOMAIN_NONE, &HASH_ID_RAW, message);
475
476        Ok(is_valid)
477    }
478}
479
480impl Default for FnDsa {
481    fn default() -> Self {
482        Self::level1()
483    }
484}
485
486/// Utility functions for FN-DSA
487pub mod utils {
488    use super::*;
489
490    /// Get the key sizes for a given security level
491    pub fn get_key_sizes(security_level: FnDsaSecurityLevel) -> (usize, usize, usize) {
492        security_level.key_sizes()
493    }
494
495    /// Validate key sizes for a given security level
496    pub fn validate_key_sizes(
497        security_level: FnDsaSecurityLevel,
498        sign_key_size: usize,
499        vrfy_key_size: usize,
500        signature_size: usize,
501    ) -> Result<()> {
502        let (expected_sign, expected_vrfy, expected_sig) = security_level.key_sizes();
503
504        if sign_key_size != expected_sign {
505            return Err(Error::InvalidKeySize {
506                expected: expected_sign,
507                actual: sign_key_size,
508            });
509        }
510
511        if vrfy_key_size != expected_vrfy {
512            return Err(Error::InvalidKeySize {
513                expected: expected_vrfy,
514                actual: vrfy_key_size,
515            });
516        }
517
518        if signature_size != expected_sig {
519            return Err(Error::InvalidKeySize {
520                expected: expected_sig,
521                actual: signature_size,
522            });
523        }
524
525        Ok(())
526    }
527}
528
529#[cfg(test)]
530mod tests {
531    use super::*;
532
533    type TestResult = std::result::Result<(), Box<dyn std::error::Error>>;
534
535    #[test]
536    fn test_fn_dsa512_creation() {
537        let fn_dsa = FnDsa512::new();
538        assert_eq!(fn_dsa.security_level(), FnDsaSecurityLevel::Level1);
539        assert_eq!(fn_dsa.logn(), FN_DSA_LOGN_512);
540    }
541
542    #[test]
543    fn test_fn_dsa1024_creation() {
544        let fn_dsa = FnDsa1024::new();
545        assert_eq!(fn_dsa.security_level(), FnDsaSecurityLevel::Level5);
546        assert_eq!(fn_dsa.logn(), FN_DSA_LOGN_1024);
547    }
548
549    #[test]
550    fn test_fn_dsa_generic_creation() {
551        let fn_dsa1 = FnDsa::level1();
552        assert_eq!(fn_dsa1.security_level(), FnDsaSecurityLevel::Level1);
553
554        let fn_dsa5 = FnDsa::level5();
555        assert_eq!(fn_dsa5.security_level(), FnDsaSecurityLevel::Level5);
556    }
557
558    #[test]
559    fn test_key_sizes() {
560        let (sign_size_512, vrfy_size_512, sig_size_512) = FnDsaSecurityLevel::Level1.key_sizes();
561        let (sign_size_1024, vrfy_size_1024, sig_size_1024) =
562            FnDsaSecurityLevel::Level5.key_sizes();
563
564        // Verify that 1024-bit keys are larger than 512-bit keys
565        assert!(sign_size_1024 > sign_size_512);
566        assert!(vrfy_size_1024 > vrfy_size_512);
567        assert!(sig_size_1024 > sig_size_512);
568
569        // Verify expected sizes (from FN-DSA specification)
570        assert_eq!(sign_size_512, 1281);
571        assert_eq!(vrfy_size_512, 897);
572        assert_eq!(sig_size_512, 666);
573
574        assert_eq!(sign_size_1024, 2305);
575        assert_eq!(vrfy_size_1024, 1793);
576        assert_eq!(sig_size_1024, 1280);
577    }
578
579    #[test]
580    fn test_utils_validation() {
581        // Test valid key sizes
582        let result = utils::validate_key_sizes(FnDsaSecurityLevel::Level1, 1281, 897, 666);
583        assert!(result.is_ok());
584
585        // Test invalid key sizes
586        let result = utils::validate_key_sizes(
587            FnDsaSecurityLevel::Level1,
588            1280,
589            897,
590            666, // Wrong sign key size
591        );
592        assert!(result.is_err());
593    }
594
595    #[test]
596    fn test_keypair_generation() -> TestResult {
597        let fn_dsa = FnDsa512::new();
598        let keypair = fn_dsa.generate_keypair()?;
599
600        assert_eq!(
601            keypair.public_key().as_bytes().len(),
602            vrfy_key_size(FN_DSA_LOGN_512)
603        );
604        assert_eq!(
605            keypair.secret_key().as_bytes().len(),
606            sign_key_size(FN_DSA_LOGN_512)
607        );
608
609        // Exercise signing and verification success path.
610        let message = b"coverage keypair generation message";
611        let signature = fn_dsa.sign(&keypair.secret_key, message)?;
612        assert_eq!(signature.len(), signature_size(FN_DSA_LOGN_512));
613        assert!(fn_dsa.verify(&keypair.public_key, message, &signature)?);
614
615        // Exercise invalid signature length error branch.
616        let invalid_signature = vec![0_u8; signature.len().saturating_sub(1)];
617        let verify_err = fn_dsa.verify(&keypair.public_key, message, &invalid_signature);
618        assert!(matches!(
619            verify_err,
620            Err(Error::InvalidSignatureSize {
621                expected,
622                actual
623            }) if expected == signature_size(FN_DSA_LOGN_512) && actual + 1 == expected
624        ));
625
626        // Exercise invalid secret key length error branch.
627        let invalid_secret_key = SigSecretKey::new(vec![0_u8; sign_key_size(FN_DSA_LOGN_512) - 1]);
628        let sign_err = fn_dsa.sign(&invalid_secret_key, b"invalid secret key");
629        assert!(matches!(
630            sign_err,
631            Err(Error::InvalidKeySize {
632                expected,
633                actual
634            }) if expected == sign_key_size(FN_DSA_LOGN_512)
635                && actual == sign_key_size(FN_DSA_LOGN_512) - 1
636        ));
637
638        // Exercise invalid public key length error branch.
639        let invalid_public_key = SigPublicKey::new(vec![0_u8; vrfy_key_size(FN_DSA_LOGN_512) - 1]);
640        let verify_key_err = fn_dsa.verify(&invalid_public_key, message, &signature);
641        assert!(matches!(
642            verify_key_err,
643            Err(Error::InvalidKeySize {
644                expected,
645                actual
646            }) if expected == vrfy_key_size(FN_DSA_LOGN_512)
647                && actual == vrfy_key_size(FN_DSA_LOGN_512) - 1
648        ));
649        Ok(())
650    }
651
652    #[test]
653    fn test_sign_and_verify() -> TestResult {
654        let fn_dsa = FnDsa512::new();
655        let keypair = fn_dsa.generate_keypair()?;
656
657        let message = b"Hello, FN-DSA!";
658        let signature = fn_dsa.sign(&keypair.secret_key, message)?;
659
660        let is_valid = fn_dsa.verify(&keypair.public_key, message, &signature)?;
661        assert!(is_valid, "Signature should be valid");
662
663        let wrong_message = b"Wrong message";
664        let is_valid = fn_dsa.verify(&keypair.public_key, wrong_message, &signature)?;
665        assert!(!is_valid, "Signature should be invalid for wrong message");
666        Ok(())
667    }
668
669    #[test]
670    fn test_sign_and_verify_1024() -> TestResult {
671        let fn_dsa = FnDsa1024::new();
672        let keypair = fn_dsa.generate_keypair()?;
673
674        let message = b"Hello, FN-DSA 1024!";
675        let signature = fn_dsa.sign(&keypair.secret_key, message)?;
676
677        let is_valid = fn_dsa.verify(&keypair.public_key, message, &signature)?;
678        assert!(is_valid, "Signature should be valid");
679        Ok(())
680    }
681}