TACEO Privacy-First Stablecoin Transfers
NoirCon 3 at Devconnect Argentina 2025 · 20 Nov 2025 · 59:27
Roman Walch, Lead Cryptographer at TACEO, leads a workshop on multi-party computation and coSNARKs, covering single-user versus multi-user private state. It moves from Noir to collaborative Noir (coNoir) and finishes with private stablecoin transfers built from ZK and MPC. The session was part of NoirCon 3 at Devconnect 2025.
Speakers
Topics
From NoirCon 3 at Devconnect Argentina 2025, hosted by Aztec Network.
Transcript
Good morning GMGM. Thank you everybody here for taking choosing [music] to spend your time at our third inaugural no >> first stable coin transfers Noah and MBC in action. So what this talk will be about um a lot of technical stuff to actually in the end show you how you can build uh confidential token transfer from just some uh little lines of no code that you can deploy on any chain. But in order to do that I will need to introduce some um concepts that we're using there. So where the talk will start with introducing secure multi-party computation collaborative snacks and then how we use these to build something that we call private
chat state and this will power the de demo in the end. it is a confidential token transfer. Then I will talk about how we uh um MPCY um the noad tool chain and then finally I will be able to talk about this actual demo where I will also show some code on how we actually built this demo on um uh base test net. So if you have any questions during this talk feel free to just raise your hands uh ask me anything I will try to answer as good as I can. So now let's start already with um MPC. This is essentially the thing that powers everything that we are doing. So MPC is actually quite old already. It was introduced in 82 by a researcher called Yao and he actually motivated this problem of MPC with his uh now famous millionaires problem. So
that the essence of these problems is that we have two parties Ellis and Bob and Ellis is like hey Bob I am rich I bet I'm richer than you and Bob is like no way you're richer than me. and uh they don't want to leak their uh actual network to each other but they have no idea how to find out who is richer then and Yao actually introduced multi-party computation as a solution to this problem they can find out who is richer without actually revealing their network net worth to each other since then so now we have 2025 a lot of years have passed NPC has become um broader has seen a lot of research and what you can do nowadays with secure multi-arty computation is essentially compute uh a function on the combined
private inputs of a lot of different parties without leaking these inputs to each other. So it's essentially arbitrary compute on encrypted data. And I want to stress on this arbitrary compute a little bit more because especially in web 3 when you talk to people whenever they hear MPC what they mean is threshold signatures. But this is um one application of MPC in that sense they are computing um a signature from without actually knowing the secret key behind that. But uh this is just one application of MPC. In general, we can use MPC to do arbitrary compute on encrypted data. And how this works is um multi-arty computation. It has it in the name. There's a setup with multiple parties. I have it here on the right side. And uh for this explanation, I
will focus on a branch of MPC that's called secret sharing based MPC. And the way this works is let's say you have some secret data. This is the picture of the cat here. You want to compute on this secret data. What you have to do is you split it up in these random shares where each of these shares alone don't leak any information about the actual picture of the cat and they give one of these random shares to each of the um computing parties that are involved in this MPC network here and what they can then do with this secret shares is compute on them. So and there we distinguish between some linear functions for example adding these shares they can actually do this locally uh without communicating between the parties and the outcome is again some secret shares of the actual design
result they wanted to compute for for yes uh I can share them afterwards uh yeah I will I will post them somewhere and uh make them available so for nonlinear function we also can compute that for example multiplying do shares but uh we cannot do this locally but the computing parties actually need to exchange some randomized information to each other. So it's all randomized but uh still they need to communicate with each other and in the end what they get is still the output in secret shares of this desired result and once you have done this all these computations you can combine these shares again and get the actual result of the computation here in this case we turned the cat into the super cat here. So it's all about
sharing uh some data amongst multiple parties. Computing on these secret shares produces another set of secret shares and this computation might require communication between these parties and in the end you can uh combine these sets again to get the actual output of this computation and um so that the the bottleneck that you usually have with MPC applications is that um um if you have a lot of nonlinear stuff in the circuit the parties need to communicate a lot with each other. So this is the main drawback of MPC. All right. So what are collaborative snacks? Um long story short, collaborative snack is essentially just creating a snack, a zero knowledge proof in MPC. And um uh why would we actually do that is is they even um leading to
some performance stuff. And the cool thing about these uh snarks is that um they're essentially all linear. So when you're looking at the um at the the main batch of a graph 16 proof system of a ultra honk proof system like in edtech you see that they mainly consists of FFTDs MSM um some check etc. And this is mostly linear that means when I evaluate this knowledge proof system in MPC I said before in the previous slides linear stuff don't require any communication between these parties. So I can actually evaluate this knowledge proof system in MPC very efficiently.
And with very efficiently I mean the MPC does not add a lot of overhead compared to evaluating the SE knowledge proof without MPC. So and what when we do this as what we get as a result is a collaborative snack essentially has programmability from MPC. So I can compute on data that I um don't know of this data set in secret. I get the provability from the co knowledge proof system and in both of these MPC and co knowledge I don't leak anything about the data sets that are actually involved in the computation so with a co snack we have computability or programmability and provability without leaking data that is the um main thing that we are using for all of our duelings here so in
a coax there's a a little bit more involved than just MPC as your knowledge proof system so because when you think about it when you um now think without MPC if you write your noir code what is actually first happening is that you have to uh compute on this noir code on your input data and then before you actually create the SE knowledge proof you need to translate it into the proving key which is essentially a trace of the proving system and then finally once you have this done you can plug it into a prover for example ultra hunk prover to create the actual knowledge proof and uh what this pipeline actually means when we do a collaborative snack from Noah which is essentially the goal of our whole tool chain is that we will also need to be able to compute this uh
circuit that we have written in MPC before we then can actually use um for example an APC version of an ultra honk prover in the end. Then the the thing about collaborative snacks is that in in research when they talk about it they usually focus on the prover in the end and this one as I said on the previous slide is super efficient in MPC. But for this whole collaborative KN tool chain we also need to consider this what we call witness extension essentially computing the program in MPC and then laying out the the trace that is actually the input of the proof system. And I what um what I want to to tell you with this slide is that um um this part is always very efficient in MPC but this part the um concrete efficiency highly depends on the circuit that you want to
compute. For example, if you have only additions and multiplications in there, this one will be also very efficient. But if you have some more um complex stuff like uh bit take composition range checks uh ROM and ROM accesses which is all supported by uh Noah then this one will be also adding a little bit of overhead in here and this uh I just wanted to um keep in mind during the rest of the presentation. So that's already everything I want to tell you about MPC and collaborative snacks and now I want to talk a little bit about how we can actually use this to build what we call private shared state. But for that I need to first define what is private shared state. So when Ethereum was launched in I think 10 years ago uh what we have with these
smart contracts is that everything that you post on chain is public. This was definitely by design back then. But uh nowadays what we see is that is actually not enough because a lot of people want privacy there. But this was definitely by design and everything I post into a smart contract I can see in plain text on Ethereum. So now with adstack what we get is an uh um an evolution of this which we call private state. So instead of posting your data on chain into a smart contract, what you do is actually you keep your data private locally on your on your system for example on your PC and uh you only post a commitment of your data on chain and whenever you execute a smart contract that changes your data you have to post a new
commitment of the output data and you have to post the SE knowledge proof that you actually modified this data according to what was written in the smart contract. So this is actually a huge step up already compared to what was uh given with uh Ethereum here in public state. But it's still not enough because if you think about it, if I have some data set on um ade and you have some data on adst, we cannot combine this in a in a smart contract to compute on our combined data set without actually leaking. For example, I leak my data to you or you leak your data to me. And this is where private shared state actually comes into place. If we put an MPC network on top of the uh adst infrastructure for example then I can just compute this uh this uh smart
contract in MPC where I secret share my data to the MPC network. You secret share your data on the MPC network and the MPC network actually executes the the smart contract function and since we have a collaborative snark we also create a zero knowledge proof in the end that everything was computed correctly. And uh same as in uh private state, we will also output a commitment of the new data. And this one goes on chain as uh together with the co knowledge proof. And then everything is uh again like it should be in private state. And uh I usually like to refer this as a type of MPC roll up for um any blockchain here.
So essentially uh putting an MPC network on top of a um um a blockchain here. So since this is um kind of also playing a role in the demo later I want to drive this point a little bit further. So how would this actually look when we have a private shared state and we want to compute on it. So going through that in more detail, what we have in the beginning is we have two parties A and B, Alice and Bob. And they have each some data set D1 and D2. And um there's also some blockchain in there with a smart contract function. And these um data sets are actually already there as a commitment on chain. And now what we want to do is we want to compute this function on this data set using private shared state. So the first step is
actually that each party um secret shares the inputs to the MPC network. So um they split this up in this random looking shares. Give each uh give each each party one of these shares. Both of Alice and Bob do this with their individual data set and um since this is a secret sharing no one actually involved learns anything about the data set. So um the NPC network doesn't know what D1 is and uh also doesn't know what D2 is and obviously Ellis doesn't know anything about the data from Bob and Bob doesn't know anything from the data from um Ellis then we also have to give the MPC network the actual function that we want to compute and um yeah go to the next slide and then the MPC network is
actually able to use MPC to execute these functions on this input and since we're using MPC also no one is learning anything about intermediate results and only the final result is then revealed to the actual receiving party. So in this case we have a third party we call it Charlie and it gets the output of the computation which we call D3. What we also need to compute since we need to represent this DD D3 onchain. We also need to compute a commitment to this data that we also do in MPC and this commitment will go into the smart contract. So this is the new private state that we actually have created with this MPC network. And what we also need to compute is the co knowledge proof. So we need to prove that the correct
function was actually computed on the input. And very crucially we need to prove that the correct inputs have actually been used in the computation. So we need to recmp compute the commitments to each data and also this commitment to this uh newly created data we need to produce. And this third commitment goes on chain. So what happens now is um the MPC network is done with the computation has created the co knowledge proof has created the commitment. So what the smart contract on chain is now doing it's um verifying the co knowledge proof with the commitment that it got from the MPC network C3 and it takes the commitments that it also already knows on chain to verify that the correct inputs were used. So it needs to verify this proof
against these three commitments where C1 and C2 were already known on chain. So this does not come from the MPC network. This is crucial to actually bind this whole computation to the existing private state. And once this proof actually verifies this is very similar to what is happening at STEC right now. We get into a new epoch where all these free private states are now existing on chain here. And so you see with this uh MPC roll up we can actually compute on the data from the two parties without leaking them to each other and we get in the end the private state on the MPC network uh on the on the um blockchain here. So any questions to that or is this somewhat clear to everyone?
Uh so here this is just a representation here you don't commit. This is just shows that this is actually a commitment to T3. So that this is uh not showing that we actually compute it. This is just showing that this is the specific commitment. Yeah. >> No. Um so this MP I guess you're referring to this NPC network. Each of them has only a secret share of the actual data. So this random looking thing from which they don't get any information about the actual data. So as a collective they have the data but each involved party has no idea what the actual data is. So so um M1 here has no idea about anything from this data. M2
has no idea of anything about this data and M3 also has no idea about this data. But together they can compute on it using the MPC techniques that I didn't tell you how this in detail works. Yeah. >> Yeah. is how you reveal some aspect of the data. >> Yeah. So finally when you have computed for example this commitment here you you just uh send your secret shares to the other parties and if all of them do this you have all the secret shares and then you can combine them. So that that is uh then uh what we call opening of the data. So it recombines the actual data.
But you should only do that once you have something like a commitment that doesn't leak anything about the input data. Or for example here um Charlie is supposed to get the the D3 data set. So each of the MPC nodes sends their shares to Charlie and Charlie can reconstruct them to get the actual data. >> Got it. And that would apply for all the data in the set. >> All the data everything that you want to open in the end. Yeah. >> So if we want selective field disclosure, it would have to be multiple NPC networks. >> Um not sure what you're referring to. So, so we have only um one MPC network consisting of multiple nodes, >> right?
>> Yeah. And uh so if you want to reveal some uh intermediate value selectively, then they have the secretares of them and they just combine them again. >> Okay, great. Then um let's continue. And there's a a nice additional property that we have with this MPC setup and that is that um if there is for example some uh computation that leaves a full data structure of secret shares on the MPC network then we can keep it there in secret so no one except the MPC network as a collective knows this data so no individual party no one else etc. and they can keep this uh data in what we call in private shared state. So that there is it actually possible to build
use cases when no one knows the actual data set. So we will see this later with this confidential token transfer where we'll have the balances of all the users in private shared state which is located on the MPC network which essentially means we will store the whole balance mapping to the addresses in secret shares on the MPC network. No one actually knows the full data set. Only the MPC network has a collectic collective which means that uh no individual party knows anything about it but only as a collective they can make computations over it. What is also very nice is that uh a property in NPC is that you can just create random data which is also not known to anyone. And uh there are use cases out there. For example, if you want to have an onchain gaming system, bokeh or whatever, you
can let the MPC network create a random seat that is not known to anyone. And they can then use this seed to shuffle some deck. That is verifiably then on chain that the correct seat was used for shuffling, but no one actually knows what the that the deck looks like. So accept the NPC network as a collective, but each party in the NPC network has no idea about what the the actual shuffling was like. So you can use private shared state also as a technique to to to create random values on chain without anybody actually knowing what this random state is actually like. And this one is uh will be probably useful for a lot of these uh gaming application for example.
All right. This is everything I want to say about the private chat state so far. We will come back to it then when we have the the actual demo that I want to show you. So now I want to talk about our efforts of um MPCifying or collaborative snarkifying the noir um language. So the goal here is actually that we we um let you guys write your no code and then you get with our dueling MPC and collaborative snack for free. So we want to MPCify Noah and Barrettenburg. So as I said it's then easy for you guys when you write your no code that you would usually do for EDS.
You can also um reuse the same programs to to to get MPC and coax and in extension private set shared state from uh your noa programs. And there is also a nice property of um coax is that once I have created the co knowledge proof in the end then this proof is actually uh indistinguishable from whether I used MPC to create it or whether I just created in my on my own. So you can reuse all the the tool links that is there in the edstack infrastructure for example the paratenburg solidity verifier normal paratenburg verifier to verify the proofs that we create with our co- Noah and collaborative snark tool chain here. Then the workflow then I keep repeating this workflow is you
guys write the noir code. We have the MPC network. You secret share the inputs to the MPC network. The MPC network also gets the Noir code and you can um then get the output of the computation and the zero knowledge proof all from our dueling based from Noah. So um the setup here exactly looks like this. We have somewhere this MPC network that uh for example is hosted by by us with some uh parties that we we contract for that and if you want to compute on data from Ellis and Bob you use our tooling to secret share this data send the shares to the computing parties in MPC network then there's also somewhere a no program for example from a smart contract or maybe Ellis has written this
program this one gets then uh compiled using the normal no tool chain and this comp compiled program gets sent to the MPC network. And this one executes this Noah program using our dueling produces some secret shares of the output uh and also the SE knowledge proof and um Charlie in this case is the party receiving the outputs. It can use our dueling to reconstruct the output data and it gets the desired output and the zero knowledge proof here uh from our dueling and as I said before um the proof itself is now uh indistinguishable from whether it was created with MPC or not. So you can use either um the normal noad dueling the paratin back tooling to verify this proof or you can use uh our version of this verifier as well to
verify this proof. Okay. So what we always have in this collaborative snark settings is we have somewhere an MPC network that does the actual computation and with konoa what we get is that this MPC network executes code that is written in noa. >> Question. >> Yes. >> Yeah. So the we have um um some nodes contracted for that. So I will mention this on the next slide. I think we call this proof. So if you have some no programs that you want to try out, you can contact us and we give you access to that.
Okay. So um what is the state of Kona so far? So we write everything uh in Rust. So it's a Rust library and if you want to play around with it, there's also a small example binary that you can call with all the different steps involved. witness extension, proof generation, etc. But uh usually you would lose the library to embed it directly into your application. So we also have um implemented a ultra honk in MPC. We call this ultra co ultra honk and this is compatible with the berenburg version v 0 uh 3000 nightly something. So this very uptoate um the witness extension and trace building that is compatible with no one beta 15. So also very upto-date already and what we support
from Noah you all know no is kind of featurerich what we support in our tool chain is u um already quite a lot so normal field arithmetic definitely is the native data type of noa but we also know support these uh smaller data types U64 U32 and so on which internally use range checks in the antin proof system we um support the ro and rum accesses which you get when you essentially write a vector in um Noah, we um also unconstraints functions which internally get called to the brillic VM in Noah. We support most of the stuff here as well.
And uh for the blackbox functions that you have in Noah, we also support a good chunk of them already. For example, the Poseidon do blackbox function and exor MSM and many more that is all implemented in our tool chain. So this is all when you're using the co ultra honk but what we also have is a a a limited version of a um feature set where we can compile down no code to a cograph 16 prover so essentially mpcified version of graph 16 and um this one is actually based on the proof kit which is um essentially a noon compiler developed by some people by word foundation. So and for this um since you all may know 16 has a very limited set
what you can actually prove. So here we also do not support all of these uh things here this more advanced stuff that you can prove with ultra honk. But if have a limited set of what you actually want to write in you can also use the cograph 16 pipeline. And for a demo we actually using cograph 16 because we the graph 16 verifier is available for a lot of different chains and just u cheaper in terms of gas cost. Then as I mentioned this before based on your question we have a um a network life where you can if you have some uh nice no programs you can test them out how they would actually perform in a real MPC setup and if you have something like that just reach out to route reach out to us and we will give you access for that.
All right so you would say yes. So the witness extension was this part where I say where you actually have to compute the the no program in MPC and prepare the trace that is then actually the input for the actual proof system. So everything from a no program to the trace is um the witness extension and then afterwards there's either gra 16 or ultra honk or whatever. So what about performance of Yeah. Yes. Um um sorry >> um so essentially same as in Barretenburg I don't know what the exact
constraint is but obviously with MPC you see this on his slide here you get a little bit of overhead so um yeah in practice what this upper limit is kind of depends on the machine setup that you will use for your for your benchmarks >> how many Um so currently um we have a free nodes in the system. This is just a sweet spot where MPC is the most efficient one and uh yeah three nodes at the moment. Yeah >> essentially. Yes. Yeah. Every node essentially does the same computation that they just perform it on some randomized data and when they combine it
they actually get the computation of the actual data. Sorry what? >> Um, yeah. So, so in the in the beginning you get the secret from the actual data and then there exist specific MPC subrotocols which uh define what you need to do for an actual multiplication to work, what you need to do for an actual let's say a lookup to work and so on. So, Yeah. So, so we implemented that in the back end and we essentially compile the Noir code and execute the the statements in there and if you encounter
multiplication we know we need to do the MPC version of this multiplication and so on. So we go through this we have implemented that all and uh essentially interpreting the compiled n code and execute these functions then all right so um continue with some uh preliminary benchmarks that we have here. uh I have it for two subcircuits. One is just a Poseidon do hash the and the other one is a full Merkel proof that you might encounter in semaphore. And here the Merkel proof has a depth of 32. You can see um for Nago and Bretenburg um the these benchmarks here even the full Merkel proof takes um for witness extension 17 milliseconds and in
the proofs around 33 milliseconds and without dueling you can actually still get the sub-second proving times for that. um sorry 623 milliseconds here to be exact but there's a still a lot of um performance improvement that we can build in this ultra honk brewer but right now it's still um uh the overhead is not too bad all right any questions so far because then I will continue with actually applying this to a confidential token transfer demo great so then let's continue so u when you look at the token transfer. There are multiple ways of privacy that we can actually implement it in. For example,
on Ethereum, both the sender receiver and also the transaction amount is public. That is what the state is on Ethereum. Uh onst you have something like this here where the sender receiver and transaction amount stay private. This is also what Ccash has. And uh what we are interested in with this demo is here um this version with confidential token where send and receiver are allowed to be leaked but we just want to hide the actual balances of the parties involved and also the transfer amount when I do a transfer from Ellis to Bob and this is a version we have talked to a lot of people about this already and this is uh in first preliminary version of confidential token with which they would be confident in that they don't get too many issues with uh regulators.
So this is a kind of version of compliant um token transfers. So and for this demo that we have built it um we are implementing this confidential token transfer from collaborative noa and we're using the graph 16 pipeline since uh there's no point kind of doing this onstack because we already have this here. So we want to do this on an arbitrary chain to to shield an arbitrary token there. So as I said we want to be able to use this on an arbitrary chain. In the demo we deployed this to a base test net and in the demo we are also um uh shielding some um USDC token that we have launched there on this test net here. So essentially what this means is um that uh um the there will be the um essentially this token
contract that has all of this USDC in there and you can either deposit withdraw elements from this token contract and send them around to these uh uh different parties but the balances and also the transfer amounts stay private. So how do we actually implement this? So we will use private shared state for that and that essentially means that we keep all the balances from all the users secret shared in private shared state on the MPC network. We have a um a counterpart a smart contract which essentially um holds all the tokens that is in total in this uh in this um uh private shared state and it also is responsible of um keeping commitments to all of these balances to these user addresses and only adapt
adapting these commitments if some co knowledge proof that we create on the MPC network for these token transfers actually um is u valid. So more details a little bit of how this looks like. So in the smart contract we will have a essentially a mapping a hashmap from the addresses to some commitments on the MPC network we have a the same mapping from the addresses but here uh on the actual values we have secret shares. So these brackets here mean secret shares from the actual balance and the randomness used uh to actually create this commitments. So for creating a commitment you need uh randomness in addition to the actual data. So here this balance and this randomness together will create the commitments that are on the smart
contract here. So um what is the actual computations that we have to do in this setup? So in the MPC nodes where we have these balances and secret shares. If I want to send some tokens to let's say you here um that means that I need to subtract the tokens from my balance added to his balance. We need to recmp compute the commitments which will then be stored on chain and we will also create the co knowledge proof this collaborative snark that proves that everything was done correctly and uh with that I mean that the commitments have been computed correctly the correct input balances were used and also that um my uh balance as a sender does not get negative after this transaction here. So this is all
encoded in the SE knowledge proof and I will show you the the noir code for that on the next slide. U in some slides then okay uh in the smart contract so what is actually happening here is when I'm as a user want to initiate a transaction or want to deposit some money I have to tell this to the smart contract this can get stored in an what we call here in an action queue where we uh store for example that I want to send some tokens to to him here and um the NPC network reads this action Q performs this um action in NPC creates is your knowledge proof and gives the new commitments to the smart contract and when everything works out the smart contract updates the commitments and everything was done um
uh correctly here and what is nice about this setup here is that when I want to know my balance that is encrypted in MPC network I don't actually need to see your knowledge proof for that because I will just ask the MPC network to reconstruct the balance and the randomness to me and I can just check on my own whether this actually produces the same commitment that is stored on chain already so I don't need any knowledge proof for reading my balance. So reading the balance is actually super efficient in this setup as well. Okay, so just one slide again to to drive this home how this uh works in more detail. So if Alice wants to make a deposit into the smart contract, what it does is sends the token to the smart contract register the deposit in the
action queue and the MPC network will read this action uh produce the collaborative snark and uh updated the commitment. If I want to uh transfer some uh the tokens from uh Ellis to Bob, I will also register this in the action queue, I will only um post a commitment actually to this transfer amount. So we the whole point of this setup is that we hide how much we um send from Alice to Bob. So we only send a commitment to this to the um to the smart contract. So nobody actually will see how much we actually transfer here. And what I also need to do here is that um uh here in this case Bob needs to secret share the the the balance that we want to transfer and the randomness used to create this
commitment to the MPC network. You can either do this offchain by sending them the secret shares directly or store them in an encrypted fashion on the smart contract. And again, the MPC network will read this state from the uh action Q on chain, produce the new commitments, produce the SE knowledge proof, tells the smart contract that everything was done correctly and the smart contract updates the balance if the SE knowledge proof works out. Finally, if we want to have a withdraw. So Charlie here tells the smart contract it wants to withdraw 10 tokens here in in this example. Then USDC. What will happen here first is only the registering in the action queue and then when the MPC network reads this uh from the action queue performs the actual um uh update of the commitments
and the serial knowledge proof and sends it to the smart contract. If the ser knowledge proof turns out uh correctly then the smart contract is instructed to send this then tokens to Charlie here. So here it's important that you can only send out the tokens if the SE knowledge proof was done correctly. Then what we can see here since um here in this deposit um Alice is actually uh transmitting this token into the smart contract and here in this withdraw we actually also see a transfer onchain there's no need to actually hide um these amounts here because the the actual token transfer leaks this anyways. So we only hide it for the actual transfers between two parties here. And finally for a read of the uh of my balance I will directly ask the
MPC network. It will give me the balance in the randomness and I can just check whether this actually matches the commitment that is stored on chain. Okay. Any questions to that? I will show you the the critical parts of the smart contract in uh in some time as well. Good to go then. Yeah. >> Yeah. When you read the balances does the MPC reconstruct the balances or is it confidential to the >> it's still confidential to NPC network. So how this would work in practice is that each uh here uh Charlie will first authenticate that it actually knows the the secret key to this address by sending a signature uh and it will also send some public key there and this public key is then used to encrypt the
secret shares and directly send to to Charlie. Charlie can decrypt them and combine these balances. Yeah. Yes. what's the rationale for communicating through the smart contract instead of just goingirectly to >> um so here we have that the the advantage of having a smart contract is that this is essentially the ground truth of everything. So you can uh see that you actually register some transaction the MPC network then uh is forced kind of to to to keep it um good light in the public to act on this action and then um both the new commitments on chain. So this is the smart contract is the coordination and the ground truth of everything.
>> Can I selectively reveal my balance to somebody else? >> I mean uh we didn't implement it. So but if your use case has something uh where where this is useful then there's um actually nothing uh preventing this from being implemented. Yeah. >> Yeah. So we will talk a little bit about that later on. Um the essentially the the short answer for that is that if you also want to try hide the send and receiver then the MPC becomes much more involved and the the throughput gets less but uh you can actually do that but uh throughut is way less than what we get here.
Okay. Um so as I mentioned this before source code is written in O. I will then look at show you the the source code of this. Um and we compile this down to an ARNCS constraint system and use a graph 16 proof to to prove everything is correctly. Um so in the NPC network what is happening is that it modifies the private shared state. It uh performs the Kona witness extension. It compiles the Konado L1Cs system and then executes the MPC version of the CR 16 prover. And now I want to show you how little um no code is actually involved in getting this thing done. So um um what we do in this demo is actually um once the MPC network exe creates a knowledge proof we don't
do this for just one transaction we do this of a batch of um here um 50 transaction here so and this is the essentially the no code that we have here we have as an input 50 50 inputs for these transactions where the inputs are actually um the old balance of the sender the um the randomness used to create the commitment for the old balance of the sender the same for the the receiver. So the old balance and the commitment we used. We have the the amount that we want to transfer as the input for the knowledge proof. Also the uh randomness used to um create this commitment that is sent by the user on chain to indicate what you want to how much you want to transfer from Alice to Bob and what we also get as an input the new randomness that the knowledge proof
system will create um use to create the new commitments for the sender and the receiver. So these are all the inputs that we have for this proof system. Uh and you see here we have num transaction is 50 50 of these inputs here. So the knowledge proof essentially proves that 50 transactions were done correctly. There's an output here. This transaction output consists of five commitments and these are um in our world if you have an output of your main function this is essentially a public input to the proof verification. So when we want to verify these proofs, we need to provide all of these five um um commitments here. And these commitments are the old commitment from the sender, the new one from the sender, the old one from the receiver, new one from the receiver and also the
amount commitment that we use to um indicate how much we actually want to transfer. Then we will see this later when I show you the smart contract. It's actually crucial that from the MPC network only the new commitments are actually sent to the smart contract. To verify that everything was done correctly, we need to get the old commitment of send and receiver and also the amount commitment from onchain so that the users actually get the assurance that the correct data was used in uh issuing this transaction here. So regarding this um the the the main function here what we actually do is um we iterate through all of these transaction inputs and call this transaction function here. And you you can see this is also when I go there that the the code is also um relatively
small here. So what we do is first um we check the amount which is essentially recomputing the commitment of the amount value that we have as I said we need to uh output this uh amount commitment again which then is used as an input for the proof verification. And what we check here what we essentially need to check is that the amount is not negative. And here I somewhat arbitrarily chose it to to limit it to 80 bits. This is u um more than enough to send millions of uh um um USD USDC uh on chain even though if you denote everything in way. So um here that the important thing is I said is limiting it uh the balance to be not negative in here. So going back again to the to the function um what the next step is that
from the from the sender we need to withdraw the the balances and um well what happens here is um just the subjection of the amount we also need to assert here that the the the resulting amount is not negative. I also somewhat arbitary here set it to 100 bit but uh the important thing here is that the the amount is not negative here so that the actual the sender has enough balance to do the actual computation. Yes. >> Oh okay. Yeah. What whatever you want. >> Yeah.
So I'm looking at this case where I think it's a pretty popular one. Let's say that every transaction is augmented with a unique civil resistant identity, >> right? So it might be many different addresses, but they're tied to the same identity. Let's say we want to make it so that you're only allowed to transfer up to 10,000 USDC, right? >> Yeah. So that part is straightforward. What I'm curious about is how would you build a transaction >> encrypted key?
>> Yeah. So um what you can do so um since encrypting some values with a fing key is also kind of a circuit. You can also evaluate this one in MPC. Let's say the NPC network have this fury here. So they can just produce a cipher text and output this and later on people. So you store essentially the all this data that might get revealed later on in cipher text and later on if you get this uh request and someone actually has this viewing key they can actually decrypt this uh cipher text. Um you can also make this that this viewing key is a secret shared so in MPC for multiple parties maybe a regulator maybe the the use case provider and so on so that they only together can decrypt this data and the the use case provider may just do
this if they get a warrant from the from a uh from a charger so that they actually should do this. >> Do you need to generate the beauty up front for the circuit or can it be dynamic? I mean you you need to have it once you as at this time where you want to encrypt the data in MPC. Yes. But uh you can also think of changing the key at some point. Uh you need to engage in a decryption and a new encryption and so on. So the in general this is all possible but uh depending on how much you actually want to do this might impact performance of the whole system.
>> Would you be able last question on this would you be able to perform such a migration to a new key uh within NBC network? you would be able to do that. Um, so it's probably better to just do it in MPC network because otherwise the the party doing this needs to know the old and the new key which kind of is then leaking all the data. So you kind of should do this in MPC network. But uh if you have a huge database of all the cipher text it might take some while to actually do that. Okay, let's continue with that. So when I withdraw I said I need to assert that the um the the new balance is not negative and then essentially rest is just committing to um the the old value and the new value again so that I then have these commitments as a public input
to the proof verification and the the remaining parties then for this knowledge proof is depositing the values to the um the receiving party and here you can see we only have this addition here for the balance and also creating the commit commments again that you need for the proof verification and that's essentially it. So there's not really much involved just balance updating do range checks and uh five commitments computations and uh that essentially powers the whole um system here and there as a return value from this transactions is all these five commitments that you need to to verify this proof. So I just want to take some time as well to show you the smart contract that we have implemented for that. So that um um it's called
confidential token here and the main parts are essentially we have a graph 16 verifier that is generated from our no code. We have this uh um balance commitment map where for each address we have this commitment stored on chain that represent represents the current balance and here this uh we have this action Q where we allowed to register some uh either deposit withdraw or transfers. So and um the main functions that we are using um in this uh uh demo is for example when you have a deposit uh you tell the the smart contract how much money you want to deposit and here is then actually happening this uh um um transfer from the user to the uh smart
contract via the ESC20 token transfer and the remaining of this is just registering that uh in the action queue that I want to do a deposit with this specific amount. Similar for the withdraw, you essentially just put into the action queue uh the the intent of doing a a withdraw. And we will see this um then later when we when I show you the function where the knowledge proof is verified. If a withdrawal is happening then uh the this verification function will actually then perform the token transfer for for transferring some tokens between two parties. Um here also um um here this amount that I give to the smart contract is actually the commitment. As
I told you before I want to hide the actual balance. So I only put the commitment into the smart contract. I can show you this later on chain that is actually a commitment. um here and here this function is also built that um the secret shares from the balance that we want to commit and um want to send and the randomness actually given as a cipher text onchain where each secret share is encrypted with a public key from the the the recipient MPC node in the MPC network. So here we do the the the um sending the secret shares uh to the MPC network on chain. So and there are a lot of checks here that everything is in the prime field. But essentially what is happening then in the end is we just register the intent that we want to to transfer some amount from some sender
to receiver uh in this action queue again. And here we also store this commitment to the amount that will be later then used to create the the the inputs for the proof verification. So for the demo that we are currently running on base test net we also have a additional function that makes it just easier for us to to uh control the demo because in this demo we have around 200 wallets that are con constantly creating a transfer request to our uh request and uh since we are not millionaires we don't want to fund all of these 200 wallets at the same time. So here we have a a demo function which allows one party to actually register multiple transaction at once. Um this definitely should not be used in a redeployment but
for a demo it makes it just easier for us to to deal with our limited siblia e funds. And here what is actually happening is just registering for all of these uh amounts some um values in this uh action queue. So transfer from sender receiver and the commitments again. And for the demo again to save on some gas costs we uh we don't store the cipher text onchain but we give them offchain to the MPC network. So this is just for the demo that we because we're not siblia if millionaires unfortunately. Okay, this is for registering the the intents for the transaction. The main function that is used by the MPC network then is this process MPC function where we get as an input um on one hand as a
knowledge proof and the other input is essentially um the the indices where we stored the intent in the in the action queue and the two commitments that we need to give um from the MPC network to the smart contract by transaction. So this is the new sender commitment and the new receiver commitment which will then be stored in this uh commitment map. Yes. Um >> I'm sorry I didn't get the >> restrict.
>> Um so yeah in this setup we only want the one specific MPC network to to be able to update the balances. In general, if you if you have a a setup where you think multiple parties should be able to create this your knowledge proofs, then it should be fine to also um uh allow multiple of these networks to actually um send the proofs to the networks. But it's just way easier if it's one network dealing it because otherwise you need to synchronize the updates that you have between the MPC networks. >> Yeah. It's more of an engineering issue because if you update on this network and you update on this, you kind of need to sync the updates with it. Yeah.
Okay. And what is happening now in this uh process MPC function is that um I I said here we we are have verifying a batch of 50 transactions here. So we essentially uh go through all of these batches. We get the um the the actual um query from the action queue and then um I just show you the one for the transfer is the most important one. Um what we do here is we essentially build the the the commitment inputs for verifying the the knowledge proof. So here we we get um the the the old commitments directly from u um um chain and the new commitments are from the inputs here and it's important that the old commitments are the ones that we get from chain and
also the amount commitments is also the one that we we get from this uh onchain registry where we have um where the user made the intent to transfer the amount. So here they put in the commitment and this amount commitment is directly taken from this queue here as well. So you can see it here in this um um let me check here in this function. So this is from the action queue. So this important that you you take uh the old commitments amount commitment from the from the queue. So and then um u we just remove it from the queue and in the end we verify the co knowledge proof here and if it didn't work we just revert the whole transaction and uh also might be interesting for the for the withdrawal case we also initiated the the token
transfer from the um from the uh smart contract to the actual user and this only gets executed if the sing knowledge proof is done correctly here as well. So any questions to the no code and the smart contract? Yes question about performance for this particular code right can you give us some rough >> I will I will give that will come okay so let's continue with the presentations about performance [snorts and laughter] so about performance um for this setup so these benchmarks are here now with a batch size of uh 96 and we are actually uh getting a throughput of 209 transactions per second and this is uh including all of the knowledge proofs so you can See the runtime on a a bigger
machine with 96 CPUs for this full batch of 96 transaction is roughly half a second here. And uh there you can see that um 270 milliseconds are from the actual proof generation and 180 from the witness extension. And here this first column here is indicating what would be the performance if we do it without the knowledge proof just doing everything with MPC which means updating the private shared state and recomputing the commitment. And they could see here that the performance is actually significantly higher if we keep on the SE knowledge proof. But obviously in a real setup you want verifiability. So we um also compute the SE knowledge proof here. Okay. Um then for this demo I told you before we have uh launched this on
um oh I had it open already. So let me check if this still loading. So we have the deployed this on base test net. And what is happening here is you can see that um our our system um sometimes um after some delays sends uh register some uh new transactions on chain and this get executed by the MPC network. And we have here um two modes. Uh we first send some base transaction that we register between uh 25 or 50. This is randomly chosen on chain and this then gets executed. We do this three times in a row with some delays in the meantime because again we are not sepia eve millionaires. So we don't uh can't do this all the time. All the time we run out of funds quite soonish I guess. And
after free base transaction we have a a burst mode where we sample between um 250 and 500 transactions. And this then get also registered on chain and then executed by the MPC network. And uh uh in active periods what we get here is uh in onchain about 1995 transactions per second. So on here on the demo website what you also get is um you see the the current utilization of the MPC network. We show that we have uh since we set up the smart contract about 1.3 million transaction have been executed and the latency uh for the user between registering a transaction and it actually gets confirmed with a knowledge proof is roughly 2 seconds per
transactions and the average coach generation time is uh less than 200 milliseconds. Also on this demo you can see here um that the locks that are running. So here is essentially what the MPC networks each node of the network is currently doing and also here is what happening is uh what is happening on chain. So also um I said this before in this demo we have roughly 200 wallets involved um and since there's a um um demo where we control everything um we build it in that you can actually see what the current amount is um on chain this commitment but we can also show what the um current uh transfer is in in USDC but this only works for the demo because we control the whole setup in a
real setup you cannot reveal that for for the users but just here um for these wallets we have 200 wallet addresses I show you then onchain as well how this looked like. But here we also show the the transaction history that was happening there for this wallet. For example, there was an outgoing transaction with 316 USDC um and this was u registered as this commitment on chain. I can show you a little bit about the smart contract how this looks as well. So that's my contract is here on this address and um I will show you um first that in the in the absolute beginning each wallet was depositing some value onto the smart contract. When I press on this transaction you can also
see that the um let me quickly check. Oh yeah, here it says that there were um in this case for this wallet, we submitted or deposited 4,600 USDC into the smart contract and every wallet did something like that. Uh and that can can also show you that the smart contract itself has a balance. Um let me check where this quickly is. Um so I think this the smart contract. Yeah, exactly. Um here the smart contract currently holds around one million USDC um which comes from all the deposits of the 200 wallets here. So and what you can also see here if you look closer um what happening all the time is
that we uh register some uh transactions there. As I said for the demo, we use this transfer batch function. And when I go into there, what you also can see is that um the input to this function are a lot of addresses, the sender addresses, receiver addresses, and then the amounts are actually these commitments here. So we don't give the actual transaction amount to the smart contract. So the public has no idea what the actual transaction amount is. And these are represented all by these commitments on chain. And then when we have this uh process MPC function, you can see the the input is uh essentially um the the the indices of the transaction in the action queue and then uh the new
commitments that will be stored on chain and also the zero knowledge proof the graph 16 proof used to verify this transaction. So you can also um uh scroll through this further. We have verified the contract. So you can see that the the source code here as well. It's the same that I have shown you before. So, and for this demo dashboard, you can um so this one is online at mercy's demo.co.io and you can play around with this. See that we we will have this running for another week probably maybe more and it will constantly issue transactions on chain and the MPC network will then execute them. And yeah, you can play around with this a little bit more.
So, um one more slide before I want to conclude the whole talk. Um we had the question before what would happen if we want to um u build a confidential document transfer we also in addition hide the send and receiver. What this essentially means that is that on the MPC side, we would need a data structure which has a hashmap where the address is also secret shared and um um in addition to the balance as well. And we also need then to represent this whole hashmap as just one commitment on chain because if I have for each address one commitment uh only then if I update these commitments this would implicitly leak send and receiver again. So um this whole hash web needs to be only one
commitment on chain private and transaction is then just modifying this data structure similar to what uh is happening in the demo right now. And we have as your knowledge proof that everything was done correctly. So and we started investigating this as well. We have a small uh preliminary version of a fully private hashmap here. But uh since uh um this is uh more involved in the MPCNK setting, you will have to uh deal with less throughput if you want to deploy that. But that this gives you the ability to fully hide any token on any chain um even send and transceiver receiver in addition to transaction amount. So this brings me to the end of the workshop. Uh what I've talked about is collaborative snarks essentially uh
combination of zero knowledge proofs and MPC which gives you programmability verifiability and uh privacy. We talked about our um efforts in um bringing um MPC and collaborative snacks from Noah. So we have an implementation of Ultra Honk and Noah in MPC and this enables private shared state uh from Noah programs. And I've shown you that we have a demo running for confidential token transfers. You can check it out on the website. And um here we hide the transaction amount for transfers on on chain and everything is u done from noa and the compilation chain to prof 16.
And this demo will be running through uh the rest of the week and also in the next weeks. So please check it out and uh yeah see what you can do with Noah. Thank you for your attention. Was a pleasure to to be here. Hope you learned something and thanks again. [applause]