 In this session we will have four interesting presentations and the first one titled Fast and Simple Constant Time Hashing to the BLS-12381 elliptic curve by Riad Wabi and Dan Bonet and the presentation is by Riad. Thank you very much. So a hash to an elliptic curve is a function that digests an arbitrary bit string and outputs an elliptic curve point. So we're going to build these things. But first let's talk about why we care about them. So our initial motivation was BLS signatures and that's a scheme that requires hashing to a pairing friendly curve like BLS-12381. But in general there's actually a lot of interest now in deploying protocols that use hash to curve. So for example there are current working drafts in the IETF for standardizing verifiable random functions, oblivious pseudo random functions, password authenticated key exchanges, all of those use hash to curve and as another example Cloudflare's Geo Key Manager uses identity based encryption which also uses hash to curve. So if we're going to use these things then it's no surprise that we want them to be fast right and probably it's also no surprise that we want them to be constant time because we all know that side channel attacks can be devastating. We have whole sessions on it here. Just to give one recent example, one of these dragon blood attacks against WPA3 was precisely because of non-constant time hashing to elliptic curves. But what about simplicity? Well okay so first I want to admit to you that this is a very stylized notion of simplicity. So what I mean is that we should be able to implement one of these hash functions using only fixed modulus arithmetic. And that kind of makes sense intuitively because that's relatively simple to implement and it will already have to be there in order to work on the elliptic curve. But beyond that we really want this in the embedded systems context especially because many microcontrollers and smart cards have hardware accelerators for fixed modulus arithmetic and that lets us save energy and go faster. And finally we're interested in hashing to the BLS12381 curve because it's becoming sort of a de facto standard for pairing friendly curves at the 120-ish bit level. And in fact the IETF is standardizing it so soon it will be more than de facto we hope. For example there are ongoing deployments for using it in zero-knowledge proofs for BLS signatures etc. Okay so what did we do? Well first we show a little trick for constructing what we call indirect maps to elliptic curves. And we'll see what we mean by indirect later and why that helps with pairing friendly curves. And we give some little tweaks to an existing map by Breyer et al that basically makes this map competitive with the fastest maps to elliptic curves that are constant time. And the result is a map for which the fastest implementations really are simple and constant time. And taken with the indirect mapping trick this applies essentially to any elliptic curve. So finally we implement and evaluate a bunch of different methods for hashing to BLS12381 and what we find is that our method is between 1.3 and 2 times faster than the previous state of the art constant time hash and we also find that you don't have to pay very much to go from a non-constant time to a constant time hash function. And finally we've open sourced implementations in several languages. So in the rest of the talk we're going to look at hash functions to elliptic curves and then I'll tell you about some of the optimizations and some evaluation results. So okay a little notation as usual we're going to use f sub p to refer to the field integers mod p and we'll use h sub p to mean a hash function from arbitrary strings to elements of fp and implicitly we're going to model this as a random oracle. Now we're going to use notation e over fp to mean the group of points on the elliptic curve so that's solutions to y squared equals xq plus ax plus b where x and y are in the field and on these slides I'm going to use multiplicative notation for group operations. And finally we're going to say g is a subgroup of e over fp of prime order q where q times h is the size of the whole group and h is the cofactor. Okay so all this mind-numbing notation out of the way let's hash to a curve. Let's do it. So this procedure is called hash and check and the idea is first we're going to initialize a counter and then we're going to we're going to while we found until we found a point we're going to loop and first we're going to generate a uniformly random candidate x coordinate by hashing the next value of the counter with our input message and then we're going to check whether there's a solution to the curve equation for this x coordinate. Now if there isn't one we keep trying but if there is that means we found a point on the curve so now we can just map that curve into the subgroup g with a scalar multiplication by the cofactor and we're done right except we're not done because this is really extremely not constant time right the message is going to determine how many times we have to loop and that means that if you watch me hashing you can learn something so in fact this is exactly the problem with that happened in dragonblood in there the message at the input was your password and if I watched the number of iterations then I learned something about your password by watching this hash function okay so maybe we could fix this so as a first-order attempt at a fix let's say we're going to say look we're going to accept the small probability of failure and we're just going to loop a constant number of times say 60 times we're going to loop and then either at the end of the loop will output a result or we'll fail so that's going to fail with probability 2 to the minus 60 that's fine but the problem is it's going to be very slow because we have to loop 60 times and also there's another insidious issue here which is you're kind of leaving yourself a trip wire in the code now because if somebody comes along later and says I could I could I could optimize this now suddenly your code has gotten optimized to non constant time so we don't want that okay what we really want is a deterministic map from a field to points on a curve over that field and in particular we're going to focus today on curves of sort of odd characteristic which means as long as p is greater than three we need five for other reasons we can write the curve equation as y squared equals xq plus ax plus b so every elliptic curve can be expressed that way in 2001 so there's a rich history of these hash functions so in 2001 for example Bonnet and Franklin showed how to do this pretty cheaply for certain super singular curves over fields with characteristic congruent to two mod three and then in 2004 2005 some Polish number theorists Shinsa and Scuba started making progress on the more general question of how do we hash to elliptic curves over unrestricted fields and actually in 2006 shallow and Vendivostin built on those results and some some really beautiful insights to kind of break this problem wide open from a number theory point of view so they give a fully deterministic map that works for any curve so that's not the end of the story because that map is relatively expensive implemented in constant time it takes sort of three exponentiation and so people kind of tried to keep going so for example in 2007 we'll ask proposed some modifications that simplified things though it didn't get rid of an exponentiation but it also cost generality so now we can only work with curves where a and b are non-zero in 2009 ecart gave what you could kind of view as a generalization of the Bonnet and Franklin method which still requires the characteristic to be congruent to two mod three but now it works over any any curve over such a field not just super singular curves in 2010 bryer at all revisited the shallow Vendivostin and ULAS work and came up with a nice simplification that also eliminated an exponentiation and they called this the simplified SWU map in 2013 building on some work by far shy at all Bernstein at all give a very efficient map called alligator to curves where B is not zero and which have an even number of points okay so so I've tried to pack a lot of rel work on this slide but I've totally failed to pack at all there's a ton of work in this area so I apologize if I've left yours out the idea is to sort of get an idea of the landscape and the question is where does our work fit in well okay so we generalize and optimize the simplified SWU map of bryer at all 2010 so so for curves with non-zero a and b we can match the best existing algorithms one exponentiation and if we remove the restrictions on a and b then we can still get to just a little bit more than one exponentiation and we're going to see where that a little bit more comes from a little later in the talk but remembers the goal originally was to hash to BLS 12 3d 1 so let's kind of look at how these things stack up so the field characteristic is a congruent to one mod 3 so that rules out Benet and Franklin and then the e-cart method a is equal to 0 so that rules out SWU and simplified SWU and BLS 12 3d 1 has odd order so that rules out alligator and so we're left with only the one that works for every curve with the shallow and end of a steam and that one really does work but we can we can make it a little more efficient and that's what that's what this work does so before we talk about the optimizations that make this possible let's let's this was just a deterministic map let's make it into a hash function so you probably guessed already that we can compose HP with a deterministic map M and kind of a natural way right so first we're going to hash to the base field using HP and then we're going to map from there to a point on the curve using M and finally we can clear the cofactor and return a result so this is nice and simple but there's a small snag and that is we've been discussing these deterministic maps but I haven't made any promises about what the output distribution of the map looks like we can kind of guess just heuristically that probably it's not a bijection and that's true and the reason is this in order for it to be a bijection it would have to be the case that the number of points on the curve and the field characteristic are the same and that means that it's an anomalous curve and we never use those for crypto because discrete log is easy so that means for any curve we care about for cryptography we're not going to have a bijection and in fact we can go further than that the map is pretty lumpy looking but actually the hash to curve so this hash to curve function is non uniform and its output that's what we call it and you so it turns out this isn't a disaster for a lot of protocols like many protocols this is totally fine maybe there's a small loss in security but usually it's really small but sometimes we really do need uniformity and it's much easier to think about things if we can just say this is a random oracle so what if we want a random oracle well in that case there's a Briar at all and Farshay at all sort of did a bunch of work on this and what they show is that if we evaluate the map twice on independent inputs and sum the result then we get something that is extremely close to uniform so in particular since we're modeling HP as a random oracle we can do something very simple we just prepend zero and one to the string to get two new strings and then we hash those add them together done so for this to work the map M needs to be what's called well distributed and I'm not going to define that precisely but you can kind of think of this as well M isn't too lumpy and the technical result that we get if M is not too lumpy is that the hash to curve function is indifferentiable from a random oracle so if you need a random oracle you can build one basically this way okay so now we know how to build one but let's see how we can do a little better let's see how we can go a little faster so remember we're working over an elliptic curve we're going to say y squared equals XQ plus AX plus B but that's a mouthful so we'll just say y squared equals F of X and at a high level the idea behind the simplified SWU map is we're going to construct a pair of candidate X coordinates and then we're going to be guaranteed by the construction that one or the other will be a point on the curve so specifically imagine that we're going to pick an X coordinate and a non-square U such that either X or U times X is an X coordinate of a point on a curve then the way we're going to do that is by choosing X and U such that F of U times X is equal to U cubed times F of X and what this implies is that since U cubed is non-square if F of X is non-square then U cubed times F of X is square so this means we do get one of those is going to be a point on the curve so we can just write out the equality that we want and grind through a little bit of arithmetic and this gives us a parameterization in terms of non-squares U which is half the field but we wanted to map from the whole field so what do we do well okay let's assume that P is congruent to three mod four in which case negative one is non-square so then we can say for any input in the field T negative T squared is non-square that's our U off we go so now we have sort of a map we have two functions that are parameterized over F P any point T on which these functions are defined guarantees us that one of the two functions will give us an X coordinate on the curve okay so let's implement this so the idea is we're going to evaluate X zero and X one check which one we want to output and output it so to start we're going to evaluate X zero F of X zero and then compute a square root and since P is congruent to three mod four we can compute a square root by exponentiating by P plus one over four and then we're going to do the same thing with X one and we have to do another square root and finally we're going to check which one is square and return the corresponding point so this works but remember we're aiming for a constant time implementation which means that no matter what we have to compute both square roots so that's two exponentiations and the goal is to try and get down to one so we're going to go back to the definition of the map and rewrite F of X one in terms of T and F of X zero and similarly we can rewrite the expensive piece that we're going to try and get rid of and when we do that what we find is this expensive piece is just equal to T cubed times the square root of negative F of X zero so that's very close to what we computed already right we tried to compute a square root of F of X zero so let's see what happened with that so if we square the thing that we attempted to call a square root then what we get out of it is F of X zero times the Legendre symbol of F of X zero so of course if F of X zero square then the Legendre symbol is one and we did actually find a square root but if F of X zero is not square then what we found was actually the square root of negative F of X zero which is exactly the value that we wanted so we already computed it all we have to do is plug that back into the implementation so the only thing that changes is line four we can do a cheap multiplication instead of an exponentiation and boom we're down to one exponentiation so are we done well kind of so I swept one thing under the rug and that is that X zero the function required computing ratio and so that seems like we're gonna have to do a modular inversion which feels like an exponentiation of course in the next talk sorry for spoilers we're gonna learn how to do that in constant time without computing an exponentiation but for now we can actually do something much simpler and that is we can just work in projective coordinates so instead of computing the value of the ratio we just keep the numerator and denominator separate and then prior work shows how we can take those two those separate values and turn it into one square root and finally what I've showed you is specialized to the three mod four case but it turns out that this is quite straightforward to generalize okay so we're down to one to one exponentiation so now the remaining problem is we still only support curves where A and B are not zero so how do we get to zero how do we get that last piece so to get around this we're gonna find a new curve E prime where A and B are non-zero and we're gonna require that there's an efficiently computable homomorphism from E prime to E and that's the curve that we really wanted so to do that it's actually quite simple we're just gonna search through the isogeny space around E until we find a low degree isogeny where the co-domain has A and B not equal to zero and that automatically gives us an efficiently computable homomorphism so specifically what we're gonna do is we're gonna evaluate the simplified SWU map to E prime and then we're gonna evaluate the isogeny map to E and we're done so there's one thing that we have to worry about and that is we have to make sure we don't break the well-distributedness property of the simplified SWU map because remember we needed that for the uniform hashing to work but it turns out that this is kind of immediate as long as the degree of the isogeny is co-prime to the order of the subgroup this is totally fine the well-distributedness applies and meanwhile remember the order of the subgroup is some 256 bit prime so we better hope that D is co-prime to that otherwise we're in trouble so this is what I meant when I said one plus earlier we have to first evaluate the simplified SWU map in one exponentiation plus we have to evaluate an isogeny map that's cheap how cheap well let's look at some evaluation results okay so we implemented hashes to BLS123D1 that's a pairing friendly curve which means that it actually defines two groups and we implemented for both groups we actually implemented a bunch of different stuff so we implemented hash and check shallow and vendor boosting and our work and for each of those we implemented a few different styles we implemented one that uses libgmp and sort of full generality one that uses only field operations but is not constant time one that uses field operations and is constant time and then we also looked at non-uniform hashing and uniform hashing and all this but I'm gonna show you all of that because there's just not time I'm gonna look at we're gonna look at the hash to G1 uniformly and the other results are very similar but in total this is about 3,500 lines of C that's open source and it's constant time field arithmetic curve operations, cofactor clearing, et cetera and we just let you know we tested with hyperthreading and frequency scaling disabled which is very important and we run all the hash functions on the same pseudo random sequence of a million inputs and record the number of CPU cycles that each iteration takes okay so here are the results the first group of bars on the left is hash and check the second group of bars is the worst 10% of the hash and check runs so remember with hash and check some inputs are bad and so what we wanna know is how bad do they get like what does the tail look like and so we just choose the worst 10% of the million runs the third group of bars is shallow inventivist and the right most group is our work and then within each group the dark blue uses live GMP and the important thing there is that we get a very fast Legendre symbol computation so that means checking for squareness is cheap the light blue line is field operations but not requiring constant time and then the magenta line is fully constant time and some of these it didn't make sense to implement right we talked earlier about how hash and check in constant time would be kind of ridiculous I computed it earlier and I think at this scale the bar for hash and check would be like on the 53rd floor so like it wouldn't fit on the slide and also there's no point in using the full power of live GMP for our work because we don't need a Legendre symbol so we didn't look at that either it would be exactly the same as the light blue line so okay a few takeaways here so first of all the tails for hash and check really are quite bad if you're restricted to only field operations so this is the worst 10% and it's sort of 2x the average case another thing to take away is the Shalom and Vendivisting map as we expected if we have to do it in constant time it's pretty slow because remember we have to compute three exponentiations it's not quite 3x because there's a fixed cost of like mostly clearing the cofactor and things like this and finally our work well the cost of going from non-constant time to constant time is quite is very small and beyond that like comparing the constant time version of our work to the non-constant time version of Shalom and Vendivisting there's like sort of a 9% overhead or something so really the simple and constant time implementations are pretty fast okay so let's recap we optimize the simplified SWU map and we extended it to apply to essentially any curve and from the evaluation we can see that fast implementations can still be simple and constant time so the high level takeaway is whereas previously only curves that were compatible with Elegator or E-Cart could be hashed to in one exponentiation now you can do that for essentially any curve and this means that pairing friendly curve families the NIST curves secp256k1 which Bitcoin uses you can hash to any of those with one exponentiation worth of cost and in constant time so finally all of our code is open sourced and we'd be psyched if you checked it out we're happy to talk more about it as I mentioned earlier there are a few different languages and with that I'm happy to take any questions any questions apparently not working now it works nice result thank you I wonder in your situation hashing curve is all you want what if you additionally to have a map back like you need injectivity how much can you rescue from this what can you do with this that's a great question thank you for the question so the question is Elegator actually shows two results and I only mentioned one of them one result is forwards from the string to the curve the other is backwards from the curve point to a uniformly random string sorry just a little background so there's some follow on work as I'm sure you know called Elegator squared and this map is still totally compatible with Elegator squared so you can sort of it doubles the length compared to Elegator but yeah you can still get uniformly random strings backwards from the curve points any other questions what you mentioned I have a question you mentioned that there's a standardization effort for parents right I think I believe by IETF are they aware of these results yeah there's actually also a standardization effort for hash to curves and this will be included I think for some of them so I think for example P256 one of the recommended methods will be this one okay great let's thank the speaker again please