|
|
@@ -23,7 +23,6 @@ def M_to_E(P): |
|
|
|
if maybe(): X,Y = Y,-X |
|
|
|
# OK, have point in ed |
|
|
|
return X,Y |
|
|
|
|
|
|
|
|
|
|
|
def decaf_encode_from_E(X,Y): |
|
|
|
assert X^2 + Y^2 == 1 + d*X^2*Y^2 |
|
|
@@ -38,6 +37,43 @@ def decaf_encode_from_E(X,Y): |
|
|
|
if not qpositive(s): s = -s |
|
|
|
|
|
|
|
return s |
|
|
|
|
|
|
|
def isqrt(x): |
|
|
|
assert(x.is_square()) |
|
|
|
if x == 0: return 0 |
|
|
|
else: return 1/sqrt(x) |
|
|
|
|
|
|
|
def decaf_encode_from_E_c(X,Y): |
|
|
|
Z = F.random_element() |
|
|
|
T = X*Y*Z |
|
|
|
X = X*Z |
|
|
|
Y = Y*Z |
|
|
|
assert X^2 + Y^2 == Z^2 + d*T^2 |
|
|
|
|
|
|
|
# Precompute |
|
|
|
sd = sqrt(F(1-d)) |
|
|
|
|
|
|
|
zx = Z^2-X^2 |
|
|
|
TZ = T*Z |
|
|
|
assert zx.is_square |
|
|
|
ooAll = isqrt(zx*TZ^2) |
|
|
|
osx = ooAll * TZ |
|
|
|
ooTZ = ooAll * zx * osx |
|
|
|
|
|
|
|
floop = qpositive(T^2 * ooTZ) |
|
|
|
if floop: |
|
|
|
frob = zx * ooTZ |
|
|
|
else: |
|
|
|
frob = sd |
|
|
|
Y = -X |
|
|
|
|
|
|
|
osx *= frob |
|
|
|
|
|
|
|
if qpositive(-2*osx*Z) != floop: osx = -osx |
|
|
|
s = Y*(ooTZ*Z + osx) |
|
|
|
if not qpositive(s): s = -s |
|
|
|
|
|
|
|
return s |
|
|
|
|
|
|
|
def is_rotation((X,Y),(x,y)): |
|
|
|
return x*Y == X*y or x*X == -y*Y |
|
|
@@ -49,13 +85,36 @@ def decaf_decode_to_E(s): |
|
|
|
X,Y = 2*s / (1+s^2), (1-s^2) / t |
|
|
|
assert qpositive(X*Y) |
|
|
|
return X,Y |
|
|
|
|
|
|
|
def decaf_decode_to_E_c(s): |
|
|
|
assert qpositive(s) |
|
|
|
|
|
|
|
s2 = s^2 |
|
|
|
s21 = 1+s2 |
|
|
|
t2 = s21^2 - 4*d*s2 |
|
|
|
|
|
|
|
alt = s21*s |
|
|
|
the = isqrt(t2*alt^2) |
|
|
|
oot = the * alt |
|
|
|
the *= t2 |
|
|
|
tos = the * s21 |
|
|
|
X = 2 * (tos-the) * oot |
|
|
|
Y = (1-s2) * oot |
|
|
|
|
|
|
|
if not qpositive(tos): Y = -Y |
|
|
|
assert qpositive(X*Y) |
|
|
|
|
|
|
|
return X,Y |
|
|
|
|
|
|
|
def test(): |
|
|
|
P = 2*M.random_point() |
|
|
|
X,Y = M_to_E(P) |
|
|
|
s = decaf_encode_from_E(X,Y) |
|
|
|
assert s == decaf_encode_from_E_c(X,Y) |
|
|
|
XX,YY = decaf_decode_to_E(s) |
|
|
|
XX2,YY2 = decaf_decode_to_E_c(s) |
|
|
|
assert is_rotation((X,Y),(XX,YY)) |
|
|
|
assert is_rotation((X,Y),(XX2,YY2)) |
|
|
|
|
|
|
|
|
|
|
|
|