 Hello, everybody. Welcome to the last day of the Merrill Village. If you are just wondering here, you are at just in time for a talk by the world famous Cappy, you know, who is going to give us a deep dive into both rivers. Now, if you are a swimmer, you may be familiar with diving deep. Diving into mathematics is a lot, it's a lot different. And you come out just as exhausted, but it's a different form of exhaustion. So Cappy here is going to very gently, gently take us for cool cruise. And I hope you all come out the other side smarter, because all of us is going to go online. Cappy, please, please be gentle. Oh, this is my lapel. Hi, I'm Cappy. First of course in Russ, both at Chain & Interstellar. And we have a fastest implementation in existence, and so I can cover and what I want to hear. So what I submitted to this talk was, let's like go really deep into the math of bulletproofs. We can do that. We can also like do less of that and talk more about things we've built on top of bulletproofs. What other people can use it for, maybe the proposals of like what Monero might be able to do. So maybe by show of hands, how many people are here because they really want to just like get things in the math afterwards. And have them sort of talk about other exceptions over that. Awesome. So we should talk about what we hear about zero knowledge proofs. So for some of you this might be redundant, but I'll just cover some basic ground first. So zero knowledge proof is a way to make a proof about, sorry, a proof that statement is true about some input without revealing what that input is. So that might be a little confusing and abstract. One example of zero knowledge proof is a range proof. So a range proof is a proof that a certain number is in a range, usually like zero to two to the n. And you can show that this proof is true without revealing what your number is. So if it doesn't reveal your number, you make a commitment to that number and that commitment is binding, hiding, and you can show that commitment to someone without revealing your secret. So we'll talk a little bit more about range proofs, actually a lot more about range proofs, so don't be too intimidated yet. So probably a lot, and the importance sum to the number that's taken to your outputs. So here, you know, usually check five plus four equals two plus six, you're not making any extra money out of an error. And if you wanted to make this confidential, there's many ways to do this, but one is just called confidential transaction proposed for Bitcoin, and a broken way to do this would be to use an additively homomorphic commitment and just say, well now we're just going to do A, C and D, so we're blinding and hiding for our secret values. And then you just check that A plus B equals C plus D. And this will be true with very high probability if and only if your interior secret values actually sum up to the same value. Now can anyone tell me what's broken? Anyone? What's that? Yes, commitment scheme, but that's like such small probabilities that that's actually like not something that we're going to worry about. What about you? Exactly, yeah. A negative number, this also still works. And so financial transaction. So we don't want this to be possible. And for those of you who want to understand the math better, it's actually a negative number mod P, so what this is basically equivalent to is an extremely large number in your current order group. And so those two statements are equivalent. So you could be allowing someone to spend negative $1 or you can be allowing them to spend like P minus 1 where P is very large. So that's just to be technically correct here. So what we want to do is to insert a proof, a range proof that all your secret values are in a certain range. So as long as your range proof is from zero to a number that's still smaller than your primary group P, then this will make sure that you don't add any like negative, weird numbers. So in the blockchain context, obviously there's many other ways to use them, and there's also many ways to use your knowledge proofs outside of blockchains too, but you're probably interested in the blockchain applications. And what do we care about bullet proofs? So bullet proofs is a pretty cool paper. It came out in 2017 from Stanford and it gives us a lot of properties that we really want in a blockchain context. So what we really want is a constraint proof size because all the nodes have to receive a proof and verify them. And bullet proofs provides a pretty constraint proof size over the players. It also gives us really fast verification. So once again you have to have all nodes sync up. And bullet proofs provides fast verification that also allows you to batch, which means that you can verify multiple proofs in parallel more efficiently, and aggregate, which means you can combine multiple proofs into one proof that they are all correct. And then lastly, this is a really nice property and sort of a big differentiator from ZK Snarks for instance. You can have an app logic that doesn't require trusted setup. So if you wanted to create a custom smart contract, for instance, you don't have to have a trusted background string that requires a set up ceremony. So that is a big thing that is appealing about bullet proofs, and a big pain point of using ZK Snarks. And I know a lot of more recent ZK Snarks protocols, such as K-Sharks, which is great, Hs for hybrid, actually gives you a hybrid mode between bullet proofs not requiring trusted setup and ZK Snarks requiring trusted setup. So that's just a good fun side note. But basically at the time, when we were looking to implement zero-knowledge proofs, bullet proofs was the thing that definitely made the most sense. So what we wanted to do was, well, first of all, understand the paper, so we don't just blindly implement it, and then second, once we understood, then implement it using really best practices and existing libraries and rusts, and then make it a good platform. So you're all here to hopefully use in range. And then it just gives us this massive multi-scaler multiplication. So I would like to hopefully give you a path between step one and step two. And when we tried these of how we get into step one and step two, and being like, no, that's still wrong. So if you listen to this talk, you want more information, or maybe you see this talk and you're confused about some of the points, we actually have... Also, I will post this slide tonight, too, so don't worry about finding all the URLs. And then, oh, the last thing is that after we understood all of the math, we went with this graphic genius and made a cyberpunk visual of this. And so hopefully we can help understand all these transitions. They'll be really great, well, most of them. Also, the most important is this inner product overview. So this is actually not unique to bulletproofs. This was introduced by previous people at UCL, and bulletproofs just made this three times more efficient. So what is an inner product? An inner product, for instance, C is an inner product of A and B, is the sum of entry-wise multiplications of vectors A and B. So four sum syntaxes in this slide represent vectors. So here, C is the inner product of vector A and vector B. So, negatively, if you wanted to prove to me that C wasn't equal to the inner product of A and B, and you had A and B, how could you do that? Like, just shout out some ideas, like, super naive. How do you do this in, like, open space? Yeah, you could just send vector A, vector B, and scalar C to me, and then I could do, I verify I could do the multiplication. So obviously this proof would be open space, because, you know, N is the length of A and B. The thing that bulletproofs introduces is a way to do this in open time. And, oh, sorry, open space. So what this looks like is first you start out with vectors A, B, and your scalar C, then you split A and B into two halves. Then you take this random scalar, X, and right now you don't have to worry about where X comes from. All you have to know is that it's not zero, because if it's zero then you're like, it's good. And it's totally random, like, you cannot predict it at a better time. So you take this random scalar, X, and you multiply it by the first half of A, and you multiply the inverse by the second half of A, sorry, the second half of A, and then you get this A prime, and then you do a specific thing with B prime, and A prime and B prime are now half the length of A and B. And then you then get this, like, big mess for C prime. But actually watch this, this sort of magic. Because of the way that we selected the inverse and not inverse for A prime and B prime for X, we can actually simplify this mess of C prime to be equal to the inner product of A low and B low plus the inner product of A high and B high, plus, like, some barrage. And wait for it. This, the inner product of A low and B low plus the inner product of A high and B high is by definition the inner product group. The same thing as the inner product group. So do you see, like, what's going on here? That line is actually the same thing as C above. Wow. Wait, okay. Can you erase that if you don't? Because I feel like this is a really critical part of what I'm saying. Okay, cool. Yeah. Half works here. So, like, you actually have C in your representation of C prime. And then you have this garbage. So this garbage, the thing underlined in green L and the thing underlined in red R. And then we send those two, so they're two points. We send those two points to the verifier. And then you just say C prime is equal to the C from the previous round plus X squared plus times L plus X negative two times R. So in summary, this is one round. And in one round, what we have achieved is that we have half the and committed to two points. That's a constant number of points. So from, like, theory of computation, if you do a happy every step and every step you do a constant number of commitments, then you have a protocol that takes O of N. So when you follow A and B, be able to make a proof that C is the inner product of A and B in O of log N space instead of before the only option is O of N space or something like on that order of four performance. And then at the very big space, we have, you know, A prime and B prime are just single scales. And you send, you know, the single A prime and B prime and the verifier test that's equal to your base KC prime. Cool. So then just as a recap, if you were the prover, now you have received one L and one R point for every one of these steps. And then you've also received the C prime. So you effectively, like, reverse this process and you build up what every higher C is using the L and R from that previous step. Until you get to the top level C. And if your top level C is equal to the C that you expect, then you're like, well, this all verifies for D. So that is our core building block here. Before I move on, any questions about this? That's to all of the things in the previous round so that you only get this random X once you've committed to everything before so you can't actually religiously choose this X. So that's something that I didn't talk too much about. If you're curious about it, I can explain more. Other solutions are actually over commitments over the plane values in all of these examples, I just use a plane and B, but we actually are over commitments. In the exact same way that in our earlier example for our confidential transaction, we're actually operating over at a regular level of the commitments and we check that they add to the same amounts. And then the last one is just a performance thing. We use multi-explanation to have faster verification. That's not fundamental to the math, it's just like cool performance, speed us. All right, so we just covered inter-product building block and now we might maybe be, whatever, by applying math and photography to a statement, we can represent effectively any statement as an inter-product. If you don't believe me, I'll show you anyways in this range proof and then constraint system proof, which therefore reduces from any statement. So we want to start out with a statement of range. 0 is less than or equal to V, which is less than 2 to the n. We want to do some things to it, TPD, until it's in the form of C equals inter-product of A and B. Such that if C is equal to the inter-product of A and B, then with a very high probability, V is in range. Cool, is everyone on board with this mission? Any questions so far? All right, so now that it's looking at this, in between passing through this step. All right, so the first thing that we want to observe is really interesting. So if V is in range from 0 to 2 to the n, then V must be a binary number of n. So in this example, if V is 3, V is definitely a range between 0 to the n if it has 4. So you must be able to represent V as a binary number of 4. Cool, so as a mental exercise, you can try this with any value between 0 and 2 to the 4, and you'll see that yes, indeed it does work. And then if you try to represent something larger, so 2 to the 4 plus 1, you'll see that you cannot actually fit everything in these boxes. Cool, so like... So I think this is pretty cool. First of all, any questions so far? If you don't follow all of this, you'll be lost for the rest of this explanation, so I want to make sure it's on board. Don't be nervous, it's like... It took us a little... So we now have V of 3. This is our secret value, and we want to prove that it's between 0 and 2 to the 4. What we do is we call the binary representation of V a sub l, and this is like what the paper uses, so it's trying to be consistent. I didn't say that V is the inner product of a sub l, and to the end, remember inner products can be of any two vectors that are the same length, so here we're actually representing V as an inner product. So maybe some of you have seen the jumps from this V as in range all the way to the inner product statement. Are we done? I wish. No, we're not done. And the reason for this is because if this is your only statement, you can actually do something malicious with your a sub l. Does anyone have any guesses as to what you can do with this selection of a sub l that would be malicious, that would allow you to make a value that's outside of the range but for whom this inner product argument is actually true? Yes, exactly. A sub l, nothing about the statement V equals the inner product of a sub l onto the end, requires that a sub l is actually just binary. So if we have the first digit is 100, then V would be a huge number but this inner product statement would still be true. So what we want to do, oh whoops, I actually have some likes to mock to all of this. There we go. So here's some examples of V. A sub l has to be binary. And the way that we do this is we create an a sub r. A sub r is the bits of a sub l minus 1. So if we have 0, 0, 1, 1, then a sub r is negative 1, negative 1, 0, 0. So this has a really like unique property where if you multiply every bit of a sub l with the corresponding bit of a sub r, then if a sub l is only this, then you'll get a vector of 0s. If a sub l is anything else, for example 100, then you'll get like 100 times 99, so that's 0. So this is actually a statement that makes sure that a sub l is comprised of bits. So now we have three statements. The vector is actually a sub l times n apart of 2n. The second one being a sub l times a sub r equals 0s. And the third is being a definition of a sub r. Cool. So how do we do this? Does this make sense? Why do we use a sub r? Cool. And obviously you can combine steps 2 and 3 into just like one statement without defining a sub r. But we try to do that and then realize that we're committing to a sub r. So just trust me that I actually need to do all three of these things. Cool. So now we have come up with these three statements with these three statements. If they're true, then your original random statement is true. So the same way that... Here let's just pretend we have a challenge together. It's not working. If a equals 0, if b equals 0, then you can actually combine these two statements together into one statement using this random challenge by saying a plus b x equals 0. And as long as x is random, then with extremely high probability the last statement will be true if and only if a equals 0 and b equals 0. Does this make sense? Let's see. And it has to be in order to make maliciously that you do not use 0. And that will also give you maliciously a way to, you know, circumvent this double combination step. So we just have to check that if it's not equal 0 to a divided by b. It's so small that we don't really worry about it. And in practice we sample x from like 255 minus 19, so like we're fine. Don't worry about it. Cool. So we can actually do this multiple times. Don't be scared, this is the same idea. We can do this multiple times. By instead of using x once, we can multiply the first one by nothing, the second one by... And the reason that we'll have to do this is because if y is random, then taking y to a certain exponent is also going to give you something that is random in that space. So the way that we write this combination is the inner product of a and b times the vector of y to the n equals 0. So it's a little bit weird syntax, but that's just how we write it. And so since it's like inner product of a and b times y to the n equals 0, it's true with very high probability. I'm just showing you how you can use random challenges to combine a bunch of statements together. And hopefully you also like have a little bit of like, hmm, this is interesting because this last statement is actually an inner product statement. So like you have a range proof, or a range statement, and ending up with an inner product, this is actually a tool that we'll use to get to that inner product. So the way that we'll use this tool is that the very far end column scale I want. So this comes from somewhere. In practice it comes from the reflection of your mistake. Then we rewrite the second two statements because the first statement is already like in the inner product proof form. So we're like already pretty, pretty well along there. But the second two statements, we use this y to combine the statements together into inner product forms. So once again, originally the second statement a sub l times a sub y equals 0, the vector of 0s, is actually multiple statements. It's n statements, one statement for each index of a sub l and b sub r. And what we have to do is we're combining all of those statements by multiplying each of those statements by a different power of y. And then we're combining them in one inner product order. So this is just the format that we write it in once we combine it with y. And then we do the same for the second one. We use this challenge scalar where we do some crazy stuff and end up in three inner product order. b equals 0 with like a plus b times a challenge scalar. b equals a sub l inner product of 2 to the n, which you can actually rewrite as 0 equals b, sorry, 0 equals a sub l. And what we do is you just multiply and then you end up with a statement. So we're really close. We have one statement that's three inner product arguments. And then we do some math that I'm not going to bore you with that's basically just algebra. You just like take some things apart and rearrange them. And then you end up with this inner product statement equals this thing on the right. So if you're curious about what that math is, we wrote it up here. It's really not, I promise you it's not actually that interesting. But look here on the right. This is exactly the format that we want. We want an inner product argument where the single left inner product with the thing on the right equals c. So we can essentially represent the format as a, and the thing after the comma is b, and the thing after the equals is c. So to recap, we have, sorry, L1. I forgot the letters in the case. But to recap, this is our, we broke it up into three separate statements that must all be true if the value is actually in range. And then we apply these range challenge scalars such that we could rearrange all three of these one inner product argument. And that is basically in the same format as what we wanted, t is the inner product of LR. And going all the way back to the beginning now that it's in this inner product argument, if and only if this inner product is true then the b is in range and we have a really efficient way in O of log n to approve that this inner product is true. Cool, so it comes full circle. Yeah, and then this is LR, t of inner product. So before I move on to how this is actually kind of oversimplifying it, I want to make sure that this simplification makes sense to anyone. Questions, questions, yes. Yes, for sure. This y, and we took a y to rewrite each of these. So now we have like here on the right-hand side, here on the left-hand side we now have three statements and these three statements have to be true. But we want some way to like somehow smush all of these three statements into one statement. So like if we're a equals zero, b equals zero, c equals zero and you want to represent that as just one statement, what you can do is you can take like a random number, z in this case and you can say if a plus b times z plus c times c squared equals zero then with extremely high probability we know that all are three individual statements. So that's exactly what we're doing here. Multiply the second thing by c, multiply the third thing by c to the zero or nothing. And then that gives us the equation right there. And then we just move the v to the end, just because it's prettier that way. Cool, does that answer your question? Okay, so on the right-hand, yes. Let's open that, you know. This delt slide, the same way that the previous slide was like, doesn't have anything that's secret in it. So we're going to verify both the number and what's in delta. And that's what we can abstract into this delta nice thing. Because it doesn't contain anything too important or too secret. Cool, any other questions? Alright, so that's a good segue into the next section, which is that as you might notice a sub l minus z on like the if you were to just send that to the prover, the very part I would just learn when you're a sub l is, and then you're like oh, I know you're secret, come on. So that's like, actually sort of silly. And so what we actually do in practice is we make a commitment to what's on the left and the right in a product. And then really nice, and then also is these four times b. So like, these are things that we actually want to make commitments to and we will send over the commitments instead of sending over the plain secrets. Like, maybe first I should, you know, review what commitments are. So if you have an additively homomorphic commitment like I mentioned way at the beginning of the talk then if you have some secrets a plus b equals c plus d then your commitments will also maintain the additive property of those secrets. So then the commitment of a plus the commitment of b would be equal to the commitment of c plus the commitment of d. And then similarly this also extends to multiplication by scaling. So if you have two times e equals f then two times the commitment of e equals the commitment of f. So you don't have to worry about how this works. You can just sort of treat this as a black box. If you do want to learn about how this works it's really just a peters commitment and it's really straightforward to just multiplying by a group element and adding applied factor types on a group element. It's not that crazy. We also have to dig into that more. But if you want to treat this as a black box then basically all you do is start with the thing on the left of the inner product and the thing on the right of the inner product and the thing on the side and you just make the commitments to that. And if the inner product of those commitments is true then extremely high probability and the secrets inside these commitments are actually true. So that's really nice. That's sort of the magic of an additive homomorphic commitment scheme. And in practice that's what we do. So as a let's see. As a recap argument without fearing that we're revealing secrets. So things like how the commitments work in detail most again there are some commitments and so skip it over that's part of how the commitments work. So if you want a deeper dive into that I'm also happy to talk about that but it's okay just treating it as a black box and being like yes that is how it works. So the end result of we understood the paper we implemented it and then it's a very 64 bit ranking verification and that's even without factoring. So if you were to batch you can get multiple verifications in even the last time. And so yeah that's our numbers and I think that's all of the material that I have for today. I'm also happy how we use this and other ways to abstract bullet groups over arbitrary statements because it's only over range groups. So maybe let's start with some questions. Let's do it in time. Anything that you missed I'm happy to review. Yes. Here you actually get the X of the B low sorry the X inverse attached to B low to cancel out the X and A low. So here let me do it. I can see A high in a product with B high. And so that's just a nice sort that we can construct C from C5. So good question. That is really cool. Questions about math? Yes. But it's sorry I asked if you want to just like review the slides. It's darkin channel dot dot like dot rs slash bullet groups. If you just go to that you can navigate all the notes. The distinction between like external with dot is that the dot dot dot is basically the API and this is a really nice thing that we have because we made everything in Rust we have Rust documentation from that. I can take requests for a statement and then make a proof about it and then as an influencer you're like what? How? And so it's transcript protocol that Henry made and he was like this would be a really good use case for a library that takes care of all the math for you. In practice for papers when you implement the fiat to new years a lot of times people just hash the things that a prover gives the verify. You're like we just have this and then we take the trample out this challenge from it and then we use the challenge so just sorry here's an example if you wanted to take a challenge like here for instance X like where does this X come from? And a lot of times a lot of the time people just like take for example the vector v and hash it and write it somehow and get the challenge X easy to misuse or easy to get a little bit wrong and also really complicated if you're doing multiple rounds of this and so that's why it's effectively a block easy and I get some randomness back that I have guarantees about that it's actually fully random that it's domain separating you don't have like hash collisions things like that so that's actually and so that's where we get X from we actually use them really transcripts to get X to get Y to get X to be for all of these random challenge skills and if you need anyone who want to hear about any other things I can also be done all of this is the clock protocol so let me just pull up my slides for that sorry so bulletproof is not just a range proof protocol where you can take any and then make a proof that it is correct over some inputs while keeping those inputs secret it turns out rotation to a constraint system they're really easily translatable from one to the next but constraints are a little bit easier to talk about so you have a multiple constraint and you have a different constraint that and you also have a linear constraint which is like some linear so these are like those constraint system and with a constraint system you can actually represent anything that is officially verifiable so by this I mean any NP-complete program can be you know changed into or represented by the constraint system so that's pretty nice final side note is that the extension that my colleague Oleg made over this constraint system protocol broadens the things that you can represent from NP-complete to piece space so like if you're a theory nerd that's like pretty fun but if you're not it doesn't matter so I have a constraint system so what we wanted to do was to make a bunch of assets protocol and a secret then you have to specify which assets are the same and that would reveal which assets are which over enough analysis so you can't just sort of sum together things the same way that you do for confidential transactions so what we came up with was sort of multiple gadgets that we composed together so on the right hand side we have a range gadget that's what we call it which is a collection of constraints that basically make sure that the variables in the constraint system are in range and then we add some new ones so make sure that the inputs and the outputs are so you can't just introduce a new input, introduce a new output then the shuffle gadget would fail and then there's an merge gadget which either merges two inputs into one or just moves them without altering same with splits, splits either splits one item into two it moves the two inputs to the two outputs without altering it at all so I guess if input to this protocol and output to this protocol are valid you want to prove that the inputs have been rearranged in such a way that the asset types are preserved but without creating or destroying value so this is really tricky because you can't actually reveal what asset roomings you have so this is like it took us a while to come up with this as the case of how you actually prove this right together into the same box so if you use the shuffle to reorder this such that your dollar amounts are together and your yen amounts into one little sum and you'll merge your yen well you will because you only have one and then you shuffle it such that your non-zero values are at the very top of the shuffle for each asset type and then this is the part that's hopefully the intuition into whatever your target amounts are so if your output target amounts are 3 yen and 6 dollars and 3 dollars so you'll take your 9 dollars and split it into 6 dollars and 3 dollars and then you'll be able to go down the coast it's just one output and then just to preserve the randomness of your output and shuffle it one more time you'll apply a range check to it to make sure that none of these are negative and then you get your outputs and so if your outputs are valid then you should be able to do this successfully if your outputs are not valid suppose that you wanted to make it 100 dollars you would not actually be able to correctly satisfy all these gadgets one of these gadgets would be like wait where this extra money come from this is not a valid constraint satisfaction so this is the intuition for how it works and then for a verifier a verifier actually only receives these commitments and inputs and commitments to the outputs and it can't tell what happened within each of the gadgets because all those are just like commitments to the verifier but all they can do is verify this indeed this proof succeeded or this proof failed and then valid and valid transaction so that's the intuition for Cloak this is just one of many uses for the Bullet Group's constraint system API that you can come up with we just sort of made this by hand after figuring out what would make sense as a way to build it and anyone else can basically make their own protocols and proofs as well so that's cool that's my little add-on do I have time? alright any questions on range check and so basically the output of the third shuffle right here is 3 again 6 dollars and 3 dollars and we just want to add a range check that all of those values are between 0 and 2 to the n for some large amount for example this is one of the outputs and then negative so basically make sure that we can make extra money sorry you can ask more questions afterwards thank you for all of your attention