All articles
solanatoken-2022privacyzkconfidential-transfers

Token-2022 Confidential Transfers: encrypted balances, and the ZK proof saga

The confidential transfer extension encrypts SPL token balances and amounts with ElGamal + ZK proofs. Here's the mechanism, the configure/deposit/transfer flow, and why the proof program got disabled.

Confidential 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

text
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 balance

Proofs 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

The cryptography is sound in principle; the implementation took two hits. Verify the proof program is live before you design around it.