Added El-Gamal encryption
This commit is contained in:
parent
dcdd72ab3d
commit
cbda2c8ccc
Binary file not shown.
210
elliptic.py
210
elliptic.py
|
@ -1,152 +1,148 @@
|
|||
|
||||
class EllipticCurve(object):
|
||||
def __init__(self, a, b):
|
||||
# assume we're already in the Weierstrass form
|
||||
self.a = a
|
||||
self.b = b
|
||||
def __init__(self, a, b):
|
||||
# assume we're already in the Weierstrass form
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
self.discriminant = -16 * (4 * a*a*a + 27 * b * b)
|
||||
if not self.isSmooth():
|
||||
raise Exception("The curve %s is not smooth!" % self)
|
||||
self.discriminant = -16 * (4 * a*a*a + 27 * b * b)
|
||||
if not self.isSmooth():
|
||||
raise Exception("The curve %s is not smooth!" % self)
|
||||
|
||||
def isSmooth(self):
|
||||
return self.discriminant != 0
|
||||
|
||||
def isSmooth(self):
|
||||
return self.discriminant != 0
|
||||
def testPoint(self, x, y):
|
||||
return y*y == x*x*x + self.a * x + self.b
|
||||
|
||||
def __str__(self):
|
||||
return 'y^2 = x^3 + %sx + %s' % (self.a, self.b)
|
||||
|
||||
def testPoint(self, x, y):
|
||||
return y*y == x*x*x + self.a * x + self.b
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return 'y^2 = x^3 + %sx + %s' % (self.a, self.b)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.a, self.b) == (other.a, other.b)
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.a, self.b) == (other.a, other.b)
|
||||
|
||||
|
||||
class Point(object):
|
||||
def __init__(self, curve, x, y):
|
||||
self.curve = curve # the curve containing this point
|
||||
self.x = x
|
||||
self.y = y
|
||||
def __init__(self, curve, x, y):
|
||||
self.curve = curve # the curve containing this point
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
if not curve.testPoint(x,y):
|
||||
raise Exception("The point %s is not on the given curve %s!" % (self, curve))
|
||||
if not curve.testPoint(x, y):
|
||||
raise Exception("The point %s is not on the given curve %s!" % (self, curve))
|
||||
|
||||
def __str__(self):
|
||||
return "(%r, %r)" % (self.x, self.y)
|
||||
|
||||
def __str__(self):
|
||||
return "(%r, %r)" % (self.x, self.y)
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
def __neg__(self):
|
||||
return Point(self.curve, self.x, -self.y)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
def __add__(self, Q):
|
||||
|
||||
if self.curve != Q.curve:
|
||||
raise Exception("Can't add points on different curves!")
|
||||
if isinstance(Q, Ideal):
|
||||
return self
|
||||
|
||||
def __neg__(self):
|
||||
return Point(self.curve, self.x, -self.y)
|
||||
x_1, y_1, x_2, y_2 = self.x, self.y, Q.x, Q.y
|
||||
|
||||
print("\n\nAdding P: ({},{}), Q : ({},{})".format(x_1, y_1, x_2, y_2))
|
||||
|
||||
def __add__(self, Q):
|
||||
if self.curve != Q.curve:
|
||||
raise Exception("Can't add points on different curves!")
|
||||
if isinstance(Q, Ideal):
|
||||
return self
|
||||
if (x_1, y_1) == (x_2, y_2):
|
||||
if y_1 == 0:
|
||||
return Ideal(self.curve)
|
||||
|
||||
x_1, y_1, x_2, y_2 = self.x, self.y, Q.x, Q.y
|
||||
# slope of the tangent line
|
||||
m = (3 * x_1 * x_1 + self.curve.a) / (2 * y_1)
|
||||
print("Slope using 3 * x_1 * x_1 + a / (2 * y_1) : \n {} / {} = {} ".format(3 * x_1 * x_1 + self.curve.a, 2 * y_1, m))
|
||||
else:
|
||||
if x_1 == x_2:
|
||||
return Ideal(self.curve)
|
||||
|
||||
if (x_1, y_1) == (x_2, y_2):
|
||||
if y_1 == 0:
|
||||
return Ideal(self.curve)
|
||||
# slope of the secant line
|
||||
m = (y_2 - y_1) / (x_2 - x_1)
|
||||
print("Slope using (y_2 - y_1) / (x_2 - x_1) : \n {} \ {} = {}".format(y_2 - y_1, x_2 - x_1, m))
|
||||
|
||||
# slope of the tangent line
|
||||
m = (3 * x_1 * x_1 + self.curve.a) / (2 * y_1)
|
||||
else:
|
||||
if x_1 == x_2:
|
||||
return Ideal(self.curve)
|
||||
x_3 = m*m - x_2 - x_1
|
||||
y_3 = m*(x_3 - x_1) + y_1
|
||||
|
||||
# slope of the secant line
|
||||
m = (y_2 - y_1) / (x_2 - x_1)
|
||||
print("Performing : R_x = m*m - x_2 - x_1 and R_y = m*(x_3 - x_1) + y_1")
|
||||
print("Co-ordinates of P+Q=R are : ({}, {}) ".format(x_3, -y_3))
|
||||
|
||||
x_3 = m*m - x_2 - x_1
|
||||
y_3 = m*(x_3 - x_1) + y_1
|
||||
return Point(self.curve, x_3, -y_3)
|
||||
|
||||
return Point(self.curve, x_3, -y_3)
|
||||
def __sub__(self, Q):
|
||||
return self + -Q
|
||||
|
||||
def __mul__(self, n):
|
||||
print("\nPerforming {} * {}..Keep Calm\n".format(n, self))
|
||||
if not (isinstance(n, int) or isinstance(n, long)):
|
||||
raise Exception("Can't scale a point by something which isn't an int!")
|
||||
else:
|
||||
if n < 0:
|
||||
return -self * -n
|
||||
if n == 0:
|
||||
return Ideal(self.curve)
|
||||
else:
|
||||
Q = self
|
||||
R = self if n & 1 == 1 else Ideal(self.curve)
|
||||
|
||||
def __sub__(self, Q):
|
||||
return self + -Q
|
||||
i = 2
|
||||
while i <= n:
|
||||
Q = Q + Q
|
||||
|
||||
def __mul__(self, n):
|
||||
if not (isinstance(n, int) or isinstance(n, long)):
|
||||
raise Exception("Can't scale a point by something which isn't an int!")
|
||||
else:
|
||||
if n < 0:
|
||||
return -self * -n
|
||||
if n == 0:
|
||||
return Ideal(self.curve)
|
||||
else:
|
||||
Q = self
|
||||
R = self if n & 1 == 1 else Ideal(self.curve)
|
||||
if n & i == i:
|
||||
R = Q + R
|
||||
|
||||
i = 2
|
||||
while i <= n:
|
||||
Q = Q + Q
|
||||
i = i << 1
|
||||
|
||||
if n & i == i:
|
||||
R = Q + R
|
||||
return R
|
||||
|
||||
i = i << 1
|
||||
def __rmul__(self, n):
|
||||
return self * n
|
||||
|
||||
return R
|
||||
def __list__(self):
|
||||
return [self.x, self.y]
|
||||
|
||||
def __eq__(self, other):
|
||||
if type(other) is Ideal:
|
||||
return False
|
||||
|
||||
def __rmul__(self, n):
|
||||
return self * n
|
||||
return (self.x, self.y) == (other.x, other.y)
|
||||
|
||||
def __list__(self):
|
||||
return [self.x, self.y]
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
def __eq__(self, other):
|
||||
if type(other) is Ideal:
|
||||
return False
|
||||
|
||||
return (self.x, self.y) == (other.x, other.y)
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
def __getitem__(self, index):
|
||||
return [self.x, self.y][index]
|
||||
def __getitem__(self, index):
|
||||
return [self.x, self.y][index]
|
||||
|
||||
|
||||
class Ideal(Point):
|
||||
def __init__(self, curve):
|
||||
self.curve = curve
|
||||
def __init__(self, curve):
|
||||
self.curve = curve
|
||||
|
||||
def __neg__(self):
|
||||
return self
|
||||
def __neg__(self):
|
||||
return self
|
||||
|
||||
def __str__(self):
|
||||
return "Ideal"
|
||||
def __str__(self):
|
||||
return "Ideal"
|
||||
|
||||
def __add__(self, Q):
|
||||
if self.curve != Q.curve:
|
||||
raise Exception("Can't add points on different curves!")
|
||||
return Q
|
||||
def __add__(self, Q):
|
||||
if self.curve != Q.curve:
|
||||
raise Exception("Can't add points on different curves!")
|
||||
return Q
|
||||
|
||||
def __mul__(self, n):
|
||||
if not (isinstance(n, int) or isinstance(n, long)):
|
||||
raise Exception("Can't scale a point by something which isn't an int!")
|
||||
else:
|
||||
return self
|
||||
|
||||
def __eq__(self, other):
|
||||
return type(other) is Ideal
|
||||
def __mul__(self, n):
|
||||
if not (isinstance(n, int) or isinstance(n, long)):
|
||||
raise Exception("Can't scale a point by something which isn't an int!")
|
||||
else:
|
||||
return self
|
||||
|
||||
def __eq__(self, other):
|
||||
return type(other) is Ideal
|
||||
|
|
|
@ -5,26 +5,49 @@ from finitefield.finitefield import FiniteField
|
|||
|
||||
import itertools
|
||||
|
||||
|
||||
def findPoints(curve, field):
|
||||
print('Finding all points over %s' % (curve))
|
||||
print('The ideal generator is %s' % (field.idealGenerator))
|
||||
print('Finding all points over %s' % (curve))
|
||||
print('The ideal generator is %s' % (field.idealGenerator))
|
||||
|
||||
degree = field.idealGenerator.degree()
|
||||
subfield = field.primeSubfield
|
||||
xs = [field(x) for x in itertools.product(range(subfield.p), repeat=degree)]
|
||||
ys = [field(x) for x in itertools.product(range(subfield.p), repeat=degree)]
|
||||
degree = field.idealGenerator.degree()
|
||||
subfield = field.primeSubfield
|
||||
xs = [field(x) for x in itertools.product(range(subfield.p), repeat=degree)]
|
||||
ys = [field(x) for x in itertools.product(range(subfield.p), repeat=degree)]
|
||||
|
||||
points = [Point(curve, x, y) for x in xs for y in ys if curve.testPoint(x,y)]
|
||||
return points
|
||||
points = [Point(curve, x, y) for x in xs for y in ys if curve.testPoint(x, y)]
|
||||
return points
|
||||
|
||||
|
||||
FFd = FiniteField(67, 1) # F_67
|
||||
curve = EllipticCurve(a=FFd(2), b=FFd(3)) # Curve params
|
||||
|
||||
F25 = FiniteField(5, 2)
|
||||
curve = EllipticCurve(a=F25(1), b=F25(1))
|
||||
points = findPoints(curve, F25)
|
||||
G = Point(curve, FFd(2), FFd(22)) # G : pub key
|
||||
n_a = 4 # Private key of A (n_a < n)
|
||||
n_b = 4 # Private key of B (n_b < n)
|
||||
k = 2 # k is a random int the sender selects when encrypting (k < n)
|
||||
|
||||
for point in points:
|
||||
print(point)
|
||||
P_m = Point(curve, FFd(24), FFd(26)) # Point encoded plaintext msg
|
||||
|
||||
print("\n\n\n=========\n\n\nEl Gamal\n\n\n=========\n\n\n")
|
||||
# Pvt key of A
|
||||
print("***************\nCalculating for A:\n***************\n")
|
||||
P_a = n_a*G
|
||||
print("\nPub key of A : ", P_a)
|
||||
# Pvt key of B
|
||||
print("\n***************\nCalculating for B:\n***************\n")
|
||||
P_b = n_b * G
|
||||
print("\nPub Key of B :", P_b)
|
||||
|
||||
|
||||
print("\nB is sending to A (Encrypting with A's pub key)\n")
|
||||
print("\n***************\nCiphertexts:\n***************\n\n C1=k*G; C2=P_m + k*P_a\n")
|
||||
C1 = k*G
|
||||
C2 = P_m + k*P_a
|
||||
print("\nC1 : {} \n".format(C1))
|
||||
print("\nC2 : {} \n".format(C2))
|
||||
print("\nC = [ {}, {} ]\n".format(C1, C2))
|
||||
|
||||
print("\nA is decrypting\n")
|
||||
P_m_dec = C2 - C1*n_a
|
||||
print("\nDecrypted plaintext C2 - C1*n_a : {} \n".format(P_m_dec))
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue