|
|
@@ -0,0 +1,61 @@ |
|
|
|
# This is as sketch of how to decaffeinate Curve25519 |
|
|
|
|
|
|
|
F = GF(2^255-19) |
|
|
|
d = -121665 |
|
|
|
M = EllipticCurve(F,[0,2-4*d,0,1,0]) |
|
|
|
|
|
|
|
def maybe(): return randint(0,1) |
|
|
|
|
|
|
|
def qpositive(x): |
|
|
|
return int(x) <= (2^255-19-1)/2 |
|
|
|
|
|
|
|
def M_to_E(P): |
|
|
|
# P must be even |
|
|
|
(x,y) = P.xy() |
|
|
|
assert x.is_square() |
|
|
|
|
|
|
|
s = sqrt(x) |
|
|
|
if s == 0: t = 1 |
|
|
|
else: t = y/s |
|
|
|
|
|
|
|
X,Y = 2*s / (1+s^2), (1-s^2) / t |
|
|
|
if maybe(): X,Y = -X,-Y |
|
|
|
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 |
|
|
|
if not qpositive(X*Y): X,Y = Y,-X |
|
|
|
assert qpositive(X*Y) |
|
|
|
|
|
|
|
assert (1-X^2).is_square() |
|
|
|
sx = sqrt(1-X^2) |
|
|
|
tos = -2*sx/X/Y |
|
|
|
if not qpositive(tos): sx = -sx |
|
|
|
s = (1 + sx) / X |
|
|
|
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 |
|
|
|
|
|
|
|
def decaf_decode_to_E(s): |
|
|
|
assert qpositive(s) |
|
|
|
t = sqrt(s^4 + (2-4*d)*s^2 + 1) |
|
|
|
if not qpositive(t/s): t = -t |
|
|
|
X,Y = 2*s / (1+s^2), (1-s^2) / t |
|
|
|
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) |
|
|
|
XX,YY = decaf_decode_to_E(s) |
|
|
|
assert is_rotation((X,Y),(XX,YY)) |
|
|
|
|
|
|
|
|
|
|
|
|