 Good evening. Welcome to this talk about quantum hardening. So before we start let me introduce myself quickly. I'm Carolyn Warner. I'm a software engineer working for Adobe. And besides the work I do for Adobe, I work as a freelance engineer, mostly doing C++ and Rust work and in the course of that one of the things I was asked to build was an HSM. A hardware security module and later I was asked to outfit that with hopefully quantum hardening technology and the research I did is basically what I talked about, what I'm going to talk about today. Right. So this is going to try to be an introductory talk so it's hopefully suitable for engineers. They haven't done that much with cryptography yet. We want a basic introduction into how this works. So I'm going to start off by introducing some of the basic concepts of how to construct a cryptographic protocol and then later move on to how those can be attacked by quantum computers. And finally we're going to discuss how you can react to that and actually quantum harden a cryptographic system. So this is about quantum hardening. It is not about quantum computing. Quantum hardening is the study of how to secure existing cryptographic protocols, existing cryptography against attacks from quantum computers. Quantum computing is the study of how to use quantum effects to build computers while quantum cryptography is about the study of how to use quantum effects to build cryptographic systems. So we're talking about the first that is run on normal computers. It involves no calculations done by quantum computers just making sure our crypto doesn't break as soon as quantum computers become practical. So before we can start introducing how today's cryptographic protocols are built we have to talk about cryptography itself. What is that? So in this example we have Alice who is trying to send data to Bertha and it's a particularly important message. I like your cat ears. Nobody should hear that. It should be very, very well protected obviously. So we would like to use cryptography to make that happen to make sure nobody can listen into that and that's what cryptography is for. So one important property cryptographic systems usually have or often have is that they encrypt data so that anybody spying on a transmission or has access to data cannot read that data. It's however not the only property you would like to have. Take for instance the example of you sending a wire transfer to your bank. You're using online banking. You're trying to wire some money to somebody. Another thing you'd like not to happen is that the data is tampered with because your money might go to the wrong address and that shouldn't happen. So that's another property we'd like that is tamper proofing making sure your data cannot be tampered with. And the third property we'd like to have in a good cryptographic system is authentication. We'd like to know the data is really coming from me because otherwise an attacker could send an encrypted message but they could just act like they're me and they could still send an encrypted message and send wire transfers in my name. So these are some of the basic properties we're going to look at today and how to introduce them and how to make sure they keep working like one of computers are there. So the first we're going to look at some archaic cyphers because they illustrate the point of on a very fundamental level how encrypting something can work. And the thing we're looking at here is quite old as a matter of fact it's roughly two thousand years old because it was invented by Julius Caesar. It's also called the Caesar Cypher. In the Caesar Cypher you take, excuse me, in a rotation cypher you assign every character a number for instance in our example here we've assigned space bar a zero, a one, b a two and so on. And now to encrypt your data you just add a constant offset, you just add the key which in our case is four. So space becomes d, a becomes e, b becomes f and so on. And to reverse that you just subtract the key again. So d becomes space again, e becomes a again, f becomes b again. We have an example of how that looks like when you encrypt our actual text. I like your cat ears become something quite unintelligible. And so yeah, this is encrypted it's very hard to read, nobody can read it so that is encrypted. But is this actually a secure scheme to encrypt data? So can we try to analyze it and find a way of reversing that encryption without knowing the key before? Of course we can because there are just 27 keys, we can just try each and every key until we find the right one. And we'll know which is the right one because we'll see text that makes sense. So that attack is called a brute force attack. And that's just trying every possible key until you find one that works. And you can do it quite quickly. Trying 27 keys doesn't take that much time. Let's look at a different cipher, one that's quite similar a substitution cipher. And here we don't add a constant offset to each character, but we're still replacing one character with another. And basically we just shuffle the alphabet. So for every character in our alphabet, we assign a random character that maps to. So space bar for instance in this example becomes J, A becomes X, B becomes N, C becomes G. So it's been shuffled. And again when you encrypt using this key, you get something that is quite hard to read. So that was successfully encrypted. Now breaking this is much harder than breaking the rotation cipher. But this is still not good enough because on one hand you have 27 factorial keys. That's a lot of keys. You cannot try each and every one of those would take too much time, but there's a weakness in our cipher. And this weakness is if you take a look at our cipher text, you will notice that certain characters appear particularly frequently. For instance the J appears quite often. Why is that? Well because the J is space bar and space bar is a common character. Same with X and D, X and D, X and D map to E and A. Each E and A are vowels and vowels are much more frequent than most other characters in the English language. So what you can do is basically just look at the distribution of characters if you have a large enough cipher text and then say with a high probability which character maps to which character in the plain text. This is called a statistical analysis and that's the way you can easily break a substitution cipher. So let's look at a third archaic cipher and that's a transposition cipher. In the two examples before in the rotation cipher and the substitution cipher we were replacing one character with a specific other character. This works slightly different. In this example we're replacing one position with another position. So we're not shuffling our alphabet, we're basically shuffling our text. So in this example it just says move the first key to the third position, move the first character to the third position, move the second character to the first position and so on. That's because our key is 3, 1, 5, 4, 2 in this example. So using this key, hello becomes Eol. Eol is quite hard to read while no not really Eol is actually relatively easy to read because it's an anagram of hello and there we already have it how this type of cipher can be broken. You just form anagram until you find one that seems to make sense and again if you have enough cipher text you can easily decrypt it. So attack against transposition cipher, just try out anagrams until you find one that works. So let's jump ahead. These were archaic ciphers that haven't been seriously used for seriously purposes in a long time. Let's look at how this type of thing is achieved in modern times, how modern cryptography works. And of course little caveat here, this is very much simplified what we're going to talk about right now. This is just supposed to give a basic overview, it's not supposed to give your comprehensive idea of how something like this can actually be built. There's a lot of subtleties when implementing cryptography, a lot of things that you can forget to do and suddenly your entire protocol becomes unsafe. So take care. So again we're looking at one particular example that can be used to construct modern cryptographic protocols and that's a block cipher. There are alternatives to block ciphers, specifically their stream ciphers, but block cipher is a particularly nice one to look at for now. The example we're seeing here is basically AES, that's the advanced encryption standard. And AES is based on a substitution permutation network. And this is what we can see on the right side of the slide. There are three distinct steps to a substitution permutation network. The first step is this cross in a circle. That stands for XOR. And XOR is actually just equivalent to a rotation in binary. And what that does is it does not rotate the entire block of plain text by a fixed value, but it just basically rotates each bit by the amount indicated from the key. So it rotates each bit from plain text with a separate bit of key material. And then you have combined your data with a key. And now this is just sent through substitution boxes, which is basically a substitution cipher. There's a lookup table and that replaces that data with another value. And then the third step we can see that's this mesh, that's this graph type thing that shuffles the bits around. And the idea here is that when you have done that multiple times, you repeat that process a couple of times in multiple rounds. The idea here is that you end up with every bit of the cipher text being influenced by pretty much all bits of the plain text and of the key. So the goal kind of is if you flip one bit in the key, 50% on average statistically of the bits of the cipher text flip. Same with the plain text if you flip 50% of the bits from the plain text. If you flip one bit from the plain text, roughly 50% of the cipher text bits should flip. So what this does is it obscures the relationship between plain text key and cipher text. So it's very, very hard to kind of find, to reverse that process without knowing two of those three things. Yeah, so one thing I forgot to say is that of course this just works in blocks. That's why it's called a block cipher. You just take a fixed size block of plain text and encrypt that and each block separately. And to reverse that process you just run it from bottom to top. We've just talked top to bottom and reversing that is bottom to top because each of those operations is reversible if you know the key. Right, so yeah, one thing you've got to mark is that that by itself is not secure. Why is that? Well, there are some caveats to look at. For instance, one property this particular construction has is that if you encrypt the same block of data with the same key, you will get the same output. Why is that a problem? Well, it sometimes happens that you do encrypt the same block for instance. For instance, if your data contains a lot of zeros, you will be able to see that. So you can still see some patterns of the, you can still see some patterns indicating what the plain text roughly looks like. And that's not good. And so you can work around it, you can build more complicated protocols. In this case, the mitigation you'd use is a block cipher mode that just combines the current block of data being encrypted with previous blocks. So you don't get the same result twice. Just keep that in mind that that's a fairly incomplete picture here. So now let's try to use that to build a cryptographic protocol. Bertha still would like to send her message. I like your cat ears too. Alice would still like to send her message to Bertha. So the first thing she has to do is she has to create a key and transmit that to Bertha. And this is the most crucial step here because the key has to be transmitted very, very securely. If the key is leaked, an attacker can read the data being transmitted. So you have to find some way to securely transmit the key, but then you can use the key again and again to send data securely. And of course Bertha can do the same. Bertha can just send keys back, send messages back using the same key basically. There's still one weakness there. Now we have encryption, but we don't really have the other two properties we want. The data can still be tampered with and Bertha wouldn't notice or you could even send completely random data. And Bertha would just decrypt it and the data might look like mumbo jumbo, but there's no real fixed way to detect that anybody sent just random stuff. So we can solve that and the solution to that is called a message authentication code. And a message authentication code just takes some sort of text, combines that again with the key and generates a short string of data representing that key together with the text. An important thing to know here is that from the authentication tag, the text and the key cannot be recovered. So you can just generate that authentication tag and add that to your message, add some redundant data. And any attacker wouldn't be able to generate their own authentication tags because they wouldn't be able to generate their authentication tags because they don't have the key. You need the key to generate the tag. So now we can just add that to our protocol. The key exchange works like before, but now Alice first encrypts her data and then runs the message authentication code on the ciphertext and then just appends the message authentication code to the ciphertext. Bertha does the same in reverse, she just also generates the message authentication code because she has the key. And if she notices that doesn't match with the message authentication tag sent by Alice, then she just abhors execution. She just stops decrypting data and says, sorry, something went wrong invalid data. But if the check succeeded, she can decrypt the data and we're fine. So if the message was changed in flight or if anybody was tampering with the data, we could detect that. So one thing you may notice that there's kind of an Achilles heel in this entire construct and that's the key transmission. Because if the key is leaked or even if parts of the key are leaked, it makes it much easier for an attacker to decrypt the data. Yeah, it makes it much easier or if the entire key is leaked, of course the attacker can encrypt the entire data. And the problem here is that the key is very bad to work with. It's a random string of numbers, it has to be a random string of numbers for cryptographic purposes. So that's very hard to transmit. You can write it down, but then you can lose the paper and that's not very nice. You cannot use passwords because most cryptographic primitives expect a high entropy key. Or a high quality key, a key that looks very, very random. And of course a password doesn't do that. A password contains more ace than access and that makes it unsuitable for direct use as a cryptographic key. We can do something to work around that problem. We can use a key derivation function. And a key derivation function just accepts key material. So that is just data containing secret data that is not very well formatted as a key, it may be too long. There may be patterns in it, it may be just plain text, it may contain more ace than access. If it contains enough entropy, the key derivation function will generate a high quality cryptographic key from that. So this basically enables us to transmit passwords because we can just transmit a long enough password, pass it into the key derivation function and generate a high quality key. Or we could even send multiple messages and just have a very, very long password that we put into the key derivation function because we just concatenate all the separate passwords. And if one of the messages or if enough of the messages get through unscathed and we actually have enough secret entropy, the resulting key will be safe. So key derivation function very, very neat for generating high quality keys to use in encryption. Let's look at how we can add that to our protocol. Basically now Alice doesn't generate a key anymore. She just generates a password and transmits that password securely to Bertha. Both insert that password into their key derivation function and now they have the same key on both sides. So yes, that is very useful. The rest of our protocol just keeps working as it did before. So having a key derivation function has improved our key handling a lot. We have a much easier time managing our keys, but it's still kind of problematic. You still need to have a trusted messenger or have some sort of very, very safe way to actually transmit the cryptographic key. And you don't really want that. So it had to be done this way. You had to have some secure way to transmit keys until asymmetric cryptography was invented. And that is pretty cool because then basically solve that problem very well. In asymmetric cryptography you don't have one key that is used both encrypt and decrypt data. You have two keys. You have one public key that you can publish and that everybody can see and use. And you have a secret key and the secret key only you keep that. So personally I could tell you my public key right now. I could just print it on the screen and you can even go to my home page and download my key basically and send me an encrypted email. That is one of these public keys. I can publish that no problem. I just have to keep my secret key private. So the public key is used to encrypt data destined for me and only the secret key can decrypt it again. There's an inverse or there's an equivalent for signatures too for authentication. And that is called a digital signature. And there I can use my secret key to sign data and you can check the signature. Check that it's really from me using my public key that's on my website. So now basically what we've done we've reduced the difficulty of exchanging keys from we need to have an unobserved channel to transmit the keys through. We have a spy free channel. We've reduced it to you just need to be sure it's coming from me. And that is much easier to create again. Think of the example of me just putting that on my card. Handing that to you we can do that in a public space no problem. But transmitting the key through whispering would be quite hard. So that improved things a lot. Yeah. So for most there is a third kind of asymmetric cryptographic cryptographic primitive. And that is called a Diffie-Hellman key exchange. Most connect most cryptography nowadays is usually done on live connections. So if you're streaming this video right now you'd be using such a good you'd be using you'd be streaming through such a connection. The connection is encrypted and both parties can just send messages very very quickly. And so in such a scenario we can use a Diffie-Hellman key exchange instead of the asymmetric encryption we've talked about before. And in a Diffie-Hellman key exchange we both just generate our key pairs and transmit each other's public key. We transmit those to each other and then I combine my private key with your public key. And you the same just with your public key and my private key. And we'd get the same password that we can then put in a key derivation function. And the cool thing about that is just we never actually transmitted the key. We just transmitted the public keys. So that's kind of a bonus there and a very nice property to have. Yeah. So this is what it looks like when we build a protocol using that. We start off by using a key exchange, a Diffie-Hellman key exchange. Have some sort of authentication algorithm going that often uses signature algorithms. And then we just put the exchange secrets, the secrets we just exchanged into our key derivation function and then encrypt data as we had before. So we just use asymmetric cryptography in the handshake. And then use symmetric cryptography like we did before in the rest of the connection. And that is very nice because asymmetric cryptography is kind of slow. So we get the asymmetric advantages of having public keys and private keys while getting the speed advantages of symmetric cryptography. This pretty much is the state of the art right now. So the connection you're using probably uses something like this. TLS, if it's a modern cipher, uses pretty much something that looks like this. Now, that is nice and all, but how do quantum computers come into play? So how can we attack that construct using quantum computers? There are basically two quantum strategies used today to attack cryptography. Or that can be used to attack cryptography. It's not done in practice in the wild actually. The first thing you can use is Grover's algorithm. And that's just a generic quantum search. So we talked about a brute force attack before. That is just trying every possible key until you find one that fits. And on a classical computer, that just takes your key space divided by two attempts. So imagine you have a million possible keys. A classical computer will just need 500,000 tries to find that on average. Quantum computers are faster. Quantum computers don't need a key space divided by two tries. Quantum computers just need a square root of key space size tries. So for a million possible keys, quantum computers for quantum effects, I don't really understand. They just need a thousand tries to search for a key in this key space of a million keys. That is quite a bit faster. And that pretty much works on any cryptographic system and on any problem. It's just the quantum search algorithm. So it's a lot faster. The nice thing here is that we can mitigate that just by increasing our key size. So if we want to have basically the same level of security, we can just use a 12-digit key, a 12-decent-digit key. So the quantum computer will need a million tries to find the key. And actually doubling the number of security bits, doubling your key space is not actually that expensive. So you can pretty much just do that and you will be fine. There is another algorithm and a more important algorithm that can be used to attack cryptographic systems. And that is Schor's algorithm. Now one thing you have to know is that all the asymmetric cryptography used today is basically based on two mathematical problems. It's based on the internal factorization problem or the discrete logarithm problem. And both of them can be solved very, very efficiently using Schor's algorithm. And of course it's nice that these problems can be solved, but since we're using them for cryptography and since they are the basis of why our crypto is secure, the fact that it is so hard to solve those problems for a classical computer is what makes asymmetric cryptography safe. So the fact that quantum computers can solve those problems effectively means our handshake is broken. Pretty much all of modern asymmetric cryptography is broken by that style of attack. So let's take a look at how much of a problem that actually is what the quantum computers today look like. So today you cannot seriously, you cannot use our quantum computers to run Schor's algorithm and attack existing cryptographic systems for the simple reasons that quantum computers are not advanced enough yet. They simply run out of memory. Quantum computers have something called cube bits, quantum bits, and the big quantum computers have something like 50, 60 bits right now. Modern asymmetric cryptography has a lot more bits than that, so they cannot be attacked. They're also very expensive and you need to cryogenically cool them, so it's not practical and it's not expected to become practical to actually run these attacks in the next couple of years. However, maybe in 10 years, 20 years, it could become a serious possibility. As a government agency or any actor with a lot of money, if you want to attack existing cryptography, one thing you can do is just store the data being transmitted right now, save it and wait it out until quantum computers become practical. And of course, for most data we transmit today, that is really not that big of a deal. The fact that your cat videos, YouTube videos can be decrypted later, that you're watching them can be decrypted in 10 years is not a big problem. But there's some data that is important enough that you still want it to be securely encrypted in 10, 20, 30 years. For instance, think of your health data. You don't really want any attacker to be able to access your health data in 10 or 20 years. So for this data, it would be nice to have a strategy that works today that is secure against attacks from quantum computers. That brings us to post-quantum cryptography and the thing is it doesn't really exist, well it does exist but it's not really in production yet. It's being developed. NIST, the National Institute of Standards and Technology in the US is running a competition to find good candidates for asymmetric quantum proof cryptography. They started a couple of years ago, around five years ago. They're right now in round two. They started out with something like 90 primitives and now they're down to around 26 last time I checked. So they're in the process of trying to find good algorithms to use. It's not expected that they will finish before 2022, probably mid-decade at the earliest. So right now we're just looking basically for algorithms that are really secure and that are really trustworthy. But you can follow that process on the PQC forum mailing list, the post-quantum cryptography forum mailing list. It's open. You can subscribe and just watch what's happening. It's sometimes quite interesting to read. So let's look at what there is. There's of course the key encapsulation methods that is basically asymmetric encryption. Based on problems like learning with errors, error correction codes, that sort of thing. Those are just the mathematical problems that are used instead of discrete logarithm or integer factorization. And they've actually been tried already. So Chrome, Google Cloudflare, they built some of those primitives into TLS. And tried it out. The result was something called CEPQ1 and CEPQ2. They tried the primitives I've written down here. I basically just worked. I mean, the handshakes were, it was a bit less efficient because they added those in. In addition to the classical handshakes, but it basically just worked. They're available to use. It's just not yet that clear if they'll really be secure. The BSI, the German Ministry of the Interior basically, they wrote a paper stating that if you really want to implement post-quantum cryptography right now, you might try ProtoKAM and classic McEllis. So if you're in Germany, those may not be bad suggestions to look at. So these are basically the cryptographic methods used for key exchanges. Of course, for digital signatures, there's also something. It's not as relevant right now because digital signatures basically protect you from men in the middle attacks. So basically a server intercepting the communication between you and your second party, opening separate connections with each, decrypting and re-encrypting again. And you need to have practical attacks for existing digital signature algorithms right now. You need to be able to run that in attack in a couple of seconds. So right now we don't have quantum computers that can do that. So it's not as relevant and you can't run that attack in the save now decrypt later style. So not as relevant but it's still being developed. There are primitives suggested for that use case too. So using digital signatures and key encapsulation methods, you can build a fully quantum proof systems provided those primitives are actually secure against classical and quantum computers. So I've just talked about that we can't really trust those algorithms yet, but Google and CloudFair tried those out in the wild. So how is it possible? Well, you don't really want to use those past quantum algorithms yet. That is true because they're new and shiny and when you're doing cryptography, new and shiny is not something you should strive for. However, you can use those algorithms in conjunction with existing asymmetric preprography primitives. Ideally, you would like to combine those two styles of key exchanges, those two styles of signatures in such a way that the resulting protocol is as secure as the strongest of the two. So if your post quantum algorithm is broken, no problem, you still have your classical algorithm. If the classical algorithm is broken, no problem, you still have the other algorithm as a backup. So implementing that in such a way, building such a system is not quite as easy as it would sound like. There is a field of study looking at how to build such protocols and that is called robust combiners. And when you type robust combiners into your search engine of choice and look for papers on the subject, you will find that, well, there's a lot of papers just saying, hey, this seems like it may be a good idea, but it really is not. So don't do that. However, there is one combiner that is pretty much proven to work and that is the concatenation combiner. So to combine your post quantum algorithm with your classical algorithm for key exchanges, it basically says just do both key exchanges and concatenate both resulting the key material from each step. Just concatenate those. I know you think, well, now my key is too long. I can't really use that except you can because you just passed that into your key derivation function. So run both handshakes and put the result into your key derivation function. For signatures, it's even easier because you can just run the signatures. You can just run both signatures. Test each and if one of them fails, consider your signature to be invalid. So that works even more easily. Now let's take a look at how we can combine that into a functioning protocol. We just do two key exchanges and authenticate twice. Now we take the entropy from both our key exchanges and pass both into our key derivation function. And then we encrypt and authenticate as we had it before. So that's pretty much it. That is how you can construct a quantum-hardened cryptographic protocol. And if you get it right, which is kind of a big if, if you get that right, you will have a quantum-hardened cryptographic system that can be used today pretty much. Doing that is not that easy though. So now the question remains which, which primitives should you use? And the answer is the jury is still out for that question. There is no straight answer I can give you because NIST is still running their competition. And right now there is not a clear winner that we're sure is going to be suitable. If you insist you want to implement something today, using classic McEllis is probably not a terrible idea. Classic McEllis was invented in the 70s, has been widely studied and is believed to be safe. The problem with classic McEllis is just that it's got giant keys. So for my protocol for the HSM I implemented, classic McEllis was unsuitable because it wouldn't fit into memory. Sphinx Plus for signatures is probably, well it's not as old and as reliable as classic McEllis, but Sphinx Plus is probably not a bad choice. Failing that photo KM, failing classic McEllis because the signatures are too large, photo KM is probably not a bad choice either. Photo KM has very very large keys as well, so that's something like 10 kilobytes, but not 100 kilobytes like classic McEllis if I recall correctly. So how do you find an implementation? Of course you wouldn't want to implement any of those primitives yourself. That's not a good idea, you're going to get it wrong. For the classical algorithms, symmetric as well as asymmetric, pretty much just use lip sodium. Lip sodium is written to be very hard to abuse. It's got a very constrained, very nice choice of primitives. So if you use one of the primitives in lip sodium or one of the constructions in lip sodium, it's hard to make a bad choice. There are other cryptographic libraries for classical algorithms out there, but a lot of those feature some outdated algorithms that are just no longer secure. So use those at your own peril. Or actually use lip sodium too at your own peril, getting this right is hard. For post-quantum hard and primitives, there's lip OQS. Lip Open Quantum Save and PQ Clean. And lip OQS actually uses quite a few implementations from PQ Clean. In my project, I ended up using PQ Clean just because it would compile for the platform I was working with. And lip OQS wouldn't trivially, so I just saved some time there. MUPQ also implements some of those primitives. It's got optimized versions for ARM. So I didn't find those to be necessary because the system I built was memory constrained and not performance constrained. So using PQ Clean was fine. But if you need higher performance, MUPQ might be something you could look at. To sum it up, we have our symmetric cryptography. That includes all block ciphers, stream ciphers, key derivation functions, message authentication codes, and so on. And those are ostensibly fine. Just double their key size to stay secure. Asymmetric cryptography is basically broken. The existing primitives that includes things like RSA, DSA, Diffie-Hallman, classical Diffie-Hallman, those are no longer secure. They have to be replaced. Post-quantum algorithms exist, but they're not really trusted yet. So what you end up doing is you use post-quantum algorithms in conjunction with asymmetric classical algorithms. And if you get that right, you hopefully have a system that is quantum hardened. Now feel free to address any questions to me. You can send me an email, caro at captive.net, that is K-A-R-O at C-U-P-D-E-V dot N-E-E-T. Or you can tweet at me at D-A-K-O-R-A-A, that's Dakota. And I'll be happy to answer questions. And finally, I'd like to thank Agnes, Jane Pie, Florian, Benven, Mimi for helping me make this talk. And thank you for your attention and have a great evening.