From 2b5f3beb316a6924dbaba211d53d5f03287df3e6 Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Thu, 18 Jun 2015 18:36:32 -0700 Subject: [PATCH] sagelike and clike routines for decaffeinating curve25519 --- aux/decaffeinate_curve25519.sage | 61 +++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/aux/decaffeinate_curve25519.sage b/aux/decaffeinate_curve25519.sage index 05594d1..57cc9bd 100644 --- a/aux/decaffeinate_curve25519.sage +++ b/aux/decaffeinate_curve25519.sage @@ -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)) \ No newline at end of file