ZK Feasibility Study: Can Kusama Asset Hub Run a Shielded Pool?
TL;DR: Yes, but the anonymity set is the hard problem — not the technology.
To my knowledge, this is the first public benchmark and feasibility study for zero-knowledge operations on Kusama Asset Hub’s pallet-revive EVM. The full study (code, data, reports) is at codeberg.org/hantoniu/zk-benchmarks (MIT license). Below is the executive summary.
Why This Matters
The Kusama Vision ZK bounty is about to fund ZK proposals. Before funding implementations, the ecosystem needs to know what the platform can actually support. Nobody has published:
- Gas costs for ZK operations on pallet-revive
- Whether Groth16 proof verification works
- Whether Poseidon hashing (needed for Merkle trees) is feasible
- What a shielded pool would actually cost to operate
This study answers all of these questions with on-chain data.
Phase 1: Benchmarks — What Works and What Doesn’t
All measurements taken on Paseo Asset Hub testnet. Contracts compiled with resolc 1.0.0 (Solidity → PVM). Full data and deployment records in the repo.
The Good: Precompiles and Groth16
| Operation | Paseo Gas | Ethereum Gas | Cost (USD) | Verdict |
|---|---|---|---|---|
| ecPairing (4 pairs, Groth16) | 2,062 | 181,000 | $0.009 | 88x cheaper |
| Groth16 verify (3 signals) | 3,990 | 202,216 | $0.017 | 51x cheaper |
| ecMul (BN254) | 991 | 6,000 | $0.004 | 6x cheaper |
BN254 precompiles are dramatically cheaper on pallet-revive. Groth16 proof verification costs $0.017 — essentially free.
The Bad: Solidity Poseidon
| Operation | Paseo Gas | Block Budget Used | Verdict |
|---|---|---|---|
| Single Poseidon hash | 47,851 | 70% | Barely fits |
| Two sequential hashes | EXCEEDS LIMIT | >100% | Impossible |
| Depth-20 Merkle path | EXCEEDS LIMIT | 1,410% | Impossible |
A single Poseidon hash in Solidity consumes 70% of the block’s computational budget (1.44 × 10¹² picoseconds ref_time). Two hashes exceed the block limit. A Merkle tree — the core data structure of any shielded pool — is completely impossible in Solidity.
Why? Poseidon requires hundreds of 256-bit field multiplications. On EVM, these are native operations. On pallet-revive’s RISC-V target, 256-bit arithmetic must be emulated, making each operation ~28x slower in wall-clock time. The gas number (47,851) hides this — it’s comparable to Ethereum’s 32,800, but the actual computation is 70% of a block.
This is the most important finding: gas numbers on pallet-revive can actively mislead. A developer looking at gas alone would think Solidity Poseidon is “slightly more expensive than Ethereum.” In reality, it’s a showstopper.
The Breakthrough: Rust Poseidon
Kusama Shield’s PoseidonPolkaVM — a hand-written Rust implementation compiled to PVM — solves the problem:
| Operation | Rust Gas | Solidity Gas | Improvement |
|---|---|---|---|
| Single hash | 2,706 | 47,851 | 17.7x |
| 20 sequential hashes | 34,267 | IMPOSSIBLE | ∞ |
| Merkle path depth 20 | 37,956 | IMPOSSIBLE | ∞ |
| Merkle path depth 32 | ~59,955 | IMPOSSIBLE | ∞ |
| Max hashes per block | 39 | 1 | 39x |
Montgomery multiplication on u64 limbs maps efficiently to RISC-V 64-bit instructions. The Rust code achieves 28x faster execution than the Solidity → resolc path for the same algorithm.
Shielded Pool Cost Estimate
Using the hybrid architecture (Solidity logic + Rust Poseidon + Groth16 precompiles):
| Operation | Gas | Cost (USD) | Ethereum Equivalent |
|---|---|---|---|
| Deposit (hash + depth-20 Merkle insert) | ~45,000 | $0.19 | $54.40 |
| Withdrawal (Groth16 verify + nullifier) | ~7,000 | $0.03 | $15.05 |
| Full cycle | ~52,000 | $0.22 | $69.45 |
A complete deposit-withdrawal cycle costs $0.22 — roughly 316x cheaper than Ethereum at 20 gwei.
Phase 2: Feasibility — The Anonymity Set Problem
Gas Economics: Excellent
The cost barrier is eliminated. At $0.22 per cycle, even the smallest denomination (1 KSM = $4.30) has acceptable overhead (5% of value). Tornado Cash on Ethereum charged $54-70 per cycle, which priced out small users.
Relayer Economics: Marginal
A relayer costs ~$50/month to operate. At projected Kusama withdrawal rates (1-5/week initially), revenue at 0.5% fee is ~$1/month. Relayers need subsidy until volume grows. The good news: subsidy cost is trivial ($50-100/month from treasury).
Anonymity Sets: The Real Problem
Kusama Asset Hub has:
- ~102 EVM contracts deployed (total, ever)
- Single-digit daily EVM transactions
- No DeFi ecosystem on pallet-revive
- Zero deposits in Kusama Shield’s existing shielded pool
Projected deposits at moderate scenario (10/month in best pool):
| Target | Deposits Needed | Time to Reach | Privacy Level |
|---|---|---|---|
| k = 10 | 10 | ~1 month | Trivially deanonymizable |
| k = 100 | 100 | ~10 months | Minimum for basic privacy |
| k = 1,000 | 1,000 | ~8.3 years | Reasonable privacy |
But stated k overstates real privacy. The Tutela study found 44% of Tornado Cash deposits were compromised through heuristics — timing correlation, address reuse, multi-denomination fingerprinting. Adjusted for these attacks:
| Stated k | Effective k | Privacy |
|---|---|---|
| 10 | ~4-5 | Useless |
| 100 | ~44-54 | Weak |
| 1,000 | ~440-540 | Acceptable |
At 10 deposits/month, reaching effective k = 100 takes ~19 months.
For reference: Tornado Cash’s Polygon 100,000 MATIC pool had only 31 lifetime deposits. It provided zero privacy. Kusama’s projected rates are comparable.
Kusama Shield Gap Analysis
The existing Kusama Shield deployment has two critical flaws, neither of which is addressed in the latest release (v0.50, 2026-02-12):
-
UI-only denomination enforcement. The circuit accepts arbitrary amounts. Only the web UI constrains options — and v0.50 actually expands these to
[0.5, 1, 5, 10, 100, 500, 1000, 10000], fragmenting the anonymity set further. The contract’sdeposit()accepts any value. Anyone bypassing the UI deposits unique amounts that are trivially identifiable, destroying the anonymity set for everyone. -
No relayer. Users must fund withdrawal addresses directly, creating on-chain links that negate the pool’s privacy entirely. This makes the system worse than useless — it’s privacy theater that encourages risky behavior under false assumptions.
v0.50 does add genuine improvements: client-side Merkle tree reconstruction from on-chain events (eliminating server trust for proof generation), WalletConnect/MetaMask support, and faster browser-based proof generation via Web Workers. These are meaningful UX advances, but they do not address the fundamental privacy architecture gaps.
Verdict
The technology works. The economics work. The privacy doesn’t — yet.
A shielded pool on Kusama Asset Hub today would provide negligible privacy due to tiny anonymity sets. It’s not a gas problem, not a cryptography problem — it’s a cold start problem. The pool needs users for privacy, but users need privacy to justify using the pool.
Phase 3: Architecture — A Proper Design
Despite the anonymity set challenge, specifying a proper architecture is valuable. When the ecosystem grows (or if incentives bootstrap deposits), the pool should be ready. Phase 3 provides a complete blueprint.
Design Principles
- Contract-enforced denominations.
require(msg.value == denomination)— not UI-only. Separate contract per denomination. - Relayer support. Relayer address and fee bound into the ZK proof via dummy square constraints (Tornado Cash pattern). Cannot be front-run.
- Simplified commitment scheme. Two Poseidon hashes instead of Kusama Shield’s three:
commitment = Poseidon(nullifier, secret)andnullifierHash = Poseidon(nullifier, nullifier). Fixed denominations eliminate the need to embed value/asset in the commitment. - Standard Merkle tree. Binary Poseidon, depth 20 (1M capacity), 30-root circular buffer, incremental insertion with cached subtrees.
Circuit
Withdraw(levels = 20):
Private: nullifier, secret, pathElements[20], pathIndices[20]
Public: root, nullifierHash, recipient, relayer, fee
1. Verify: Poseidon(nullifier, nullifier) == nullifierHash
2. Compute: commitment = Poseidon(nullifier, secret)
3. Verify: MerkleProof(commitment, path) == root
4. Bind: recipient², relayer², fee² (dummy constraints)
~5,829 constraints (vs Tornado Cash's ~28,269)
5 public inputs → ~4,500 gas verification on pallet-revive
Cost Summary
| Operation | Gas | Cost | Block % |
|---|---|---|---|
| Deposit | ~42,000 | $0.18 | ~52% |
| Withdrawal | ~9,500 | $0.04 | ~10% |
| Full cycle | ~51,500 | $0.22 | — |
Threat Model Highlights
| Threat | Severity on Kusama | Mitigation |
|---|---|---|
| Timing correlation | Critical — days between deposits | Long wait times, honest UX about privacy limits |
| Amount correlation | Eliminated | Contract-enforced denominations |
| Address reuse | High | Fresh addresses, UI warnings |
| Multi-denomination fingerprinting | High | Different patterns for deposit/withdrawal |
| Bridge metadata | Medium | Time separation, native KSM users preferred |
| Privacy death spiral | Critical | Single denomination focus, incentivized deposits |
| Relayer IP logging | Medium | Tor, future onion routing |
Integration
| Bridge | Status | Trust Model |
|---|---|---|
| Hyperbridge (Messier) | Live on Kusama | Trustless (zkSNARK + BEEFY) |
| Polkadot-Kusama Bridge | Live | Trustless (GRANDPA light clients) |
| Snowbridge | Live Polkadot-ETH, not yet Kusama | Trustless (BEEFY light clients) |
All bridges are publicly visible. Privacy begins at the pool deposit, not at the bridge.
Recommendations
-
Fix Kusama Shield’s denomination enforcement. This is a one-line code change (
require(msg.value == denomination)) that eliminates a critical vulnerability. Should be done immediately. -
Build a relayer. Without one, no shielded pool on Kusama provides real privacy. A minimal relayer is a simple HTTP service. Cost: ~$50/month.
-
Don’t oversell privacy. Be transparent that early users are building an anonymity set for future users. Display the current k prominently in the UI with honest assessments.
-
Focus on one denomination. Launch with 10 KSM only. Four pools with 3 deposits each is worse than one pool with 12.
-
Advocate for a native Poseidon precompile. The 17.7x gap between Solidity and Rust Poseidon shows the opportunity. A runtime-level precompile would make pure Solidity ZK contracts feasible, eliminating the Rust PVM dependency.
-
Wait for ecosystem growth — or create it. The pool is infrastructure. It becomes useful when Asset Hub has enough activity. DeFi, governance tooling, and DOT/KSM migration to Asset Hub are the prerequisites, not the pool itself.
Repo Contents
repo/
├── contracts/src/ # Benchmark contracts (Solidity)
│ ├── PrecompileProbe.sol
│ ├── PoseidonBenchmark.sol
│ ├── RustPoseidonBenchmark.sol
│ └── Groth16Verifier.sol
├── data/ # Raw benchmark data (JSON)
│ ├── paseo/ # Paseo testnet measurements
│ └── deployments.json # All contract addresses + tx hashes
├── report/
│ ├── 01-benchmarks.md # Phase 1: gas costs, precompiles, Poseidon, Groth16
│ ├── 02-feasibility.md # Phase 2: economics, anonymity sets, gap analysis
│ └── 03-architecture.md # Phase 3: contract design, circuit spec, threat model
└── circuits/ # Circom circuit source
All contracts are deployed on Paseo Asset Hub (chain ID 420420417) with verifiable transaction hashes.
Key Numbers
| Metric | Value |
|---|---|
| Groth16 verification cost | $0.017 (51x cheaper than Ethereum) |
| Poseidon hash cost (Rust) | $0.012 (12x cheaper than Ethereum) |
| Shielded pool deposit | $0.19 (286x cheaper than Ethereum) |
| Shielded pool withdrawal | $0.04 (376x cheaper than Ethereum) |
| Max Poseidon hashes per block | 39 (Rust) / 1 (Solidity) |
| Solidity Poseidon: block budget | 70% per hash |
| Rust Poseidon: improvement | 17.7x gas, 28x ref_time |
This study was produced as an independent contribution to the Kusama ecosystem. The full methodology, data, and source code are available for reproduction and verification.