diff --git a/code-ch01/Chapter1.ipynb b/code-ch01/Chapter1.ipynb index f8055f46..47851cca 100644 --- a/code-ch01/Chapter1.ipynb +++ b/code-ch01/Chapter1.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -19,9 +19,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "False\nTrue\n" + ] + } + ], "source": [ "from ecc import FieldElement\n", "a = FieldElement(7, 13)\n", @@ -43,9 +51,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + ".\n", + "----------------------------------------------------------------------\n", + "Ran 1 test in 0.020s\n", + "\n", + "OK\n" + ] + } + ], "source": [ "# Exercise 1\n", "\n", @@ -55,18 +75,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "1\n" + ] + } + ], "source": [ "print(7 % 3)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "12\n" + ] + } + ], "source": [ "print(-27 % 13)" ] @@ -87,25 +123,41 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "20\n37\n51\n41\n" + ] + } + ], "source": [ "# Exercise 2\n", "\n", "# remember that % is the modulo operator\n", "prime = 57\n", - "# 44+33\n", - "# 9-29\n", - "# 17+42+49\n", - "# 52-30-38" + "print((44+33)%57)\n", + "print((9-29)%57)\n", + "print((17+42+49)%57)\n", + "print((52-30-38)%57)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "True\n" + ] + } + ], "source": [ "from ecc import FieldElement\n", "a = FieldElement(7, 13)\n", @@ -127,9 +179,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + ".\n", + "----------------------------------------------------------------------\n", + "Ran 1 test in 0.009s\n", + "\n", + "OK\n" + ] + } + ], "source": [ "# Exercise 3\n", "\n", @@ -152,17 +216,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "23\n68\n63\n" + ] + } + ], "source": [ "# Exercise 4\n", "\n", "prime = 97\n", "\n", - "# 95*45*31\n", - "# 17*13*19*44\n", - "# 12**7*77**49" + "print((95*45*31)%97)\n", + "print((17*13*19*44)%97)\n", + "print((12**7*77**49)%97)" ] }, { @@ -178,22 +250,61 @@ "Do you notice anything about these sets?" ] }, + { + "source": [ + "K=1\n", + "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}\n", + "{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36}\n", + "→{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 1, 3, 5, 7, 9, 11, 13, 15, 7} => 元の集合d" + ], + "cell_type": "markdown", + "metadata": {} + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]\n[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]\n[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]\n" + ] + } + ], "source": [ "# Exercise 5\n", "\n", "prime = 19\n", - "k = 1 # 3, 7, 13 and 18 are the other possibilities\n", + "# k = 1, 3, 7, 13 and 18 are the other possibilities\n", "# loop through all possible k's 0 up to prime-1\n", "# calculate k*iterator % prime\n", "\n", - "# Hint - sort!" + "# Hint - sort!\n", + "\n", + "for k in (1,3,5):\n", + " print(sorted([(k * p) % prime for p in range(prime)]) )" ] }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]" + ] + }, + "metadata": {}, + "execution_count": 36 + } + ], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -220,9 +331,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + ".\n", + "----------------------------------------------------------------------\n", + "Ran 1 test in 0.023s\n", + "\n", + "OK\n" + ] + } + ], "source": [ "# Exercise 6\n", "\n", @@ -232,9 +355,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 41, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "True\n" + ] + } + ], "source": [ "from ecc import FieldElement\n", "a = FieldElement(3, 13)\n", @@ -255,13 +386,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 50, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[1, 1, 1, 1, 1, 1]\n[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n" + ] + } + ], "source": [ "# Exercise 7\n", "\n", - "primes = [7, 11, 17, 31, 43]" + "primes = [7, 11, 17, 31, 43]\n", + "\n", + "for p in primes:\n", + " print([(k ** (p-1) % p)for k in range(1, p)])" ] }, { @@ -279,15 +421,45 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 59, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "4\n29\n13\n" + ] + } + ], "source": [ "# Exercise 8\n", "\n", - "# 3/24\n", - "# 17**-3\n", - "# 4**-4*11" + "print((3 * 24**(31-2)) % 31)\n", + "print((17**(31-2)) * (17**(31-2)) * (17**(31-2)) % 31 )\n", + "\n", + "print((4**(31-2)) * (4**(31-2)) * (4**(31-2)) * (4**(31-2)) * 11 % 31 )" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "29" + ] + }, + "metadata": {}, + "execution_count": 62 + } + ], + "source": [ + "prime = 31\n", + "pow(17, prime-4 ,prime)\n" ] }, { @@ -305,9 +477,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + ".\n", + "----------------------------------------------------------------------\n", + "Ran 1 test in 0.012s\n", + "\n", + "OK\n" + ] + } + ], "source": [ "# Exercise 9\n", "\n", @@ -317,18 +501,63 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "True\n" + ] + } + ], "source": [ "from ecc import FieldElement\n", "a = FieldElement(7, 13)\n", "b = FieldElement(8, 13)\n", "print(a**-3==b)" ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ], + "source": [ + "1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], - "metadata": {}, + "metadata": { + "kernelspec": { + "name": "python373jvsc74a57bd031f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6", + "display_name": "Python 3.7.3 64-bit" + }, + "metadata": { + "interpreter": { + "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + } + } + }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/code-ch01/ecc.py b/code-ch01/ecc.py index b5bf616e..92d324cd 100644 --- a/code-ch01/ecc.py +++ b/code-ch01/ecc.py @@ -22,9 +22,11 @@ def __eq__(self, other): # end::source1[] def __ne__(self, other): - # this should be the inverse of the == operator - raise NotImplementedError + if other is None: + return False + return not (self == other) + # tag::source2[] def __add__(self, other): if self.prime != other.prime: # <1> @@ -39,15 +41,18 @@ def __sub__(self, other): # self.num and other.num are the actual values # self.prime is what we need to mod against # We return an element of the same class - raise NotImplementedError + num = (self.num - other.num) % self.prime # <2> + return self.__class__(num, self.prime) # <3> + def __mul__(self, other): if self.prime != other.prime: raise TypeError('Cannot multiply two numbers in different Fields') # self.num and other.num are the actual values # self.prime is what we need to mod against # We return an element of the same class - raise NotImplementedError + num = (self.num * other.num) % self.prime # <2> + return self.__class__(num, self.prime) # <3> # tag::source3[] def __pow__(self, exponent): @@ -64,8 +69,8 @@ def __truediv__(self, other): # this means: # 1/n == pow(n, p-2, p) # We return an element of the same class - raise NotImplementedError - + num = self.num * pow(other.num, other.prime - 2, self.prime) % self.prime + return self.__class__(num, self.prime) class FieldElementTest(TestCase): diff --git a/docs/matome.md b/docs/matome.md new file mode 100644 index 00000000..885a3ce6 --- /dev/null +++ b/docs/matome.md @@ -0,0 +1,50 @@ +# 1 有限体 +* 楕円曲線暗合(ECC)を学ぶ→トランザクションの根本 + * 署名アルゴリズム + * 鑑賞アルゴリズム +* トランザクション + * ビットコインで価値移転 + +## 1. 2 有限体の定義 +* 有限個の数からなる集合 +* 加算と乗算が以下を満たす + * 1. 閉じている + * 独自の加算の定義をしている + * 2. 加法単位元→0がある + * 3. 乗算単位元→1がある + * 4. 加法逆元→-aがある + * 5. 乗算逆元→a-1がある + +## 1.3 有限集合の定義 +* 有限体の数学の表記 + * Fp = {0, 1, 2,...p-1} +* 位数をpとする + * 勝訴は0,1,2,3の一人は限らない + * 体の位数は最大要素より1多い数になる + * 体の位数は素数の冪になる + +## 1.4 モジュロ演算 +* 四則演算について、閉じている有限体を作るために利用できる + * モジュロ演算 + * 1つのかずを別の数で割った時のあまりを求めること + +## 1.5 有限体の加算と減算 +* 加算 + * a, b \in F_19 + * a +_f b \in F_19 + * 定義: a +_f b = (a + b) % p + * 例 + * (7 + 8) % 19 = 15 + * (17 + 18) % 19 = 16 +* 減算 + * a -f_b = (a - b) % p + +## 1.6 有限体の乗算とべき算 +* なんかそのまんま + +## 1.7 有限体の除算 +* 難しい +* 有限体において、a/b = a *_f (1/b) = a *_f b^(-1) + +# まとめ +なんとなく理解出来た