Start now →

The Evolution of On-Chain Privacy: Mixers → Shielded Pools → TEE Execution

By Mani Yadla · Published March 28, 2026 · 6 min read · Source: Cryptocurrency Tag
Blockchain
The Evolution of On-Chain Privacy: Mixers → Shielded Pools → TEE Execution

The Evolution of On-Chain Privacy: Mixers → Shielded Pools → TEE Execution

Mani YadlaMani Yadla6 min read·Just now

--

While reviewing several privacy-focused projects, I started noticing a recurring set of design patterns in how privacy is implemented. Each system approached the problem differently, but the underlying structure often followed a similar progression, with clear trade-offs at every stage. This evolution felt almost generational each new approach building on the limitations of the previous one, improving certain guarantees while introducing new assumptions. That observation motivated this article: to highlight these patterns, examine the trade-offs they introduce, and show how privacy architectures in blockchain systems are steadily evolving through iterative engineering rather than a single definitive solution.

The Classic mixer approach

Although this approach doesn’t hide the amount a sender is sending or receiving, it was the first widely used method for private transactions (and yes, some illegal use happened — we don’t talk about that).

The idea is simple: you send funds to a smart contract, but here’s the key twist — everyone deposits the exact same amount. This is intentional. If Alice deposits 1 ETH and Bob withdraws 1 ETH, there’s no way to tell if Bob is Alice, or one of the hundred other people who also deposited 1 ETH. If amounts varied, you could just match deposits to withdrawals by amount and the whole thing falls apart.

And here’s where it gets interesting — the more people depositing, the stronger the privacy. If only 3 people have deposited and you withdraw, there’s a 1-in-3 chance someone can guess it was you. But if 10,000 people have deposited? Good luck. This pool of depositors is called the anonymity set, and size is everything. A mixer with 5 users is basically useless. One with thousands is genuinely hard to trace.

The flow looks like this: you deposit funds into the contract and get a secret key in return — think of it like dropping cash into a locker and keeping the only key. Later, from a completely fresh wallet, you (or anyone you give the key to) can withdraw the funds. The key works once and is discarded after use, so you can’t drain the same deposit twice.

Technically, the contract doesn’t track balances. Instead, each deposit creates a commitment derived from a random secret:

commitment = hash(secret, nullifier)

This commitment is added to a Merkle tree containing all deposits (the anonymity set). The contract only stores commitments, not ownership. During withdrawal, the user generates a zk proof showing:

The nullifier prevents double spends, while the proof hides which deposit is being withdrawn. Funds are then sent to a new address, typically via a relayer to avoid linking the withdrawer’s new address back to the original deposit transaction.

Press enter or click to view image in full size

A deeper dive into this if you are interested:

https://soliditydeveloper.com/tornado.cash

ZK-based privacy with hidden amounts

Mixers removed deposit-withdraw linkage, but amounts were still public, forcing fixed denominations.

Shielded pools remove this by converting deposits into confidential balances that move privately inside a shared pool.

A user first deposits into the pool, turning public tokens into an encrypted note representing their private balance. From that point onward, transfers happen entirely inside the pool by spending notes and creating new ones. These notes can be split, merged, and forwarded across multiple hops, all without revealing sender, receiver, or value. Only when funds exit the pool does a public transfer occur.

This creates a continuous private flow:

On-chain, observers only see commitments being added and nullifiers being consumed. The internal transaction graph remains hidden, and privacy strengthens as more notes accumulate in the pool.

However, one leak remains: the transaction sender is still visible.

The address submitting the zk proof and paying fees is public, even though the logical sender inside the pool is hidden.

One possible technical structure

Funds are represented as encrypted notes:

note = {
token,
amount,
owner_pubkey,
randomness
}

Each note produces a commitment:

commitment = hash(note)

Commitments are appended to a Merkle tree representing all private balances.

To spend a note, a nullifier is derived:

nullifier = hash(note, spend_key)

A private transfer consumes input notes and creates new output notes, while generating a zk proof that verifies:

The chain only sees:

{
nullifiers[],
new_commitments[],
merkle_root,
zk_proof
}

This hides which notes were spent, who received them, and how much was transferred, while still enforcing balance correctness.

Press enter or click to view image in full size
Press enter or click to view image in full size

A deeper dive into this if you are interested:

Confidential Stablecoin Transfers on Plasma: A zk-SNARK-Based Shielded Pool Design

A Research paper proposing a zk-SNARK based shielded pool for the Plasma team

parallelresearch.substack.com

TEE-Based Complete Confidentiality with Trust Assumptions

Now for the final approach the one that’s actively being built at the time of writing this article — TEE-based private execution. This model hides the entire transaction, not just parts of it. Instead of publishing sender, receiver, and amount on-chain, the user encrypts the full transaction locally and submits ciphertext. The blockchain only sees opaque data, while execution happens inside a Trusted Execution Environment (TEE). Balances, transfers, and even contract logic live in encrypted state, so observers can verify that something happened without learning what actually happened.

The flow is simple from a user perspective. You construct a transfer, encrypt it with the network key, and send it through a relayer. The relayer submits the encrypted payload, and the contract processes it inside the enclave. The state updates remain encrypted, and only the user can decrypt their own balance afterward. There’s no deposit/withdraw model, no anonymity set, and no fixed denominations. Privacy exists even with a single user, and as more encrypted activity accumulates, the system naturally becomes harder to analyze.

Under the hood, this combines TEE execution with homomorphic encryption. The TEE guarantees that approved code executed correctly, while homomorphic encryption allows computation directly on ciphertext. Instead of decrypting balances, the system updates encrypted values and writes back encrypted results. Validators only verify the enclave attestation and accept the new encrypted state root. The chain never sees plaintext — just valid transitions between encrypted states.

A minimal view of what happens internally

User encrypts the transfer:

constencTx=encrypt({
from,
to,
amount
})
submit(encTx)

The contract stores encrypted balances:

balances[enc(user)] = enc(balance)

Inside the TEE, the transfer runs as encrypted math:

enc_sender_new   = FHE.sub(enc_sender_balance, enc(amount))
enc_receiver_new = FHE.add(enc_receiver_balance, enc(amount))

Validity checks also run on ciphertext:

valid = FHE.gte(enc_sender_balance, enc(amount))
balances[sender] = FHE.select(valid, enc_sender_new, enc_sender_balance)
balances[receiver] = FHE.select(valid, enc_receiver_new, enc_receiver_balance)

Homomorphic encryption makes this possible:

FHE.add(enc(a), enc(b)) = enc(a + b)
FHE.sub(enc(a), enc(b)) = enc(a - b)

So balances update without ever being decrypted. The enclave returns the updated encrypted state, the chain stores it, and the user decrypts their new balance locally.

Press enter or click to view image in full size

A deeper dive into the homomorphic proof validation:

Homomorphisms by Example | RareSkills

Homomorphisms by Example A homomorphism between two groups exists if a structure preserving map between the two groups…

rareskills.io

Interesting paper about TEE

https://arxiv.org/pdf/2203.08548

This article was originally published on Cryptocurrency Tag and is republished here under RSS syndication for informational purposes. All rights and intellectual property remain with the original author. If you are the author and wish to have this article removed, please contact us at [email protected].

NexaPay — Accept Card Payments, Receive Crypto

No KYC · Instant Settlement · Visa, Mastercard, Apple Pay, Google Pay

Get Started →