A post-quantum research blockchain with hand-rolled zk-STARK shielded payments, built with audit-readiness discipline. 23-entry threat model. 5 self-disclosed bugs. Ready for external review.
QChain explores what it takes to build a system secure against today's adversaries AND against future quantum computers AND with real privacy AND on a working peer-to-peer network — all in one coherent project, with every claim traceable to code and tests.
A complete research blockchain: transparent, shielded, and fully-anonymous transactions coexist in the same blocks, gossiped between real nodes, with a hand-rolled zk-STARK system written in Rust. Persistent, encrypted, rate-limited, authenticated.
Post-quantum signatures, quantum randomness, zk-STARK design from scratch (AIR, FRI, Fiat-Shamir), shielded pool design, P2P consensus, fork resolution — and how to apply audit-readiness discipline across the full stack.
Production cryptocurrency software. No BFT consensus, no TLS, no peer authentication, no peer-reviewed cryptographic analysis. Every limitation is documented as a numbered threat with explicit status; nothing is hidden in the margins.
Today's blockchains face two adversaries that aren't going away.
A sufficiently large quantum computer recovers private keys from public keys in polynomial time. Every secp256k1-signed transaction on Bitcoin / Ethereum becomes forgeable retroactively.
Bitcoin and Ethereum reveal sender, recipient, and amount of every payment. Address clustering deanonymizes most users within months of normal activity.
Each implemented end-to-end. Not stubbed.
Dilithium / ML-DSA-65 (NIST FIPS 204) replaces ECDSA on every transaction.
IBM Quantum QPU seeds stake-weighted PoS proposer selection.
Custom AIR over Goldilocks in Rust. 110 tests including adversarial cases.
TCP gossip, message dedup, fork resolution, per-peer rate limiting.
FastAPI + WebSocket + React UI. Bearer-token auth. Multi-node convergence.
Compose them as needed. Or use all three.
| Property | Transparent | Shielded (M3) | Schnorr Anon (M4) | STARK Anon (M8.6+) | Mixer (M10) |
|---|---|---|---|---|---|
| Note values hidden | ✗ | ✓ | ✓ | ✓ | fixed denom |
| Recipient pubkey hidden | ✗ | ✓ | ✓ | ✓ | ✓ |
| Spender pubkey hidden | ✗ | ✗ | ✓ | ✓ | ✓ |
| Cross-spend unlinkability | ✗ | ✗ | ✓ | ✓ | ✓ |
| Which leaf was spent: hidden | n/a | ✗ | ✗ | ✓ | ✓ |
| Value conservation in-proof | n/a | ✗ | ✗ | ✓ | ✓ |
| Same-block timing defense | n/a | n/a | n/a | n/a | ✓ |
| Anonymity set size | n/a | n/a | — | 1,048,576 | per denom |
| Post-quantum safe | ✓ | ✓ | ✗ | ✓ | ✓ |
What an external observer sees from each transaction.
M4's Schnorr proofs reveal the specific leaf being spent. And Schnorr breaks under quantum. So we built our own zk-STARK system in Rust.
M4 reveals which leaf was spent through the public Merkle path. That's unlinkable identity, not real anonymity. And Schnorr falls to Shor's algorithm.
A succinct proof that the spender knows some leaf in the pool — without revealing which one. Hash-based, quantum-safe by construction.
Using an existing SNARK library would hide the AIR design choices that matter. The premise is honest cryptography end-to-end. Built on Winterfell; the AIR is ours.
// trace layout: 17 cols × 64 rows Block 0 (rows 0– 7): LEAF → P0 Block 1 (rows 8–15): P0 + sib₁ → P1 Block 2 (rows 16–23): P1 + sib₂ → P2 Block 3 (rows 24–31): P2 + sib₃ → ROOT Rows 32–63: padding (state unchanged) // four constraint groups, all gated by periodic columns hash round deg 8 Rescue-Prime equation, fires within-block block boundary deg 3 next.input = swap_by_dir(prev.output, sibling) witness static deg 2 dir and sib stay constant within each 8-row block direction binary deg 2 dir × (dir − 1) = 0 — every direction bit is 0 or 1
Every limitation shipped open. Every closure has its own milestone or pass. None hand-waved.
| Gap | What it was | Original | Status | Closed by |
|---|---|---|---|---|
| A | Value conservation — unshield amount not bound to leaf value | OPEN | CLOSED | M8.8-A1 (range proof via 64 bit-decomposition cols) |
| B | Nullifier binding — same note spendable many times | OPEN | CLOSED | M8.6 (AIR computes nullifier = H(sk+1, r, v)) |
| C | Anonymity set ≤ 16 — too small to hide spends | OPEN | CLOSED | M8.9 (sparse Merkle depth 20, set size 1,048,576) |
| D | Pool not chain-replicated — each node had its own pool | OPEN | CLOSED | M8.7-D (ShieldTransaction gossiped + replayed) |
| E | Partial-spend change outputs — every spend consumed full leaf | OPEN | CLOSED | M8.11 (4 phases — change-output AIR + value-binding) |
| — | Chain-replay validation pattern (M8.10 admission ≡ replay) | OPEN | CLOSED | M8.10 (is_valid() re-verifies historical proofs) |
| F | Persistence — chain & wallet in-memory only | OPEN | CLOSED | PERSISTENCE pass (versioned JSON, restart-safe) |
| G | Mixer pool — fixed denomination + timing-attack defense (T13) | OPEN | CLOSED | M10 (4 phases) + M-timing (historical-root anchoring) |
| H | Coinbase inflation — replay-side reward check missing | OPEN | CLOSED | AUDIT-FOLLOWUP (self-found; replay validation added) |
| I | Transparent-tx replay — same tx mineable twice (found by Hypothesis) | OPEN | CLOSED | PROPERTY-TESTING (self-found; mined_txids set added) |
| J | Wallet key compromise (T21) — plaintext JSON only | OPEN | CLOSED | WALLET-KEY-ENCRYPTION (argon2id + AES-256-GCM) |
| K | Gossip flood / DoS (T15, T23) — unbounded message rate | OPEN | CLOSED | RATE-LIMITING (per-peer per-msg sliding window + MAX_BLOCK_TX) |
| L | Dashboard endpoint abuse (T22) — unauthenticated /api | OPEN | CLOSED | DASHBOARD-AUTH (bearer-token auth on all /api and /ws) |
| M | Same-height-fork ping-pong — infinite get_blocks loop (self-found) | OPEN | CLOSED | RATE-LIMITING side-effect (one-line guard in _handle_blocks) |
| N | Rescue-Prime constants source bug (Winterfell-extracted) | OPEN | CLOSED | DIFFERENTIAL-AIR-PHASE3 (algebraic + regression + snapshot harness) |
Over the past year, the project ran a deliberate audit-readiness arc: 11 passes designed to make external review productive. The arc is done. The materials are public. The next step is engagement, not more code.
FORMAL · FORMAL, MODULO · DEFENDED · HEURISTIC · NOT DEFENDED. Every threat scored honestly. Reading the threat model is reading the codebase.
Coinbase inflation, transparent-tx replay (Hypothesis-found), same-height-fork ping-pong, and two doc-vs-code drift defects. All documented with discovery mechanism and fix.
Layer 1: algebraic self-checks. Layer 2: regression vectors. Layer 3: snapshot harness. Catches the "circuit is wrong but positive examples pass" class of bug.
T1–T23 with explicit status, code references, and test references. 20 actively defended; 2 explicitly out of scope; 1 partially defended.
Milestone READMEs, audit package, threat model, publication, SoW, grant application, outreach plan. Every cross-reference checked.
AUDIT-SOW.md, AUDITOR-ONBOARDING.md, AUDIT-GRANT-APPLICATION.md, AUDIT-OUTREACH.md. The procurement layer is in place.
No marketing math. The numbers are what they are.
The line between cryptography and crypto-LARP is honesty about what works and what doesn't. These are the standing limitations after the full audit-readiness arc.