我也看得云里雾里,
但是ECC和RSA并列为非对称加密双雄,
还是很有必要了解一下的。
RSA是用质数分解,ECC是用离散的椭圆方程解,安全度更高。
而且,这个ECC的加法乘法规则,和普通都不一样,
其解是属于一个什么阿贝尔群(一听就知道高级啦)。
百度的文章,下面这个比较详细。
https://www.sohu.com/a/216057858_465483
from hashlib import sha256 def sha256d(string): if not isinstance(string, bytes): string = string.encode() return sha256(sha256(string).digest()).hexdigest() def inv_mod(b, p): if b < 0 or p <= b: b = b % p c , d = b, p uc, vc, ud, vd, temp = 1, 0, 0, 1, 0 while c != 0: temp = c q, c, d = d // c, d % c, temp uc, vc, ud, vd = ud - q * uc, vd - q * vc, uc, vc assert d == 1 if ud > 0: return ud else: return ud + p def leftmost_bit(x): assert x > 0 result = 1 while result <= x: result = 2 * result return result // 2 print(inv_mod(2, 23)) print(3*inv_mod(1, 23) % 23) def show_points(p, a, b): return [(x, y) for x in range(p) for y in range(p) if (y*y - (x*x*x + a*x + b)) % p == 0] print(show_points(p=29, a=4, b=20)) def double(x, y, p, a, b): l = ((3 * x * x + a) * inv_mod(2 * y, p)) % p x3 = (l * l - 2 * x) % p y3 = (l * (x - x3) - y) % p return x3, y3 print(double(1, 4, p=5, a=2, b=3)) def add(x1, y1, x2, y2, p, a, b): if x1 == x2 and y1 == y2: return double(x1, y1, p, a, b) l = ((y2 - y1) * inv_mod(x2 - x1, p)) % p x3 = (l * l - x1 -x2) % p y3 = (l * (x1 - x3) - y1) % p return x3, y3 print(add(1, 4, 3, 1, p=5, a=2, b=3)) def get_bits(n): bits = [] while n != 0: bits.append(n & 1) n >> 1 return bits class CurveFp(object): def __init__(self, p, a, b): """ y^2 = x^3 + a*x + b (mod p).""" self.p = p self.a = a self.b = b def contains_point(self, x, y): return (y * y - (x * x * x + self.a * x + self.b)) % self.p == 0 def show_all_points(self): return [(x, y) for x in range(self.p) for y in range(self.p) if (y * y - (x * x * x + self.a * x + self.b)) % self.p == 0] def __repr__(self): return "Curve(p={0:d}, a={1:d}, b={2:d})".format(self.p, self.a, self.b) class Point(object): def __init__(self, curve, x, y, order=None): self.curve = curve self.x = x self.y = y self.order = order # self.curve is allowed to be None only for INFINITY: if self.curve: assert self.curve.contains_point(x, y) if order: assert self * order == INFINITY def __eq__(self, other): """Is this point equals to another""" if self.curve == other.curve \ and self.x == other.x \ and self.y == other.y: return True else: return False def __add__(self, other): """Add one point to another point.""" if other == INFINITY: return self if self == INFINITY: return other assert self.curve == other.curve if self.x == other.x: if (self.y + other.y) % self.curve.p == 0: return INFINITY else: return self.double() p = self.curve.p l = ((other.y - self.y) * \ inv_mod(other.x - self.x, p)) % p x3 = (l * l - self.x - other.x) % p y3 = (l * (self.x - x3) - self.y) % p return Point(self.curve, x3, y3) def __mul__(self, other): e = other if self.order: e = e % self.order if e == 0: return INFINITY if self == INFINITY: return INFINITY e3 = 3 * e negative_self = Point(self.curve, self.x, -self.y, self.order) i = leftmost_bit(e3) // 2 result = self while i > 1: result = result.double() if (e3 & i) != 0 and (e & i) == 0: result = result + self if (e3 & i) == 0 and (e & i) != 0: result = result + negative_self i = i // 2 return result def __rmul__(self, other): """Multiply a point by an integer.""" return self * other def __repr__(self): if self == INFINITY: return "infinity" return "({0},{1})".format(self.x, self.y) def double(self): """the double point.""" if self == INFINITY: return INFINITY p = self.curve.p a = self.curve.a l = ((3 * self.x * self.x + a) * \ inv_mod(2 * self.y, p)) % p x3 = (l * l - 2 * self.x) % p y3 = (l * (self.x - x3) - self.y) % p return Point(self.curve, x3, y3) def invert(self): return Point(self.curve, self.x, -self.y % self.curve.p) INFINITY = Point(None, None, None) p, a, b = 29, 4, 20 curve = CurveFp(p, a, b) p0 = Point(curve, 3, 1) print(p0*2) print(p0*20)
输出:
12 3 [(0, 7), (0, 22), (1, 5), (1, 24), (2, 6), (2, 23), (3, 1), (3, 28), (4, 10), (4, 19), (5, 7), (5, 22), (6, 12), (6, 17), (8, 10), (8, 19), (10, 4), (10, 25), (13, 6), (13, 23), (14, 6), (14, 23), (15, 2), (15, 27), (16, 2), (16, 27), (17, 10), (17, 19), (19, 13), (19, 16), (20, 3), (20, 26), (24, 7), (24, 22), (27, 2), (27, 27)] (3, 1) (2, 0) (24,7) (15,27)