ZK HACK mini - Introduction to Miden VM
2 Mar 2022 · 45:25
Bobbin Threadbare explains how zero-knowledge virtual machines let developers prove arbitrary programs without designing a custom AIR (algebraic intermediate representation) for each computation. He argues that they also give one reviewable constraint set, a natural fit for STARKs and a route to recursion. A toy stack VM with four instructions shows how execution traces, operation flags and transition constraints encode instruction logic. Miden VM, built on Winterfell, is a stack machine whose programs form a Merkleized abstract syntax tree, so calls are hash-addressed and unexecuted branches can stay hidden. Its next version, still in development, moves to a 64-bit field and adds read-write, word-addressable memory. The roadmap targets Solidity as a first-class language, and a short Fibonacci program in Miden assembly closes the session.
Speakers
Topics
Transcript
yeah thank you on again welcome back everyone um so um maybe like uh in the first session i should have given a bit of an interaction myself but basically i am the author of winterfell uh or it was one of the authors and might in the vm is something that is built on top of winterfell and i'll explain the reason for doing that but it is a part of this polygon modem project which is the zk roll up uh starting bck roll up so uh and what we want to do is build a general purpose zk roll up you know using stocks as an underlying proven technology and we're using winterfell and minded vm as uh kind of the building blocks to
achieve that so um the things that i would like to cover um see during this talk is just do a quick introduction to zkbms and explain you know what they are why do we even care about them and some design considerations that we think about when we uh you know build this type of vm so then go through a very simple toy example of uh like a uh what it would take to build a ckv i'm gonna in a stark context and then uh give a bit of a very short deep dive on the uh architecture of might and vm and then show how we could code let's say financial sequence in magnum vm
or how we would prove execution of a blast sequence in my vm all right let's jump in um so the way to think about the geometry virtual machine and this is by no means kind of the only way to do it there i'm sure there are other ways to describe it but the way at least i think about this if we think about this function that i showed at the very beginning of the last uh session where uh we have a function we have public inputs we have uh eyewitness and we have the output in the context of the of a zero knowledge virtual machine this function is actually uh instruction execution logic of the virtual machine so basically something that executes instructions um public inputs in at least in this
description definition could be like a commitment to the program so it's on the program itself but it's a commitment to the program uh it's a commitment of two initial state of the virtual machine and also as the public inputs that go into uh computations in terms for the witness itself we can actually provide the program as a as a witness so as a secret input we can also provide initial state of machine as a secret input and we could also have some secret inputs if we needed to uh and like you know have let's say signatures that don't need to be shared as an a fire um and then the output of the vm is the final state or actually a commitment to the final state of the
and to illustrate this in in another way so let's say this is our zero knowledge virtual machine um we take a commitment to the initial state and the program um this is provided as public we have things provided as uh as a witness or kind of private inputs the program itself the initial state the actual initial state and the secret uh set of inputs this gets expanded into kind of the actual like they did these get compared to uh the commitments uh that were provided from here and then the output is the final state commitment as well as the proof that the program was executed correctly so the
verifier actually to verify this transition the execution of this program uh really just needs to know the commitment to the program commitment to initial state uh commitment to the final state and the proof itself so the the the verifying theory doesn't even need to know what the program was or what the initial state was or you know any other secret inputs that went into it and this opens up a lot of like interesting opportunities for some like privacy preserving applications um so why do we care about this uh zero knowledge virtual machines so one thing and probably one of the main things is ease of use so in the previous session i described how
you would uh like uh you know how to use winterfell and describe how many things that winterfell takes care of for you like the low degree extension and you know constrained evaluation all of that stuff but it is still uh it still requires you to come up with this recipient uh of your problem and uh you know while it is not necessarily like you don't need to like study cryptography for five years to be able to do that it is still non-trivial and a very steep learning curve so like while winterfell helps you uh and doesn't require you to be a cryptographer to use it it is still far from ideal in my mind from actually like a a developer without uh prior
context being able to pick it up and use it because you need to think about these columns polynomials there's still a lot to learn so with the virtual machine ideally we can avoid all of that so you don't need to know even anything about gkps to do that you don't need to even understand what the optimization is the other i think is very attractive properties i mean for the lack of a better word is reliability i guess here basically what this means is that you can design your error only once and then you can use the same air to generate proofs for any other computation you don't need to design air multiple times this helps in the number of ways the this single error could be added it does
it you know many people can look at it understand it it could get much more review uh in a blockchain context you only need to write one smart contract that verifies uh this specific error while like if you uh whether it was the other approach you might have to write multiple small smart contracts each one for each air and things like that so in this case uh it is uh you know it simplifies things from uh from the standpoint of uh kind of uh usability and being convinced that what you're doing what you're using is actually has been reviewed and is reliable the other thing is especially in the start context a virtual machine is a very attractive way to address this composibility problem that i talked
about before if you think about what a virtual machine is it has a small transition function or relatively small transition function that gets repeated in millions and you know potential millions of times anytime you kind of execute a cycle in the virtual machine you're executing the same exact transition function so it is very suitable for stark which is this uniform computation so basically you're describing a uniform computation and can be applied you know practically a different number of times uh so in the context of start uh virtual machine sets especially attractive and then last thing is that you can use virtual machines to have basically infinite uh recursive parts all you need to do is like if you have a virtual
machine uh uh you which is powerful enough and in entering complete virtual machine will be powerful enough to uh to write a code that can verify um a stark proof of its own execution uh you basically get instant recursion with starks so it is not the only way to get recursion restarts but it is one of the potentially simpler ones so this is the main reasons why we care about virtual machines uh or especially in the star context with i mean this uh this i kind of list the benefits there are potential downsides here uh for example you may argue that by hand you might be able to build
better error than in that specif you know tailored to a specific task and in some cases that could be true for simple computations you can probably build air more efficiently because you don't have the overhead of the virtual machine running on top of it but uh as soon as you try to get more sophisticated and write complicated programs uh writing here by air by hand becomes extremely challenging and doing so reliable it becomes doubly challenging uh making sure that you didn't introduce any bugs and so forth so uh i would say for simple things yes maybe doing it by hand is an option but for uh complicated programs especially when uh a lot is at stake i think a much better approach would be to use a virtual
machine that has you know has had many people validate and verify its air and things like that all right um let's talk about design considerations of virtual machines so now um why this happened again just a second all right so the first thing is which type of the machine there are many things and again i don't mean to make this list exhaustive in any way i'm sure there there's going to be a lot of things uh kind of missing but at least i'm trying to highlight the main points but uh for example for machine type we can have stack machine which is
for example what edm is or you know webassembly also uses a stack-based design it could be a registered machine or which you know most modern cpus are registered machines so it could be memory memory machine which you know is an interesting way to think about it because uh in the context of uh kind of the ck virtual machines memory is fairly cheap so you can potentially just you know operate directly on memory which is not necessarily true in regular cpus the other thing is how do you handle flow control basically loops and if statements and all of that stuff and there are also approaches to different approaches to this so hardware architecture of neumann architecture one of the approaches that i will talk a
bit more is this merkle abstract syntax tree approach which is i think unique to modern vm how do you provide program to the vm so i described it as providing commitment but it's not the only way to do it so you can provide the hush for example which is a commitment or you can provide the program in public memory which is then you basically providing program in the clear you can also do codeword commitments which is slightly different approach and all of this by the way have their pros and cons and different sets of trade-offs and things like that um you know another set of considerations is how do you do function calls like do you allow static or dynamic code targets uh can you write can you have code that can write code
within a virtual machine for example you can you know in terms of memory model what do you do do you have like run right once memory and you have read write memory how do you address that memory is it per byte is it per uh field element or is it something else um and then what native data types do you want to support within the vm can you uh you know at the core level all of all this zero knowledge virtual machines will have a field element as the core data type but what can you do on top of that can you do regular integers for example as the native data of the vm can you use tracks array sets or whatever else um in the vm and then one of the other things to
highlight is uh which field is going to work over is going to be 64 bit 128 bit 256 bit um you know there are different considerations of why you might want to use one versus the other for example the smaller the field the the better performance you'll get but at the same time you know there are trade-offs in terms of like uh can use elliptic curves in small fields for example or uh you know what kind of like if you pick a specific field uh uh what kind of uh you know this what we call a blow up factor has to be for pool generation which affects the proof generation time and you know what uh how how high of a degree of constraints you want to have within your within your vm and so
forth so there is a lot of kind of like considerations uh that are related to when choosing a field and again this is meant to be kind of a high level uh this is not meant as a as a fully exhaustive list but just some set of things that we're thinking about when we're thinking about design of the virtual machine or zero knowledge virtual machine let's do like a very quick uh very simple journal virtual machine example and how that translates into constraints and all of that stuff so let's say we have a toy vm that has only four operations it has this normal operation which doesn't do anything and stack this vm for simplicity here uh you can you know do
push something onto a stack you can add values at the top of the stack where you can multiply them and we assign these op codes here which are conveniently basically just powers of two um so to describe this vm we're going to have to do build its execution trace so again this is not gonna be optimized or anything so i'm just doing it for illustrative purposes so let's say we have a single column that is gonna hold uh the op code we call it c we're gonna have operation flags uh basically a set of columns that uh take on the values of you know uh one if a given operation is executed and zero if not so like if all of these are zeros then we actually know if this one is one then we execute a push if this
one is one we execute the end and if this one is one way to move operation we're gonna have a few columns that will describe our stock so in our case the stock is going to be fixed it was just uh you know at most depth four so as you execute things you'll push things onto the stack and do operations there but we have these four columns to describe the stack and then we'll have something called this instruction sponge as you execute the creations they get absorbed into the sponge and then at the end of the trace you'll you know if you've absorbed a set of instructions you will get the program that you are expecting that to execute so basically this commits or binds uh kind of opcodes that get executed on the vm to the instruction that to the
program that we think we're executing all right um so with this basic design let's see how we would perform some operations so again these are our columns so let's say we want to we start in the initial state which is basically all zeros nothing is the vm is in a clean state we want to execute a push operation so here push means uh um we've set this flag to true which means this the output is one set the slot to true we'll put uh the actual instruction and the immediate value into this instruction sponge i kind of uh put this here as like some it will be set to some values but which values uh you know we
don't know it depends on the hash function that we you're gonna use so for illustrative purposes they just use dashes to put in there but think about this part is containing kind of the rest of the hash of the accumulated program and again in reality it's going to work slightly differently from this but this is for simplify the example i think this works and then i'm going to do another push so again another push now we have you know you notice that we push three onto the stack now we have five and three on the stack and then we're gonna do an add so notice that uh the uh the output is now two now this flag is set to true we've computed an end and now we have uh you know a different so like our immediate value was set to nothing
because n doesn't take an immediate value and our instruction uh kind of like that got absorbed into the sponges too all right so this is kind of like a very simple execution trace if you think back to the previous session uh it's exactly as we were doing with other like we have we're recording a state of the computation at a given point in time and in this case the state of the computation is the state of the virtual machine um now what are the constraints that we want to impose against this execution trace so let's think about back again as a in the setting of we have a current row in the next row in this execution trace and i'm going to mark the next values with primes so c and c
prime so c is the current uh val value in the current row in the given column and c prime is the next value in the same column uh so again this is not going to comprehensive just like a few constraints that we would want to impose on this execution trace um so the first one a constraint that says that you know we only want to have ones and zeros in this uh in this columns and this this constraint basically says that for any i from 0 to 2 we would have we need to make sure that this expression holds like this is the constraint there's actually three separate constraints because we have three values for i but you know this would hold only if the values in those
cells either are either one or zero it would not hold for any other value the next constraint we want to do is that we want to make sure that whatever is in this f columns is equal to whatever is in the c column so it's fairly simple it's uh because we've chosen this powers of two you know c minus this expression must always be zero and this expression is just you know value from here value from here plus value from here times two plus value from here times four the next constraint that we might want to impose is that only one value is at set at a time so we don't want to have a
situation where for the flag i mean where we have multiple flags set to one because in this model very simplistic model we have we allow like we have a flag per operation and this constraint basically specifies that it's a bit complicated little formula but basically if you run if i didn't make a mistake and if you run the numbers you'll see that it's impossible to have more than one one value set to one here and then one other constraint and again not exhaustive there is many more constraints that we care about but uh one other constraint to illustrate how we will execute the creations is that again it looks more complicated but actually there are different components to it so
uh what this says is the next value in this radius in this cell should be equal you know to whatever was previously computed based on whatever the flags are set so for example if so s zero prime uh you know minus if we are executing push operation it would be f zero prime times h1 so h1 was the immediate value that we put in there this would evaluate to zero uh if uh uh if the transition was correct and we are doing a push uh if we are doing an add operation uh then this flag would be set to one and then this would evaluate potentially to a non-zero value so this would have
to hold true as 0 plus s1 so these two together should equal sum that together should equal to this and same for multiplication and for norm so basically this describes the transition function for uh for different operations and we kind of just combine them together because we have this flags that are mutually exclusive um this is not the only way to do it but this is fairly straightforward and again there's a bunch of other constraints that i'm not like there are constraints on the rest of the stack there are constraints on uh how you compute the operations tangent the spine instruction stage and all of that so uh this is meant to be kind of like a very high level uh overview of how you would build a virtual machine but you know
uh it is taking this uh and building a full-blown virtual machine uh is uh you know more complicated from a gx point of view but conceptually it's not super complicated there is one thing that we didn't mention here is like how do you use like build random access memory and that requires another kind of like set of tricks which you have to do with permutation arguments but uh these are not yet supported in winterfell by the way uh something we will need to support uh to build like a more robust virtual machines and the next version of mining vm will require those all right so let's talk about mining vm architecture uh so at the high level like going back to those choices that uh or uh
consideration that i i listed uh earlier we have a few kind of like this design choices that we made with might and dm specifically the next version of my mdm is going to be in this 64-bit field it's very performant field it has a number of attractive properties you can you know modular reductions are cheap you can kind of like emulate 32-bit uh unsigned integer operations fairly cheaply in this field so it has a lot of good properties of the current version but the one that you will see on github right now in the main range uh is still using a 128 bit field but the one that isn't being developed in the next branch for my vm uh is already
been switched to the 64-bit field um we're using um for machine type where we decided to go with a stock machine and there are again a number of different considerations why you might want to use a different architecture but for our purposes at least the kind of initial thinking is that stock machine will provide uh kind of best trade-off between performance and simplicity um we'll see if it turns out to be correct uh assumption because there are definitely other approaches to do to doing this um flow control is accomplished using this mask-based execution and i'll cover this uh in a bit more detail in the next slide uh but this is something that is fairly unique to
my nvm um most other vms that i'm aware of are you know either using like a harvard openneumann architecture to do flow control program inputs and this is related to this mass based kind of representation of programs it's basically a root of them program kind of moralized abstract syntax tree and again i'll cover it in shortly and this also uh kind of like flows into like how to build function calls so in our case well in usual architectures you do function calls by like you know start executing instructions from a new place in memory or something like that uh basically you you move the instruction pointer to the beginning of the code that describes the
function in our case uh functions are hash addressable so there's a cache of the function that you invoke and make and then that gets executed and that also requires that all uh function calls uh like call targets are known at the static time because you can only call something that you know hash off you can call some a function for which you don't know what the code will do this is an attractive property in my mind in the blockchain context where you want to have as much uh kind of deterministic behavior and like limited dynamic behavior as much as possible to avoid bugs and things like that um for my vm the memory model is read write memory so you can both read and write from memory and it is word addressable
meaning you know you can aborted our context is a set of four field elements so you read and write four field elements at the time or you can if you interpret those field elements of 32-bit integers it could be you basically write four 32-bit integers in a single operation and there are reasons for why we chose this i think first of all choosing read write versus like write one's memory uh makes sense because it simplifies a programming model and word addressable memory you know in the context that we care about i think or the use cases at least that i foresee the vm being used for uh i think frequently we need to write in batches and that actually makes performance you know increase the performance of the vm
um and then native data types uh we as i mentioned we have field elements but we also at this point in time also have regular 32-bit unsigned integers which you can use and we will uh kind of problem you know down the road add some additional data types but at this point in time it is field elements and 32-bit unsigned integers is the coordinate effects the other coordinate types of the idea all right um so at the very i know this is like a complicated chart and i'm not going to go into full detail of this but this kind of describes that architecture of this the next version of the vm that is being developed right now um the the trace itself is you know i
showed in the toy example we have just maybe like a 10 columns or so the trace for the vm itself is probably going to be closer to like somewhere 80 90 maybe 100 columns depending on you know what optimization we want to do and uh what functionality we want to support and there are different parts of the vm so there is like a just you know two system columns for example to keep track of like a system clock and some memory pointers and then um there is the decoders like the set of trace that is allocated to decoding instructions and computing this you know program uh absorbing instructions into the sponge and basically computing this hash of the program as we execute this there is a set of 19 columns that is used to
represent the stack and we actually can represent stack of unlimited depth using this 19 columns uh anything like that so there is like a set of columns that are dedicated to doing efficient 16-bit range checks um because those checks are used uh in many places in the vm and then there is a bunch of uh other kind of segments that i use what we call uh co-processors where you know we upload some hashing operations to compressor we upload float bitwise operations to co-processors actually all the random access memory is being managed here and so forth and we might be adding additional core processors to this um as we need you know as needed if we need to add additional functionality to the vm um the other thing i wanted to mention is
that i didn't really address addresses this is i call this virtual tables but this is basically a permutation argument that allow us to use like this uh kind of things that are used in plonk as well for linking different parts of the trace together so uh they these techniques actually improve compressibility quite a bit so if you have access to those permutation arguments some of the pains of doing composable air goes away not all of the pains but some of the pains do go away and in our case we will be using them to kind of like you know we have this independent columns we need to link them together in different ways and this is what this virtual tables are going to be used for um all right
so let me talk a little bit more about this mass based execution uh and what i mean by this so traditionally like we think of programs as just sequence of instructions and then you have an instruction pointer that jumps into uh you know a given point in the program and then starts executing from there um and uh in our case we we approach it differently so in our case uh we think of a program as a abstract syntax tree and executing a program is basically traversing a path through that tree so let's say there is some program that looks like this uh right so we have some instructions that get executed so this is a linear sequence of instructions and you have an if else statement in this case like if uh
true means that if the value on top of the stack is true then you execute this branch if the value on top of the stack is false you execute this range and then inside we have some sequence of instructions again and then you have some loop in there so this will basically execute while the top value on the stack is true and then you know you execute loop in this loop or uh and then execute this instructions and then uh you execute this f one through f1 instructions um the way this gets translated is uh you know and i'm not gonna go into super uh deep detail on this but uh um you know this is kind of the abstract syntax representation of uh this program where we have what we call different nodes uh uh or we call them program
blocks in the tree so for example the join block is something that means that you execute the left side and and then the right side but a split block it means you only execute either one of the branches depending on what the condition on top of the stack is and then the loop block it just executes whatever is inside of it uh for um until the top of the stack becomes uh false uh so you know this program can be represented as this abstract uh syntax miracle tree yeah abstract syntax tree but we also make it a merkle tree so we actually can hash each of these blocks and in the end you in the entire program can be represented by single hash that is the root of the program and then as you executed like as i
mentioned the decoder uh you you will notice that here a fairly large part of the trace is devoted to the decoder actually builds this abstract syntax tree as the program gets executed um and uh for example if you know it starts at the uh at the top and the uh and figures out that well this is a joint block so i need to start executing the left branch so this is a another joint block so i need to start executing this so it executes the a zero through ai instructions and then it sees that this is a split block uh you know starts executing the split block but then it realizes it needs to first execute uh check the condition of the top of the stack so if condition is let's say true then it will execute uh
just this instructions and then go back up the tree but if the condition falls it will start executing this subtree and so forth so uh this um this is a very i should say unusual mode of executing things in the vm and there are a couple of reasons why we decided to use this uh one of the reasons as i mentioned that you get for free this static function calls like if you have a function call somewhere you have to provide a hash of that function and you know exactly which sequence of instructions you're going to be executing uh as part of the of that function so there is no kind of undefined behavior in that context where you know you know you don't have self-modifying code you have you don't have dynamically kind of
like chosen code targets and things like that that simplifies the formal analysis and like you find that the programs are correct and all of that stuff uh the other approach in this context is that uh it's easier to achieve a kind of privacy especially code privacy in the context of blockchains for example if you think about like a contract as a commitment to a to a program you only first of all you only have to reveal the the path that was taken during the execution if you want to reveal something so like if uh we build up this hash as we execute uh the program but if this branch was never executed the hash of this branch is provided non-deterministically
so you don't actually need to reveal what happens in this branch if you want to execute only this range the other benefits that you get is that you can take this it's very easy to compose this with other programs and like hide some aspects so like for example if i wanted to have some preconditions and post conditions to this program i could like have build another tree on top of this and i would say i'm gonna hide this program entirely i'm gonna reveal what the preconditions were now what post conditions were programs that executed before and after uh but i will not uh provide the actual code of the program and the daily fire whoever needs to verify execution of this program can still say well yes i know a program with this hash was
executed between these two programs but i don't know what the actual program in between was and this could be useful for example think about a smart contract where you want to ensure some invariance you want to make sure that no new coins have been created so you would you know count the number of points in the contract in uh before and then count them uh after and you will compare that before is equal to after but how they moved uh in between is uh completely hidden from queer one is to verify that you know the everything was done correctly um all right a few highlights about might and beyond specifically so i talked about a little bit about some of this already but
um what we want to do is make the vm super develop developer friendly that means we don't need to know anything about cryptography or even like uh finite fields or anything of that sort so it's a regular stack based machine it has 32-bit integers as a base data type that you can use you don't need to even understand what field the final fields are it has read write memory uh doesn't have that native exception handling yet but we'll have a native exception handling and we're building kind of an expensive standard library with no traditional hash functions that like blake 3 and chat 256 will be in there um you know elliptic signature verifications and things like that so we're working on and obviously the support like uh
and i'll get into this in a few seconds but to support solidity for example we will also have like 256 bit in pictures and and all of that other stuff um we don't foresee people will program a lot using modern assembly specifically or like the core language of the vm but we do want to provide multi-language support so our goal is to have solidity as is the first class language in the vm but we also want to make sure that other languages can work in the vm as well a few of the interesting ones that i listed here is move that was developed by facebook novi and then sway is something that fuel labs is working on so those are pretty interesting languages and we hope we'll be able to support them as well our kind
of philosophy on this is that we want people to code in whichever languages that they're comfortable with and want to make sure that they compile get compiled efficiently to widen vm um as i mentioned we have this very safety centric design [Music] kind of philosophy where we don't want to have we want to be touring complete but at the same time not the expense of some safety so the vm is going to be true incomplete but it's not going to allow some of the things that are in my mind are fairly dangerous to do especially in the blockchain world where you know you don't want to have dynamic call targets for example you don't have you don't want a code that can write like self-modifying code and things like that and you know all operations in the vm
are safe by default uh and then as i mentioned because of this uh mass-based approach to uh to program execution i think there is a fairly good path that we have to supporting both transaction privacy but also privacy preserving smart contracts all right a little bit more about the uh the actual uh multi-language support that i mentioned so as i mentioned solidity is something that we want to support as a primary uh programming language and the way we will do it is through compilation to you uh and then we actually already have uh a separate project that uh there are people who are building ultim
might and transpiler and doing awesome job with that um and then uh mine assembly is the native language of the vm and that's what the vm can execute uh and as i mentioned we do want to support other languages so every the model is that other languages will be compiled to modern assembly as well um i wanted to share some performance goals that we have for the vm and again this one's more preliminary so take them with kind of like this aspirational goals hopefully we can get there but maybe it's not going to happen immediately so we have um on the single core uh 25 kilohertz right now the current version of my of mighty mdm the 3.1 can do about 10 kilohertz on a single core but with
some of the improvements uh we can get to uh 25 kilohertz and then as i mentioned this scales fairly well and hopefully with like gpu and fpga acceleration we can get to some number of megahertz uh and this is again cycles per second and some of the ways to get there first of all we're using winterfell as a back-end which is uh you know very performant and up-to-date star protocol implementation uh we're using this goldilocks field and that same field that is being used by polygon zero at this point in time uh which is very fast modularity that has very fast visual reductions and you can you know has quite a few other attractive properties and also we will be using this randomized there was pre-processing to like do this for example range checks
efficiently and uh there you should be decorations and so forth um so i talked a lot about where we want to get but here is like where we are now so v01 is uh available on github now it's fully working the group generation all of that is working it has basic stack manipulation basic operations and control flow implemented uh v02 is very actively being worked on then should be available maybe in the next five six weeks i mean some in some you know plus minus a week or two um and this will have random access memory will have native support for 32-bit integers we'll have procedures which is kind of like functions um and then we plan to kind of keep working
on it for add storage uh and modules like modules would be kind of like smart contracts function calls which is basically cross contract calls and then more cryptographic primitives that are useful in the blockchain context and then finally you know get to a point where you can take solidity and compile it into my vm hopefully you know uh sooner than this but at the very least by that time and i'll skip this part let's do a very quick fibonacci example we didn't get to do like the actual fibonacci example of how you write air for fibonacci in the last session because we run out of time a little bit uh but just to show how to do this in
this in my nvm so let's say we wanted to compute the millionth term of fibonacci sequence in modern assembly this would look something like this there isn't really it's basically like a 10-line program that allows you to do this you don't need to understand anything about polynomials or air or finite fields you just can write a typical program that uses like push and swap operations and this is the program that um you know you can write in my nvme right now um and uh you know obviously you do need to understand might and assembly but hopefully this is a much uh much less of a steep learning curve as
compared to like figuring out what air is and how to write algebraic uh formulas for describing a given computation and uh even now like if you wanted to uh this is like a u representation that can get compiled into uh modern assembly code so that you could do this using you as well you is an intermediate representation so you probably wouldn't want to write it just like that but in theory like if you wrote that consolidated it would get compiled to something like this and you and then in you would be able to uh you know this would this you would actually compile into something similar to this assembly code here um all right
i think that covers the content that uh i've had i probably went fairly quickly through this uh so let me see if there are any questions right uh question from willie is there a read write is the read write memory a problem for the parallelism of might and vm um doesn't julienne this comment as a problem for parallelism i don't think i mean execution within the vm itself is always single threaded there is no kind of multithreaded execution within the vm the proof generation is multi-threaded so you can generate proven parallel but the vm itself executes operations uh sequentially uh now if we had to
work with uh let's say uh you know if we wanted to have like a multiple transactions as an example and verify them uh concurrently that really depends on like the uh architectural underlying like ledger for example does can you do parallel execution of transactions in the given in a given context and if you can then you know maybe we can do parallel execution of those within the vm as well um and uh uh for example in that case actually what could make more sense is like recursive approach where you would uh verify independent transactions recursively and then aggregate them into a single proof but you may still kind of like a single
transaction will still be executed sequentially um next question how much uh cryptography one needs to know in order to work with starks so depends on what you mean by work with starts for example if you use my vm you don't need to know any cryptography if you use uh or at least you know you need to understand what the hash function is but probably you don't need to be very deeply knowledgeable about it um if you use winterfell there is a bit more cryptography that you then you need to uh understand it's not cryptography per se because really what you need to understand is the characterization concept
but if you wanted to build a uh let's say a stack protocol from scratch then yes you need to understand quite a bit of cryptography and uh i mean it's not necessarily cryptography again per se because this is the hash function being used but you do need to understand the protocol and all the security tradeoffs and all that stuff and that is fairly complicated [Music] there's a question is maiden simply polygon's implementation of winterfell or should we consider it between the next generation of winterfell uh no to both uh uh might and vm uses winterfell as dependency as a coover so minden you can think about this as uh the vm itself has a set of air that is
described uh uh kind of describes the execution of the vm and then we use winterfell as the proving system that proves that this air was uh you know to generate troops using this air so uh you can think about like with build uh vdf and top of winterfell mine and vm is kind of another thing that you can build on top of winterfell but you could it is not replacing winterfell and it is also uh kind of not next generation you still need both uh it's kind of like a separation you know one is concerned about the actual vm and the logic of the vm execution how you describe it in there the other one is concerned of how do you take air and generate our proofs given the error description
let's see will this particular example be available um this part i'm assuming it is we're talking about what i have on the screen right now uh there is a there are a bunch of examples in the current maidan repo i don't think this specific example is there but there is a code for fibonacci sequence which i think is fairly close to this one uh there is a code for some other things in there as well and you know if you want to look at the new version of midan vm that is being worked in the new branch or next branch uh they're actually uh code there's like a standard library of functions already there which has as simple things as like how do you do a
64-bit multiplication or addition uh to something as complication complicated as how do you do you do like a blank free hash function which is you know you know a thousand lines of assembly code for example um let's see i don't know if you've reached the end of the questions we're a little bit over time actually so we might need to wrap up we have to announce the puzzles and i know that some people are just arriving ready for this too so yeah um i'm happy to um take some questions uh at a different time or like i think there's discord and i can answer those maybe there at some
point exactly actually yeah if folks aren't already in the discord channel there's a workshop sort of sub thread we'll talk more about all of this stuff and we'll be posting videos there as well um so yeah yeah yeah sorry if i didn't get to to answer uh some questions but hopefully i can do it in a different medium very cool thanks so much bobbin for the talk on maiden vm yeah definitely was my pleasure and if you guys are interested like we are looking for contributors so if you are passionate about zero knowledge stuff and virtual machines and things like that drop me a line nice