 Hello everyone. Let's welcome our next speaker in security of the room, is Gils and his talk about implement incrementality and deck functions. Thank you, welcome everyone. Thank you for attending my talk during the lunchtime or almost lunchtime. So indeed in this talk I will talk about symmetric cryptography and I will talk about some considerations we've had recently around the notion of incrementality. So when I say we, in this presentation, everything I'm going to say is joint work with the rest of the catch-act team, namely Guido Bertoni, Johann Dahman, Seth Offert, Mikael Peters, and Ronny Van Keer. So just a bit of background on what we do. So we are interested in permutation-based crypto. So permutation-based crypto is something, a new kind of crypto in the sense that instead of having a block cipher, we use a keyless permutation. The name catch-act team comes from the designers, originally from the designers of catch-act, which was selected as chat tree during the chat tree competition. We designed some many stuff based on permutations. So we didn't stop at hashing, we also looked at encryption and authentication. We developed some new constructions. One instance is a key duplex, another one is farfale. From these you can build encryption schemes, authentication schemes, or authenticate encryption schemes. And we developed, of course, we designed some specific instances. But yeah, in this talk, it's not going to be about all these new schemes. Instead I would like to talk about what I call incrementality. So incrementality is the notion that if you have some kind of cryptographic primitives, you have some input, some output. You can, from the input, get some output. And then you take your input and you increase. You add some more string to your input and you get another output. Then you add more string, you have another input and so on. You every time get some output on everything that you have, constructing your inputs step by step. The key thing about incrementality is that every time you do that you don't have to start all over again. You only pay the price for the additional string that you're adding to your input. That's what I mean with incrementality. And we're trying to look around this notion and we think it's an ingredient that can help simplifying symmetric cryptography. So that's our goal. We want to do something that is simpler in terms of description, in terms of implementation when it comes to authenticate encryption. We recently developed something called a deck function. So a deck function is not a new construction on top of all your other constructions that I mentioned. It's more an interface, something that aims at capturing the notion of incrementality. And on top of this interface we can build modes for authentication, encryption and authenticated encryption. Okay, so in this presentation I will talk first about incrementality and for that I will take as an example the Discord protocol and then I will talk about deck functions more specifically. So why is incrementality useful and in the sense that it can help us simplify things? So the Discord, I will explain of course what the Discord protocol is, but to start I need to go back to the basics. And the first, let's say incremental construction that we defined was the duplex construction. If you may know that the catch hack is uses a sponge construction, the duplex construction is just cryptographically equivalent to the sponge construction. The only difference is the interface. The interface allows us to have input, one input block, one input block, one input block, one input block every time. So it uses a permutation, the permutation is F here, you have some block of input and you can get some block of output. Then you have a second block of input, permutation, block of output and so on. And if you look at maybe this block of output, this block of output is going to depend on all the past input blocks. So we have this notion of incrementality. But as such, the duplex is not really useful, we need to have some layer on top of it to build something concrete and useful in crypto. One thing that we can do is to use the stroke protocol. So the stroke protocol was designed by Mike Hamburg and it was presented at Hillwell Crypto three years ago. And so it's just a layer of duplex, but it provides a really nice and simple syntax that you can use for instance to build secure channels or to hash the transcriptable protocol. And it's simple enough that it allows for a really compact implementation. So in terms of lines of code, it's fairly compact. Concretely, what can you do with the stroke protocol? You can have some, these are the functions, you can have some associated data, that is some data that does not need to be encrypted, but you need to authenticate. You can input a secret key, actually you would start with inputting the secret key. You can get some output, PRF. And then there's this notion of client server communication, you can send data in the clear, but besides sending the data, the data, the state of stroke will be affected by the data so it will authenticate. If you, when you authenticate, it will also authenticate the clear text data, receive clear text is the equivalent from server to client. Send encrypted, I'm going to send some data, but in an encrypted form, and my state is going to depend on it. Receive is vice versa. I'm getting some ciphertext and I want to get back the plain text and I want my state to depend on it. Send Mac, I need to authenticate myself to server. I send a message authentication code, depending on everything that was done so far. Receive Mac, I get a Mac from the server. I need to check that it fits my key and my context. And then finally, ratchet is something that ensures forward secrecy. So it erases part of the state in a way that you cannot go back in case the state gets compromised. Here is a small example of a protocol on top of strobe. So it's a really simple protocol in the sense that we have a client server. The client is going to request a file. We want this request to be encrypted. So the name of the file is going to be encrypted. And we want the server to send back the file in an encrypted form. So I start by putting my secret key here. It's either a pre-shared key or a key that comes from a public key operation. I leave the hand man. And then I have some context X that is going to summarize on what the state depends. And I start with an empty X. So the next operation is AD. So I'm going to add to my context some associated data. In this case, the string nonce and the sequence counter I. That is going to be incremented every time I use it. Then the string auth data followed by the IP addresses of the client and the server. So when I write that X gets incremented with all these strings, it doesn't mean we have a buffer with all these strings. It means that these strings are absorbed and the state of the cryptographic object, the duplex object underlying a strobe somehow contains a hash of everything that is in X. Then I want to send my request get file. File is being a fine name. I just encrypt this string get file under the key K. And that's my server text that I send to the server. And at the same time I update my context with this get file string. Then I send a message authentication code that depends on the entire context. So from the entire transcript of the protocol so far. Then the server sends me back the file in Cypher text. I'm going to decrypt it and get the plain text. So the file in the clear. I update my context accordingly. And then I check the Mac. The Mac contains everything. And in particular it contains the plain text that I just received. So I'm now sure that my file was not tampered with on the way from the server back to me. Okay, so in the end it's fairly nice syntax. You can build many things of this form. Then so strobe is only about the symmetric key part. What about the public key part? There is another protocol called the noise protocol framework defined by Trevor Perrin and presented at Helua Crypto two years ago. It's a fairly popular protocol in the sense that it's used for instance in WhatsApp and WireGuard. It does two things. First it handles the public key handshake. So it does typically cryptic operations to establish a common secret key. And then it also handles the secret key encryption and not the authentication aspects. In this diagram so you can see what's happening inside noise. So I'm focusing on everything. I'm not going to detail this figure. I'm just showing it to point out that it's fairly complicated when it comes to describing what happens in the symmetric part of noise. So you have different primitives. You have hash functions, key derivation functions, cipher so authenticate encryption and all that gets mixed in a fairly complicated way. So the idea was of the idea of Disco. So Disco was presented by David Nguyen at Black Hat three years ago. And the idea is just to take noise but replace the symmetric part of noise with something based on strobe. And the idea is to make things simpler. And if you take the previous figure and now you look at Disco instead of noise itself, then you can see that the symmetric part is much clearer. It's just one code to strobe every time. The entire state is maintained by strobe itself. There is no need to have different things running in parallel somehow. You may say okay but maybe now the complexity is hidden behind these function codes. Well if you look inside these functions codes it really relies on the duplex construction which as operations only need to sort some strings into the state and apply the permutation when it's needed. So the kind of operations that lie behind these function codes are really simple. And that makes the implementation of Disco really nice, really simple. Here are some figures provided by David Nguyen about the size of Disco written in C, C sharp and go. And you can see that Disco fits in a few thousand lines. If you compare that to OpenSSL, it's of course much smaller. I don't think these figures are really fair because OpenSSL does a lot of more things and they have many, many options to look at. But still I mean my point is that Disco can is really simple. And one aspect of it is the use of the duplex object and its incrementality to allow for this simplicity. Okay, so starting from incrementality, we decided, yeah, let's take a step back and look at how can we define incrementality, how can we maybe refine this notion and try to define things on top of a new object, a new interface that we call deck function. So what is a deck function? I'm sorry, that's the most technical slide of the presentation, so that's some notation. But basically a deck function is a pseudo random function that takes as input a sequence of strings. So the input is either one string or two strings or three strings and it's a deterministic function. So it takes a secret key and the sequence of strings and it's going to produce as many output bits as you wish. These output bits depend on secret key, they depend on the input. If you change just a single bit of your input, you get some unrelated output. It's deterministic. So if you know the secret key and of course you have the input, you can compute and if you compute it twice, you get the same result. A pseudo random in the sense that from the point of view of another adversary who doesn't know the secret key, these output bits, they just look like unbiased random bits. They just, an adversary cannot predict them for a new input string. So I said it takes, it outputs as many bits as you want. Of course you don't need an infinite number of bits and this notation is, I'm not going to detail the notation but it just says that I can take n bits starting from offset Q. Okay. That's a deck function but that's not all of it. Another requirement of a deck function is to allow for this incrementality. Maybe I forgot to mention that deck stands for doubly extendable cryptographic key function. So doubly extendable is really the feature I'm now describing which is the incrementality. I want to have extendable input and extendable output. By extendable input I mean let's say you first compute fx over some string x and then later on you want to compute fx over y after x. But you already computed f of x. You have maybe kept some state. Then if you do that, the computation of fy after x does not cost you, the cost only depends on the length of y, not the length of x. You don't need to start all over again. You don't need to pay for evaluating f of y after x if you already evaluated f of y. So that's incrementality on the input. On the output it's also very simple. I mean you can take some bits of output and if you need more, you just pay for these extra bits. You don't need to start all over again. Okay, so that's the doubly extendable feature of a deck function. Okay, so now assume that we have some deck function. I'm going to of course describe how we can build one concretely, but assume we have one. What can we do concretely with a deck function? First application, very simple application. I want to just to encrypt some data. So I have my deck function, I input the secret key and I input some sequence number, a nonce, and then the output I use it as a key stream. I saw every bit of my plain text with the corresponding bit of the key stream and the result is my cipher text to decrypt. I just do the same, I saw the key stream to the cipher text and if you saw the same thing twice, you decancel each other and you get back the plain text. So encryption, stream encryption, very simple application. To do authentication, you input your message to the deck function. The output is your authentication tag that you attach to your message. Okay, now about incrementality. So you can have this deck function, the output is going to depend on everything that was received so far. So if you maintain a deck function and you encrypt different messages that follow each other, then you can have something which we call a session. And by session, I mean that if you exchange some messages, and let's say you exchange three messages, the tag on the third message, so the authentication of the third message, it's not just locally authenticating this third message, but really a sequence of all the messages received so far. So maybe this last message is just a confirmation, it's just a bit okay with the tag. You don't want the adversary to be able to reuse this okay in different contexts, otherwise the adversary could send an okay on something you don't want, maybe. But in this case, because the tag depends on all the past, it's okay, it's clearly referring to the context which is the sequence of previous messages. So I think it's really convenient and comes naturally with the notion of incrementality that is buried in deck functions. Okay, yeah, I'm going to go quickly over this slide. So we defined a mode called deck scene which does this session-based encryption using a nonce. And it's really simple, so you initialize it with some nonce and you can get a tag over the initialization. Let's say you have a first message composed of metadata, something you want to authenticate, but not encrypt and the plain text. You use the deck function to produce some Pstream encrypted as done two or three slides before and the tag includes everything including the metadata and the cycle text. Now, because we already processed the nonce, this nonce is now grayed on my slide. It means we don't need to pay for it. We just pay for this metadata and cycle text. And if I have a second message, then I need to pay the price only for this second message. All right, so deck scene needs a nonce. It means that you need to have a sequence number. It may be it's a packet number, but if you repeat that value, then you get into trouble. So there are other deck-based modes that we define. One is called Sanse. And the idea is to replace this sequence number by some synthetic sequence number based only on the plain text. So you don't need to really maintain this sequence number. And the other one is WBC, wide block cipher. The idea is to achieve authenticated encryption with minimal expansion. So if you have plain text that already contains some redundancy, you can just base yourself on this redundancy to ensure authenticity. And maybe you want to encrypt something into something else without any expansion. Because of course, in deck scene, the X and C, you have this extract tag that increases the size of your cipher. So you have cipher text and the tag that you need to transmit. So we have some expansion with WBC. You can manage, if you have enough redundancy, you can just have your cipher text whose length is equal to the plain text full stop. So that's really a nice feature. Yeah, then a few minutes about how we can build an efficient deck function. So recently we developed a new construction called Farfale. The name Farfale comes from, yeah, maybe it's shape, I don't know. So again, I'm not going to detail everything that's happening inside. So it takes a secret key and some input blocks. But the key thing to look at on this figure is that the permutation f that is being evaluated in this construction, they can all be evaluated at the same time because they can run in parallel. So you can parallelize your implementation and maybe you can plug in a vector implementation of this permutation. You can compute two permutations at once, four, eight, depending on the size of your SIMD instruction, vector instructions. So it can really speed up things. And the same goes for the output. All these fs, all these permutations can be computed at the same time. So basically we defined two instances of ciphers based on Farfale. The first one is called Kravate. And Kravate uses a catchback permutation reduced to six rounds, so that's one f. We claim that it has a security of 128 bits and we claim that it also includes adversaries who would have access to a quantum computer. So Kravate is fairly fast. The only disadvantage is its big block size of 200 bytes. So we defined another permutation that was recently called Zudu. That's a 384-bit permutation, so 488 bytes. And we defined Zuf, which is Farfale, using Zudu with six rounds. There again we claim a security of at least 128 bits. This post-quantum claim was reduced a little bit because the permutation is smaller and that's just a consequence of this size. So performance figures. So that's Kravate on a Skylake processor. So Skylake processor is a fairly common processor nowadays. It has a VX2 instructions. VX2 are 256-bit SIMD instructions. And using that we can implement Kravate with a speed that is slightly, so it's slightly faster than AES encounter mode on that platform. Bear in mind that on this platform there is the AES-NI instruction. So basically the AES implementation is a hardware implementation. Whereas Kravate uses just the regular, the general purpose vector instructions on that machine. Okay, so last thing is about Zuf. So Zuf, as the name suggests, is supposed to be fast. But the key message for Zuf is that because we use a smaller permutation, this permutation, the state can fit in 12 registers of 32 bits. So that can fit in a typical ARM Cortex processor. It can also run fast on small processors. And because of the parallelism, it can also run fast on IN processors. So concretely on the Cortex M0 processor, that's a fairly small one. It's about four to five times faster than the AES. And about the same figures for, I mean the same ratio for Cortex M3. On Skylake it's slightly slower than the AES encounter mode. But if you have access to the new AVX512 instructions, then it again becomes faster than the AES encounter mode. Again, using general purpose instructions. So that's all I wanted to say, just to conclude. In this talk I tried to explain to you why we think incrementality in symmetric crypto can make protocols simpler. We've seen that with an example, which is Disco. We also think that it can make some modes more natural. The notion of sessions really directly benefits from this incrementality. And then to capture this incrementality we define the deck function interface. And we show that we could make some efficient schemes based on that, by specifically using the Farfali construction. And that's it, thank you for your attention. We've got time for one or two short questions. So is there any other questions? Okay, thank you very much for this interesting talk. It was not clear from your description of the Farfali construction. You can paralyze the encryption and decryption operations. But can you receive messages out of order and validate the max that correspond to it? Because that would be a very important use case for things like wire god for instance. Okay, so if you have out of order messages, so basically the notion of session simply doesn't work. So you cannot really exploit it. The parallelism I was mentioning, it was not about this session mechanism, it's independent. It's just that this construction allows you to implement. So the longer the input, the more parallelism you can exploit. Independently of session mechanism if it's out of order or anything. The thing is from the security point of view, we would like to validate max as fast as possible to avoid denial of service conditions. So having too large messages is not necessary. Of course, and that's why in this mode, we have a tag at session startup. So you have a tag that you can immediately check just based on the notes. So denial of service attacks, I mean they need to have this tag correct otherwise you can just stop there and you don't need to check the whole message. Thank you. We are out of the time so thank you for your questions and for your talk. Thank you.