ブロックチェーン システム探索への道: 楕円曲線上の点 "+" 操作のコード実装

上一节我们了解了有限域的定义,并使用代码进行实现。作为区块链技术的底层技术支柱之一,它跟有限域有着非常紧密的联系,正式因为如此,椭圆曲线才能用来给区块链创建公钥,由此形成区块链钱包的地址。

对椭圆曲线而言,我们并不关心它本身,但是我们关系椭圆曲线上的点,以及这些点在特定操作下所形成的性质。因此我们代码的逻辑在实现椭圆曲线上的点,首先我们实现代码如下:
```python
class EllipticPoint:
    def __init__(self, x, y, a, b):
        """
        a, b为椭圆曲线方程 y^2 = x ^ 3 + ax + b
        对于区块链的椭圆曲线a取值为0,b取值为7,其专有名称为secp256k1
        由此在初始化椭圆曲线点时,必须确保(x,y)位于给定曲线上
        """
        if y**2 != x**3 + a*x + b:
            raise ValueError(f'({x}, {y}) is not on the curve')

        self.x = x
        self.y = y
        self.a = a
        self.b = b

    def __eq__(self, other):
     """
     两个点要相等,我们不能只判断x,y是否一样,必须判断他们是否位于同一条椭圆曲线
     """
       return self.x == other.x and self.y == other.y and self.a == other.a and self.b == other.b
       
    def __ne__(self, other):
        return self.x != other.x or self.y != other.y or self.a != other.a or self.b != other.b

いくつかのインスタンスを作成して、上記のコードを確認してみましょう。

'''
设置曲线y^2 = x ^ 3 + 5x + 7, (a=5, b=7)
'''

b = EllipticPoint(-1, -1, 5, 7)
c = EllipticPoint(18, 77, 5, 7)
print(b == c)
print(b != c)
#下面的点不在曲线上因此会出现异常
d = EllipticPoint(5, 7, 5, 7)

上記のコードでは、3 つの楕円曲線ポイントを作成しました。最初の 2 つのポイントは曲線上にあり、3 番目のポイントは曲線上にないため、ポイント d がインスタンス化されると例外が生成され、実行結果は次のようになります。 :

False
True
Traceback (most recent call last):
  File "/Users/my/PycharmProjects/pythonProject3/blockchain_curve.py", line 104, in <module>
    d = EllipticPoint(5, 7, 5, 7)
  File "/Users/my/PycharmProjects/pythonProject3/blockchain_curve.py", line 78, in __init__
    raise ValueError(f'({
      
      x}, {
      
      y}) is not on the curve')
ValueError: (5, 7) is not on the curve

前節で楕円曲線上の点の足し算について述べました. 楕円曲線上の2点を選択し, それらを接続します. このとき, 3つの状況があります. 2点接続が延長されてから曲線下の図に示すように、3 番目の点で交差します。
写真の説明を追加してください

2 番目のケースは次のとおりです。2 点が同じ直線上にあるため、2 点を結ぶ線と曲線には 3 番目の交点がなくなります。前のセクションで、有限体に
写真の説明を追加してください
はポイント "0" は、内部の任意のポイント a に対するセット Do "+" 操作に関連していますが、結果はポイント a のままです。上記の状況は点「0」に対応します. 上記の直線と曲線の間には3番目の交点はありませんが、この直線と曲線の追加を「無限大」で「定義」し、その交点を「定義」できます.は「0」なので、この場合、直線と曲線の2つの交点は「反対数」です.上の交点をaとすると、下の交点は-aに対応します.曲線上の2点を結ぶ線がy軸に平行 のとき、この2点の「+」演算結果を「0」として記録します。

楕円曲線上の 2 点が一致する 3 番目のケースもあります。つまり、それらは実際には同じ点であり、2 点を結ぶ線が接線を形成します。楕円曲線上の任意の 2 点を選択すると
写真の説明を追加してください
、 execute "+" 操作の後、楕円曲線暗号化の基礎となる 3 番目の点は数学的に予測できません。次に、点の「+」操作を実装します。まず、2 番目の場合を目指します。2 点が同じ直線上にある場合、3 番目の点が無限遠の曲線に「追加」されるためです。 x=None , y=None を使用して表すと同時に、そのような点が他の点 a と "+" 操作を行うようにします。結果は a です。コードの実装を見てみましょう。 :

class EllipticPoint:
    def __init__(self, x, y, a, b):
        self.x = x
        self.y = y
        self.a = a
        self.b = b
        """
        x == None, y == None对应点"0"
        """
        if x is None or y is None:
            return

        """
        a, b为椭圆曲线方程 y^2 = x ^ 3 + ax + b
        对于区块链的椭圆曲线a取值为0,b取值为7,其专有名称为secp256k1
        由此在初始化椭圆曲线点时,必须确保(x,y)位于给定曲线上
        """
        if y ** 2 != x ** 3 + a * x + b:
            raise ValueError(f'({
      
      x}, {
      
      y}) is not on the curve')

    def __eq__(self, other):
        """
        两个点要相等,我们不能只判断x,y是否一样,必须判断他们是否位于同一条椭圆曲线
        """
        return self.x == other.x and self.y == other.y and self.a == other.a and self.b == other.b

    def __ne__(self, other):
        return self.x != other.x or self.y != other.y or self.a != other.a or self.b != other.b
    
    def __add__(self, other):
        """
        实现"+"操作,首先确保两个点位于同一条曲线,也就是他们对应的a,b要相同
        """
        if self.a != other.a or self.b != other.b:
            raise TypeError(f"points {
      
      self}, {
      
      other} not on the same curve")
        
        #如果其中有一个是"0"那么"+"的结果就等于另一个点
        if self.x is None:
            return other 
        if other.x is None:
            return self
    def __repr__(self):
        return f"EllipticPoint(x:{
      
      self.x},y:{
      
      self.y},a:{
      
      self.a}, b:{
      
      self.b})"

上記のコードは、元の初期化関数の実装を変更します. x と y の 2 つのコンポーネントのいずれかが None の場合、それは "0" 点に対応し、"+" 操作に対応する __add__ 関数を実装します. 2 つ追加 ポイントの 1 つが「0」の場合、結果は別のポイントと等しくなります。上記の実装をテストして結果を確認しましょう。

zero + p1 is EllipticPoint(x:-1,y:-1,a:5, b:7)
zero + p2 is EllipticPoint(x:-1,y:1,a:5, b:7)

出力は私たちの期待に沿っています。以下では、3 つの "+" 状況の中で最も単純な状況を実装します。つまり、2 つの点が同じ直線上にある、つまり、点の x 成分は同じですが、y 成分は互いに反対であり、同時に、このような 2 つのポイントは "+" 操作の後、結果は "0" です。実装を見てみましょう。

    def __add__(self, other):
        """
        实现"+"操作,首先确保两个点位于同一条曲线,也就是他们对应的a,b要相同
        """
        if self.a != other.a or self.b != other.b:
            raise TypeError(f"points {
      
      self}, {
      
      other} not on the same curve")

        #如果其中有一个是"0"那么"+"的结果就等于另一个点
        if self.x is None:
            return other
        if other.x is None:
            return self
        
        """
        两点在同一直线上,也就是x相同,y互为相反数
        """
        if self.x == other.x and self.y == -other.y:
            return __class__(None, None, self.a, self.b)

上記のコードをテストしてみましょう。

p1 = EllipticPoint(-1, -1, 5, 7)
p2 = EllipticPoint(-1, 1, 5, 7)
# print(f"zero + p1 is {zero + p1}")
# print(f"zero + p2 is {zero + p2}")
print(f"p1 + p2 = {
      
      p1 + p2}")

上記のコードを実行した結果:

p1 + p2 = EllipticPoint(x:None,y:None,a:5, b:7)

これは私たちの予想と一致しています. 以下では, より複雑な状況, つまり, 3 番目のタイプを実装します. 2 点で形成された直線は 3 番目の点で曲線と交差します. ここではいくつかの数学的導出が必要です. 与えられた 2 点 (x1,y1 ),( x2, y2), まず、高校の代数 k = (y2 - y1)/(x2 - x1) に従って、これらの 2 点を結ぶことによって形成される直線の傾き k を取得し、2 点は直線方程式 y = k * ( x - x1) + y1、直線が楕円曲線と交差する 3 番目の点は直線と曲線の両方にあるため、3 番目の点の座標は両方の方程式を満たさなければなりません。

y = k*(x - x1)+y1
y^2 = x^3 + a*x + b

最初の式の y を 2 番目の式に代入すると、次のようになります。

(k*(x - x1)+y1)^2 = x^3 + a*x + b

上記の式の右側の部分を左に移動し、同時に展開します。

x^3 - k^2 * x^2 +(a + 2*s^2*x1 - 2*k*y1)*x + b - k^2(x1)^2 + 2*k*(x1)*(y1) - (y1)^2 = 0  (1)

(x3, y3) を使用して 3 番目の点を表す場合、(x1, y1)、(x2, y2)、(x3, y3) は次の式を満たさなければなりません。

(x-x1)*(x-x2)*(x-x3) = 0

上記の式を展開すると、次のようになります。

x^3 - (x1+x2+x3)*x^2 + (x1*x2 + x1*x3 + x2*x3)*x - (x1*x2*x3) = 0 (2)

(1) と (2) で x ^ 3、x ^ 2、x ^ 1 に対応すると、定数項目は互いに対応します。

k^2 -> (x1+x2+x3) (3)
(a + 2 * s^2*x1 - 2*k*y1) -> (x1*x2 + x1*x3 + x2*x3)
 b - k^2(x1)^2 + 2*k*(x1)*(y1) - (y1)^2 -> (x1*x2*x3)

ヴェーダの定理によると
、上記 (3) の -> は = に置き換えることができるため、x3 を解くことができます。

x3 = k^2 - x2 - x1 (4

次に、直線方程式に x3 を代入して、y3 を解きます。

y3 = k * (x3 - x1) + y1 (5)
#记得要根据x轴做对称得到"+"对应结果
y = -y3 = k*(x1-x3) - y1 (6)

したがって、式 (4) および (6) に従って、3 番目の交点を直接見つけることができます。コードの実装は次のとおりです。

    def __add__(self, other):
        """
        实现"+"操作,首先确保两个点位于同一条曲线,也就是他们对应的a,b要相同
        """
        if self.a != other.a or self.b != other.b:
            raise TypeError(f"points {
      
      self}, {
      
      other} not on the same curve")

        #如果其中有一个是"0"那么"+"的结果就等于另一个点
        if self.x is None:
            return other
        if other.x is None:
            return self

        """
        两点在同一直线上,也就是x相同,y互为相反数
        """
        if self.x == other.x and self.y == -other.y:
            return __class__(None, None, self.a, self.b)

        """
        计算两点连线后跟曲线相交的第3点,使用韦达定理
        """
        x1 = self.x
        y1 = self.y
        x2 = other.x
        y2 = other.y
        k = (y2 - y1) / (x2 - x1)
        x3 = k ** 2 - x1 - x2
        y3 = k * (x1 - x3) - y1
        if self != other:
            return __class__(x3, y3, self.a, self.b)

上記の実装をテストしましょう。

#测试两点直线与曲线相交于第三点
p1 = EllipticPoint(2, 5, 5, 7)
p2 = EllipticPoint(-1, -1, 5, 7)
print(f"p1 + p2 = {
      
      p1 + p2}")

上記のコードを実行した後の結果:
p1 + p2 = EllipticPoint(x:3.0,y:-7.0,a:5, b:7)

最後に、2 点を結ぶ線が曲線の接線になる状況を認識します。2 点が同じなので、以前のように直線の傾きを直接計算することはできません。k = (y2 - y1)/(x2 - x1)、この時点では x2 = x1 なので、分母は 0 なので、ここでは高度な数学を使用する必要があります の微積分 : 特定の点での曲線の接線の勾配は、曲線方程式によると、その点での曲線の微分に等しくなります。

y^2 = x ^ 3 + a*x + b

x
両側微分ます (4)、(6) を使用して 3 番目の点の座標の計算を完了することができるため、前のコードは次のように変更されます。


   def __add__(self, other):
        """
        实现"+"操作,首先确保两个点位于同一条曲线,也就是他们对应的a,b要相同
        """
        if self.a != other.a or self.b != other.b:
            raise TypeError(f"points {
      
      self}, {
      
      other} not on the same curve")

        # 如果其中有一个是"0"那么"+"的结果就等于另一个点
        if self.x is None:
            return other
        if other.x is None:
            return self

        """
        两点在同一直线上,也就是x相同,y互为相反数
        """
        if self.x == other.x and self.y == -other.y:
            return __class__(None, None, self.a, self.b)

        """
        计算两点连线后跟曲线相交的第3点,使用韦达定理
        """
        x1 = self.x
        y1 = self.y
        x2 = other.x
        y2 = other.y
        if self == other:
            # 如果两点相同,根据微分来获得切线的斜率
            k = (3 * self.x ** 2 + self.a) / 2 * self.y
        else:
            k = (y2 - y1) / (x2 - x1)

        x3 = k ** 2 - x1 - x2
        y3 = k * (x1 - x3) - y1

        return __class__(x3, y3, self.a, self.b)

上記のコードの効果をテストしましょう。

#测试两点相同所形成切线与曲线的交点
p1 = EllipticPoint(-1, -1, 5, 7)
print(f"p1 + p1 = {
      
      p1 + p1}")

上記のコードを実行した後の結果は次のとおりです。

p1 + p1 = EllipticPoint(x:18.0,y:77.0,a:5, b:7)

最後に、別の特殊なケースとして、
写真の説明を追加してください
対応する点の y 成分が 0 の場合があります。この場合、微分を使用して曲線の傾きを計算することはできないため、このケースの判断を次のように追加できます。 __追加__:

    def __add__(self, other):
        """
        特殊情况,两点相同而且y分量为0
        """
        if self == other and self.y == 0:
            return __class__(None, None, self.a, self.b )
        #余下代码省略   
        ....

以上が楕円曲線上の点「+」演算の実現です。ブロックチェーン アプリケーションでは、最初に曲線上の特定の点 G を選択し、次に前のセクションで説明した有限フィールド プロパティを満たす集合 {1 G, 2 G, ...} を生成する必要があります。ブロック チェーン ウォレット アドレスを作成するには、最初に秘密鍵とも呼ばれる大きな数 k を選択し、次に k * G を計算します。結果が公開鍵です。一連のハッシングの後にウォレット アドレスを取得し、公開鍵のエンコーディング、詳細については、ステーション b でコーディング ディズニーを検索してください。






おすすめ

転載: blog.csdn.net/tyler_download/article/details/129602619