楕円曲線の式
以下のようなグラフになる
secp256k1と呼ばれ、以下の式で表される
以下のようなグラフになる
楕円曲線の点の加算とは、曲線上の2つの点を演算して、同じ曲線状に3つ目の店を得ること。
点Aに点Bを加算を加算することは点Bに点Aを加算することと同じ(点の加算は交換可能)
点の加算を考えるときは、
同一性とは単位元(ゼロ)があることを意味する。点Aに加算すると点Aになる点Iが存在する
この点を「無限遠点」と呼ぶ
可逆性とは任意の点Aに加算すると単位元(ゼロ)になる別の-A点が存在する
グラフで見ると点Aと点-Aは以下のようになり、x軸に対して対象な位置にある
無限遠点は上記の垂直線と曲線が交差する3つ目の、楕円曲線上にある1つの特殊な点と考える
可換性とは以下のような特徴をもつ
結合性とは以下のような特徴をもつ
傾きsは以下となる
x3がわかれば、y3を求めることができる。P3は以下の式を使って求めることができる(証明は省略、というかむしろ誰か教えてほしい)
x1 = x2なので、x3とy3は以下のように求めることができる
上記のs(曲線に対する接線の傾き)は楕円曲線の等式の両辺における微分係数を取り出して、
dy / dxを解くことで求めることができる
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 __repr__(self):
return 'Point({}, {})_{}_{}'.format(self.x, self.y, self.a, self.b)
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('Points {}, {} are not on the same curve'.format(self, other))
#無限遠点の加算の場合(ここでは無限遠点はNoneとする)
if self.x is None:
return other
if other.x is None:
return self
#2つの点が加法逆元(xが同じでyが異なる垂直線)の場合、無限遠点を返す
if self.x == other.x and self.y != other.y:
return self.__class__(None, None, self.a, self.b)
#2つの点がx1!=x2のとき
if self.x != other.x:
s = (other.y - self.y) / (other.x - self.x)
x3 = s**2 - self.x - other.x
y3 = s * (self.x - x3) - self.y
return self.__class__(x3, y3, self.a, self.b)
#2つの点が等しいとき(接点を通るとき)かつ、yが0のとき(接線かつ3点目がない)⇒無限遠点を返す
if self == other and self.y == 0 * self.x:
print('uso-n')
return self.__class__(None, None, self.a, self.b)
#2つの点が等しいとき(接点を通るとき)
if self == other:
s = (3*self.x**2 + self.a) / (2*self.y)
x3 = s**2 - (2*self.x)
y3 = s*(self.x - x3) - self.y
return self.__class__(x3, y3, self.a, self.b)