This repository provides experimental implementations of post-quantum cryptographic schemes for the Stellar blockchain, explored both at the application level (via Soroban Smart Accounts) and at the protocol level, by studying signature schemes that are candidates for aggregation.
The direction of the work tracks Stellar discussion #1915 — Post-Quantum Signature Verification Host Functions in Soroban, which scopes native verification for the three NIST PQ signature schemes — ML-DSA (FIPS 204), FN-DSA / Falcon (FIPS 206), and SLH-DSA (FIPS 205). FALCON-512 is implemented today; see Roadmap for what's next.
Audited. Veridise audited the three contract crates under the Stellar SCF Soroban Security Audit Bank (report V2, 2026-09-10): five findings, none high or critical, all fixed in this code. The report and the audit pack are in
docs/audit/. The instances already deployed on testnet and mainnet predate the fixes, so do not use them in production or with real funds. An audit is not a guarantee of security.
| Path | Purpose |
|---|---|
contracts/falcon-512-core |
Pure-Rust, no_std, soroban-sdk-free Falcon-512 verifier. Shared by the two contracts so crypto fixes land in one place. |
contracts/soroban-falcon-verifier |
Standalone Soroban contract exposing verify(pk, msg, sig) -> bool as a public utility. |
contracts/soroban-falcon-smart-account |
Soroban CustomAccountInterface that authorizes transactions with a Falcon-512 signature over a domain-separated payload. Supports __constructor(falcon_pubkey) and two-step key rotation (propose_key / accept_key / cancel_key): a new key only becomes active after a proof-of-possession signature by that key, so a mistyped rotation cannot brick the account. |
web-demo |
Vite + React reference frontend driving the smart account — deploys, funds, and submits Falcon-signed transfers from the browser using a vendored falcon-wasm signer. Out of audit scope: frontends are user-replaceable; the contract must remain secure under any signer (see docs/audit/threat-model.md). |
e2e |
Reproducible testnet harness — produces an audit-grade JSON receipt with a real Falcon-signed transaction. See e2e/README.md. |
docs/audit |
The Veridise audit report and the security pack — per-finding write-ups, threat model, constant-time analysis, dependency / lint / Scout scans, remediation log, optimization report, raw tool outputs, and committed e2e receipts. Indexed in docs/audit/README.md. |
The verifier implements the NIST Round-3 Falcon-512 submission (the
"original Falcon" design) and is validated against the 100 official
Round-3 Falcon-512 KAT vectors. It interoperates with Round-3 Falcon
signers such as falcon.py, the
official C reference, and PQClean falcon-512/clean. For convenience we
also publish falcon-rust,
a thin binding to the reference C implementation.
Note on FIPS 206. This is not FN-DSA / FIPS 206. The forthcoming FIPS 206 standard changes the message-hashing preamble (a domain-separation byte, an application context string, and a hash of the public key bound into the challenge). Those bindings are tracked in the Roadmap; at the application layer the smart account already supplies its own domain separation. See
docs/audit/optimization-report.mdand the audit notes for details.
The smart-account contract holds the user's Falcon-512 public key in
instance storage. When Soroban's host runs __check_auth, the contract
prepends a fixed domain-separation tag (b"soroban-falcon-smart-account-v1")
to the host-provided signature_payload and Falcon-verifies the
provided signature against the stored public key. The
signature_payload itself is a SHA-256 of the
HashIdPreimageSorobanAuthorization XDR struct, which already binds
the network id, account nonce, expiration ledger, and the full root
invocation — so almost every replay vector is defeated by the host's
own preimage and the contract's job is essentially "refuse to undo
that". The standalone verifier contract is the same Falcon primitive
exposed without the smart-account wrapper.
# Build all three contract WASMs (writes to each crate's target/)
make build
# Run unit tests across all three crates
make test
# Run the testnet end-to-end harness (Falcon-signed transfer on testnet)
# Requires SOURCE_SECRET in e2e/.env — see e2e/README.md
make e2e
# Re-run the security tooling scans whose output lives in docs/audit/
make audit-scan # cargo audit + cargo clippy on every crate
make ct-scan # constant-time analysis fixturesPrerequisites: a recent stable rustc with the wasm32v1-none target
(rustup target add wasm32v1-none), cargo, the
stellar CLI
v23+, and bun v1+ for the e2e harness. The constant-time scan
additionally needs the
Trail of Bits constant-time-analysis
plugin or its analyzer script — see docs/audit/ct-analysis/run.sh.
.
├── README.md # this file
├── Makefile # build / test / e2e / audit-scan / ct-scan
├── LICENSE # MIT
├── contracts/
│ ├── falcon-512-core/ # no_std verify primitive (NTT, SHAKE-256)
│ ├── soroban-falcon-verifier/ # public verify(pk,msg,sig) contract
│ └── soroban-falcon-smart-account/ # CustomAccountInterface impl
├── web-demo/ # Vite + React demo of the smart account
├── e2e/ # reproducible testnet harness (Bun)
└── docs/
└── audit/ # audit report + security pack — see docs/audit/README.md
Veridise audited the three contract crates for the SCF Soroban Security
Audit Bank. The report (V2, 2026-09-10) found five issues, none high or
critical, and confirms all five fixed; it is in
docs/audit/reports/. The full pack (report,
per-finding write-ups, threat model, constant-time analysis, dependency /
lint / Scout scans, remediation log, optimization report, raw tool
outputs, and committed e2e receipts for every on-chain deployment) is
indexed in docs/audit/README.md.
| Area | Status |
|---|---|
falcon-512-core verify path |
Constant-time-clean at the contract's -Oz profile (see docs/audit/constant-time-analysis.md); 28 unit tests, including exhaustive field-arithmetic checks |
| Test coverage | 75 tests across the 3 crates (full suite green; the contract crates' integration and benchmark suites need --features testutils), including a tests/kat.rs suite that replays all 100 official NIST Round-3 Falcon-512 KAT vectors (tests/falcon512-KAT.rsp), wrong-message / wrong-public-key negatives, a DEC-002 malleability regression test, and long-message gas benchmarks (16 KiB and 64 KiB) |
| Smart-account contract | Domain-separated __check_auth, panic-free runtime paths, two-step key rotation (propose_key / accept_key / cancel_key), KAT + integration + benchmark tests |
| Standalone verifier contract | KAT + integration + benchmark tests; deterministic Soroban env-test snapshots committed under test_snapshots/; includes a DEC-002 malleability regression test and long-message gas benchmarks (16 KiB and 64 KiB) |
| Deployed (testnet) | Standalone verifier live at CDDZZJ3B3BMKBPJ7ZVMC3JQC7MDNIODUXYHBCHNCGVXAL56UFBEPM4RC — transactions and receipt in docs/audit/README.md. |
| Deployed (mainnet) | Standalone verifier live at CA5RY3BUC4AXNQ4MJJITOUZVMFO3MW3CF4743SIAD46CGY4ICSU6J7OY — WASM byte-identical to the testnet artifact; transactions and receipt in docs/audit/README.md. |
| Web demo | Reference frontend — out of audit scope; functional on testnet |
| End-to-end testnet flow | One full Falcon-signed transfer landed on testnet via the smart account (see receipt) |
| Mainnet | Standalone verifier deployed (see above). Audit complete (Veridise report V2: all five findings fixed in this code), but the deployed verifier predates the fixes and has not been redeployed. Production reliance on it, and any smart-account mainnet use, remain not recommended until then; the TM-002 follow-up is also still open. |
What's next, aligned with Stellar discussion #1915:
-
ML-DSA verifier (FIPS 204). Pure-Rust ML-DSA-44 / ML-DSA-65 verifier deployable as a Soroban smart contract, mirroring the structure of the FALCON-512 verifier. ML-DSA is the NIST-standardized general-purpose PQ signature, supported across HSMs, KMS providers, and consumer platforms (e.g. Apple CryptoKit, AWS / Google Cloud KMS).
-
SLH-DSA verifier (FIPS 205). Pure-Rust SLH-DSA-128s / SLH-DSA-128f verifier deployable as a Soroban smart contract. SLH-DSA is the conservative hash-based fallback in the NIST PQ portfolio: its security reduces to standard hash preimage and second-preimage resistance, making it the right fit for high-value vaults, governance, and key-rotation flows. Signing is expensive, but verification — the only path that runs on-chain — is plain SHAKE.
-
PQ signer registration in the Smart Account. Extend the Soroban Smart Account so a PQ public key (ML-DSA, FALCON-512, or SLH-DSA) — or a proof-based signature commitment (see below) — can be registered as a signer alongside existing signers. This is the "add another signer" form of the hybrid pattern: any registered signer can authorize a transaction, letting users pick a scheme (or rotate between them) without redeploying the account.
-
Public Soroban PQ benchmark harness. Compare host-function vs. pure-WASM verification costs across all three NIST schemes (ML-DSA, FALCON, SLH-DSA) inside a real Soroban contract, so the cost-profile arguments in #1915 are backed by reproducible numbers.
-
Proof-based signatures: a Stellar-native PQ migration path. Ed25519 under RFC 8032 already derives the signing scalar deterministically from a seed via SHA-512 — the seed is the preimage. When a quantum threat becomes realistic, Stellar can stop accepting Ed25519 signatures and start accepting proof-based signatures (specifically, a proof of seed): a PQ zero-knowledge proof that the holder of an address knows the seed
xsuch thatQ = (SHA-512-derived scalar of x) · G, without revealingx. This is the only migration strategy that satisfies all four desired properties (P1–P4) in the Coinbase Independent Advisory Board position paper on Quantum Computing and Blockchain, which cites this approach directly. The Soroban-side verifier is based on WHIR; a prototype and benchmarks are in progress. The same WHIR verifier plugs into the Smart Account as an additional signer type — a registered seed commitment authorizes a transaction by submitting a proof-based signature, sitting alongside the NIST PQ signers above.Crucially, this is straightforward to adopt on the signer side: wallets and custodians keep their existing Ed25519 keys, key derivation paths, and HSM/MPC stacks unchanged, and only need to add the ability to produce a proof over the seed they already hold. Compare this to rolling out a new PQ signature scheme, which requires new key formats, new HSM/KMS curve support, new MPC protocols, and a coordinated key-migration ceremony for every account. Proof-based signatures move the PQ work into software that sits next to the existing signer, rather than into the signer itself.
MIT — see LICENSE.
For security issues, please email
security@soundnesslabs.com rather
than opening a public issue. We will acknowledge receipt within two
business days. The standing remediation policy is documented in
docs/audit/remediation-log.md.