ZK Feasibility Study: Can Kusama Asset Hub Run a Shielded Pool?

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):

  1. 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’s deposit() accepts any value. Anyone bypassing the UI deposits unique amounts that are trivially identifiable, destroying the anonymity set for everyone.

  2. 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

  1. Contract-enforced denominations. require(msg.value == denomination) — not UI-only. Separate contract per denomination.
  2. Relayer support. Relayer address and fee bound into the ZK proof via dummy square constraints (Tornado Cash pattern). Cannot be front-run.
  3. Simplified commitment scheme. Two Poseidon hashes instead of Kusama Shield’s three: commitment = Poseidon(nullifier, secret) and nullifierHash = Poseidon(nullifier, nullifier). Fixed denominations eliminate the need to embed value/asset in the commitment.
  4. 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

  1. 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.

  2. Build a relayer. Without one, no shielded pool on Kusama provides real privacy. A minimal relayer is a simple HTTP service. Cost: ~$50/month.

  3. 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.

  4. Focus on one denomination. Launch with 10 KSM only. Four pools with 3 deposits each is worse than one pool with 12.

  5. 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.

  6. 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.

2 Likes

This is great! Thank you for putting this together @hantoniu-codeberg . For everyone reading please note that PolkaVM is outperforming EVM here. 26x better does the poseidon on polkavm(There is still lots of improvements to be made here).

  • Zero deposits in Kusama Shield’s existing shielded pool

We are continuously switching pools/redeployig them therefor the user numbers on the Kusama AH is to be considered as unstable right now. The paseo pool has more users right now and we will switch the new zk logic to mainnet after 1-3 weeks when we can make sure it runs stable, the zk logic in the new paseo pool offers a lot stronger privacy guarantees contra the older version. The rates suck right now, we are aware of this and we expect to see a significant spike in users once the new zk logic is deployed on mainnet and our swaps are well documented as well.

2: Build a relayer:

There is a token forwarder that allows for unique addresses every use, its not merged/added into the main logic yet: The fear, the treachery.

BN254 precompiles are dramatically cheaper on pallet-revive. Groth16 proof verification costs $0.017 — essentially free.

This is great that you mention this as BN254 is something that has been on my mind for a few months and without saying to much it may be some pushes that put in place to make the developer experience better for future developers.

316x cheaper than Ethereum at 20 gwei.

Amazing numbers!

Thanks a lot for putting these numbers together as they are a great resource!!!

2 Likes