 Yeah, the talk that is symmetrically and asymmetrically marked cryptography by Alex Ruyukov and Lil Perin. Lil is here to present the work. Thank you for the introduction. So yeah, this is what I did when I was in Luxembourg. I'm not there anymore. I'm also not related to our program chair. There is a slight difference. I'm so nervous in here as far as I know. All right. So in this talk, I'm going to talk about a wide variety of subjects within symmetric cryptography. And I'm going to argue that they are all particular cases of the same general idea. So I'm going to talk about white box crypto, big key encryption, password hashing functions, key derivation functions, time locks, and possibly others. And see what they all have in common. We also explain what they are if you are not really with them. So first I'm going to argue that this is about efficiency and specifically inefficiency of a primitive. Then I'm going to describe some modes of operations which allow us to build such functions and then present a particular case of one function we designed ourselves. So when you're building a new, say a new block cipher, you want to have, you want to have an efficient implementation and to measure the efficiency of this implementation, you look at several metrics. I'm going to simplify here, but basically what you look at is the time it takes to encrypt one block, which you may measure in a CQ cycle, sorry, in seconds. You're going to look at the code size. So that's the size of your implementation. Do you need to store tons of information in your source code to implement your algorithm or not? And you also need to look at the RAM consumption. So that's the huge also majority of just invites. And it's the information that you're going to generate every time you receive a new input. So suppose that you have some, a given algorithm, a fixed algorithm, and you're just going to make various implementations of it. So you have a certain amount of time, certain amount of memory, certain amount of code that you need. Then you can use some tricks in your implementation. You can enroll the groups and your code is bigger, but your time is a bit smaller. You can use some pre-computations. You can use underfly computations. So instead of storing information in the code itself, you really just read it every time. It's going to be slower, but your code is smaller. So you have this kind of trade-offs. So these are the kind of trade-offs we think about when we design a new algorithm, a priori. But in fact, what we have found is that many algorithms from asymmetry crypto are actually designed to be inefficient on purpose around one of these three axes. So for instance, there are algorithms which we are going to call time hard, which are slow on purpose. So I'm not going to talk too much about possible parallelization here, but basically it's algorithms which are intended to be slow. The idea is often to just slow down brute force. So PBKDF2 is a key derivation function which basically just iterates a hash-based MAC thousands and thousands of time. And the idea is that if you are putting a low entropy password through this function, which is from a set which could be brute-forced, then the time it costs, the time it takes to brute-force it is multiplied by thousands of thousands. So the aim of having a slow algorithm is to frustrate brute force. But these algorithms, you want them to just be slow. You don't want them to take tons of RAM. You don't want them to take a huge code size. So this is time hardness. You also have what we call code hardness, which is an algorithm which takes, which requires a very large implementation. So to clarify the distinction we made between code hard and memory hard, which is the next slide, in code hard the information that you need to store does not depend on the input of the function. So you have your implementation of the function. It requires huge amounts of data. But this data does not depend on the input of the function. It's at rest. It's information you're only going to read when you evaluate the function. So an example of such a code hard function is XT2, which was presented at crypto 16, which is used for big encryption. So the idea, very roughly the idea of big encryption and XT2 in particular, is to frustrate key leakage. The idea is that you are using some encryption on your computer, but there is some malware in your computer which might just send the key you use for encryption to whoever is your favorite boogieman. And the idea then is that if you make this key huge like gigabytes, then it's much harder for this malware to just exfiltrate the key. You can assume that your systems and your network administrator might notice that you're suddenly uploading gigabytes of data. So to prevent this kind of key leakage, you might want to have an algorithm which uses a huge key. This is big encryption and XT2 does that. So XT2 is basically a, you can think of it as a kind of hash function, which requires huge tables to run properly. And if the adversary has even just half of this big key, they can't do anything with it. So that's code hardness. Again, you will put that line, this function, fast. You don't want it to use as a run. You just want it to be huge. You have memory hardness after that. In this case, the idea is that the function has a small implementation, but on every input it gets, it generates a ton of data which it needs to store, so to write and then read in RAM. And that's memory hardness. An example of this, so it's more recent. The example of this is Argon2, which is the winner of the password hashing function. We also have balloon hashing, which is even more recent. And that's the aim of N. So both of them are intended for password hashing. The idea in this case is that since the function requires this huge amount of RAM, it's going to make it harder to build dedicated ASICs to efficiently run the function. So, for instance, if you just have a function which is code hard like ppdf2, what you can do is just build dedicated chips, which are going to run your hash days very, very fast. And that will allow you to kind of offset this slowdown through hardware. The point of this is to prevent that. The particularity of memory hardness is that since you need to write this information to memory every time you run the function, it can't be arbitrarily fast because it takes time to write. You need to generate and then write the data to memory. So in this case, you want the code to be small, you want the memory to be huge, but the time you can't make it arbitrarily small. You want it to be as small as possible, but you can't make it arbitrarily small. All right. And so this was just what we call symmetric hardness. Then we can go further and introduce asymmetric hardness. So asymmetric hardness is the idea that you have two functionally equivalent algorithms. So for even input, they will give you the exact same output to both of them. The difference is that one of them is run hard, run hard, both hard or time hard, and the other is not. And what separates whether you can evaluate the efficient one or not is the ownership of a key. So you divide the users into basic users and privileged users who know a secret key. And the privileged users can evaluate, so we denote the FK, which is an algorithm which is functionally equivalent to some hard algorithm F, but FK is not hard. So time hard, road hard, run hard. We say road hard is to be higher. So obviously, you don't want the adversary to be able to recover K from the division of F, because then for this adversary, the function is actually not road hard, the adversary just recover K from F and then evaluate the efficient one. So this is asymmetric hardness. So this, what I just presented is like a new way of thinking about these different areas, but you actually have algorithms which fit in almost all the niches of this table. So you have time hardness, you have which can use for key derivation, you already have function, for memory, again, for password hashing exists already. For the symmetric, those hardness, you have the encryption, which is called IHC2 and WAIL, which I'm going to very briefly present later. For asymmetric hardness, we have the time loss, which is based on the RSA log. I'm going to go into more details about how it works later. But the idea of time loss is that you would have a piece of information that you encrypt with some guarantees that it cannot be decrypted before a certain date. So that was for the time loss. You take your information, you want to really release it eventually, but you don't want to release it now. So what you do is you release an encrypted version of this information and you know that the key cannot be derived before a certain date. For asymmetric memory hardness, we, as far as we know, are introducing the concept and we will introduce also a function which provides this. So how can you be used? We don't know. Hopefully you can figure something out. And asymmetric code hardness is what some recent white box algorithms have tried to achieve. So the idea is that your implementation of the function needs a huge amount of space, but there is another party who knows a secret key and who wants to be able to evaluate the same function. So in this case, it's an exciter. Without storing these huge tables. So that's recent iterations of symmetric white box cryptography are really about asymmetric code hardness. So now that we have this nice unifying view, can we do anything with it? And in particular, can it help us design primitives with either of these six forms of hardness? Yes or yes? So the idea we had is to combine secure primitives, symmetry primitives we know and trust. So Ketchak permutation and AS and combine them with the small functions which give us the form of hardness we want. So anyway, so yeah, we have these small functions which we can combine with the primitive. The primitive gives us the security and the small function gives us the hardness and we're going to figure out how we do that. So in order to be a bit more formal, we introduce a gain which is lifted actually from a definition of white box crypto from last year's Asia Crypt. But first let's clarify a bit what the aim of the adversary is in this context. So we have a function f which is row hard. So it goes hard memory hard time hard one of them. And what the adversary wants is to be able to evaluate this function f without paying for this price without paying for this hardness. So what they want to find is a function f prime which is not row hard but which is equal which is such that f prime of x is equal to f of x with a high probability. It's sufficient perhaps for the adversary for this to be true half of the case or with probability to the minus 20. So that's the aim of the adversary. And also the resources needed to come up with f prime even f should not be too high like if they need to reinforce AESD say we don't care this adversary is too powerful to be involved with it. A generic method against this which does not depend on the form of hardness is to just take f of f the function f which a prior a prior is public and just evaluate it on a bunch of inputs and store the results in a table. So this will give you a function which has a huge good hardness but which might still remain practical. So this is the generic adversary we want to bother ourselves against. So we gave the name it's the 2 to the p adversary and it's another adversary you basically can store 2 to the p blocks of information. And also we are not giving this adversary an unlimited amount of computing power. So what we don't want them to be able to do for instance is to like break an RSA key or recover an AESD etc. We want this adversary not to be infinitely powerful but we don't want this adversary to be able to find efficient approximations of our row property function. And then we play a game with this adversary and so we can find a more formal definition of our row hardness which is here and again this is basically lifted from the work of Pierre Valençouk and his friends from Penn which was presented at Foster's Egypt but it's generalized in all forms of hardness. So the idea is that the challenger has chooses a row hard function f which is made public so the 2 to the p adversary gets it and then tries to find an approximation f prime of f which is not row hard. And then the challenger picks an x uniformity at random and sends it to the adversary and the adversary wins if his approximation is correct on this x. Note that the adversary does not control x because otherwise there is an obvious attack the adversary receives f he concludes f of x and then he wins so he does not control x. The way we suggest building primitives which are both secure in the cryptographic sense and row hard in our sense is like this. So for a block site it's the same in each case so you take a small function p which is row hard possibly asymmetrically if you want to and you use it basically as a fister function inside either your block site or your sponge function and your sponge updates limitation. So p is a function just blocked here so since we are just touring engineers we want it to plug and it has to be again code hard type hard whatever you want. You have to iterate these several types so if again if you do this for asymmetric code hardness you basically end up with the construction which was introduced last year but you can do this with any form of hardness asymmetric or asymmetric. You can do it also with sponges for sponges we add requirements that both the input and the output of the plug need to fit inside the capacity inside the inner part of the sponge otherwise you might get issues since the adversary can actually control what happens here. And so the small functions you can use to build whatever hard function you want are here so if you want a function which is super slow you just take your hash function and you iterate it multiple times on your input you can't make it any faster as far as we know. For asymmetric I'm going to explain in more detail how it works but this is basically a time lock memory you have argon 2 if you wanted asymmetric you have geodon which I'm going to introduce soon. For the code size you can have just a huge table of random stuff and if you wanted asymmetric instead of random stuff you use the outputs of a block cipher where you have these most of the input and only various small parts of its input. So for this function if you want to evaluate it fast you just evaluate the block cipher and if you don't have a secret key you have to store the huge table as with asymmetric code hard. So you take any of these functions and you combine it with those operations before and you can build any of those. So we have described a code hard hash function which is functionally pretty close. I mean what it aims to achieve to xk2 it works completely differently but it's designed for basically the same as xk2 and it's a symmetrically code hard hash function. A steeper is an asymmetrically dying hard block cipher which is a block cipher which can be fast or not depending on whether you know an RSA private key or not so everybody can just evaluate the block cipher but if you want to be able to evaluate it fast they have to know the RSA private key and we can actually tune the speed difference between privilege and the basic users. So this is great. The problem we had when we started working on this was that we had all the functions in lag but for asymmetric memory hardness there was a big gap in our table it was the only one which couldn't be achieved so we tried to design an asymmetrically memory hard function and we started from s script so this is s script the way it works is you have your input x and from x you generate a huge array of data by just hashing x again and again and again and you have to store all this in RAM and the reason you have to store all this in RAM is that you then make a second loop where you take the last entry here and then you hash it along with some entry from the from the previous table so you generate some index in the table here which is basically the value here modulo the size of the array you concatenate your hash you store in your hash that is necessary and then you repeat this and the idea is that if someone doesn't store all this information they're going to have to re-compute a lot of it every time since h is one way so this function is memory hard because of this then you just take the last value you concatenate to the length you want and that's your output so this is s script well-known memory hard function what we did was basically force the basic users to store the food table just like in s script but do it in such a way that privileged users can actually compute any entry in the table in constant time so without needing to store anything and the way we do this is using this time loop I mentioned before which is based on RSA and the way it works is that you have so your usual RSA group and the basic users only know the public key and the privileged ones do the factorization of your modules and the evaluation of the function is raising your input x to the power 2 to the power eta or eta is some parameter so you have to do eta squareings and what happens is that the basic user can only evaluate this function in this way they have to do eta squareings while the privileged user can first reduce 2 to the eta modulo this thing and then return x to the power that thing which is much much faster as eta increases and so what we do instead is that instead of having force to the hash function at the top we have force to this RSA time loop so the basic user has to store the array just as before because if they need the previous value they it's exactly the same as with s script but for the privileged user they don't need to store anything they just every time they need an entry they just raise it to the appropriate power which they can compute quickly using the fact that they know the factorization of n so since they know the factorization of n they can compute this value here efficiently and then x to the power that thing efficiently as well so we went from how do you store all of this to basically nothing one downside of this is actually a downside it inherits from s script instead if a user wants to divide the memory usage by k they only multiply the running time by k what you would like is that they multiply the running time by k to the power something where something is strictly greater than one as you have in organ 2 and balloon hashing that the main strength they are more memory harder in some sense than s script the downside is that we couldn't fit this kind of trick into neither s script nor either organ 2 nor balloon hashing but nevertheless this is a symmetric memory hardness which is what we set out to achieve so we're pretty happy about that we actually implemented it the information is not online but if you want it I'd be happy to send it to you the problem we have is that RSA is much slower than a call to a hash function so in order to so if we just use the same structure as in s script we can only fill one megabyte of RAM in about 10 seconds for basic users and previous users don't store anything so what we had to do to make it much much more efficient than fill one gigabyte in about the same time for basic users is to set eta to be equal to one and basically change so in s script the length of the volume which generates this and the length of the volume is here are the same it's not the case anymore if we want it to be fast we have to reuse a lot the length of this whole compared to the other one so it has to still be long in some sense otherwise some attacks become obvious but it should be if we make it shorter we can gain hugely in terms of efficiency we can fill one gigabyte in 10 seconds and again for previous users the time is basically the same but the RAM consumption is it's zero of course that it's very low so yeah the conclusion is that whatever you want in here you can have it thank you so thank you for your presentation you mentioned at some point white box you can you remind us with the connection between your construction white box so yeah so you have lots of algorithms which have been published recently so again age records you have this boggy cipher and white block block cipher you also have space block cipher etc so the aim of these algorithms for these block ciphers is to be such that you have again two classes of users they won't don't read that but basic user and the privileged user the privileged user can just run the algorithm in using a small implementation while the basic ones have to store huge cookup tables and have huge implementations of the program and have to use that huge implementation of the program to be able to evaluate the function so the functionality is probably anyone can evaluate the block cipher but if you don't know how these huge tables were generated you have to store them if you know how they were generated you don't need to store them so the implementation is much smaller the code size is much smaller so it's for the code size yes it's for the code size it provides a solution for the code hardness exactly so as I said come where this this version of this view of white box cryptography is basically what we call asymmetric code hardness okay thank you