Benchmarking Tessera: 0.85ms Proofs, 326 ops/s Throughput, 0% Forgery
Every claim Tessera makes is backed by a reproducible experiment harness in scripts/. There are seven: E1 through E7. Each writes results to results/ and is runnable with a singleuv run python scripts/... command. This post summarises what each harness measures, the headline numbers, and how to reproduce them.
Headline numbers
| Metric | Value | Experiment |
|---|---|---|
| ZK proof generation | ~0.85 ms | E1 |
| ZK proof verification | ~13 ms | E1 |
| Proof size (R ‖ s) | 64 B | E1 |
| AES-GCM encrypt (1 KB) | ~0.02 ms | E1 |
| Subscribe throughput | 326 ops/s (4.5× naive) | E4 |
| Route throughput (~75 subs/bucket) | 440 ops/s | E4 |
| FAR / FRR (tamper, swap-key, forge, replay) | 0 / 0 | E6 |
| Adversary linking AUC (DP, ε=0.1) | 0.526 | E3 |
| Bucket k-anonymity | k ≥ 75 at default N | E2 |
| Churn delivery (mesh, 50% offline) | 100% | E5 |
The seven experiment harnesses
E1 — Crypto microbenchmark (bench_crypto.py)
Measures proof generation, proof verification, AES-GCM encrypt/decrypt, and payload sizes. The output includes per-operation latency distributions and a summary table. Headline: ~0.85 ms to generate a Schnorr proof, ~13 ms to verify, 64-byte proof size.
uv run python scripts/bench_crypto.pyE2 — Anonymity simulation (analysis/anonymity_sim.py)
Simulates the bucketing layer with varying subscriber counts and bucket counts, measuring k-anonymity per bucket and the Bloom filter false-positive rate. At default parameters the bucketing scheme provides k ≥ 75 anonymity with a Bloom FPR below 1%.
uv run python scripts/analysis/anonymity_sim.pyE3 — Linkability simulation (analysis/linkability_sim.py)
Trains an adversary classifier on the published per-bucket counts under Tessera's (ε,δ)-DP cover traffic and measures the area under the ROC curve for the "did bucket b receive a real delivery" task. At ε=0.1 the AUC is 0.526 — within Monte-Carlo error of the random baseline (0.5). This is the empirical privacy guarantee against a global passive observer.
uv run python scripts/analysis/linkability_sim.py --epsilon 0.1E4 — Throughput benchmark (bench_throughput.py)
Measures persistent-connection node throughput: subscribe rate, route rate, and delivery latency under load. The single-writer SQLite design (synchronous=NORMAL, one persistent connection + lock) is the verified bottleneck mitigation. Headline: 326 ops/s subscribe (4.5× the naive baseline) and 440 ops/s route at ~75 subscribers per bucket.
uv run python scripts/bench_throughput.pyE5 — Churn simulation (analysis/churn_sim.py)
Spins up a multi-node cluster (mesh or ring topology) and takes nodes offline to measure delivery rate under churn. Mesh topology maintains 100% delivery at 50% node offline; ring degrades to ~85% because a single missing node breaks the loop. Tessera defaults to mesh.
uv run python -m tessera.deploy.cluster --nodes 5 --topology ring
uv run python scripts/analysis/churn_sim.py --nodes 8E6 — Security benchmark (bench_security.py)
Runs the verifier against four attack classes — tamper(mutated proof), swap-key (proof under a different key), forge (proof from a non-holder), andreplay (reused proof on a new message) — with 5000 trials each. Result: false-accept rate (FAR) and false-reject rate (FRR) both 0/0 across all four classes. The Schnorr proof is EUF-CMA secure under DLog, empirically confirmed.
uv run python scripts/bench_security.py --trials 5000E7 — Leakage comparison (analysis/leakage_compare.py)
Produces a comparative leakage matrix across signed messaging, metadata-private messaging (mixnets/DC-nets), and Tessera, scoring each on routing metadata, network timing, recipient identity, colluding- recipient resistance, and authentication. Tessera matches metadata-private messaging on privacy while adding authentication that the metadata-private lineage lacks.
uv run python scripts/analysis/leakage_compare.pyReproducing all at once
uv sync
uv run pytest tests/ -q # 151 unit tests
uv run python scripts/bench_crypto.py # E1
uv run python scripts/analysis/anonymity_sim.py # E2
uv run python scripts/analysis/linkability_sim.py # E3
uv run python scripts/bench_throughput.py # E4
uv run python scripts/analysis/churn_sim.py --nodes 8 # E5
uv run python scripts/bench_security.py --trials 5000 # E6
uv run python scripts/analysis/leakage_compare.py # E7Test environment notes
- All numbers are single-threaded on a laptop unless noted.
- The single-writer SQLite design (
synchronous=NORMAL) is the verified mitigation for the storage bottleneck; see the throughput harness for the comparison. - The Flask web service is dev-grade; production deployment should sit behind a real WSGI server.
- The
EncryptedKeyStore(PBKDF2, 100k iterations) is the production keystore; the default in-memory store is for benchmarks only.
What the numbers say
Three takeaways:
- Crypto is fast enough to be invisible. 0.85 ms proof generation adds no perceptible latency to a delivery.
- Privacy does not cost correctness. The DP cover traffic that hides bucket counts leaves the adversary with AUC 0.526 — yet the verifier still rejects every forgery (FAR 0/5000).
- The network is usable for real-time messaging. 326 ops/s subscribe and 100% delivery under 50% churn mean Tessera runs on commodity hardware without a dedicated mix infrastructure.
For the formal security properties and threat model, see theresearch page; for the engineering deep dives behind each number, start withSchnorr ZK proofs and(ε,δ)-DP cover traffic.