開発環境
- macOS Mojave - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Python 3.7 (プログラミング言語)
Programming Bitcoin: Learn How to Program Bitcoin from Scratch (Jimmy Song(著)、O'Reilly Media)のChapter 4(Serialization)、Compressed SEC Format、Exercises 2(79)の解答を求めてみる。
コード
Python 3
ecc_test.py
#!/usr/bin/env python3 from unittest import TestCase, main from ecc import FieldElement, Point, S256Point, PrivateKey class S256PointTest(TestCase): def setUp(self): pass def tearDown(self): pass def test_parse(self): secrets = [5001, 2019**5, 0xdeadbeef54321] for secret in secrets: private_key = PrivateKey(secret) point = private_key.point self.assertEqual(point, S256Point.parse(point.sec(compressed=True))) if __name__ == '__main__': main()
ecc.py
#!/usr/bin/env python3 class S256Point(Point): def __init__(self, x, y, a=None, b=None): a = S256Field(A) b = S256Field(B) if type(x) == int: x = S256Field(x) y = S256Field(y) super().__init__(x=x, y=y, a=a, b=b) def __rmul__(self, coefficient): return super().__rmul__(coefficient % N) def __repr__(self): if self.x is None: return 'S256Point(infinity)' return f'S256Point({self.x}, {self.y})' def verify(self, z, sig): s_inv = pow(sig.s, N - 2, N) u = z * s_inv % N v = sig.r * s_inv % N total = u * G + v * self return total.x.num == sig.r def sec(self, compressed=True): if compressed: if self.y.num % 2 == 0: prefix = b'\x02' else: prefix = b'\x03' return prefix + self.x.num.to_bytes(32, 'big') return b'\x04' + \ self.x.num.to_bytes(32, 'big') + \ self.y.num.to_bytes(32, 'big') @staticmethod def parse(sec_bin): if sec_bin[0] == 4: x = int.from_bytes(sec_bin[1:3], 'big') y = int.from_bytes(sec_bin[33:36], 'big') return S256Point(x, y) x = S256Field(int.from_bytes(sec_bin[1:], 'big')) left = x ** 3 + S256Field(A) * x + S256Field(B) y = left.sqrt() is_even = sec_bin[0] == 2 if (is_even and y.num % 2 != 0) or \ (not is_even and y.num % 2 == 0): y = S256Field(P - y.num) return S256Point(x, y)
sample2.py
#!/usr/bin/env python3 from ecc import PrivateKey secrets = [2001, 2019 ** 5, 0xdeadbeef52321] for secret in secrets: private_key = PrivateKey(secret) sec = private_key.point.sec() print(sec.hex())
入出力結果(cmd(コマンドプロンプト)、Terminal、Jupyter(IPython))
C:\Users\...>py ecc_test.py .................... ---------------------------------------------------------------------- Ran 20 tests in 0.041s OK C:\Users\...>py sample2.py 038d3f06b158ddd609f83b0531466fc2a3da6aa80b433a92ddeeb20435cf33ddae 02933ec2d2b111b92737ec12f1c5d20f3233a0ad21cd8b36d0bca7a0cfa5cb8701 02984d8976231dcb7873ef76f4f11c0986a60c3560bfef1e45f3db696e26f3f656 C:\Users\...>
0 コメント:
コメントを投稿