Research project · audit-readiness arc complete · 499 tests

QChain

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.

post-quantum sigs
quantum randomness
zk-STARK proofs
shielded notes
P2P gossip
rate limiting
wallet encryption
differential AIR testing
honest scope
ELEVATOR PITCH

What is this?

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.

What it is

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.

What it teaches

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.

What it isn't

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.

THE THREAT MODEL

Two attacks. One chain that has to survive both.

Today's blockchains face two adversaries that aren't going away.

⚛ QUANTUM ADVERSARY

Shor's algorithm forges ECDSA

A sufficiently large quantum computer recovers private keys from public keys in polynomial time. Every secp256k1-signed transaction on Bitcoin / Ethereum becomes forgeable retroactively.

OUR ANSWER
Sign with Dilithium (NIST FIPS 204).
👁 SURVEILLANCE ADVERSARY

Public ledgers leak everything

Bitcoin and Ethereum reveal sender, recipient, and amount of every payment. Address clustering deanonymizes most users within months of normal activity.

OUR ANSWER
Spend via zero-knowledge STARK proof of ownership.
THE BIG IDEA

Five technical pillars

Each implemented end-to-end. Not stubbed.

1

Post-quantum signatures

Dilithium / ML-DSA-65 (NIST FIPS 204) replaces ECDSA on every transaction.

2

Quantum randomness

IBM Quantum QPU seeds stake-weighted PoS proposer selection.

3

Hand-rolled zk-STARKs

Custom AIR over Goldilocks in Rust. 110 tests including adversarial cases.

4

Full P2P network

TCP gossip, message dedup, fork resolution, per-peer rate limiting.

5

Live dashboard

FastAPI + WebSocket + React UI. Bearer-token auth. Multi-node convergence.

PRIVACY MATRIX

What each privacy layer hides

Compose them as needed. Or use all three.

Property Transparent Shielded (M3) Schnorr Anon (M4) STARK Anon (M8.6+) Mixer (M10)
Note values hiddenfixed denom
Recipient pubkey hidden
Spender pubkey hidden
Cross-spend unlinkability
Which leaf was spent: hiddenn/a
Value conservation in-proofn/a
Same-block timing defensen/an/an/an/a
Anonymity set sizen/an/a1,048,576per denom
Post-quantum safe
KILLER DEMO · UNLINKABILITY

The same wallet. Two spends. Unlinkable.

What an external observer sees from each transaction.

SPEND A
nullifier63805cdddc692bd0…
leaf spent47f6c04a6e03ed45…
value commit0269eaf7239315e3…
pubkey commit02a4ff6a76084adb…
schnorr R021fc3089cdc1a20…
SPEND B
nullifierce0ad2f4c01929ac…
leaf spent561ca119d6037344…
value commit02cc03b10c7ea0a0…
pubkey commit02180887a34fef5f…
schnorr R03e2615d7f20763c…
MILESTONE 8 · ZK-STARK FROM SCRATCH

The gap M4 left open

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.

The gap

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.

What zk-STARK gives

A succinct proof that the spender knows some leaf in the pool — without revealing which one. Hash-based, quantum-safe by construction.

Why hand-rolled

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.

Inside M8.3 — the AIR architecture

// 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
MILESTONES 8.5 → AUDIT-READINESS ARC

Every gap. Closed in scope.

Every limitation shipped open. Every closure has its own milestone or pass. None hand-waved.

GapWhat it wasOriginalStatusClosed 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)
AUDIT-READINESS ARC

Engineering complete. Awaiting external eyes.

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.

5-tier threat taxonomy

FORMAL · FORMAL, MODULO · DEFENDED · HEURISTIC · NOT DEFENDED. Every threat scored honestly. Reading the threat model is reading the codebase.

5 self-disclosed bugs

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.

3-layer differential AIR testing

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.

23 numbered threats

T1–T23 with explicit status, code references, and test references. 20 actively defended; 2 explicitly out of scope; 1 partially defended.

44 maintained docs

Milestone READMEs, audit package, threat model, publication, SoW, grant application, outreach plan. Every cross-reference checked.

Ready for engagement

AUDIT-SOW.md, AUDITOR-ONBOARDING.md, AUDIT-GRANT-APPLICATION.md, AUDIT-OUTREACH.md. The procurement layer is in place.

Read the publication (13 pages) → Open AUDIT-PACKAGE.md
BY THE NUMBERS

Real evidence. Measured.

No marketing math. The numbers are what they are.

499
tests passing
110 Rust · 21 PyO3 · 368 Python
23
numbered threats
20 defended · 2 documented gaps
5
self-disclosed bugs
all fixed · all documented
44
maintained docs
cross-refs auto-checked
1,048,576
STARK anonymity set
sparse Merkle depth 20
3
differential AIR layers
algebraic · regression · snapshot
STARK proving time · ms per proof · historical milestone progression
15.0
0.5
2.8
3.4
6.6
22.0
M8.1Fibonacci
M8.2Preimage
M8.3Merkle d=4
M8.6+ nullifier
M8.7depth 8
M8.8-A1depth 16
HONEST SCOPE

What's still NOT done — said openly

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.

!
No formal proof of AIR correctness — Differential testing in 3 layers catches several failure modes but is not a proof. Several threats marked [FORMAL, MODULO] ride on AIR correctness as their non-formal assumption.
!
No external security audit yet — The hand-rolled AIR and multi-pool composition have not been reviewed by a cryptography firm. The audit-readiness arc is preparation for this; outreach materials are ready.
!
No BFT for malicious-quorum PoS — PoS uses a single QRNG-seeded proposer. Real PoS would need fault tolerance against a fraction of malicious validators.
!
No peer authentication or TLS — Any node that completes the TCP handshake is treated as honest. Rate limiting bounds blast radius; it doesn't prevent participation.
!
No statistical timing-attack defense across blocks (T14) — Same-block defense (T13) covers single-block correlation. Long-term observation could still infer deposit-to-withdrawal pairings via statistical analysis.
!
No replay protection across networks (T20) — Transactions on one chain instance can be replayed onto another. Not relevant for single-network use; would matter for multi-network deployment.
!
No on-load chain validation (T18, partial) — Blockchain.load() doesn't call is_valid() on the loaded chain. A corrupt-but-parseable persistence file would be accepted without protocol-level invariants re-checked.
!
No off-chain note backup — The chain holds only leaf commitments; the spending witnesses live only in the wallet. Wallet file loss = unrecoverable notes by design.
!
No peer-reviewed cryptographic analysis — Audit-readiness is engineering discipline, not formal cryptographic review. Preparation for review, not substitute for it.