Commit 7691fb13 authored by Michael Hamburg's avatar Michael Hamburg

eddsa_to_decaf_opt working

parent b423ac35
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment