1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! # falcon-multisig
//!
//! Production-grade post-quantum threshold multisignature library based on Falcon-512
//! (NIST FIPS 206 / FN-DSA).
//!
//! ## Overview
//!
//! This library provides M-of-N threshold signature schemes built entirely on Falcon-512,
//! the lattice-based signature algorithm standardised by NIST. It is designed to be:
//!
//! - **Chain-agnostic** — no dependency on any specific blockchain runtime or VM.
//! - **Production-ready** — extracted from and validated against a live PQC blockchain
//! (QuantaChain) running Falcon-512 at the consensus layer.
//! - **WASM-compatible** — uses `falcon-rust` (pure Rust, no C FFI) throughout.
//! - **Misuse-resistant** — domain separation on all signed data; secret keys are
//! zeroized on drop.
//!
//! ## Threat Model
//!
//! The cryptographic security reduces to the hardness of the NTRU problem and the
//! Short Integer Solution (SIS) problem over NTRU lattices — both believed to be
//! quantum-resistant under current knowledge. No classical or known quantum algorithm
//! breaks Falcon-512 with fewer than 2^128 operations.
//!
//! ## Quick Start
//!
//! ```rust
//! use falcon_multisig::{KeyPair, ThresholdConfig, SigningSession};
//!
//! // Generate a 2-of-3 committee
//! let keypairs: Vec<KeyPair> = (0..3).map(|_| KeyPair::generate()).collect();
//! let public_keys: Vec<_> = keypairs.iter().map(|kp| kp.public_key().clone()).collect();
//!
//! let config = ThresholdConfig::new(2, public_keys).unwrap();
//!
//! // Each signer produces a partial signature
//! let message = b"transfer:alice:bob:1000";
//! let mut session = SigningSession::new(&config, message);
//!
//! session.add_signature(0, keypairs[0].sign(message)).unwrap();
//! session.add_signature(1, keypairs[1].sign(message)).unwrap();
//!
//! // Verify the complete threshold signature
//! assert!(session.verify().unwrap());
//! ```
//!
//! ## Feature Flags
//!
//! | Feature | Default | Description |
//! |---------|---------|-------------|
//! | `std` | yes | Enables `std`-dependent APIs and error formatting |
//! | `serde` | yes | Enables JSON serialization of all public types |
//!
//! ## Security Notes
//!
//! - **Never reuse a `KeyPair` across incompatible domain contexts** — always pass the
//! full message payload to `KeyPair::sign`, not a pre-hashed digest.
//! - Domain separation (`FALCON_MULTISIG_V1:`) is prepended internally before signing.
//! - All secret key bytes are zeroized when a `KeyPair` is dropped.
extern crate alloc;
pub use MultisigAddress;
pub use Error;
pub use KeyPair;
pub use SigningSession;
pub use ThresholdConfig;
pub use verify_partial;
/// The domain separation tag prepended to every message before signing.
///
/// Changing this value constitutes a breaking protocol change. All peers must
/// agree on the same tag for cross-party verification to succeed.
pub const DOMAIN_TAG: & = b"FALCON_MULTISIG_V1:";
/// Byte length of a Falcon-512 public key.
pub const PUBLIC_KEY_BYTES: usize = 897;
/// Maximum byte length of a raw Falcon-512 signature.
pub const SIGNATURE_MAX_BYTES: usize = 666;
/// Minimum byte length of a valid raw Falcon-512 signature.
pub const SIGNATURE_MIN_BYTES: usize = 10;