Skip to main content

falcon/
lib.rs

1//! # falcon — FN-DSA (FIPS 206) Post-Quantum Digital Signatures
2//!
3//! Native Rust implementation of **FN-DSA** (FFT over NTRU-Lattice-Based
4//! Digital Signature Algorithm), the NIST FIPS 206 standard formerly known
5//! as Falcon. Ported from the [C reference](https://falcon-sign.info/) by
6//! Thomas Pornin.
7//!
8//! ## Quick start — Pure FN-DSA
9//!
10//! ```rust
11//! use falcon::prelude::*;
12//!
13//! // Generate an FN-DSA-512 key pair
14//! let kp = FnDsaKeyPair::generate(9).unwrap();
15//!
16//! // Sign with no context (ph_flag = 0x00)
17//! let sig = kp.sign(b"Hello, post-quantum world!", &DomainSeparation::None).unwrap();
18//!
19//! // Verify
20//! FnDsaSignature::verify(sig.to_bytes(), kp.public_key(),
21//!     b"Hello, post-quantum world!", &DomainSeparation::None).unwrap();
22//! ```
23//!
24//! ## HashFN-DSA — pre-hash large messages
25//!
26//! ```rust
27//! use falcon::prelude::*;
28//!
29//! let kp = FnDsaKeyPair::generate(9).unwrap();
30//!
31//! // ph_flag = 0x01: message is SHA-256 hashed before signing
32//! let domain = DomainSeparation::Prehashed {
33//!     alg: PreHashAlgorithm::Sha256,
34//!     context: b"my-protocol-v1",   // optional, max 255 bytes
35//! };
36//! let sig = kp.sign(b"large document ...", &domain).unwrap();
37//! FnDsaSignature::verify(sig.to_bytes(), kp.public_key(),
38//!     b"large document ...", &domain).unwrap();
39//! ```
40//!
41//! ## Key serialization
42//!
43//! ```rust
44//! # use falcon::prelude::*;
45//! let kp = FnDsaKeyPair::generate(9).unwrap();
46//!
47//! let private_key = kp.private_key().to_vec();  // 1281 bytes (FN-DSA-512)
48//! let public_key  = kp.public_key().to_vec();   // 897 bytes
49//!
50//! // Import from both keys or from private key only
51//! let restored = FnDsaKeyPair::from_keys(&private_key, &public_key).unwrap();
52//! let restored2 = FnDsaKeyPair::from_private_key(&private_key).unwrap();
53//! assert_eq!(public_key, restored2.public_key());
54//! ```
55//!
56//! ## Security levels
57//!
58//! | `logn` | Variant | NIST Level | Private Key | Public Key | Signature |
59//! |--------|---------|------------|-------------|------------|-----------|
60//! | 9 | FN-DSA-512  | I | 1281 B | 897 B  | 666 B  |
61//! | 10 | FN-DSA-1024 | V | 2305 B | 1793 B | 1280 B |
62//!
63//! ## Modules
64//!
65//! | Module | Description |
66//! |--------|-------------|
67//! | [`prelude`] | Re-exports all core public types — `use falcon::prelude::*` |
68//! | [`safe_api`] | High-level SDK: keygen, sign, verify, serialization |
69//! | [`falcon`] | Low-level C-equivalent API (streamed signing, expanded keys) |
70//! | `codec`, `shake`, `rng`, … | Internal ports of the C reference |
71//!
72//! ## Features
73//!
74//! | Feature | Default | Description |
75//! |---------|---------|-------------|
76//! | `std` | ✅ | Cross-platform OS entropy via `getrandom` crate |
77//! | *(no std)* | — | `no_std` / WASM — use `generate_deterministic` |
78//! | `serde` | — | `Serialize`/`Deserialize` for all public types |
79
80#![no_std]
81#![allow(
82    clippy::needless_range_loop,
83    clippy::manual_range_contains,
84    clippy::identity_op,
85    clippy::excessive_precision,
86    clippy::too_many_arguments,
87    clippy::unnecessary_cast,
88    non_snake_case,
89    non_upper_case_globals,
90    dead_code
91)]
92
93#[cfg(feature = "std")]
94extern crate std;
95
96extern crate alloc;
97
98#[doc(hidden)]
99pub mod codec;
100#[doc(hidden)]
101pub mod common;
102pub mod falcon;
103#[doc(hidden)]
104pub mod fft;
105#[doc(hidden)]
106pub mod fpr;
107#[doc(hidden)]
108pub mod keygen;
109#[doc(hidden)]
110pub mod rng;
111pub mod safe_api;
112#[doc(hidden)]
113pub mod shake;
114#[doc(hidden)]
115pub mod sign;
116#[doc(hidden)]
117pub mod vrfy;
118
119/// Prelude — import the entire public API with `use falcon::prelude::*`.
120///
121/// ```rust
122/// use falcon::prelude::*;
123///
124/// let kp = FnDsaKeyPair::generate(9).unwrap();
125/// let sig = kp.sign(b"msg", &DomainSeparation::None).unwrap();
126/// FnDsaSignature::verify(sig.to_bytes(), kp.public_key(), b"msg",
127///     &DomainSeparation::None).unwrap();
128///
129/// // Expanded-key fast repeated signing
130/// let ek = kp.expand().unwrap();
131/// let sig2 = ek.sign(b"msg", &DomainSeparation::None).unwrap();
132/// FnDsaSignature::verify(sig2.to_bytes(), ek.public_key(), b"msg",
133///     &DomainSeparation::None).unwrap();
134/// ```
135pub mod prelude {
136    pub use crate::safe_api::{
137        DomainSeparation,
138        FalconError,
139        FalconKeyPair,   // backward-compat alias
140        FalconSignature, // backward-compat alias
141        FnDsaExpandedKey,
142        FnDsaKeyPair,
143        FnDsaSignature,
144        PreHashAlgorithm,
145    };
146}
147
148// Root-level convenience re-exports so `falcon::FnDsaKeyPair` works directly.
149pub use safe_api::{
150    DomainSeparation, FalconError, FalconKeyPair, FalconSignature, FnDsaExpandedKey, FnDsaKeyPair,
151    FnDsaSignature, PreHashAlgorithm,
152};