 Good afternoon. We have our first talk that would be a presentation by Yolande Ramaye. He's a security researcher at Kadaelsky security focusing on cryptography. He's spoken at Black Hat USA, DEF CON and others. Please a warm welcome for Yolande. Hey, hello, I'm super happy to be here today. So my talk will be about one key to rule them all. It has a subtitle in the program telling you it will be about elliptic curve math tricks. And it should not scare you because you were there last year at NSEC when Morten gave his Getting Ahead of the elliptic curve talk, right? So you all know everything about elliptic curves. Nah, I'm kidding. So an elliptic curve is just a set of points basically which satisfy certain equations. Here is the Viostras equation. And I require the elliptic curve to be non-singular. But you don't really need to know all of these today to understand the talk. Which is super important though, is that you understand that those elliptic curves even additionally a group will define on the curve which is well-behaved. It does what you expect it to do when you add two points together. It gives you a third point on the same curve. And now about elliptic curve cryptography briefly you've seen this morning that elliptic curve cryptography is almost dead, right, in the past quantum talks, but nowadays it's almost a big it's everywhere. You can find elliptic curve cryptography whenever you connect to a website and so on. Elliptic curve cryptography is usually working with a set group of prime order M, a huge prime order of the elliptic curve C we just defined. And we have a point on the curve which we call the generator or the base point G. And everything is done in that subgroup, so it's important. Now the security of elliptic curve cryptography is based on this discrete logarithm problem, DLP, which I have nothing to do with the data loss prevention, right. And the DLP basically tells you that if you have a point Q, which is equal to N times a point P, for N a scalar, an integer, it is super difficult to find the value of N if you are only given the points P on Q. Okay, I might have been a bit faster, so what's scalar multiplication? It's exactly what you expect it to be. So two times P, the point P, is just basically P plus P. Three times P is P plus P plus P and so on. And by definition, the scalar multiplication is distributive over the addition. And this is the main point of this talk. Everything which I'll present to you today is made possible because when you do A times P plus B times P on an elliptic curve, it is equal to A plus B times P. So that might sound a bit scary, but it will be clearer in a little bit. Alright, so we've seen the discrete logarithm problem and now about elliptic curve schemes. We have mostly signatures like ECDSA, key exchange like ECDH and we can even do encryption sort of with the hybrid crypto systems such as ECUS where you will encrypt with a symmetric key algorithm, but you will share the key using public key algorithm based on elliptic curves. So I've just said public key. So what's a public key and what's a private key? Well, elliptic curve cryptography is usually a public key crypto system where the private key is simply an integer. So it's a value k. Here I say it's smaller than P because I want it to be an element of Fp. The finite field of dimension P for P a big prime, but it's none of your concern. It's just like the details behind, you know. The stuff the cryptographer will deal with. And a public key then it's a point P on the curve which is computed using the private key k. Multiplying it with a generator which has been decided by NIST or standardizing bodies or whoever made up the elliptic curve you are using or maybe you can choose a point to use as a base point yourself and just multiply it with integer k. And you will get a point P equal to k times g which will be on the curve. So private key is an integer, public key is a point on the elliptic curve. That's the main point here. And now that you know that, I can go ahead and tell you a bit about Bitcoin. You all know about Bitcoin, I guess. And Bitcoin is using ECDSA, the signature scheme, to basically sign its transactions, but also to generate the addresses. So when you send bitcoins to somebody, you are actually sending them bitcoins to the hash of a public key. And this is important because since it's using elliptic curve cryptography, it can rely on all the NIST structure, the elliptic curve's AVE behind the scene. And somebody, Peter Vughel, proposed the idea of your hierarchical deterministic wallets a while back. And this idea is basically that you can use the math to derive child keys for elliptic curve schemes out of a master key, a parent key. And this has been actually implemented in Bitcoin. And it's used nowadays to derive child keys. So as I told you, the public key is just like what you will hash to get the addresses in bitcoins. And you can do some magic tricks with those public keys, like you can take a public key, which is a point P equals to K times G. And you can take an integer R and multiply it with the base point G. You get the point R times G. What happens if you sum P, the public key, with those newly generated point R times G? Well, you just get another point on the elliptic curve Q. And what is super interesting is that this elliptic curve point is actually the public key corresponding to the private key given by K plus R. That's by distributivity, as I just explained you a couple of slides before. And this is super powerful because you can use this idea to have one master Bitcoin address kind of and derive other keys that you will know the private key of just by knowing the value R. And anybody can send you money to new addresses and so on. And that's something that has been implemented in Bitcoin, in the BIP32. So Bitcoin Improvement Proposal. I might have skipped some details. But it's not too important. The idea is really that you have a private key, which is an integer. In BIP32, they have extended keys, whereas they have an extra value at the end of the private key, which will be then used as a hash-mack key to hash the public key on some index to produce a random value, absurd a random value, which is deterministically generated by the hash-mack, you know, R. And this value R will be then added to your public key to generate a child key for your parent key. And it has been implemented. It is in use in most Bitcoin wallets because it allows you to basically have multiple wallets at once with just one private key. You can handle different addresses and assign the transaction as you need. And this is all based on the ideas that P plus R times G is equal to K plus R times G. There are a couple of things I've skipped, like the idea of ordinary keys and so on, but it's not too important for what I want to present today because what I've been thinking when I've read about BIP32 is, oh, that's a nice idea, actually. What can we do with these beside Bitcoin addresses? And where do we use public keys, actually? Who amongst you has already signed on a server using SSH keys? Most people, right? Who has been using PGP or who has been using modern VPNs, such as WireGuard and so on. All those services or tools are relying on elliptic curve keys sometimes. So it's not always mandatory. You can use a RSA instead or something like that. But for SSH, for example, nowadays, you have a lot of public keys which are based on elliptic curves because they are smaller in size. And actually, the last research we've done with one of my colleagues was about scanning the internet to collect all the keys we could find out there. And we can see that SSH keys are mostly relying on one curve, SecP256. And that curve 25519, a really nice curve designed by DGB which is being used by EDDSA, is naturally used in practice. And that's a good thing for the stuff I will present you now because with EDDSA, you can naturally do the same kind of tricks I just presented you because the private key will be hashed before producing the integer you multiply with the base point. So you will have to compute a frame age which is not something you want to do. So that sounds fun, right? Deriving new public keys out of a private... out of a previews public key. So what could we do with that kind of stuff? So the idea is that you could basically publish your public key and if somebody wants to add your SSH key on a server, but you don't want to, you know, if somebody finds the public key, you will know it's yours or something like that, he doesn't want that. He could just put a new public key generated by adding a random value times g to your public key. And if he sends you the random value he used, you could then compute the private key which corresponds to that public key he generated because you know the private key of your own public key. And this is the idea behind what I'm going to show you shortly. So it's called one key. And basically it's a tool which will take a SSH key and SSH keys can be elliptic curve-based. So I'm using a SECP256R1 public key there and you can use one key to derive new public keys in practice. So it's basically to showcase it's working, what I just said. So let's do this. Not what I wanted. Okay. So one key is made in Go. You can get it on GitHub, actually. And it's quite easy to use. You give it a key, like here is the test key, and you give it what I call a derivation code. And it will produce an integer R, which is here the derivation integer, as I call it. You can see it here. And basically the public child key here is the public key which corresponds to the test ECDSA public key. Plus C1B69. So one times the base point of the elliptic curve I'm using there, so P256. And this is nice because it works here with a private key, but actually what I could do is just here take the public key and do the same thing. And you can see I get the same public child key here. And what I can also do is take another value as a derivation because test two is basically what's getting hash-macked with a secret value which I'm not showing on screen. It's in a config file basically. And you can see here when I change tests to test two, the derivation integer changed. And this is the value R you are adding to your public key times G to get the public child key. And now that's cool, but you need the private key, right? So what you can do is basically just like if you were plugging UB key or something, a smart card in your computer, you can add keys to your SSH agent, which is nice because you can derive the keys, add them to the SSH agent, and then you can just use SSH as you would usually. So now you have one master SSH key and you can derive new child keys on the fly in memory without writing them on your computer whenever you need them. So here I will use a dash-q and this will not work because I use the public key. If I use instead the private key, let me maybe show you, okay? That's what happened. So what does it mean? It means that my SSH agent got a new key added to it, which is called child key test two here. And if I want to add another key, I can test three. And the SSH agent just got the child key test three key added to it. And that key is not persisted into memory. And let me remove all those keys. So I just got the keys I usually have, SSH. Okay, let me try and connect to some server. This should not work. Maybe my internet timed out. Demo effect. Too bad. So the idea was on the server I'm trying to connect to, I have a public key in the authorised keys which correspond to the test two child key. And I could connect to it if my child key is added in my SSH agent, but I couldn't if it's not added to the SSH agent. So let's go back to the slides. You can use it today if you want. One key is a puck, but it's on GitHub. You can go and get it with go get. And you can play with SSH keys. You might ask, what about security? What happened with those child keys? Well, there are two things. The first thing is a child key is not weaker than the private key used as a master key because both are relying on the same ARB-NAS assumption which is a discrete logarithm problem. So if somebody is able to break your child key, you would have been able to break your master key in the first place. Now, what happens if you have a child key and somebody is able to get the private key corresponding to that child key? Well, if he also knows the public key of your master key and he knows the value R you use to derive the child key, he could recover the master key because K plus R minus R is equal to K, right? So that's just plain math. So the private keys are integers. The child key, the child private key is K plus R. If I know the value R and I know the value K plus R and I know it has been derived, I can just compute K. So you don't want your private key to leak, right? Obviously. So BIP32 has a workaround to avoid this using Arden keys. I haven't implemented it for SSH because it's just a POC, it's just a pack, but anyway. What's interesting here is that you can imagine something the other way around. So you have a master public key which you use on all your machines and whenever you get a new machine, you can generate a new private key, K, and you can compute the difference between your master, a new private key. Yeah, anyway, you can compute the difference between your new key and your master key. And that difference will be the value R. And once you've computed it using, you need to know the both private keys to do so. Then you can derive your master key out of your child key whenever you need it. So it can be seen either as a feature allowing you to derive the master private key when you need it and never persist it in memory on your other machines or it can be seen as a problem. If you leak it and the value R you use is also leaked. What could we do with these kind of IDs? It really depends. My first idea was to do a WireGuard key distribution method because WireGuard is a really cool, modern VPN and I like it. And I've seen a lot of people complaining about the leak of PKI and the key distribution method for it. But it uses ED2519 which is hashing the private keys which makes the ID here a bit more difficult because you will need to modify the way WireGuard is using the private keys so that you will use the integer directly and not the hashes which is not really a good idea. Another idea I had with this is that you could imagine some sort of an S run somewhere or basically you run somewhere it's really mean, it encrypts all your files with public key cryptography. And then when you want to get your files back you will basically have to send money to an attacker. But if you send money and it doesn't send you the key you are a bit sad, right? So you don't want that to happen. So the idea will be basically you could send the money to some trusted third party like let's say a smart contract on a blockchain, you know, not really a trusted third party but a workaround to AVE1. And if the smart contract is able to derive the same child keys out of the private keys the attacker will send you it could then deliver the money to the attacker or stuff like that. I'm going to write a blog post about it at some point. It was a fun thought project we had with some colleagues at EPFL anyway. So other things you could imagine is to have disposable keys where you have a public key out there, I don't know, like on GitLab or GitHub. You can see anybody's public keys on GitHub by simply typing github.com slash username.keys. And you see the public key people are using which is privacy-wise a bit bad because maybe you can link some identities with some other nicknames by looking at which private keys, which public keys they even their profile, which is not something you want, right? But what you could do is derive a key out of your master key and if you want at some point to prove it was you who owned both private keys, you could give the value or which is the difference between the two private keys so that anybody could verify out of the public keys that one public key derives into the other public key. So it's kind of like opting non-reputability for SSH public keys on the internet. Not sure it's a thing, but it might be done right. So, yeah, just try it out. As you can see, elliptic curve and math are not so scary. You can do cool things with them and, yeah, if you have ideas, just try them out. It works out well sometimes. Minor keys keep them encrypted because, as I said, if you have a child private key leaking, it might compromise your master key and that's bad. So encrypted keys are supported by one key if you want to try it. And anyway, so the mass collection of public keys we did with one of my colleagues is actually there to help you check if your RSA keys can be batch-factored. You can test them on keylookup.codoskeys.security.com if you want. And you can get the one key software on GitHub as well. And I'll put the slides on Twitter and my homepage at some point in the future. So I don't know if anybody has questions. Anyone has a question? Thank you. That was really interesting. And I can see lots of interesting things to play with here and explore. I'm just wondering is this notion of deterministically deriving keys from a master key, I could very easily be mistaken, but isn't this what happens inside a U2F device? Or is that a different mechanism for creating new key pairs? In which devices? In like a UBiCo or UBiT kind of thing. As far as I know, the current devices which are being used for 2FA and stuff like that, like you have the brand new FIDO2 authentication method which is also based on elliptic curves, is not using that kind of method because they need space to store the key and they just generate new keys on the device. I might be mistaken though. But there are devices out there which are using this method to derive new keys. It's basically the Bitcoin ledgers and Ethereum ledgers. So all those hardware wallets, they usually implement BIP32. So the ID is out there. I'm not sure whether the constructors of 2FA devices are actively using it. If not, they should because it allows them to basically derive as many keys as they want. They don't need to store the private keys on the devices anymore. They can just derive them out of a master key they would generate at first use or something like that. That's a good question. Thank you. Thanks. So you had kind of two ways to compute the deriving factor R. So in the command line tool, it uses the HMAC method using a key that you said was in some configuration file somewhere. But it seems that a lot of the applications, like if I want to make a derived key for you, I obviously don't know that HMAC key and I have to use the raw R itself. So under kind of what are the use cases of using the HMAC with a little short easy to remember string versus when do you have to use the full R and remember some big number? So the idea here is really that if you want to just use it to populate your SSH agents, you can do it easily with large R values by just using HMAC and deriving the integer in that using that. But if you want to generate the key, the public key for someone else to use based on their own public key, what you can simply do then is you generate it as you want the integer or you can HMAC it with your secret value and then you need to release a value R. You need to tell the people the actual value you use for R. Currently, BIP32 and also one key are using the public key of your master key inside of your of the HMAC to have some link between them. But that's why in the demo, maybe I want to be too quick there, but you can see when you generate a key, just like test, it's outputting the actual derivation integer, which you can then use instead of using test 2, I could use dash R and I can give directly the value R to it. And it will derive the same key, so... But in the Bitcoin setting, you don't generally know someone else's public key, you just know the hash of their public key until they use it, right? So then, you can't do any of this until... Yeah, in the Bitcoin setting, the idea is naturally to have somebody else generating the wallet for you, is that you can yourself have a web application, for example, which will generate new public keys for you to unlock later without knowing your own private key. So if you have a Bitcoin, if you have a website selling stuff and accepting Bitcoin, they might not want all transactions to link to their main Bitcoin wallet, you know? They might want each transaction to go on its own wallet so they can monitor it and see whenever it came and if it came, give you the stuff you bought. So it's not the same kind of use case, I would say, but yeah, it's correct that in the Bitcoin case, it's not as straightforward as here. I would just strongly recommend that for the case that you demoed, instead of just using an HMAC to get from effectively a password for driving R, that you also put in a strong password, you know, at PBKDF2 or its successives. Yes, so the secret value has to be strong if you use the secret value as a key for HMAC because otherwise it's not really secure, you know? So I recommend Ezra using big random value as your secret. Or yeah, I could maybe implement some kind of key stretching so that weak passwords will be better, but yeah. Anyway, that's just for the puck. If you want to play with it, you can. It's open source. All right. We have time for one more question if there's one more. Okay, thank you.