|
|
@@ -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] |