ZK HACK - Introducing Circom 2.0 - Iden3

4 Nov 2021 · 2:25:33

Alberto Rubio and Jose M introduce Circom 2.0, a Rust rewrite of the zero-knowledge circuit compiler that Rubio says improves compilation speed, type checking and security. Rubio explains R1CS constraints, the programmer's responsibility to ensure a computed witness is their only solution, public inputs on the main component, and why circuit generation cannot depend on signal values unknown at compile time. Jose M compiles a multiplier and proves it with Groth16 in snarkjs, then sketches a voting-census membership circuit whose proposed nullifier combines the key, secret key and voting ID. He finishes by implementing a Merkle proof verifier and testing it with circom_tester.

Speakers

Topics

Transcript

to kick off the iden items like basically what we're here for the circum 2.0 workshop with iden 3. so if albert and jose could join the stage and actually kobe and susanna you're you're free to go we'll see you again at the end of the session [Music] hi jose hi everybody nice to meet you hi there hello we have also here uh jordi beilina who is the creator of the monster so oh by the way if you're hearing some echo jose or albert just make sure you close the any other browsers that might be open um sometimes people have i just heard

that a little bit yeah that might actually help you out a little bit just just make sure there's no other hop-in open if you're hearing any sort of feedback but do you want to invite is is jordy meant to come to the stage oh you're muted well in fact jordy is on my side so oh no way yeah hey jordy he's here hello guys well i just want to say just uh 30 seconds here and uh say that we are very excited right now to because it's the first time that we introduce silicon 2.0 it has been a huge effort

i need to say thank you to a lot of people you know starting from the ethereum foundation that got a grant for doing this uh for rewriting all this in rust of course the uh universitat components in madrid with albert in front also they were stuck working in catalonia with jose in front all the people in united three and especially all the ivan iii community in the in the chat that has been doing a lot of work there so i just i hope that you enjoy right now the silicon 2.0 is a step forward in what was starting like a toy at some point and right now we we just gave a a step forward to do a professional and production ready and much tester easier to auditable well you

will hear a lot uh about this uh by uh albert and then in the second part jose will do uh actually the workshop where we will start from the scratch and create a circuit from the beginning so i hope that you enjoy uh thank you all and just enjoy the workshop and thank you anna for all your your work yeah cool all right well i'm gonna actually hand it off to jose and albert i'm going to close my video i know you have as i understand it albert you're going to start with a presentation and then there's going to be more of a hands-on workshop you guys should all know there's two chats there's the event chat and the sessions chat focus more on the sessions chat for

anything here and there's also a q a i don't know if you if albert if you guys want to check that out every once in a while but we're going to be around to moderate so we can highlight it for you great so should i start yeah i would do a screen chair okay and then jose and i'm gonna drop off jose you can stay on or and maybe mute yourself in the meantime and i think i think it is it okay if people ask questions as you're going that's the question in the chat and actually i think jose you were going to jump in it's okay if you ask questions as we go so yeah we'll take a look second

i don't know if this is the way to go sharing oh all the things is it this okay uh we see it yeah there you go you did fine like this looks great oh sorry i'm a bit at the beginning not at the beginning sorry oh all the way okay okay okay sorry okay good take it away uh here's the workshop so here we are so i will start with the presentation so you have already seen jordy and jose myself but

i will start with the presentation as jordy said this is part of this iron three project and founded funded by the ethereum foundation and we at the university we are part of it uh as well so this is gonna be uh the the overview talk so i will i will do it really quick this part because i guess that most of you know uh what we are talking about but uh just to give a little bit of context to to later introduce the circum language and compiler and i will make a i will give some time to to

describe the differences or the what what has changed uh from the previous version of silicon that needs to be known for those that were already working with circum and now they needed to to change minor things to to make them compatible with uh with the new compiler i will then conclude with a little bit of talking about the constraint simplification which is a really key part of the of the new compiler and i will talk a little bit about performance and then jose will come and will give you a real practical

tour uh using techcom 2.0 so let's start with this so we all know that transparency is uh it's very important and desirable property of of the distributed ledgers but well privacy is is is also that we want to warranty in many cases so you we need to find this balance between both properties and zero knowledge can be a a good solution in this way so what is a zero knowledge proof or protocol it's just a this protocol between these two parties in which the prover uh

can convince the verifier that that some statement is valid without revealing anything about the the statement apart from the fact that it is valid so we have this completeness which is that uh uh on uh honest proverb can convince a very failure soundness that malicious prover cannot top in the reminder and of course the zero-knowledge part which is that nothing will be shown beyond the validity of the statement so the key point here to introduce uh why we use these uh languages uh in in this context is what kind of

statements uh can be proved and then is when we come to to arimatic circuits uh stability uh satisfiability so here our statement is a demonistic uh arithmetic circuit in which you are we are given uh some public input some private input and we produce an output so given a circuit and the inputs the prover runs the the circuit and generates a proof okay then given the proof and the public input and the output the verifier can check that the prover knows the private input and has executed the circuit okay so on the

most important part nothing is is revealed uh apart from the fact that the that we we [Music] up from the the the information about the private input which is already known so let's go a little bit on this circuit uh part and what's a circuit and there's nothing more than a standard circuit but where the gates as you can see here they're multiplications or additions okay so every time we have such uh gates so we get a result and so on and this gave us this important thing which is this quadratic constraints okay you see here

we have that this output here we call this meth one it's the is the result of the multiplication of these two this uh uh map2 is the multiplication of these two and the output is the sum okay so these are quadratic constraints but just keeping this in mind so we need these quadratic constraints and we don't want things that are not quadratic for instance if we express it directly like this this is not a quadratic constraint okay because here this is not quadratic this one okay so another important thing is this notion of simplification here you you you can realize that this

intermediate uh signal is not really needed because we can express the output like this and this is still a quadratic constraint okay so here just a multiplication plus adding this uh this signal okay so the important property is that the circuit operates on values in a finite field okay where this p of the finite field is a large prime number like this okay so somehow we work modulo this prime number all the time okay and the important thing in our context is that the constraints describe the arithmetic circuit and are

given in this r1cs format we which is a format of this form we saw last week that there are many languages working with this format there are other formats but we will uh talk about this rc r1 scs format in which all constraints should be of this form where a b and c are linear okay see so all should be expressed this way okay and executing the circuit which is something that the prover has to prove it's done it's obtaining a value for all signals in the secret and we call this

the witness okay so somehow we need these these constraints in this format and also we need this witness to show that we have executed the circuit okay so just very quick zk snarks okay so how do we generate this uh ck proof and the verifier and this is by means of these snarks okay this uh in these snarks we have that they are not interactive also we pay this uh the price of this trusted setup must fit on probably and what these uh these snags uh do among other things is to transform these uh

r1cs uh constraints into these quadratic algebraic problems magnetic programs sorry and um and the the key point is that these snarks generate short proofs and there are implementations with constant time verification in particular as an rjs with another which is another tool of item three which combines uh very well with uh with the circum language so let's go into the silicon language and this is the picture we've shown so we we want we have this computation that that we want to prove it's been done but this

competition must be stated as an arithmetic circuit and then from this arithmetic circuit we get this r1cs format for the constraints and if we are given the input we get the witness okay the values for all the signals and all this is sent to us in rgs and we get the prover and the verifier and uh and in fact we get the proof and the verifier that can check the proof and in particular uh this verifier can be given as a solidity uh code as well okay so

here we have that the second language help us here okay when we want to describe with a with an arithmetic circuit our computation so the silicon language help us here and the compiler help us here to get these constraints in this format and to get a way to compute or code to compute the the witness once the input is given okay so this is a circum silicon is a primary language and a compiler and in particular is a domain specific language okay the majority

uh for designing these uh circuits in in ck protocols so silicon 2.0 which is what we are presenting here was has been just released okay so uh two weeks ago and and uh it's a compiler fully written in rust okay and it provides faster compilation compared to the previous compiler and more security especially because it is written in rust but also because it applies a stronger type checking and static analysis to detect as early as possible programs that are really

not intended to be correct programs in the in the language okay so many things are are detected quickly in the earlier uh stages of the compilation uh process okay the the aim of a circumference is to fold it but this part of the of the secret uh silcom language and compilers both to provide a symbolic description of the of the circuit which is a list of constraints in this format which is given in a binary file and also to provide an efficient way to compute the witness from the inputs okay and this uh

is made by providing either a webassembly code that can be combined with uh with javascript or or a browser or to provide a c plus plus code which is needed for large secrets for instance in the context of zika roll-ups for layer two there's another project of item three item two uh no item three so we we have uh we need uh very very light circuits the circuits that cannot be handled with uh webassembly okay so this is uh it goes beyond the the the amount of memory available in in uh in the

webassembly uh victor machine so it should be done with c plus plus and then we we have this possibility as well so you can choose your one web assembly or or simple bus or both so silicon allows the programmer to design this argument is secret at a low level like done with electronic circuits okay so this this is the the key property of of of circum okay it's like uh when you design circuits uh with very long uh so it's just that you want to be at the level of the of the circuit okay so it's really low level and and the the the key point is that

all constraints have to be explicitly added by by the programmer and when we apply this simplification steps that we will talk later we can remove signals but we will never introduce new signals uh by the compilation process so everything should be introduced by the by the programmer that's the uh the key property of of the design in using circum so let's make a first uh presentation of circum later on you will see it in practice with uh but

here we we have that that in circum the actual circuits are called components and components are created by instantiation of a template which is a parametrized general description of circuit okay for instance let's start with the simplest uh one of the simplest circuits we we can have so here this is a multiplier that receives two two inputs and returns uh the multiplication the product of these two signals in the output okay so you see here we have this this assignment here in which we say that the output is this uh

multiplication okay so the key feature of silicon is that it provides different instructions to do all these things to work only at the symbolic level which means we only define a constraint for instance here we are just saying that in the set of constraints we have this constraint included okay but there is no computation here we simply say this should be a constraint of of my describing my secret okay we can do only computations and say for instance use

this instruction to assign the value of the output from these these two signals but in this case we only generate an assignment but there is no constraint associated to to it okay we can also write it this way okay so second we can do uh both things and also we and this is a nice thing we can do both okay so if we use this nice uh circum operator we get both we get second stream and the assignment both things it could be used in both directions like we have

seen here for the other operation okay so we can do all these things either both together or split into parts okay so it would be really desirable to always use this operator okay why because then we get both the computation uh level the way to get the the the value of the signal from the other signals or and also to get a constraint associated to each of these assignments okay but sometimes it is not uh not not not possible so let's see it in a simple example so

suppose that we want to but also illustrates that it's not that easy to to to build uh circuits using only uh quadratic constraints okay so let's just imagine that we want to to define a circuit that checks if the input is zero or not okay so we have this uh an input signal and an output signal okay so then we try to think a little bit and then well suppose that we with our first circuit and and just say well let's do it like this okay so we we put the output we we write this with this that gives you uh

the constraint but also the the instruction but what happens that well this is not allowed because of course this is not a quadratic constraint okay so there is an attack on the contact in the compiler will say no this is not a quadratic constraint okay so then we say okay then let's forget about the the constraint part we just write it like this ah this is terrible you cannot you don't want to write it like this because then there is no constraint at all okay so you just are giving a a a an assignment but there is no constraint in your in your secret so if the secret has no constraints so what are you going to check okay so we need both and that is not that easy so then there is a way to to express it okay so we do

it introducing an intermediate uh additional signal that express that it is the inverse of the of the input signal okay so then you can see here that we are expressing the fact that that is the inverse here as a using this assignment but also this constraint that states that after all it will be uh either zero here or zero here at this zero this will be one okay which is set here but we need this way

okay this efficient way to express how to compute the inverse of uh of in okay note that with these two only these two okay if we don't we we don't have this okay so suppose that we only have these uh two then it would be really difficult to to to compute it okay because this is not helping us to know that this is the the inverse okay we have nothing said about imp so we have this to express if and these are the constraints that express that really is the inverse okay so if we use both if we use these operands like this and like this here okay

then there is no warranty that there is an equivalent between the symbolic part and the computational part between the constraints and the execution okay so you have to be careful with this in fact to show that they are exactly the same we may need even to introduce this extra constraint okay but well we we may be happy with this okay so the important thing here is that there is no guarantee that the reason we will speak between both but is really a desirable property as we will see later so another important thing in in in system is that we build secrets combining templates i'm creating uh

let's say some components from other components like here you see so we have the multi-and is built using another component which is the e0 that we have just seen okay and then we also can have this notion of variables which is an interesting new thing it's not a signal because signals are in immutable but variables can change the value and they are also can use to to to express uh let's say expressions that that are built of several uh components for instance sorry components sub expressions for instance here we have that sum

is obtained by summing all these in data inputs okay you see okay so we we we can compute this sum by summing all these inputs in this case you see that we have arrays of inputs okay so we have an array of inputs and here we are summing all these inputs and look what we do here we say that the output is the result of summing all these all these all these inputs and checking if the sum minus n which is the number of uh of um of

of inputs we have is exactly zero okay so we send this as input to this component and we get the output from this component see here we are using exactly this component okay so the the the nice thing is that the variables have two different uh use uh uses so they can be symbolic expressions okay here when we when we create the constraints okay but also they are numbers when we are computing okay so look at this variable sum as these two things so when computing

the the value of the of the signals it is really a number okay it's computing summing all these but when computing the the when generating the constraints it is the expression which is the sum of all these signals okay so it has these two meanings in the same program okay depending on which part we are whether we are in the in this symbolic part or in the computation part okay so um suppose that that just to show a a final example and to and to

to show the important part of this equivalence between the computation and the and the constraints support that we want to to get uh from an input we want to transform it into its final binary representation okay so suppose that that we have this input and we want to produce this array of outputs in which this is the binary representation of input of the input okay so of course it's clear if we were programming in in a standard language we would write something like this okay which we see that the output

is obtained by extracting every single bit of the of the input and then storing this in the corresponding uh uh bit of the output okay so that would be the standard but this would be only computation we need to provide also the constraints and here we have the additional stuff to do that okay so look as before we introduce this uh these variables here this is not that important just for efficiency it computes it keeps the power of of two and then look at this b sum is like

in the previous example we are accumulating an expression which is really describing the expression that says that that b sum is the uh binary representation of of in we so we keep this expression this expression here accumulating it and finally we state it as a constraint that the input should be equivalent okay to the sum of the of the of the bits multiplied by by the corresponding power of two okay so this would be the constraint saying that this is a representation uh of the

of the input in in in binary style but we are missing one property which is that all these values in output in the output are binary so these oops sorry this is what we have to to add here okay so this uh this constraint here states that every every uh value in the in the output array is uh is uh is zero or one okay yes so the important thing again is that we need both because without this there is not a a a reasonable way to compute the binarization of the input okay so we

need on one hand the constraints but also we need this to efficiently uh obtain the the solution or the value for all the all the signals okay so we need both so we need both but they must be the same so that's the the key point so as we have said a silcon program has two representations the constraints and the executive executable code either in was more in c plus plus so the compiler does not check whether they are related or not okay so it's a programmer's responsibility to do so so if we

don't use this operand okay so then everything is fine we we if we don't use this and only library templates we are safe but otherwise we have to be sure that they are same and in fact it means that both express exactly the same relation between the signals of the circuit okay that is the computed witness must be the only solution to the constraints okay that's the key point but is a programmer's responsibility okay the the the compiler will not check that it's in fact it's not easy to prove it and sometimes okay so

just to conclude this part just take into account that many things i was saying just use the library templates because there are many things that already are provided in the sitcom leap library okay it it has implementations for binary transformers gates comparators hash functions okay elliptic curves the sparse miracle trees and it really shows the power of the of the language and you can learn how to encode complex computations using these uh constraints by uh going through the the circumlate okay

so now a little bit of what's different from silicon to silicon 2.0 so that's the that's useful for those that already have been programming in silicon and now they want to know what's what what is anything that has changed and the the important thing and the reason we moved to 2.0 is that we are not preserving uh compatibility or full compatibility with uh with the previous version of sitcom it's not that different but there are some uh some difference that should be taken into account okay so well you it means that if you have some projects

don't you have to change a little bit something so let's make a quick pass on on these differences and one is that semicolon is now mandatory so you can see many many circuits there that for instance have a line like this in which all of a sudden like happens with javascript there is no uh semicolon here so this is not allowed anymore so you have to put all them otherwise you will get a compilation error okay so something a bit a bit uh a bit more uh maybe painful for for uh

for for silicon users is the fact that the this keyword private public has changed completely in its use so in fact private and public are not used anymore in templates okay so in the past it was all all templates were having this private public thing but now the only remaining keyword is public and it's only used when defining the main component okay so no no you we cannot use either public or or or private in any other

context but when defining the the main component and private in fact is gone you cannot use it anymore and let's see a little bit of of how it works now and and why this is like this and the point is that you we we have this uh for instance here this uh template and here we define the main uh the main component okay and then is the the point in which we say that for instance these two inputs are public okay so we here can put the list of the of input of the input um the of the input signals of this uh template that are public so we can

maybe take these two or maybe we can take one we can take no one and then we don't need to put anything here so we will just put mainly equal to a multiplier it means that all them are private and the default is that if we don't say that they are public they are they are private okay so this was what was the way to to express this in the old silicon circum it was like this and this is forbidden from now on and if you write this public private here you you get a compilation error okay saying that this keyword is not expected or this this token is not expected here okay so we have to come back to here and

the reason is that in fact what happens that all output signals okay of the main component are considered public and cannot be stated as as private the input signals of the main component are private if not stated otherwise so we don't need to say anything about private signals we just say when they are public and the rest of signals they are all private and cannot be made public okay all the remaining signals are really intermediate signals and they are for that reason they are really private if you want to make something public you just have to transform it into an output and pass it to the

to the main uh to the main component somehow okay so you you you can do it but you need to explicitly say there is a new output and then it's public from now on but you cannot say that something in the middle is is public in fact the semantics of the previous circum was that they were all private if they were internal signals so after all the only private public thing that was important was of the template that was instantiated for the main component okay so after all all these private we we had before okay they were only used in the final in the in the template that was uh instantiated to get the the main

component so after all there was a lot of private public that was never that was uh not meaning private uh public okay because they were intermediate signals so they were all private after all okay so another uh another difference is that in silicon 2.0 and this becomes strict because in the in the previous version well in some cases could be or not depending on the on on whether the signals were constant or not you know here this is not uh allowed anymore so no no the secret cannot depend in on on the values of the signals okay so

we have to think of it as a physical circuit okay it makes no sense that your circuit is changing depending on the input you get okay so it would be quite weird you you get a zero in some in some uh in some uh signal and then all of a sudden your your secret is different okay so then it's it's it makes no sense in the in this context so the constraint generation which is what is describing your your secret cannot depend on this unknown information but this is the unknown information at compile time which means it can never depend on signals okay whatever they are they cannot depend on signals okay let's see a little bit of

examples that something you cannot do so for instance you cannot write an if statement okay with the condition using a signal and then adding a constraint there okay remember that this will add a constraint thing y equal blah blah okay so this is not allowed okay and you will get a a a completion error like this okay in which you say that no no no you it cannot happen that uh the constraint depends on the unknown information okay so no not allowed but also something like this you may think oh there is why not i would like to do that but this is not

this is not uh correct either because the the the if this is a an array of signals which signal you are really using depends on the value of this uh x signal so this this would be changing the circuit depending on which is the input of x so this is not allowed okay and you will get a message like this from the compiler so every every time you get some some message saying talking about unknown it means that something depends on something that should be generated as a constraint depend depends on the value of some of some signal okay

maybe after several steps okay so so the the compiler checks this and says no okay another another thing that also has changed is simply because we wanted to make it precise in the definition that all signals and components must be defined at level zero okay in templates it cannot be nested for variables there is no problem you can define them at any level of of nested uh in the in the blocks but signals or components should be a level zero at the top level okay so for instance if we have something like this which which was a part of the silicon bleep

of for the previous uh circum this is not allowed anymore because here you see you have this component which is defined here in this nested block and this is not allowed anymore so how we uh so you will get a message like this signal or component calculation outside initial scope okay so how do we solve this and how do we write this in the circum 2.0 so we define the the the component at uh stage at first level at zero level and then we create it when we want inside and

that makes the uh it makes a little difference because here what happens that this component maybe is not created depending on on the value of this of this uh of this parameter okay but it is defined but maybe it's not created okay so this can happen and has no problem for the compiler okay so another thing that is is uh is a bit painful but not that much is that arrays must have constant size at compile time this is important okay so many things now should happen at compile time because we don't want things to be

decided uh uh dynamically while executing okay so one important thing is that it's not meaning that you you need to put a constant explicitly but here this is allowed okay why because when we instantiate the template we will give a actual number so we know that this will be uh um of constant type uh at compile time because we know that is used like this okay okay so you we will never comply d compile this alone it will be together with this main component okay this is also uh okay because y

is somehow uh constant as well because we will get always this instantiated and this y will be a constant and if it is not modified between this and this instruction then this is perfectly fine what is not allowed is to use it in a in a function okay because functions could be called in other contexts and maybe is not necessarily be constant uh this n might not be constant in some execution okay so we don't want to check what uh we are always calling it with a constant or not because maybe functions are only used in the computational path and this is not executed when when compiling the code okay so

it's the same thing you say no no no we don't allow this then you will get this compilation error and well probably in the near future it will be allowed when if we if we had this some statement saying that something is constant because then we you can check that really it's only used using constant information and so on like in the sense of this const when you have c plus plus code or or other languages okay so the semantics of const as a keyword okay so another thing which is not that important but but we think we believe it's good to to to ensure that

that we don't make mistakes and forget some some part of the definition of function is that we we check for for function path completeness okay so all parts in the control flow should end with a return statement okay so for instance something like this would not be uh accepted because here you don't have all the paths uh in the control flow so you have if else and then there is no no no more else so here it could be that there is no no no return in one of the cases you you may think well but i know that i only call this function with zero or one well maybe yes but

we are in a context where security is important so better to to say explicitly that while you don't care or or that in any other case you will return some value okay so for instance suppose that we say yeah return 64. well or whatever you like okay or you can do it like this way too i mean in both cases you cover all paths and then it's fine so the compiler is not gonna complain okay so this is it so there are no more important changes okay from from the previous silicon to silicon 2.0 and from that point on we will keep this compatibility with silicon 2.0

on okay so let's talk just briefly about constraint simplification and performance before you go to the real stuff with with the practical example and here i just want to say that that when describing these uh these uh cryptographic protocols we may generate constrain systems with hundreds of millions of constraints okay you can think oh no it's not going to be that that many but it is it can be and many of those constraints can usually be eliminated okay so simplifying these systems is really essential for the efficiency of the next steps for instance this transformation to the

quadratic arithmetic programs as uh for instance but also in in some cases there are limits in the number of constraints that that the zks narc system can handle and then you also need to to to remove uh unnecessary constraints okay so we allow constrained simplification that do not modify the behavior of the circuit okay and preserves that's important this r1cs representation remember that we will never add new signals okay so we cannot say i will simplify adding this this new signal but this allows me to remove these and that no no no we can simplify but never adding new signals okay so just a simple example remember

the the initial the initial the this initial example with the multi-and and we have uh constraints like this and the the the nice thing is that these two here okay so can be simplified and this is the point so we will replace this one by this one okay and we'll replace uh let me see and we will replace uh this one by this one and then we get as a result this new representation in which you see we are simplifying these linear constraints okay and we get a new system with two constraints less but it's still in r1cs

form okay you see okay so it's multiplication just one multiplication here and the rest is in in the upper peak form and here we have the multiplication of this by this and this is clear is linear so we are happy with uh with this constraint too so the point thing is that the key thing here is that the simplification of of linear constraints is simple as uh it can be done just performing these linear substitutions okay so what we do is every time we have a linear constraint we expect as a substitutional intersection and we can preserve the r1cs form okay so if

you have a constraint like this and you apply a linear substitution you get again a constraint in the same r1 cs4 okay the simplification of non-linear constraints is far more challenging and there is work in progress we are trying to do something there but it's not that simple okay so linear constraint simplification is very efficiently implemented in circum the compiler applies clustering this was already done in the in the previous one but now it is done in the same phase and just trying to avoid uh to minimize the number of operations we know we we do okay so we apply the clustering and pronunciation as before

but in a different way and this simplification is is is done using this culture of an elimination and we can remove all linear constraints and every time we remove a constraint we remove a signal and the only risk is that we we cannot remove public signals okay but this only applies to the main component so remember so it means that in in almost all cases we will able we will be able to remove these linear constraints and we iterate the process because sometimes after applying the linear uh simplification some nonlinear constraints become linear and then we can simplify them again so we have we we

iterate this process and we are able to get reductions up to 80 of constraints which is very important so the only the only uh problem in this is that this is quite expensive but it pays off for four large uh circuits but for instance imagine so you may need something like seven 750 gigabytes of local memory so well in any even big machines it will need uh swapping and this slows down a little bit the the process but still so we can reduce for instance uh large secrets get that uh half at the beginning 650 million constraints to

only uh 130 million constraints okay and and know that now the the compilation of such uh secret can take more than 10 hours okay in a in a in a powerful machine but the previous sitcom was taking several days to do the same okay so this is important and note that for instance in examples like this that the size of the binary file with the with the constraints could be about uh 58 gigabytes so uh and on the other side if we think of something not that big okay but still big a secret of of 10 million

constraints can be compiled with full simplification with this iteration in a laptop for instance it it takes around eight minutes okay so in my laptop okay so it's it's something that that uh you can do uh with your with a with a standard machine okay so now i'm done and it's time for jose to to give you a practical tour with uh silcom thank you oh can i just jump in real quick i just want to make sure albert that you had a quick peek over on the q a oh no that had a little bit to do with you maybe you want to just close your

screen for a minute okay because now we're just seeing the epic yeah cascade of infinity and i know someone was asking about a recording uh except here no yeah you just thought yeah the little screen yes okay okay so frederico i'm gonna answer one of these because it's about recordings we are recording this it will be on the youtube channel of the zero knowledge podcast starting tomorrow and then we also add this on the workshop page on the website so that was one and then oh i guess somebody actually somebody deleted their questions so maybe maybe there aren't any more but maybe albert if you want to look through uh just sort of the last little bit in the chat but the chat because then the question i can

see that people actually didn't they kind of got rid of the q and a's there were some in there but i think they maybe had those answers already jose i think an answer i've been answering but i don't know if all of them but uh well no worries i'm gonna let you go i don't mean to interrupt you i just wanted to make sure that you're keeping an eye on that cool okay so i don't know okay maybe you uh should uh answer in the chat yeah but let let should i start yet

um okay so now let's uh move to some more practical uh uh more practical stuff related with uh circum and i'm going to divide it in like uh two parts in the first part we're going to do a very simple circuit that just made some multiplication and we will generate i mean we will compile the circuit generate the weakness and and then generate the proof and validate the proof um i'm going to i'm going to do it quite uh quick because as you see here we have the documentation is just follow this just follow this uh tutorial okay this

is getting a starter tutorial uh so yeah it is easy i'm going to just more or less comment all these steps okay the first thing is that the compiler is now writing in rust so you need to download the rest and then clone the repo and then uh just compile okay but uh we are planning to build all the binaries for all the platforms but this is not uh yet done so the easy way but the way to go is just uh download and compile okay so i just i already did this um yeah docker images yeah we're discussing it but some people in the team is not very happy with

docker so maybe just binaries because you know just you're just uh building something so yeah um okay so let me uh so i already compiled it the i already compiled a circum and silicon produces like a lot of equations and then a lot of values for all the wires of our of our circuit okay and then from this we need to produce the proof and then this is used by the verifier to check that the circuit that you know uh a valid input for the circuit okay

so the tool that goes after sircom is a snare js okay and in this case we are going to use the graph16 system to prove uh that you know the weakness that the private input of a circuit okay so let's let's start building a simple circuit go through all the process and then we will move to a more complex circuit and and essentially the idea is that you see how to think in designing a circuit and and all the things that we need okay so yeah let me go here in a console and if i do circle my hobby okay but if it's complaining because i didn't put any any

file but i have it already installed for you the that you said the previous version make sure that in your path you have sircom.0 okay if you see here zero something you have the old version you should remove it okay the previous version was javascript so npm remove and so on okay and i i also installed snare gis you have these instructions there okay so i'm just going to quickly follow the tutorial okay here so yeah let's create a telecom tool and then uh let's create uh our first

circuit it's a multiplier so let's say multiplier two okay and then uh well i can copy anything to go faster but i will is it is really easy the circuit so okay so in silicon um we define circuits first the first thing is to define a small circuit it's like integrated circuits so we need to define a circuit and in this circuit is the simple it's almost the simplest possible circuit it's just multiplying two inputs it's a small

piece in of a circuit okay well in this case it's going to be the circuit but in a bigger circuit this could be a small piece of the circuit okay so in our case this is going to be the circuit so i i need to instantiate this it's create this circuit okay so and since this is like the main circuit later we will do a more complex one i put a component main okay so this is going to be the circuit and it's a multiplier multiplier 2 which i have defined it before okay so here i have the definition of the circuit and then the instantiation of the

circuit and that's all what i'm going to use okay the first instruction we introduced this instruction to uh to manage the versions different versions and as you see it's just uh we receive two inputs a and b okay and then we have an output c okay and then c is a plus b so we have a computation here and also a constraint okay c must be equal to a times b and a times b is r1cs because it's just a multiplication so this is uh this is okay okay this is a quadratic equation so everything okay okay this the circuit now the circuit is not important it's just all the

machinery now that to you know compile and create the weightness and so on okay um okay so that's it so we have now the definition of of the circuit the next thing is to compile this circuit okay i'm going to do circuit multiplier two and i have here all these uh i don't know if you see it yeah uh i'm going to generate the questions this is dash dash r1 cs is generate all the equations related with this circuit wasn't wasn't is uh the uh i mean we need to generate values i mean you will provide me all the inputs of the circuit

and uh the compiler will generate a program okay that when we run it with the inputs it will generate the values for all the wires okay so i'm saying here that please generate a program let's put it these two together also let's talk about the last one the last one seam is symbolic means that it will generate some debug some information for debugging okay but uh wasam and c these two means uh generate two programs okay to generate the values of all the wires of the circuit

when i provide you some input and i can provide you different inputs and then these programs will compute all the values of these wires okay so let's give the run and everything went okay and if i do an ls now i can see here that i have well i ask sircom to have the all the equations all the equations are here then i have some symbolic information okay and then it created these two files okay to direct two folders sorry uh one in c plus plus and another one in this javascript is awesome in fact okay these two help us

in uh building all the uh to create for uh computing all the values of the all the wires of our circuit okay okay well right now this is really easy the the circuit so okay so i enter here and i see several things but if you follow the tutorial you just need to run let me check yeah so yeah and we need to create an input here okay so mouse here okay

um so here i'm going to create an input remember that our circuit just has two inputs a and b and we'll compute c okay so i'm going to generate my input okay and uh it's a json file okay so now uh it's json a was the first input of our circuit i don't know it's going to be three for example and then b and it's going to be 11 for example and then our circuit the the the program that we are quite going to run now will compute just c which is 33.

this is quite easy but if the circuit has a lot of gates then this will this will be much bigger okay so i have my input here and to generate uh all the values of the wires of this circuit we use this wasm program you need to have node.js installed okay and just run generate witness okay and for using this wasn't program and then this input and then store all the store the values of all the wires in this file okay this is what i'm saying

and okay i have this witness dot wtns this is a binary format okay to efficiently store the values of all the wires of our circuit okay and that's it essentially we finish with silcom may we need to design more complex secrets but that's it okay the problem someone was asking in the in the chat that well uh i was talking with jordy i think they have tested this uh this weakness calculator uh this was a witness calculator and said that was around one million constraints it's okay

but if you have a bigger if you have a bigger circuit then it's better that you use this c plus plus version okay remember this is just a program to compute the values of all the wires okay and uh well you need some dependencies now the in the documentation we specify the dependencies that you need you need three 3d three libraries okay i already stole these libraries on my system okay so if everything goes okay you should just run make and it will compile this and generate the c plus plus witness calculator okay it seems that it's going okay

so nice then i have this uh this file here this multiplier two this is the this is the program that now computes the weakness that is in c plus so it's much faster then uh to run it just need to run it okay and uh using the input okay i can copy the same input in fact so let me copy the input that i use from js here and then let's run it it's faster

probably you can see a difference because the the circuit is very small but promise i promise that this this is what this one is faster okay and also generates this weakness double or double up tns which is the thing that we need to uh is the only well this uh that the witness uh and the r and the a r one c s file is what we need to create the proofs okay so this is the output of the of the circle dot o okay probably you don't trust me so let me let me check that these two witnesses are the same okay so i do a shot of this and i do a shout out the other one and

you will see that they are the same okay so if we are not wrong if not we have to kill alberto but yeah no you're safe so yeah the same files okay but if the circuit is bigger we recommend that you use the c plus blast version okay so that's it we compile a circuit from the compilation we obtain two ways of computing all the wires of our circuit and uh and this is stored in this file and then we also have a file with the questions which are the which is the rc1 uh drc1 file okay and now we are going to use another tool which is well today the session is about

silcom.0 but it is nice to see all the process and then we will focus on just designing circuits so now i need to create i need to create proofs okay and we're going to create proofs one with one proving system that is called graph 16. right now uh we are starting to also integrate block is more or less integrated but we should optimize a lot of the process so let's let's go with growth which is like the classical okay and in growth uh there is a trusted setup okay and this trusted trusted setup is per circuit okay so each circuit has a different trusted setup and from this

structure setup essentially we create some randomness okay and that's it um let's go for the easiest way of doing this okay so i'm just to copy and paste and comment what i'm doing but going fast i have a problem with the cursor here let me check here okay okay this one is to is going to create the phase one of the thruster setup this phase is common for all the uh it's common for all the circuits okay it's randomness that can be reused in all the circuits that you create uh with uh that you create okay

in fact this is just uh 12 is two to the to the power of twelve georgie i have story here yeah so you have you can uh with this trusted setup you can build up two two to the twelve uh two two small circuits of uh up to two to the twelve uh constraints okay okay so this is like the um preparation and then uh i can do a contribution since uh the trusted setup is a is a very delicate phase because um typically the trusted setup is built

as a multi-party computation with several people contributes and this gives this gives more security because if one of the contributors do does it right then the the the result is okay okay so with one honest contributor that's it that's it uh that's that's enough okay uh trying not just to contribute once but in a uh in a real system we will have like several contributions and also there are uh i think someone in the chat is saying that there are already uh some uh some uh information uh some some phase some powers of tau available okay so but but here i generate uh this

phase one with just one contribution and then after this we move to the next phase which is a specific for the circuit okay so you're going to you're going to see that we are going to use now things uh uh well i'm saying the chat but you can do it as as you see job i compile the circuit first and then i'm doing all the snark thing after you can do it in i mean they are independently independent until uh until this point here okay until a certain point here okay so yeah this prepare as you see with that we haven't used anything special from the

circuit that i compiled yet okay so this we are now preparing for phase two okay this may take a little bit because what this is an optimization in fact for doing uh computations later faster [Music] so these steps you can do these steps independently of the compilation okay but now uh now then the the next step you will see that depends on the circuit okay

by the way while this is finishing just uh look for a fiercom item three and it will bring you to a gate started and then there you have all these all these steps okay so my idea is to do it really quick but it's lasting a little bit but we're in 11 so i think just the last 12.

okay this is the size of the circuit it's 2 to the 12 equations let's say okay let me see the q a while um let me check the chat meanwhile

about half circle i was reading that they were starting to to integrate it but i don't really know how how by the way you can talk because if you want to talk okay it finished and now the specific part okay so as you see here we are using multiplier r1 cs these are all these constraints okay all these equations that our that are forcing that the inputs at the outputs are

related correctly okay so yeah now uh this is generating uh some stuff which is the zk this is all the all the all the previous cryptographic material merge with the uh with the r with these equations and we create here uh all the cryptographic material for the approver and the verifier okay and now we can contribute because we still need to generate the randomness of this second phase which is specific for the circuit okay so yeah we created

the file that will contain this but in this okay as you'll see it's entropy okay so now here uh this key is already contains the randomness okay and as i said this is valid for for the two for the program the verifier okay now let's extract the part of the verifier okay with this command i am uh i'm storing here in the verification key json i'm extracting the randomness and the stuff that the verifier needs okay from this key

okay and now we have all the randomness and all the parameters necessary then now we have two processes one guy the proverb is going to generate the proof and the other and another guy will we will provide the proof to this other guy and our girl in this case and uh the other one will check that the proof is correct okay so let's uh let's do this okay so this is the first part generating the proof okay to generate the proof as we as you see we use the witness i mean i need to generate i'm the proverb so i need to provide you information i mean i need to provide you this multiplier

this z k contains all the randomness okay to generate the proof the witness contains all the values of the circuit and with this uh two with these two data we generate the proof and uh some public uh inputs and outputs okay that the proof will need uh some some some values here and then we also need all the public things here okay so this command will generate this proof in public okay oh something uh well all right we need the witness here as you see we were using the witness so let's copy the

witness from any of the witness computer witness programs json let me check the name multiplier maybe i okay copy multiplier to the this one it's okay so the witness i copy the witness here okay and then again i okay okay

so now uh we have this that the proof and the public inputs and outputs okay so i just need now to verify the proof okay um we can verify the proof in several ways with just a separate program okay and i'm going to do this but the snare js also can generate a smart contract that also proves uh also checks these proofs okay so let me do just the separate using snapchat yes you can proof okay so i to verify uh i just need to pass the cryptographic

stuff for the verifier which is the verify which is inside the verification key the public inputs and outputs and the proof okay and well you must trust that it checked everything okay so yeah this is okay okay if i uh try to manipulate something uh i change the uh let me check it's 33 so let's change to 34 for example if i try to work five well it will say that it is an invalid proof okay um well this is the whole process and you can go through the documentation and it's the same okay

so but now we are more interested in designing circuits okay so this is a multiplier it's okay you can prove in zero knowledge uh that you know two numbers but it's not very exciting so let's try to do something nicer okay and i must apologize i don't have like the nice uh nice slides that that albert has but i'm going to you know draw it like a like in a in a blackboard okay so uh let's let's try to design a step of a voting protocol which and there is a step in which we check that someone belongs to a census

okay so we have a watch one minute ah sorry much a bit as well let me check yeah now it's working um okay so let's let's do this okay so there's a step in the protocol that i need to check that someone okay

is in a census okay and uh someone is going to be a public key okay this the identity of someone is going to be a public key and the census right now is something known okay so let's say we have uh four public keys okay so public key three and public key four okay so i i would like to check that someone that this public key is one of these four public keys okay but not only this i want to check that you really own this public key so in some way you need to use your secret key okay so it is very obvious you could say uh

okay provide me something science probably a signature okay provide me a signature of something using your secret key okay well this is very dangerous providing a signature of something what something that you give me uh you i mean when you sign something you must be very precise so your signature cannot be used in other contexts okay so uh we are going to sign something very specific that is okay i want to both four mile collections in barcelona

to 2021 okay so i'm signing here very something very precise okay and i'm using my secret key to you know to sign this okay we're going to call this the voting id okay it's an identifier of the of the voting that uh that i am i i want to do okay and i can provide this signature to someone no it's okay and you know that verification will just use the signature and well the possibility and the verification algorithm uses some public key so we can try all these four public keys until one of them to check if one of them is okay and yeah you are in the sensor okay nice but not zero knowledge at all

obviously okay so when i do this uh i mean so the someone is going to check this and say okay is this okay this signature is has been done with this public key okay but then this is identifying me so we want to do this in zero knowledge okay so to do this in zero knowledge we can try to build a circuit remember that we are with circum where we're building circuits okay and we have several inputs some of these of these inputs some of them can be public okay and someone might be private which is by default by default all of them are

private that you can also have public and then we have the output okay outputs and typically outputs well outputs are public okay okay so i want you i wanted to give you a proof okay that i know a secret key from one public key of the list okay so i i want to prove you this okay so and i'm going to build a circuit

to prove to prove you this okay so let's let's go for our first version of the circuit um by the way in you you probably know that several uh public key schemes okay you know that we have like several ways of building pairs of secret keys and public keys okay um we have elliptic curves or you can use multiplicative groups or several several different ways okay but with uh zero knowledge we can also use a hash function to build a pair of public keys and i'm going to do this in the first moment okay so

i can use a circuit in which i implement the hash function okay some hash functions uh in uh with silicon we have like several implementations of hash functions we have for example the implementation of sha 256 okay but the problem is that sha 256 what was created uh well it makes a lot it makes a lot of binary operations someone was asking the wires in our circuit can be zeros and ones yes can be zeros and ones but then you are losing a lot of power you are using just the the wire for two values okay but you can do it and share 256 what was created with binary operations

and which is translated means that you need a lot of equations a lot of uh to express this function okay so there are nicer functions uh like uh well positive and position is also implemented in the in a in a library of circuits that we are providing together with circum okay which is called a silicone lip okay so in simple lip we have position two so we could build this circuit okay and use this public key this use the output of this circuit as a public key and the input of the circuit as the secret key okay so

if i can prove you that i know the secret key associated with the output of a hash function well i'm i mean this can be public so this is a scheme of public key this can be public and i since i'm pro i'm proving in zero knowledge you will not know anything about the secret key okay so yeah this is okay but in fact what i want to prove is that i know the secret key with not with a list which is the secret key of this secret key produces one output that is one of a list okay let's try to build this circuit okay so it should it should be something

like this okay it's a secret key i have my secret key i put the secret key in a circuit okay and then we do the hash inside the circuit okay and this produces my public key okay and then we should check that this public key is one of the four possible public keys okay public key one public key two and public key three or four okay how do i do this well i just take this wire and connect to an is equal oh well around it's okay is equal okay

if and i provide here the public key one okay if these two are equal then the output of this part of the circuit will output one if not we will output zero okay so one of zero and i do the same for the i mean i take this signal here and public key two and so on okay and then i get like different outputs and then i do the or here okay so if any of this is one then uh this outputs one okay this is this is the output and this output is going to be public too okay

so in this circuit i have the secret key which is an input and it is secret okay and then the circuit will check it will check without revealing anything about this input that this secret key after doing a hash produces some output that is equal to one of these four public keys okay three and four okay this secret keys this public key sorry they are also public okay so they are also inputs of the circuit maybe i should draw them okay outside so

this is a circuit in which i'm providing uh four five inputs okay the secret key which is private for uh public keys okay which are public okay i said that secret is a private input okay i i provide four public keys which are public and then the output which is also public okay well this could be our simple well this could be a simple circuit that we could build okay but it is not okay i mean this circuit has a problem the problem is that uh if we have a real sensors of uh of a country for example

then we should put here millions of public keys so it is not a good idea is there is a better way to do this okay which are our friends uh medical trees okay so let's go to build a merkle tree to build this circuit okay and let's start with a merkle tree of just uh four eight notes okay so what i'm going to do here um i'm going to build a miracle the idea is to create a circuit that cre that validates that one of the inputs belongs to the merkle tree okay so let's do a let's create a miracle tree okay with

eight values for example i'm going to create a small one so i can make a picture of it each of the leaves of the merkle tree they're going to they're going to be public keys okay so uh i need to do it here hash okay of secret key i mean all the all the keys here will be hashes of secret keys okay okay and then we built a classical milka tree which we take these two values concatenate them and make a hash take these two concatenate it and make a

hash let's put some uh let's do this and this okay this is the root we're going to call this the first level then the second level and then the third level okay so this is a miracle tree that has three levels and eight leaves okay remember that uh we're going to we're going to name this one as h000 okay this is going to be h001 so this one here is going to be h00 and it's simply the hash

of zero zero zero concatenated with zero zero one okay well i'm going to just put without h i will put just the numbers okay so this is going to be 0 1 0 0 1 1 here is 1 0 0 1 0 1 one zero and one one one okay um so in the first level we will have h0 which is the concatenation and here we have h1 and the root okay so this is the

structure that we're going to use and then you want to prove that you know some secret key of this then you will you want to prove that you own some secret key of these three for example this one okay so i want to prove you that i know the secret key which is in this case is a pre-image of a hash function okay then to make this to to if you want to prove me this then is you know it's regular merkel trees so i know the secret key so i do can do the hash and compute this thing here and then i need to provide you some siblings some notes of the tree that will prove you that will prove anybody

in fact that i'm i know the secret key okay i need to provide this note here so you can do a concatenation and hash and obtain this node here and then concatenate with this apply a hash function obtain this one and then with this other sibling you can open the room okay these in blue are the siblings or also all the siblings together are the medical proof and essentially we check that with the siblings if you do all the hashes you end in the root okay

and uh if you provide me uh if you provide me all these notes i will be convinced that this note here is in the tree okay okay so yeah let's let's try to to build a circuit with this okay there's something let's we will go back to this picture okay you know in a moment maybe you could think okay then uh i want to prove you that i know a secret key that is in the tree okay so maybe you you could think okay try to

build a circuit like this okay well it's not a nice little better and i input here the secret key okay i input here the siblings an array of siblings and then this this sequence you should do all the hashing and all the stuff and i'll put here the root okay maybe the question is what is public here what is private i don't know if someone want to obviously the root of the tree seems that needs to be public okay the secret key obviously

seems to be private okay i should not reveal my secret key regarding the siblings what do you think should be public should be uh private i don't know if someone wants to ask but should be private okay if i i mean to check as you see as you said before we need to provide the public the public signals to the very fire so if i provide the siblings he will know where i am okay uh yeah the nullifier is going to appear uh in a while okay um

so yeah this is enough i mean to build my circuit uh this is not i mean there are enough entries here to build my circuit and the answer is no okay because i need to uh i mean i need to provide a circuit that allows you to prove any any of the uh possible secret keys okay and uh see that if we have this secret key then we need to hash i mean if i provide you this secret key then i need to hash the secret key using using it in the left and then hash with this sibling on the right okay

and then obtain this and in this hash i need to use the or the value that just computed i need to put it on the left and this on the right so i mean and you know that the hash of a concatenated with b is obviously different from b concatenated with a so in some way i need something i need i need to add something to the inputs so i know in which order do i need to do the hashing okay and for for this reason we're going to use the key okay so this node here we have the key 0 0 0 this node here will have the key 0 0 1 this node here will have the key 0 1 0

and so on okay and the key of an element will tell us which is the order in which we have to do the hashing okay for example in uh for this well for for this example here for example okay 0 1 1 means that the first 0 means that in the first half sorry the last level is the last bit okay so in the last level i need to put this note on the on the left on the right okay in the next level also on the right okay but in this level this go this hash goes on the left okay so that this key will tell us which is the order in which we have to do the

hashing okay and this is something that we need to include in the circuit to do the correct hashes in the correct order so here we need also to include a key okay and obviously this key is also secret because if not you are telling which in which position you are in the tree and then you we know where are you okay okay so if i prove you if i prove if i make a proof to you and give this proof to you okay in which uh only i mean only the merkel three only the root of the marker tree is some public output okay only the root is a public op

input then i provide you all the stuff to prove but all the the rest of the things that uh that create the proof then i will prove you that i am in the tree okay but you you don't know in which uh leaf of the tree which leaf of the tree i am proving which means which secret key do i know okay so well this this uh this also [Music] creates a problem because zero knowledge proves you can generate as many zero knowledge proofs as you want okay and all of them are different okay in this case proving that i know a secret key of the tree as someone said in the chat

if we are not careful this means that you can create like two different proofs but you are proving the same secret key okay so you we should not allow this okay and uh well in this case we introduce another thing here which is the remember that we started with i want to vote uh for modular election in barcelona we're going to introduce this also as a public input here we're going to call this the voting id okay and essentially we're going to do the the trick is to do a hash between the key the secret key

and the voting id to generate something okay that is related with the elections and with my secret key and is something that is another output of the circuit okay and is the famous nullifier okay if you try to do uh another i mean each time you do you try to do a proof with you're with the same secret key it will yield the same nullifier so essentially you cannot uh you cannot uh try to be in two parts two different persons okay this is the the idea so

well in fact this is like part of a voting scheme okay uh so let's focus just right now let's focus on trying to build this part here okay let's let's try to focus on building the verification uh of a miracle proof okay so let's let's try to to to see how to build this thing on circle and it's not an easy it's not as easy as uh just a multiplication obviously okay so uh to to build this thing here we will need

let's go here maybe i'm running out a little bit of time now i see it i should go a little bit faster [Music] okay um you need to build some i mean you need to you need some help in in some way uh the circuit is just going to verify i mean you need to provide to the circuit the root you need to provide the circuit all the siblings and all this stuff okay so

probably you are going to need some external programs okay to to build this i mean to create this information okay uh i mean probably if you are in an election you you will give given like several public keys okay okay i will give i will be given an array of public keys okay but from this i need to compute the root okay so and what else then i need to compute the siblings okay because i need to provide the siblings to a circuit so i need to comply this i need to to get the siblings and uh all this

information all this stuff to build all this stuff i need a hash function so i need the employee i need to do hashes okay uh we are going to do not shut 256 we are going to do position hashes because they are they create less constraints on the circuit okay so uh what i'm saying here is that i need some external things that are not in the circuit the secret is going to verify that that you know a secret key okay but to build all this stuff okay well we provide uh for example the the position implementation we have a positive implementation made in

javascript okay so finally to build this circuit you're going to we're going we are going to use some pieces that we already created okay which are we're going to use templates from circle lip okay so this is one of the main pieces you have a library of already created uh small circuits that you can integrate in your circuit okay so this is one of the things on the other way you will on the on the other hand you will need some external programs to you know manage do hashes or

manage uh all this stuff okay we provide some uh will write some programs javascript programs in silicon lead js okay you also have available this other package okay okay so let's try to build this stuff here uh to create this uh miracle tree and and so on i'm going to copy and paste quite quite fast some a little bit of code okay that just does this okay

just uh or yeah let me let me explain you what it will do and then i copy past okay so the we are going to use a function which is called merklize we are gonna not going to analyze it mercallis and for this function i'm going to provide the field because i'm going to do hashes but this i mean i want to do hash of elements remember

all the wires in our circuit are elements of fp which means our elements that go from 0 to p minus one okay so really we can have here from zero to a really huge number okay p is a very big number okay so uh and we need to do operations in this field so uh we provide this uh f field okay by the way this is implemented if i'm not wrong this is implemented in ff javascript or javascript ff ff javascript okay this is another package okay so here you are seeing all the pieces that surrounds circle it's not only silcom okay there

are several it's inside it's not js okay it's also in the third conditions okay you will see it later because i'm going to yeah take a look at this okay what else needs this function obviously this array okay and this array i'm going to call it let me check let's well i need a hash function by the way i need the implementation of the position in this case okay so i'm going to pass this function the hash the array okay and the number of levels okay in this case it's going to be three

okay and this function essentially will create a an array okay with a big array okay it will it will put all the public keys in the tail of this array and then take two of them create a hash two of them create a hash two of them get a hash and create another level here okay this is going to be level three and then it will create all the hashes of level two which are half of them and then well it is not as at scale there are two only at level one and then uh it will put the root here

okay this is the mercalize function and you need you need a little bit of external program to do this okay the circuit just needs you know some signals and do the verification okay so let me create it uh okay so finally if maybe we can not finish it complete or maybe we can provide you a you know repository with all the all the software and so on and just try to you know you

can maybe finish finish it okay so now i'm going to create mk mkdir uh let's say sensors check okay this is and as i said we only we not only we need the silicon stuff we also need some javascript stuff some we will need some circumstance okay so let's create these two directories and inside yeah yes let's create these uh let's uh and medical32js and this is a helper okay to to build all the necessary uh things that we need to

uh create uh create proofs for for our circuit okay so let's edit this i'm going to really copy past all the functions okay i'm not going to discuss them in detail i was a little bit optimistic with the time but okay this is the mercalli function okay it's a recursive function all the records functions have like the same structure check if we are in the last case okay if not do whatever i need to do on my level and then call the again the function and then with the return

you know build the final return okay but sorry but i'm not going to discuss it uh by the way i think i can copy in fact all the file let me jose you have it you have another 10 minutes at least on our clock i hope that's enough time no it's not going to be enough time also also remember that what we're just going to do is we're going to break to start the puzzle but we you can actually continue that after so yeah i think yeah because i i would like to discuss a little bit the circuit okay so sounds good yeah maybe well i continue for 10 minutes and then okay we do a little break where we

announce the new puzzle and then you're welcome to continue yeah i am going to directly i'm going to go back a little bit yes this is nicer okay let's let's go directly for the circuit and then i will provide you we will provide you a regular repo okay with uh with all the all the information so yeah then then let's let's see how this the the circuit for verifying let's focus on silicon then and all the related stuff we will provide you let me check what i did

one minute okay so well and and this is going to be important because you know it's the strategy to build a circuit okay so if i take a look at maybe i can copy this merkle tree

okay so um i'm going to build something okay to check one of the levels of the tree okay remember uh i'm going to provide why we what we have uh on the what what is which is the input of our circuit okay remember it is going to be the key okay well let me draw it in with a key okay but the key is going to be a number so i need to convert this key okay we will have a circuit here which is

known to bits as it its name says it converts one number to the corresponding bits okay so i in the circuit i will provide i don't know the number four five eight whatever okay and this will uh will convert this in three bits in this case okay um and and here i will have the the key okay in this case for example if i'm if i'm trying to prove this one here this is three right so i will provide a three as a number and the output of this circuit is going to be 0 1 1 okay and i'm going to use this 0

but i'm going to use these numbers okay to know the order in which i need to do the hashes okay this is this is the reason for why i'm using the key as an input in the circuit okay and then i need to do let me focus on this on one of these nodes here for example let me see let me see what happens in this check here okay so on one level okay let's call this generically level i okay i'm going to i come to build a template that it will verify one level okay and i and i am going to

instantiate this template several times as many as levels okay and this is for this is the reason for we are we are using the four loops and so and these things to create the to create the circuit the specific uh the specific parts of the circuit need to be instantiated okay and need to be known as albert said okay so let's create this stuff here okay so i'm going to call it okay i'm going to call this uh later we will provide you all the all the circuits and all the stuff okay this is going to be a merkle tree of two binary miracle tree okay verifier level

okay so i'm going to create one template that is a very a it's a small piece that verifies a level okay to verify a level this is going to be level i to verify a level what do i need okay uh to i need to do the hash of this level okay so what i need i need something for example in this level this node here is computed from the lower level okay i'm going to call this low this is an input of this template okay

and this comes from another mk to verify level okay then i will uh take i will connect the i mean if i am in this level okay and i am checking this key here zero zero one uh in the second level is a one okay you see the in the in the in this level i mean the value of the key in this bit is going to is is going to tell me how to do the hash okay so i will take this one here and i call

it selector okay and this inside this circuit will have a selector circuit here that essentially it will just outputs like the input and the output it either copies the input to the output and the input one in the output one or it is rather to say left and right okay input left and import right to the output left and output right okay right and left and left or if this circuit has another input which is selected

that if selector is zero doesn't cross anything but if selected is one it will connect like this okay okay it will connect right to left and left to right and then we hash essentially inside they were using this selector to change input and output and do the correct the hash in the correct order okay and the bit of the key is who is telling me is is the input to this selector and decides if we need to cross or not cross okay so i'm going to put the selector here and uh then i need to do the hash with the sibling in this case with this sibling here so i

need to input the saving here also okay and the sibling we're going to take remember that we provide the siblings as an input okay and they were secret so i'm going to take sibling i and connect it here okay the the sibling of the i'm going to take the array of siblings and select sibling i and connect it here okay and then this will do the hash and produce a new value which is root or maybe it's better to say too root okay it will probe it will produce this value here okay so this is the

piece the pieces that we are building here okay and essentially we need just we just need uh well this mk2 verifier level okay we need this selector we need uh some hash function to do the hash and then connect all this i mean then i have like all these pieces and i need to put it in a in a motherboard and put all these pieces and connect everything okay well circum allows to do this okay let's see the code okay of circum or maybe we can do the i'm going to show the the circuit and a

little bit of testing but i want to just take a look and then i think that the best idea is to provide to provide all the people the link okay so they can check out try stuff i don't know ask questions they are very welcome to join the item 3 telegram group and we are answering our answering questions there so nice yes would it make sense to share the link now or you only want to do that oh yeah yeah the link of the repo of that of this uh yeah it makes sense uh let me check for a minute by the way oh you're freak but uh is this uh maybe

i can cut and paste here uh it is not finished okay uh but uh anyway i paste it here and it has like all the code okay awesome um probably i'm going to convert this in a marina tutorial and write down everything and so on so when it's available i can also provide it perfect and actually we can put that on our like workshop page after the fact because we're putting the videos and slides on the workshop page now so if you want to share that as well i think that would be awesome okay um okay so let me

share and let's go to just uh take a look at the at the circuit okay uh in uh circuits okay you will see uh well tester no uh yeah this is the circuit okay so um as i said we need uh we need the the switcher okay remember that the switcher is something that selects i mean takes like leaves the input and output uh not crossed or crosses depending on the selector okay then i need the pause addon which is a hash function and in

this other file we have the number two bits okay that we need to do the hash in the correct order let me check that i don't see you okay now so uh here we can see how the how we implement the merkle tree verifier level okay remember that it has a sibling the sibling is the value which i need to hash low this is the value that comes from the lower level okay selector selector uh will come from the from converting the key to bits okay and then the root which is the hash

okay of that this piece is performing okay so um and then uh we instantiate as uh albert was saying we create a switcher here how i instantiate a switcher from the silicone lip okay so just need to include here and then just creating the insulation then i then i create the hash okay and and then i connect the selector and uh maybe i can help with the picture remember that the selector

uh well i didn't draw it like very well but here the selector well in fact it's called switcher i instantiate a switcher and then i connect in this switcher i connect the low and the sibling i okay i connect these two and these two are what i need to hash okay so i'm i'm hashing one level okay and this comes from sibling i and the low uh and the low signal so in the switcher i

need to you know connect and the switcher inside has two signals okay if we take a look but um yeah it's not going to be here because it's in the isn't the silicone lip um [Music] i don't think i have it one minute i am going to i do npm install click on leap all the circuits are also npm package if you download this if you clone this ripple it it it has a package json with

all the of the javascript packages okay i didn't install them so let's okay so now now i have these another models here and inside we should have fiercom let me check item three uh circumlife okay we can go through leave we can go to circuits and then we can take a look at the switcher for example okay this switcher as you see it's just taken

left the inputs are a selector left and right i think that if the selector is zero it will not change this two values if selector is one it will change them if you see here these equations is what are saying okay so if selector is zero then aux is zero which means that output left is left because aux is zero okay if uh selector is one then we have left minus right so output here is right minus minus left so minus minus left so it's right okay so

output left is right and if you do the same if you plug here this it output left will be left okay so it's switching the is uh computing and verifying that we are switching the values okay so these are the uh i mean we are computing the value of output l and also forcing that the output should fulfill these equations the computing and forcing the that these equations uh fulfill it okay so in our example we need to connect the left and the right to the sibling

and to the low okay we need to this this value key here comes from the low and and the sibling okay so we will see this in the circuit okay so if we take a look at the uh the circuit where is it but building circuit with third circuits with circle mainly is most of the time may be connecting already done circuits in the circle name okay so this merkle 2 verifier is

like this okay so the selector that is an input of this big of this bigger circuit the mk this ver this verifier level where it receives the sibling and the low and the selector and the root okay it produces the root sorry but it receives these three okay i connect the sibling to the right uh input of the switcher and i connect the low to the left uh input of the switcher and then the selector to the selector on the switcher okay and this will produce

the the switcher remember that produces two outputs okay which are switcher out l left and switcher out right okay so now i use the position to do the hash okay i put i connect the hash okay i connect the hash function with the with the left with the switcher left and uh the other input of the hash function this position is of two values to the output right which will be in the correct order according to the key okay and uh i then i connect the output of this hash which is the hash value okay to the root which is the output of this box

okay so as you see uh building circuits is just it's a nice nice idea to make a picture okay and see what you need to connect okay uh it's just uh this this this picture maybe not so nice but i i promise i will do some pictures and provide you some you know some link with with a nicer pictures okay and now someone was i was asking and uh i don't understand the difference between you know this double and the four and the eaves and all this stuff okay well this is just uh i mean the loops the ifs all these all this uh

all these constructions are to create the final circuit okay in our case uh we are going to create a circuit okay and uh the the circuit is going to be a concatenation of these merkle two very fire levels okay so if i if i have three levels i need to i will create a verifier not from a level but to verify everything okay and i will provide three levels in this case okay and this is like the final circuit so it is receiving the key okay the value which is the secret key in our case the root which is the final root the

root of the the last level and an array of uh an array of siblings okay and now what i need to do well i need to instantiate this component okay number two bits okay with three so this is a box that converts any number to three bits okay so keys should be should be between two and three okay but if you provide something bigger but it will convert this to three bits so you can use bigger keys if you want but it will take only the less significant bits and and then uh i create an

array these levels will contain uh boxes like this okay verifier levels okay so this is a this is a component built with uh three three levels okay later i will assign uh each each uh each of these okay to this variable then uh i uh i need to do this is a technical minor thing but remember that i need to do i will provide the secret key remember and i need to do a hash of this secret key the first thing that i do is this

and then we need to do pairs of hashes okay because you are now in the tree but i need to do like a first hash okay so uh this is easy when you take a look if you understood what we are building uh so i'm instantiating here a position of just one value so this is to do a hash of one value okay this is the hash of the secret key okay we are going to do we are going to use this to create the hash of the secret key and uh then we connect the value remember that is our secret key to the input of this hash okay and

well this is going to be the first low value okay then we connect the key that we are receiving externally okay we connect it to the number uh two bits in a template that we instantiate here okay and to the input of this template okay so i'm connecting you know it's a little bit okay so is this part here okay the num to beat i'm connecting the key to this element here and this element here has here is in okay the input so i'm connecting the circuit is receiving a key and then i'm instantiating a num two

bits and inside this is called i in so i'm connecting things i'm doing i'm doing this wire here okay so this is the connection here and then this is a for loop okay and what is is creating is like uh putting all the i mean it's building the circuit it's putting all the integrated circuits we created this m verifier level and uh well essentially we are uh creating uh the circuit for the current level and then connecting uh the sibling of this verifier to the siblings i i mean this is from

the output this is from the inputs of the circuit i'm connecting this i'm connecting the selector okay as i said to the uh correct bit of the num2 bits output okay and then uh if we are in the first level okay we just need to i mean if we are in the in the first level then the the value that i need to hash comes from hashing the value okay hashing the secret key what i said so this is levels i low okay well i'm connecting this to the hash

if not well i am connecting [Music] the low i mean the root i i'm i'm doing this uh in in the reverse order as you see okay so i'm connecting from up to down so i'm connecting the level plus 1 root as yeah to that low of the current level okay and finally the last the the level zero is the is the final route okay uh

well that's it uh i think i have a nicer picture but again it's the same picture let me see in the readme okay here so it's just doing this okay level i and connecting siblings i and connecting the the root here to the low here and the selector comes from these and then it outputs a root okay and the four loop is just building this circuit okay just connecting more uh connecting circuits like very high level circuits small templates okay

um we're going a little bit fast here but uh hopefully you will take a look and we'll see that it's just connecting and then the for loop defines how to connect all these templates okay all this definition of small pieces and to finally build the big circuit okay uh finally when we have like everything built then we instantiate we just create another file in which well in fact we're going to test this so in the test circuit directory i create like a tester which is just an instantiation of the definitions that i make okay i'm going to create a merkle 2

verifier for three levels okay now you should install uh phil contester okay what is silicon tester it's another tool of the ecosystem three coptester will do all the things that i did manually to create i mean i compile the circuit manually and then i run the witness uh the program completely calculating the weakness okay i do all this manually but when you want to do a test this is a helper okay javascript helper to do all this stuff compile the circuit run the wasm or c plus plus

well i don't know if albert can take a look at job but all this stuff is already implemented in the circum tester to create tests with javascript so you just need to do npm installs in contester okay you will see it on the package.json of the project that we are providing okay and then we just built a text okay so how we do how we do the test okay um i need uh in in this case the wasm tester is just that i i'm going to compile the circuit and create and just create the wason uh the wasam uh wire calculator okay or

weightless calculator the program that computes the wires okay i'm going to use the wassum version okay then the position is implemented in in silicon lib.js remember gis are all these helpers built in javascript okay that are out are outside circuits but you need them okay to provide inputs to the circuit or check things okay then if i had more time but merkley's and get medical proof this is implemented in this function is just create the merkel tree and compute this array that i said that i mentioned at the beginning with all the values okay and get medical proof it will just

get the siblings this is to get the siblings and so we can plug them on the circuit okay and the field well all the elements that we are using are on the field f in this case so to make this uh this test we just uh create we just call this wasam tester providing the path to the to the file that i just created instantiating okay i instantiate what the circuit that i did okay so i just call this and this will compile the circuit as i did manually and go then and generate also the uh all the wires okay which is which are stored

here in the circuit okay well then to do the to do a test okay i just need to call numericalize we'll generate all these uh we will generate uh this uh vector that i said with all the values at the beginning we have the root then the value the hash values of the first level then the values of the second level and so on so here i'm i am making the hash making a miracle tree with these eight values okay so in this m it's just an array with all the hashes okay in the position zero we have the root okay so then i call this function if you take a look you will see that it

provides you an array with all the siblings okay and then then i call my circuit okay and remember which were the inputs of the of our circuit the key okay to do the hash shares in the right order the value which is in our example is our secret key and then the the root okay which i've completed here and the siblings and then i just i have this function here okay and then i execute calculate witness okay right now i'm executing the uh wasm program that i executed manually on the console i am executing this got this from this fieldcom tester

okay and essentially this test if everything goes okay this doesn't throw any exception if something goes wrong then you will have the test will fail okay uh and more or less that's it i mean uh yeah to recap a little bit i mean the ecosystem of tools that we have uh remember we have circum we have certainly in which we have already a lot of templates a lot of small circuits silcom essentially is a language to connect all these templates essentially okay then you need external things to provide the correct inputs and outputs okay and for this we

have silicon lib.js okay and then you need if you want to do automated tests you cannot do this compilation manually and we provide just sitcom tester which is also javascript package so you can you know you can execute i mean you can compile the the circuit and then run the witness uh that program that computes the witness and see if there is any problem and so on okay maybe we will complete this test a little bit more with you can also check signals and so on so um yeah what else just a small thing that i didn't say but

while we are compiling we can see the values of certain wires okay just in circum you can do lock okay uh okay um you ask someone is asking if there will be silicon leap rs uh well maybe in the future not right now but uh yeah all these programs that a lot in rust i mean yeah you can build this in in any language that you like uh probably not not in a in a we don't have it right now okay but um well i hope that i describe more or less all the tools i know that finally i

have to accelerate a little bit um and maybe the best thing is to take a look at this check and then if you have questions maybe uh i uh i really advise you to you can add to the item three telegram group okay we are very friendly there so i don't know where you want to say something else not really so not really um okay well i think that's it uh as i said i will try to write this down and and maybe publish in the next next few days um

and well that's a it was a pleasure and i hope you have a good time with zero knowledge which is really fascinating yeah thank you all thank you all for being here with us bye-bye thanks jose thanks albert thanks everyone for coming thank you so much and just again we're going to put this up on youtube so if you missed anything and now you have actually the document to be able to go through it yourself so this is pretty cool okay okay thank you see you soon see you next week everyone bye-bye bye bye