Token-2022 Confidential Transfers: encrypted balances, and the ZK proof saga
The Token-2022 confidential transfer extension encrypts SPL balances and amounts with ElGamal + ZK proofs — the mechanism, and the proof-program saga.
devrels.xyz/a/34short linkConfidential Transfers is an SPL Token-2022 extension that encrypts token-account balances and transfer amounts on-chain — hiding the numbers while keeping everything verifiable. Crucially, it hides amounts, not identities: senders, receivers, and the fact a transfer happened all remain public. It is not anonymity.
How it works
- Balances are encrypted with twisted ElGamal (a Pedersen commitment plus a decryption handle), which is linearly homomorphic — so the program can add and subtract encrypted values without decrypting them.
- Each account has a separate encryption keypair and two encrypted balances: pending (incoming) and available (spendable). Splitting them blocks front-running griefing.
- A native ZK ElGamal Proof program enforces correctness via range proofs (amounts are non-negative and within bounds — transfers capped at 48-bit) and equality/validity proofs (the same value is correctly encrypted under sender, receiver, and auditor keys).
- An optional per-mint auditor key can decrypt transfer amounts for compliance.
The account lifecycle
ConfigureAccount set the account's ElGamal encryption key
Deposit move public balance → encrypted "pending"
ApplyPendingBalance owner merges pending → "available" (spendable)
Transfer proof-gated move of an encrypted amount
Withdraw decrypt back out to a public balanceProofs are heavy enough that they're typically submitted via context-state accounts rather than inline, making confidential transfers multi-instruction and compute-intensive. A companion ConfidentialTransferFee extension keeps fees encrypted too.
The ZK proof saga (read before you build)
Two soundness bugs hit in 2025. In April, a Fiat–Shamir soundness issue was found and patched via validator upgrades (no exploit). In June, a second bug — a forgeable sigma-OR proof — led Solana to disable confidential transfers and the ZK ElGamal Proof program on mainnet (epoch 805), pending audits. As of the latest official docs available at writing, the program remains disabled pending audit completion; treat any claim that it's fully re-enabled as unconfirmed and check the token-2022 issue tracker before relying on it.
The honest read
Confidential Transfers is a genuinely elegant primitive — homomorphic encrypted balances with on-chain ZK enforcement — but temper expectations: only amounts are private (not counterparties), there's no confidential native SOL, wallet/tooling support is thin, real-world usage is near-zero, and the feature has been offline since mid-2025 over proof bugs. For amount privacy with a compliance escape hatch (the auditor key) it's the canonical design; for true anonymity, look to dedicated privacy layers like Arcium or Umbra.
References
- Confidential Balances — overview (solana-program.com)
- token-2022 #657 — live status of the ZK ElGamal program
- SPL Token vs Token-2022
The cryptography is sound in principle; the implementation took two hits. Verify the proof program is live before you design around it.
Keep reading
Solana is the most transparent it's ever been — and privacy tooling is finally catching up. Four distinct approaches now ship: Token-2022 encrypted balances, Arcium's MPC, shielded ZK pools like Privacy Cash, and TEEs inside Jito BAM and MagicBlock. A map of the landscape.
'Private' is doing a lot of work in Solana marketing right now. Confidential Transfers hide amounts but not who's transacting. Shielded pools hide both but can't compute. Arcium and MagicBlock compute on hidden data — one trusts math, the other trusts a chip. The right question isn't 'which is most private?' — it's 'what exactly do I need hidden, and whom am I willing to trust?' Here's the matrix.
Zero-knowledge on Solana is two parallel stacks that share almost nothing: a curve25519 sigma-protocol stack purpose-built for confidential transfers, and a BN254 SNARK stack (alt_bn128 syscalls + Groth16) that powers ZK compression and general-purpose verifiers. Here's the full map — syscalls, programs, provers, costs, and the mid-2025 soundness bug that reshaped the roadmap.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
