Browse Source

eddsa_to_decaf_opt working

master
Michael Hamburg 7 years ago
parent
commit
7691fb1380
1 changed files with 34 additions and 10 deletions
  1. +34
    -10
      aux/decaffeinate_ed25519_too.sage

+ 34
- 10
aux/decaffeinate_ed25519_too.sage View File

@@ -28,21 +28,24 @@ def eddsa_to_decaf(x,y):


def isqrt_trick(to_isr,to_inv): def isqrt_trick(to_isr,to_inv):
to_sqrt = to_isr*to_inv^2 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!") if not is_square(to_sqrt): raise Exception("Not square in isqrt_trick!")
tmp = 1/sqrt(to_sqrt) tmp = 1/sqrt(to_sqrt)
isr = tmp * to_inv isr = tmp * to_inv
inv = tmp * isr * to_isr inv = tmp * isr * to_isr
assert isr^2 == 1/to_isr assert isr^2 == 1/to_isr
assert inv == 1/to_inv assert inv == 1/to_inv
return isr, inv
return isr, inv, tmp


def eddsa_to_decaf_opt(x,y,z=None): 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: if z is None:
# Pretend that we're in projective # Pretend that we're in projective
@@ -50,15 +53,15 @@ def eddsa_to_decaf_opt(x,y,z=None):
x *= z x *= z
y *= 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: if rotate:
isr *= (z^2-y^2)*inv
isr = tmp*(z^2-y^2)*magic
y = ii*x y = ii*x
if hibit(2*inv*y*z) != rotate: y = -y
if hibit(2*minv*y) != rotate: y = -y
s = (z-y) * isr s = (z-y) * isr
if hibit(s): s = -s 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") 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 assert y^2 - x^2 == 1+d*x^2*y^2
return (x,y) 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]

Loading…
Cancel
Save