# 区块链系统探索之路:基于椭圆曲线的私钥与公钥生成

y ^ 2 = (64 ^ 2) % 103 = 79, x ^ 3 + 7 = (17 ^ 3 + 7 ) % 103 = 79

``````"""

"""

a = LimitFieldElement(0, 223)
b = LimitFieldElement(7, 223)
x = LimitFieldElement(192, 223)
y = LimitFieldElement(105, 223)
p1 = EllipticPoint(x, y, a, b)
print(f"Elliptc Point over F_223 is {p1}")
``````

Elliptc Point over F_223 is EllipticPoint(x:LimitFieldElement_223(192),y:LimitFieldElement_223(105),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))

``````if y ** 2 != x ** 3 + a * x + b:
``````

``````s = (y2 - y1)/(x2 - x1)
x3 = s ^ 2 - x1 - x3
y3 = s * (x1 - x3) - y1
``````

`````` def __sub__(self, other):
if self.order != other.order:
raise TypeError("不能对两个不同有限域的元素执行减法操作")
num = (self.num - other.num) % self.order
return __class__(num, self.order)

def __rmul__(self, scalar):
#实现与常量相乘
num = (self.num * scalar) % self.order
return __class__(num, self.order)
``````

`````````a = LimitFieldElement(0, 223)
b = LimitFieldElement(7, 223)
x = LimitFieldElement(192, 223)
y = LimitFieldElement(105, 223)
p1 = EllipticPoint(x, y, a, b)
#print(f"Elliptc Point over F_223 is {p1}")

#基于有限域上椭圆曲线点对应的"+"操作
x2 = LimitFieldElement(17, 223)
y2 = LimitFieldElement(56, 223)
p2 = EllipticPoint(x2, y2, a, b)

print(f"Elliptic point P1 + P2 is {p1 + p2}")
``````

``````Elliptic point P1 + P2 is EllipticPoint(x:LimitFieldElement_223(170),y:LimitFieldElement_223(142),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))

``````

``````#计算点G(47, 71)的常量乘法
x = LimitFieldElement(47, 223)
y = LimitFieldElement(71, 223)
G = EllipticPoint(x, y, a, b)
result = G
for k in range(1, 22):
if k != 1:
result = result + G
print(f"{k} * (47, 71) is {result}")
``````

``````1 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(47),y:LimitFieldElement_223(71),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
2 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(36),y:LimitFieldElement_223(111),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
3 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(15),y:LimitFieldElement_223(137),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
4 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(194),y:LimitFieldElement_223(51),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
5 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(126),y:LimitFieldElement_223(96),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
6 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(139),y:LimitFieldElement_223(137),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
7 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(92),y:LimitFieldElement_223(47),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
8 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(116),y:LimitFieldElement_223(55),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
9 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(69),y:LimitFieldElement_223(86),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
10 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(154),y:LimitFieldElement_223(150),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
11 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(154),y:LimitFieldElement_223(73),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
12 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(69),y:LimitFieldElement_223(137),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
13 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(116),y:LimitFieldElement_223(168),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
14 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(92),y:LimitFieldElement_223(176),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
15 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(139),y:LimitFieldElement_223(86),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
16 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(126),y:LimitFieldElement_223(127),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
17 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(194),y:LimitFieldElement_223(172),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
18 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(15),y:LimitFieldElement_223(86),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
19 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(36),y:LimitFieldElement_223(112),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
20 * (47, 71) is EllipticPoint(x:LimitFieldElement_223(47),y:LimitFieldElement_223(152),a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
21 * (47, 71) is EllipticPoint(x:None,y:None,a:LimitFieldElement_223(0), b:LimitFieldElement_223(7))
``````

1，单位0，也就是群中必然包含一个特殊元素"0”，任何元素跟他执行”+“操作，其结果都是该元素自己，也就是如果A是群中任何一个元素，那么A “+” 0 = A,
2，闭合性，如果A, B是群中两个元素，那么A “+” B 所得结果还是群中的元素。
3，可逆性，如果A是群中的一个元素，那么群中比如存在另一个元素B, 使得A “+” B = 0
4，交换性，如果A, B是群中两个元素，那么有 A “+” B = B “+” A
5，关联性，(A “+” B) “+” C = A “+” (B “+” C)

“群“是抽象代数中一个至关重要的概念，它也是密码学的支柱性概念。前面我们实现k * G时，代码是把G点执行k次”+"操作，现在我们给椭圆曲线的点添加常量乘法，在EllipitcPoint中增加代码实现如下：

`````` def __rmul__(self, scalar):
#如果常量是0，那么就返回椭圆曲线"0"点
result = self.__class__(None, None, self.a, self.b)
#自加给定次数
for _ in range(scalar):
result += self

return result
``````

``````#测试常量乘法：
for k in range(1, 22):
print(f"{k} * (47, 71) is {k * G}")
``````

``````#测试G点是否在曲线上
gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
p = 2 ** 256 - 2 ** 32 - 977
print(gy ** 2 % p == (gx ** 3 + 7) % p) #True
``````

``````k = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
x = LimitFieldElement(gx, p)
y = LimitFieldElement(gy, p)
a = LimitFieldElement(0, p)
b = LimitFieldElement(7, p)
G = EllipticPoint(x, y, a, b)
print(f'result of n * G is {n * G}')
``````

``````    def __rmul__(self, scalar):
#二进制扩展
coef = scalar
current = self
result = self.__class__(None, None, self.a, self.b)
while coef:
if coef & 1: #如果当前比特位是1，那么执行加法
result += current
current += current  #如果上次比特位的位置在k，那么下次比特位的位置变成k+1，2^(k+1)*G 等价于2^k*G + 2^k * G
coef >>= 1

return result
``````

``````result of k * G is EllipticPoint(x:None,y:None,a:LimitFieldElement_115792089237316195423570985008687907853269984665640564039457584007908834671663(0), b:LimitFieldElement_115792089237316195423570985008687907853269984665640564039457584007908834671663(7))

``````

``````
P = 2**256 - 2**32 - 977

class S256Field(LimitFieldElement):
def __init__(self, num, order=None):
# 参数写死即可
super().__init__(num, P)

def __repr__(self):
return '{:x}'.format(self.num).zfill(64)

N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

class S256Point(EllipticPoint):
def __init__(self, x, y, a=None, b=None):
a, b = S256Field(0), S256Field(7)
if type(x) == int:
super().__init__(S256Field(x), S256Field(y), a, b)
else:
# 如果x,y 是None，那么直接初始化椭圆曲线的0点
super().__init__(x, y, a, b)

def __repr__(self):
if self.x is None:
return 'S256Point(infinity)'

return f'S256Point({self.x}, {self.y})'

def __rmul__(self, k):
k = k % N
return super().__rmul__(k)

G = S256Point(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,

print(N * G)
``````

``````S256Point(infinity)
``````

THE END

)">

)">