- What it is: fully homomorphic encryption lets the network compute on ciphertext, so smart contract state can remain encrypted while validators still execute and verify transitions.
- Why it matters: the alternative privacy approaches (ZK proofs, MPC, TEEs) each require off-chain coordination or trusted hardware. FHE keeps the computation on-chain and makes composability between private contracts structurally simpler.
- The gotcha: decryption still has to happen somewhere, and the trust you removed from the plaintext layer reappears in the threshold key committee. The cryptography is sound; the governance is where the real risk lives.
Who this is for: smart contract engineers and protocol designers who want on-chain confidentiality without the user-interaction overhead of a ZK-based private state model. You should be comfortable reading Solidity, understand how the EVM storage model works at a high level, and have at least a passing familiarity with public-key cryptography. You do not need a math background in lattices, but the section on FHE schemes will give you enough vocabulary to read the relevant docs without getting lost.
The problem with a transparent ledger
Blockchains are built on transparency. Every account balance, every storage slot, every call argument is visible to every node on the network. That property is what makes trustless verification possible, and most of the time it is a feature. But there is a class of applications where it is a hard blocker.
Consider a sealed-bid auction on-chain. The point of a sealed bid is that no participant sees the others’ bids before the deadline. On a standard EVM chain, every bid transaction is visible in the mempool before it is included, and readable in storage afterward. You can work around the first problem with commit-reveal schemes, but the second one never goes away. The settled bids live on-chain in plaintext forever.
The same problem shows up in private DeFi. An AMM where pool reserves are public is vulnerable to front-running because any observer can see the pool state before constructing an arbitrage. Private governance votes, confidential payroll distributions, healthcare-adjacent on-chain records, all of them run into the same wall: the state is inherently sensitive but the ledger is inherently transparent.
The standard toolbox for this problem has three main entries. ZK proofs let users prove that a state transition is correct without revealing the underlying values, but state stays off-chain with the user, which makes contract-to-contract composability awkward. Trusted execution environments (TEEs, like Intel SGX) push execution into hardware enclaves and rely on the enclave attestation being trustworthy, which is a hardware supply-chain assumption. Multi-party computation (MPC) distributes computation across parties so no single party sees the full input, but it requires coordination rounds proportional to the circuit depth, and the latency compounds quickly.
Fully homomorphic encryption takes a different path. The state stays on-chain, encrypted. Validators run the computation directly on ciphertext, producing a ciphertext result. No one decrypts anything during execution, because no one needs to. The encryption scheme guarantees that decrypting the output gives the same answer you would have gotten by computing on the plaintext.
FHE schemes: what practitioners need to know
There are four schemes worth knowing by name. They are not interchangeable. Each makes different tradeoffs between the kinds of operations it supports and the performance cost of those operations.
BFV and BGV are both schemes that encode integers modulo a plaintext modulus and support addition and multiplication on ciphertext. BGV is essentially a noise-management refinement of BFV. Both are well-suited to integer arithmetic where you know in advance how deep the computation is, because each multiplication roughly squares the noise in the ciphertext, and once noise exceeds a threshold decryption breaks. To handle deep circuits, both schemes rely on a technique called bootstrapping that refreshes the ciphertext at the cost of significant compute time.
CKKS is designed for approximate arithmetic over real or complex numbers. It is the scheme of choice for machine-learning inference and signal processing, where some loss of precision is acceptable. The “approximate” qualifier is important: CKKS does not give exact integer results, so it is wrong for applications where correctness requires exact equality (like “is this balance exactly zero”).
TFHE is the scheme that the fhEVM work is built on. It supports fast gate-by-gate evaluation of boolean circuits and comparison operations on ciphertext. The key characteristic is that TFHE does not accumulate noise in the way BFV/BGV do; instead, it bootstraps after every gate, which sounds expensive but is fast enough that individual gate operations complete in the millisecond range on server hardware. For smart contract logic, where conditionals and comparisons are the most common operations (“if encrypted_balance >= encrypted_amount”), TFHE’s support for fast comparisons is a better fit than schemes optimized for polynomial arithmetic.
Figure 1 shows how the four schemes position against each other on the dimensions that matter most for contract logic.
quadrantChart
title FHE scheme positioning for contract workloads
x-axis "Slower evaluation" --> "Faster evaluation"
y-axis "Approximate results" --> "Exact integer results"
quadrant-1 Good fit for contract logic
quadrant-2 Possible but slow
quadrant-3 Poor fit
quadrant-4 Good fit for ML inference
TFHE: [0.75, 0.85]
BFV: [0.35, 0.80]
BGV: [0.40, 0.78]
CKKS: [0.55, 0.15]
Figure 1. FHE scheme positioning by evaluation speed and result precision. TFHE sits in the upper-right quadrant because it bootstraps per-gate rather than accumulating noise, giving it fast comparisons at the cost of higher per-gate overhead than CKKS.
The fhEVM architecture
Zama’s fhEVM is the most concrete implementation of FHE-based smart contract execution as of early 2026. It modifies the EVM to add a set of precompile-like operations that perform TFHE evaluation server-side. Fhenix and Inco Network are both building L2 chains on this foundation.
The model works like this. A contract declares state variables using encrypted integer types: euint32, euint64, and so on. These types are not stored as plaintext integers; they are ciphertexts on-chain. When a transaction calls a function that operates on these types, the validator invokes TFHE evaluation on the ciphertext operands and writes the resulting ciphertext back to storage. Nothing is decrypted during execution.
Decryption is a separate, explicit operation. Contracts can request decryption for specific values, which triggers a threshold protocol: a committee of keyholders each produce a partial decryption, and the partial results are combined to reconstruct the plaintext only when a threshold (typically two-thirds or more) of committee members participate. No single committee member can decrypt on their own.
Figure 2 shows the flow from transaction submission through encrypted execution to the two-step async decryption path: a request transaction that triggers the committee, and a separate callback transaction that delivers the plaintext.
sequenceDiagram
participant User
participant Chain
participant Validator
participant Gateway
participant Committee
Note over User,Committee: Tx 1: execution
User->>Chain: submit tx (encrypted inputs)
Chain->>Validator: execute contract with TFHE precompiles
Validator->>Validator: homomorphic ops on ciphertext state
Validator->>Chain: write ciphertext result to storage
Note over Chain: state remains encrypted at rest
Chain->>Gateway: emit DecryptionRequest (contract-gated, specific value only)
Note over User,Committee: Async gap: Gateway relays to committee
Gateway->>Committee: request threshold partial decryptions
Committee->>Committee: each member produces partial decryption
Committee->>Gateway: combine partial results into plaintext
Note over User,Committee: Tx 2: callback (separate on-chain transaction)
Gateway->>Chain: deliver plaintext via onRevealCallback()
Chain->>User: event / state readable by dApp
Figure 2. Transaction lifecycle in an fhEVM system. Execution operates entirely on ciphertext (Tx 1). Decryption is asynchronous: the contract emits a request to the Gateway, the threshold committee settles it off-chain, and the plaintext arrives in a separate callback transaction (Tx 2). Validators never see plaintext state during execution.
Worked example: a private auction contract
Here is a simplified encrypted sealed-bid auction in pseudocode that follows the fhEVM style. This is not production Solidity, but the types and operations map directly to the fhEVM API.
// SPDX-License-Identifier: MIT
// Pseudocode: fhEVM-style encrypted auction (not production)
pragma solidity ^0.8.20;
import "fhevm/lib/TFHE.sol";
contract SealedBidAuction {
euint32 public highestBid;
address public highestBidder;
mapping(address => euint32) private bids;
bool public ended;
// Called by each bidder with their encrypted bid
function submitBid(bytes calldata encryptedBid) external {
euint32 bid = TFHE.asEuint32(encryptedBid);
bids[msg.sender] = bid;
// Encrypted comparison: does this bid exceed current highest?
ebool isHigher = TFHE.gt(bid, highestBid);
// Encrypted conditional update: update highest only if isHigher
highestBid = TFHE.cmux(isHigher, bid, highestBid);
// Track bidder address off-chain via event or separate logic
}
// Step 1: called after deadline - request async decryption of the winning bid.
// The Gateway/oracle picks up the request and settles it in a separate tx.
function revealWinner() external {
require(!ended, "already ended");
ended = true;
// Emits a decryption request; plaintext is NOT available in this tx.
Gateway.requestDecryption(highestBid, this.onRevealCallback.selector, 0, block.timestamp + 100, false);
}
// Step 2: callback transaction delivered by the Gateway once the threshold
// committee has produced and combined the partial decryptions.
uint32 public revealedHighestBid;
function onRevealCallback(uint256 /*requestId*/, uint32 cleartextBid) external onlyGateway {
revealedHighestBid = cleartextBid;
emit AuctionEnded(highestBidder, cleartextBid);
}
}
A few things in this sketch are worth noting. TFHE.gt(bid, highestBid) runs an encrypted comparison and returns an encrypted boolean (ebool), not a plaintext bool. TFHE.cmux is a ciphertext multiplexer: it selects between two encrypted values based on an encrypted condition, so the contract never branches on plaintext. The comparison and the conditional update are both homomorphic operations; the validator executes them on ciphertext and the result is a new ciphertext written to storage.
The revealWinner function does not return a plaintext value directly. It submits a decryption request to the Gateway; the threshold committee produces partial decryptions off-transaction, and the plaintext arrives in a separate callback transaction (onRevealCallback) that the Gateway delivers once the threshold is met. Decryption is requested for a single value at the end of the auction, not during the bidding phase. Every bid remains sealed throughout.
The hard part
The cryptography works. The hard part is everything around it.
Performance is the dominant constraint. A single 32-bit encrypted comparison in TFHE takes on the order of tens of milliseconds on server hardware. For a simple operation like “compare two bids,” that is manageable. For a complex operation like encrypted sorting over a large set, or encrypted division (needed for an AMM price calculation), the costs compound quickly. Fhenix’s testnet targets block times significantly longer than standard EVM chains precisely because the additional TFHE computation overhead is real. Hardware acceleration via FHE-specific chips is an active area of research and commercial development, but production-ready ASICs are not in general availability as of early 2026.
Ciphertext size. A TFHE ciphertext for a 32-bit integer is substantially larger than 4 bytes. Storing encrypted state on-chain means storage costs that are meaningfully higher than the equivalent plaintext storage. For applications with large state surfaces, this is a cost modeling problem that needs to be worked through before committing to an FHE-based design.
Key management for the decryption committee. The threshold committee that holds the global decryption key is the trust anchor for the entire system. If the committee is compromised, all historical encrypted state is retroactively decryptable. This is a different threat model than ZK-based privacy, where no global key exists and users hold their own secrets. The committee must be large enough that collusion is expensive, distributed across jurisdictions, and subject to rotation procedures that do not require re-encrypting all existing state. Most current fhEVM deployments use centralized or semi-trusted committee setups, which is fine for testnet but needs careful governance design for production.
Who decrypts, and when. The decryption gate is a policy decision encoded in contract logic, but it relies on the committee actually cooperating. If committee members are unavailable, decryption fails. If they are coerced, decryption happens against the user’s interest. Designing the conditions under which the contract can request decryption, and who can call revealWinner() in the auction example above, is part of the security model, not an afterthought.
Integration and day-to-day development
For a team building on an fhEVM chain like Fhenix, the development loop looks mostly like standard Solidity development with additional type discipline. The main practical changes are:
Encrypted types cannot be used directly in if statements (no if (ebool) in Solidity). All branching over encrypted conditions must use cmux or the TFHE equivalent. This forces a programming model where all branches execute and results are selected homomorphically, similar to how constant-time cryptographic code avoids secret-dependent branches.
Testing is harder than plaintext contract testing. You cannot inspect encrypted state the way you can read storage slots in Foundry or Hardhat. Fhenix’s tooling provides mock decryption keys for local development that let you decrypt state for debugging, but those keys must never reach production. The separation between the debug/test key and the production committee key is a configuration discipline item.
Gas estimation changes. TFHE operations are priced differently from standard EVM opcodes, and the gas model on fhEVM chains reflects the actual compute cost of homomorphic operations. Profiling a contract’s gas usage requires running against the actual TFHE precompile implementations, not a standard EVM emulator.
Decryption results arrive in a callback transaction, not in the same transaction that requested them. dApp developers must treat any state that depends on a decrypted value as pending until the callback lands: UI flows, downstream contract calls, and off-chain indexers should all be designed around this two-transaction gap rather than assuming synchronous availability of plaintext.
Figure 3 shows where an fhEVM chain fits in the broader L1/L2 architecture relative to the applications that would use it.
flowchart TD
User["user (encrypted inputs)"] --> App["dApp frontend"]
App -->|"encrypt with user's public key"| fhEVM["fhEVM chain\n(Fhenix / Inco)"]
fhEVM -->|"TFHE precompile calls"| Validator["validator set\n(ciphertext execution)"]
Validator -->|"ciphertext state writes"| Storage["on-chain storage\n(all ciphertext)"]
Storage -->|"decryption request\n(contract-gated)"| Committee["threshold committee\n(global decrypt key)"]
Committee -->|"plaintext result\n(specific value only)"| App
fhEVM -.->|"bridge for settlement"| L1["L1 (Ethereum)"]
Figure 3. Architecture of an fhEVM deployment. All storage is ciphertext; the decryption path is a separate protocol mediated by the committee. Note that the user encrypts inputs with their own public key before submission, and the chain holds a separate evaluation key used only for homomorphic operations, not for decryption.
Related work: FHE vs ZK, MPC, and TEEs
These four approaches are often presented as competing, but they solve overlapping problems with different tradeoffs. A practitioner choosing between them needs to understand where each one is genuinely better, not just different.
ZK proofs (Aztec’s private state model, RAILGUN, Tornado-style shielded transfers) give users strong, cryptography-guaranteed privacy with no global decryption key. The user holds their own secret; no committee can decrypt their state. The cost is composability: private state transitions in a ZK system require the user to be online and participate in each step, because only they can generate the proof for their secret state. When a private contract calls another private contract, re-encryption or proxy re-encryption is needed to pass secret state across the boundary. For use cases where composability is critical, like a private AMM feeding into a private lending protocol, this coordination overhead is significant. FHE handles this naturally because the ciphertext state can be passed between contracts and computed on without any user interaction.
MPC distributes computation across a set of parties such that no single party sees the full input. It provides strong privacy guarantees similar to FHE without the performance penalty of bootstrapping. The tradeoff is communication rounds: the number of round trips between MPC participants grows with the circuit depth, which creates latency that is hard to hide on-chain. MPC is a better fit for off-chain computation over shared private data (privacy-preserving ML training, private data marketplaces) than for on-chain contract execution.
TEEs (Intel SGX, AMD SEV) place execution inside a hardware enclave that even the host operator cannot inspect. They can be very fast, close to native execution speed. The trust assumption is that the hardware attestation is genuine and the enclave implementation has no exploitable vulnerabilities. SGX has a history of side-channel vulnerabilities (Foreshadow, SGAxe, and others), which has made some practitioners cautious about it as a primary privacy mechanism for high-stakes applications.
FHE’s advantage is that its security rests on mathematical hardness assumptions (Learning With Errors, LWE) rather than hardware trust, and it enables composable on-chain computation without user interaction. Its disadvantage is that it is still substantially slower than plaintext execution, and the decryption key committee reintroduces a social/governance trust assumption that ZK eliminates entirely.
None of these are universally better. A sealed-bid auction with a defined reveal time and a small state is a strong fit for FHE. A confidential transfer between two users who are both online is a strong fit for ZK. Off-chain training over encrypted medical records is a strong fit for MPC.
Where it breaks
Performance ceiling for complex operations. Simple comparisons and additions are feasible at current TFHE speeds. Division, modular arithmetic, and operations on large integers are significantly more expensive. An encrypted AMM that computes a price quote in real time is not practical today, because the homomorphic division required for the constant-product formula would dominate block time. Be conservative about what you classify as “simple” when scoping a project.
Storage cost at scale. TFHE ciphertexts are large. A contract that stores thousands of encrypted records will have storage costs that dwarf the equivalent plaintext contract. This is a fundamental property of the scheme, not a tooling immaturity issue. For applications with large, frequently updated state, a hybrid approach (encrypt only the sensitive fields, leave the rest plaintext) may be more practical than encrypting everything.
Committee governance is unsolved in production. The threshold decryption committee model is well understood cryptographically. The practical governance problem, who selects committee members, how membership rotates, what the slashing conditions are for misbehavior, how you handle committee members in coercive legal jurisdictions, is largely unsolved for production deployments as of early 2026. Testnets can use simplified setups. Production systems with real user funds or sensitive data cannot.
No debugger for encrypted state. You cannot read a TFHE ciphertext the way you can read an EVM storage slot with cast storage. Debugging a contract that misbehaves requires either decrypting state (using test keys in development) or inferring behavior from outputs. For experienced smart contract developers, losing the ability to inspect intermediate state is a meaningful productivity loss. Tooling is improving but lags well behind the standard EVM development experience.
Threshold collusion is a real attack surface. If enough committee members collude, all historical encrypted state can be decrypted. This is not a theoretical concern for systems that handle sensitive data: it means the privacy guarantee is only as strong as the weakest governance mechanism around the committee. Compare this to ZK-based systems where there is no global secret to compromise.
Forward secrecy is absent. If the committee’s decryption key is compromised in the future, all past ciphertexts become readable retroactively. ZK-based systems do not have this property because there is no stored secret. Systems handling long-lived sensitive data (medical records, legal documents) should weight this heavily.
Further reading
The Zama documentation [1] is the most concrete starting point for fhEVM development, covering the TFHE Solidity library and the type system. The Concrete library [2] is Zama’s open-source FHE toolchain in Rust, and its benchmarks give an honest picture of current TFHE performance. For the cryptographic foundations, Chillotti et al.’s 2020 TFHE paper [3] is the primary reference for the bootstrapping construction underlying fhEVM. Fan and Vercauteren’s BFV paper [4] and the BGV paper by Brakerski, Gentry, and Vaikuntanathan [5] provide the context for the other main schemes. The CKKS scheme is described in Cheon et al. [6]. For the ZK comparison, the Aztec yellow paper [7] describes their private state model in detail. The Fhenix testnet documentation [8] covers the L2-specific deployment concerns including gas pricing for TFHE operations. For MPC in a blockchain context, the Enigma white paper [9] is a useful historical reference, and the MOTION framework [10] gives a more current treatment of practical MPC systems. The Learning With Errors problem, which underlies the security of all lattice-based FHE schemes, is described accessibly in Regev’s survey [11].
Written with AI assistance, editorially reviewed.
References
[1] Zama, “fhEVM Documentation.” https://docs.zama.ai/fhevm
[2] Zama, “Concrete: TFHE Compiler.” https://github.com/zama-ai/concrete
[3] I. Chillotti, N. Gama, M. Georgieva, and M. Izabachène, “TFHE: Fast Bootstrapping over the Torus,” Journal of Cryptology, vol. 33, no. 1, pp. 7-58, 2020. https://doi.org/10.1007/s00145-019-09319-x
[4] J. Fan and F. Vercauteren, “Somewhat Practical Fully Homomorphic Encryption,” Cryptology ePrint Archive, Report 2012/144. https://eprint.iacr.org/2012/144
[5] Z. Brakerski, C. Gentry, and V. Vaikuntanathan, “(Leveled) Fully Homomorphic Encryption without Bootstrapping,” ACM Transactions on Computation Theory, vol. 6, no. 3, 2014. https://doi.org/10.1145/2633600
[6] J. H. Cheon, A. Kim, M. Kim, and Y. Song, “Homomorphic Encryption for Arithmetic of Approximate Numbers,” ASIACRYPT 2017, LNCS vol. 10624. https://doi.org/10.1007/978-3-319-70694-8_15
[7] Aztec Protocol, “Aztec Yellow Paper.” https://github.com/AztecProtocol/aztec-packages/tree/master/yellow-paper
[8] Fhenix, “Developer Documentation.” https://docs.fhenix.io
[9] G. Zyskind, O. Nathan, and A. Pentland, “Decentralizing Privacy: Using Blockchain to Protect Personal Data,” IEEE Security and Privacy Workshops, 2015. https://doi.org/10.1109/SPW.2015.27
[10] F. Boemer et al., “MOTION: A Framework for Mixed-Protocol Multi-Party Computation,” ACM Transactions on Privacy and Security, vol. 25, no. 2, 2022. https://doi.org/10.1145/3490390
[11] O. Regev, “On Lattices, Learning with Errors, Random Linear Codes, and Cryptography,” Journal of the ACM, vol. 56, no. 6, 2009. https://doi.org/10.1145/1568318.1568324