Flash and JavaScript are required for this feature.

Download the video from Internet Archive.

Lecture 18: Confidential Tr...

The following content is provided under a Creative Commons license. Your support will help MIT OpenCourseWare continue to offer high-quality educational resources for free.

To make a donation, or to view additional materials from hundreds of MIT courses, visit MIT OpenCourseWare at ocw.mit.edu.

TADGE DRYJA: And that brings us to today's lecture, which is also something I was not as familiar with. So sort of a disclaimer-- I might have gotten little things wrong, or it might not be quite as clear. But do ask questions.

So if it's stuff like Lightning Network or Discreet Log Contracts, well, for me-- that's sort of easy, because I know it really well.

This stuff is things I've known about, but I've never really went as into the details. So it's a little bit like, OK, figure it out well enough to explain it rather than just well enough to understand how it works.

So the basic idea is you want to hide the output amounts. So we saw last week how looking at output amounts can deanonymize and let you link a lot of different things. And so we'll look at how to do that.

How do we hide output amounts? And so we'll talk about commitments. So first, we'll talk about the reasons why and how to do it. Then we'll talk about the definition of commitments. What is a commitment in cryptography?

And then we'll talk about Pedersen commitments, and then we'll talk about range proofs and put it together to get what's called "confidential transactions," which is a vaguely confidential transaction-- it just means the output amounts are secret.

So interrupt with any questions at any point of the way if something's not clear. So coinjoin-- last time we talked about combining transactions with other people where you have your input-- they have their input. You have your output-- they have their output.

And if you shuffle the ordering of the inputs and outputs, it might not be clear who's sending what where. You're aggregating it, and in the process, you're losing information, because no one gets to see the border lines between-- hey, this is one transaction-- this is another transaction-- it's all in the same transaction, so you can't really tell.

But one issue-- and a really big issue-- was that the output amounts can often reveal who's sending what where. So in this example-- well, maybe I don't know who's A, who's B, who's C, who's D-- these all look like uniformly, random addresses or pubkeys.

But if I see an input with 10 coins-- an input with 2 coins, and then an output with 2 coins, and an output with 10 coins-- well, there's probably something like this going on. Why else would you do this?

If you were trying to send 2 coins somewhere, why even involve this 10-coin input? Why not just say 2 coins to 2 coins, and you're done?

So if the goal is to obscure the transaction graph and have better anonymity because no one can tell what's going where-- well, this doesn't really work. I think it's going like that.

And then I showed that there is a way to do it, whereas if you have 2 to 8, then the 8 is obviously from the person with 10. But the 2 different 2 coin outputs are unlinkable. So that helps, but it's not great.

And then for things like the aggregate signatures, maybe you can get people to aggregate their transactions together because it's cheaper and smaller.

But in general, they'll have totally different input sizes, totally different output sizes, and it won't really give you any anonymity. And it won't give you any privacy, and it hurts fungibility. So how can we do this?

Wouldn't it be great if we could hide the output amounts? That would be really cool. So instead of having it like this-- it's just you don't see how many coins there are. Why don't we just delete the output amounts entirely? Why even that saves 8 bytes.

So we can't just delete it. So what does this mean? This would be really cool, though, if we could somehow obscure this so that no one can tell what the amounts are.

And, I guess, initially, so they're going to be some transition since Bitcoin wasn't built with this from the get-go.

At some point, there will be a transaction where you can see the input amounts, but then you can't see the output amounts. But then you can have bounds and say, well, neither of these can be more than 12.

And then as it goes forward, and if the transaction graph gets bigger, those bounds start getting really wide because you're like, well, this might have been 11, and this might have been 1, and then the next transaction if it's mixed in with a bunch of things that have a pretty wide range, you have to take the max and min of all those things. And, the min is always going to be 0, so it works pretty well even with this transaction.

You could also think of a new system where either you start with obscured amounts, or the first mining amounts are non-obscured, and then you mix them.

Anyway, so this seems like it'd be really useful because it would allow you to combine transactions and get better privacy. Also, just really nice in general, even if you're not trying to combine with anyone else-- it's really cool that people can't see how much money you have.

If people can see how many coins you have, they can try to charge you more-- they can try to rob you-- there's all sorts of reasons why people don't usually say how much money they're carrying around, or how much they make, or how-- things like that.

People are sensitive about pricing information, and some of it's societal taboo, but also a lot of it's like I don't want people to know how much money I have.

And I think there's-- I've read recently like Uber doing this thing where they like, oh, you're rich-- we're going to charge you more. And people don't like that. It has been historically doable. Companies segment things, but often the way they do it is they're like, OK, well, we're going to make first-class seats and then economy seats. And the first class seats don't take up the space of 10 economy seats-- they take up the space of maybe 2, but they cost like 10x.

And the idea is, well, if you're rich-- we're going to charge you more. You can have the fancy stuff, and we're going to make more profit off of that. That's more OK, I guess, but if it's just-- no, you're getting the same economy seat, but we know you're rich, so we're going to charge you more-- that-- I don't know.

And we're getting into that future where there's enough data that a lot of companies can do this. And some people, probably myself included, is like wait, no, I don't like that. I like the way it was before where companies didn't really know that much about me.

So this is an effort to try to keep things obscured-- try to keep the customer a bit more anonymous with respect to merchants so that they don't have as much information to charge more.

And then-- rob you-- that's maybe more Bitcoin-specific where like-- yeah, I mean if you're walking around in an area that's sort of high-crime with a bunch of money hanging out of your pocket-- that's a bad idea.

The internet is sort of a high-crime area, especially, with respect to Bitcoin. And it's really easy to see how much people have. And so people-- the hackers know who to target, especially if it's like an exchange-- they're pretty clear-- OK, this exchange has tons of money.

So it might not help the exchanges that much-- it obviously has a lot of money, but anyway. So this would be really cool to do. I think people sort of agree-- this would be really cool. This is a nice thing to have.

And it also helps with privacy. You're trying to make it hard to link different outputs to each other or link the outputs to a specific person. And hiding the amounts makes them really hard to distinguish.

So if you don't know the amounts, they become completely uniform where this is a completely random address. I have no idea how many coins there are. I have very little way to distinguish between these outputs. I can try to trace the graph and say, OK, well, this came from here-- this came from here, but they all look the same.

So I've got this big graph with no real information other than the links between the notes, which is still information. But it's much harder to tell what's going on.

So we're sold-- how do we do it? First, we need to define-- what exactly are we trying to do? What are we hiding from whom? Who knows what and when kind of thing?

So the long-term state of the system-- no one can see any-- no one can see it in the amounts. A has signed a signature from key A-- a signature from key B-- some amount of coins. You don't see it. you don't see any of this.

So that's the long-term state. But wait, people receiving the payments should probably know how much they're receiving, right? And they should probably know how much they have. If you don't know how much money you're getting-- that's not a very useful payment system.

People sending should-- they should also know how much money they're sending. If the amount can be completely determined by the receiver-- that's also not a good payment system. I'm just going to take lots of money.

So we can have two views. We can say, OK, only the sender and receiver know the amounts. How about that-- where from the network's point of view-- so if I'm just the third party looking at this transaction-- I don't see any of the amounts. I just see there's no-- I have no idea how many coins are being sent.

But from the sender's view, the sender says, OK, I know I have 2 coins here. 7 coins-- I changed it from 2 and 10 on that line-- 2 coins here, 7 coins here. And I'm sending 7 coins here and 2 coins there.

So the sender knows the whole thing because they're the ones creating this transaction. And then maybe the receiver doesn't see everything. Maybe the sender can prove to the receiver a single amount but hide everything else. That would be ideal.

So the receiver only sees, oh, I'm receiving 2 coins, but I don't know. If I know this, then I can figure out what these are, or at least the sum of them.

But if I don't know any of these things-- I don't know how much the person sending me money has. I just know, oh, I got 2 coins. Cool, that's what I wanted. But I don't learn anything about their inputs or their other outputs within the transaction. So that would be ideal if we can do that.

So what we want is a system where network doesn't see any of the amounts. The sender presumably sees all of it. Now, there could be cases where there's multiple senders, and there are two people working together to make a transaction, and maybe we don't see each other's inputs, but we'll keep it simple for now where there's a single sender.

And then the receiver only sees their own output. So that would be a really powerful system. Then the receiver would only know they're getting the right amount and not learn anything else about the sender's coins.

So we might want to-- like I was saying, you might want to hide per output. So if you have a-- if it's a global-- either you see everything or you see-- sorry-- you see nothing, or you see everything-- that's still pretty good. That's still better than what we have when everyone sees everything, but it is better if you can hide the rest of these three things from the receiver.

So any ideas? Some kind of encryption? Hide the amounts so the only people with the right private key can see the numbers?

So, I don't think I've even talked about encryption ever in this class, because there is no encryption in blockchains. [LAUGHS] Which is something you-- if you read something about blockchain and you're like blockchain is encrypted. And you're like no, no-- they don't know what they're talking about.

So I haven't defined encryption. But encryption is-- generally, you have some kind of private key-- you take a clear text, you apply-- you do some-- so like I had with signatures, you have a set of functions.

So encryption is-- you've got some encryption function which takes a key and a message and outputs a ciphertext. And then you've got some kind of decryption function, which takes off in the same key or something and then the ciphertext and outputs the same message.

And this is symmetric encryption because you're using the same key. You can also have asymmetric encryption where this could be a public key, and this could be a private key.

So in order to decrypt, you need the private key, but in order to encrypt, you only need someone's public key.

So, in practice, all the things that people-- in practice, you usually stage it, so you have an asymmetric algorithm to agree on a key, and then you just use the symmetric encryption and decryption where the keys are the same because it's way faster.

So you can do this operation on the order of hundreds of megabytes a second, whereas the asymmetric ones are slow-- it's sort of like signing. Maybe I'll go into it later. But if you understand all the signing and stuff, it's not too bad.

But so maybe you could say, OK, well, there's some kind of private key that the sender creates-- encrypts the amounts, and then they put the encrypted amounts in the transaction, and they reveal the key to the receiver. And, potentially, you could have different keys for each amount-- that would work. Any problems with that idea? You can encrypt everything. Yeah, you know?

AUDIENCE: You would need to send over a public key or something so they can decrypt it.

TADGE DRYJA: Yeah, oh, OK, so that is a sort of problem-- it's a limit. But that limit will carry forward to the stuff we do.

So you're going to have to-- right now, in Bitcoin, you can find someone's address, send them the coins-- you're good. With this system, there will be more interactivity between sender and receiver. So that's not great, but not a deal breaker. So we will need to do that. Other problem? Yeah.

AUDIENCE: A key for every amount.

TADGE DRYJA: Yeah.

AUDIENCE: [INAUDIBLE] because of the fact that there can be a lot of different ways to split up the--

TADGE DRYJA: Yeah, it could get bigger. And the actual solution gets big. So that's not great either. But the one that really screws it up. [LAUGHS] Yeah.

AUDIENCE: How do the nodes verify the transaction?

TADGE DRYJA: So the nodes don't verify the transaction at all because they can't see anything. Well, I can do that. Well, how about I just make 70 coins and 2,000 coins? I can make as many coins as I want. No one can see anything because the network just sees nothing-- have no idea how many coins are being sent.

But I'd be like, hey, hey, I'm making more coins all over the place. [LAUGHS] And this doesn't work. Because if I can send coins to myself and multiply them indefinitely, and it's hidden-- so to some extent, you're like well, maybe the network doesn't care. Because well, I'm making them, but they're only my own coins.

But if the network doesn't see anything, it's easy to create the coins. And if those coins are later used, I can't tell if they were made up or not.

So if I'm accepting-- so if I see this, and someone's like, hey, here's 2,000 coins-- I'm like dude, you're making them up. You can't write extra zeros on $100 bill and be like here you go. This is-- come on. No one's going to accept these later.

I won't even know. Did you even have 7? Does this 7 coins come from something where you did the same kind of thing before?

So, basically, if we do that where we completely obscure the amounts from the network and from all third parties, then anytime I'm going to accept this, I'm going to have to enforce the rules myself. And then retroactively enforce the rules for all transactions beforehand to make sure nothing like this happened.

So we could do that. It's all obscured. The third-party-- the network doesn't see anything. And it's up to the participants themselves to say, well, if you're going to send me coins-- since I know if I'm sending it to someone later, I'm going to have to provide some kind of proof that this kind of nonsense didn't happen.

I'm also going to need proof that all of the ancestor transactions that led to these 2 and 7 coins-- I'm going to need those amounts.

And, so, yeah, you could maybe do that. You could provide the decryption keys for all previous amounts. But that basically gets you back to where we are right now-- not quite, but pretty close.

Either you allow people to create coins, or you basically are revealing close to all previous amounts eventually to everyone.

Because as that transaction graph gets bigger and bigger, I'm going to start having all these thousands and thousands of ancestor transactions that I'm going to have to require proof for. I'm going to require all those decryption keys to make sure nothing like this happened.

And then eventually, all the people receiving money will be able to see everything-- well, not quite everything, but a lot.

So it's like well, third-parties-- the miners or maybe people who are just looking at the blockchain who aren't really receiving any funds-- maybe it's hidden from them.

But once you start using the system, you're going to basically be able to see everything. So that's not great.

And it would also be really annoying because then when you have to receive coins, you have to go back through thousands of transactions to make sure that didn't happen.

So we need to prevent coin creation while still keeping the amount secret. This is a tricky problem-- any general ideas here?

So wouldn't it be cool if we could do this where the network sees there's w coins here, there's x coins here, and there's y coins here, there's z coins here? And then we have a proof-- w plus x equals y plus z, without telling you what w, x, y, and z are. Cool. Let's do it. Any ideas? [LAUGHS]

So this seems like this would work. This would do it in that if we can reveal like say, hey, the person d-- z is 2. Cool. So I got 2 coins.

And they can also verify that these amounts are correct. And then if you're-- you could either keep this proof only to the receiver, but then you'd have to give proofs about all the previous transactions, or you can just, say no-- the whole network enforces these groups. This is now a consensus rule where if you want-- even if it's not your transaction, it might be a parent of your transaction someday. So you have to verify it. If you're going to accept the block-- verify these proofs for every transaction. So that would work.

AUDIENCE: So that's essentially a minor deal, right?

TADGE DRYJA: Yeah, a miner, or-- the miners would do it and also the full nodes. If you're running a node-- well, I'm not receiving anything here, but I still need to make sure this is a valid transaction in order to accept it.

AUDIENCE: Isn't that a problem then, because what if a miner is in that transaction?

TADGE DRYJA: If the miner's receive-- the miners D in receiving this coin?

AUDIENCE: Yeah.

TADGE DRYJA: Then they'll know-- then they'll both get the proof, which is sort of redundant for them. And they'll also get the actual amount-- z.

So they'll know this is 2. So that miner would know more, but that's OK. I guess other miners wouldn't-- or other nodes wouldn't. So if you're participating, you'll potentially know more. But the idea is third-parties see a proof and don't see the amounts. Yeah.

AUDIENCE: So SPV will have no way of knowing if a transaction was valid until it was [INAUDIBLE]?

TADGE DRYJA: They already know. So SPV, while it's already have no idea how many coins are coming in on the inputs because they don't have a UTXO set.

And the coin-- so if you see an input, you see it's pointing to some txid. I don't know how many coins there are. I would have to-- you could provide a proof to an SPV wallet that, hey, there were-- I can give you that previous transaction, and you can see how many coins, but then what about the one before that?

So, generally, SPV wallets can't enforce that amounts are correct or verify signatures, because they don't know enough about these inputs, whereas full nodes-- when you tell me to input 0, I know how much. I know what keys-- things like that.

So SPV can't well-- no there's maybe some way to make the SPV have it so that SPV proofs are compatible with this. But it's-- you already don't have that. So I don't think there's much idea-- there's much much research into how to make this SPV compatible. But yeah, it's a good question. Other basic ideas?

So how do we do this? [LAUGHS] So this will take a little-- the actual way to do this will take the rest of the class. Because there's a lot of things where that seems like it'll work, and it's like oh, no, it doesn't.

And this is sort of replaying the ideas from several years of people trying to do this. So how will we do this? So there's an idea called commitments. And the simplest form of a commitment is you commit to some value-- you ouput it-- call it c-- and then you reveal the value and then someone can verify. Well, given c and the value you just revealed, is that a correct commitment?

So I'm committing to the value 2. I'm outputting something c and then revealing it was 2. And let me throw this into my function. 2 and c-- do those match? Oh, it's true-- we're good.

And then there's certain properties you'd want. You don't want people to-- I think I have slides about that. So the hash function is a commitment.

I can say the hash of 5 is 68 empty-- whatever. And then I commit to 68 something. I publish this, and I tell everyone I'm committing to something. I'm not going to tell you what I'm committing to exactly, but here's this 68fde0b7-- some long hash output. And then I reveal days later the thing I was committing to-- that was 5.

And then everyone can check. Let me throw 5 into my hash function. Oh, yeah, it was this. True. So that's a commitment scheme.

It is binding. So there's binding and hiding, and there's different properties of commitment schemes. So this we could say is a computationally binding commitment scheme.

Once I've committed to this, I'm not going to be able to find another number. So I'm not going to be able to say, oh, it was 6 And then get the same commitment out.

So I'm not going to-- so in practice, this is really long. This is a shot 2 output. I didn't want to write the whole thing, but it goes to here, or two lines.

So the idea is I can't find another number, especially exactly the number I want. But I can't find any other number that will get me to that same hash output.

That's a collision, and I'm going to have to try it. Wait, so for a specific number, I'd have to try 2 to the 256. For any collision, I only have to do 2 the 128.

But still, both of those are really big numbers. I can't do it. So it's computationally binding. If I had some amazing computer that could perform an infinite calculation, I could find a collision.

So there's the distinction between computationally and information theoretically. Information theoretically is stronger where even if I had the most powerful computer, I still couldn't do this, whereas binding, in this case, it's computationally binding-- computationally is good enough.

Everything in Bitcoin is already-- everything in all these systems is already basically computational. There are some schemes, which are not computationally bound.

So one of the parts here-- and the Pedersen commitments are not computationally-- and things like severe secret sharing and a couple other things where this is not dependent on processing power.

Even if you have infinite processing power, you just can't figure out what the values are, which is cooler, but it's nice to have. It's not a requirement for our systems.

So this is binding. Any ideas of what this is not-- why this would not be a good commitment scheme? You want to commit to a value and then later reveal it.

You don't want the person who's committing to be able to change their commitment. What else might you want that this probably doesn't provide?

AUDIENCE: Do you need some way to be able to hash the commitment?

TADGE DRYJA: Yep. So you want to be able to do fancy stuff with the commitments. Before we even get there, that's in 5 or 6 slides-- before we even get there, this doesn't satisfy something else we want. Yeah.

AUDIENCE: All but like 5 is such a common number?

TADGE DRYJA: This is easy to guess. So if I'm committing to a number, I'm going to commit to the number of pizzas I'm ordering at my party. And everyone's wondering how many pieces are you going to order? I try things. It's binding, but it's not hiding.

So verifier can easily guess and check the committed value. So for i equals 0. Just keep trying different i's and see if the hash matches 68fd even. And this will take very little time because 5 is going to happen pretty quick.

And then everyone will know he's ordering five pizzas-- sounds like a decent party, but not really worth going out of my way to go to. If it was fffff pizzas-- that would be something else.

So solution-- pretty straightforward solution. Add a blinding factor. So we're going to call that, r I guess, r is random.

So r is b8bc7579. And now I'm going to take the hash of 5 and concatenate r, and now this is a different hash. And now to reveal what I was committing to-- you reveal both 5 and r.

And you need to tell people what order you're doing things in. The system needs to be predefined.

When you're committing, you also have to commit to the algorithms or have pre-agreed upon algorithms, because otherwise, you could do something-- no, I committed to r. 5 was my blinding factor.

You need to have protocols set up beforehand, which you never know, that could be some-- if you say, I'm committing. Here's this value.

How are you committing? What hash functions? What are you doing? But that's obvious. It might not be super obvious, so you have to be careful on that.

So this is now blinding. And it's hidden, and it's still binding. You can't change it to 6. I think that's the next slide, wait.

So you can't change this to 6 and change to a different r. I mean, you could, but you'd still have to do a lot of computation.

And this is now-- some things get easier. So before if you really wanted to reveal that it was 6, you basically can. Because there's a single output for 6, and it just doesn't match this.

So there's not-- if you have a single chosen value that you want to reveal that's not the one that you committed to-- you're basically stopped. There's no way to get around it even computationally.

With this-- that's not true. It's like I really want to reveal 6, I can come up with a different r such that the hash of 6 and our prime is that. And then that's now computational-- slight distinction.

It's still binding computationally. But before, chosen values may not have been. So that's, I guess, the difference.

It's computationally binding for any value. But for a specific value, it might be-- not information theoretic, but you can't do it, because the hash function doesn't help you there.

So what else do we want to do? You're saying we need more. We want to be able to prove things about the commitments. So we need some kind of homomorphic commitments.

And we've seen the homomorphic properties of these elliptic curve points, which are really nice-- where you can add private keys or add scalars, and that's the same as adding these points on a curve.

So let's try that. We want something like this. We want a-- commit to x, commit to y, and get these commitments-- a and b.

And then we want to reveal z, which is x plus y. And then we want the verify function that's put z in and a and b-- either a plus b or a and b separately and return true.

So we don't want to reveal x and y separately. We will reveal the sum of x plus y. And then we will reveal-- and then we'll have the commitments themselves.

So since these are the same operators, it'd be cool if that worked. This is what we want. So that's not that bad. But we also want all those properties where it's hiding, and it's binding and things like that.

So what should we try? First idea is-- this would be useful. How can we build this? We want to-- we can reveal sums without revealing individual parts that we've committed to.

So probably the first idea is let's just use private keys and public keys. Let's use a times g-- that kind of thing.

Oh, oh-- I forgot the joke-- was going to say, gee, how can we build this? g-- it's g. You want a commitment to act. You want a commitment to y. You want to reveal z is x plus y.

So what if you did this? You said, I'm going to make a point on the curve-- x, which is just my value x times g-- point on the curve y, which is my value y times g. This does have that homomorphic property. But is this binding?

It is. I can't come up with a different x that gets me to that point. So multiplying by the generator point is a hash function in that you're not going to be able to find collisions.

So you can't find two different private keys that give you the same public key. Sometimes you can. [LAUGHS] So I don't want-- in this specific case, this is binding. There's a bunch of asterisks that's there. I probably shouldn't. It gets complicated.

There are some curves where it's not. And some systems where it's not. And there have been problems in currencies where people assume that this is the case-- I think in Monero. But, yeah.

AUDIENCE: Can you draw an example of curve?

TADGE DRYJA: Yeah. So they-- the curve for Bitcoin, I think it's y q? No, y squared equals x cubed plus or minus? Minus 7, I think. That's it. It looks sort of like this. It's symmetric, which that isn't.

I think I had it in an earlier one. And then the x-axis is like this is the origin-ish. And then the idea is you have points and you can-- the sum is if you have the sum there it's going to be here, except it's here.

So the idea is 3. Any line you draw more or less will intersect at 3 points unless it intersects at a tangent, or if it's straight up, then you say it intersects at the point at infinity.

But any random line you make will probably intersect in 3 different points. And so then if this is a, b, and c, we define a plus b plus c to be 0.

So then we would define b plus c to be here-- negative a. And the negation is you flip it over the x-axis.

So I talked about this a little bit before. But the idea is you've still got this nice property where you pick a point on here-- g-- everyone picks a random point, and it's a generator. Because if you keep adding. So here's g-- sorry-- and take the tangent-- find this is 2g. Take the tangent here-- maybe it goes here to 3g. Take the tangent here-- or no, that would be 4g-- sorry-- this would be 8g.

So you can keep adding the g, and you'll eventually cover the entire curve and get back to g. So that's why it's sort of a generator because it lets you get to every point by just multiplying.

So the nice property here is if you have some number x times g, and some number y times g-- you can also do x plus y times g, and that equals xg plus yg.

So you can add the points. And that's the same as adding the scalars before you multiply by g. And that's what basically we use for everything.

And then the idea is you can't go back. Given a point, let's say we call this big X-- given a point-- big X, which is little x times g-- you can't figure out what x is. So you can't divide by a point.

You can't say oh, given x, I want to do x divided by g, which is little x. I can't divide some stuff. I can multiply by repeatedly adding. But division is not defined.

So this is binding, but I don't want to-- there's asterisks that's there. But it's not blinded. So same problem is the raw hash-based commitment where if I want to commit to the number 5, and 5 times g, and that's my point that I'm going to use for my commitment.

Same problem-- 4-loop will pretty quickly show you that was 5. How about-- this seems like a good idea. I should say it in the less obviously-- it's not a good idea way. [LAUGHS]

So why don't we add a blinding factor? What would the problem be here? I want to commit to 5. I'm going to add some random number r and then multiply that sum by g, and then when I want to reveal that I was committed to 5-- I reveal 5 and r.

AUDIENCE: You don't know which one is [INAUDIBLE]?

TADGE DRYJA: No, but I can say, look, the first-- well, yeah, the problem is addition is easy to break. When I committed to 5 plus r, I revealed 5 and r, but it's not binding. I can find r prime, which is 5 plus r minus 6. And then 6 plus that r prime is going to be 6 plus 5 plus r minus 6.

I can compute whatever r prime I want and whatever number I want to reveal later. So this isn't binding anymore.

I'm now adding a random thing in, and I'm committing to the sum of the thing I want and a random thing. But it's not binding because that addition, I can play with.

So how about this? I'll hash 5 and concatenate r and then multiply that hashed output by g. Maybe, but then it's no longer homomorphic-- then I can't add.

So if I have the hash of 5 and r1 times g and then the hash of 7 and r 2 times g-- I can't add these anymore And then have the 5s and 7s add up to 12-- it won't work. Because now it's a hash. And I've just got these hashes adding, and you don't really get any meaning there. So that doesn't work either. So we're stuck.

Then the way you do it is totally non-obvious. And introducing g's fraternal twin-- h. [LAUGHS] You make another point on the curve, and you call it h, which is the letter after g.

It's another generator point distinct from g. So you pick one-- here's h. You also need to make sure that nobody knows n such that n times g equals h.

That n might exist, but you want to be sure that no one knows what it is because you know how to move between g and h, then that'll break this.

But if you take two random points, g was randomly chosen, and you chose a random h, this shouldn't be possible. That would be breaking the discreet log problem.

So I shouldn't be able to compute h divided by g-- you shouldn't be able to compute that.

And so I think in a lot of cases, they'll define h as-- take the hash of g's x-coordinate and then assign that to the x-coordinate for h-- something like that. So it looks pretty random-- should be able to find it.

So we've got another arbitrary point on the curve that we're going to start using for multiplying things.

And so this is basically a Pedersen commitment, which sounds involved and it gets involved, but really it's not. At its core, it's not too bad. It's saying we're going to have a blinding factor in the actual value we're committing to.

And so now I'm multiplying the blinding factor by g and the actual value by h. And I'm just adding those two up.

So you know how we can do that? If my actual value is 5, I take 5h by taking the tangent-- getting 2h-- take the tangent again-- getting 4h, and then adding 4h and h by drawing the line between them-- I'll get 5h. And then I'll also get r. r's going to be some giant random thing.

R's not going to be like 5. r's going to be a 256-bit random number, and that will obscure what h was-- sorry. what v was because I added them together.

So this is binding unless I know the ratio. Unless I know h over g, or g over h-- whatever-- same thing-- I can't come up with another r and v pair that gets me back to x.

So I can try. There is one. There's probably bazillions of-- if I could find a different r, I could then reveal that v was 8 instead of 7.

But I can't find that r, because I need to know some way to get between g and h-- some factor n where n times g equals h. If I don't know that, I can't do this. It is binding.

It's also hiding. So you might successfully guess-- I might commit vehicles 5-- do some random number r times g plus 5h, and you might guess correctly. But this should have been g-- oops-- sorry. This is g.

But if I have some really long, random number times g, it's also an x, and you're not going to be able to guess that. So this is also hiding.

And it's homomorphic. So x is r1g plus v1h. y is r2g plus v2h. And what if I want to prove that z is value 1 plus value 2 without revealing them individually? Can you see how I could do that?

I can reveal both r's individually. Well, no, sorry-- I cannot reveal both r's individually because then you might be able to figure out the values.

But I can reveal the sum of the r's and the sum of the v's. So I'm going to define a point z, which is point x plus point y. And that's just going to be the sum of the r values-- the sum of those random values times g plus the sum of the actual values I've committed to times h.

And then I reveal the sums. I reveal this-- I reveal that. And then the verifier can do the math themselves. It's a little hard. I'm revealing r and v, which is equal to this. But I'm not revealing these separately. I only reveal the sums.

And then the verifier can check-- is this r they gave times g plus this v they gave times h equal to these two points added together? And if it is, they've proven the sum.

So, for example, it's binding, hiding, and homomorphic. So this would allow us to make proofs.

Binding, hiding, homomorphic-- you reveal the sum of the r's. You reveal the sum of the v's-- it works.

So basically now instead of coin amounts, which are 8-byte-- they're in 64s-- I just provide elliptic curve points, which are 33 bytes, so it's a bit bigger-- not a huge deal.

I can put another 20-something bytes in my outputs-- no big deal. And then I provide a proof by revealing these sums each time.

So I prove that w plus x equals y plus z. And everyone can see this little w amount of coins-- there's actually y coins. There's actually x coins. There's actually z coins. And there's a blinding factor that all the participants have to keep track of.

So the receiver's views-- they learn their own v and r. When someone sends, they would have to tell the receiver, hey, here's r4. The sender makes up r4.

And they can just compute-- let's make a random r3. And then compute r4 such that r4 plus r3 equals r1 plus r2.

They need to make sure that the randomnesses add up, which is easy because they're regular scalars, and the sender has full control over r3 and r4.

So, basically, make random ones until you get to the last one. And then make the last one such that they all add up to the right number.

And then the sender can say, here's your r4 and here's 2. You're getting 2 coins. And the receiver gets those two numbers and says, I can see that this transaction commits to z-- a point.

And you gave me an r and a v that when I do the operation-- I get z. So I know that successfully, you've revealed that these are two coins. And I can use these values later when I want to send my own coins.

So this works, but there's more problems. [LAUGHS] Any idea what the next big problem is? Yeah.

AUDIENCE: If there are only two outputs, and then c's r4 and d4-- they could be able to [INAUDIBLE] r3 and d3, right?

TADGE DRYJA: Yeah. But that's OK. I mean, there's no way around that. If there's only one input-- or wait-- if there's only two outputs, so if the receiver learns these, they will be able to distinguish-- if you know the total amount of inputs, and there's only one other. You can just subtract and figure it out.

So there's all sorts of things. If there's only one output, that person knows it's the sum of all the inputs.

AUDIENCE: You don't know-- in this case, you don't know the total input, right?

TADGE DRYJA: Right. In this case, they don't have to reveal to you the v's-- they just have to reveal that 2 plus y equals w plus x.

So you don't have to learn their input amounts. If there's only one output, then you learn if this is 2, these must have added up to 2. But I don't learn exactly which.

So this is useful. There's still a big problem. r1 plus r2 is r3 plus r4-- you can prove w plus x equals y plus c-- it works. It's great.

AUDIENCE: Do nodes only mean the bigger transaction-- to know that the inputs you put [INAUDIBLE]?

TADGE DRYJA: Yep. nodes can just compute these numbers, and they're good. So one thing you could do here-- OK, wait.

So there's one thing that you can do to break it. But it's not a big deal. And then there's another thing-- you need a break that's a really big deal. Yeah.

AUDIENCE: Since you're proving sums, is it that you can have a higher likelihood of proving something that doesn't-- like that wasn't actually true?

TADGE DRYJA: Yeah, but how exactly? So one thing you could do is-- I think, I said-- so, basically, you can verify it and put in outputs-- add up all the points-- make sure they're equal.

You reveal r and v to the person receiving. And you don't want to forget r. r is now a private key. If you forget r-- you're stuck. You can't prove anything anymore.

You can make invalid outputs, which are just points with no known r and v. But nobody should accept those. So you can do this where-- I have no idea what-- there is no commitment here.

Maybe these have valid commitments, but this is a point, which is w plus x minus y. And there's no known r values or v values for these things.

And from the network's point of view, this will still be valid. The networks are saying, well, w plus x equals y plus z-- we're good.

But then anyone accepting that transaction-- you're not going to be able to give them an r value. And so they're not going to say this is actual money.

So this is possible, but it's not a huge problem because you can destroy your own money. You can already do that in a million different ways in Bitcoin.

But if you send to it to an output amount that doesn't have an actual r and v value-- that doesn't have a valid Pedersen commitment-- those coins can essentially be destroyed because no one's going to be able to figure out r's and stuff for here.

So that's one issue-- not a big issue. Just don't do that. Don't ruin your own money. Make sure you always have valid commitments.

And when you're accepting payments always make sure that you're given the values and the random blinding factors. So that's one little risk but not the big problem.

Anyone have an idea about the big problem? So as a hint-- all of these things, and I haven't written it because it gets really redundant-- all of these things are like mod p, which is some giant prime number that's 2 to 56 minus 17, or it's not-- in the curve, ed25509 it's 2 to the 255 minus 19. So that's an easy one to remember.

So that's why they call it curve 22519. In bitcoin, it's 2 to the 256 minus some numbers that are not too huge.

So since all of these things are modulo-- some big prime number-- what's a potential problem here? It's a big problem or in some ways the opposite of a big problem. Not a small problem. [LAUGHS] The opposite of a big problem but not small-- big negative problem. [LAUGHS]

You can basically commit to negative values. So I send negative 99 coins here, positive 108 coins here-- the numbers all work out. So you don't have negative.

Usually, if you're doing mod-some integer, you don't think of it as negative, but you can think of being almost right at the top of that modulo range as being equivalent to being a negative 1.

So if you say, I'm going to have p minus 1-- that's some huge number that's within the very allowable range. But it also will let you treat it as a negative 1 for operations like addition and multiplication.

So this would work, and you can calculate what negative 99 is-- that's just going to be p minus 99, or minus 100.

I always am off by 1 when I do these things. [LAUGHS] Wait, is it 100? Anyway, so you can calculate-- it's not really minus 99-- it's some big number that's going to be 32-bytes long-- that's modulo.

Modulo p doesn't change, but it's equivalent to minus 99. So that if I do add these to this huge number plus this other small number, it loops over that modulo and then gets back to-- what, 9.

So this plus this is going to be 9 even though this is some really long number. This plus-- this is going to be nine, and then it all adds up.

And then I've got this either negative or implausibly large value that I've committed to, but I can just ignore that. I can get rid of that.

That negative output will be hidden. No one will see that I've got this negative 99 here-- then I can toss it and end up with a whole bunch of negative values that are anti-coins and a whole bunch of more new coins.

And later on, I can prove I've got valid proofs-- all these w plus x equals y plus z proofs worked the whole time. Shoot-- [LAUGHS] so we're stuck.

We need more than a proof that the sums are equal-- was working really well. But just a proof that the sums are equal is not enough because we're modulo-- this big prime number. And so you can make these negations.

We also need a proof that they're non-negative, and not just not negative, because that negative 99 is essentially p minus 99, which is some huge-- it's 2 to the 256 minus 99-ish. So it's not just that they're non-negative-- we have to prove that they're reasonably sized-- that they're fairly small.

So if you could prove this number is non-negative, and it's less than 2 to the 64-- that would be cool. How can we prove something about the number itself without revealing it?

So now this is an even trickier problem, because, before, we wanted to prove a sum. We wanted to prove that z equals x plus y.

I don't want to tell you what x plus y is, but I'll tell you what z is. That was proving a relation between these numbers. This is just proving something about that number itself individually.

We have to prove individual numbers-- ranges. So we have to say, this to 2h-- there's a 2h in there, and I can't show you it, because I'm just committing a w.

But I want to somehow show you that the v here-- which should happen to be 2, although I'm not going to tell you-- the v there is within a small range-- without telling you what it is-- without revealing it-- tricky.

So what you can try to do is sign with the points. Somehow, this is what'll get us there. The idea of we've got these Pedersen commitments-- we've got these points on a curve-- those are public keys. That's how we used to usually think of them.

Can we sign? We know the private keys. We know r1. We know 2. Can we make signatures somehow and somehow use that to reveal some information about h but not too much?

So the signature equation-- I didn't really review as much, but we've talked about this a couple times. Come up with a random value k-- take the hash of k times g and the message to be signed times your private key-- that's your signature s.

The problem is x. Your value that you've got committed to here-- it's r2g plus 7h. What's your private key here? Well, it's our 2 plus 7. But, no, because you know the private scaler's here. But there's 2 points involved in this key.

So you can't make a signature. Generally, signatures are with respect to a single generator point.

The way to verify this is to multiply both sides by g. s times g should be k times g minus the hash of k times g, message times 8 times g which is a public key-- that works.

But now you've got h in here. So we're stuck. We could try to define another signature thing with both h and g, but that doesn't work.

But what we can show, which is kind of interesting, well, what if v is 0? Then x is r2 times g plus 0h, which is just r2 times g.

This is nothing. There is no h here. And that means my private key's going to be r2. Well, now I can sign-- now I can re-sign with respect to g with this point x that I've committed to because the value is zero. The value-- the thing that I'm multiplying by h is 0.

So it'll work for a signature system. The same regular old signature equation that we use, I can sign a message with key "big X." And so this is a proof of a 0 value-- I'll sign with my own key.

So if x is some random blinding factor times g plus 0 times h-- where v, the value you're committing to is 0-- well, that means that the signature is just-- so, the question is, what message do you sign? Well, maybe sign the message which is the pubkey itself. You don't need to sign a message but throw that in there.

And then this will work. And someone can say, hey, here's a signature from key x. And the signature is arbitrary. It can be a signature of any message you want. But the fact that they are able to produce a signature reveals to you that v is 0.

So that's cool. It's not that cool, right? Because, well, I just revealed my value, and it revealed to be 0. But I did it without revealing r. So that is cool, right?

I could do it by saying, hey, here's my r and v values-- multiply them and add them up to see that it gets to the point I committed to. But I can now prove that-- I can prove something about v without revealing anything about r.

Before-- we were saying, the way you reveal these commitments is you reveal the blinding factor, and you reveal the value itself. Well, now I can keep the blinding factor secret and reveal a little bit of information about v.

This works, and you can't sign if h is non-zero. You're not going to be able to-- you're not going to be able to calculate any valid signature unless v is-- ah. V is non-zero. Sorry.

So you can also do this with a proof of v equals 1. Again, sign your own key. So you define x prime to be just x minus h.

And then you can say, well, look, I'm going to prove to you that v is 1, and the way I do that is take the point I've committed to x, subtract h from it, and I'll

provide a signature on that new point. Well, this should be v. I can't do that unless v is 1. So if I have this, and then I subtract h, then I get back to r times g. I can now provide a signature just using r-- it'll work.

So what does this get us? We can prove that v is 0, or we can prove that v is 1, or, really, we can prove that v is anything. Just subtract a whole bunch of h's and subtract 7,000 h and now provide a signature. And that proves that v was 7,000.

But wait, we just revealed v, so what's the point? Did that really get us anywhere? If we can make a signature that reveals the value we've committed to with hiding the rest of the stuff-- is that useful? If it's kind of cool, but what can we do with this? Any ideas?

So there's another part that I didn't have time to introduce, but maybe will at some point, and you can read about it. It's really cool.

Ring signatures-- a ring signature is similar to a normal signature. You've got key pairs. You've got sign, verify, but there's a set of public keys during the signing and verification process.

So the basic idea is, I sign a message with one of the public keys, but I don't tell you which one. And you verify that, yep, there was a signature here. I'm not quite sure who signed it.

There's possibly three or four different people who may have signed it. But I know one of them signed it but not which.

So, basically, it's the key-generation step-- same as before. You have some keygen-- takes in some randomness, and it spits out a private key and a public key for you. And you can use those later.

Sign, on the other hand-- sign function used to have the message to sign in your private key, and it would output a signature.

In ring signatures, you sign with the message you want to sign-- your private key and then pick a list of other people's public keys.

And this list can be just a single one. It can be 1,000. You pick a bunch of other people's public keys, and you generate a signature.

And then verify, you use the signature to-- take the signature in-- the message that's been signed, and that list of pubkeys.

And it outputs a Boolean of, yep, that signature worked, or, no, it didn't but it doesn't tell you which of the public keys is signed.

So this is a really cool idea. I think the initial paper was How to Leak a Secret, which was-- and then there's different papers about different more efficient ring signatures.

But this is a really cool thing to use. I think this could be really cool for a lot of different things. If people had public keys that they were associated with and wrote them on their business cards and stuff like I do-- you could then have leaking information that's more credible.

So instead of just the newspaper saying, sources close to the matter said x, y, z, or a top official at the White House said this.

You could have it being signed, and we've got all these different White House officials' public keys-- one of them signed this message.

So either there was a key compromise, and they all lost their keys, which is, in practice, probably more likely in that case, or one of these people signed this message, and I know it's one of them, but it doesn't reveal anything about which of the public keys-- so, that's pretty cool.

So you can verify it's from a key in the array of public keys but not which. So let's put these together. I can sign with x to prove that v is 0. I could also sign with x prime, which I'm defining as x minus h to prove that v is 1.

Well, what if I have a ring signature where I say I'm going to produce a signature from both of these-- from one of these 2 public keys. And that would prove that v is either 0 or 1. But it doesn't prove which. Make sense?

So the idea is, I can make these signatures that essentially reveal what v is. They indirectly reveal what v is by saying there's no way I could have made this signature unless v was 0, or unless v was 1 because you're-- you know that the h component-- v is the coefficient for h.

So you need to know that I don't have an h component in there if I'm going to make a signature with respect to g.

And I can make any number of different x primes by subtracting different amounts of h. But a single signature would just reveal what v was, which isn't useful.

But a ring signature, whereas there's 2 different pubkeys-- one of them's x-- one of them's x prime, we just subtract h. And I'm going to provide a ring signature from one of these 2 pubkeys.

Now I've proven to you-- well, v is either 0 or 1-- it can't be both. But it can't be 2. It can't be 3. It's got to be one of those two values. So does this make sense? Questions on this? Yes.

AUDIENCE: What does unverified look like? How does it verify that?

TADGE DRYJA: Oh, well, the original scheme is kind of complicated. The one used in confidential transactions is Borromean ring signatures.

You do a bunch of hash functions. I don't know it. I don't even really know it well enough myself to really be able to explain it in a minute.

But, basically, you compute something on all of the pubkeys, and then verify the signature on the aggregate pubkey as a way to think about it. The signatures can-- the computing time gets big with a number of pubkeys.

So if you have millions of pubkeys that could possibly be signing-- the verification algorithm gets really time-consuming. So I can maybe go into ring signatures another time. Yeah.

AUDIENCE: I thought the point of this was to prove that v is non-negative. So right now, we're just saying it's not-- it could be two values. How does it help us through the signs?

TADGE DRYJA: Well, neither of these are any good. So we've just proven-- we've done quite a bit more than prove it's non-negative. We've proved that it's exactly 0 or exactly 1. We might want more values.

So make a ring signature from a million different public keys where the pub n is just pub n minus 1 minus h. And then I just proved that v is somewhere in the range from 0 to 99999. Yeah.

AUDIENCE: What is computation time for ring signatures as the number of public keys?

TADGE DRYJA: Yeah, it goes up. The best is linear, or, no, there might be-- sorry-- there's probably sublinear now. But this is not feasible. [LAUGHS]

The traditional ring signatures are linear with the number of public keys to be verified. So if you did this-- well, all even then, you'd have to throw, though, because-- you have to at least throw the public key into the verification function. And so that means you need to compute a million pubkeys-- throw it into that function. It's going to take a long time. So this is not itself going to work. Yeah.

AUDIENCE: Just Monero uses ring signatures?

TADGE DRYJA: Yes, Monero uses ring signatures for a different reason. Well, now they use it for this kind of thing, too.

The Monero ring signature was initially used for not hiding the amounts but hiding which outputs were being spent.

So in Bitcoin, everyone should-- So in Bitcoin if you have a transaction-- here's my input, here's my output. And the simplest one is just-- this points to tx5 or something, and then my output is address-- and it's address b, and it's got 7 coins.

Everyone can see what you're spending. The idea in Monero is, I don't point to an input-- I just provide a signature. And it's up to you to figure out where that signature's from.

So I provide a signature and a list of pubkeys-- pub a-- pub b. So the smallest would be 2. And then I provide a key-- key in a number.

So the idea is instead of thinking of it as outputs, you think pubkeys have associated values. You don't look at the transactions themselves.

This is key c. And there previously have been-- pubkey a and pubkey b have had values-- 7 coins sent to them.

And I can now say, look, I'm going to provide a ring signature from either pubkey a or pubkey b. And I'm not going to tell you which, but you can see that both pubkey a and pubkey b have received 7 coins in the past. I want to send 7 coins over here. I'm going to prove that I own one of those two. And then you can validate that the transaction's valid.

And then if later, you see another transaction with a ring signature from pub a-- pub b-- also sending to the key d-- 7 coins.

Now, I can delete pub a and pub b. I don't know which, this-- so in transaction 1, I don't know whether a or b was spent, but one of those two was. And then in transaction 2, I don't know whether a or b are spent-- one of them was.

But anyway, they've both been spent now. And so I can delete them from my storage. But the ring signature's in Monero were used to obscure the transaction graph itself-- where you can see that there's a bunch of different keys that have money associated with them. And I'm going to provide a signature that I own one of them, but I don't tell you which.

And now they also do confidential transactions to obscure the outputs using ring signatures as well.

So I don't-- well, it's interesting. I haven't looked at it that closely. So I know that's the basic idea. But there's a lot of subtle details involved in how that works, and I'm not super familiar with that.

So I can finish up. So the way to make this practical is, let's say you have a ring signature for each bit, so you're going to have to have a different signature for each bit in your value.

So the pubkey x0-- well, I'm going to have a ring signature where I prove that it's either 0 or 1. And here I'm going to prove it's either a 0 or 2. Here I'm going to prove it's either 0 or 4.

And so if I have 32 signatures, I can now prove a 32-bit number. Each of those individual signatures only has 2 public keys associated with it. So that's now more feasible.

There's a total of 32 public keys, 32 signatures-- not the end of the world-- still kind of ugly. And then there's optimizations where since these pubkeys are all the same, the 0 value for that bit-- we can squish them together and stuff to make it a little bit smaller.

So you have a signature per bit of your output. If your values are not too big-- this works. We're going to limit it to 32-bits. So from 0 to 4 billion.

Now you can prove that each bit was either a 0 or 1, essentially, without revealing whether it was a 0 or 1.

And then it's a couple of kilobytes per output. So it's a little bit annoying. It used to be 8 bytes. You said, hey, I've got 37 points. Also, these 8 bytes are very sparse in that they rarely exceed 4 bytes.

So you can compact it down on disk. So this is a little-- scalability-wise, it's an issue. You're now going from what used to be 8 bytes is now a couple kilobytes.

I think they've got it down to 2 kilobytes. But still, that's 2 kilobytes. And it takes a bit more CPU time to verify. Because now, instead of verifying one signature to see that the coins are moving to the right place, you're verifying 30-plus signatures for every input and output.

Also, the real problem is it's not really compatible with Bitcoin-- this would be a really tricky fork to implement.

How do you implement this such that the old software on the network is OK with these transactions where they're expecting a transaction that has a value?

Here's how many coins are being moved. If you say, no, I'm not going to tell you anymore. Well, old software doesn't know how to deal with this and by default, will reject these transactions.

So there's ways to do it that doesn't break compatibility, but they're pretty ugly. One of the ways is to say, OK, from now on, all these transactions-- all output values have to be 0.

So the old software will still work, but it will be pretty confused and say, I see all these values. I see thousands of transactions. No one seems to be sending anyone any money. So they seem to be pointless.

And then there's this hidden value that's in a different data structure that would look something like segwit. And segwit was a little bit ugly-- this would be real ugly. Those are the trade-offs we're dealing with here-- tricky fork.

But you get this. This is what you get when you use confidential transactions. You got it, right? We have private, unlinkable amounts where the network can verify-- OK, let me verify that w plus x equals y plus z-- that's the easy part.

Now, let me verify for every individual w, x, y, and z that it is within the range of 0 to 6223222232-- 02 to the 32-- it's a tongue-twister-- by verifying all these separate ring signatures for each bit of the amount.

But you can do it, right? You can verify-- input amounts equal output amounts. All these input amounts and output amounts are normal looking numbers that aren't too big that aren't right up near the modulos to wrap around. And it works-- it's just big and slow-- we're trying to make that faster.

So probably not going to go-- if you're interested in this, though, there's a lot of research about this kind of thing right now. It's really cool getting in the crazy, interesting math.

So there's bulletproofs, which was Benedict's at Stanford. He wrote up-- I mean, a bunch of people wrote it, but I think it was sort of his idea, or his thing working with other people, too.

That's more efficient range proofs. I do not know how bulletproofs work. I tried to read the paper and got two pages in, and I don't know. [LAUGHS] But I'm sure I could figure it out-- it would just take me a long time.

And then the Borromean ring signatures-- the more efficient ring signatures that can compact a lot of data so that you're not-- so you get it down to two kilobytes for these range proofs in confidential transactions.

And then I may try to give a class about this in a week or two-- MimbleWimble. The idea is that when all of the transactions in the network are like this and that have confidential inputs and outputs amounts, the transactions can be canceled out in an interesting way.

Because the output amounts are unique. They have these blinding factors. They have these range proofs. And so if you're in a block-- so just a hint about MimbleWimble-- the idea is if you have a transaction and amounts are all obscured. But a is being consumed, b is being consumed, c is being created, d is being created. These are amounts.

And then I see later in the block there is another transaction which spends d coins and sends to e coins.

I don't have to verify that a plus b equal c plus d. And d equals e kind of thing-- I can just cross these out.

And I can verify on a block-level instead of a transaction-level that the input amounts and output amounts all matched up because I don't know what d is.

But, anyway, it was on an output side and on an input side within the same block. So, anyway, it's gone. It's being added to and subtracted in this block.

So I can do that. And I can do that over multiple blocks. And I can basically keep a tally of how many coins are in the system and cancel things out.

So that lets you do some really cool things where you can skip a lot of verification at no loss of security.

So that's the idea of a MimbleWimble, which is really a fun paper because it was written by Lord Voldemort.

Someone posted a Pastebin link on IRC. And who knows who wrote this-- Lord Voldemort. Except it was Lord Voldemort-- the French word for Lord Voldemort.

So when they translated Harry Potter into French, they changed the names around, I guess, and it was the French equivalent of Lord Voldemort.

And so now there's a bunch of people programming MimbleWimble and implementing it. And they all use Harry Potter-- not all of them, but a lot of them use Harry Potter names on GitHub. So it's kind of funny.

It's also really funny that it was one of the most-- I would say, the most-- whoa, kind of paper of 2016 now.

And so it's of an interesting indicator of the space we're working in that you've got IBM and all these big companies, and they're working on blockchain research, and, honestly, not a ton of awesome stuff, whereas like, whoa, MimbleWimble, OK, Lord Voldemort-- he really showed everyone. [LAUGHS] So it's fun that it's still a very out-there hackery system.

So that's-- hopefully, most people got most of the idea. It's a little bit fast. It sort of explained all the Pedersen commitments and range proofs and everything in a little bit of time.

But I think you got the idea. And if you're interested in it, there's a lot of current research on this and people implementing it. And there's a lot of cool things you can do with it, so.

## Welcome!

This is one of over 2,200 courses on OCW. Find materials for this course in the pages linked along the left.

**MIT OpenCourseWare** is a free & open publication of material from thousands of MIT courses, covering the entire MIT curriculum.

**No enrollment or registration.** Freely browse and use OCW materials at your own pace. There's no signup, and no start or end dates.

**Knowledge is your reward.** Use OCW to guide your own life-long learning, or to teach others. We don't offer credit or certification for using OCW.

**Made for sharing**. Download files for later. Send to friends and colleagues. Modify, remix, and reuse (just remember to cite OCW as the source.)

Learn more at Get Started with MIT OpenCourseWare