ZK8: Poseidon VM: A zkApp friendly blockchain virtual machine - Shumo Chu & Brandon Gomes - Manta

28 Sept 2022 · 27:54

Poseidon VM is presented as an EVM-compatible proposal to lower development, gas and proving barriers for zero-knowledge applications. Its layered design combines elastic anonymity-set storage with precompiled circuits for programmable private assets, configurable disclosure and anonymous signaling, while re-randomized commitments enable composition in Solidity. The speakers describe a middle ground: EVM applications remain supported, but tooling would not yet fully match, aggregation was future work, and compatibility sacrifices a uniform interface.

Speakers

Topics

Transcript

foreign good afternoon everyone today I'm going to talk about President VM a ZK app friendly blockchain VM with evm compatibility and I will just give a brief brief intro of where I'm from We're from pasadon Labs at the goal of the Poseidon Labs is to bring privacy to every web series project So currently we're working on deploying a mental Network and the cloud Mari Network on both kusama and polka dot and today I'm going to talk about President VM which is our research

project and the talk is brought you by me I'm the co-founder of posted on labs and also Brandon he's our CTO um yeah let's get into the talk right so what's a go here I think the goal is to bring the next 70 000 ZK apps hey you may ask me like why you come with these magic numbers and first I just the coming coming up with a number arbitrary and second and if you are into kind of like a programming language research nerd group your action can get a joke and if you get a joke I'll buy your beer afterwards um yeah so let's briefly look at the ZK application landscape right so I think

the first category I would say for the ZK application is for privacy right so you have the sort of OG privacy cryptocurrency Z cash like where men child were building some cool stuff in poker kusama for a private assets and there's a Leo and there is uh ZK uh optimistic Grow Up by uh PSE from ethereum foundation and there is Aztec there is espresso and uh sorry if I don't include your favorite project here right I only have so much screen realist and I will say the second category of the ZK applications is scaling right so they're like I went for a ZK event project like ZK sync scroll and polygon Hermes and also we've seen a new class of emerging applications

um basically using ZK for attestation oracles for example you have sismo they have a ZK tester and there's like a ZK graph slash hyper Oracle right I think the question we are asking today is that so how can we further democratize ZK applications right why isn't there like a 70 000 ZK application today so we think there are like three problems from the kind of like a democratization of ZK applications the first is that high barrier to entry for ZK development right in our team we actually hire like a ZK uh cryptographic phds but I don't think like every ZK app development should have that right so I

think that's the first barrier the second barrier is actually for high gas fees and high prover costs I think for high gas fees right even in L2 right a lot of like a ZK applications you have you do have a very prohibitive gas cost and let alone a lot of ZK circuits they have like minions or 100 minutes constraint and this which incurs a very high prover cost and last but not least right so their lack of a tool chain support right so if you're looking at how people are programming ZK today right you're either using very high level language with like circum which is great but once you want to deploy it right so it's very hard to get like an Integrity of optimizing the

circuit or you are using um some like wonderful libraries like arcsworks but you kind of like a writing assembly code and you are spending a lot of time to do the security audit spend a lot of time to hand optimizing the circuit right it seems like this have kind of like a dichotomy of how do programming ZK apps right so we're here to solve the question so then let's come to the personal VM goals right I think Pursuit on VM have this explicitly three design goes to solve these three issues so first for high barrier to entry for ZK development so our solution is that we want to bring layer the programming abstractions and we think we need to provide programming

abstractions in three layers the most bottom layer restored layer which we want to have a unified and convenient storage apis for zika applications the second layer is circle layer right we want to bring compostable ZK Circle pre-compiles and the top layer is the app layer we want to enable you can do a lot of a composition using pure solidity right I think Brandon later will dive into detail of these all these three layers and the second issue is a higher gas fees and high prover cost I think the second design goal here is that we want to bring Dirt Cheap ZK uh transactions so um we need to do a lot of work in order to make this happen but

in a very high level so also all this optimization Works need to get into these three different layers just give an example right for example in Paseo in the storage layer right we're actually using um like a ZK for any hash functions like Paseo to replace the cachac in the like ethereum storage um so the last point is lacking tool chain support and our solution is that we want to actually maximize The Leverage of existing ethereum tool chain systems which means that the VM itself should be compatible with existing ethereum apps and for the ZK part right we want to work with existing tool chain providers

like a hard hat truffle and you name it right so that's a three design goes and let's actually take a step back to think about a little bit about the design philosophy of the VM right so what we're taking here is we're actually taking learning from the best which in my view is a Unix program Unix operating system right we want to make the design modular which means we write simple parts that connect connected by Clean interfaces we want to make it simple in a sense that we only add complexity where you must and we want to make the rule of Separation which is clearly reflects in the layered abstractions where we want

to separate policy from mechanism and separate interfaces from engines right next branding will tell you how can we achieve that all right so I'm going to tell you how we are able to achieve those three goals so first let's look at the general architecture so we have those three layers that you want to describe the storage the circuits and then the DAP layer and we'd like to make this analogy

with Unix as well so at the bottom layer you can think of having the file system API um so think you know the the calls that you can make to direct files and then above that lives like the C programming language and so if you are you know really hardcore trying to optimize make really performing code you write C code that lives and calls the file system API and then above that you have let's say bash scripts so bash scripts the the individual scripts themselves could be written in C but they're called in this higher level language and so you don't really have to know how C Works to enable to like build batch scripts and build programs using your uh using your computer so this is sort of the the kind of analogy we want to make with the three layers so first let's talk about the storage layer

at the bottom so the the first abstraction that we want to build here is called elastic anonymity sets so so what are those so first just think of a set I have a collection of items and it's a dynamic set so I can insert and remove items and I can also have a notion of a membership where the item is in this set or not and then we want to add anonymity over it this is where the ZK part comes in so if there's an item in this set I can I can do a membership proof of it without revealing which item I'm referring to and when I remove an item I'm not telling you which item I'm removing I'm like nullifying the item so that contains will always return false but nobody knows which item I've removed so you can see here this API we have the

those three methods contains insert and remove and for contains you need a ZK proof uh to you provide SDK proof so that you don't reveal which item you're referring to and then for remove you also need a ZK approved to build the nullifier so that you don't reveal which item you're removing but you still remove it so for insert you don't need a zkp you just insert the item so the so that's the anonymity set part the elastic part refers to the fact that we don't need to give the developers the API for growing this set the second grow dynamically underneath inside the VM itself and it preserves the anonymity ratio that you provide so let's say you want one and one and one million

anonymity the the set can grow over time it's going to support more than a million items while still keeping one in a million anonymity so this is the API we give here and so where does this live inside of the state inside of the state tree so on the left you have the evm compatible storage this is still using the kesjack hash function this is the MPT that you you're usually familiar with if you're using evm and so we just build a side tree here that has the uh the EAS is inside of them and you can see there's the those three there the three different color ones uh each one will be given to a contract a contract can read and write from either one of those and then other contracts can read from other contracts State using the contains method so of course

for zkp we need to have a hash you know a ZK friendly hash function so Poseidon which is about 2 000 times faster you can think just uh than catch up in circuit right so this is sort of the main structure of the of the state tree so once we have the storage layer now we have a notion of adding and removing items from a from a storage without uh revealing which items we're moving so now let's look at the kinds of applications that build on top of this so first we have ZK assets these are programmable private assets so if we start with something like say zcash where we have the notion of private transactions we want to extend this to Applications so that we can given the assets that we have we can give them to

applications like uniswap or openc or what have you and they can operate on those assets without having to for us to unwrap them put them in some public account and then do it and then put it back so we want to find some automatic way to do this so let's say for now we're only supporting the standard tokens the rc20 721 1155 and we can we build an abstraction on top of the of those assets that lets you privatize them and lets you um forward contract forward calls to contracts so they can use those assets without revealing their owner so that's the first part of the programmability the second part is that these should also be compatible with other ZK applications some stuff like

metal semaphore and espresso so so this is sort of the overview of that so let's look at the API again so for the shielded pool we have the familiar deposit transfer withdrawal functions which take you from the account model world of ethereum or whichever system you're on into the private utxo model like zcash so that's deposit and then of course withdrawal you can come back into the account world or you can transfer internally within the utxo world and the fourth thing here which is special is the fact that given a utxo we have we can give this utxo to a contract and the contract can modify the state of the utxo to to do whatever it's supposed to do like swapping and can return the utxo back into the shielded pool without

having to without for example the user having to know what the final state of utxo is so this is the this is the part that we can provide here with ZK assets so the how does work so we have the notion called transparent utxos so you see at the top there we have a zcash style private transaction where inside of the commitments you store the the actual value of this of this of this utxo and the purpose of the zkp is to make sure that you're preserving the value as you're taking inputs and outputs so you don't create you don't create money out of nowhere and to also ensure that when you nullify those those objects that you're not double spending so that's the purpose of the zkp up there so instead of we do is we extend

the the utxo not just being a commitment but also containing some public value externally to it and this we just extend this notion of transfer where you can move the the amounts inside and out inside and outside of the utxos so still here you can see on the left we have two fully opaque utxos like nine and six and then we transform them into one of them which is transparent which has eight value outside and seven inside so now this one with eight can be given to a contract and the contract can modify that that outside part so you can form say a swap so we'll see an example and this design is is inspired by flax by waydai it's highly modified but it's uh it's inspired by that so let's go

through an example so let's say we want to do a we want to call uniswap without revealing our address so first we we select one utxo we'd like to spend we'd like to swap with so we let's say we have 10 wrapped eth so we select one of these we make it transparent using one of those transfer mechanisms then we give it to this ZK asset router which we can say Okay given these utxos and given this contract I'd like to call please execute it for me and so the ZK asset router given the utxo knows the value that's stored in in the transparent part withdraws those funds from the shielded pools account itself performs a swap and then can rebuild the the other transparent utxos

that should go back into the pool so let's say you know you're taking one wrapped Ethan creating 2000 die so you create those two output transparent utxos and then just insert it into the pool so because you know that you're you're able to spend that first one you create the transparent utx Zone in such a way that those final ones you can also spend but the contract doesn't know who who it is right so basically you're saying the let the shielded pool act act in my behalf instead of me revealing my address all right so this is the this is sort of the main example people that you can you can look at here so that's that's revealing the entire state of the utxo this that's fully transparent but maybe we only want to give a few details about it we want to

just prove some smaller property of it so we call these configurable asset disclosures so an example perhaps is you have some nft let's say you have the an ape nft like and you want to you want to you want to proof inside of a inside of a contract that it is an nft sorry that it is an ape nft but you don't want to reveal which one you have right so you could have this is nft disclosure where you pass in the address of the ape contract you give your utxo and you give a proof that if you were to open the commitment you would see that there was a in there without revealing which one you have so this is a little component you could use and then another one doesn't doesn't have to be just about the ID you can also prove other

kinds of properties so for example that you have at least five wrapped each where you could have more than a five right so these kind of little modules right these can also be pre-compiles that are built in at this circuit layer so you can build more uh more complex applications than just you know spending and transferring so the the third category of uh applications that this are the third category of uh pre-compiles that live at the circuit layer is stuff like uh signaling so this is inspired by semaphore it's slightly modified but so you can think of signaling as anonymous on-chain messages and so the way you build one of these systems is you build some context where you give some set of

rules on who is allowed to make messages and how often they're allowed to make them and the rules for those messages so let's look at two examples the first example is the polling example so let's say you want to run some some vote on chain and the rule is that one identity one vote so you you build some set of identities which you consider to be um you consider to be the the allowed participants and the the signaling protocol will ensure that when they sign their vote that they are in fact you know it's a valid signer that they've only signed one vote and not multiple votes um and it still keeps them Anonymous right so this is a kind of assistant and you can build with signaling another

kind of system you can build is a message board so on a message board you want to still allow multiple messages not just one but maybe you want to right limit them right so you don't get spam in your message board so these kind of rules you can encode and the signaling level and then the signaling zkp is just ensuring that you're following the rule of that of that context so that was the the circuit layer where we build sort of these these pre-compiles that are are optimized for this for this VM so that developers can use these Primitives when they're building their sort of bash scripts at the solidity level so let's talk about how we can build those so the first thing we need to figure out is how do we compose ekps so before we

saw we had a bunch of these different circuits like the shield pool transfer or the is nft circuit or the signaling circuit so we need to find a way to compose uh compose them so so that we can know that we're calling the same uh we're calling those circuits on the same private data so here's a naive solution is let's say you have these circuits C1 and C2 and they operate on this private data W and the public data X and so you would if you do these separately you produce two different proofs right so one solution is okay I'll just combine both circuits so that I know that I'm actually operating over the same W right you could think in some malicious prover they could just put a different W in C1 and different W and C2 right you'd have

no way of knowing so instead let's just put the circus together right but this doesn't scale because let's say if we have a hundred or a thousand of these little modules right you'd have to build every combination you could expect right which which doesn't it it grows too much right so that doesn't work it's not modular so let's find some other solution for this so one solution is called re-randomized commitments and so what we do is we take that original circuit that operates on W and x and instead we add an extra an extra constraint inside of it where we basically just commit to the private data W and we reveal that commitment we we um we we make the commitment value the the actual commitment uh public input so that now we can compare those

and make sure that they're the same for multiple circuits so at the bottom here we have that original scenario we have the C1 and C2 and we'd like to transform them into this RC form so now because W is still private our c is public and because of the binding properties of these commitments if RC is the same on both then you know the W is the same up to the security of the current scheme so let's look at an example of how we can use this RC system the randomized commitment to build an example contract so let's say you have the ape Fest 2023 event and you want all the ape holders to vote on where the venue is right but you want them to vote anonymously so if we build this contract here first you

build your mapping of all the votes right you have some set of proposals let's say you know five different venues and you count how many you votes you got so first you uh first for anonymous vote the first object is the RC this will link together all the different proofs that we provide and then you have the proposal you're trying to signal on and then the proof that it's a valid vote so the first thing we do is we take the shielded pool contract and we check that the RC is that the RC binds to some some value in that pool so I just prove I own some asset I don't know which one it is yet but I own something right then the next line is saying okay let's check that it is an ape nft so we take the same RC right because we know that

the same witness is being used here so we take the same RC and we say okay now that I've proven I have some asset I know no it's it's an ape nft I still don't know which one it is but I know it's one of them so now we're saying okay those are the valid credentials for someone to vote right in this in this protocol so now that they we know that they're a valid voter now we check the proposal okay because the the um because it's using the same RC we we check the signature of The Proposal that it matches the signal that we're allowed in this context so once you've checked all those three things we just increase the the number of um the number of votes for that proposal so this is how you would build one of these at solidity right you don't have to build any

circuits yourself you just compose these smaller modules sort of in this unix-like way that lets you um lets you build some more a complex application on top so that's the story of composing sort of at this conjunction level where you have multiple properties you'd like to prove about a single piece of data this is the conjunction kind of composition but there's other kinds and the other kind is is chaining so let's say you have some proof that someone gave you about something you'd like to prove that you know that that proof is valid right so now I'm proving something about a proof and you can keep changing these things and in general this is known as proof aggregation so so far we haven't talked about aggregation we just talked about

conjunction based composition but aggregation is also something we'd like to support in the future so the way we're going to build that is instead of just having pre-compiles for specific circuits that you'd like to compose also have pre-compiles for different curves so you can build your own proof aggregation Primitives yourself so stuff like the pasta curves start verifiers or also the BLS curves so the the pre-compiles that live at that circuit level don't also just have to be circuits they can also be cryptographic Primitives so you can build your own you can build your own aggregation systems so that's sort of the overall design now let's just talk about the different trade-offs that we've made and to try and position um trying to make the the decisions that

we made clear why we made them so first let's look at vitalik's classification of zke VMS so we we're not as easy this is not a zkvm necessarily but uh we it we think it's still helpful to look at the Spectrum here so we've also put optimistic role upstairs as well so if we look at the the different categories here the first is ethereum equivalent so exactly the same as ethereum supports it you know exactly the same execution and this is sort of what the PSE group is is working on with their zkvm still a work in progress the second category is minor changes so you don't break any existing applications but it's not exactly the same as ethereum L1 then you have then you have category

three which is maybe you're missing some hash functions so maybe you've instead of just replacing some of the state tree like we did with Poseidon maybe replace the whole state tree with Poseidon right so in that case you you can't be in exactly the same as evm so you're in sort of category three and maybe you're missing some pre-compiles like you don't have the BN pre-compile in your system so that's sort of category three and then category four is just okay just forget the evm entirely let's work on a high level language like solidity or maybe even um it's literally your viper or or also Cairo for Stark net so this category four so we think Poseidon VM lives in category two where we still support every evm application but we're providing more more pre-compiles so it

won't be uh it won't match all the existing tooling just yet so this is sort of where we live on this compatibility Spectrum and so let's look at some other trade-offs that that we've made against other projects so let's the three categories I'd like to talk about here are on-chain execution the the way that you build composite systems and the programming model so we just look at an optimistic roll up like optimism or arbitrum the execution is evm and you compose using the evm composition and the programming model is solidity right or other kinds of evm high-level languages so in those systems you can also build zkp you can build ZK apps but you need let's say using circom it won't be as fast as the system we've built

because we have the the pre-compiles that let you optimize the gas cost of individual circuits so you can do it there but it's not going to be as efficient so that's sort of the that's that's why we for example use ZK pre-compiles over not using them and then you have something like aliormina where you have the verifier has this on-chain execution and the rest is done off chain or you you build your proofs off chain and then you do the verification on chain and the way that it composes by proof aggregation right right so you have this notion of you know when when I'm calling another contract I build a proof that I executed that contract correctly off chain and then if that contract calls another contract then I just pass the proof of the first one into the second one and verify in

the second one I just chain these together so that's just uh just purely using proof aggregation and you have to sort of use a custom language for any of these systems um so something like Leo or typescript right in the meanest case and then Poseidon VM sort of somewhere in the middle where we still want to have evm as our main on-chain execution but we want to support making ZK apps themselves faster not just trying to do something like arbitrine where we make everything faster sort of by scaling everything so this is sort of the middle ground that we've Chosen and so at first we can support for composition because we're making ZK ZK apps faster we can use re-randomized commitments immediately to get composition at that

level without having to do you know resort to something like proof aggregation right in the future we of course want to support um at first we use it just re-randomize equipments and so you can also again use solidity and you can in this case use cercom um to to build your circuits as well and we're working also on something called opencl which lets you um not just use stuff like circom that lets you build let's say your solidity verifier for you but also integrate with other systems that are sort of less connected in this open source world like Halo 2 or plankey2 and maybe you wanted to write some code in solidity and then compile it sorry write some code in circum and then compile it in Halo 2. so this is sort of the kind of space that open ZL lives in and this is an

experimental project also alongside Precision VM so just generally the strengths and of these two protocols right Elio and Mina they're able to get this you know perfect uniform interface across the Caps you know you just have to think just Leo and then you can build everything with that um whereas for Poseidon VM we want to give uh compatibility with evm so we make this we we sacrifice that uniformity for compatibility so this is sort of the space of the trade-offs we're making here so just a summary of what what we've talked about right so first thing is to make ZK apps uh to make CK apps accessible right first you build these layered programming abstractions the storage the pre-compiled circuits and the uh and the composition at the top

then we make sure that these pre-compiles are making ZK apps faster so to get dirt cheap transactions and make sure that this whole system is as compatible as possible with the evm so join us if you're interested we're we're always hiring for all positions to build the next 70 000 zkaps thank you [Applause]