y^2 = x^3 + ax + b
-> yが2乗となっているため、x軸に対して対象となる。
-> ビットコインは y^2 = x^3 + 7 で表されている(secp256k1)
2^256 – 2^32 – 2^9 – 2^8 – 2^7 – 2^6 – 2^4 -1を 有限体上で定義された楕円曲線
曲線 y^2 = x^3 + ax + bをclassで表現すると
class Point:
def __init__(self, x, y, a, b):
self.a = a
self.b = b
self.x = x
self.y = y
if self.y**2 != self.x**3 + a * x + b:
raise ValueError('({}, {}) is not on the curve'.format(x, y))
def __eq__(self, other):
return self.x == other.x and self.y == other.y and self.a == other.a and self.b == other.b
from ecc import Point
p1 = Point(-1, -1, 5, 7)
p1 = Point(-1, -2, 5, 7)
楕円曲線上にあるかの判定
d = {2:4, -1:-1, 18:77, 5:7}
for x, y in d.items():
try:
Point(x, y, 5, 7)
print(x, y)
except ValueError:
pass
$ python3 main.py
-1 -1
18 77
### 点の加算
2つの点を演算して、同じ曲線上に3つ目の点を得ることを加算と呼ぶ
垂直、接線の場合は、直線が2点で交差する
無限遠点とは、限りなく遠いところ(無限遠)にある点のこと
点Aに換算すると点Aになる A + I = A
Pythonでは無限遠点をNoneで表現する
from ecc import Point
p1 = Point(-1, -1, 5, 7)
p2 = Point(-1, 1, 5, 7)
inf = Point(None, None, 5, 7)
print(p1 + inf)
print(inf + p2)
print(p1 + p2)
__init__を修正してaddをoverloadする
class Point:
def __init__(self, x, y, a, b):
self.a = a
self.b = b
self.x = x
self.y = y
if self.x is None and self.y is None:
return
if self.y**2 != self.x**3 + a * x + b:
raise ValueError('({}, {}) is not on the curve'.format(x, y))
def __eq__(self, other):
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 not (self == other)
def __add__(self, other):
if self.a != other.a or self.b != other.b:
raise TypeError('Point {}, {} are not on the same curve'.format(self, other))
if self.x is None:
return other
if other.x is None:
return self
x1 != x2 の時の加算コーディング
if self.x != other.x:
s = (other.y - self.y) / (other.x - self.x)
x = s**2 - self.x - other.x
y = s(self.x - x) - self.y
return self.__class__(x, y, self.a, self.b)
P1 = P2(x座標が同じでy座標が異なる時)