Zero Knowledge Proofs (zkSNARKs) are cryptographic protocols that allow one party (prover) to prove to another party (verifier) that they know a value without revealing any information beyond the fact that they know it. zkSNARKs are succinct (small proof size), non-interactive (single proof generation), and provide zero-knowledge guarantees. The implementation involves converting computational statements into arithmetic circuits over finite fields, where the prover demonstrates knowledge of private witness values that satisfy circuit constraints while keeping them hidden from the verifier. This technology enables privacy-preserving applications like anonymous reviews, confidential transactions, and scalable blockchain solutions such as zkRollups.
Zero Knowledge Proofs with zkSNARKs, Circom, and Snarkjs
Added:uh hello hi everyone hi saurabh hello this is uh founder and ceo of kryptonoku.com so today we have saurabh agarwal he is blockchain developer and an educator he is a gold medalist in computer science from indian institute of technology palakkad so he is going to you know conduct this workshop on zero knowledge so uh all the best sorrow and i hope you guys will learn a lot of things uh from this workshop so i'm handing out this workshop to you sorry please all right so hello everyone i hope that you are ready to gain zero knowledge today so zero knowledge proof what is it in cryptography a zero knowledge proof or zero knowledge protocol is a method by which one party which we will call as the prover can prove to another party the verifier that they know a value x without conveying any information apart from the fact that they know the value x so on a philosophical level they are part of a set of new cryptographic tools that show that transparency does not have to be in conflict with privacy let's look at some examples so that it is more clear for instance you all are viewing this session right here now suppose a student wants to give a review of an instructor say me but he or she wants to give it anonymously so with zk proves the student can't prove that he or she is indeed eligible to give a review basically the student belongs to the class and they can do that without revealing their actual name so anonymous reviews in a class student can give a review for instructor anonymously by proving that they are eligible to give reviews that a student belongs to that class without revealing their identity similarly let us look at this example kobe 19 test you can prove that you have recently tested negative for covet 19 without revealing the exact date you were tested or on which lab etc you only reveal that you were tested within a requested window of time at an officially recognized location nothing more similarly an exchange etc can prove that they're solvent basically they have more assets than their liabilities and they can do that without revealing anything about their assets besides the fact that it is it matches their liability similarly you can pay your taxes without revealing anything about your financial data so ck proves helps us enable write such decentralized applications also like let me first tell you a bit about these two types of zq proofs one is interactive and the other one is non-interactive in interactive we have to and through two and four communication between prover and verifier the verifier gives the challenge and approval gives back a response the verifier then again gives a challenge which can depend on the previously received response and then the proverb again gives her his response and so on until the verifier is convinced whether the proof is valid or or not i mean whether the approval indeed possess the required knowledge or not now we also have another type known as non-interactive and our focus will be on this type so what is this non-interactive approval gives a proof to a verifier which the verifier checks and let prover know whether it is valued or not so no further interaction just one thing prover gives a proof and verifier tells whether it is valid or not that's it so this is suitable in the sense that smart contract can act as a verifier to which approver gives a proof and receives back the response this is far better than having a smartphone track unit doing this to inflow to improve repeatedly many times between this proverb verifier this is far better and this is what is mainly used in this blockchain world moving on regarding the scope so we have this so somebody asked what privacy preserving technology do you think will be the most widely adopted consciously or unconsciously by the majority of nations in 2050. so vitalik replied i expect zika snacks to be a significant revolution as they permeate their mainstream world over the next a decade or two so to understand more about you know the relevance of zk proofs maybe you can try searching about these terms zk roll ups for scalability and you know we also have this tornado cache application for privacy you know zika rollups are considered as a perfect solution to this scalability problem and if i were to give you a you know a very high level idea about this zika roll up then zk roll up bundles the transaction and executes them off-chain it then generates a cryptographic proof known as zero knowledge proof for the hundreds of transaction it has settled off chain so prover is an option web service and then this proof gets submitted on the like layer one chain for validation and the verifier in this case will be an on-chain smart contract which will see whether it's valid or not so this is how you know zk roll ups work and therefore we can see that zq crypto enables one to do new things that weren't possible before dabs shouldn't be just about doing existing stuff better better will be that we can add some additional possibilities also if i were to give you like this zk roller what i have mentioned here is like a very very high level idea similarly for the tornado cache if i were to give you a just a high level idea will be user deposit funds suppose we have three players and all three are depositing same amount of fund the in the newer version of tornado cache the funds can be indeed arbitrary uh i heard that they are using something like utxo model there but for this simpler implementation the classic tornado cache uh or everyone is depositing the same amount of funds say one ether so three people have deposited all the this one ether vanitar vanitar so the pool has three iter now somebody comes and takes one ether from that pool we will not know the one who has taken the money from that pool which of the three participants the person is so with the help of zika snacks we are able to achieve this there are of course many other things there are relayers because the withdrawal will be calling the you know like the withdrawal function and then the withdrawal will require some gas etc so as to avoid that we have relayers also in tornado cache i mean there are other things so let us not go into that don't worry if you did not understand this tornado cache thing that's not the focus of this session now we will move to this zk snacks so let us first understand about this arithmetic circuits zk snacks permits proving computational statements but they cannot be applied to the computational problem directly the statement first needs to be converted into the right form specifically zk snarks require the computational statement to be modeled with an arithmetic circuit although it may not always be obvious how to do this conversion most computational problems we care about can easily be indeed converted into an arithmetic circuit and fb arithmetic circuit this is basically a field containing all the elements from 0 to p minus 1 i hope that you are familiar with this abstract or like modern algebra concepts of groups rings fields so if i go in introducing field here that would not be that will take so much time so if you are not familiar with fields i would suggest you to to look about them because they they are very essential in understanding the application part of zika snacks so an fp arithmetic circuit is a circuit consisting of set of wires that carry values from the field fp and connect them to addition and multiplication gates modulo p so i hope you are also familiar with this modular arithmetic so regarding this arithmetic circuit i will be going to this link now to show some other thing also okay i think it is visible so an arithmetic circuit over a field f and the set of variables x 1 to x n where of course these all are variables in that field f is a directed acyclic graph as follows every node in it within degree zero basically these leaves things this is called as an input gate and is labeled by either that variable name or a field element every other gate is labeled by either plus or multiplication since in the field which is uh you it's like some things i mean base structure is the ring and then the ring we have this group addition and this ring multiplication so that is these two binary composition operations is what is available in a field so in the first case it is a sum gate and in the second it is a product gate i mean this plus and this multiplication and arithmetic formula now this thing is not relevant but if you want to read an arithmetic formula is a circuit in which every gate has out degree one and so the underlying graph is a directed tree a circuit has two complexity measures basically this size one is what i will use later also so let us read that so has two complexity measures associated with it namely the size and depth the size of a circuit is the number of gates in it so all these input gates this and etc and the depth of the circuit is the length of the longest directed path in it for example the circuit in the figure has size six so one two three four five six right and the depth is two i hope that is clear this part is what i'm mainly interested to show regarding this polynomial so like the polynomial defined by the circuit an arithmetic circuit computes a polynomial in the following natural way an input gate computes the polynomial it is labeled by a sum gate we compute the sum of the polynomial computed by its children a gate u is a children is a child of v if the directed edge vu is in the basic graph theory a product gate who computes the product of the polynomials computed by its children consider the circuit in the figure for example the input gates computed from left to right this x1 x2 and 1 that is what we have x1 x2 and 1 the sum gates compute so this one is computing x 1 plus x 3 and this one is computing x 2 plus 1 right so they compute x 1 plus x 2 and x 2 plus 1 respectively and the product gate will compute the output of this plus gate which is x 1 plus x 2 and there it is having the another input so into x 2 and then another input is this x 2 plus 1 so this is the polynomial computed by this circuit in case anyone has any query you can raise a comment or interrupt in whatever way this software is allowing moving back to where we were we saw this arithmetic circuit thing so let's move on now regarding this magic you might be a bit curious that how is this magic possible so to give you a gist of it like an high level idea of how it is possible we have this homomorphic encryption right so so let's see that so suppose alice wants to add two secret numbers x and y where these x and y are belonging into in the set of natural numbers so when i say natural numbers i'm also including zero so z positive union zero equivalently in some fb like as such if they are in natural numbers i can have them contained in some fp for large enough p basically this prime field p right but she wants to add these two numbers but she lacks the corresponding computational power so what homomorphic encryption is allowing us she sends h of x and h of i to bob encrypted such that bob doesn't know private key to decrypt so here also assume that this edge is a good hash function basically one way and having strong collision resistance i hope you know this one way basically once you have computed h of x it is computationally sort of impossible to find the pre image x similarly strong collision resistance means it is computationally impossible to find two inputs x1 x2 such that their hash image is the same so bob after receiving h of x and h of 5 he has the computational power he does this h of x plus h of i and returns the result back to alice alice then decrypts this h of x plus h of i to get x plus y this is normally not seen but in case of homomorphic encryption it is preserving the addition that is h of x plus y equals to h of x plus h of i so this is the power of homomorphic encryption so suppose this was true for any arbitrary polynomial f defined by an arithmetic circuit that is h of f of x comma y equals to f of h of x comma h of y now suppose i have this problem given an output y which is belonging to this prime field and a function f defined by an arithmetic circuit proved the knowledge of a secret value of x such that f of x equals to y given that such a x exist right so i want you to think for a minute i want you to think for a minute how a solution to it can be fine so let's just wait for a minute we are 30 seconds in just 30 seconds remaining all right so minute is done so this is the solution verify being satisfied with the mathematical properties of h approval can reveal h of x not x prover can reveal h of x and perform all the computation like this f of you know this thing to get h of y now verifier can verify this whole computation starting from h of x everything this whole computation the verifier can verify and verify will check that indeed in the end you got that h of y equals to this the end result of this computation so this is the solution so sort of this is the magic of homomorphic encryption of how you know this zika snark proof is possible notice that here y was public and x was private this distinction will be explained next but you can very clearly see that this y was given so this y was public and x was the knowledge the prover has to prove of so so this x was private so moving on an arithmetic circuit takes some input signals perform computation and gives out output signals every other signal is an intermediate signal so the output of every addition and multiplication gate is considered as an intermediate signal if it is not an output signal so if i show you in that diagram of wikipedia that we saw let me move the here okay so here the output of this plus gate and this plus gate will be an intermediate signal and that final output of this whole circuit after this multiplication gate will be our output signal okay in circum so this is the language we will use to write circuits in circum all signals are by default private so first i want you to understand this clearly or like have this strongly ingrained that all signals are by default private and there is a restriction to which signals you are allowing to be public so let me tell about that restriction there is something known as main component fine just for now understand that there is something known as main component for this specific component this main component its output signals will be public fine so one thing which is public is the output signal of the main component second thing which can be public so output signals are public for the main component and some like input signal it is up to the circuit writer which of the input signals he or she is allowing as to be public so all output signals are public and input signals can be specified as public so you can specify which of the input signals you want as public rest all signals are private so all these intermediate signals and every other signal that all are private so i hope this part is clear we will see examples and then it will become more clear just give me one minute okay a signal being public implies that verify knows them so in case you are slightly confused what is the relevance of making a signal either private or public so a signal being public implies that verify knows them and in cases verify might set some of them so some of the public signals might be set by the verifier like in that case the y was set now prover has to prove knowledge of private signals so this is what we call as you know you could think of this as argument of knowledge such that these private signals so prover has to prove the knowledge of these private signals and these private signals along with public signals which i am going to denote by p for the rest of the slides so make that note that public signals i'm denoting by p they satisfy all the constraints of the circuit this constraints term i have not explained but while writing the circuit in this circum we specify the constraints suppose that this value has to be that etc so all these private signals along with the public signals they should satisfy the contains constraints of the circuit so what the prover will prove essentially that he knows some private signals that he or she or whatever entity knows the private signals such that those private signals along with public signals satisfy the constraints of the circuit it might be the case that are given cons that the constraint said the possible solutions for that constraint set might be multiple not just a single so the prover has to just prove that whatever the private signals the approver has along with those public signals the constraints are satisfied so that is the circuit satisfiability this set of signals these private signals plus public signals is what is called as witness and this witness i will denote as w so this witness is a secret right you don't want to leak your fitness because it has the your private signals which you don't want to reveal so now moving on to the constraints part so let us understand the constraints part circum allows one to specify quadratic constraints not you cannot write any constraint you have to specifically write only quadratic constraints between various signals so between various signals so let us see how is that so a quadratic constraint is of this form we have this pair of parentheses multiplied by some another pair of parentheses plus a third pair of parentheses so we have this s i all this s i which you can see here that forms the set of all signals of the circuit right all the public private all these input intermediate output whatever all the collection of those signals is what i'm denoting as this si set so to that s i i multiply any field element a i and of course i'm doing this summation from i equals to 1 to n for these n signals assuming there are n signals right multiplied by again this another linear expression this b i into s i so we have this another linear expression then plus some linear expression right so in case so for the quadratic expression i cannot have like this s1 into s2 into say again s2 so s1 into s2 into s2 this is not quadratic how can you put it in this form right you did s1 into s2 from here but how will you now do into s2 again right so that is not quadratic that that perhaps would be called cubic constraint so what we have is quadratic constraint of course these a i b i c i can be zero you can have all of these a i b i zeros so suppose the constraint s one plus s two equal to zero so that is a valid constraint now this set of all constraints describing the circuit is what is called as rank 1 constraint system so the terminology is this that the set of all constraints describing this circuit is called rank one constraint system now this is like the important part about zika snark so the full form of zika snake zero knowledge succint non this instant this s first of all stands for succinct n stands for non-interactive ar for the argument and k for knowledge so succinct non-interactive argument of knowledge so this argument system is a triple spv so for the succinct part is what i'm trying to explain in this slide so regarding this succinct plot part we have this triple spv right so to this s we give this the rank one constraint system and a random security parameter lambda this thing is called as random security parameter which i will explain later right and verify generates these lambda of course i mean it will become clear so to this s if i give these two things i get a provers key and a verifiers key so these two things again approval key and a verifier key now to this proverb if i give if the approver use this proving key and the witness so if the approver uses this proving key and the witness what the approver will get is a proof and what the succinct part implies that the size of this proof is asymptotically bounded this big o notation we have to the logarithmic of this size of the circuit so when we are using this mod symbol c what i mean is the size of the circuit and what is the size of the circuit is what we saw right i show you the i showed you the definition so this size of the circuit and this random security parameter so log is finished and then comma this size of the public inputs i mean size of sorry not public inputs i mean it is also called as public inputs but in our terminology it is public signals right so if i show you and these public signals right so the output signal of this main component can also be public so all the public signals input signa the public input signals and the output public output signals so all that is p and the size of that p is what is being talked off here and so i have told you that c denotes the size of the circuit and then we have this verifier which will take the verify verifier key and then it is going to take the public signals so here you see that it is not taking witness or private signals what the verifier is taking is public signals and in case of witness it is using pi the proof right so then the verify will tell whether this proof is valid or not i mean satisfied the circuits or not so either accept or reject and the succinct part besides this size of pi the succinct part also implies that the time the verifier takes to verify is asymptotically bounded this like this the size of p comma log of this right so this is the succinct part now if this spv is also zero knowledge that is we learn nothing about the private signals besides of course the fact that they satisfy the circuit along with those public signals then we say that it is zk snark so i hope with this you have gone you have received the you know the high level idea about zk snacks now there are different protocols which implement this snark so we will be working with growth 16.
in case of growth 16 the time complexity is as shown in the slide that the size of pi is this o 1 and comma this time complexity of this verifier to verify is we go one so this part is done now let me talk about this security parameter right i just briefly touched it in the previous slide so let us understand it more this lambda is considered as a toxic waste so let us see what what i mean by that the verifier after generating this random number must discard it so this lambda should not get leaked fine if the prover gains the knowledge of lambda then it can generate fake proofs pi which will get accepted even though the corresponding weakness won't satisfy the circuit constraints so this is the reason why we want this lambda to be hidden we don't want this lambda to be leaked out and because then the prover can generate fake proofs but uh you know if only one person is generating this lambda and then the person's responsibility is very high they all have to trust that specific person that he or she must have discarded this lambda so a remedy towards that is this multi-party computation what multi-party computation allows it allows that many players generate their own lambda and even if one of them successfully discards it then the protocol is safe so suppose v10 people are generating our lambdas the we can combine when we are doing this this part here the first part here we can combine all of our lambdas can be combined and it is required that at least one of us have discarded it so let me show you this you know this thing is also called as ceremony and let me show you this link which i mentioned in the slides okay yeah you can see that so this is that site which i am at ceremony.tornado.cash and you can see here tornado cash trusted setup ceremony the ceremony is completed thank you for your participation and all these people these 114 parties contributors so all they participated in generating that lambda and this was like open everyone was allowed to you know put up their contribution and we can see vitalik gavin etc have given their contribution to make tornado cash secure so with this open nature we can be sort of sure that at least one of these thousand or so participants must have discarded their lambda fine there is also this z cash ceremony you can look at in youtube for the z cash i think the participants were very less basically i think six but they you know elaborately documented it etc so you can see that on youtube zcash ceremony so so multi-party computation is allowing you know the safety here now regarding this circumstances tool chain you know this pipeline that we have to understand you know where does circumference and what is the you know use of snark js etc and do you know to get a broader the eagle eye view about what all tools and how we will work with them i have created this diagram which is you know this whole thing will be on github so github wrapper will be shared in the description somehow it will be shared and in that github repository in the presentation folder i have this file this slide will also be in that github folder fine so let me open this diagram which i created okay so yes you can see this diagram so we have this circum to that circum we will write a circuit right we will write our we will like we will of course write a high higher level description of the circuit we won't write we won't work in these little gates etcetera we will write a high level description of the circuit and circum will do the res if to the circum compiler i give this flag r1 cs then it will generate this rank one constraint system file r1 cs5 right and to this r1 cs you saw that we insert lambda right we insert lambda to get that proving key and the verifying key so what the smart people have done that for this part you know like there is if i were to say in this computation like this z key that we have this z key is that your you know your proving key and the verifying key though these both proving key and the verifying key is in this z key file right but to do everything from the scratch at least some part of it some part of it won't require that we call you know all the participants that hey everyone come do your contribution make a protocol secure for that some part we need not do and for this some part we can use the you know pre-generated file basically if i were to show you with the help of a diagram maybe so let me just open that software just a second i'm opening that software okay so let me just move to this window now okay here i told you that we need this lambda right so that we can make our protocol secure so this lambda thing so what the folks have done is that you know to this lambda part we can think of it is as in terms of two things we can say some private thing and one public thing so this is sensitive this private thing is what is sensitive and public thing is not when generating this lambda you can think of this lambda as this private thing in this protocol when we are generating you know we did this s which was taking the rank one constraint system and the lambda so that lambda you can think of as private thing once we have done this s of r1 cs comma this private thing lambda we are getting this some public thing right now another person another person will do this again this s of r 1 c s suppose this was lambda 1 then this lambda 2 to generate another public thing right and so on all these participants will do and this is combinable using multi-party computation somehow i have not explained how exactly that math works but somehow we are able to combine them and only if all of these lambda i's are leaked is when the you know protocol becomes unsafe but what that this diagram which i showed you earlier signified that for that particular phase this public thing was not dependent on this circuit folks are able to abstract some part of it out so that this public thing generated was not dependent on this circuit this r1cs so if i go back to where i was yeah here so to that file we take some previously generated ceremony file we feed it in our snap js and this we are using the growth 16 protocol fine so to the snark js which is a growth 16 protocol and it takes these two files to generate this this contains proven key and verifying key but here is where we must add contributions this is where we will have you know contributions like this so this is called phase 2 contributions this is where we will you know need help to make from other people so that we are trustable and then we will get our final z key so this is what will con which will contain our you know the private key and this verifying key here if you want you know separately export the verifying key snark just provides that feature so to the z key to export the verification key you can do that we will you know when we will write the code so at that time it will become clear so we get this verification key so this part uh i will explain first let us also see this wasm file this web assembly file right this is used to you know generate our witness so how do we generate the witness in the circuit suppose this circuit if i know the set of inputs that i am giving to the circuit so so here x1 x2 and 1 once i know once i provide the set of inputs here then all the intermediate signals the output of this plus gate this plus gate and you know the final output signal that is known to me right so once i give the set of input signals i will know the intermediate signals and the output signal so if i go back to where i was yes here so to this web assembly file generated by circuit we circum we give this input file so only inputs to the circuit need to be given intermediate signals and outputs will be computed so we will have this you know generate witness file it will this will you know generate i mean uh sorry i just missed one thing when we are using this wasm flag wasm flag will also generate this generate witness file snark just also has a feature where this generate witness file i mean we need not basically use this generate witness file the snark just also gives that functionality but the main use of this vasam flag is not this generate witness file the main use of this wasn't flag is this circuit dot vessel to get this circuit.versum file now to this and when we use this wasm flag it will also generate this file generate witness but as i told you uh even if it was not generating this generate witness file there was another way also but let us not bother about that another way so to this generate witness file i will give my inputs to the circuit and the circuit.vasim file and then it will generate this witness right so you can think of this versus like computational trace so it will do the computational sector to get this witness but this is not what we want to reveal we want to reveal the proof right so from this z key containing we will take this witness file also if i showed you show you back the slides part let me go back there you can see here that the approver was taking that proving key and the witness right so that is what we were doing we are doing here so let me go back okay here so from this z key we will take the proving key basically instead of you know extracting the private key this whole z key file is inserted in case of circum it's not just tool chain so we insert this z key and we use snark js with this growth 16 parameter and of course this proof parameter to generate the proof it takes this command will take two inputs the witness file and the proving key in case here we are providing this you know combination of proving in the verifying key and then it will generate two outputs one is this proof dot json which is what we need actually this public json is you know the [Music] public signals so public inputs and you know the output of that main component and the public input of that main component but this public json is not that relevant for us even if it was not generating it was fine what is mainly needed is the proof.json file now you have seen how that verifier verifies so the verify verifier needs the verification key so that is what we will provide by the way this yeah i have told already that this diagram is also in that github so you can see it later also so the verifier will take the verification key it will take the proof and it would also take the public signals just like what i told in theory so we will provide all these and we will use you know this command snark just growth 16 verify to get the verification result so it will let us know whether the proof was valid or not whether proof was valid or not so also where did we use the you know smart contract here so to for to generate that smart contract thing you know we from this z key file we exported the verification key we can also export the verifier contract so using this command snapchat z key export solidity verify giving the input as this z key we will get the verifier dot soul file now since we can instead give inputs to this verify.sol file here this proof.json and the public.json first of all we will you know of course need to encode them in a suitable way i mean this is just a helper utility function you can of course do it yourself if you're smart enough but this is the helpful utility function so snark js z key exports already called data it will present them using these two files it will generate the like output of this command will be the suitable input parameters that we can pass to this verify dot sold file and then this will return a boolean telling true or false whether the proof was valid or not so this is what i wanted to cover in the theory part we will see further as we will write our application so in these slides we were here we saw this and then now we will do you know the hands-on we will start i will explain you know the circum part next so so let's do that but first let's also take a you know five minute break so that everyone is at ease so let us take five minute break break and i will be back after that hey so you you okay hmm okay okay so the five minutes are done if we move on what i want you to do is first install this circum thing so navigate to this link this docs dot circum dot io getting started installation basically visit this docs dot circum. and from then on it will be easy to navigate you know this getting started and the first section first section is this installation so to install what i did basically you know first they have mentioned very simple way of installing so first use this command to have you know the rest available in your system so this they are mentioning that it is for linux or mac os so for the windows you will have to see how to do it mine is mac os so it worked very easily for me we need to install rust because the circum compiler is written in rust this is sort of irrelevant but even otherwise if you are having the you know the version less than 10 so kindly update it because there they require the updated version once you have this done use this to install i mean first of all of course clone their repository then enter the circum directory and use the cargo build to compile like that now this will take around three minutes so let it happen i will just explain the theory part of the circum so let it take the three minutes which it wants to take when the command successfully finishes it generates the circum binary in this directory target forward slash release you can install then this binary as follows fine the previous command will install the circum binary in this directory and then the circum part should be done so what i'll do i just pause here for 30 seconds for you to you know just navigate here and have it all set up so i just pause here for 30 seconds and then we will be back hey so i hope that you are at least able to reach at this command which is taking around three minutes to complete so let us start with a simple circum circuit here here is my terminal so what i'm going to do i'm going to just create a directory named backend and i'm going to move into this directory now i'm just going to initialize the hardhat environment here it is not at all required but i just basically we will need some npm packages and i don't want to work with you know empty npm any type of thing so i'm just initializing it here using you can use this command this npx hardhead in case that hardhat won't be installed then it will install it so not an issue there so i'm gonna hit enter to all this and wait for it to get completed we will also be using a plugin known as hard hat circo basically as you will see in this session that when generating all this z key wasn't etc it is quite cumbersome and for the development phase we would like to have it automated so this is where that hard hat circum plugin comes in picture there are other helpful tools also which the people have released you can look into you can just search about it but for this session we will be using hardhead circum plugin of the hardhat but yeah but for the initial part we will reach that z key stuff without using that plugin so as such hardhat is not needed but let's have it installed so this is done what i will want you to install next use this npm install circumlab fine i want you to have this also installed so this part is done so let us create a directory named with circuits right so let us create a directory named circuits let's move into that directory let's create a file named multiplier dot circum this example i will take straight from the documentation it's a very simple example and we will be able to understand the basic syntax of the circum using this example right so i'm just going to you know open this file now actually instead of opening that single file let me open this whole directory the visual studio code and then i can just move into that directory here so this is the directory in which we are so for this uh what is this lock dot soul oh wait where is my circuit folder yeah this is my circuits folder i think hard hat uh upgraded their initially first for before it used to be some other contract anyways let us not go into that so to this i'm going to now paste a code which we will try to understand here just give me one second okay this is the code first line if you notice pragma circum 2.0.0 what we are doing here as per my understanding that we are explicitly specifying the compiler version basically with what compiler of this circum we should compile this file so you would have downloaded the latest version basically when you are downloading installing this circum compiler that compiler is like a set it doesn't have just the ability to compile with version 2.0.5 it is also able to compile with 2.0.4 2.0.3 and so on and also 2.0.0 so when i'm compiling this file using that circom how do you compile if i show you just give me one second okay here so you can just mention after this circum the file name right but if you do just like that it will just tell you that circuit is compilable fine you will also i mean when the and no file will be generated if i show you we just have our initial file so what you can do you can specify what you want r1 ss and this wasn't thing right so now if i see those two things have been generated one is this r1cs and the other is this js file and if i show you what is the version we are using 2.0.5 and i believe i compiled that file yes i also checked that i compiled that file using version 2.0.0 so even though when i'm doing this circle minus which is showing that it is 2.0.5 but the way you should see is that it is actually having the support to compile a file using version 2.0.0 2.0.1 so on and also this 2.0.5 so to that file if i change like if i also show you to that file if i make this 2.0.5 and now if i compile here it has successfully compiled now let me also change it and make it 2.0.6 let me just quickly show you that i have indeed made it 2.0.6 as you can see here i have indeed made it 2.0.6 and now let me try to compile it then you can see that version 206 is not supported by the compiler which you are using so i hope that clarifies the pragma statement here so let's move back okay now this is the line which i want you to pay attention is this this is the main component this is where you know like we can have another templates some whatever i mean there could be multiple templates in the program you can think of these you know as sort of like a like a composable block structure so you can use the template now here this could be you know another like we can multiply three elements here so let me create an intermediate signal and i will name that signal as enter so to this enter i will explain what this means shortly so don't worry about that and yeah okay i mean we can create multiple templates and then at the main we are specifying that we are using this template and when we these composable structures such that this multiplier 3 could indeed use this multiply 2 as a component fine but let me not do that in this example let us focus here in this code fine to this main we are instantiating this multiplier two thing so this is that multiplier two thing it is having this input signal a notice how we specify the input signal we first of all specify the it is a signal signal is immutable once this a has received value you cannot change it there is something known as war so in case you want mutable things you should use war signal signals are immutable we specify whether they are input or output and in case we don't use this keyword either input or output then it would be an intermediate signal so here like i have this intermediate signal which i have named as enter fine there is just one thing which i want to do give me one second yeah okay i wanted to you know pull up that youtube window also fine now in this multiplier to circuit if you look we are giving it two inputs and we have this output c as such this output will be private but since the main component is using this as a template this signal c would be public right all outputs will be public now when you are writing the circuit in circom you should think that you are writing two separate things and this distinction basically the constraints part is something which you would you should pay strong attention towards fine like constraint now if i tell you the constraint this is a constraint i type the c followed by these three equal symbol and then this a star b right i just commented this last line how do you put comments you use these two forward slashes fine use these two forward slashes to write a comment you know if you want multi-line this was the single line comment if you want the multi-line components then use this sentence this is just like in c or c plus plus also in case you are familiar with that language fine now this is the constraint here what i am specifying that the value of this signal c should be a star b fine now i would also like to in this circuit for instance in this circuit i would also like to you know assign a value towards c which will be using this basically you do this c this less than symbol and then these two dashes and then you do this a star b so in this line seven i am assigning to c this value a star b and then here i am constraining i'm putting this constraint that c should be equals to a star b and instead of writing these two lines circum provides us the ability to write them together using this less than and then two equals like this using these these two lines are combined into a single statement and it is also advised that we should use this as as far as possible i mean as much as possible instead of i mean this this part should be avoided this single dash part should be avoided but sometimes it is also necessary like but uh that thing i will show you when we will see the is zero template i will i plan to show that is zero template also to you so that is something which we will see there okay now uh regarding this input signals also as the circuit it is now these input signals are private but you can make them public like if i show you how when you are instantiating your component you can do this in this curly braces you can use this public keyword and then specify which of the input signals are public so if i do a comma b in this case these like all the signals will become public i have mentioned that a is public b is to be treated as public and c is also public c is public by default you know for the main component output signals are by default public i can leave it like that and specify that only a signal is public so in this case the verifier suppose that the verifier takes one of the input parameter a and of course verify this c is also public so suppose it also takes c suppose the verifier puts c to be 33 and a to b 11 okay c 33 a 11. since these are public verify i can put them the prover will have to prove that the prover knows a signal b such that a star b is equals to c notice that i mean this constraint part is very important here using this constraint i mean when we do this this c assigning value a star b this is you know has been done like you can think of it like that that prover is able to you know generate the witness but anyone can write their own circuits and in that circuit they might do c assigned something else but what will save us will be this constraint here that c is indeed constrained to be a star b this part basically what matters to the verifier ultimately is the constraints like if i go back to our diagram maybe it's better to you know emphasize this so that it becomes more clear give me one second okay here yeah here you see for the verifier verifier knows the public signals and it does not take any other signal what it is taking as the proof what verifier wants that whatever proof you give those constraints which we have satisfied uh which we have specified gets satisfied so basically the constraint satisfaction is important right the assignment part is not that important in the sense that you know approver prover can write some another circuit where it is assigning something else we are not bothered with that verified has the verification key using this constraint system which it got right so we are saved there so what matters to us ultimately is the constraints those assignment helps in generating you know these computational traits the web assembly and then which helps us to give this witness fine so the constraint part is what is you know at most important so let me also go back to my code window yeah here fine now in case i remove this the part which i had and now only the output signal is public so if the verifier sets the output signal as a 33 then the approver will have to prove that it has two input signals a comma b such that the constraint that c is assigned equals to 8 star b satisfied basically that 33 should indeed be this a into b fine that is the you know what this circuit will specify now you remember we did this command npm install this circumlib right now if i go to this node modules we would have that circle blade here here circuits and i think comparators right we have this is 0 template so let us now try to understand this 0 template so let me also create a file so i'm just creating that file okay it's created here and i'm going to you know copy this code here one thing which i would like you to notice is that all these templates the styling is such that the first letter is capital so in case they have here they have put the first letter as capital fine so and so it's the instance of this is zero so what this is doing maybe i should put this comment here out signal is set to one in case input signal in is zero and is set to 0 otherwise right so in case this input signal is 0 what i want fine what the verifier wants that the output signal should be 1 and in case this input signal is positive and it of course in that field that zp field what we want this output to be set to zero now when writing these circuits i want you to forget about this thing this part and this part i want you to forget about this part but focus on this the constraint thing fine now for this you can see that output is either 0 or 1 fine so one of the constraint could be this that out minus one and this out is constrained to be zero one of this constraint can be this because the only way this equality is satisfied is when either this part is 0 this vector which will imply out is 0 or when this factor is 0 which will imply out to be 1 so this is the one of the constraint which you can think and what are the other constraints which you can think you will notice that they have not used this constraint in this example because this was redundant this was not needed we have only these two constraints here this line number 12 and this line number 13 and in this line number 12 we have one constraint and this line number 13 we have another constraint this constraint is not used here but you will see such constraints in practice but for this example this was not needed but this is also one of the way but this will just give us one help that output is constrained to be either zero or one we need one more thing we need the logic like i mean we need the constraint that it is not the case you know we should not have both input and output to be zero that should not be possible if input is zero output must be one and in case out i mean in in case you know the input is some positive the output should be zero fine so how they are doing it so let me show you like their logic and this will make sense also then we have this inverse thing inverse signal is this is an intermediate signal defined here notice that they are doing this ternary operator here fine now if ternary operator is possible you might think that we can you know simply do this that in if you know whatever like it's equal to zero you put one otherwise you put zero fine you will you think that you might think that this is part possible that if ternary operator is allowed well the fact is the constraints have to be quadratic expression and this ternary operator is not a quadratic expression first of all yeah i mean that was also fine so this is not allowed so that is why they are using this single arrow not double arrow because double arrow will imply the presence of constraint as well and we cannot put a ternary expression in a constraint fine so that possibility is ruled out and that is why they have single arrows here now what is this one by in basically this is of course the modulo inverse and i think maybe i should spend some time very little time to explain a bit about this modulo i mean as such this is something prerequisite but let me just tell you a like a small example consider this field z p sorry let's make it let's make p to be 7 so that we don't have much elements to bother with so this will be this 0 1 2 3 4 5 6 right every addition you do you will do modulo 7 so 6 plus 1 will be 7 which is equals to you know 0 when we are doing this modulo 7 fine now what i want you to do is find the inverse of 2 so what is the inverse of 2 inverse of 2 is an element x such that when you multiply that element with 2 you get 1 modulo 7.
so can you find any element here such that if you multiply 2 with that element you will get 1 modulus 7 so that element is 4 here so 4 into 2 is 8 and 8 mod 7 is indeed 1 so this x is four in case you know since we are working with prime fields an efficient way to find a modular inverse is this you do to the power you know p minus two modulo p so in this case you know 2 to the power 7 minus 2 5 mod 7 we have to do this is equals to 32 mod 7 and you know 28 plus 4 so this is 4 mod 7. so same value this is called as you can just google if you want formats little theorem and in case you want a revision about what is a field field is a community ring with unity such that every non-zero element is a unit basically has an inverse so i know this was a mouthful i was just trying to you know give a small gist of what is field in case somebody have you know nave idea at least have studied modern algebra in past so i mean that's fine you may not know that so you can just google that so this is the modulo i mean this is the inverse of 2 in this example moving back towards our code so what this 1 by n is doing or for that matter wait a second and for that matter any expression like this a by b what this is this is you know equivalent to a star inverse of b this is what it is so in in our case suppose i mean i hope like 1 by 2 in our case will be 4 because that is the inverse of 2 in 7 prime field 7 but here you know the prime is something very big it's a 254 bit big number you can see that i i might show you also so i think it's called baby jab jab prime so fine okay so here we saw that because of this ternary thing we cannot use this double arrow so they have this inverse specified here but as i told you this single arrow means nothing this single arrow is helpful in generating witness this all this vasaar etc but for us for the verifier it would mean nothing what would mean for the verifier is this that for the out what they have done they have multiplied this number with its inverse so that it will become one any for of course the inverse exists for the non-zero element so for the nonzero element the inverses exist and when they are multiplying with it that inverse so i mean assume for now that n is non-zero so multiply with its inverse you will get 1 so minus 1 plus 1 you will get as 0 that is what they have assigned to the out but as i told you this inverse can be anything for the verifier i mean anyone can write circuits so this inverse can be anything what we have is just these two constraints now let us brainstorm and think that just by having these two constraints what we want will be satisfied what we want that out signal is set to one when input is zero and no i mean like our signal is one when input is zero and out signal is zero otherwise so let us do that suppose that input is zero then output should be one suppose input is zero now if input is zero this whatever with the value of inverse let me not bother about it since in i n is 0 0 into anything will become 0 so this expression will become 0 and out would ins indeed be 1 that this constraint will as such like also make out to be you know equally equal 1.
fine so that this constraint is satisfied only when out i mean this will indeed this constraint in itself will imply out is 1 and this thing if we do 0 into out which is 1 that is again 0 so that constraint is satisfied so let us now think of other possible scenarios what this scenario gave is out to be one now you know when out is one one one like if out is one now if we look at the you know the converse the reverse way so if out is one this is also one so this entity will become you know zero the constraint as such will specify that this entity is zero and this constraint here wants that one of them to be zero and what i told you was if i remember correct i think i told you out is 1 right so out is 1 so what we will have that n to be 0 fine now let us look at for the case suppose n is 3 for whatever some positive number of course less than that less than equal to that baby egyptian prime i mean of course less than that prime because model of that prime you will get 0 now that n is positive and we have these two constraints this constraint will of course then imply that out has to be 0.
so with the help of this constraint itself that out will become zero so what we will have that zero minus in into something plus one so this will also imply that inverse is indeed the inverse of this i n signal so i hope this part is clear one thing more that i would like to add here that it won't be possible you know also like one thing here i did not explain this ternary right so what this ternary is doing that if this is non-zero basically some positive number you find the inverse fine and in case it is zero you set the inverse to be 0 so 0 into 0 will be 0 and then this 1 will get assigned 2 out i mean this part is as such not needed but they had to put something here i mean in the case when n was equal to 0 so that is why we have this case one more thing which i would like to add here is that you know if we do something like this i mean forget the context here that we are in this is 0 but for the general thing if we have this constraint like that and this won't be valid this is not valid as as it is not quadratic so instead of writing this what you can write is this this thing which i'm going to show you now that in star in is constrained to be one so these are the cases in where you will need to use you know the single arrow because via single arrow you can first do this and then using that triple equal symbol you can you do that this n star in equals one of course i mean for this simple example we could have yeah no sorry sorry not for this example so this is indeed what you would have to do because when you're using this assignment operator you use this for a signal so here this inverse is the signal which we are putting this assignment operator to you don't put any expression here but instead you put a signal here so to this signal i am assigning this 1 by inverse and then i can do this inverse star in equals 1. so that is how you can you know put up a constraint and this is the example where you will need to use the single arrow fine also this exists i mean uh we could have as as well you know did this so this holds in also valid i mean this can be reversed that is what the circum is allowing us circum also allows this thing this operator to be reversed so just uh these conveniences the circum is providing us somehow space got here fine so these are the two circuits i wanted you to see also let me see whether there is one more thing which i would like to cover or not also the documentation which is present in the circum website that is very very small i mean i believe that you can finish that documentation in less than an hour personally it took me less than an hour to finish this documentation i mean after covering you know the basics here which we have done seeing the documentation will become very easy it will be a breeze so let me just see whether do i have one more example i thought i had one more like as in homework which you guys can see yeah i found it so i'm just going to put that here so this is the circuit which i would want you to you know take up as in homework to understand the working of this circuit but if i were to give you you know adjust about it first of all this template is taking this input parameter and this input parameter has to be a compiled time constant so here we have specified in this file itself as three so the sign is three basically the the point here is to get the bit representation of this input signal provided that input signal is you know um it should be yeah less than equal to seven provided this input signal is less than equal to seven to fit in the three bit binary they have this wars here so war is mutable you can change the value of o you cannot change the value of signal once you have assigned it so we have this for loop here just like in other languages also i find it funny the way they are writing you know their code if you look at it there is a white space here i mean but you don't see white space here so they are not consistent also after this subtraction operation you have this one but otherwise they are using white space and this inconsistencies not in just you know this documentation example in the actual code i have seen when i was going through i could see you know such inconsistencies so i wonder why is that the case all right so so this war thing is there now they are having you know a non-quadratic expression so they are doing this here they are using that trick which i showed you to constrain that that output bit should be either zero one so this is what they this thing will constraint and then ultimately what they are putting is that the final value basically what they are doing that once they have this output bit multiplying with the corresponding power of two first of all this starts with one and then you know to the power 0 is 1.
so that is why 1 here and then 1 plus 1 is 2 so then e2 will become 2 and then the third iteration 2 plus 2 4 so it will become 4 like that so a cheap way i mean from cheap i mean the computationally easier way and also we are using e2 again so this is a very smart move here so that is what they are doing so once they have this lc1 computed in the last they are mentioning this constraint that lc1 should be indeed equal to this ion so end up they are also using arrays here this out is an array and when instantiating this component they are specifying the public signal as in so this is the example which i want you to you know explore further i mean yeah i have a as such i think i explained it fully so this is the example i wanted you to have you know clear understanding of okay so let us go back to our multiplier example yeah here so let us go back to this multiplier example let me fix few things so the setup is as i've told you this c will be the public signal and we have to find the factors so suppose that's this is from the documentation so suppose i fix c to be 33 the approver must prove that it has two factors a comma b such that their product is equal to 33 that a could be one and b could be 33 so i mean as such this is a very easy problem for the prover i mean not but i mean it's a very simple example not that relevant in practice but we just i want to show you the compilation part of it so let me go back to the terminal here okay so this command i showed you right so this circum multiplied i mean the file name and then we want these both files we want to generate the witness so wasm and we also want to generate the keys proving key verifying key so that rank one constraint system so i have generated that okay so let us generate the witness first so i'm going to go to this multiplier file so we have this generate witness and this multiplier.wasm so let us use them i'm going to put up the commands and you can see what are those commands when i'm putting them in the terminal let me also go there also let me just show that here basically in that circum website in the getting started you can see all these commands also so in that getting started page these commands are also mentioned there so just give me one second here first of all to generate the witness i told you that we need to give the inputs to the circuit so let me do that so let us name it multiplier.input.json it has to be a json file and if i go back to my visual studio code and open that file i'll just show you that file after putting the values okay so i created this multiplier.input.json file to that json file i'm i've specified my inputs so a is to be three here this is to be three and b is to be eleven so that the output is indeed 33 fine let us now move on to our next step next step will be this which i am mentioned here so we will use this generate witness file giving it our multiplier that thing and then this is this and the output i'm going to name it multiplier dot witness so so finally we have our witness file that we wanted also we use we use this javascript file right generate witness the we also get provided with the c plus file which you can use in case you you have a very big circuit so for the you know big circuits that would be computationally cheap so that can be used in case you have the big circuits you will have to use the compilation like just how we use you know wasm you will need to use the compilation flag dash dash c to get the c plus file so now if i go back to that pipeline diagram here we did this thing we generated our circuit file so we have reached this point so now let us use this r1 cs thing and to use that if you go here github.com forward slash id3 the one who are maintaining it and have created this knock jails so in that snapchats they have all these you know steps which you can follow one thing which i would like to say that here we will use a p tau file right find this is what we are going to use so either you can download a file or you can just use this command to have that file for you now they are specifying this contribution so in case you want to add robustness to this add more contributions you can do this i personally don't think it to be necessary then they have this command verified to verify that everything is going fine and this is something which i would like to spend some time on this random beacon now what is the case that the ones who have written the research paper about this random beacon according to them what they are saying that it was easy to prove the security of the protocol if you provide the random beacon but they're also saying that most likely the security will hold even if this was not provided but they did not have time to prove it that is their statement if you will read the research paper so as such it is safe to apply the random beacon so what is this random beacon the understanding what i have of this random beacon basically some value which is not known before compu when doing all these things that random value can be say a block hash at a particular date i mean bitcoin block header hash at a particular date so you can use that at a particular date but the issue with that is that it has a bit less entropy what i mean because of the high difficulty in mining you know that the first bits the first few bits of that bitcoin header will be zero i mean this is what the mining difficulty is all about the nonce thing you can just search about it in case you don't know so the first few bits will be zero and then the entropy therefore basically that randomness you can say will be in those remaining bits only the remaining bits which need not be zero so that is why that perhaps is not the good example to take that header as a bitcoin header but what i i think the zcash folks took bitcoin block header when in their own implementation also there is this verifiable delayed functions basically suppose you are a miner and somehow and the protocol thing is that in case the block hash is even you will get the reward right suppose the smart contract whatever is implemented like that that in case the block hash is even then you will get the reward so now once you have mined the block if you see that it is even oh sorry if you see that it is odd then you can discard it right as a miner you can discard it you know that at this block hash the winner will get the i mean i will get the reward if the block hash is even so in case it is odd you might discard it and try to have it to try to mine the other block now a way to circumvent it is that this value which the miner was using as such if you use the blunt block hash header then the miner can easily see whether it's even or not why not have it a further computation basically the miner will try to do the more computation towards it so that it takes reasonably more time than 10 minutes in bitcoin protocol you know every block is produced i mean a block is produced every 10 minutes so if case that computation takes reasonably more than 10 minutes then this thing will get you know somewhat hampered some more thought need to be given in it and you can give that thought but this is the understanding you know which i have of this random beacon so now let us just quickly do all these commands here right so i'm just going to move that multiply dot witness file words outside so so that my file is outside oh wait sorry i just forgot to set the focus to the terminal here so outside my this multiply.js folder i have put this multiply dot witness file right so now i'm going to put this command this thing is done and i mean we did that now then contribute second contribution third contribution verify random beacon all this is not as such needed but i mean you can read the description of this command in that file they have mentioned the description of what a particular command is doing right so this sorry yeah i mean i'm not being you know giving it actual random thing here so now we have this command for the phase two thing to make it ready for the phase 2 so i have pasted that command here and it's taking some time to compute it taking quite good amount of time all these commands are from that repository which i just showed you so you can just have a look at it and use those commands from there and also read their descriptions from there tomorrow we will use hard hat circum plugin so that we won't be it won't i mean these all these commands we will need not write this all will get automated so that's the cool thing about it so what was the command which i inserted this one right preparing it for phase two fine if i move next to what it is providing me we have all these things circuit compile circuit that all we have done witness we have done then beacon is what i had and when did i when did they make it finals let me see okay in this file itself so i have this bot final right like if i look i did put that prepare for phase two right but somehow it is not showing me okay it is now showing yeah so i did put that prepared thing so fine that part is fine next they have this setup now we have these two algorithms if you look at that page we have two algorithms one is growth and one is this [Music] uh this plonk ping planck is a bit more suitable in the sense that it does not require require that phase two contributions but in our case let us go with growth 16 and it needs this r1.cs file so did i have this here r1cs yes i do so i can use this just need to make it like that so that part is done so hopefully let's finish it then they have this contributions so i'm not going to do that here then they also have this random beacon so let me just do that random beacon thing here okay so that random beacon thing is done now let us do this verification of i mean this export exporting the verification key so what did i name it circuit final yeah the command named its circuit final so let us use that that name only circuit final now let us quickly create the proof from that documentation itself they are mentioning that proof thing so i think i named it this it will generate these two files proof.json and public.json so if i show you that group.json which is what we will send we have this and that public should contain 33 as such it was not required but they have done it so now let us verify this proof right the ultimate thing which we were waiting for so to this proof we very we put past the verification key the public inputs i mean that sorry public signals should be the better word and then this proof so let us hit enter and it is giving us okay so yes the proof was indeed valid now if you do some slight changes in the proof you will see that it it won't get passed so that is all what i wanted to cover today so congrats in making this far tomorrow is when we will do the smart contract part so i haven't done smart contract part here that is for the tomorrow session so thanks for joining in and this is where i will end this session ah thank you sarah and thank you everyone who have you know joined the session and you know supported i know this is this was longer one but yeah like this will help you understand zero knowledge second and all so thank you everyone and thank you saurabh uh we'll meet tomorrow at the same time like 3 p.m ok yeah see you then bye
Up Next

Tornado Cash Deep Dive: Smart Contract Analysis & Code Walkthrough
@themandalore9
1.4K views•2022-08-23

Torrent File Format & Bencoding: A Technical Deep Dive
@AsliEngineering
12.5K views•2022-08-08

Operational Security Essentials: A Guide for Hacktivists (OPSEC)
@hitbsecconf
157.4K views•2012-11-26

Understanding Ethereum: A Comprehensive Beginner's Overview
@99Bitcoins
3.1M views•2018-06-26
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Blockchain & Crypto






































