 Hello everyone, thank you for sticking with us that late in the day So my name is Niels. I'm a security researcher at Kudalski security I focus on privacy and I like to process Large data sets and I'm a huge Linux fan and today. I'm also here with my colleague Marco Hello Marco Macchetti. I work as a cryptographer for Kudalski security and my background is hardware design cryptanalysis and applied cryptography in general So what are we going to talk about today? This is a new attack that we devised against an algorithm to generate digital signatures, which is called ECDSA It's well known for being the digital signature algorithm beyond the Bitcoin blockchain This attack is called PolyNOS and we will give you some details of the attack and the things we tried to put it in Practice how we did it and what we learned in the process and there will be a brief demo and then we will give also some results and takeaways Let's head over to the introduction What is a digital signature? Basically digital signature is just a proof of knowledge of a private key, right? Everyone can verify your signatures with your public key, but only you can generate signatures with the private key So in a real world Your signature on a piece of paper is a proof of identity in the digital world The knowledge of your private key is a proof of identity and on blockchains the private key means ownership of the coins So everyone will try to steal your key If it's on backups paper nodes brain wallets and sometimes it's it's a strong key But it's protected with a weak password Digital signatures are mildly complex objects Signature algorithm is actually a set of three arguments. You have key generation, signature generation and verification Is there randomness inside all of this? Well, yes essentially key generation is a throw in the dice to obtain your key pair and randomness is also Present in the signature generation process along with your private key and a message you throw the dice again And you obtain a signature and verification is just a deterministic algorithm Well, if everyone wants your private key, is it possible to obtain your private key just by looking at the signatures? Well in general no, but under some assumption Yes, for example, if you generated the key with low entropy or with short seeds or using a brain wallet Maybe it's easy to guess But provided that the key is properly generated. Is it possible to obtain it? From your signatures. Well, remember there is randomness in the signature generation So there is more attack surface that we can explore In this paper we target the ECDSA algorithm This is probably the mostly deployed algorithm for digital signatures EC is for elliptic curve and elliptic curve is just a curve on a finite field with some parameters You all know the Bitcoin curve and the curve is also a set of points You can perform operation with the points you can add the points or multiply a point times a scalar This is called scalar point multiplication And why it is so useful because the scalar point multiplication It's easy to do in one direction, but it's hard to invert and this is called the discreet logarithic problem And this is the basis of the security for ECDSA So what is in detail? The set of algorithms for ECDSA. Well key generation is quite simple You just pick an integer D in a certain range And this is your private key and the public key you just obtain it through scalar point multiplication To generate a signature you ask the message first and then again you have to pick an integer in the same range Again uniformly at random and this is called the nonce and you have to have a different nonce for each signature Then the signature is just two numbers r and s and r is just the x coordinate of the point Which correspond to your nonce and s is obtained with the expression that is in the slide And verification is just a deterministic argument We are not very interested. So the takeaway is that you also performing key generation for every signature basically and if the nonces Can be predicted or some bits are known then you can use lattice attacks and You can also use a side channel attacks in combination with lattice attacks to retrieve the key So what you have to choose to to generate this the randomness is to choose your dice There are good dice like those RNGs based on cryptographic algorithms like H mark and a yes These are the good ones and then you have bad ones like algebraic generators LFSRs And then they are the awful ones like a fixed secret constant the run functions and these kind of things And once you choose the dice you also have to seed it with entropy Let's pick one of these bad RNGs the linear congruential generator This is that's been known for decades. I mean, it's it's a generator that is implemented basically everywhere It's in GMP of our libraries and it was also Referenced from the NIST documentation basically An SCG works in this way you generate a random number and then you apply a linear Relation to obtain new numbers with known coefficients a and b There is no bias in this so it's good But in fact it has been shown by by previous projects that you can use lettuce attacks To retrieve the private key So if your SCG is not full state, but it's 128 bit for example for the Bitcoin curve then with as low as 22 signatures You can get the private key, but here we want to go beyond What if you use a full state? SCG There are no results published so far on this and what if you increase the degree to quadratic or even cubic then? Lattice attacks are not possible and what if you keep the coefficients unknown secret then you you may think you are safe Right, but in fact no we show that we've pollinons We can retrieve the private key in a fraction of a second So how does it work? Basically, we don't care about the air part of the signature But we just look at the S part of the signature and we rewrite the expression of S To be a linear relationship between the nonce and the private key. What does it mean? It means that there is only one secret behind all your signatures You can think that it's the private key or you can think that is one of the nonces or maybe some partial information on more nonces and And so we want to exploit this this additional information that is in the S part of the signatures. How can we do it? Basically suppose that you are you are generating your nonces with an SCG So you generate a first nonce k0 and then you generate k1 k2 k3 in this way and Suppose that the attacker doesn't know a1 and a0 these are the secret coefficients But basically what we can do you can subtract the second equation from the first and the third from the second and we get this pair of equations here and Then we can solve for a1 in both and we can just equate the results and we get this expression here And we got a completely rid of the unknown secret coefficients and then This is the trick we can replace every nonce in this polynomial with the expression in D The static private key. So basically we get a polynomial which were the only unknown is D We find the roots of the polynomial. It's easy to do and we get the private key and We extended this to all n-degree polynomial relationships So we we are able to attack quadratic and cubic and higher degrees and this is a recursive algorithm It's a fast generic. It's not using lattice and if you want to take a look there is an e-print paper on this And then I add over to nice will explain how we put this into practice Thank You Marco So with all of that, how can we actually attack things in practice? Well to run the pollinance attack what you will need is at least four signatures But that's for the linear case if you want to target a higher degree relation Then you'll need more than four signatures in any case You'll need to make sure that these signatures are sorted by the time in which they have been generated on top of that You'll need to also have associated with each signature the message and the public key if you have all of that and The nonces were indeed generated in a biased way then you can retrieve the private key So where can we find the cdsa signatures in practice? Well one good source of that is Bitcoin In Bitcoin you have blocks and inside blocks you have transactions and these transactions They contain inputs and outputs and good for us these inputs are signed with e-cdsa So how do we get what we need? Well the public key and the signature They are contained in that input the message. However, you have to compute it and Computing that message is a very error-prone and under documented process You will need to use Fields from the current transaction, but also fields from previous transactions So you will need to keep track of all of that to compute the message So to actually get the data what you'll need is to let your Bitcoin client sync and download the whole chain and We did that it took about a day and we got all of the blocks until September last year and When it was synced we dumped all of the signatures the popkeys the messages by just reading the block files from disk and We with that we dumped about 700 million signatures We only covered the most common type of Bitcoin signature which is pay-to-public key hash Signatures, but that covers more than half of the the Bitcoin transactions Another good source is ethereum because transactions in ethereum are also signed with e-cdsa and In that case the signature is directly in the transaction the public key Not directly But there is actually a lesser known feature of e-cdsa called e-cdsa recover that you can use to compute the public key Based on the signature and the message plus a third value that I won't discuss but which is in the transaction The message also must be computed to compute the message the main challenge here is that ethereum has multiple protocol versions and These versions Change based on the block number meaning if you want to compute the message for a specific transaction Depending on what block this is the way you compute the message changes So if you want to dump all of the signatures for the whole chain You basically have to implement all of these ethereum versions of the protocol. So we did that If you want to have a look at the details, please check out our code. It's on github To actually get the data you'll need two things an execution client first such as gith and a consensus client Such as lighthouse you let these two sync so that it downloads the whole chain for us That took about three weeks and a ton of disk space But then we got all of the blocks until October last year when we did that We used the Jason RPC API of the execution client to get the blocks directly parsed in Jason and dumped the signatures popkeys and messages to a file and We dumped 1.7 billion signatures that way We also had a look at two more Signature sorry two more sources that are not blockchain related The first is a sample of TLS servers So why TLS servers well if you make a TLS handshake with a server It's gonna send you a signature and if the key is an ACDS a key you get an ACDS a signature So that's what we collected The second one is actually a set of data sets from the Minerva attack These are publicly available and these are ecdss signatures that were generated from TPMs smart cards and a bunch of software libraries So a few stats Here at the top you see that about 97% of Bitcoin wallets only generated Three signatures or less and at the bottom for Ethereum This is a bit less extreme, but only 77% of wallets generated Well 77% of wallets generated less than four signatures The rest however so those that have at least four signatures We can try to attack and that means there's at least a few million Wallets we can try to break with that attack So we implemented the attack in Sage and it's a multi-threaded implementation the code is out there on on github So just a quick demo So here we We start TLS server which is vulnerable. It's it's gonna generate biased nonces We capture the network traffic dump it to a pcap file Then we make TLS handshakes to that vulnerable server We stop the capture stop the server Then we read the traffic from that pcap file and Dump the signatures messages and public keys to a CSV file And finally we run the attack against the signatures in that file And that's it. We got the private key here So how did it go? Well, no, we didn't drive in in a new Ferrari today Well for Bitcoin and Ethereum we use the big machine with lots of cores and for Bitcoin the attack run for about two days and We were able to get the private key of about 700 wallets, but None of these had any money on them. So it looks like someone else had drained them before us For Ethereum we processed about 20% of the input file in two days and we only got two private keys so We stopped it because we thought the cost time ratio was not really worth it These two also had a zero balance here It turns out that all of the signatures that we used that that were generated by these vulnerable wallets Actually had repeated nonces and of course the pollinance attack is also going to Find repeated nonces because that's just a particular case of an LCG where the last Unknown coefficient is the only one which is non-zero and it's equal to that repeated nonce value But this could also have been found with a simpler attack For the two others TLS and Minerva This was actually pretty quick. So just a few seconds for the TLS set we had and for Minerva a few Hours so you could just run this on a laptop We did a n equals four five and six signatures because it was quick, but we got no successful successful attacks there so we wanted to see what happened to those stolen Bitcoin and We tracked that and we found that about a hundred and forty bitcoins were stolen in total So that's about 10 million USD at Bitcoin speak price We also saw that some of the addresses that received that stolen money Had readable names in them like one hack one gift something like this and there is one One idiot address that sent the money It's stole to another address called one Andreas and This address is owned by a guy who made significant Contributions to the Bitcoin ecosystem and when people found out about this in 2017 They decided to make a ton of donations to that guy So it looks like the one idiot guy stole Bitcoin to give it back to this guy as a donation for charity and We also saw on some public forums that people had been saying like how many Bitcoin they stole Due to repeated attacks repeated nonsense attack just publicly on the forum like oh, I have collected seven bitcoins so far so few takeaways Make sure you don't generate Signatures with the biased months and to make sure you don't do that You should use something that does deterministic nonce generation such as deterministic ECDSA or EDDSA We just barely scratch the surface here So there's plenty of other areas that we didn't touch and that you could apply this attack on And it's very easy for you to check your own wallet You don't need to have the whole chain if you just have the signatures for your wallet the pub key and the message You can run this on your laptop basically So for more research from our team, please visit our blog we have more exciting research on this topic and We hope that people get more secure by releasing our code. It's public. It's on github. Please check it out And thank you. Do you have any questions?