Privacy in Cosmos Live: Henry de Valence (Penumbra) - Penumbra's state model

6 May 2022 · 28:16

Henry de Valence of Penumbra speaks at ZKValidator's Privacy in Cosmos event in Amsterdam about Penumbra's state model. He explains how the fully shielded proof-of-stake network connects to the Cosmos ecosystem over IBC to create an ecosystem-wide shielded pool, and how ZSwap, its private decentralized exchange, uses sealed-input batch execution against concentrated liquidity to protect market makers' strategies while revealing only each batch's total volume.

Speakers

Topics

Transcript

and now i would like to welcome to the stage henry the valence from penumbra bravo [Applause] um well uh hello everyone um so my name is henry um i'm the founder of penumbra labs who are incubating penumbra um and today i'm going to be talking to you about some of the aspects of the state model that i think are kind of cool and interesting um so

oh does this oh no there we go i'm just bad at the remote all right so to start off um the uh the useful question is sort of like okay what is penumbra um and i think a good way to conceptualize that is that it's an answer to this question of how do we provide useful functionality on a private ledger so for the people who have kind of self-selected for a privacy and cosmos event i think the value of like having a private chain is is pretty um clear at least to this audience um but it it's we have this kind of unfortunate situation in which on the

one hand we have uh a lot of people who get a lot of use out of blockchains and then we also have some private blockchains and the venn diagram between those two things you know as someone who works on privacy is like uncomfortably close to two circles right so how do we fix like how do we actually build something that is useful and our answer is penumbra so penumbra is uh sort of a combination of of three things first of all we have this private proof of stake l1 built on tendermint that acts as just like a private base layer for everything has a private staking system which has some interesting things that um

we won't be getting into in this talk but you might want to check out later um and this l1 acts as a cross-chain shielded pool that lets you take any asset from any ibc compatible chain and shield that asset and record it privately on this this uh zone why would you want to do that um it's because we've also built or we you know by the time this launches we'll have built this private dex that allows people to do on-chain trading in a in a private way and i think i think that's actually a really interesting application because trading is a use case where privacy

doesn't just have this kind of abstract sort of principled value right you know i believe in privacy um but that doesn't itself make a compelling product whereas with trading you have the a situation in which privacy actually has this kind of concrete quantifiable near-term financial value that's giving people a positive reason to use this okay so maybe that sounds cool but there's this issue oh sorry um and and this is the the diagram of basically how that fits together right so you've got this big beautiful ecosystem in cosmos at the moment um everything is transparent and although there are

uh you know not just penumbra but other projects that are trying to build uh private parts of this ecosystem um it does seem pretty clear that we're not gonna you know just tomorrow wake up and everything is gonna be private right so from anywhere in this ecosystem you should be able to do an ibc transfer into penumbra and when you do that transfer you shield your your assets whatever they might be and then inside of the shielded zone you can transact stake swap market make and all the time just have uh privacy by default so this is all cool but okay like how do you actually build this right how you go from like what would be useful to how

are we going to build the useful functionality um and what i'm hoping to convince you of in this talk is that actually the biggest challenge to building a useful private system is not actually the kind of zk cryptography or like what proof system you're using or whatever but it's the the fundamental state model um and and that this is really the big blocker to building useful private systems so as a bit of context right in a traditional blockchain you have essentially like global mutable state right you have here's the chain state uh we get some transactions uh i have a transaction i execute it now i have a

new state and i'll have this other transaction execute that one new state and i just keep doing this in practice it would be kind of annoying to have to come to consensus on every single transaction separately right so you bundle them into blocks but fundamentally it's a big ball of state and you you know change it um and on the other hand if you have a shielded blockchain you need to have a a different state model that's built on composable state this is actually kind of more similar to the original utxo model in bitcoin where instead of saying like oh well we have this like big ball of of global state and a transaction can just like edit that and do whatever we have

this collection of state fragments and these state fragments are immutable but they're also composable so when i have a transaction what's actually happening is my transaction is going to say okay we take these state fragments we consume them together uh we're going to compose them into this new set of state fragments and then we'll append those into this like big collection of like little bits of state and why would you need this for building a shielded chain it's because this is what's going to let you make the whole thing private and the way that we're going to do that is we replace the actual state fragments themselves with just cryptographic

commitments to those fragments and instead of having okay here's the transaction that you can like literally apply uh that transaction is gonna have just a proof of of correctness that you know these are commitments to the the new state fragments that were made according to the rules and stuff so this is all really cool and awesome um and great and so we've you know solved the problem we have all these shielded blockchains right no um the the unfortunate problem with this is that this only works when there's no shared state right and the the problem is that whoever is making this uh transaction is has to build this zero

knowledge proof of a complete valid state transition and so there's two obstacles there the first is that whoever is making that proof has to have not like it's a proof of knowledge so they have to have knowledge of what the state transition is so there's no way that i can interact with your private state right without knowing what that state is and also there's this kind of early binding property where the transaction has to be this totally sealed blob that completely defines here's what the state transition is you can go execute it and that's kind of a problem if you're ever trying to interact with some shared resource because how do you know right if you want to submit a swap right you can't know

in advance like at the point that your transaction is processed exactly what clearing price you're going to get in order to be able to kind of pre-seal that into into a proof and so if we return to our question of like how do we build useful functionality um when we think about what kind of functionality people like to use essentially all of it involves having some kind of public shared state and so we can reframe this question as like how do we allow private interaction with some public shared state um and and this the way that i think

about this problem is that this is sort of the problem of shielding value flows okay so what do we mean by that um we have this kind of general situation where there's there's a blockchain it has some state it's got um it's doing some stuff right and so there's value that's occupying different roles within that protocol that application or whatever and there's transactions that are happening and those transactions are causing value to flow between different parts of this system right um and the the challenge that we have is like how do we hide information about these individual transactions so it's not possible to see what each one

specifically is doing while still revealing information about the kind of overall aggregate state of different parts of this system so as an example right you know how do you hide the amounts of each person's delegation but still be able to see the kind of aggregate total voting power of all the different validators or how do you hide individual votes right i mean you definitely want to have private voting because otherwise people are just going to like airdrop bribes to people but you still need to be able to like figure out what the governance outcome is the motivating case actually for

penumbra was like how do we hide individual trade amounts but still reveal the reserves of the amm so there's a kind of cute paper um by taron and guillermo and alex about how you know like if you have the amm before the trade and after the trade like it turns out you just like you know plug in a formula figure out exactly what the trade amount was um and then the last one that i think is kind of you know topical here is like how do you hide um bridge transfers well still revealing the the chain solvency so these are all actually kind of like different facets of the same basic problem um

and there's sort of two fundamental kind of classes of strategy for dealing this that go in opposite directions so the first one is trying to split up flows into little chunks and then the other thing you could do is you could batch flows uh into bigger chunks what does that look like so in the first case right splitting you could imagine some user has some like amount um and they're just going to split that into some randomized sub-amounts maybe they have some you know user agent that will do this for them and then they'll like spread those out into some like different transactions that each has like a little part and then later they'll try and like reassemble them and

just like hope that whoever's looking at the chain doesn't know statistics um so that's like obviously kind of sub-optimal um but i would i would say that the one thing that is good about this is if you do end up in this kind of happy world where there's like multiple private chains there is some sense in which this isn't necessarily the worst thing like if you tried to do this on a transparent chain you're gonna like definitely lose right away um but there's a kind of like worse is better thing in that disk is like something that some individual user can do on their own without requiring any kind of protocol changes or whatever

but definitely not the thing that you want to build you know like your whole protocol on and so the the second kind of class and an alternative is uh batching flows so here instead of having um you know just one user let's say we have a bunch of these different users with different values and what they're going to do is they're going to encrypt all of these integer amounts using a primitive that that we've started calling flow encryption so you can think of this as basically like a sort of spicy additive homomorphic encryption um and the the reason to pick a different name for it is that once you start thinking about how do we integrate this

into a blockchain you come up with this like long list of like all these extra properties that it has to have in order for it to actually like function as part of a system and at that point it's better to have um you know distinct name for the concept um so we have some docs on this on our protocol spec but effectively the flow is that once you have these ciphertexts right they're all additively homomorphic so the chain can aggregate all of the encrypted values over some interval um maybe that's over a block maybe that's over a full day maybe you know longer or shorter it depends on the application logic and the context but then the validators can do threshold

decryption to reveal only the batch total for that whole amount and once they have that batch total they can use that to do some public on-chain computation and at that point okay it's like this is cool but how do we actually use this so if we return to this original problem that we had of how do we allow private interaction with public shared state this mechanism of using flow encryption to do batching actually lets us do this in a way that is pretty cool but

has some interesting consequences for the state model so we'll start off with some user who has some private input and what they're going to do is create some transaction that does something you know what it is might depend on uh the application but that transaction is going to have along with whatever else some encryption of of their inter input which is their contribution to some some part of the fl of some kind of flow you know whether that's their vote whether that's an input to a swap uh whatever and they make that transaction they submit it to the chain and the other side effect of that transaction is that they're going to get

this kind of private state nft that'll it acts as basically like a receipt for participation so what happens when that transaction is actually processed and included in the chain it gets batched together with some other inputs from some other transactions maybe this you know will take some time if there's like a very long batch interval depending on the application but at some point um the validators will aggregate that together and then decrypt some batch total and at that point right they're going to do this public computation and the neat thing is that then you can have public outputs of that computation that get committed to the chain state and at that point uh the user who

originally submitted their um the the this transaction can use their private state nft to effectively just like mint some new private outputs and as part of the uh transition proof for their outputs they can use the results of this public computation so for instance if you wanted to do a shielded swap right your input is like you know what the amount that you're submitting uh to the as part of the trade and the public computation is like okay well we'll go and like resolve all these like batches of trades maybe we'll do arbitrage and

consensus or some other you know sick hacks and then end up with all these clearing prices and now everybody can just like mint their new tokens um and so this is a kind of really interesting model because it's uh it's dealing with the problem of of having um interaction with shared state by basically explicitly segmenting uh the activity into distinct phases where someone is submitting part of a an entry into a batch and then later using the results of the batch computation to prepare their outputs and

as a side effect um you end up with having the chain basically execute every piece of you know functionality whether that's explicitly kind of as a smart contract or you know part of the consensus but effectively every contract instead is just going to execute once per block so you can get some considerable efficiency savings and you end up getting a kind of neat property which is that you have no transaction ordering because everything is just batched together anyway so once a transaction is included in a block the ordering within that block

has no effect on the results of the execution and there's also no visibility into what the transaction does prior to it being processed and so if you think of you know what's going on with mev you're basically saying okay some like block proposer is going to get some like actionable information about the transaction and use that to you know discriminate against it but uh first of all it's not actionable because there's no transaction ordering and second there's no information because there's no transaction visibility and so the the result is that by design you have like effectively no mev so yeah anyway that's the punch line um

i think this is a kind of neat model for how to go forward and happy to have any questions [Applause] um yeah very cool project add a question so if there's no transaction ordering and everything is sort of batched together what kind of impact do you expect it to happen like pricing in in amms for the end user um yeah so uh there's definitely trade-offs with this approach um one is that um

you are kind of uh well okay so i'll separate two two things first is like there's the concept of just like having this type of state model and then there's also what we're going to be doing with penumbra specifically so in general with this class of state model you could still have that type of control so for instance you could say every input is going to set its own custom um uh you know slippage limit or something and as part of this like batch processing you would like sort them all by slippage limit and then you know the ones that were above would just not be processed um

for and so i don't think that there's any inherent kind of issue with this type of like just fully commit to batch processing of everything and not having transaction ordering um for penumbra specifically we want to achieve long-term privacy for individual trades right so unlike a system where it's like okay well we'll encrypt transactions until they're committed and then we'll disclose them right we want to have them be protected also after they're executed and so we basically in in the amm design we sort of pick two different trade-off points on privacy versus fine-grained control over

trade execution and on the market taker side we prioritize privacy but on the market maker side we prioritize the execution control so all of the amm positions are public but anonymous and so the idea is like okay if you if you would really like to have um like really exact control over your execution then you might want to use like a concentrated liquidity position as a limit order or alternatively if you're a um uh want to like stay on the market taker side you could do something like um sharding your execution into like

multiple uh sub transactions you spread out over multiple blocks so you're um uh minimizing the sort of um price uh risk of you know ending up in a batch with some whale or something um i have a question so thanks a lot for the talk um so in this in this particular model what happens if one of the individual transactions that were batched what happens is this transaction is actually invalid and does that open some [Music] room for denial of service attacks um so the the the really cool thing

about building the chain around zk proofs is that you can guarantee that that isn't the case right because um before you batch the uh before before you take this some transaction and include it into the batch that transaction has to have a whole complete set of validity proofs that establish that it is an allowable state transition and so at the point that the chain is aggregating these contributions uh it can already be assured that they are definitely guaranteed to be correct um but that is actually a big issue and it's one of the

the sort of finer points of like what is like this concept of flow encryption one of the additional properties that you end up needing um that's beyond just like additively homomorphic threshold encryption is you need to have a strong kind of end-to-end verifiability that like all of the cipher texts were well-formed and that all of the aggregation was done correctly and that none of the validators like you know substituted a different decryption and have this kind of end-to-end integrity of the value flow through the whole system cool thanks should i just throw hey um thanks for talk

i was talking to lydo at one point about encrypted memo pools and they raised an interesting uh concern which was um basically like opening up spam vectors so in in this case uh you have no um ordering within the the block or like the segment that you're um that you're anonymizing but uh one could potentially um just flood the mempool with like microtransactions to like eat up the entire

um segment uh and and and then just have like one large trade in that in that period so uh do you have like mitigations for for this kind of attack i mean their their thesis is like meb just like cannot be eliminated it can only be like pushed into other kind of domains which i thought was like an interesting perspective um so i think it's kind of important to know that we we don't actually have like an encrypted mempool right it's that all of the transactions that are in the mempool uh don't reveal any information and

so at that point you don't have a particular concern about uh at least if i'm understanding the question correctly i don't think that you have a particular concern about uh denial of service attacks that is any different from just like being able to dos a chain by submitting a bunch of like spam transactions right like all of these transactions are going to have to pay a fee um and the the nice thing about um [Music] batching is that if somebody is like adding a bunch of extra transactions like that's just increasing your own privacy so if you're using a zero knowledge

crucial assist are you actually then are you only charging a fee or do you have any sort of gas as well for this um so we're still kind of like refining exactly what the the cost model is going to be like but um uh there there are fees um and what we're probably going to end up doing is having a kind of like lightweight like uh pre so one thing i guess that is is a difference is that when you have a uh a shielded transaction with these sort of pre-finalized like sealed state updates um on the server side to validate that you're not having to do

like execution and so you can just like know exactly what the cost is uh up front and so we're probably going to end up with a fee model where you know if you add like if your transaction is bigger and it does more expensive stuff it has more proofs in it like your required fee will probably end up being higher to like account for that cost but a lot of the complex resource use problems that come from having this like on-chain execution actually go away in a shielded model because the actual state transitions are happening off-chain and what we're left with is and on the so just to rewind to this

kind of batch processing diagram another thing that's very cool about only executing each piece of functionality once per block is that you get to amortize the cost of that execution over every single transaction and so depending on which way you go right either that could be much cheaper or you could say for the same amount of cost we could do like much more like uh computationally intensive uh processing and do cooler things uh as part of the app logic thank you very much thank you henry all right

[Applause]