 Our next speaker is a master student from the Netherlands. His name is Dan Sprenkels. He told me that he's maybe the youngest speaker in this Congress. So if you know anyone, any speaker younger than 23, just let him know so that he loses the contest. And please pull out pen and paper because this talk is a course Dan holds on his university. So this will be graded afterwards. Dan Sprenkels, please, on We Should Share Our Secrets. Thank you, Harold, for introducing me. And thanks for inviting me here on this conference. It's kind of an honor. So my name is Dan Sprenkels. I'm from the Robert University, where I did a research internship on an algorithm called Chamele secret sharing. So this talk is kind of a bit about secret sharing, but secret sharing is not new. And it's kind of about crypto implementation because I would like to make a point to you. So first of all, I'm Dan Sprenkels. I study at the Robert University, where I did my bachelor's in chemistry. And after finishing chemistry, yeah, I just skipped to computing science because that's obviously better. So on a regular day, I'm currently doing implementation of elliptic curve cryptography. And that's kind of a specific field. So I would like to share some of my knowledge with you on how cryptographic implementation actually works. So the other people that are involved in this publication in this research are Peter Schwabe, which is my supervisor, and Sean Moss. He's the CEO of a company in Taiwan, in Taipei. And they do a Bitcoin, well, blockchain stuff. So first of all, because I don't know really what the mathematical knowledge of you guys are is, I would like to ask you who've heard of this? OK, that's really good. Second question, who actually knows why we say this all the time? OK, so that's a pity because I wanted to explain this. Well, actually, I wanted to explain the second one. So rolling your own crypto is a bad idea because it's not that easy. You can do stuff wrong very easily. You can screw it up very easily. And the second one, you've also got this case. Implementing your own crypto, as we have seen yesterday in Philippo's talk, is really hard. And in his case, one carry flag in the CPU can screw up your security. And in his case, have a full private key recovery. So in this talk, I'm going to try to explain to you why is implementing your own crypto so very hard. And for this, I used the most easy, most simple crypto scheme, which is your secret sharing. So this is my outline. I'll talk about what secret sharing is, like theory. How can you do this stuff on paper? And then I'll go into the implementation. I think this is a better outline. I'll try to make the first part a little easy to understand. And the second part may be a bit less easy to understand. But I think that everybody here can easily follow this talk. So first part. Well, we've got this problem. Most people don't really consider this a problem. But when you've got a key, and I always use the example of a Bitcoin wallet key, because Bitcoin is a buzzword, and everybody will go to your talk if you mentioned Bitcoin once or twice in your abstract. So you've got your Bitcoin key. And you want to keep your Bitcoin key secure, because it holds, I think, maybe tens of thousands of euros in the worst case. And secure means two things. The first thing is nobody can ever compromise your secret. So your secret has to be secret. And the other thing is, you don't want to lose your secret, because losing your secret also means losing your money. And the straightforward way to back up your keys is to give one of your keys to your bank. And you store it on a piece of paper over there. Or you take somebody you really trust, like your spouse or your lawyer, and you give it to them. But then you have this thing called a single point of failure. And the single point of failure is one way that stuff can easily go wrong. So instead of giving it to one person, we don't really want to give it to one person, because one entity may break. And this may be like our house burning down, because that piece of paper was stored below our sink. And now it's gone. So instead, we really want to split up our trust into little pieces. And every piece we want to give to some entity or some person that we trust to keep it secure for us. And Shamir's secret sharing solves this. But first, let me take some easy examples to how would we do this in a simple, well straightforward way. And the first idea would just be OK. We have a key of maybe, say, 30 characters. And we just take the first 10 characters. And then the second 10 and the third 10. And we give the first 10 to a single person. And the second 10, we give to another person, et cetera. But in the case of crypto keys, so in the case of Bitcoin wallet keys and stuff, then if you've got the first two, it's quite easy to brute force the key to get the last one. So this is not really secure. A more theoretical, more secure approach would be to use some kind of one-time-pad construction. And a one-time-pad construction is where you generate a random key. And then this key will actually be used to decrypt a secret. And in our case, we can generate two shares. That's how I call them. Our shares, A and B. And A and B are randomly generated. And our randomly generated A and B, we use to generate another share C. And we generate these things by using the actual combination of M, A, and B, where M is the secret. And then to reconstruct the secret, we can compute the XOR combination of A, B, and C. And we can see why this works, because C equals M, A, and B. And because two XORs cancel each other, those A's and B's cancel each other. And then we get M back. But here, we only solved the single point of failure problem in the case of confidentiality. We only know that if we do this, then the secret will remain secure. But this does not solve losing one of these shares. And in our case, if backing up your secret, if losing your secret is your problem, then this doesn't solve anything. So we want something better. And we have something better. And we have something better for about 40 years now. So Shamir's secret sharing was published by Shamir almost 40 years ago. And it's called the threshold scheme. And the threshold scheme implies that we can share a number of shares from our secret. And in the parameters of our scheme, we can set a number of shares that is required to restore the original secret. So we don't need all the shares to restore the secret. We can just, we'll say, distribute five shares. And then only three of them will restore original secrets. And losing one or two shares isn't really a big problem for us. Also, this scheme is provably secure. Provably secure is often used as a term. I don't really like this term because it doesn't really say anything. So I used the term information theoretically secure, which is quite better. Information theoretically secure means that if you don't have enough shares in this case, then you won't be able to restore the secret. And this is not like encryption where the key is unknown, where you can brute force the key. You can try every key, but the key space is so large that it's impossible to do this. Now, in this case, even with unlimited power and millions of years of computing power, we still will never be able to reconstruct the secret. And so this implies also that this is resistant against quantum computers because extra computation power does not give us an advantage here. So here's an example. Let's say I've got my secret message, my secret key, M. And I want to distribute this M among my friends so that they only have their shares and cannot do anything. But I would still be able to recompute my original secrets if any time I lose my secrets. So I distribute five of these shares by just computing them. And then each of my friends has a share. I might lose my share sometime in the future. And I'll ask my shares back. And even if some of them, well, in our case, one of them spoils the fun and does not give me my share back because he's evil, then in our case, we can still restore the share. Because in the beginning, I set the threshold value to four. So in this case, four shares is enough to restore my secret. I use these four shares. I recompute my secrets and I get back my message M. So obviously, this is easy to understand when you see this. So let's go into the math. And the math is quite fun. And this is notation quite difficult to understand. But I'll tell you anyway. So for a threshold scheme of what we want to distribute N shares, and the threshold of recombining to the original secret is k, then we construct a random polynomial of degree k minus 1. So a times x to the power k minus 1 up till the lowest coefficient. But instead of filling in the lowest coefficient as a random value, we fill in the lowest coefficient as a secret message. So this simplifies to just using a number. Then we've got this polynomial p. And we start generating points on this polynomial. So for x equals 1, x equals 2, x equals 3, et cetera, up till n. Now we distribute these points as the shares. And we distribute these points so that in the end, we can use these points to reconstruct the secrets. And in our case, so when we got this polynomial, when we got all the coefficients of this polynomial, we also have the lowest coefficient. So we do have m. So we take these points. And we can make a system of equations, just like back in linear algebra. And this system of equations we can solve by filling in the x and y values of these points. And if we've got enough points, then we can actually find the original polynomial and we will do this. So in practice, we use a set of formulas called Lagrange interpolation, which you can look up on Wikipedia. But this is easier to explain. So I'll explain it by using this. So this may be a bit hard to understand. So I've got pictures. First, we take 42 as our secret message, obviously. Then we generate a random polynomial. In our case, our first coefficient is 4, and our second coefficient is minus 25. So you've got this nice parabola. And we can construct points on this parabola, so that we, like in our case, four points. And we saw here three coefficients. So a threshold of three, important. We see that if you only have two points to reconstruct a secret with, the only thing you can do is, well, you can generate a line and they'll get some random value on the lowest coefficient. And, well, this does not give back your secret. Only if you take a third point, then you can make this parabola. You can fill in x equals 0. Then you get back your secret message. So solving the system of equations is like filling in these x and y values. Then you can solve this on a piece of paper. You can do this within, I think, five minutes. And then you will get your message back, which is 42. So this is all good. Well, we know this thing is the information theoretically can secures. So nothing could go wrong. Well, yeah, it can. So this thing is information theoretically secure for confidentiality, which means if your secret is secret, it will remain secret. But nobody said you couldn't change the secret. So what we'll want to do is to hack this. We just have a share as one of these persons. And we will tamper with this share. We make another share, which looks like the original share, but actually constructs to a different secret. So how we can do this is here is a polynomial of degree 2, degree 1. So this is just a line. Take two points. If I generate another point and we generate a new line through this point by me giving back a malicious secret or a malicious share, then we get a new point, which is not the original point. And if I have enough information about the original secret and if I have enough information about the x values of the other shares, then I can actually choose this point. So how to solve this? Well, there's two things to solving this. And I'll come back to this later. The first thing is I knew that the other point that was shared was on x equals 2. So this gives me information about how I can make this specific slope to get a new value. And the other thing is I knew something about the original secret. And Shamil's secret sharing assumes that the secret is secret. Well, because it's secret sharing. But this may not be the case in every time. So I knew something about the original secret. So a solution would be to randomize this secret. And well, you might say, but then you cannot secret share anything anymore. Yeah, I'll get back to this. So here's part two. So this was my introduction. Now I'll get to the implementation part. And this is where most normal cryptographers stop talking. Because they say we've got this beautiful scheme. It works. We know how to use it. And now it's done. Like implementation is magic. Implementation is easy. And as a cryptographic engineer, I would like to make the point to you that cryptographic engineering is not always the most easy part of this process. So the story is that Bitmark, a company in Taiwan, asked us, hey, we want a library for Shamil's secret sharing, any library. And we asked, how do you want it? Yeah, we want it secure. And we want to be able to use it anywhere, on any platform, like Android, iOS, maybe microcontrollers somewhere in the distant future. So OK, we think what libraries are out there. So there is SSS and Gfshare, which are the most popular libraries. And we looked at the code. And we needed code that was really, really secure and also secure against side channel resistance. And this code either didn't really port well to other platforms, or it had some cache or timing flaws that, in our case, wasn't really acceptable. So it does not mean that these libraries are bad. Just good code, good libraries. Only for our requirements, this didn't fit. So yeah, we're going to implement this thing ourselves. And I'll take four challenges that I have had with my implementation. And these are not the only four challenges that I had. There are a lot more challenges. But I think these are the best to explain cryptographic implementation challenges to you. So the first thing is this integrity problem, which we saw in the last slide from the previous part. And how to encode our values, because we were only using just values and not bytes or integers. And we will have to choose something to compute in. How to prevent side channel attacks. I'll explain how side channel attacks work. And how to make this thing fast in the end, because I like really fast code. And I like really challenging optimization problems. So the first part, this integrity problem, we could either randomize these x values or randomize the secret. And these x values are not really easy to randomize, because we would need to choose really big x values. And in our case, this really slows down our computation. And the security decreases with the number of shares that we give out. So instead, we chose, OK, we just randomize the stuff that goes in the algorithm. And we've got a really random polynomial, and nobody can use anything. So we use some term, which is called hybrid encryption. So instead of using our message and pulling it directly through the Shamir secret sharing algorithm, we instead, we generate a randomized key. This thing, we can pull through the Shamir secret sharing algorithm. And then we use this key to encrypt our secret message. And so in this case, we don't have to pull text to through an algorithm which is actually used for, well, numbers and stuff. And more importantly, we can pull this thing through an algorithm which is used for randomized numbers. So this is how it works. We encrypt the secret with a randomized key. And when we want to decrypt it, we just take the key shares, so the shares of the keys. We get the key back by recombining the original key. And then we use this key to decrypt the original ciphertext. And this week, we will get back the secret. So the second challenge, how to encode our values. This may be a little bit hard to understand why this is a problem for people that don't know really the finite fields, arithmetic stuff. But it essentially boils down to this. In the beginning, we had these numbers. And when we're working in computers, we cannot just use any numbers because we're limited. We're restricted to using integers or signed integers or bytes, or et cetera. So in our case, we want to take a mathematical structure in which we can compute these numbers. And we want to take our original key and we want to map it to this mathematical structure. And the most common thing that we do in cryptography is we take a really large prime. And we take this prime and we compute modulo this prime. And this works really well for spots where we actually have to have a prime order or a large order. In our case, this is not a requirement. So we will map to a structure that has exactly 256 elements. So when we have a structure that has exactly 256 elements, then we can map a byte to one of these numbers. And for the mathematicians, the bottom thing is what we use. We use a finite field reduced by the Reindahl polynomial. And you'll see later on that this allows us to do a really, really powerful optimization trick. And it boils down to the fact that when we have every byte separately in our key, then we can just implement our algorithm for one byte. And then we just put a for loop around this. And for each byte, we will secret share. And this allows us to parallelize over these bytes. And later, I'll show how we do this. But first thing, rules of cryptographic implementation in software. So side channel attacks are attacks that are not attacks on the outputs of an algorithm. So let's say I put something in the algorithm. I see what kind of output it delivers. And then I'll know if the algorithm did something or did not do something. Side channels are a little bit more subtle. Instead of taking the output, we take a property of the algorithm. And we take a property that we can measure. And the best example is timing. We can measure how long an algorithm takes. And if we know that a key contains a one at a certain position, and then it will take a longer time to compute, then we can measure the algorithm's computation. And if it takes a long time, then we'll know, oh, there's the one. And if it takes a shorter time, then we'll know, oh, it's probably a zero. And we can do this iteratively and do this number of times. And we can take just a big statistics toolbox and put a load of statistics on this. And then it's sometimes really easy to crack an algorithm. So the first rule of side channel resistance is we may never branch in an algorithm. So branching is you have an execution path, and you choose where to go next. So if statements are forbidden, L statements forbidden, logical and logical or are forbidden, switch statements are forbidden, et cetera. So the second one is similar to the first one, but uses a specific trick. And it's called a cache timing attack. So we use the fact that if we take something from memory, the timing may be different when a piece of data, when a piece of memory is already in CPU cache, than when it has to be fetched from the main RAM module. And this can be a really big time, and we can have really big, bad vulnerabilities because of this. And the last one is something that's often forgotten. We are not allowed to use variable time instructions from the CPU. And so on Intel processors, for example, the division instruction is often variable time. But also if you look at the manuals of some maybe older CPUs, and you also see that some other instructions, for example, the multiplication, may actually be in variable time. So we really have to look out for this. And that kind of brings me to my last point. How do we do this in a high-level language like C? And how do we do this fast? And this we do through bit slicing. Bit slicing is a really awesome technique. So we had all these bytes, and we shared these bytes separately. So what we can do is we can parallelize over these bytes. And remember that a CPU is made up only of logical instructions, right? So we would be able to multiply and add using only logical instructions, right? So what we do is we take these bytes. We take the first bit of every byte, and we put it in a register. And we'll take the second bit of every byte, and we'll put it in another register. And for every bit in these bytes, we will put it in a separate register. And in the end, we will have used eight different registers. So now we will implement this algorithm. Instead of using normal operators like, I don't know, division, multiplication, et cetera, we will implement this thing using only logical bitwise operators. So only really bitwise and bitwise XOR and bitwise OR. And remember, this is a full adder for two bits. And this is just a really small part of how a CPU adds two numbers. And this is an example of how we could do this. So we'll make this whole thing inside these kind of circuits. And we will have to finish this computation. In our case, we were building on a 32-bit platform, so we could easily run on older ARM devices. And in this case, we have a really large, more bulky computation, but we also have a parallelism factor of 32. And well, this was a 32-bit platform. If we use a 64-bit platform, we will get 64-bit parallelism. And even on AVX2 and AVX, this works. And even if the CPU wouldn't clock down, this would have worked in AVX512. So in the end, we've got this overview of how we implement such an algorithm. So we take this really random thing. This, by the way, is one of these other challenges that I did not talk about. And we generate a random key. We encrypt with this key our secret message. And then we take this key and we bit-slice it so that we actually can compute our secret shares in parallel. And then when we're done with these computations, we actually have to undo the bit-slice operation and we get our shares. And restoring the original secrets is just the other way around. We take our shares. We bit-slice our share values. We execute the recombination algorithm using these Lagrange interpolation formulas. We have to undo the bit-slice operation in the end. And we use this key to decrypt and verify the original ciphertext. So the performance of this thing is quite good, I think. Well, these are kind of bad benchmarks because I did not make them that proper. And well, I made this presentation, did some benchmarks, not really accurate. So a tight C loop takes 10 microseconds, et cetera. The other things also take 10 microseconds. I have no clue why the rust bindings actually are better than the other ones. If anyone is able to tell me, please do. But in the end, roughly 100,000 calls per second. And this is plenty performance. We don't really need to get more performance. But if we do, well, I noticed that about more than half of the time is in the encryption algorithm and not in the Chamele secret sharing. So to optimize this further, we may just use a better encryption implementation. Because in our case, we use Tweed Salt. And Tweed Salt is a really secure, really good implementation, which is really portable. But it is not optimized for performance. So in the end, stuff that could have gone wrong. And the first thing is that, well, this is something that we as cryptographers often see on, for example, Stack Overflow, that people think that encrypting a secret will make it secure against integrity. Because if a secret is encrypted, people will know how to change it to get another value. But in the case of cryptography, this is not the case, people. Integrity is only assumed if you have a message authentication code, or in our case, you use an authenticated encryption scheme. And the second thing that could have gone wrong is timing attacks. And timing attacks is stuff that actually exists in a lot of implementations. And so this gives me the impression that the amount of cryptography engineers in this world may be a little bit too small. Because otherwise, we would have had constant time crypto implementations, for example, in the ghost in the library, which I think we may not have. Or we wouldn't have timing leaks in Gcrypt, which was published recently in the May the 4th be with you paper. So this is kind of a problem. And this last problem that, in this case, it was in Armory. And Armory is a high-security Bitcoin wallet system. And Armory had this Jamia secret sharing implemented. And they did not generate the polynomial fully randomly. And I think this actually led to quite bad vulnerabilities in their implementation. So it's kind of dangerous terrain to implement this cryptographic code. OK, here's a sidetrack. This is something that most programmers, so not limited to cryptographers, most programmers do not think about the existence of their code as a tool for everybody to, well, do whatever they want with it. And I think it's important to ask ourselves, we have built this software. What does this software? How is this software meant to be used? And in the worst case, can it be used for people with malicious intent, for people who don't actually want to play by the rules? And I'm telling you this because I think that most programmers will actually have to think a bit more about this sometime. So in our case, we distribute secrets to the masses. And we distribute secrets to trusted people and stuff. So I do not really think that the malicious user is able to use this for many malicious purposes because power is, most of the time, centralized. And this tool, most of the time, allows us only to decentralize this power. But the most important thing is that we are responsible for writing our own software. And whether I'm making a cryptographic library or if I'm making testing code for Volkswagen, then we are responsible for stuff that happens with it. So to get back, I'll show you a small demo. This will obviously grow wrong. So I have installed my secret sharing tool. Yeah, I'll try to. So can we use plus? No, we cannot use plus. Ah, we can use plus. OK, how does this work? Let's make us five secrets with a restoration threshold of four. Whew, what's my secret? Well, yeah, I don't know. So we've got a couple of secrets here. So here's the third one. And I'll copy-paste this into my restoration script. So we start with. So I'll ditch the first one. And I'll take the second one up to the fifth one so you can actually see what happens when we ditch one of those. Yes, demo gods. OK, so in the beginning of the talk, I said to you, do not implement your own crypto. And well, I hope that you may have seen a couple of reasons and have given you quite a bit of feeling about why implementing crypto is hard. And so I'll say to you, please do implement your own crypto. Try to implement crypto. Try to understand how the crypto works. But if you're not really sure, if you're not 100% sure about what your implementation does and if your implementation is secure against every attack factor, if it's, I don't know, maybe side channel resistance or checking that single carry bit in this single flag register, then put a big warning in bold-faced letters at the top of your read me saying, hey, guys, this is academic code. I used this code to learn myself how crypto implementation worked. But I'm not really sure. I've not checked this with any cryptographers. Please do not use this for your really high-secure, well, wallet software or whatever. So that's it. These are some people I want to thank. And my slides can be on my website. It can be found on my website. I've got some extra reading for you if you'd like to have some. I forgot to register my DECT extension. This one does not work. So that's it. Do you have any questions? Dan Sprenkels, thank you very much. Thank you. Any questions? Please feel free to assemble behind the microphones. And I will put you through then. Let's start with number three. How do you make sure you didn't make an implementation mistake? Do you have unit tests? Well, so that's the terrible thing is that in a cryptographic implementation world, well, I do have unit tests. Unit tests do not always fix your problem because your key space is large enough that you won't be able to test everything. And in the case of my elliptic curve implementations, the only thing I can try to do is prove every single function. And that's really error-prone and can also be doing wrong. But I'm honestly not 100% sure about the fact that my implementation does not contain any errors. I checked it. People checked it for me. And I'm, well, quite sure, but I still am not this 100% sure. And I think this is with all codes that is security relevant in our field. Microphone number four, please. First of all, thank you for the interesting talk. One technical question. I've seen from your demo that the actual shares are quite a bit larger than the original text. And my question is, how does the number of bytes information scale with the number of shares you have and with the number of required shares? OK, so I'll get back to this slide. What we do here is we have this encryption key. And we have this point, this x value. So we have to add one single value for x, so one byte, because we were working in bytes. And this is the 1, the 2, the 3. And this will be the first byte of our share. So this adds one byte. And then we'll take this key. And this key has to be randomly generated. And this key, in our case, we use Salsa 20 as an encryption algorithm, which uses 256-bit key, which is 32 bytes. And this adds another 32 bytes. So in the end, we only have 33 bytes, which are actually added to our shares. But the amount of shares that we generate and the threshold will always generate the same amount of bytes in the shares. And actually, from the shares alone, you cannot see what the threshold of the algorithm was in the first place. Does this answer your question? And we have a question from our IRC chat. Yes. First of all, Geilis is sitting on Twitter. Thank you for losing Leitech, so I just forward this. There's a big discussion on the IRC how to defend against social engineering. What if some of the shareholders evenly plot against you? And are there any ideas to remedy this issue? Yeah, that's a good question. That's the thing that I hadn't solved for myself, because I don't have every person's environment. So my own recommended stuff in my readme and stuff is generate five shares, and four shares will construct your original secret. But even this, I'm not aware of if this is secure. In your case, you have to choose yourself who you trust with your shares. So I cannot really answer this question for you. OK, microphone number two. A question about the integrity problem. How exactly does your hybrid encryption engine solve this problem? And what does your tool, if you put in some tampered secret? Ah, yeah, that's a good question. So here we actually could spoil the secret, because the original secret was some value that we knew. And what this does is it randomizes the value that's come out of any tampered secret. So if we tampered a share, if we changed even one bit, then the value that will come out of the secret will be fully random, because the original thing was fully random. And what our algorithm will do is, in the Salsa 20 Poly 1305 authenticated encryption decryption step, this will actually fill on the authentication tag of the cipher text. And it will say recombination filled, or otherwise the key or the cipher text was invalid. And we'll just say, no, this won't work. Mike, one, please. Hello. It's similar to a previous question, probably. But I mean, assuming I'm trying to protect my huge Bitcoin wallet. And in that case, I don't want to really fully trust anyone. And would it be an option to? So I would like to avoid that if three of my family components agree with each other, they steal my wallet, basically. Is it an option to double up the shares and they keep 50% of it? Yes. But then you also have the larger problem of that losing the shares. Actually, it may be a risk for you. So that's the trade-off here. So let me tell you a small anecdote of which you can use this also is, for example, if you've got your Bitcoin wallet and you want your relatives to be able to inherit your wealth after you die, then you may choose to distribute your shares among your family members and people so that after you die, you can actually tell them, yeah, OK, then you're allowed to reconstruct the secret. And then you can inherit my Bitcoin wealth. And that's also an application for this. But in your case, well, if you have a system where you have yourself most of the shares, then in this case, you always have the fact that if you lose those shares, then you will also maybe lose the secret, which in your case may be what you want. IRC, please. Doddick is asking, if you're separating the message into individual bytes and then applying SSS for each byte separately, doesn't it suffer from the similar problems as the electronic code book mode in stream ciphers, namely that data patterns are not hidden? Yes. So that's also why we use this hybrid encryption scheme. So this hybrid encryption scheme, this encryption works on the whole block, on the whole message. And the Schemele secret sharing works on the individual bytes. And there is no pattern in there, because we generated this secret key fully randomly. OK, microphone three, please. Well, I come from a field which is quite similar in a way to the problems that you have considered here, which are error correction codes. And well, in my fields, there are a lot of error correction codes. And for instance, there is the low-density parity check code, which can be, from my point of view, of course, in a way hacked to make a similar implementation. But have you considered other codes? So I did. And the reason that we actually used this was not because of real security stuff, but because the Salsa 20 Poly 1305 implementation was already there. If I would do this in a more sophisticated way, Schemele secret sharing is not the only threshold scheme that exists there. So we also got Feldman verifiable secret sharing. And we also have Peterson verifiable secret sharing. And this is actually secret sharing that solves the integrity problem. But they are a little bit more complex. So that's probably what I would have used. Number two, please. Hi. Great talk. And back to implementations. Could you go a bit into the relationship between optimizations, both from compilers and just what we as programmers tend to do ourselves and vulnerabilities in general? Basically, what I'm asking is, do you hate compiler developers? Well, so yeah, compilers sometimes make assumptions that are correct in normal code. But when I do something in my C code, then I mean it. Yes. No, I do not hate C compiler developers. I choose to program in C. And the really, really low level stuff I actually program in assembly. So yeah, well, they do not have this obligation to cater to us as cryptography engineers. So yeah, what can I say? Maybe it's nice to have an option where you can say to the compiler, yes, I really, really want to use these things. And please do not assume that because this stuff in memory is not read after this line, that you do not have to re-initialize it to zero because I really want to set this key value to zero in the end. So yeah, well, there are tricks in compilers that you can exploit. And this is mostly the way we do it when we actually need to really tell the compiler, yes, we want to do this this way. And most of the time, Peter and I, we look at the assembly code that rolls out of it and we think, OK, well, they did it. And yeah, no, it's just OK. And if it's really, really critical, then we implement it in assembly. What would be your advice to you basically told people to implement their own crypto? And since we have not enough cryptographic engineers that's a good advice, but what would you tell them to check for? How to see if there is going to be a timing problem? So yeah, you can always look at the assembly codes and see if there's stuff. Well, so the first two items that I showed you, this do not branch and this do not look up. Well, compilers won't do this wrong. If you don't put an if statement there, they won't actually introduce a branch. And also, most of the time, they won't change an instruction. Well, like a bitwise instruction, they won't change it to a multiplication either. So if you have these kinds of really simple instructions, then it's actually, well, not that big a deal. And another thing is, this is maybe not really good for me to say, but well, there are a lot of not really good implementations out there. And as long as your one is better than the others, then it's good, right? Microphone number four, please. Hi. So you said we don't have the threshold in the shares, what happens if we give the real-time application more or less shares than it expects? Does it try to solve the polynomial of the wrong degree? So if we have less than the required amount of shares, then it will reconstruct the bad polynomial and it will try to use the lowest coefficient of this bad polynomial to decrypt our secrets and this will fail. If we have too many shares, then the solving of the equations will actually just work. So more shares will not be a bad thing. There's only one problem, which is if you add duplicate shares, then it will fail with the first error. And that's one thing that I did not solve yet in a good manner. OK, number three. Hi, thank you for the talk. How close is your code to be used in production? So do you mean how much review it got and stuff, testing, and whatever it's needed, how safe it is to use it in production? So that's a really dangerous question, because if I say it's super safe, then people will use it and it may turn out that it was not safe. And then I'll like, it's my fault. Well, no. So the efforts I did was I made it and I checked it by putting it, so by having it checked by auto-cryptography engineers and having my methods checked by auto-cryptography engineers, and in the core C codes, I expect there won't be any problems, because also the way we do this in these bit-slice operations using only bit-wise operations, it's quite easy to do this correctly. Thank you. And go ahead. Thank you. You were talking about optimizations, and I was thinking that instead of picking one very large prime to use as a modulo for a finite field, pick a prime which is just slightly bigger than your secret. Is this implementable? Can you use a variable prime? Yes, but modulo reductions are tricky in how constant time implementations are done. So when we do modulo reductions in elliptic-cryptography, we most of the time we do this kind of conditional subtraction, and this conditional subtraction will be done only when a number is larger than a prime, or if a number overflows or underflows during a subtraction. And this can be quite easily done in software, because we can just do this in constant time. But this becomes a lot harder not only when our prime is not chosen at the time when we built the software, but also when this prime is not really regular. So that's why there's this prime, which is called 2 to the power 255 minus 19, which is a really popular prime to implement crypto with, because it's really easy to reduce, because any number above that, we can carry it to the lowest limb and multiply it by 19. But if we do not have a really regular prime, then this problem becomes actually really hard, and we would have to use a multi-precision library, which are often not side channel resistant. Right. Thank you. Number two, please. The way I understand this, the security of the whole thing depends on the integrity and security of the machine it's being computed on. Is there any way to distribute the computation of a Shamir secret sharing? Of Shamir secret sharing, no, there ain't. I think that there are threshold schemes, yes, where you compute these things separately on separate computers. But in the Shamir secret sharing case, we assume that the dealer's computer, so the person who gives out the shares, is actually trusted, because it also holds the secret. So if we trust the computer to hold the secret, then we'll also trust it to compute these shares, yes. Any further questions? No. So then please, a warm applause for Dan Sprenkels.