開発環境
- 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 1(Finite Fields)、Finite Field Division、Exercises 9(16)の解答を求めてみる。
コード
Python 3
ecc_test.py
#!/usr/bin/env python3
from unittest import TestCase, main
from ecc import FieldElement
class FieldElementTest(TestCase):
def setUp(self):
self.a = FieldElement(6, 13)
self.b = FieldElement(7, 13)
self.c = FieldElement(6, 17)
def tearDown(self):
pass
def test_ne(self):
self.assertNotEqual(self.a, None)
self.assertNotEqual(self.a, self.b)
self.assertNotEqual(self.a, self.c)
def test_neg(self):
self.assertEqual(-self.a, FieldElement(7, 13))
def test_sub(self):
self.assertEqual(self.a - self.a, FieldElement(0, 13))
self.assertEqual(self.a - self.b, FieldElement(12, 13))
self.assertEqual(self.b - self.a, FieldElement(1, 13))
def test_mul(self):
self.assertEqual(FieldElement(3, 13), self.a * self.b)
def test_mul_exc(self):
with self.assertRaises(TypeError):
self.a + self.c
def test_true_div1(self):
prime = 31
actual = FieldElement(3, prime) / FieldElement(24, prime)
self.assertEqual(FieldElement(4, prime), actual)
def test_true_div2(self):
prime = 31
actual = FieldElement(1, prime) / FieldElement(17, prime) ** 3
self.assertEqual(FieldElement(29, prime), actual)
def test_true_div3(self):
prime = 31
actual = (
FieldElement(1, prime) /
FieldElement(4, prime) ** 4 *
FieldElement(11, prime)
)
self.assertEqual(FieldElement(13, prime), actual)
if __name__ == '__main__':
main()
ecc.py
#!/usr/bin/env python3
class FieldElement:
def __init__(self, num: int, prime: int):
if num < 0 or prime <= num:
raise ValueError(f'Num {num} not in field range 0 to {prime - 1}')
self.num = num
self.prime = prime
def __repr__(self) -> str:
return f'FieldElement_{self.prime}({self.num})'
def __eq__(self, other) -> bool:
if other is None:
return False
return self.num == other.num and self.prime == other.prime
def __ne__(self, other) -> bool:
if other is None:
return True
return not self == other
def __neg__(self):
return self.__class__(-self.num % self.prime, self.prime)
def __add__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
return self.__class__((self.num + other.num) % self.prime, self.prime)
def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot subtract two numbers in different Fields')
return self + (- other)
def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot multiply two numbers in different Fields')
return self.__class__((self.num * other.num) % self.prime, self.prime)
def __pow__(self, other):
return self.__class__(pow(self.num, other, self.prime), self.prime)
def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot two numbers in different Fields')
num = (self.num *
pow(other.num, other.prime - 2, other.prime) %
self.prime)
prime = self.prime
return self.__class__(num, prime)
入出力結果(cmd(コマンドプロンプト)、Terminal、Jupyter(IPython))
C:\Users\...>py -3 ecc_test.py -v test_mul (__main__.FieldElementTest) ... ok test_mul_exc (__main__.FieldElementTest) ... ok test_ne (__main__.FieldElementTest) ... ok test_neg (__main__.FieldElementTest) ... ok test_sub (__main__.FieldElementTest) ... ok test_true_div1 (__main__.FieldElementTest) ... ok test_true_div2 (__main__.FieldElementTest) ... ok test_true_div3 (__main__.FieldElementTest) ... ok ---------------------------------------------------------------------- Ran 8 tests in 0.001s OK C:\Users\...>
0 コメント:
コメントを投稿