[00:00.000 --> 00:03.060] Let's give a warm welcome to Filippo Valsorda and Ryan Castellucci. [00:08.940 --> 00:12.500] I'd like to start out by thanking everyone for coming to our talk. [00:12.900 --> 00:14.280] I am Ryan Castellucci. [00:14.580 --> 00:18.260] I work for a company called White Ops, but this is just a side project. [00:18.760 --> 00:24.320] At DEFCON 23, I gave a talk called Cracking Cryptocurrency Brain Wallets. [00:25.520 --> 00:31.160] And since then, I've co-authored a couple of papers about Bitcoin cracking. [00:32.560 --> 00:33.440] So, hi. [00:33.800 --> 00:34.980] I'm Filippo Valsorda. [00:35.080 --> 00:39.800] I work at Cloudflare, but just as above, this is a completely side personal project. [00:40.340 --> 00:48.240] At the last Hack in the Box in Kuala Lumpur, I spoke about using ECTSA mistakes to compromise Bitcoin private keys. [00:49.320 --> 00:56.920] Now, we all know that math is scary and dangerous, and if you see someone doing math, you should say something, right? [00:58.360 --> 00:59.000] Good. [00:59.460 --> 01:03.260] But, how is math exactly dangerous for Bitcoin? [01:04.080 --> 01:08.580] Obviously, to understand this, we need to understand a bit more about how Bitcoin works. [01:09.460 --> 01:13.300] Now, these are the fundamental pieces of Bitcoin. [01:13.300 --> 01:18.560] You start with a private key, which is nothing else than random bytes. [01:19.100 --> 01:28.220] And you convert that into a public key, using some crypto black magic that I'm not going to go into the details of right now. [01:29.040 --> 01:32.020] And then you hash that public key to get an address. [01:33.040 --> 01:38.680] Now that you have an address, you can use it to receive Bitcoin from other people. [01:38.680 --> 01:45.420] Because people can use this address to send Bitcoins they own themselves to you. [01:46.720 --> 01:51.640] All these addresses are published on the Bitcoin public ledger, which is called the blockchain. [01:52.440 --> 02:02.500] So every time an address receives some money, some Bitcoin, that is logged on this append-only blockchain. [02:02.500 --> 02:10.020] And anyone has a complete idea at any time of all the addresses that hold any balance. [02:11.040 --> 02:21.240] Now, whoever had the private key that generated this address can use that private key to spend the Bitcoin it just received on that address. [02:21.760 --> 02:22.880] So far so good. [02:23.040 --> 02:24.960] This is probably something you already knew about Bitcoin. [02:25.980 --> 02:45.120] And so obviously you can also imagine that if what we want to do is stealing Bitcoin without literally just hacking into the server that stores them or buying a wrench, a $5 wrench to get the money out of the person that owns the Bitcoins. [02:45.880 --> 02:51.400] What we will want to do is to somehow compromise or guess or figure out the private key. [02:52.620 --> 02:59.600] And here, obviously, the simplest thing that could work is to just try them all sequentially. [03:00.560 --> 03:06.400] Now, you start with the private key number one because the private key number zero is not valid. [03:07.180 --> 03:19.080] And you do the crypto black magic, you get the public key, you hash into an address, you go to the blockchain and you check if that private key holds any balance. [03:19.700 --> 03:22.140] And then you do the same for two, you do the same for three. [03:22.880 --> 03:25.520] Now, I swear that this is not all the talk is about. [03:25.740 --> 03:29.780] We're not here to tell you that you can just go over all the private keys and steal everybody's Bitcoin. [03:31.340 --> 03:33.560] But stupid things sometimes actually work. [03:36.880 --> 03:42.580] As part of my DEFCON talk, I released a tool called Brain Flare, which was used for cracking brain wallets. [03:42.700 --> 03:46.220] But I've since modified it so that it can also do this attack. [03:46.580 --> 03:53.220] And sometimes doing, as Filippo said, doing a stupid thing really fast is a decent attack. [03:53.220 --> 03:57.560] So, I did a scan. [03:58.360 --> 04:00.460] We actually did find some results. [04:02.540 --> 04:05.460] I don't know if I'd say I was surprised, but results. [04:06.480 --> 04:11.640] I went through about the first 150 billion possible keys, got 149 hits. [04:11.800 --> 04:13.000] This was back in February. [04:14.080 --> 04:26.160] One interesting thing I noticed is that there were a lot of patterns that looked kind of like people were deliberately leaving Bitcoin around, playfully, to see who would take it. [04:27.100 --> 04:39.220] And that's really interesting because from some of that I was able to infer that somebody has actually tried guessing the first 700 trillion keys. [04:40.800 --> 04:43.940] And it looks like it was over the course of less than a year. [04:44.120 --> 04:47.320] So, I'm guessing they have something faster than Brain Flare. [04:47.540 --> 04:50.480] Probably a big ol' botnet or a GPU cracker. [04:50.480 --> 04:56.860] But the highest possible private key is really, really big. [04:57.020 --> 05:00.840] I don't know that we have a word for this number, but it's large. [05:04.400 --> 05:08.460] So, you know, sequentially searching keys got old. [05:09.000 --> 05:15.820] And what's the next thing that I can do that is also dumb but slightly more creative? [05:15.820 --> 05:17.800] Well, patterns. [05:18.180 --> 05:29.040] So, this first one appears to have been generated by taking the string 1234 in ASCII and using it as the least significant bits of the private key. [05:29.160 --> 05:35.760] These are all real private keys that were really associated with Bitcoin at some point. [05:35.760 --> 05:38.400] They are all long since emptied though. [05:39.780 --> 05:41.780] So, I tried putting strings in. [05:41.860 --> 05:42.620] That didn't really work. [05:42.920 --> 05:46.900] I tried keys that only had a few bits set. [05:47.100 --> 05:47.880] That got a few. [05:48.500 --> 05:49.940] Some stupid patterns. [05:50.900 --> 05:53.640] You know, starting with 42. [05:53.880 --> 05:54.840] 42 is a great number. [05:56.240 --> 05:57.240] Yeah, patterns. [05:57.240 --> 06:00.800] And so, that got old too. [06:01.100 --> 06:04.380] So, I had to get a little creative again to find more things. [06:05.940 --> 06:11.120] Again, these are all real private keys that really were associated with Bitcoins at some point. [06:11.700 --> 06:18.100] So, the formatted addresses you see aren't actually what's used in the Bitcoin protocol. [06:18.340 --> 06:20.220] There's actually a raw format. [06:20.220 --> 06:27.200] So, I took all of the raw formatted addresses and tried them as least significant bits of private keys. [06:27.500 --> 06:29.120] And I got hits there too. [06:30.460 --> 06:31.580] I don't know why. [06:33.540 --> 06:36.220] And then, I tried the... [06:38.480 --> 06:44.060] This is a little out of scope of the talk, but every block in the blockchain has a specific hash. [06:44.420 --> 06:46.140] I tried running all of those through. [06:46.320 --> 06:47.400] I got hits there too. [06:47.400 --> 06:54.620] Then, I just tried dumping the entire blockchain, each offset one byte at a time, through there. [06:55.060 --> 06:56.280] That got hits as well. [06:56.420 --> 06:58.640] And I don't even know what those are. [07:01.400 --> 07:01.960] Okay. [07:02.300 --> 07:04.460] So, this was all fun and laughs. [07:04.780 --> 07:14.760] But obviously, just searching the entire private key space sequentially or by shooting in the dark is not exactly something we can keep doing. [07:14.760 --> 07:20.100] So, we need something to limit the search space of possible private keys. [07:20.760 --> 07:25.040] And when you're looking for this, something that is very useful to know about is brain wallets. [07:25.680 --> 07:34.280] Now, the idea of brain wallets is to be able to control some money, some Bitcoin, with just something that you can keep in your head. [07:35.020 --> 07:39.060] And this may seem like a good idea because nobody can read your mind, right? [07:39.820 --> 07:47.480] But, as we learned, a fast computer can probably take a very good guess at anything that you are able to remember yourself. [07:48.880 --> 07:56.220] So, how brain wallets work is that they just add another step in the derivation process we've seen before. [07:56.560 --> 08:12.340] So, to generate the private key, they just take some memorable string, like correct horse battery stable, or whatever you're using, and hash it to get a private key that then is used to generate the public key, to generate the address, which they use to receive money. [08:12.940 --> 08:19.220] And then, by just remembering that string, you can move that money and use it to pay for something else. [08:20.240 --> 08:29.100] Sure, the idea of using passwords to save money is already kind of unsettling. [08:29.260 --> 08:43.500] But, since we've learned so much about password storage and how to make sure that database dumps are not cracked, you would think, well, obviously they used something slow, something like bcrypt or scrypt, that is hard to brute force, right? [08:44.200 --> 08:45.080] You'd be wrong. [08:46.060 --> 08:47.860] They use SHA-256. [08:49.400 --> 08:51.440] A perfectly cromulent hash algorithm. [08:55.820 --> 09:05.260] So, for my DEFCON talk, I did a bunch of research into cracking brain wallets, and I went through the transaction history of a lot of them that I was able to find. [09:06.300 --> 09:09.020] Correct Horse Battery Staple was, in fact, used. [09:09.240 --> 09:13.040] It's had about 15 Bitcoins go through it, give or take. [09:14.480 --> 09:16.500] And over 4,000 transactions. [09:17.860 --> 09:21.580] There's a complicated reason for that, if you want to know why, find me later. [09:22.480 --> 09:23.620] Then, Bitcoin is awesome! [09:24.800 --> 09:30.740] Had 500 Bitcoin put into it at once, and then somebody else found it. [09:30.740 --> 09:33.400] And whoever put it there originally was sad. [09:33.920 --> 09:36.400] My favorite, though, is the empty string. [09:37.060 --> 09:39.560] Nobody would ever guess that one. [09:41.320 --> 09:46.780] That has had almost 60 Bitcoin go through it, and 50 of it was all at once. [09:47.780 --> 09:49.560] Somebody had a really bad day. [09:50.920 --> 09:52.380] Because it was stolen instantly. [09:53.240 --> 09:58.800] The quick brown fox jumped over the lazy dog, has had about 100 Bitcoin go through it. [09:59.800 --> 10:03.840] So, yeah, people do some things. [10:05.400 --> 10:09.220] So, of course, I'm not the only one who's had this idea. [10:09.580 --> 10:16.720] There are plenty of other people who have gone through with quite extensive dictionaries and guest brain wallets. [10:16.880 --> 10:22.520] This fellow was active on Reddit and the Bitcoin forums for a while. [10:22.520 --> 10:27.960] He would crack the addresses, sweep them off for safekeeping. [10:28.220 --> 10:40.500] I have no idea how much he actually kept, but anytime somebody would complain about getting their brain wallet ripped off, if he had the key, he'd show up and offer to return it. [10:42.380 --> 10:44.000] Some people were not so nice. [10:45.260 --> 10:50.400] This other fellow came on Reddit to complain, because that's what people do on Reddit. [10:51.240 --> 10:54.180] He lost four Bitcoins out of his brain wallet. [10:54.400 --> 10:59.300] And the passphrase was a line from an obscure poem in Afrikaans. [10:59.920 --> 11:05.300] So, somebody had some pretty serious dictionaries they were throwing at this. [11:07.480 --> 11:08.740] Which is really interesting. [11:10.300 --> 11:13.960] And if you're curious, what sort of performance can be done with this? [11:14.120 --> 11:21.660] Brain Flare itself, in the latest version, the biggest job I've run in it was checking all six character ASCII passwords. [11:22.040 --> 11:25.660] That ended up being a search space of a little less than 750 billion. [11:26.220 --> 11:31.900] I did that in less than 24 hours for $50 on Amazon's cloud computing service. [11:40.360 --> 11:55.940] So, to hammer in the point of how dangerous it is to essentially take a password dump that is already public, because it's in the blockchain, and putting money on it, after not even using S script, we're gonna lose some money on stage. [11:56.440 --> 12:03.520] So, what we're gonna run here is a simple script that now will generate a brain wallet with short enough keys. [12:04.480 --> 12:06.260] That's the brain wallet password. [12:06.680 --> 12:08.600] And it will send some money to it. [12:09.300 --> 12:11.520] And if the demo gods are with us... [12:13.860 --> 12:16.120] Okay, so this is the blockchain.info page. [12:16.600 --> 12:23.580] And this is our transaction that just deposited some money in this very vulnerable brain wallet. [12:23.700 --> 12:25.640] It's currently spreading through the network. [12:25.940 --> 12:28.980] And with a little luck, somebody will be watching. [12:29.760 --> 12:31.060] Obviously, nobody can... [12:31.580 --> 12:32.040] Oh, there we go. [12:32.300 --> 12:32.800] All right. [12:35.360 --> 12:35.920] Yeah. [12:36.700 --> 12:37.260] Yeah. [12:37.400 --> 12:38.600] I'm sure this guy loves us. [12:38.720 --> 12:40.340] He's been stealing our test wallets all day. [12:46.080 --> 12:46.640] Okay. [12:47.420 --> 12:54.840] Obviously, nobody can compute all the ASCII five characters phrases in such a short time. [12:54.840 --> 13:06.640] So what happened here probably is that they have a huge database of all the possible addresses and mapped to the original private keys. [13:06.820 --> 13:17.860] So that as soon as they see a transaction depositing money in such an address, they can immediately, it took 40 seconds or less, steal the money that was deposited in it. [13:18.360 --> 13:23.460] Sadly enough, it used to be that even stronger brain wallets would be stolen on the fly. [13:23.460 --> 13:31.240] And instead, right now, we still have some money on a six-character brain wallet that nobody has webbed, which was kind of disappointing. [13:31.920 --> 13:41.160] Anyway, this guy was not disappointed because you can see that it has four Bitcoin and that's been just like since November 2015. [13:41.580 --> 13:43.780] Yeah, that's currently worth about $3,000. [13:45.240 --> 13:48.160] Okay, so got the point. [13:48.360 --> 13:54.820] We shouldn't be using password to save money on them after they get published. [13:55.580 --> 13:55.840] Good. [13:56.300 --> 14:04.260] So brainwallet.org had this other button that inspired so much more trust, this random button. [14:04.580 --> 14:10.720] A random private key is definitely something that nobody can figure out because the search space is so vast, right? [14:11.060 --> 14:20.860] So what you will do instead of making a brainwallet with correct horse battery staple is that you click the random button and you write down the private key, maybe. [14:21.660 --> 14:22.460] Yeah, good. [14:23.820 --> 14:28.920] Now, something that you should be asking, I guess, is where does this random value come from? [14:29.480 --> 14:36.120] Well, obviously, the site owner is responsible and it's probably coming from the local browser, from JavaScript. [14:36.440 --> 14:38.460] So you can check the code that generates it. [14:39.020 --> 14:53.640] And indeed, it's this function called Crypto Util Run Bytes, which I'm sure is absolutely fine function that is not... [14:53.640 --> 14:54.240] F*ck! [14:59.380 --> 15:00.080] Ah. [15:04.080 --> 15:04.720] Sorry. [15:05.080 --> 15:11.820] So there's still research to be done on this, but the weakest case I could find was the Firefox random number generator. [15:13.000 --> 15:30.100] At the time this site was popular, it would be seeded with the number of milliseconds since the Unix epoch, which, if you don't know, is midnight January 1st, 1970, XORed with two pointers. [15:30.100 --> 15:35.240] And the way the two pointers were chosen, they were almost always very close in value. [15:35.440 --> 15:42.100] So you could just ignore the pointers and figure it would be about right if you just use milliseconds. [15:45.040 --> 15:53.980] So if the seed is predictable, somebody can predict the seeds and replay what would have been generated. [15:53.980 --> 15:56.900] And, in fact, this happened. [15:57.820 --> 16:01.600] As we said earlier, people go to Reddit to complain about theft. [16:02.020 --> 16:09.120] And this guy lost a couple Bitcoins and posted his address, hoping that somebody would be nice and return them. [16:10.300 --> 16:13.400] Unfortunately, he was not in luck there. [16:14.520 --> 16:20.860] So I took a look at the transaction history on this address and looked at the time it was initially funded. [16:21.240 --> 16:23.560] And I ran a scan. [16:24.300 --> 16:31.540] And I was able to find the timestamp, which was very close to the time the address was originally funded. [16:31.680 --> 16:34.200] This is, I think, a date mid-2013. [16:35.600 --> 16:41.320] And with the seed, I was able to recover the private key and verify that it matched the address posted on Reddit. [16:41.320 --> 16:41.420] All right. [16:42.700 --> 16:43.500] So, good. [16:43.620 --> 16:46.160] Now we know another way not to generate private keys. [16:46.320 --> 16:46.840] Math random. [16:47.740 --> 16:47.980] Good. [16:48.400 --> 16:49.040] Note taken. [16:50.740 --> 16:56.760] Now, to graduate to the next kind of attacks, however, we need to expand our Bitcoin knowledge a bit. [16:57.440 --> 16:59.380] We're going to be talking now about transactions. [17:00.220 --> 17:06.800] I've mentioned before that how money moves in Bitcoin is that something is published on the blockchain, right? [17:06.800 --> 17:13.300] A transaction on the high level is just this public statement that says, so I own this money. [17:13.480 --> 17:18.580] And please make this money be owned by this other address now instead. [17:18.920 --> 17:19.740] And this is a payment. [17:20.840 --> 17:31.720] You sign this statement with your private key, which proves that whoever owned that money before, owned that address, actually wants that money to change hands. [17:31.720 --> 17:40.560] And this is recorded on blockchain, so we have access to this gigantic database of statements with their signatures and public keys. [17:41.140 --> 17:56.120] So, we can take any transaction and we'll see the public key that sent the money, the signature from the corresponding private key, and the target addresses which are meant to be the next owners. [17:56.120 --> 17:56.960] Okay? [17:57.480 --> 18:06.360] So, obviously, the idea here is that anyone can verify that the public key actually hashes to the address that used to own that money. [18:06.660 --> 18:11.780] And they can use the public key and the signature to verify that the statement is true. [18:12.080 --> 18:20.620] And so, the entire network can go to their ledger, to their balance, and say, okay, this address now has a different balance. [18:20.620 --> 18:25.960] And this is how Bitcoin accounting works. [18:27.140 --> 18:33.880] Now, obviously, it's not exactly as simple as I put it, and it's much more flexible than that. [18:34.060 --> 18:43.620] Because transactions are actually full scripts that essentially pose a challenge to someone that has to be solved to be spent. [18:43.900 --> 18:48.660] But usually, this challenge is just sign a statement that says you want to move the money. [18:48.660 --> 18:54.640] So, back to our high-level approach, because this is all we really need to start cracking. [18:55.320 --> 19:01.640] Now, next step is what exactly is this signature, right? [19:02.040 --> 19:05.960] So, this signature is an ECDSA signature in Bitcoin. [19:06.340 --> 19:10.620] ECDSA is the elliptic curve digital signature algorithm. [19:10.620 --> 19:13.760] An algorithm that does two jobs. [19:13.940 --> 19:16.640] With a private key and a message, makes a signature. [19:16.920 --> 19:21.780] And with a signature, a public key and a message, says, yes, it's true or no, it's false. [19:24.060 --> 19:25.980] Now, a fair warning here. [19:27.060 --> 19:28.260] ECDSA is math. [19:28.700 --> 19:32.680] So, we are about to show math on the slides. [19:32.680 --> 19:37.980] If there's anyone with serious sensibility to the topic, you should leave the room now. [19:38.420 --> 19:39.760] There is math ahead. [19:40.140 --> 19:41.300] Have I been clear? [19:42.440 --> 19:43.040] Excellent. [19:43.340 --> 19:46.880] So, this is how a ECDSA signature looks like. [19:47.000 --> 19:47.640] I want it. [19:49.000 --> 19:51.820] Now, let's break it down into pieces a bit. [19:52.300 --> 19:57.120] We have G, which is the global curve base point. [19:57.120 --> 19:58.580] This is always the same. [19:58.580 --> 20:00.060] It's a property of the curve. [20:00.260 --> 20:02.720] And all Bitcoin transactions use the same. [20:03.320 --> 20:04.820] Then, there's K. [20:05.200 --> 20:10.280] K is this random number that every time anyone makes a transaction, they have to come up with. [20:10.560 --> 20:11.900] It's a long number. [20:11.900 --> 20:13.600] It's 256 bits. [20:13.940 --> 20:19.860] And it's supposed to be, again, unpredictable, random, and new every time you make a transaction. [20:20.900 --> 20:23.620] And then there's D, which is the private key. [20:23.880 --> 20:26.680] The private key is just the one we've seen in the first slides. [20:26.680 --> 20:28.560] It's just interpreted as a number. [20:28.780 --> 20:30.940] Because, again, ECDSA is old math. [20:31.040 --> 20:37.720] So, all string of bytes are just interpreted as this very long ass number and used in normal math. [20:38.420 --> 20:43.280] And finally, there's Z, which is the hash of the message you are trying to sign. [20:43.580 --> 20:55.440] In Bitcoin, the message is, if you remember, the sentence that says, the script that says, this money I used to own, now please let it be owned by this other address. [20:56.040 --> 20:56.600] Okay? [20:56.900 --> 20:58.040] So, we have the pieces. [20:59.780 --> 21:03.680] Now, the signature is made of two parts. [21:04.120 --> 21:05.580] One part is called R. [21:05.720 --> 21:10.300] And it's just that random number multiplied by the curve base point. [21:10.740 --> 21:14.440] That generates a coordinate on the curve, and we take the X coordinate. [21:15.260 --> 21:20.180] As much as you need to know, it's simply an operation that maps a number into another number. [21:20.180 --> 21:30.200] So, you go from K, which is this random long number, to R, which is this other very long number that could be as random as far as you know. [21:30.340 --> 21:33.100] But it only depends on K, because G is fixed. [21:33.780 --> 21:34.040] Okay? [21:34.440 --> 21:41.820] And then you have S, which is the other half of the signature, which is just the result of that formula. [21:42.580 --> 21:47.100] That's literally big int math that the computer does. [21:47.320 --> 21:54.360] It takes the hash, interpreted as a number, adds R times D, which is the private key, and divides everything by K. [21:55.460 --> 22:01.540] Now, I'm not here to explain to you why this works, because that is what you need a cryptographer for. [22:01.820 --> 22:08.460] But the important thing to know is that as long as you publish these two numbers, anyone with the public key can verify the signature. [22:08.460 --> 22:10.520] And that's exactly what Bitcoin does. [22:10.720 --> 22:23.940] Every time you make a transaction, you use your private key, you generate a new K number, and you publish these two huge numbers for everyone to know that you actually want that transaction to happen. [22:25.260 --> 22:26.360] So far so good? [22:26.840 --> 22:28.300] This was a lot of math. [22:29.180 --> 22:29.780] Sorry. [22:32.400 --> 22:35.500] So, now let's see what we can do of fun with this. [22:36.380 --> 22:38.700] Let's see what happens if we know K. [22:39.120 --> 22:44.560] Because we've said that K needs to be... is commonly called a nonce. [22:44.960 --> 22:51.900] But this is kind of a misnomer in ECGSA, because it's not enough to use the number ones, nonce. [22:52.100 --> 22:55.380] But it also must be unpredictable and random looking. [22:56.020 --> 23:09.480] So, if you instead know K, you can do what you've learned in algebra and just put this formula down as an equation and solve for the private key. [23:10.460 --> 23:11.580] Look at this formula. [23:12.080 --> 23:18.840] Here you have S, which is the other half of the signature, which you have because it's published on the blockchain. [23:18.840 --> 23:23.160] You have R, which is published on the blockchain. [23:23.600 --> 23:28.840] You have Z, which is the hash of the message, which is published on the blockchain. [23:29.680 --> 23:34.580] And now if you also have K, you can recover the private key. [23:34.580 --> 23:38.280] So, you take this from the blockchain. [23:38.940 --> 23:41.960] You take this from hashing the message. [23:42.540 --> 23:49.420] And then if you have that last piece, K, the nonce, then you know the private key. [23:50.700 --> 23:51.620] And you fall. [23:52.600 --> 23:53.200] Sorry. [23:54.500 --> 23:55.420] I'm sorry. [23:59.500 --> 24:03.260] So, how would you know that you have R and you're about to fall? [24:03.260 --> 24:10.440] Well, you would know because you would notice that R is exactly K times G. [24:10.700 --> 24:19.740] So, if you have an hypothesis about what K that has been used is, you can derive R and look for R on the blockchain. [24:23.240 --> 24:26.720] And, again, the stupidest attack that can possibly work. [24:26.860 --> 24:28.380] We just searched sequentially. [24:29.620 --> 24:41.820] I will point out that this is actually searching not for R for a particular transaction, but for R in any transaction all at once. [24:42.660 --> 24:44.380] So, we let this run overnight. [24:45.820 --> 24:48.020] It only got three hits. [24:48.040 --> 24:50.680] And we only ran through the first nine billion or so. [24:50.680 --> 24:52.880] And I did that, like, on Thursday. [24:54.700 --> 24:55.220] Um... [24:55.220 --> 24:55.860] But... [24:55.860 --> 24:57.700] Now, this is... [24:57.700 --> 25:00.100] So, this is what, again, the stupidest attack. [25:00.320 --> 25:06.280] Now, we know that if we can figure out K, we can break, uh, use a signature to recover the private key. [25:06.440 --> 25:12.440] But, again, searching linearly the entire space won't work because the nonce is just as long as the private key. [25:12.940 --> 25:15.300] So, there's another attack you can pull out. [25:15.580 --> 25:16.600] The math doesn't stop. [25:16.740 --> 25:17.040] I'm sorry. [25:18.260 --> 25:24.060] Now, you can take two, um, two transactions that you've noticed have the same R. [25:24.320 --> 25:28.560] And if they have the same R, it means they have the same K, right? [25:29.440 --> 25:37.540] And take the other half, which is the one that is different, and try to figure out, okay, so, what are the parts of this other half, of this S? [25:37.540 --> 25:48.540] Well, there's the private key, which might be the same if it was two different transactions sent from the same wallet, uh, from the same address. [25:49.540 --> 25:55.380] The K, we just said that it's equal because we've noticed that R is the same in the two transactions. [25:57.300 --> 25:58.820] R, the same. [25:59.160 --> 26:04.660] So, we just group together all the parts that are the same. [26:05.480 --> 26:06.460] This half. [26:07.400 --> 26:13.400] And if we just do S1 minus S2, what do you think is left? [26:14.320 --> 26:17.480] All the parts that are equal cancel out. [26:18.500 --> 26:21.080] So, now, we have this formula. [26:21.920 --> 26:29.500] S1 minus S2, so, the second half of the first signature and the second half of the second signature. [26:29.500 --> 26:30.540] the second half of the second signature. [26:30.540 --> 26:32.000] Their difference is equal to that. [26:33.280 --> 26:37.680] Again, group, a lot of algebra, turns out high school has been useful. [26:39.100 --> 26:45.160] And finally, we can derive a formula that only uses things we know. [26:45.540 --> 26:49.400] Because again, hash of the first message, which is public on the blockchain. [26:49.800 --> 26:52.460] Hash of the second message, which is public on the blockchain. [26:52.860 --> 26:58.520] Second half of the first signature and second half of the second signature. [26:59.780 --> 27:01.840] Using this formula, we get back K. [27:02.180 --> 27:07.220] And again, we've learned before that if we recover K, we can get the private key. [27:07.780 --> 27:20.280] So, to wrap this up, if you see two transactions in eCDSA that reuse the private key and the nonce at the same time, you will notice, because you will see that R and the public key are the same. [27:20.680 --> 27:25.740] And you can use these formulas to compute K and then to compute the private key. [27:26.160 --> 27:29.040] And the surprising thing is that they actually work. [27:29.140 --> 27:35.000] You just literally code them into math on the laptop and you get numbers and those are private keys. [27:35.180 --> 27:36.280] I find that wonderful. [27:43.140 --> 27:48.160] Now, obviously, I can't claim any merit for coming up with this attack. [27:48.300 --> 27:48.800] Let's be clear. [27:49.020 --> 27:52.040] This is a well-known shortcoming with eCDSA. [27:52.040 --> 28:02.940] And at the CCC, I think it was 27C3, it was shown how to use it to jailbreak the PlayStation 3. [28:03.240 --> 28:09.560] Sony had used a static number for their eCDSA signatures. [28:14.000 --> 28:15.660] Relevant XKCD, obviously. [28:16.720 --> 28:21.720] And they were able to use it to recover the private key and sign new firmware updates. [28:22.360 --> 28:24.840] But others have used it in different contexts. [28:24.960 --> 28:41.840] For example, in the context of TLS, the factorable.net team has scanned the Internet for certificates that were doing these mistakes and got private keys and published it into mining your P's and Q's, which is possibly my favorite academic paper title. [28:42.780 --> 28:50.720] Now, for a complete analysis of this, there's more on the slide deck of my Hack in the Box Kuala Lumpur presentation. [28:51.140 --> 28:57.000] For example, there is some analysis of this happening on the blockchain. [28:57.000 --> 29:06.140] This is over time and the different addresses and there are some pretty high profile events that involve this. [29:06.440 --> 29:13.660] For example, here is a Bitcoin forum post complaining about losing up to 55 Bitcoins because of bad signatures. [29:14.580 --> 29:22.440] This is about blockchain.info not seeding the random number generator well enough on some browsers and, again, losing money. [29:22.440 --> 29:31.320] Because if you have a bad random number generator, you risk reusing the same K twice and you end up with losing your private key. [29:32.020 --> 29:41.300] And finally, there was the very high profile Android bug where a lot of applications weren't seeding the random number generator at all. [29:41.600 --> 29:51.280] And even if you generated your key somewhere else and then imported it on your phone and made two transactions, anyone would be able to recover your private key from the blockchain. [29:52.840 --> 30:00.900] Here we used to have a nice demo because there used to be a bot that would do this on the fly just like with brain wallets and it's gone. [30:01.320 --> 30:02.960] It's not running anymore. [30:03.360 --> 30:10.760] And doing a demo where you depend on some third party has these negative outcomes. [30:11.120 --> 30:18.800] But we did set up some test wallets and these very addresses have at least 20 bucks on them. [30:18.800 --> 30:22.840] That if you followed the talk well enough and you're fast enough, you can definitely steal. [30:25.540 --> 30:27.420] We're going to sweep it when we get off stage. [30:27.720 --> 30:30.300] So, if you can get it before then, it's yours. [30:31.580 --> 30:32.020] Otherwise... [30:32.020 --> 30:32.800] I'm going to hide them now. [30:34.800 --> 30:35.240] Okay. [30:35.760 --> 30:41.440] So, you'll be thinking, well, but that's pretty dangerous and random number generators are usually not that good. [30:41.680 --> 30:42.500] So, can't we do better? [30:42.500 --> 30:43.700] The answer is yes. [30:44.000 --> 30:47.080] There is a way to do ECDSA deterministically. [30:47.360 --> 30:53.260] Which means that instead of picking a random K, we think about the three things that K needs to be. [30:53.480 --> 30:55.500] It needs to be random looking. [30:55.740 --> 30:57.000] So, high entropy. [30:57.340 --> 30:58.800] It needs to be unpredictable. [30:59.300 --> 31:01.360] And it needs to be different for every transaction. [31:01.360 --> 31:12.800] So, if we hash together the message we are trying to sign and the private key, it's something that nobody can figure out because it's a hash of the private key. [31:13.000 --> 31:18.100] It's something that is always different for different messages because the message will be different. [31:18.760 --> 31:22.580] And we can just use that as the K value instead. [31:25.740 --> 31:32.560] Now, all this, as we said, only works if you use K and D at the same time. [31:33.840 --> 31:38.060] Everyone on the same page about this attack, you see two transactions in the blockchain. [31:38.100 --> 31:40.920] You notice they have the same R and the same public key. [31:41.040 --> 31:45.540] And you say, hmm, I can probably compute the private key from that. [31:46.160 --> 31:49.960] But if the private keys are different, this attack doesn't work out of the box. [31:52.580 --> 32:10.980] However, if you have a lot of people with bad random number generators that are prone to producing colliding results, odds are eventually two people will independently produce the same bad random number generator. [32:13.590 --> 32:16.340] This is another avenue for attack. [32:17.680 --> 32:21.160] We haven't seen this documented anywhere. [32:21.160 --> 32:24.820] We call it the ECDSA pivot attack. [32:26.620 --> 32:35.580] So, earlier we mentioned with simple reuse, we see here that R is the same in these two transactions. [32:35.960 --> 32:38.020] Therefore, they must have the same nonce. [32:38.240 --> 32:42.260] The public key is also the same, which means the private key is the same. [32:42.260 --> 32:50.300] So, we are able to solve here for the private key and the nonce for this specific R value. [32:52.980 --> 32:55.980] So, this guy reused an address. [32:56.360 --> 32:56.860] Oops. [32:57.320 --> 33:02.060] Well, what happens if somebody else makes a transaction with that same nonce? [33:05.620 --> 33:12.860] So, we see that this has the same R value, therefore the same nonce, but the public key is different. [33:12.860 --> 33:14.660] So, the private key is different. [33:14.660 --> 33:20.660] So, the equation we used earlier wouldn't work, but we already know this nonce. [33:22.120 --> 33:26.720] And as we saw earlier, if you know the nonce, you can simply solve for the private key. [33:27.860 --> 33:31.300] And then this fellow does another transaction. [33:33.900 --> 33:45.580] And since we know the private key, we can rewrite our equations a little bit, move things around, write it in terms of the private key instead of in terms of the nonce. [33:45.620 --> 33:47.500] And we can solve for the nonce here too. [33:47.660 --> 33:50.380] So, now we know nonce for this new R value. [33:50.380 --> 34:02.760] And then somebody else, wouldn't you know, makes another transaction with that R value, which has never been reused with the same public key. [34:03.300 --> 34:14.580] But again, since we were able to compute that nonce by going back and forth between private keys and nonces across multiple transactions, we can solve there too. [34:15.480 --> 34:17.940] We know that nonce, we get that private key. [34:20.380 --> 34:22.580] This is not terribly difficult to scan for. [34:23.160 --> 34:36.740] And so, when that was run, it turned up 719 additional private keys that were exposed as second order vulnerabilities in this weakness. [34:37.120 --> 34:39.920] And close to 100,000 nonces. [34:40.260 --> 34:44.840] And some of the chains back and forth were as much as seven hops long. [34:46.060 --> 34:59.220] Another interesting thing is that we saw that blockchain.info, one of the sites that had some problems with this, looks like they figured this attack out on their own and tried to protect as many of their customers' funds as possible. [34:59.680 --> 35:03.080] But there was a bot that was attacking this too, for a while. [35:03.340 --> 35:06.980] We also would have had a demo here, but that bot is also shut down. [35:06.980 --> 35:14.060] Something we hand-waved before is that a Bitcoin wallet technically is usually not a single address. [35:15.340 --> 35:20.620] Often, a wallet is made up of multiple addresses, and so multiple private keys. [35:20.940 --> 35:36.480] So this attack can allow the compromise of one of the addresses to cause the compromise of other addresses in the same wallet, just because they reuse, they share nonces across the different private keys. [35:39.130 --> 35:39.930] Right. [35:40.450 --> 35:49.030] So another interesting thing that we get out of this is that we see a lot more plain text nonces. [35:49.410 --> 35:54.530] And we can analyze them and look at what might have gone wrong. [35:55.690 --> 36:07.210] So the first interesting cluster I found were these ones that had the first half of the nonce filled out apparently at random, and then the second half was all zeros. [36:08.830 --> 36:12.430] Somebody put 16 bytes where they should have put 32. [36:12.670 --> 36:13.190] I don't know. [36:14.010 --> 36:26.690] A real cryptographer will also tell you that such nonces are probably vulnerable just by themselves, because using nonces with too strong patterns is vulnerable to what I'm told is lattices attacks. [36:26.690 --> 36:34.090] But this is definitely not something you can easily scan for, because you have to target the specific transaction that you know had this mistake. [36:34.510 --> 36:35.030] Right. [36:35.170 --> 36:38.790] And we don't know of any specific way to find such transactions. [36:40.370 --> 36:47.970] The other one we saw is very similar to the first one, except for there was something else at the end instead of zeros. [36:50.490 --> 36:56.750] Again, somebody probably put the wrong number of random bytes in their code, and bad things happened. [36:57.590 --> 37:00.510] My favorite one, though, was this one. [37:01.730 --> 37:10.230] This looks like it was uninitialized memory in a... on a Intel machine. [37:10.530 --> 37:13.440] At the very end, you can see it starts with... [37:14.940 --> 37:17.600] You can see what looks like a pointer at the very end. [37:18.200 --> 37:22.940] And so that's another... Yeah, that's interesting. [37:24.060 --> 37:25.440] But what else can we do? [37:29.260 --> 37:34.520] The last one, and very interesting one, is a related nonce attack. [37:34.960 --> 37:44.900] So we said earlier that if you reuse the same nonce and the same private key together in two different transactions, functions, you can recover everything. [37:45.180 --> 37:55.440] But if you know of a algebraic relationship between the two nonces, for example, the nonces were incrementally generated. [37:56.440 --> 38:02.100] One was generated at random, and then out of laziness, the next one was simply one more. [38:02.320 --> 38:04.240] Because after all, they're different numbers. [38:04.380 --> 38:05.160] They're only used once. [38:05.320 --> 38:06.360] That's probably okay, right? [38:08.520 --> 38:24.040] So, if you know the difference between two nonces, and we'll call this difference C, you can solve for one of the nonces and then the other using this terrible mess of an equation right here. [38:24.320 --> 38:29.600] And the derivation of this, I'm unfortunately going to have to leave as an exercise to the audience. [38:32.400 --> 38:37.840] But you may be asking, how can we know that such a relationship exists? [38:39.400 --> 38:43.800] Well, the answer is, of course, more math, because this is stealing Bitcoin with math. [38:46.680 --> 38:52.880] So, our second nonce is the first nonce plus a constant. [38:55.220 --> 39:03.980] our two r values are simply those two nonces plus the constant, all multiplied by the base points. [39:04.280 --> 39:08.320] And it turns out that this relationship carries through through r. [39:09.040 --> 39:17.380] So, with the first r, you can simply try adding one to it, and then see if that ever shows up. [39:19.800 --> 39:21.140] I was somewhat surprised. [39:21.280 --> 39:22.360] So, we ran this scan. [39:23.040 --> 39:27.340] And I was actually quite surprised to see that this didn't ever happen. [39:32.170 --> 39:41.830] We're confident that there are other patterns that you can look for that you can still scan for, because nothing stops you from having C being not one, but something else. [39:42.150 --> 39:45.010] And, for example, maybe some bit patterns. [39:45.250 --> 39:49.790] And we're confident that someone can run other scans to find interesting ones. [39:49.810 --> 39:52.330] Because here is really just a matter of creativity. [39:52.730 --> 39:56.190] Because the elliptic curves math to do all this is there. [39:56.390 --> 40:08.170] And it's essentially just the fact that addition carries over to elliptic curves, where you can, instead of adding one, you can add the point that corresponds to one. [40:08.390 --> 40:11.230] And point addition results in the same result, anyway. [40:12.250 --> 40:13.430] This is faster. [40:15.170 --> 40:15.770] Okay. [40:16.310 --> 40:16.990] Excellent. [40:18.230 --> 40:18.910] Then... [40:18.910 --> 40:20.230] Oh, yeah. [40:20.470 --> 40:29.550] The remark about faster is that this is actually even an optimization Ryan figured out to scan faster for sequential points. [40:29.750 --> 40:43.670] Instead of, for each point, first, figure out, add one to the private key, and then multiply the private key by G, then you can instead add always the same one. [40:43.950 --> 40:52.730] So the secret I kept from you here is that that black magic of turning the private key into a public key is nothing else than that. [40:53.650 --> 40:55.010] Multiplying by the base point. [40:55.770 --> 41:02.110] So there's a lot of parallel between nonce and are and private key and public key. [41:02.110 --> 41:08.430] So that's also why some, a lot of attacks or optimizations carry over and even let us pivot between them. [41:08.510 --> 41:21.630] And in fact, there were even transactions where we found instances of nonces and private keys being in various transactions, the same value used as both a nonce and a private key. [41:22.130 --> 41:24.530] Um, so... [41:24.530 --> 41:26.190] Well, I just said they're similar, right? [41:26.190 --> 41:29.370] Yeah, very, very similar, in fact. [41:29.630 --> 41:34.230] Um, and we're still experimenting with, uh, more nonce-cracking techniques. [41:34.450 --> 41:38.190] We're going to try some weak random algorithms and see if we find anything there. [41:38.430 --> 41:39.970] Um, and I suspect we will. [41:40.590 --> 41:42.950] Okay, so this is it for math. [41:43.230 --> 41:44.510] You can take a breath. [41:44.770 --> 41:47.650] There are no other formulas for the rest of the slides. [41:48.650 --> 41:57.710] Now, I will actually just mention a couple other attacks that can happen remotely that don't require hacking or, you know, wrenching. [41:58.210 --> 42:03.850] And the first one is kind of well known in the Bitcoin, uh, uh, industries. [42:04.310 --> 42:05.170] It's double spending. [42:05.350 --> 42:12.410] The idea is that Bitcoin works because all these transactions are from time to time bundled into a block. [42:12.590 --> 42:18.670] And let's not go over the reasons, but it's very hard then to reverse this operation. [42:18.670 --> 42:25.050] So they are etched in, in stone forever after enough blocks have been wrapped around it. [42:25.390 --> 42:45.590] If you trust a transaction and you accept a payment and maybe you ship an item or provide a service before this setting in stone block operation, which we call confirmation happens, what the attacker can do is show you a payment to you and then send, uh, [42:45.790 --> 42:49.490] to be written into stone, a payment to himself. [42:50.270 --> 43:02.010] And now what happens is that the money actually never reaches you, because the one that is written down, uh, for posterity is the one that says, oh yeah, this money just went back. [43:02.950 --> 43:05.370] So this is what's called a double spending attack. [43:05.890 --> 43:09.930] The other attack is, um, is called transaction malleability. [43:10.190 --> 43:30.330] The idea is that a transaction, which is remembered that R and S encoded in some format can be messed with, can be touched, can be changed without, uh, invalidating it while still being a valid transaction, a valid signature by the same private key for the same message for the same public key. [43:30.330 --> 43:35.730] So this is a problem per se, and it's actually specked out in the protocol. [43:36.210 --> 43:51.930] But if your accounting system relies on transaction hashes to not do operations twice, now what I can do is send you a transaction that says I've deposited some money on my account, on my Mt. [43:52.050 --> 43:53.090] Gox account, for example. [43:53.590 --> 43:55.790] They lost a lot of money this way. [43:55.790 --> 43:56.170] Yes. [43:56.950 --> 44:03.350] And then change it a bit so that the hash changes, but it's still the same transaction, and send it to you again. [44:03.950 --> 44:04.650] And Mt. [44:04.730 --> 44:07.010] Gox was like, oh, look, a new transaction. [44:07.230 --> 44:07.890] What's the value? [44:08.330 --> 44:08.750] 10 Bitcoin. [44:09.110 --> 44:11.530] Well, now this account has 10 more Bitcoins. [44:11.910 --> 44:21.870] And if you could keep it up and find other ways to change it, you could keep changing the same transaction and deposit the same 10 Bitcoins over and over and over again. [44:21.870 --> 44:21.870] 10 Bitcoin. [44:22.230 --> 44:24.830] There were two main ways to do it. [44:25.870 --> 44:35.550] Bitcoin's protocol has been changed to enforce normalized representations, which as far as anybody can tell has fixed this. [44:36.030 --> 44:44.630] But anyway, the two methods that were available were changing the sign bit on the S portion of the signature. [44:44.630 --> 44:51.910] That is going from a positive value for S to a negative one or a negative one to a positive one. [44:52.610 --> 44:57.710] Due to some quirks about the way ECDSA works, both are valid. [44:58.350 --> 45:08.690] The other trick is due to the fact that these signatures are encoded in a scheme called ASN.1, abstract syntax notation. [45:09.130 --> 45:10.890] I don't know what the .1 stands for. [45:10.890 --> 45:16.890] Anyway, if anybody here is familiar with it, you're probably cringing right now because it's terrible. [45:18.010 --> 45:23.190] The trick there is it's a very flexible encoding standard. [45:23.430 --> 45:28.610] And you can do things like have variable width number representations. [45:29.030 --> 45:35.390] So the other method of transaction malleability that was used a bunch against Mt. [45:35.470 --> 45:43.710] Gox in particular was adding extra bytes of zero at the beginning of the R and or S portion of the signature. [45:44.590 --> 45:57.090] And all these things that start going wrong or in weird ways when you start looking at bytes as numbers and try to apply math to them is really one of my favorite things of cryptography. [45:57.330 --> 46:03.070] And let's be honest here, all these weird attacks is actually why we love Bitcoin. [46:03.850 --> 46:04.670] Thank you. [46:14.200 --> 46:19.580] Looks like even if everything else happened, we still have time for a few questions. [46:19.880 --> 46:26.300] So, Mike, I don't believe that everyone got everything I've said. [46:26.440 --> 46:28.120] I'm not that good of a speaker. [46:28.360 --> 46:30.220] So get there and ask me what you didn't get. [46:31.820 --> 46:38.640] I spent at least at least 20% of the time we were working on these slides, having no idea what was going on. [46:38.780 --> 46:39.420] So don't feel bad. [46:40.480 --> 46:40.980] All right. [46:41.120 --> 46:42.740] Like, like a quick question. [46:43.400 --> 47:07.800] Like, do you know, like what curves, you know, did they use, you know, in those like, oh, they use like Diffie-Hellman, like Edwards curve, like Bitcoin Bitcoin specifically uses a curve called SECP 256K1, which is defined in a document called standards for efficient cryptography from CertiCom. [47:08.020 --> 47:11.800] And if you would like the details, you can read them in that document. [47:12.040 --> 47:15.260] I might be terribly wrong, but I think the case stays for Koblitz. [47:15.460 --> 47:16.300] Yes, it does. [47:16.480 --> 47:16.920] That is correct. [47:17.180 --> 47:19.460] It's so it's easy to say over a Koblitz curve. [47:19.460 --> 47:23.920] But these, these attacks would work on any, any elliptic curve. [47:24.680 --> 47:26.800] And what do you see as the future of Bitcoin? [47:28.460 --> 47:34.240] Well, the only thing, honestly, personally, I'm concerned with is the future of attacks on Bitcoin. [47:34.540 --> 47:38.080] So I'm, I'm sure there will be many mistakes coming. [47:39.700 --> 47:45.540] But honestly, the more economic side and changing the world side is above my pay grade. [47:45.540 --> 47:50.320] And definitely more drama and geeks with opinions. [47:51.240 --> 47:52.100] There we go. [47:52.200 --> 47:56.580] Did you guys look at any of the early transactions before they changed to pay to script hash? [47:56.680 --> 48:00.760] And were there any attacks against those that were, that you guys have ever looked at? [48:01.380 --> 48:11.180] To be honest, there, there weren't enough of pay to public key transactions for it to be worth adding parsing code for it. [48:11.300 --> 48:20.860] But if you're interested in that information, you could certainly add to the, the code that's up on GitHub and do that search yourself. [48:21.860 --> 48:27.040] Just to clarify, did you say that GU is the same for every transaction? [48:27.340 --> 48:27.480] Yeah. [48:27.820 --> 48:28.900] And then how is it picked? [48:29.100 --> 48:29.780] Like, what is this? [48:30.260 --> 48:34.160] Uh, elliptic curves, black magic. [48:34.520 --> 48:45.960] The base point of the elliptic curve is essentially this fixed parameter of the curve, which in this case is the two, five, six, uh, two, five, six SCC key. [48:46.340 --> 48:49.040] So it's like a unique piece of the curve that's used? [48:49.240 --> 48:49.300] Yeah. [48:49.700 --> 48:49.920] Yes. [48:50.060 --> 48:55.340] It is, it is chosen by whoever chooses the rest of the parameters of the curve. [48:55.700 --> 48:56.020] Yeah. [48:56.140 --> 48:58.360] Hopefully in a totally trustworthy manner. [48:59.060 --> 49:00.160] Um, yeah. [49:02.100 --> 49:03.340] Like, I'm sure it's fine. [49:06.440 --> 49:07.560] It's fine, it's fine. [49:08.020 --> 49:13.140] You think, uh, people might be using application-specific integrated circuits to crack some of the brain wallets out there? [49:13.380 --> 49:14.240] What do you think's behind? [49:14.700 --> 49:22.600] Uh, so I actually have a blog post on why bitcoin mining ASICs are completely useless for cracking passwords. [49:23.020 --> 49:28.860] Um, and it is because bitcoin mining ASICs accelerates bitcoin mining. [49:28.980 --> 49:31.040] They do not generically accelerate hashing. [49:31.380 --> 49:33.160] Uh, what about building an ASIC for that? [49:33.460 --> 49:37.720] Uh, you could totally make a brain wallet cracking ASIC, but I don't know why you would. [49:37.720 --> 49:38.340] Yeah. [49:38.660 --> 49:41.160] And considering it's shadow 56, yeah. [49:41.600 --> 49:42.440] But anyway, sorry. [49:42.700 --> 49:45.840] Have you tried this in any altcoins or any of the newer? [49:46.360 --> 49:46.800] Yes. [49:47.080 --> 49:47.240] Yeah. [49:47.740 --> 49:57.480] Uh, in fact, there is a website called Ethercamp where if you click new address, it makes a brain wallet for you on Ethereum and it does not say it's a brain wallet. [49:57.660 --> 50:03.380] And, uh, the guy who runs this site, um, he and I don't agree on this. [50:03.500 --> 50:04.960] I will, I will just say that. [50:04.960 --> 50:05.860] Last question. [50:06.120 --> 50:06.260] I'm sorry. [50:06.740 --> 50:12.120] And I have found brain wallets on Litecoin, Dogecoin, and a couple of other altcoins. [50:12.520 --> 50:18.260] Uh, something interesting would be to, uh, track nonces and private keys and pivoting between altcoins, by the way. [50:18.460 --> 50:30.700] Yes, this is, this is a tip, you know, if then you can ask me for a bitcoin address and you, if you find money that I won't ask where they, where it come from, you can, you know, send me tips because of this tip. [50:31.120 --> 50:31.500] Anyway, sorry. [50:31.640 --> 50:32.700] Yeah, cross-chain attacks exist. [50:32.700 --> 50:33.080] Last question. [50:33.900 --> 50:42.600] Um, so all of these attacks are, are, are most, these attacks seem to, uh, sorry, arise for mostly from client vulnerabilities, you know, poorly coded. [50:42.720 --> 50:43.960] None of them arise from the protocol. [50:44.120 --> 50:50.420] Do you think there are protocol level changes we could make to make things safer, or bad programmers just going to always put people with money at risk? [50:50.600 --> 50:55.080] Um, he's right that, uh, all of these are vulnerabilities on the client side, bugs essentially. [50:55.080 --> 51:05.060] Um, definitely something that could have been done was, uh, standardizing ECDSA only as deterministic, but, um, I can't think of any other specific ones right now. [51:05.220 --> 51:12.140] And I, the, uh, the, uh, the, the, the malleability form enforcement. [51:12.380 --> 51:12.500] Okay. [51:13.020 --> 51:14.420] We'll vacate the stage now. [51:14.600 --> 51:15.480] Thank you, uh, much. [51:15.740 --> 51:16.460] Thank you very much.