Fully Homomorphic Encryption (FHE) enables blind data processing on blockchains by allowing computations on encrypted data without decryption, and Zama's fhEVM implements this technology on Ethereum through a co-processor architecture that handles FHE computations off-chain while maintaining compatibility with existing Solidity smart contracts, using encrypted data types (booleans, integers up to 256 bits), threshold key management for secure decryption, and symbolic execution for efficient on-chain operations.
Implementing FHE on Ethereum: The fhEVM Co-Processor Approach
Added:[Music] today we'll uh introduce uh FH on eum using coprocessor so I will do it with uh Peter we uh we will present you everything so the first uh the first problem on uh blockchain is that everything is public so this is great like this is beneficial because since uh everything is transparent uh the process is uh trustworthy and veryable however when you want to build a decentralized application with privacy uh this uh openness uh become an issue and also we have like what we call a fully homomorphic encryption or FH so FH is a technology that allows uh blind data process so it means that you can uh process data with without needing to decrypt it at any point so if you build a decentralized application or you build like a clo service and you use f you you can like maintain encryption during the whole life cycle of the data to from transmission to storage to uh processing so that's why fhvm uh brings uh confidential smart contract uh on chain using FH the goal of fhvm is to bring like end to end encryption directly uh on the blockchain by encrypting inputs and states and since everything is using FH you can also have a compos so you can imagine that you have some encrypted data on contract a un crypted data on contract B and you can store for example the result on contract C so if we think about like bring FH on uh on the blockchain you can think about like many use cases with possible with that so we can talk like quickly about like the blind auction for example if you think about blind auction without FH it would mean that any bidder will push encrypted bits on chain but this bits at the end would be like decrypted to compare and decide which is like the winner of the auction if you think about fhg you can imagine that all beers push encrypted bits and in the end you can determine who is the winner of the auction without decrypting any bits even the winning bits so the only information in the end is you know the winner but you don't know the amount of token he put in the auction so uh what is what is great with fhvm it's uh that also it brings like everything directly in solidity so you write contract directly in solidity the goal here is to have like a a library where you have like new types so this is what we call encrypted types so you have like encrypted booleans obviously but you also have encrypted integers for four bits 8 Bits up to 256 bits and this types can be used in many operators so we have like comparison operator so you can compare two encrypted integers for example like equal lower than greater than but you can also do arithmetic operation on these types so you can have addition subtraction multiplication and so on a good thing also on fhvm like with the FH it's possible to generate uh random number so this is encrypted random number directly on chain without the need of any Oracle so you can just create Cipher text containing an integer nobody knows what is the integer in this ier Tex until it is decrypted at some point and the last thing like I said at the beginning uh of this slide is that everything is in solity so you can like easily uh use it directly with your solidity stack you already know and this is what we will uh look right now by taking like for example a erc20 transfer so this is like basic example and we can imagine that we write it in directly in uh in F so as you can see this is like pretty similar of what you would do with uh like plain text uh amount but there are a few differences so we'll start with the first part it's uh the the ADD and sub for example so what happen under the wood it's like we are using tfhs Library so tfhs library is a library onlink types directly so when you write 3T code under the wood what you're doing is basically like manipulating everything with TFS and we basically like for the ad we will have the the ad for the balance and the sub to the S where we remove the the amount today uh based on o Benchmark we are like around two or three TPS uh with a CPU if we have like a node using a CPU and when we talk about the GPU we are like about six uh transaction per second uh for that in the future what we plan it to multiply everything by by five so to have like something like a 30 on GPU and even like when aik will be ready we can reach something like 1,000 GPS so this is a a lot to the second part of the this transfer method is this uh Alo so when you write Cipher text and you push Cipher text on chain this is great because everything is encrypted but at some point you would expect to have the possibility to decrypt some data but you want to avoid like anyone to decrypt it that makes sense so the the goal of this allo function is to have like an ACL contract so Access Control list contract directly on chain and you can imagine that this Access Control list is like a key value store where you say okay this saer text can be decrypted or can be Pro processed by only this address for example so this is like just unchain contract and it will like allow or disallow uh contract and wallet to manipulate this saer text and decrypt it so to use it is pretty uh like easy like you see the code it's just saying that this sa text I allow this address to use it meaning like we can process it or or decrypt it the next part will be presented by uh Peter and this is about the decryption and real encryption can you hear me okay uh so with FH obviously you can do computation on data and data remains encrypted uh all the time you can do this in succession multi many many computations in a row but for this to be meaningful you have to at some point show the data and that's why we have uh decryption and re encryption uh and let's look at how we do it so on the on the fhvm uh data is encrypted under FH public key but the secret key obviously we don't want to give it to some some single party because this party can decrypt all the data uh it can do it uh offline and basically there's nothing we can do about that so our solution is to introduce the threshold Key Management Service or KMS for short and what what this thing basically does is we we split the the FH secret key uh into multiple shares uh and we give these shares to separate um separate nodes it will be best if these nodes are independent um and then we use multiparty computation to do encryption and decryption between these nodes um and uh at no point in time the secret key uh is known to any single party so basically if if there's an attacker they have to basically corrupt multi parties um and also this system also supports uh secure FH key generation which means that uh when when the fhvm is created for the first time for example we will uh run the NPC protocol to create the key and uh again the key won't be available to any single party uh even when it's created uh it's interesting to to note that the the KMS is also a blockchain itself and we use the blockchain because we first of all we want immutable walk of all the actions that happened on the on the KMS all the decryptions or encryptions it did uh and uh and also we can use it for payments like the operating the KMS we want to basically for it to be paid uh and because now the the KMS is a blockchain and fhvm is on a blockchain we now need a component that allows these two blockchains to to work together and this is uh the Gateway component that we uh that we introduce and I will talk about itth a bit later but basically it just uh it can read all the all the data needed to to do a decryption or encryption it can read the Theo from the from the chain as CL was mentioning also extract proofs that um the is actually persisted on the blockchain fetch the cyer text and pass all this information to the KMS to to do a decryption or re encryption uh and for the KMS it's a complex uh system and we have a separate talk on it so if you want to know more about it you should listen to that talk uh let's look at decryption so the the the meaning of decryption is to make a value public so basically you have an encrypted value we put it on chain and now we make it public by decrypting it uh it works in a asynchronous way uh in the sense that um the develop veler would uh call this function like gateway. request decryption and pass in the the cipher text in the form of a handle to the cipher text so the handle is a very small value that refers uniquely to a cipher text but not the actual Cipher text and also call back callback function and this function will be called eventually when uh when uh decryption is uh is done in a future block uh in some sense it works like an oracle uh yeah that's uh that's decryption uh and if we look at it in more detail what happens is that um when request decryption is being called there is a decryption event d That's emitted on chain uh for a particular handle that is to be decrypted uh and then the Gateway just listens to these events on chain uh and when such an event occurs then the Gateway will fetch a proof from the blockchain that this handle is to be decrypted in practice this proof is a merco storage proof from the from the smart from the from the ACL smart contract uh step three the Gateway will go to go fetch the actual Cipher text from the from something called Data availability layer I'll talk about it basically the da is just a key value mapping from a handle to a cipher text so this is this is public uh nothing special just persistent key Value Store can be implemented as a blockchain even um and once the Gateway has this information like the cipher text and the proof uh it can send it to the KMS to to do the decryption and the KMS will um check the proof uh and if it verifies then do the do the decryption via MPC sign sign the the pl tax value uh and uh give it return it back to the Gateway uh and at that point the Gateway just calls the call back function in a separate transaction to to the blockchain could be on ethereum the blockchain could be ethereum itself so uh and and here we on the on the blockchain we can verify the the signature from the KMS and we this way the application will know that uh the KMS actually decrypted the value and the pl text value is actually correct so that's uh that's decryption re encryption is a bit different because the main idea for encryption is to not make a value public but to just show it to a particular user uh for example good example would be if you have an encrypted tc20 token I for example would like to see my balance but I wouldn't want to make it public so with re encryption I can uh I can view it uh myself uh by by for this to work I can generate uh my own secret and public key pair this doesn't have to be an FHA key pair can be any any scheme uh and basically I can sign my public key and send it to the system and the system will uh reencrypt the value from the FH encryption to to my key and this way only I can see this this value uh encryption happens fully off chain so this is the way it works is that um there is a network call to the to the gate way there's a there's no transactions here uh and we have a there is an example here of how you can use it in JavaScript uh basically we we ship a library which makes it easy for users to to send this networking request the the signatures and everything that's needed for it and if we look at the the FL itself it starts by the user sending the request by signing their uh their own public key for this for the handle for the value that want they want to decrypt uh the Gateway will again fetch the similar proof uh storage Merk proof uh again step three fet the actual Cipher text and step four send all the data to the KMS but this time including the public key and now the KMS will magically transform the uh this the the value from being encrypted ther FH to the to the user provided public key but without revealing the value at any point in time it's not decrypting and then encrypting it's re-encryption a special protocol where uh no no no information about the value is leaked so no no no KMS Noe sees anything about the value any other note can see anything about the value just magically encrypted under the user key also again signed by the KMS uh and the gy just forwards it back to the user and the user can use the their own secret key to decrypt the uh decrypt the value and only the user has this secret key so that's [Music] encryption uh and uh we've been working to to make this the the whole fhvm run on ethereum not just on a a native blockchain so that's what we've been working on recently uh and the way we do it is to first of all say we we deploy all the contracts are deployed ethereum on L1 without changing the compiler without changing the tooling the whole bite code is on ethereum itself uh and uh what we do is we remove FH computation from uh from from the from from L1 basically we we put it in a separate offchain component which we call the fhvm co-processor and the way it works is that when F first of all the cor processor itself is also full know so it's executing all the blocks that happen on ethereum and when when an fhvm FH operation is detected by the co-processor because it's doing every executing all the blocks it will it will also do the actual F computation so to give you an example if you let's say you want to do a plus b and a plus B encryp A and B and encrypted values uh on the on the co-processor we wouldn't do like ual FH computation will just uh fetch A and B from the da uh and just produce uh uh a new result so we I'll talk about this in a bit but the main idea is to to remove FH computation from uh from onchain uh data availability I was started mentioning it is just a persistent key value store and it's public so it's just to to map handles to Cipher text uh so yes that's uh that's the basic idea I'll go into more detail uh and the the benefits of doing it this way is that we don't have to change the blockchain so we can do it on any almost any blockchain could do it on ethereum and this uh makes it very easy to develop because developers don't have to change networks users don't have to change networks they only interact with ethereum only a single endpoint uh all the assets are on on this on on the L1 there's no bridging uh you can easily mix and match plain text and encrypted uh computation you can even compose uh like um have an encrypted smart contract and uh compose with existing uh let's say uh to rc20 tokens usdt or whatever it is uh and it will work uh automatically uh and uh it it also uh allows us to to run FH computation faster I'll explain a bit how by uh running it in parallel like splitting U doing the fhu execution itself in power uh and uh the way the way we do it is by something called symbolic execution uh what this means is that on the on the L1 on ethereum we we just do comput we don't do FH comput we just do operations symbolically on on these handles on the cipher text handle so the handle is a very small value like a 32 by value that refers to a cipher text and we uh we we essentially commit to the to the operation that has to be done on ethereum itself for for example if we do a plus b uh what happens on L1 is that we just deterministically produce a new handle that uh is a is the result of a plus b uh but without any computation so in practice we just basically Hash A and B and produce a new handle C which is the result and that's that's all that happens on A1 it's very cheap to do it it's uh almost no computation but on the offchain co processor that's also full note when when it sees that uh there is Cal a plus b uh the co-processor will uh will actually do the FH computation and uh insert uh when when the result is ready insert the result under C in the da lay so that's why that's how uh that's how uh the result becomes available and uh this works because we it's very rare that uh people want to decrypt immediately after doing the the execution most of the time people will be doing multiple executions like if it's a near C20 contract you do many transfers in maybe at some point you want to see the value or if it's a blind auction you'll be doing lots of computation on the cipher text and at the end maybe you want to decrypt the the winning bit uh so the coprocessor will be lagging and uh filling in this data uh on its own in on its own pace uh and I mentioned handles multiple times but uh just to talk about it a bit more it's just um un 256 value or 32 bytes just uniquely identifying a cipher text it can point to any any kind of a cipher text could be 8 bit Cipher text uh could be 64bit Cipher text any any uh any uh Precision uh and you can think of these handles as Futures in the sense that uh you when you do a plus b on L1 the result is uh a future that will eventually be resolved when the the co-processor does the computation so it's a yeah asynchronous in some sense uh we talked about what we do for results of computation but uh we didn't talk about how a user can input encrypted data to the to the system uh and uh basically want to avoid uh people abusing the system by for example if I have a a valid input I don't want anyone else to take my input and use it maybe they'll use it maybe they'll decrypt it I don't want uh my my input to be um to be usable by anyone else and that's why we we we require an additional step when when you want to input Cipher text and an example is your C20 transfer if the amount I want to transfer is encrypted then I I need to pass it from the outside as an input so what I will do is i u first of all encrypt the plain text value and uh additionally I will produce a zero knowledge proof of knowledge that I actually first of all know the value that the encryption was done correctly and that and that uh this particular Cypher text is to be used in a particular contract I don't I also don't want this value to be used in different contracts so when I encrypt the value I want it to I want to be used in this particular context this particular contract that I'm uh I'm using so so step one here is for the user to send the the input the the cipher text and the the zero knowledge proof to the co-processor this is an normal networking call no transaction um we have a library for that JavaScript library that makes it very easy to do the encryption and send the the input and um the co-processor will verify the zero knowledge proof and if it verifies it will first insert it into the da so that it's Norm a normal Cipher text that can be used as the other ones and uh also signs the input and the the reason for signing is that when when the user later uses the handle in a normal transaction we we want to make sure that the user cannot just come up with some random handle that uh doesn't have a cipher text in the D D layer so uh if the V if the signature doesn't match we'll just fail on the blockchain itself if it matches then it mean if it verifies it means that the co-processor signed this input uh yes and um there are different ways to secure the co-processor uh a simple solution could be to just use trust and run it in a central way uh maybe use reputation like maybe a company is well reputable and the users will trust it um another way is to decentralize the the coprocessor and in this case uh we just run identical copies of the co-processor and they can reach consensus on what the results are uh another way is to use fraud proofs similar to optimistic rups in that case uh everything that the co-processor is doing is public and also the data availability layer is also public so anyone can verify if he doing the right thing and uh if not fraud proof can be submitted and maybe the co-processor is penalized for that we can also use like a third party service to to actively validate it but the idea is that there are options depending on the on the application uh and finally uh so I was talking about uh symbolic execution and that is very cheap so what could happen is that a malicious user a malicious actor can just create a contract that's doing a ton of symbolic execution which is very cheap on L1 uh but this execution will lead to a lot of f computation that's expensive uh and the co-processor will not be able to keep up with that so uh that's why we want to charge for FH operations on the co-processor and also we want to charge because operating the co-processor requires Hardware resources so uh we just have a different ways to do it we can pay by Fiat money we can pay by the native token we can we can pay by uh your C20 tokens we can also think about who pays right it could be the developer could be the the end User it's just depending on the application uh and yes I think that's that's it on the slides and I think now we have something interesting uh a real demo yeah um how that uh we will okay perfect so um so the good thing is to to look a little bit at some code and run it and see what's happening um so this is like um uh a contract I think it's big enough yeah okay so um we can take a look at uh one uh function um is the mint so this is like ASC 20 contract so mint um in this case uh it's uh it won't be encrypted so this is a like plain text mint amount but as you can see we still have some tfh add function so it means that even if you send a minted amount in plain text uh this amount will be added to the balance of the owner of the contract but the balance of the the the owner is encrypted so what we are doing there we are adding the adding the M uh amount to the current uh balance of the owner which is like maybe not zero so this is like a TF operation because you want to add uh plain text to A encrypted amount okay so this is like the first line and the two line following are the Alo we discuss uh earlier so the idea it's like since we just created a new encrypted uh unall so this is a the result of this tfad will be like a new unle we want to uh let this handle be accessible for the owner so if if the owner at some point want to see is balance uh well you need to access it and also you you need to give access to the contract so this is a true line for the TF yellow so the first line would say okay this a test can be decrypted at any point by the contract and the second would be like the owner uh of the balance can at any point uh do a re encryption to get is balance then you just add the unencrypted value to the total Supply and you just emit an event so pretty pretty simple on this side so this is a mint and we can take a look also at the transfer function it's just there so uh the transfer function is a a little bit more complicated because we receive an encrypted amount because when you want to transfer uh some amount to someone you want you don't want to disclose the amount so you send an ncrypted amount to someone so the first thing is to verify that you have head of token because if you want to transfer a large amount that you don't have enough of token this is not good and you don't want to decrypt uh any balance at this point so this is the goal of this select value this select function sorry you see first line This select is basically if uh the condition so the question condition is is transferable this is like computed above just there if the this encrypted Boolean is true the value will be the first the second parameters if is transferable is false the the third parameter will be set so what we say we say okay the transfer value is the amount or if the the person has not enough fund we say the transfer amount to zero like this we transfer nothing and we in some way cancel the transaction by just adding zero and removing zero because like we don't decrypt anything this is like everything is done in an encrypted manner so we can't have the the concrete information the only thing we can do it change the amount by zero if uh something is uh false in this case so then we can have like the new balance for the the receiver yeah the receiver so we just add the transfer value which is like the amount or zero to the balance and we directly assign the authorization for this new unall so we let the the owner of the balance to decrypt reencrypt the value by calling the Alo like we did for the mint and it would be exactly the same for the second part for the Sounder where basically we do the same we add we remove the transfer value and we reassign correct authorization to to uh the owner so this is uh basically this is the Cod so when you you have this contract like you you see this is pure solidity and since we have like co-processor onm we can like directly deploy that on sepolia and play with encrypted types directly on seia so this is what we will do so we have like a a small website to test that we just deploy a contract on seia so this is like the contract we we've seen so the the rc20 will be uh deployed and we'll start with with zero token in it so the first thing to do is to uh uh mint it so as you can see like we just display the the balance so you can see the handle is z x0 so it means that I don't have enough token so for no the the is new N I don't have any token of any sort but if I add I try to Mint a few tokens so I just pushing like a basic transaction so it's just calling mean function so I would expect to have an encrypted balance with the value of uh 1,000 337 and this is the case so like you see it's like more like instantaneous because I'm the only user right now so I we lost the connection and um so uh so like as you can see um the under change so now on chain on eum on this specific contract my balance is ZX FB so it's a u 256 and this is the unle of an actual Cipher text this Cipher text is store somewhere else on the co-processor side but on Shain you have this handle and you have like a a DA layer data vity layer where you can verify that this actual uh andle uh ex is this Cipher text and if you decrypt it because I have the right to decrypt it I'm the owner this is the value I get I can also like check quickly uh on uh SS scan the transaction for mint and since we saw that the mint is a plain text if I look at parameters it just like uh directly the the the amount is just uh 13 37 I think we can see the plane text in logs yeah you see the the plane text there so this is like plain text this is what we did but in no case if we start playing like by transferring some token so I will take the second account for example and if I transfer uh few tokens to my second wallet let's say uh this so what you you see in logs uh the first thing to do is to encrypt this uh swis 37 so to do that uh it would be done like a client side so no information leaked from my browser so the value is encrypted directly in my browser we have like some wasm to do it directly in the browser and this value then will be sent to the co processor so the co- processor will just receive the cipher text and the proof and returns like a correct uh Andals so this is like a a u 256 uh like representing the actual safer text and what is a sent if I check on S scan maybe it will take sometimes to load and what would be sent uh during the transfer it just like unle of the actual cyot cyot is already on the co-processor because I pushed it before transferring before emitting the transfer uh transaction but what has been sent from the method is this and this is just the encrypted amount like the the unle representing the encrypted amount pushed on the cor processor so from like the from anyone perspective like there is no information leakage you just see in transaction with some like uh Ash passing but you don't have the cipher you don't have the plain text value and if I check the what I what I have on the my balance now I have effectively just one, now because I just transferred some tokens and normally if I switch to my second account I should see my uh my new uh value I didn't check sorry and I see like the I know as effectively the correct amount but so on this you have everything like uh just unall and everything uh encrypted on Co processor but you still manipulate and do transaction only on eum and at no point you change your your L1 that's all I don't know if anyone uh ask questioning question so uh regarding the usage of encrypted value as you've shown uh the unle are stored in the storage of the contract I think so if you want to do only memory operation it's not possible to use it right now uh you you can do uh you mean like if you not persisting the handle yes you you can do it you basically so I was uh I was saying that U when you do an FH operation you basically hash the input handles to produce the result handle so nothing prevents you from doing that you can do a lot of uh uh so my other question is how is the handle computed because I thought that it was based on the storage slots but if it's not then no no the handle itself is only uh is only computed based on the on the input on the input handle so if you do let's say uh you know you do add and you pass in handles you just basically hash the handles themselves to produce that's all you do uh so you just C the A and B let's say you concatenate it's not like that but let's say you just concatenate A and B and you produce the result and that's the the result handle it doesn't depend on state only on the okay so the same two input values will produce the same yes you and I do one this is the same yeah but you would have to but you would have to use the same SI vertex so maybe you if you encrypt one and encrypt one we would wouldn't end with the same saer text so but if we manipulate the same saer text obviously yes okay and also uh the underlying tfh scheme is the terministic meaning that if you do any operation on the same inputs you get the same output all the time so on the Practical side when we have minted now some token that is in this smart contract how would interoperability between existing rc20 tokens and this kind of confidential transaction look like uh I I think one project we have is to to have like some rapper around the like classic us20 so the idea to to say okay you have like a plain text us20 would say and you just wrap this token with that uh but otherwise uh you you are pretty limited if in the contract uh from the start you don't like under TF and and like any un types is there like any way for potential leakage of information let's say we wrap a some amount of tokens we sent part of the tokens to some other address and now this other address withdraws them unwraps them basically kind of you can reconstruct then like how much initially now is on this other account right yeah yeah if you don't like uh design everything with encrypted types from the beginning you you you like the risk is to leak at some point an amount if you for example like try to to do some swap for example with an encrypted erc20 and a non un crypted 20 this is like possible but you leak some information at some point so this is like the the risk uh with like plain text like because you you need to to yeah to take in consideration that you you always need to think about like when you decry something what would be uh happen in the end okay um yeah I thank you for the presentation um a question about the infrastructure that is needed you were referring like you can now do that on ethereum what about if I want to do it in another layer too is it flexible enough or right now is just on ethereum uh it's it's flexible you can do it on uh on any any uh infastructure we you just need to agree on the have a way to agree on the symbolic execution like if you sell to then maybe you agree on the on the L2 on the symbolic execution then you have I don't know maybe it's like an L3 some the co processor outside of that does do that's doing the computation okay but right now is deployed for ethereum if I get it right all right in practice this is just uh what we did for for ETC but in practice you can do it on any any chain great thank you it has to be uh yes uh it has to be evm right now has to be evm compatible yeah yeah great [Music] okay uh on your example I think that the inputs are uh you in 64 is it the limitation currently uh yeah for now we just implemented a64 uh we plan like next quarter to have a un 256 I think it like more related to taming taming and Hardware Hardware we are using um like today we know that we can use a 256 uh but for example for division it can takes a few seconds so regarding the block time but on Coosa this is not an issue because if you want to divide 256 maybe it will take longer but you just delay the decryption process you can like C many operation and maybe have a like a wait few seconds for a specific transaction because you want to divide something bigger so in it's planned to have a bigger types and uh we are like for now we are running everything on CPU but like running on GPU will be like far easier to to have bigger types but it's planed next quarter we we have for example encrypted address for example so this is one 60 bits already thank you time
Up Next

Confidential ERC20 Tokens: FHE Integration by Inco and Circle Research
@WhiteboardCrypto
13.1K views•2024-12-03

Torrent File Format & Bencoding: A Technical Deep Dive
@AsliEngineering
12.5K views•2022-08-08

Privacy-Preserving Portfolio Management with FHE | Zama Demo
@zama_fhe
415 views•2025-10-30

Understanding Ethereum: A Comprehensive Beginner's Overview
@99Bitcoins
3.1M views•2018-06-26
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Blockchain & Crypto













![[Panel] Beyond TPS: The Modular Road to Scale](https://i.ytimg.com/vi_webp/wcYQdgOupL0/maxresdefault.webp)

























