Production-grade post-quantum threshold multisignature library using Falcon-512 (NIST FIPS 206 / FN-DSA).
falcon-multisig provides M-of-N threshold signature schemes built entirely on
Falcon-512, the lattice-based signature algorithm standardised by NIST. It is
extracted from and validated against QuantaChain —
a production post-quantum blockchain that has run Falcon-512 at the consensus
layer across a live testnet.
The library is:
- Chain-agnostic. No dependency on any blockchain runtime, EVM, or specific transaction format. Integrate it into any protocol that needs threshold authorisation.
- WASM-compatible. Uses
falcon-rust(pure Rust, no C FFI) throughout. Runs in browsers and embedded targets. - Misuse-resistant. Domain separation (
FALCON_MULTISIG_V1:) is applied to all signed data internally. Secret keys are zeroized on drop. - Fully tested. Every public function is covered by unit tests. Integration tests verify end-to-end threshold workflows across all common M-of-N configurations.
BLS signatures — used by Ethereum and many POS chains for validator aggregation — are not quantum-resistant. Falcon-512 is the NIST-standardised replacement for lattice-based digital signatures (FIPS 206). It offers:
| Property | ECDSA (secp256k1) | BLS12-381 | Falcon-512 |
|---|---|---|---|
| Quantum resistance | No | No | Yes |
| Key size | 33 bytes | 48 bytes | 897 bytes |
| Signature size | 64 bytes | 96 bytes | ~666 bytes |
| Verification speed | Fast | Slow | Fast |
| Native aggregation | No | Yes | No |
The lack of native aggregation is the principal engineering challenge for Falcon-512 in large validator sets. This library addresses the M-of-N case explicitly and cleanly.
[dependencies]
falcon-multisig = "0.1"| Feature | Default | Description |
|---|---|---|
std |
yes | Enables std-dependent APIs and formatted errors |
serde |
yes | JSON serialization of all public types |
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 threshold
assert!(session.is_complete());
assert!(session.verify().unwrap());Run the included examples:
cargo run --example dao_governance
cargo run --example bridge_validatorsA DAO spending proposal requires 3 of 5 committee members to sign before execution. Any 3 members can authorise; the remaining 2 may be offline.
A bridge validator set of 7 requires a 4-of-7 supermajority to authorise a cross-chain transfer. The bridge address is derived deterministically from the validator set and policy.
Falcon-512 keypair with a zeroizing secret key.
let kp = KeyPair::generate();
let signature = kp.sign(b"message payload");
let address = kp.address();Immutable M-of-N committee configuration. The canonical multisig address is derived at construction time and is insertion-order-independent.
let config = ThresholdConfig::new(required, public_keys)?;
println!("{}", config.policy()); // "3-of-5"
println!("{}", config.address()); // "ms<40 hex chars>"Stateful session for a single message. Verifies each partial signature at insertion time.
let mut session = SigningSession::new(&config, message);
session.add_signature(index, signature)?;
session.verify()?;Low-level single-signature verification.
let valid = verify_partial(message, &signature, public_key_bytes, signer_index)?;| Type | Prefix | Example |
|---|---|---|
| Single key | 0x |
0x3f4a1b2c... (40 hex chars) |
| Multisig | ms |
ms3f4a1b2c... (40 hex chars) |
Both addresses are 20-byte truncated SHA3-256 hashes. The multisig address incorporates the sorted public key set and the (M, N) policy, ensuring that a 2-of-3 and a 3-of-3 committee with the same keys produce different addresses.
- Pass the raw message payload to
KeyPair::sign, not a pre-hashed digest. Domain separation (FALCON_MULTISIG_V1:) is applied internally before hashing. - Secret keys are never included in
Debugoutput orserdeserialization. - All secret key material is zeroized on drop via the
zeroizecrate. - This library is extracted from production code but has not yet been formally audited. Use appropriate caution in high-value deployments.
cargo benchResults on an AMD EPYC-Milan Processor (commodity VPS, single core). Note: Benchmarks were taken while concurrently running a live QuantaChain consensus node, indexer, and mining, proving the efficiency of the verification pipeline under heavy real-world server load.
| Operation | Time (approx) |
|---|---|
| Key generation | ~382 ms |
| Sign (single) | ~1.1 ms |
| Verify (single) | ~0.06 ms |
| 2-of-3 session | ~2.2 ms |
| 3-of-5 session | ~3.3 ms |
| Batch verify (100 sigs) | ~6.4 ms |
The Ethereum Foundation's leanMultisig
project targets aggregation of hash-based (XMSS) signatures via a custom zkVM.
falcon-multisig is complementary: it provides a straightforward, deployable
M-of-N scheme for Falcon-512 without ZK infrastructure, suitable for chains and
applications that need threshold PQC today rather than after a zkVM is production-ready.
ZKNox's ETHFALCON provides on-chain
(Solidity) Falcon verification. falcon-multisig operates off-chain and
chain-agnostically; it can be used alongside ETHFALCON to produce threshold
signatures that are then verified on-chain.
Extracted from and validated against QuantaChain, a production PQC blockchain that has operated Falcon-512 at the consensus layer across a live validator testnet. The core signing and M-of-N multisig logic is battle-tested in that environment.
Licensed under either of:
at your option.
Built by QuantaLabs.