Build the post-quantum migration layer before it becomes urgent
QLSA aggregates thousands of post-quantum signatures into a single constant-size proof, targeting scalable blockchain verification without trusted setup and without forcing a hard fork.
QLSA (Quantum-Layered Signature Aggregation) is an open deep-tech project exploring how ML-DSA, Merkle commitments, and STARK proofs can make post-quantum blockchain systems operationally viable.
What's been built
Phase 6 complete — live on Ethereum Sepolia (2026-05-05). V23 production pipeline: 8 ML-DSA circuits in 1 STARK proof (3,505 trace columns). MVP-4 complete (2026-05-22): QLSAVerifierVFRI6 — O(1)-gas on-chain FRI verifier. MVP-5 complete (2026-05-30): QLSAVerifierVFRI7 + BatchRegistryV4 dual-VFRI7 — cross-proof binding (keccak256(batchRoot ‖ traceRoot)) prevents proof-mixing attacks. VFRI8 Phase 1 complete (2026-06-10): QLSAVerifierVFRI8 — Poseidon2 Merkle trees + Poseidon2 Fiat-Shamir channel — 20-query on-chain FRI verification ≤15M gas on Ethereum mainnet. BatchRegistryV5 dual-VFRI8. Security & code audit (2026-06-10): 7 fixes across 5 files; 3 crypto findings, 4 systems findings. 847 Solidity + 528 Python + 210 Rust + 71 TS tests — all CI green.
HttpClient._decode_json() guards all 7 JSON call-sites — proxy HTML responses (nginx 2xx) no longer crash the SDK. testnet/e2e.py sender_key recomputation eliminated; unused import hashlib removed. 239 Python tests green.boundRoot10 = keccak256(batchRoot ‖ traceRoot8) — mixing proofs from different witnesses fails Merkle verificationThe Problem
Direct migration from classical signatures to post-quantum signatures can severely inflate block payloads. That turns protocol safety progress into an operational scaling problem.
| Signature | Size | 3000 tx block | Operational impact |
|---|---|---|---|
| ECDSA (current) | ~70 bytes | ~220 KB | Fits today's assumptions |
| ML-DSA-65 (FIPS 204) | ~2,420 bytes | ~7.2 MB | Severe throughput penalty |
The Solution
QLSA is not a new signature scheme. It is a post-quantum aggregation layer that aims to make large signature sets proof-friendly, compact, and verifiable at fixed on-chain cost.
What QLSA does
- Aggregates
NML-DSA signatures into one batch commitment - Uses Merkle commitments to structure batch data
- Generates a STARK proof for batch correctness
- Allows fixed-cost on-chain verification independent of batch size
Why the architecture matters
- Heavy proving remains off-chain
- Public inputs can be kept minimal with commitment roots
- MVP can ship before full ML-DSA-inside-AIR is solved
- The system remains crypto-agile across future upgrades
Architecture
The system is split into three layers so that user flows stay familiar, proving stays off-chain, and on-chain verification remains lean.
Signing
Wallet-level signing using post-quantum keys.
- ML-DSA-65 for signatures
- Address derived from
SHA3-256(pubkey) - Intended to preserve a familiar wallet-style UX
Aggregation
Batch formation and proving pipeline.
- Collect transactions off-chain
- Verify ML-DSA signatures off-chain; V23 proves arithmetic witness (8 circuits) inside STARK
- Build Merkle tree with
SHA3-512; root bound into Fiat-Shamir channel (V22+) - Generate STARK proof — c̃ + merkle_root mixed; RangeQBatch proves az_hat ∈ [0,Q)
Verification
Constant-cost contract-side validation.
- Verify proof in Solidity verifier contract
- Store
merkle_rootand finalize the batch onchain_commitment = Blake2s(proof[:32] ∥ c_tilde[:32])[:16]— 128-bit binding- MVP-6: VFRI8 — Poseidon2 Merkle + Fiat-Shamir channel; 20-query verification ≤15M gas. Both LOG=10 and LOG=8 trace groups verified on-chain with 130-bit soundness.
MVP Strategy
The project intentionally separates realistic implementation milestones from the hardest research component.
| Stage | What STARK proves | ML-DSA in STARK | Status |
|---|---|---|---|
| MVP-1 | Core crypto & Merkle | No | ✓ Done |
| MVP-2 | Hash-chain + Poseidon2 AIR (Stwo) | No | ✓ Done |
| MVP-2b | ML-DSA batch proof (Rust + STARK) | Off-chain | ✓ Done |
| MVP-3+ | All 8 circuits inside AIR + RangeQBatch (V23) | Yes (V23) | ✓ Complete |
| MVP-4 | VFRI4/5/6 — O(1)-gas on-chain FRI verifier; BatchRegistryV4 | Yes | ✓ Done (2026-05-22) |
| MVP-5 | VFRI7 cross-proof binding; security audit round 2; code quality hardening | Yes | ✓ Done (2026-05-30) |
| MVP-6 | VFRI8: Poseidon2 Merkle + channel; 20-query ≤15M gas; BatchRegistryV5; security & code audit | Yes | ✓ Done (2026-06-10) |
Key risks
- ML-DSA inside STARK: All 8 circuits complete in V23 (NttBatch + AzFull + Ct1Full + InttBatch + WPrimeFull + NormCheckBatch + UseHintBatchV2 + RangeQBatch), 3,505 trace columns, 1 FRI commitment. c̃ + Merkle root Fiat-Shamir bound; RangeQBatch closes AzFull multiplication soundness gap.
- Aggregator trust model: the MVP relies on off-chain verification before challenge systems exist.
- Adoption timing: the need is real, but mainstream migration may still take years.
Tech Stack
The technical stack reflects a staged path: fast iteration now, stronger proving infrastructure later.
Cryptographic core
- ML-DSA-65
- SHA3-512 for Merkle hashing
- SHA3-256 for address derivation
- Python 3.10+
liboqs-python >= 0.14.0
STARK layer
- Stwo 2.2.0 — Circle STARK over M31 field
- Poseidon2-over-M31 AIR (t=2, α=5, 8 full rounds, 7 columns, 6 constraints ≤ deg 3)
- V23 single STARK: 8 ML-DSA circuits, 3,505 trace columns, 1 FRI commitment
- ML-DSA-65 FIPS 204 verifier in Rust; c̃ + Merkle root Fiat-Shamir binding
- FRI blowup ×64, N_FRI_QUERIES=20, POW_BITS=10 — 130-bit soundness; zeroize crate for secure key wipe
- nightly-2025-07-01 Rust toolchain
Contracts & infra
- Solidity + Hardhat 2.28
- VFRI8 verifier stack: CM31 · QM31 · Blake2s · Poseidon2M31 · Poseidon2MerkleVerifier · Poseidon2Channel · CirclePoint · QLSAVerifierVFRI8
- BatchRegistryV5 — dual-VFRI8 with cross-proof binding
- FastAPI aggregator + rate limiting (proxy-aware, stale eviction)
- Python SDK (Wallet, LocalClient, WitnessStatus) + TypeScript SDK
Performance targets
| Batch size | 3,000 tx |
| Proof size | 90–200 KB |
| On-chain verification | O(1) |
| ML-DSA-65 sign (avg) | 0.12 ms / tx |
| Merkle build N=3000 | 7.1 ms |
| Full pipeline N=3000 | 354 ms |
| V23 STARK columns | 3,505 (649+1523+295+649+24+15+61+288+1 preproc) |
| 20-query VFRI8 gas | ≤15M gas (Poseidon2 Merkle ~10K gas/path vs ~800K for Blake2s) |
| Solidity tests | 847 passing |
| Python tests | 528 passing (with PyO3) / 336 without |
| Rust tests | 210 passing |
| TS tests | 71 passing |
| CI pipeline | 5 / 5 jobs green |
Repository snapshot
QLSA/ ├── core/ # ML-DSA, Merkle, batch ├── aggregator/ # Mempool, batcher, FastAPI ├── stark/ # Python prover/verifier wrappers ├── stark_stwo/ # Stwo STARK + ML-DSA AIR circuits ├── contracts/ │ └── src/verifier/ │ ├── CM31.sol # GF((2³¹−1)[i]) │ ├── QM31.sol # quartic extension │ ├── Blake2s.sol # pure-Solidity │ ├── Poseidon2M31.sol # t=2 over M31 │ ├── Poseidon2MerkleVerifier.sol │ ├── Poseidon2Channel.sol # Fiat-Shamir │ ├── MerkleVerifier.sol │ ├── TwoChannel.sol # Fiat-Shamir (Blake2s) │ └── CirclePoint.sol # CanonicCoset + FRI fold ├── sdk/python/ # Wallet, LocalClient ├── sdk/js/ # TypeScript AggregatorClient ├── testnet/ # E2E demo, deploy, submit └── tests/ # 847 Sol + 528 Py + 210 Rust + 71 TS
Roadmap
The roadmap prioritizes a credible implementation path before expanding into the hardest proving research.
Phase 1 — Core
✓ CompleteML-DSA-65/44/87 keys, signing, transaction model, SHA3-512 Merkle tree, batch aggregation.
Phase 2 — STARK Prototype
✓ CompleteStwo 2.2.0 Circle STARK — Poseidon2-over-M31 AIR (t=2, α=5, 8 full rounds, 7 main columns, 4 preproc columns, 6 constraints ≤ deg 3), ML-DSA-65 batch verifier in Rust (FIPS 204), FRI blowup ×4. 128-bit Blake2s commitment. 210 Rust tests green.
Phase 3 — Smart Contracts
✓ CompleteQLSAVerifierFull, QLSAVerifierBound (Merkle-root-bound Blake2s, bytes16 128-bit commitment), BatchRegistry, BatchRegistryV2 — all deployed (Hardhat). Contract tests green.
Phase 4 — Aggregator Node
✓ CompleteIn-memory mempool (thread-safe, atomic drain), auto-batcher with transaction recovery, FastAPI REST endpoint. Full STARK prove→submit pipeline via PyO3 native FFI.
Phase 5 — SDK
✓ CompletePython SDK (wallet + async client) and TypeScript/JavaScript SDK with full input validation and typed API. wipe_key() backed by Rust zeroize crate (volatile writes) for secure key wipe.
Phase 6 — Testnet
✓ CompleteLive on Ethereum Sepolia (2026-05-05). QLSAVerifierBound: 0xF2dcad845F0fb4a11106E4c4cF23D260a3CB65Dd · BatchRegistryV2: 0xF44A51CF1d7620e070ecaf611685418DE4679879. First batch: tx 0x5a9215d2aeb4…bd82, 3234 bytes, finalized in 9.16 s. Security hardening: nonce registry, rate limiting, pubkey validation.
MVP-3+ — ML-DSA Native in AIR (V22/V23)
✓ CompleteAll 8 ML-DSA-65 arithmetic circuits unified in one FRI commitment (V23, 3,505 trace columns): NttBatch (LOG=10, 649 cols) + AzFull (LOG=8, 1523 cols) + Ct1Full (LOG=8, 295 cols) + InttBatch (LOG=10, 649 cols) + WPrimeFull (LOG=8, 24 cols) + NormCheckBatch (LOG=8, 15 cols) + UseHintBatchV2 (LOG=8, 61 cols + 1 preproc) + RangeQBatch (LOG=8, 288 cols). Fiat-Shamir transcript: c̃ → merkle_root → Tree0 → Tree1. RangeQBatch closes AzFull multiplication soundness gap.
MVP-4 — Mainnet-grade On-chain Verifier
✓ Complete (2026-05-22)Full on-chain Circle STARK FRI verifier (Solidity). Verifier library stack: CM31 · QM31 · Blake2sYul · MerkleVerifier · TwoChannel · CirclePoint · QLSAVerifierV4–V13 · VFRI–VFRI6. QLSAVerifierVFRI6: O(1)-gas off-chain OODS combo — 649, 1298 and 2206-column traces all verified within 15M gas. BatchRegistryV4: dual-VFRI6 registry.
MVP-5 — Cross-Proof Binding & Security Hardening
✓ Complete (2026-05-30)QLSAVerifierVFRI7: adds mixRoot(merkleRoot) before drawQueries — FRI query indices depend on the batch Merkle root, preventing proof-mixing attacks. BatchRegistryV4 updated: boundRoot10 = keccak256(batchRoot ‖ traceRoot8) / boundRoot8 = keccak256(batchRoot ‖ traceRoot10) — cross-binding both LOG groups. Security audit round 2: 24 findings resolved. Code audit 2026-06-03: HttpClient._decode_json() + e2e.py sender_key. 847 Solidity + 239 Python + 210 Rust + 39 TS tests — all CI green.
MVP-6 — VFRI8: Poseidon2 Trace Commitment
✓ Complete (2026-06-10)QLSAVerifierVFRI8: replaces Blake2s Merkle trees and Fiat-Shamir channel with Poseidon2-over-M31 — 20-query on-chain FRI verification fits within 15M gas on Ethereum mainnet (vs ~300M gas with Blake2s). Gas breakdown: 20 queries × 2 paths × depth=10 × ~1000 gas/permute ≈ 400K gas (Merkle) + ~5M (rest) ≈ 5.4M total. BatchRegistryV5: dual-VFRI8 registry with identical cross-proof binding logic (keccak256(batchRoot ‖ traceRoot)). Commitment format unchanged: Blake2s(proof[:32] ∥ merkleRoot)[:16]. Security & code audit 2026-06-10: 7 fixes — VFRI8 OODS division-by-zero guard, cross-bound num_folds param, BatchRegistryV4/V5 short-proof calldataload guard, API rate limit on /stats+/config, VFRI8 witness_commitment fallback, _sender_txs eviction sync. 847 Solidity + 528 Python + 210 Rust + 71 TS tests — all CI green.
FAQ
Short answers to the questions most people will ask when they first encounter the project.
Is QLSA a new signature algorithm?
No. QLSA is an aggregation and verification architecture built around post-quantum signatures such as ML-DSA.
Why not just replace ECDSA directly?
Because the size increase of post-quantum signatures can cause major throughput and cost problems if deployed naively.
Does QLSA already prove ML-DSA inside STARK?
Yes — V23 is the production pipeline. All 8 ML-DSA-65 arithmetic circuits are unified in one FRI commitment (3,505 trace columns): NttBatch + AzFull + Ct1Full + InttBatch + WPrimeFull + NormCheckBatch + UseHintBatchV2 + RangeQBatch. c̃ and batch Merkle root are both mixed into Fiat-Shamir, binding each proof to one specific witness and batch.
What on-chain verifier exists?
MVP-6 (2026-06-10): QLSAVerifierVFRI8 + BatchRegistryV5 (dual-VFRI8). Poseidon2 Merkle trees + Poseidon2 Fiat-Shamir channel — 20-query on-chain FRI verification ≤15M gas (Poseidon2 Merkle path ~10K gas vs ~800K gas for Blake2s). Both LOG=10 (1298 cols) and LOG=8 (2206 cols) trace groups verified within 15M gas with 20 queries. On-chain soundness: LOG_BLOWUP=6 × N_FRI_QUERIES=20 + POW_BITS=10 = 130-bit ✓ (matches off-chain prover config).
Is this production-ready?
No. QLSA is research-stage software (not audited by external parties). Infrastructure is fully implemented and tested (847 Solidity + 528 Python + 210 Rust + 71 TS tests). Not recommended for production use or real funds.
Interested in PQC, ZK proofs, or blockchain infrastructure?
QLSA is an open research and engineering effort. Contributions, technical feedback, research discussion, and collaboration are welcome.