secp256k1は
a=0, b=7 すなわち y**2 = x **3 + 7
p(※有限体の素数prime) = 2**256 – 2**32 – 977
Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
n(※群位) = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
すなわち2*256は32バイトで記憶することができ、秘密鍵の記憶が比較的簡単にできるという特徴を持つ
gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
p = 2**256 – 2**32 – 977
print(gy**2 % p == (gx**3 + 7) % p)
$ python3 test.py
True
gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 p = 2**256 - 2**32 - 977 n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 x = FieldElement(gx, p) y = FieldElement(gy, p) seven = FieldElement(7, p) zero = FieldElement(0, p) G = Point(x, y, zero, seven) print(n*G)
256ビットの数を常に64文字で表示する。
P = 2**256 - 2**32 - 977 class S256Field(FieldElement): def __init__(self, num, prime=None): super().__init(num=num, prime=P) def __repr__(self): return '{:x}'.format(self.num).zfill(64)
a, bの初期化
class S256Point(Point): def __init__(self, x, y, a=None, b=None) a, b = S256Field(A), S256Field(B) if type(x) == int: super().__init__(x=S256Field(x), y=S256Field(y), a=a, b=b) else: super().__init__(x=x, y=y, a=a, b=b)
群の位数
N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 class S256Point(Point): def __rmul__(self, coefficient): coef = coefficient % N return super().__rmul__(coef)
x, yも定数として定義Gしておく
G = S256Point( 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 )
from ecc import G, N
print(vars(N*G))
$ python3 main.py
{‘a’: 0000000000000000000000000000000000000000000000000000000000000000, ‘b’: 0000000000000000000000000000000000000000000000000000000000000007, ‘x’: None, ‘y’: None}