● Measured · Not projected

Benchmarks

Real numbers from real hardware.
Updated as each stage ships.

Every number on this page comes from an actual run on actual hardware against actual on-chain transactions. We do not publish projections, marketing approximations, or "in theory" numbers. When something is missing, that means it has not been measured yet — not that we estimated it.

Privacy on-chain has had a credibility problem

For most of the last five years, "private blockchain" has meant either a research paper with no production deployment, or a product whose performance numbers were quoted from a benchmark on a different protocol. Sunima publishes its own measurements on its own deployments, names the hardware, and links the source so anyone can rerun them.

This page covers three things: (1) the gas cost of fully homomorphic balance arithmetic on EVM (Stages 1 and 2 Part 1, both live), (2) the latency of fully homomorphic predicates on Sunima's TFHE worker (Stage 2 Part 2, live — on-chain attestation verifier deployed and source-verified, off-chain worker bench published), and (3) what each number actually means in user-facing terms.

Block production, sustained throughput, recovery

The sovereign Sunima testnet (chain-id sunima_8081-1) has been live since genesis time 2026-05-20T01:40:08Z. The numbers below were captured by a 30-second-interval logger writing CSV rows of chain head, block-time moving average, transactions per 20-block window, mempool depth, and success rate. Each row is a real point on the live chain, not an estimate.

Metric Idle (no synthetic load) Realistic user-load (~10 tx/sec) Overload (saturation test)
Block time2.0 – 2.3 s3.5 – 4.3 s13 – 18 s (deadly spiral)
Transactions per block08 – 2080 – 97 (mempool grows)
Transaction success rate—100%100% (admitted)
Mempool depth (steady)05 – 50160 – 200+ (climbing)

Real chain measurements via bench logger (30 s interval). Block time is a 20-block moving average. Transactions per block is the 20-block window total divided by 20.

What these numbers tell us

  • Sustained throughput ceiling sits at roughly 10 – 12 transactions per second on the current measurement run. Above this rate the mempool depth (mempool — pool of unconfirmed transactions) starts growing block-over-block — a sign the network is admitting transactions faster than it can finalize them. These numbers were captured on non-NVMe storage. The dominant per-block cost at this layer is concurrent fsync from EVM execution and commit paths; for context, SATA-class SSDs typically deliver low hundreds of IOPS on fsync workloads, while NVMe-tier SSDs reach tens of thousands. Moving the validator's storage from SATA-class to NVMe-tier raises this ceiling materially without any protocol-level change.
  • Recovery after intentional overload is automatic. When the saturation test stopped, the network drained back to the idle 2 s block time within approximately 45 seconds, without operator intervention.
  • State-sync onboarding of a fresh node is sub-30-second on a 500-block snapshot. A new validator joining the network can sync from snapshot rather than replaying history from genesis — applied in under thirty seconds in the measured run.
  • Block time stayed within the 2 – 5 s target band for realistic user load. This is the design target measured on the current testnet run; the saturation test established its envelope.

Status. Sovereign testnet live since 2026-05-20. The network runs a multi-validator set; the operator program opens spots progressively and onboarding is curated. TFHE attestation pipeline is wired end-to-end and exercised on chain; expansion of the GPU coprocessor pool proceeds through governance proposals. Hardware recommendations for prospective operators emphasize NVMe-tier SSDs over SATA-class drives — the fsync-latency gap between the two classes is the single largest determinant of per-validator block throughput at this layer.

Predicates that additive HE cannot express

Stage 2 Part 2 brings TFHE — torus fully homomorphic encryption — to the Sunima protocol. TFHE can compute arbitrary functions on ciphertexts: range checks, comparisons, conditional branches. The trade-off is per-operation cost: TFHE primitives run in tens of milliseconds rather than microseconds, so they live off-chain in a worker process that signs attestations consumable by an on-chain contract.

On-chain verifier — live. SunimaTFHEPredicates is deployed and source-verified on Arbitrum Sepolia at 0x9e11c9840f17d799b11c03ba129676dde30b88d6. The off-chain Rust worker built on Zama's tfhe-rs v1.6.0 (not a fork) signs EIP-191 envelopes binding the consumer, ciphertext digest, chain id, verifying contract, and validity window; the on-chain contract verifies the signature and replay-protects each consumed attestation by the tuple (consumer, ctHash, chainid, verifier, validUntil). Pause is bounded to a 30-day maximum with a 7-day cooldown, held by an isolated guardian role with no custody surface. Measured on-chain via forge test --gas-report over 1,050 calls: verifyAndConsumeRangeProof 32,894 gas median (27,100 min · 55,533 max).

The three predicates the worker has to prove it can run, end-to-end, are:

add — homomorphic addition

Add two encrypted balances and return an encrypted sum. Already covered by Part 1's EC-ElGamal — included here as the lower-bound sanity check that the TFHE crate is functional.

ge — encrypted compare ≥

Given two encrypted values, return an encrypted boolean: 1 if the first is greater than or equal to the second, 0 otherwise. The result stays encrypted; only the holder of the client key can decrypt the answer. This is what makes range proofs and "is the user's balance enough to cover this withdraw?" queries possible without leaking the balance to the worker.

cmux — encrypted conditional

Given an encrypted boolean and two encrypted values, return one of the two values depending on the boolean — without leaking which branch was taken. This is the primitive behind selective disclosure: a user can prove that a transaction satisfies one of several allowed branches without revealing which one.

The first measurement — a hello-world worker that runs all three predicates on encrypted 64-bit integers and asserts the decrypted answers against plaintext — is now functional. Latencies were captured on three platforms:

Operation Linux x86 server CPU ARM dev workstation CPU Consumer discrete GPU GPU vs x86
Setup (key generation)738 ms606 ms2,932 ms0.25× (slower)
Encrypt one u642.3 ms1.3 ms3.0 ms0.8×
Homomorphic add212 ms272 ms146 ms1.5×
Encrypted ge137 ms162 ms84 ms1.6×
Encrypted cmux177 ms246 ms49 ms3.6×
Decrypt one u6438 µs25 µs782 µs0.05× (slower)

Reference benchmarks on community hardware (tfhe-rs v1.6.0, release build). CPU rows single-thread. GPU row on a consumer discrete card (24 GB VRAM, CUDA 12.4). Numbers reproducible by anyone running tfhe-rs benches — not a description of production infrastructure.

Reading the numbers honestly

  • cmux is the only meaningful per-op GPU win — 3.6× over server CPU. This matters because cmux is the hot path in selective-disclosure flows.
  • add and ge get only 1.5 – 1.6× on a single GPU launch. This is honest data, not a sales claim. Larger speedups (the "10 – 50×" numbers seen in TFHE marketing) apply to batched workloads, where the GPU is amortised across many ciphertexts in one launch. The Stage 2 Part 2 production worker will batch.
  • Setup and decrypt are slower on GPU — 4× and 20× respectively — because each call pays the CPU↔GPU transfer cost. In production the server key stays resident on the GPU and decrypt happens rarely (only when a result leaves the worker), so this cost is paid once at startup.
  • Server CPU is enough for the dev loop and for low-throughput predicates. GPU becomes worth the extra spend once the worker batches predicates per block.

Status. Worker bench functional on three platforms (Linux x86, ARM dev, consumer discrete GPU); all three predicates pass plaintext asserts on every platform. The HTTP attestation worker is in place — JSON-RPC surface for range-proof, encrypted-compare, and encrypted-conditional, EIP-191 signing under a fresh worker key — and the on-chain verifier SunimaTFHEPredicates is deployed and source-verified on Arbitrum Sepolia, replay-protected, with measured on-chain consumption at ~33K gas median. The encrypted-withdraw path is now wired end-to-end: SunimaVaultElGamal v0.7.1 requires a valid verifyAndConsumeRangeProof attestation on every withdrawal. Publishing the reproducible benchmark script is the next milestone.

12 – 18× cheaper than Stage 1, live today

Stage 2 Part 1 replaces Paillier with EC-ElGamal on the BN254 curve, using Ethereum's native ecAdd and ecMul precompiles for the homomorphic operations. The vault is deployed on Arbitrum Sepolia at 0x3a0d9A52416847D984a17D0dBe849cdF6492209E (v0.7.1), source-verified, transacting end-to-end (deposit, withdraw, encrypted transfer, off-chain decrypt).

Operation Stage 1 (Paillier) Stage 2 Part 1 (EC-ElGamal) Reduction
Cold deposit~2,000,000151,36813×
Warm deposit— (no equivalent)56,065new
Withdraw~1,600,00088,78918×
Encrypted transfer~3,400,000222,31815×

Stage 2 Part 1 vault, Arbitrum Sepolia. EC-ElGamal on BN254. Full Foundry suite passes across Stages 1, 2 & 4 with no regressions.

What this means in dollars. At Arbitrum mainnet gas prices (around $0.10 per million gas), a Stage 2 Part 1 deposit costs roughly $0.015 — down from approximately $0.20 on Stage 1. The original Stage 2 commitment was a 200 – 300K gas envelope across the three primitives; all three landed under the lower bound of that envelope.

EC-ElGamal is additive: it can add two encrypted values, but it cannot natively compare them, decide which is larger, or branch on encrypted conditions. Those operations require fully homomorphic encryption. That is the reason for Part 2.

Where Sunima started — additive HE on standard EVM

Stage 1 deployed a Paillier-2048 vault on Arbitrum Sepolia at 0xe5254A5E21403Ae07a6925071796d596451f7f86. It was the first public proof that homomorphic balance arithmetic — adding and subtracting encrypted balances without decrypting them — works on standard EVM infrastructure with no precompiles. It is the baseline against which every later optimisation is measured.

Operation Gas (measured live) Cost @ Arbitrum mainnet ($0.10 / Mgas)
Cold deposit1,900,000 – 2,300,000~$0.19 – $0.23
Withdraw~1,600,000~$0.16
Encrypted transfer~3,400,000~$0.34

Stage 1 vault, Arbitrum Sepolia. Paillier 2048-bit, single-organizer trust model. Numbers are success-path max gas — the cost of an operation that fully completes its ciphertext mutation. Min and median in forge test --gas-report are much lower because the test suite includes many early-revert paths (bad signature, replay, expired deadline). On-chain cold-storage initialisation can add ~10–15% to the first deposit call from a fresh account vs the warm-path forge max.

For comparison, Tornado Cash's classic deposit cost approximately 1.1M gas — Sunima Stage 1 is roughly 2× more expensive per deposit, but in exchange it does full homomorphic balance arithmetic on every operation rather than just appending to a fixed-denomination commitment tree. Stage 2 was tasked with closing that gap.

How to read these numbers — and how to rerun them

What "measured" means here

Gas numbers were captured from real Arbitrum Sepolia transactions on the deployed vault contracts. The transactions are publicly inspectable on Arbiscan; the values quoted are per-operation gas-used as reported by the network, not local estimates from foundry or hardhat.

TFHE worker latencies were captured by the worker binary itself, using std::time::Instant around each operation, release build, no debug symbols. Each platform was measured by building from the same Rust source with the appropriate feature flag (cargo run --release for CPU, cargo run --release --features gpu for GPU). The hello-world bench is single-shot — it does not warm up the JIT, prefault pages, or run multiple iterations to compute a median. Numbers are first-run, cold; production workloads will be faster on average.

What is not yet measured

Reproducibility

The TFHE worker crate is a standalone Rust package — roughly a hundred lines of source. Anyone with a Rust toolchain (≥1.91.1) can reproduce the CPU numbers in under five minutes; the GPU numbers require a CUDA-capable card with CUDA 12.x and CMake ≥3.24. The vault contracts are source-verified on Arbiscan, so anyone can redeploy them on a fresh Sepolia address and reproduce the gas measurements.

This page is updated as each stage ships. If a number changes — because we re-measured, fixed a regression, or ran on different hardware — the previous value is replaced and the change is noted in the protocol changelog, not silently rewritten.