From 7691fb1380a9e341f638c7bbc055e674c44f426f Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Mon, 22 May 2017 17:53:57 -0700 Subject: [PATCH] eddsa_to_decaf_opt working --- aux/decaffeinate_ed25519_too.sage | 44 ++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/aux/decaffeinate_ed25519_too.sage b/aux/decaffeinate_ed25519_too.sage index 9a9127c..d6b5095 100644 --- a/aux/decaffeinate_ed25519_too.sage +++ b/aux/decaffeinate_ed25519_too.sage @@ -28,21 +28,24 @@ def eddsa_to_decaf(x,y): def isqrt_trick(to_isr,to_inv): to_sqrt = to_isr*to_inv^2 - if to_sqrt == 0: return 0,0 # This happens automatically in C; just to avoid problems in SAGE + + if to_sqrt == 0: return 0,0,0 # This happens automatically in C; just to avoid problems in SAGE if not is_square(to_sqrt): raise Exception("Not square in isqrt_trick!") + tmp = 1/sqrt(to_sqrt) isr = tmp * to_inv inv = tmp * isr * to_isr + assert isr^2 == 1/to_isr assert inv == 1/to_inv - return isr, inv + return isr, inv, tmp def eddsa_to_decaf_opt(x,y,z=None): """ - Optimized version of eddsa_to_decaf. - - Uses only one isqrt. + Optimized version of eddsa_to_decaf. Uses only one isqrt. + There's probably some way to further optimize if you have a T-coord, + but whatever. """ if z is None: # Pretend that we're in projective @@ -50,15 +53,15 @@ def eddsa_to_decaf_opt(x,y,z=None): x *= z y *= z - isr,inv = isqrt_trick(z^2-y^2,x*y) - inv *= magic + isr,inv,tmp = isqrt_trick(z^2-y^2,x*y) + minv = inv*magic*z - rotate = hibit(inv*z^2) + rotate = hibit(minv*z) if rotate: - isr *= (z^2-y^2)*inv + isr = tmp*(z^2-y^2)*magic y = ii*x - if hibit(2*inv*y*z) != rotate: y = -y + if hibit(2*minv*y) != rotate: y = -y s = (z-y) * isr if hibit(s): s = -s @@ -85,3 +88,24 @@ def decaf_to_eddsa(s): if y == 0 or lobit(t/y): raise Exception("invalid: t/y has high bit") assert y^2 - x^2 == 1+d*x^2*y^2 return (x,y) + +def decaf_to_eddsa_opt(s): + """ + Convert a Decaf representation to an EdDSA point, in a manner compatible + with libdecaf. + """ + if s == 0: return (0,1) + if hibit(s): raise Exception("invalid: s has high bit") + if not is_square(s^4 + (2-4*dM)*s^2 + 1): raise Exception("invalid: not on curve") + + t = sqrt(s^4 + (2-4*dM)*s^2 + 1)/s + if hibit(t): t = -t + y = (1-s^2)/(1+s^2) + x = 2*magic/t + if y == 0 or lobit(t/y): raise Exception("invalid: t/y has high bit") + assert y^2 - x^2 == 1+d*x^2*y^2 + return (x,y) + + +print [s == eddsa_to_decaf(*decaf_to_eddsa(s)) for _,_,s,_,_,_ in points] +print [s == eddsa_to_decaf_opt(*decaf_to_eddsa_opt(s)) for _,_,s,_,_,_ in points] \ No newline at end of file