Added El-Gamal encryption

This commit is contained in:
Afeedh Shaji 2021-03-25 01:11:00 +05:30
parent dcdd72ab3d
commit cbda2c8ccc
9 changed files with 139 additions and 120 deletions

Binary file not shown.

View File

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

View File

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