代码
def extGCD(a, b):
if b == 0:
return 1, 0, a
x, y, q = extGCD(b, a % b)
x, y = y, (x - (a // b) * y)
return x, y, q
def modReverse(a, p):
x, y, q = extGCD(a, p)
if q != 1:
raise Exception("No solution.")
else:
return (x + p) % p
class EllipticPoint:
def __init__(self, curve: "EllipticCurve", x: int, y: int):
self.curve = curve
self.x = x % self.curve.mod
self.y = y % self.curve.mod
def __rmul__(self, other: int) -> "EllipticPoint":
if not isinstance(other, int):
raise Exception("只支持左乘整数")
temp = self
res = None
while other:
if other % 2:
if not res:
res = temp
else:
res += temp
temp += temp
other //= 2
return res
def __add__(self, other: "EllipticPoint") -> "EllipticPoint":
if not isinstance(other, EllipticPoint):
raise Exception("只支持两点相加")
if not self.curve == other.curve:
raise Exception("不是同一个椭圆曲线")
if self == other:
lam = (3 * self.x ** 2 + self.curve.a) * modReverse((2 * self.y), self.curve.mod)
x = lam ** 2 - 2 * self.x
y = lam * (self.x - x) - self.y
else:
lam = (self.y - other.y) * modReverse((self.x - other.x), self.curve.mod)
x = lam ** 2 - self.x - other.x
y = lam * (self.x - x) - self.y
return self.__class__(self.curve, x, y)
def __sub__(self, other: "EllipticPoint") -> "EllipticPoint":
if not isinstance(other, EllipticPoint):
raise Exception("只支持点减点")
return self + self.__class__(other.curve, other.x, -other.y)
def __neg__(self) -> "EllipticPoint":
return self.__class__(self.curve, self.x, -self.y)
def __eq__(self, other: "EllipticPoint"):
return self.x == other.x and self.y == other.y
def __str__(self):
return f"({self.x}, {self.y})"
__repr__ = __str__
class EllipticCurve:
def __init__(self, mod: int, a: int, b: int):
self.mod = mod
self.a = a
self.b = b
def __call__(self, x: int, y: int) -> EllipticPoint:
if (y ** 2 - x ** 3 - self.a * x - self.b) % self.mod:
raise Exception(f"({x}, {y})不在曲线上!")
return EllipticPoint(self, x, y)
def __eq__(self, other: "EllipticCurve"):
return self.mod == other.mod and self.a == other.a and self.b == other.b
举例
利用椭圆曲线实现ElGamal密码体制,设椭圆曲线是E_{11}(1,6),生成元G=(2,7),接收方A的秘密钥n_A=7。
(1) 求A的公开钥P_A
(2) 发送方B欲发送消息P_m=(10,9),选择随机数k=3,求密文C_m。
(3) 显示接收方A从密文C_m恢复消息P_m的过程。
# 初始化 e = EllipticCurve(11, 1, 6) # 椭圆曲线 G = e(2, 7) # 生成元 na = 7 # 密钥 # 计算公钥P_A=n_AG Pa = na * G print("公钥: %s" % Pa) # 求密文C_m=\{C_1,C_2\}=\{kG,P_m+kP_A\} Pm = e(10, 9) # 明文 k = 3 C1 = k * G C2 = Pm + k * Pa print("密文: {%s, %s}" % (C1, C2)) # 求明文P_m=C_2-n_AC1 print("明文: %s" % (C2 - na * C1)) ```输出 公钥: (7, 2) 密文: {(8, 3), (10, 2)} 明文: (10, 9) ```