zkSummit: ZkVM: fast confidential smart contracts powered by a motocrab - Oleg Andreev (Stellar)
13 May 2020 · 43:18
Oleg Andreev of Stellar presents ZkVM at zkSummit, a virtual machine design for fast, confidential smart contracts built around a construct he calls the motocrab. The talk digs into how zero-knowledge proofs can keep smart contract execution both private and verifiable without sacrificing performance.
Speakers
Topics
Transcript
I was not sure about my internet connection so I pre-recorded the talk it's pretty short it's an overview of Zika VM that I was designing for the past several months months and the idea is here is to give you this short overview and then answer the questions and so the talk is shorter then maybe the most interesting part is the questions about cryptography vm parts performance whatever whatever is interesting to people so was get it started we'll talk about making confidential smart contracts with speed
and style so our goal is to make something like a blocking with TLS you can use public infrastructures or some money between private actors most basic confidential ledger will have some sort of encryption for balances and transmitted amounts and would require the use of zero knowledge proof to prove to the network that transactions do not inflate money supply but since the blockchain is a decentralized consensus system it is hard to update to any new feature that you makes think about in the future so we need to permit some amount of program abilities so that users can build the features they need on top of it so to implement such ledger we define a new transaction format zkd M it sits on top of the peer-to-peer
network and some consensus protocol and other things like payment channels or books arbitral contracts they are all implemented using instructions of DBM on top of it the best way to think of the KVM is like a fancy parser most systems define transactions as hierarchical data structures like XML aetherium is programmable but the programs are stored and executed at the level of a global state machine and the transaction is more like a single signed procedure call so zucchini M transactions fully describe their effects but using an imperative programming language sort of like a PDF this allows expressing value flow and composing conditions in a
more natural way so let's see how it works in the KVM each transaction is a that moves assets from inputs to outputs for those familiar with Bitcoin this is very similar to Bitcoin transactions structure unlike Bitcoin you can also issue arbitrary assets and not just transfer a single built an asset the assets travel from one output to another now how do we authorize those changes in the KDM each output is an object called a contract which is frozen in the blockchain state access control is done through contracts contracts contain a list of items that could be assets or arbitrary data parameters these items are protected by something that we call predicate the predicate can be satisfied
by a signature in which case items has simply unlocked and placed on the vm stack alternatively a predicate can commit to a complex program user may choose to reveal a branch of the program and VM will execute it in such cases sub program gets a chance to do something with its items for instance check conditions create constraints locks some of the amounts and create new ones remaining items are left on the stack for the outer program to use to implement predicates we use a variant of a taproot scheme designed by Gregor Maxwell and Peter ruling the big idea behind the scheme is that multi-party contracts are resolved either through cooperation or dispute in a happy case when all parties cooperate they simply sign for an aggregated public key making
this spend indistinguishable from a simple transfer but if one of the parties is offline or does not cooperate the counterparty can reveal the pre committed branch and permits them to unlock the contract the predicate also allows choosing a program later sort of to implement a dynamic linking pattern so instead of using it to sign a specific transaction you can instead sign a program that will be executed by the VM within such sign you can directly perform not only checks but also asset transfers so you would effectively be signing a partial transaction without awkward and limited hashing models this is quite simple but very powerful model that allows us to build a lot of useful protocols on top of the akkadian now
let's put together transaction contracts and predicates the transaction does not literally contain inputs and apples instead the transaction is a program that performs instructions that destroying create contracts via input and output instructions the transaction also contains an aggregated cryptographic proof for all operations performed on encrypted data the verifier instantiates a vm for verifying a single transaction it is a simple stack based machine with just a stack in your persistent storage VM is discarded after transaction execution has finished each instruction works with high-level concepts values constraints and it provides both the functionality to the user and also
enforces the network rules like making sure that assets are not counterfeited instructions produce two kinds of effects the first is the constraint system it is built on the fly by the executed instructions constraint system reflects both the network enforced rules and additional custom rules coming out of the contracts when execution finishes the entire set of constraints is verified using single zero knowledge proof using the bullet proofs protocol another effect of transactions is deleting existing outputs and creating new one in the you take soul set during execution VM does not change the UT cassette instead all updates to the blocking state are recorded in the
transaction log which is applied later if executions succeeded this allows me refine all transactions in parallel and applying changes very efficiently in a batch so this has been a little bit abstract so how does the program actually look like so here's a complete set of instructions in C KVM these are broken into categories the ones that manipulate items on the stack others express arithmetic and boolean constraints the group of instructions that issue and move values around and the instructions to interact with contracts let's see a quick example of custom constraints let's say we want to enforce that a payment to some address matches some formula we start by pushing
a Pedersen commitment to a secret payment amount and alongside with commitments for parameters such as time and price then the VAR instruction allocates variables and the bullet constraint system you can create a rhetoric expressions with these secret variables with addition multiplication and then you can form the boolean statements and compose them with operations such as eke and an oar and finally the complete constraint object is added to the constraint system via verify that arithmetics all the constraints and encodes them in the bullet proofs format if you take a closer look then you have a formula something like that where you say that B must equal sum or isn't a formula or some other condition must be valid in
the Z KVM it looks like this stack machine a pretty straightforward instruction code after you verified were added the constraints for the variable for the commitment that you have you can use it to make the payment imperatively to do that we use a bore instruction that produces a pair of passes a positive and a negative value the positive one is locked in a new contract or address the negative one is simply left on the stack that the KVM forbids from simply destroying the author of the transaction must combine this negative value with the corresponding positive one using the cloak instruction that merges and splits any number of values in a transaction and also makes sure
that the values are not counter faded or transmute it incorrectly so this is a very important feature of the akkadian the contracts can directly express their requirements as an imperative program with linear logic eliminating the entire class of security vulnerabilities like confused deputy so we'll see a few examples of how do you build protocols on top of the KVM let's start with a payment protocol the basic payment protocol is implemented as such your account is represented by a public key as usual but that key is no longer directly visible in the network instead it's uniquely blind at each time you receive a payment this is very familiar to anyone who uses Bitcoin to receive a payment you generate a receiver a
special container that describes the unique destination for the funds it contains the unique blinded address and also the blinding factors for the asset type and quantity the sender will encrypt the asset with these keys the does not know about accounts but your note does or reward so the automatically combines a collection of distinct transaction outputs into a collection of balances components secure control over funds you can create a multi signature conditions for secure call storage for instance or to implement escrow finally users can cryptographically notarize and verify chains of provenance so the regulated parties for instance can easily get verifiable proofs of source of funds linked to the blockchain data with selective disclosure and
what's interesting is that all of these concepts exist completely off chain so why is it important as Gregory Maxwell said box chain is a court it's a place where settlement and conflict resolution happens it's not a universal computer so the private data is not exposed you have less load on the network it's easier to program and less complexity in the consensus critical layer so you can improve software without upgrading the whole network so now let's take a look at the order book example water book is a subset of unspent outputs that permit full or partial lifts of the asset provided corresponding payment the contracts can verify the payment and
unlock the offered asset and the matching is performed off chain at the network layer how does it look like a contract contains three items an asset that we sell a price in the payment address in the simplest case the contract has just one clause lift which does three things first it receives the payment so it ensures that provided quantity of the payment asset is delivered to the address second we compute the reminder of the asset that we need to log back into the same instance of the contract in case it was a partial lift and finally the requested amount of the asset is simply unlocked in the transaction so the author of the transaction can decide where to put it
finally let's take a look at how payment channels look like payment channel is a two-party state machine that allows rapid balanced updates without publishing the intermediate transactions the message that they sign effectively security guarantees what both parties are done they sign the final payout is the actual transaction and publish it so all the intermediate transactions are simply not visible in the network but if parties do not cooperate and one of them decides to exit the channel it publishes the most recent security guarantee since the blockchain does not know whether it is the actual latest version the contract has a timeout provision the counterparty can detect the attempt to exit and if
it's the latest version replace it with a new one finally when there is no new version of the signed payouts and the timeout is over the payers can be from finalizing the personal addresses of each party 7zk DM the only state is the set of unspent outputs or contracts so we model the state machine using them first each state is represented by an instance of a contract and each transition is a separate Akkadian transaction that destroys one contract and creates new one the contracts can store not only assets but arbitrary parameters and have a flexible support for sign messages so modeling such state machines is very straightforward let's compare the KVM to a couple of
other designs since he gave him as a smart contract engine it is only natural to compare it to aetherium first so when people hear smart contracts they are used the e theory model that the blockchain is a global decentralized computer and you can ran your custom applications on top of it the Akkadian takes a different approach blockchain is only used for settlement and enforcement of rules but not for the storage and processing of users data this means that in the KVM most data is normally off chain in the remaining data necessary for contract clarification is kept confidential Gideon is deliberately not tearing complete this makes behavior of the contracts much more predictable and allows making the consensus critical parts of the protocol simpler and more robust the complexity of the contract
logic is pushed to the end-users contract since Akkadian is strongly isolated from each other transactions do not use global state finally issued asus NZ KDM of first-class types that can be many related directly and sent from one contract into another in aetherium a system modeled as entries in a miniature ledger is stored inside the blockchain state this means that your smart contract has to reinvent the ledger rules against double spending while the kayvyun enforces them automatically let's compare see finally let's compare the KVM with Z cash and Manero too cryptic coins aimed at confidentiality Z cash and Manero are designed very differently but I would like to show how their common features compared to the
KVM so first smart contracts in the KB I'm a part of the confidentiality architecture in Z cash in mineiro contracts are not part of the privacy design for instance in Z cash one can use contracts in a Bitcoin style fully public and traceable transaction and switch back and forth between clear text transactions and private transactions the powerful aspect of the cash and Manero is that they provide graph privacy out-of-the-box because it is non interactive with the KVM the best you could do is a coin joint protocol by mixing your payment with others interactively however the big improvement to the graph privacy indication dinero comes with a high cost and scalability zucchini n requires very little storage which remains small as
usage grows while Z cash and manera unfortunately do not scale quite well the amount of data one needs to store and actively use is growing with every single transaction and cannot be easily pruned finally the KVM like stellar is designed for issued assets while tsukishima mara network with a single native asset we have covered a lot so let's summarize the KTM is a blockchain protocol with practical confidentiality solution for real-world requirements it's smart contract architecture is based around lightweight stateless VM where contracts follow the object capabilities pattern in assets or native linear types the cryptography that we need is implemented in purest cleanly and with record-breaking
performance the design is scalable transactions are compact fast to create and verify and the blockchain storage is compressible complexity of the higher order protocol slice of chain removing a necessary load from the nodes and making the core protocol simpler so there is much more to learn the key VM is a part of a slingshot project maintained by stellar Development Foundation you can find complete specifications roadmap documentation and code all in one repository buy this dress and is fully open and we invite you to participate you can also try out the demo app at the KVM - demo and our stellar death org thank you very much and we still have a few minutes left for the questions
hey all right cool let's make you big close the video down do that did you want to continue with a small short presentation now or do you want to do from the QA yeah there was a little part that I missed in the initial recording and was literally to ablate it so I can say a couple of words about the cryptography stack that we have it will take like a minute and some performance considerations and then yeah I'll be happy to take questions so let's share the screen here we go all right so a
couple of words about our stack in the whole thing is based on the curve to 5519 dalek implementation that offers the edwards curve with the very high performance vectorized operations that we have which is the basis for all the performance that we're proud of on top of that there is a ristretto group which implements the correct prime order group because you're not supposed to actually use curve define 19 as is because of the cofactor so for all the fancy protocols out there bulletproof and such you need the promoter group so ristretto gives us
lists and using it we've implemented bulletproof it's also part of the Dalek project and it gives to api's one is for range proofs only and another one is for the the whole constraint system API so this is pretty powerful thing that we have and using that we're going to get it closer to use akkadian project we have to pee one is the cloak protocol which implements the mixing of some number of facets on the input sense into some number of facets on the outputs that does this in serum knowledge meaning that you don't know the distribution of
assets but also make sure that you cannot transmit assets like dollars in two years or create negative amounts so close make sure that the network rules of integrity are maintained while offering you confidentiality in terms of directing the asset flow at the same time we use the same constraint system in both proofs to create custom constraints within the contracts and to do that we use the instructions of the Zika VM to drive this so the cloak is one instruction and all the other instructions allow you to do the custom custom formulas that you use in the contracts finally on top of all of that you can build your own protocol so
you're interacting with this whole stack through instructions of ZK DM and the cool part is that the whole stack is in route is written in the pure rest so everything is compiled very neatly optimized and also every layer is sitting on top of the rust API which is powerful and type and type safe unlike for instance C api's so the whole stack is pretty complex and tall but still it's a very little amount of code and everything's easy to audit and read from bottom to the top and the whole system was designed with performance in mind from the beginning so here's the cool
part the VM has two categories of instructions some are very cheap so it's really just like parsing a transaction but the expensive operations are all uniform it's some elliptic curve operation scalar points multiplications and all of these expensive operations are deferred so the whole system is designed to use this operations only to verify something for instance verify a commitment like top route commitment or verifies no signature or two the bullet proof verification so all of these instructions they're uniform from the perspective of ristretto group and we defer them and verify together in the batch which gives tremendous savings so
is the result what we get is something like less than a 1 millisecond on a 3d rehearse Intel CPU with with the latest if my instructions and the cool part is that this performance is consistent meaning that the range proves that you have to do in the outputs to prove that the numbers are not negative they dominate the performance and all your custom constraints in the contracts they kind of come for free unless you build something super complicated in the custom context so your performance characteristic is pretty predictable no matter whether you use the contracts not really also the transaction signatures are always aggregated so you don't have
a linear number of signatures it's just a single single nor signature for the whole transaction again as I said we have batching and the transaction size is pretty compact so we have roughly one 1/2 kilobytes for the zero knowledge proof which scales logarithmically so even even if you have a giant transaction it will be performing less than 2 kilobytes and for all the commitments for the asset type for the amount I in total for input/output pair in a transaction you would have to spend around 160 bytes so a small transaction with a couple of inputs coupled output would have at all of three 320 bytes for just this data plus the proof and then
if you actually gate transactions in something like Co enjoying then the marginal cost of the proof will go down and only these commitments will dominate which is kind of compared comparable to to the size of Bitcoin transactions and finally Co enjoying is interesting here because it's a rare case where cryptography and privacy preserving protocols are aligned with with performance that you're incentivized to do coin joints because you're also saving in terms of size of the transaction and performance all verification so you don't have to make a trade-off between privacy and speed it's actually faster and cheaper to make transactions that are more
private by using coin sharing so that's a cool property of all the system yeah that's that's basically all I wanted to add to the talk and now I'm looking into the questions like I'm gonna have to bounce out soon to get our next session so we're about 15 minutes late but you should be able to continue here what will happen is I'm gonna start the new session at 6:45 suss in three minutes but anyone if you want to keep answering the questions or if anybody would like to come back into this session Oh like you just stay here and you should actually be play this you should be able to continue on this session as long as you need to but I'm gonna go get ready
with the next presenter sure Thank You Ana also just one thing when you hit when you start answering those questions hits start answering because I believe that then when people come back to this they can actually find out exactly where you answer the question like in the video itself so just click on start answer and then end with stop answering when you finish the oh well where is that but do you see in questions ask a question alright super pal oh my good okay I missed it there are some good questions okay good I'm glad you saw that okay good okay thank you yep okay so so the top question is yeah where did
I click the button okay so what's the rationale for using coin join for graph privacy instead of for another solution well kind of the central consideration was the scalability of the state right so a if you if you raise the link between inputs
and outputs like manera des where it can a does it partially with the ring signatures or z cash where did fully where the full anonymity set of the entire collection of privately committed coins you no longer can use the utak so set meaning the set of unspent outputs because you don't know which ones are unspent so you have to converse the problem you have to remember the spendings so you prevent the double spends right and this scales much worse because there is not yet a good good at cryptographic accumulator to make this
efficient especially in the setting where you know you have you are not proving something to a central server but you have to prove this to like arbitrary third parties so the best that people came up with is a set of nullifiers which is kind of this exactly the same Foreman error and z cache although their approaches are completely different but the common thing is that you have to remember some piece of data to make sure that it it's like uniquely tied to some coin and it's not showed up in the blockchain again so you simply just remember all of them and this set grows linearly and it has pretty bad from the from the caching perspectives pretty bad cache access pattern right
because you need to access the set randomly so effectively there is you cannot say that okay the recently viewed items are more likely to be accessed so will sort them and you know fast expensive memory and everything else goes on a spinning disk so we don't care how how much they take this is not possible because every new key image in Manero or in every new nullifier and easy cache is a random number that could be like anywhere of course you will have some kind of like tree and logarithmic access to it but you have to look arithmetica at access to the random points in this whole state which grows linearly with every transaction while you ticks are said does not grow
linearly it kind of grows linearly with the number of wallets but not the activity of transactions so if you use the unique subset you cannot automatically erase the graph but then you can compress it even further and then make the system much you know better you know scalable because you don't okay okay let's not assume yeah because you don't have to think about the storage costs so in case of the carryin we use the Utrecht so
compression as a built-in protocol rules so the storage is actually a logarithmic in the number of get excels which is great because now you don't have to worry about how much state you're wasting there's no notion of dust outputs nothing like that so you can create as many contracts as you want because it's only you who have to like track their presence so this leaves you with basically only one option to have the coin join to but you can increase your anonymity set during the a transaction to join multiple payments at once but again this is seems like a Nakul approach because it also allows
people to make transactions cheaper by saving on the size of the bullet proofs proof so that's that's my answer on that question so how tightly coupled zkv out to the bulletproof proving system well it's pretty tightly coupled because the constraint system is a part of the VM state so effectively almost like half of the instructions they modified the constraint system right yes so if you say okay I want you know some condition to be verified a zero knowledge then these instructions are operating on objects called
expressions and variables and commitments and they all amount to creating some linear and multiplicative constraints inside there bobrucz constraint system however it's going through the air 1cs api so in principle the whole KDM system can work on some other or 1cs framework if it if we have it later but it must be a system with a trusted set up oh by the way like do people hear me right now thank you
yeah so so on one hand it's not like tied specifically to the bulletproof but to the Erawan CSV API but it needs to be without without a setup because when you verify a transaction it builds the constraint system on the fly and if you need some you know pre-processing or some you know kind of trust a ceremony to do that that would not be possible with the KVM so so far the system that can it can do that is the bulletproof but maybe in the future there will be something possibly better and then it could be kind of swapped out from from under provided you have somewhat similar everyone's ESP a third question is still are going to provide any custody
solutions for users to custody their state I don't quite understand this question whether the seller would provide well I mean in in general whether stellar would provide some you know in infrastructure for users to you know store their valuables I'm probably not in a position to answer this question because I'm not you know working on that kind of infrastructure I'm doing the protocol design so I think it's better to ask this the like evangelist team or or someone who's gonna working specifically on stellar
ecosystem so fourth question is it possible for zucchini in contract to interoperate with another contract and read and write like Syrian yeah so there is some limited ability to do that because the contract can have an executable program embedded in it and it could be either you know statically linked like embedded in the taproot or it could be dynamically linked provided as a signed program tie it to that contract ences so there can a couple ways this could be
exploited you could form the program that claims another contract so it will be can invest it clean so first to clean the outer contract and say look okay this exists I want to take it from the Utica set and then when you show up the branch in the contract is and this being executed can claim some other contract and the contracts they can implement the object capability pattern so you can adjust do whatever you want you have to interact with the contract gonna call into it and then if you satisfies conditions then it will give you some valuable objects can I leave it on the stack for you as a as an outer program that interacts with the contract so you
can kind of compose one contract claiming another one also you could have signed programs that are kinda more flexible can be applied to different instances of the contracts this comes up with a payment channel example where you want to have some signed agreement about you know the new sequence number in this in this payment channel that you can apply to bump the state of your payment channel from wherever it is and you can use a single indicate a.m. you can sign this predicate or this piece of program not tied to unique instance of the
country but tied to some anchor point agreed by by the parties so you can apply the signed predicate to whatever state your payment channel is in so it's going to rephrase this the state of a payment channel some contractor in the Utica set and it can be changed when people contest and try to kind of force close it and those instances are all unique because they are uniquely anchored but if you want to be able to kind of bump down with a signed predicate from any state of those you can tie this or like bind the spread - not the contract identifiers but -
it's tagged so that's why there is instruction called signed tag so this gives you some flexibility in applying the can a partially signed predicate - not this unique concert but to some you know set of contracts so that's another example of interoperability but in general you cannot just really merely access random places and the global state and it can a call from one to another you have to kind of compose the relationship between contracts first in in the transaction and then you will see deterministically what what will be result of it and as long as all the contracts actually exist in the proper state then this whole transaction can
succeed so compared to a theory we kind of know 100% how like whether the transaction will fully succeed with the predictable results or it will be fully rejected so if you're not gonna get stuck in some middle state because you know during the executions the state was not exactly as what you imagined it would be for that matter like stellar has a similar issue as aetherium because transactions can have this like intermediate failure mode where the kind of superficial checks were passed but then you have to do what complicated operations look do lookups in the
database and then something has changed maybe some orders were claimed and now some conditions - no satisfied and your transaction would be in a too expensive to verify - just not accept at all so it's kind of partial except that it's stored in the Box checking the fees are paid what transactions marked is invalid so some effects are not done but some effects such as deduction of the fees from the account those are those have happened so so this kind of situation is not possible with the KVM there's only two states if the transaction is fully deterministic applied or it's thrown away and the last question is how to handle a
situation where there is no other transaction make some coin join when there is only one transaction to process well that's a success that state of affairs where you have one user nobody uses the system so I guess there is a like there's an answer like we don't handle it in any way there's in fact we don't have the facility for coin join at all for for for a moment so it's gonna you know theoretically possible but we you know don't have the you know the world's infrastructure to do coinsurance at all for for now but in general if you don't have any other transaction then you either just wait till there is or the network is not as popular as it
should be so if if the networks are not popular then there's that's a bigger problem than not having someone to mix with the coin join so probably have to work on trying to make it useful and popular first and then hopefully there will be enough bandwidth and enough users to to actually mix with low latency meaning like not waiting for for users to show up for too long yeah so that's all all the questions I got please let me know in a chat or in the Q&A box whether you know there's something else we could talk about otherwise it was a big pleasure to talk
about this year you