<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>Hi all,</div><div><br></div><div>Rambus has agreed to release the code!  It’s on Sourceforge (for export control reasons) at</div><div><br></div><div><a href="https://sourceforge.net/p/ed448goldilocks/code/ci/master/tree/">https://sourceforge.net/p/ed448goldilocks/code/ci/master/tree/</a></div><div><br></div><div>The code is still experimental, and I haven’t picked a hash yet (suggestions?).  So you can do keygen and ECDH, except that the output of ECDH isn’t hashed.  The base operations for sign and verify are there too, but I haven’t implemented those operations yet.</div><div><br></div><div>I should be able to update the repository without future export control issues.</div><div><br></div><div>Cheers,</div><div>— Mike</div><br><div><div>On Feb 12, 2014, at 1:50 PM, Michael Hamburg <<a href="mailto:mike@shiftleft.org">mike@shiftleft.org</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">To be clear, the requirements from our legal department are:<br>* I need to ask them before releasing code, and<br>* I need to comply with US export control law, which (as Legal interprets it) requires preventing IPs associated with a few specific countries from downloading the software.<br><br>I don’t believe that GitHub can filter by country (please tell me if that’s changed), but SourceForge or some other service might be able to.<br><br>Anyway, I haven’t gotten the ball rolling yet, so it might take a while to get permission, especially since the software isn’t done yet.  But I’ll see what I can do.<br><br>Cheers,<br>— Mike<br><br>On Feb 12, 2014, at 12:26 PM, Michael Hamburg <<a href="mailto:mike@shiftleft.org">mike@shiftleft.org</a>> wrote:<br><br><blockquote type="cite">Hi Trevor,<br><br>Not a github initially, because of Rambus legal and export control and all that.  I’ll see if I can set up something more private and get back to you.<br><br>Cheers,<br>— Mike<br><br>On Feb 12, 2014, at 11:22 AM, Trevor Perrin <<a href="mailto:trevp@trevp.net">trevp@trevp.net</a>> wrote:<br><br><blockquote type="cite">Could we expect a github?  I'd love to see this!<br><br>Trevor<br><br><br>On Tue, Feb 11, 2014 at 12:31 AM, Mike Hamburg <<a href="mailto:mike@shiftleft.org">mike@shiftleft.org</a>> wrote:<br><blockquote type="cite">Hello curves,<br><br>I've been working on implementation for the new curves, and I'd like to<br>report status and some formulas and issues I found.<br><br>I'm aiming for a fairly generic C/intrinsics implementation which should<br>support any curves with minimal extra effort, but I'm starting with<br>Ed448-Goldilocks because it's mine.  I have Haswell and Sandy Bridge test<br>machines.  I also have a vectorless Cortex A9, but it doesn't work yet<br>because I'm using 64x64->128-bit multiply intrinsics.  Here's what I've<br>found so far.<br><br>If you have any suggestions on the formulas or algorithms, I'd definitely<br>appreciate it.<br><br>Field arithmetic:<br>* Karatsuba is beneficial for Ed448.<br>* Radix 2^56 in a 64-bit limb, 8 limbs.<br>* M ~ 153cy on Sandy Bridge, 125cy on Haswell<br>* square ~ 0.75M<br>* small fixed mul ~ 0.25M<br>* add/sub (unreduced) ~ 0.04M, a little cheaper on Haswell because of AVX<br><br>I'm using the 1/sqrt(x) point encoding for now, basically because I already<br>have code for that from an earlier project.  I'm not yet counting the time<br>to serialize and deserialize field elements, which is maybe 100 cyles at<br>most (counting the full reduce / checking that input is fully reduced).  I'm<br>not yet counting hashing or RNG times.<br><br>My earlier email about 1/sqrt(x) was slightly off: it encodes even points on<br>the curve, but odd points on the twist.<br><br>I haven't tried blind+EGCD for inverses or Legendre symbol checks.  It might<br>well be a win.  One inverse square root is 56k Sandy cycles (I don't<br>remember the Haswell number).<br><br>Full Montgomery ladder:<br>* Decompress.<br>* Constant-time ladder by 448-bit scalar.  The scalar should be even for<br>security.  It actually could be 447 bits.<br>* Recompress.  Reject points on the twist.  This is basically free, but<br>important because they can't be encoded with the 1/sqrt(x) encoding.<br><br>This takes about 571kcy on Haswell, and 688kcy on Sandy, corrected for<br>TurboBoost.<br><br>I'm using the formula from the thread on efficient laddering with the<br>isomorphic curve, but twisted.  Let (xd,zd) be the point to de doubled, and<br>(xa,za) be the point to be added.<br>  A = (xd+zd)<br>  B = (xd-zd)<br>  DA = (xa-za)*A<br>  BC = (xa+za)*B<br><br>  oxa = (DA+BC)^2<br>  oza = (DA-BC)^2 * xbase<br><br>  AA = A^2<br>  BB = B^2<br>  AAod = AA*(1-d)<br>  E = AA-BB<br><br>  oxd = AAod*BB<br>  ozd = E*(AAod-E)<br><br>  return (oxd,ozd,oxa,oza)<br><br>Except I'm actually using zbase instead of xbase, because of the 1/sqrt(x)<br>format.<br><br>Twisted Edwards (a=-1) windowed algorithm:<br>* Assumes that cofactor is canceled somehow.<br>* Recode scalar in signed form, because it's easy and I'm lazy.<br>* Compute 8 odd multiples of P.<br>* Constant-time add/sub chain with a 4-bit window, 448 bits.  Could be 446<br>bits, except that 446 isn't divisible by 4.<br>* No compress or decompress.<br><br>This takes slightly less time than the Montgomery ladder, some 530kcy on<br>Haswell and 636 kcy on Sandy.  A 5-bit window makes things maybe 1-2%<br>faster, but uses extra complexity and memory so I didn't think it was<br>worthwhile.<br><br>I'm using readdition coordinates:<br>"Projective half-niels" for the tables, ((y-x)/2 : (y+x)/2 : dxy : 1) * z.<br>"Lazy extended coordinates" for the accumulator, (x : y : z : t : u) where<br>xy = tuz.<br><br>I might replace the lazy extended coordinates with Hisil et al's lookahead<br>extended-or-not coordinates, which use less memory but require more care.<br><br>Full constant-time scalarmul using twisted Edwards:<br>* Decompress points, rejecting those on the twist.<br>* Isogenize to the twisted curve, canceling the cofactor.<br>* Above windowed algorithm.<br>* Isogenize back to the main curve, effectively multiplying by 4.<br>* Recompress.<br><br>This takes slightly longer than the Montgomery ladder: something like 633kcy<br>on Haswell and 750kcy on Sandy.  So Edwards or twisted Edwards is best for<br>points you've already got in projective form, and Montgomery is best for<br>ECDH.  Unsurprising.<br><br>The total executable code size to test and bench the arithmetic and curve<br>routines is currently around 41k under clang -O4 -fPIC.  That'll get bigger<br>once there are precomputed tables.<br><br>Formulas:<br>I'm making use of the "inverse square root trick":<br><br>def trick(a,b,i):<br>  # assumes p==3 mod 4; similar trick exists for 1 mod 4<br>  # returns sqrt(+-a/b), 1/i, is_square(a/b)<br>  # assumes a,b,i are nonzero<br>  ai = a*i<br>  abi = b*ai<br>  s = 1/sqrt(+- abi*i) # using a powering ladder<br>  output sqrt(+-a/b) = s*ai<br>  s2abi = s^2*abi<br>  issquare = s2abi * i # = Legendre symbol<br>  if you care about the result of 1/i when a/b is nonsquare:<br>      output 1/i = s2abi*issquare<br>  else:<br>      output 1/i = s2abi<br><br>You can tweak the trick to change the Legendre symbol of the output<br>according to some other variable as well; this depends on the residue of p<br>mod 8.<br><br>The formula I'm using for point compression with Montgomery form is:<br><br>Let P1 + P2 = P3 and (u1,v1) = P1 etc.  Then<br>  4*v1*v2*u3 = (u1*u2-1)^2 - u3^2*(u1-u2)^2<br><br>To compute the numerator of the RHS, do:<br>  sa = (z2*z1 - x2*x1) * z3<br>  sb = (x2*z1 - z2*x1) * x3<br>  numerator = (sa + sb) * (sa - sb)<br>This is good enough to get the Legendre symbol.  It shouldn't be too hard to<br>convert this into a formula with some other sign bit using the inverse<br>square root trick.<br><br>This is on an untwisted (B=1) curve, but the same "ought" to be true of<br>4*B*v1*v2*u3 on a twisted one.<br><br>To serialize an Edwards point, we have to deal with the fact that the<br>isomorphic curve you'd get from Wikipedia is twisted, because it sets B =<br>4/(1-d) which isn't square, at least when p==3 mod 4.  So I'm negating x to<br>get to the curve:<br>  4y^2/(d-1) = x^3 + 2(d+1)/(d-1) * x^2 + x<br>where you can then scale y by sqrt(4/(d-1)) to get the standard curve.<br><br>To deserialize an Edwards point, compute<br>  denominator = (u+1)^2 * (d-1) + 4u<br>  x = 2 sqrt(u/denominator)<br>  y = (1+u)/(1-u)<br>using the inverse square root trick.  This lands you on E_(1,d), because it<br>scales the x-coordinate to get rid of the twisting that the obvious<br>decompression would give you.<br><br>You have to check if u=0 or u=1.  The latter isn't on the curve, but you<br>have to make sure it doesn't slip past the check due to the zero divide.<br>The former works in the 1/sqrt(x) encoding without any checks.<br><br>To do:<br>I'm planning to use WNAF for variable time scalar mul, WNAF for signature<br>verification, and a precomputed signed comb for key generation and Schnorr<br>signing.<br><br>I'm experimenting with the best way to implement Elligator.  I currently<br>only have the map to the curve done, and I might change the signs.  My<br>implementation maps directly to affine using the inverse square root trick.<br>I'll report the formula once I'm done messing around with it.<br><br>And of course there's API packaging, testing on ARM, etc.<br><br>Cheers,<br>-- Mike<br><br><br><br><br>_______________________________________________<br>Curves mailing list<br><a href="mailto:Curves@moderncrypto.org">Curves@moderncrypto.org</a><br>https://moderncrypto.org/mailman/listinfo/curves<br><br></blockquote></blockquote><br>_______________________________________________<br>Curves mailing list<br><a href="mailto:Curves@moderncrypto.org">Curves@moderncrypto.org</a><br>https://moderncrypto.org/mailman/listinfo/curves<br></blockquote><br></blockquote></div><br></body></html>