Skip to content

Commit

Permalink
added tests for jupyter ch1
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmysong committed Nov 6, 2018
1 parent 8784a12 commit 7802243
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 84 deletions.
6 changes: 3 additions & 3 deletions appa.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class FieldElement:
...
def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot subtract two numbers in different Fields')
num = (self.num - other.num) % self.prime
return self.__class__(num, self.prime)
----
Expand Down Expand Up @@ -110,7 +110,7 @@ class FieldElement:
...
def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot multiply two numbers in different Fields')
num = self.num * other.num % self.prime
return self.__class__(num, self.prime)
----
Expand Down Expand Up @@ -162,7 +162,7 @@ class FieldElement:
def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot divide two numbers in different Fields')
num = self.num * pow(other.num, self.prime-2, self.prime) % self.prime
return self.__class__(num, self.prime)
----
Expand Down
7 changes: 3 additions & 4 deletions ch01.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ We want to represent each finite field element and in Python, we'll be creating

The class represents an actual element in a field F~prime~. The bare bones of the class is pretty intuitive:

.ecc.py
[source,python]
----
class FieldElement:
Expand All @@ -87,13 +86,13 @@ class FieldElement:
self.num = num # <2>
self.prime = prime
def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)
def __eq__(self, other): # <3>
if other is None:
return False
return self.num == other.num and self.prime == other.prime
def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)
----
<1> We first check that `num` is actually between `0` and `prime-1` inclusive. If not, we got an invalid Field Element and we raise a `ValueError` which is what we should raise when we get an inappropriate value.
<2> The rest of the $$__init__$$ method simply assigns the initialization values.
Expand Down
8 changes: 5 additions & 3 deletions code-ch01/Programming Bitcoin Chapter 1.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
"metadata": {},
"outputs": [],
"source": [
"print(7%3)\n",
"print(-27%13)"
"print(7 % 3)\n",
"print(-27 % 13)"
]
},
{
Expand Down Expand Up @@ -99,7 +99,9 @@
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from ecc import FieldElement\n",
Expand Down
88 changes: 88 additions & 0 deletions code-ch01/chapter_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from unittest import TestCase

from ecc import FieldElement, FieldElementTest
from helper import run


class Chapter1Test(TestCase):

def test_apply(self):
def ne(self, other):
return not (self == other)
FieldElement.__ne__ = ne
def sub(self, other):
if self.prime != other.prime:
raise TypeError
num = (self.num - other.num) % self.prime
return self.__class__(num, self.prime)
FieldElement.__sub__ = sub
def mul(self, other):
if self.prime != other.prime:
raise TypeError
num = self.num * other.num % self.prime
return self.__class__(num, self.prime)
FieldElement.__mul__ = mul
def div(self, other):
if self.prime != other.prime:
raise TypeError
num = self.num * pow(other.num, self.prime-2, self.prime) % self.prime
return self.__class__(num, self.prime)
FieldElement.__truediv__ = div

def test_example_1(self):
a = FieldElement(7, 13)
b = FieldElement(6, 13)
self.assertEqual(a == b, False)
self.assertEqual(a == a, True)

def test_example_2(self):
self.assertEqual(7 % 3, 1)
self.assertEqual(-27 % 13, 12)

def test_exercise_2(self):
prime = 57
self.assertEqual((44 + 33) % prime, 20)
self.assertEqual((9 - 29) % prime, 37)
self.assertEqual((17 + 42 + 49) % prime, 51)
self.assertEqual((52 - 30 - 38) % prime, 41)

def test_example_3(self):
a = FieldElement(7, 13)
b = FieldElement(12, 13)
c = FieldElement(6, 13)
self.assertEqual(a + b, c)

def test_exercise_4(self):
prime = 97
self.assertEqual(95 * 45 * 31 % prime, 23)
self.assertEqual(17 * 13 * 19 * 44 % prime, 68)
self.assertEqual(12**7 * 77**49 % prime, 63)

def test_exercise_5(self):
prime = 19
for k in (1, 3, 7, 13, 18):
self.assertEqual(
sorted([k * i % prime for i in range(prime)]),
[i for i in range(prime)]
)

def test_example_4(self):
a = FieldElement(3, 13)
b = FieldElement(12, 13)
c = FieldElement(10, 13)
self.assertEqual(a * b, c)

def test_example_5(self):
a = FieldElement(3, 13)
b = FieldElement(1, 13)
self.assertEqual(a**3, b)

def test_exercise_7(self):
for prime in (7, 11, 17, 31, 43):
self.assertEqual([pow(i, prime-1, prime) for i in range(1, prime)], [1]*(prime-1))

def test_exercise_8(self):
prime = 31
self.assertEqual(3 * pow(24, prime-2, prime) % prime, 4)
self.assertEqual(pow(17, prime-4, prime), 29)
self.assertEqual(pow(4, prime-5, prime) * 11 % prime, 13)
12 changes: 6 additions & 6 deletions code-ch01/ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ def __init__(self, num, prime):
self.num = num
self.prime = prime

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __eq__(self, other):
if other is None:
return False
Expand All @@ -20,9 +23,6 @@ def __ne__(self, other):
# this should be the inverse of the == operator
raise NotImplementedError

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __add__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
Expand All @@ -31,12 +31,12 @@ def __add__(self, other):

def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot subtract two numbers in different Fields')
raise NotImplementedError

def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot multiply two numbers in different Fields')
raise NotImplementedError

def __pow__(self, exponent):
Expand All @@ -46,7 +46,7 @@ def __pow__(self, exponent):

def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot divide two numbers in different Fields')
raise NotImplementedError


Expand Down
12 changes: 6 additions & 6 deletions code-ch02/ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ def __init__(self, num, prime):
self.num = num
self.prime = prime

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __eq__(self, other):
if other is None:
return False
Expand All @@ -20,9 +23,6 @@ def __ne__(self, other):
# this should be the inverse of the == operator
return not (self == other)

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __add__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
Expand All @@ -34,7 +34,7 @@ def __add__(self, other):

def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot subtract two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
num = (self.num - other.num) % self.prime
Expand All @@ -43,7 +43,7 @@ def __sub__(self, other):

def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
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
num = (self.num * other.num) % self.prime
Expand All @@ -57,7 +57,7 @@ def __pow__(self, exponent):

def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot divide two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
# use fermat's little theorem:
Expand Down
12 changes: 6 additions & 6 deletions code-ch03/ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def __init__(self, num, prime):
self.num = num
self.prime = prime

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __eq__(self, other):
if other is None:
return False
Expand All @@ -24,9 +27,6 @@ def __ne__(self, other):
# this should be the inverse of the == operator
return not (self == other)

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __add__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
Expand All @@ -38,7 +38,7 @@ def __add__(self, other):

def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot subtract two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
num = (self.num - other.num) % self.prime
Expand All @@ -47,7 +47,7 @@ def __sub__(self, other):

def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
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
num = (self.num * other.num) % self.prime
Expand All @@ -61,7 +61,7 @@ def __pow__(self, exponent):

def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot divide two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
# use fermat's little theorem:
Expand Down
12 changes: 6 additions & 6 deletions code-ch04/ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def __init__(self, num, prime):
self.num = num
self.prime = prime

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __eq__(self, other):
if other is None:
return False
Expand All @@ -27,9 +30,6 @@ def __ne__(self, other):
# this should be the inverse of the == operator
return not (self == other)

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __add__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
Expand All @@ -41,7 +41,7 @@ def __add__(self, other):

def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot subtract two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
num = (self.num - other.num) % self.prime
Expand All @@ -50,7 +50,7 @@ def __sub__(self, other):

def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
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
num = (self.num * other.num) % self.prime
Expand All @@ -64,7 +64,7 @@ def __pow__(self, exponent):

def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot divide two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
# use fermat's little theorem:
Expand Down
12 changes: 6 additions & 6 deletions code-ch05/ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def __init__(self, num, prime):
self.num = num
self.prime = prime

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __eq__(self, other):
if other is None:
return False
Expand All @@ -27,9 +30,6 @@ def __ne__(self, other):
# this should be the inverse of the == operator
return not (self == other)

def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)

def __add__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
Expand All @@ -41,7 +41,7 @@ def __add__(self, other):

def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot subtract two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
num = (self.num - other.num) % self.prime
Expand All @@ -50,7 +50,7 @@ def __sub__(self, other):

def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
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
num = (self.num * other.num) % self.prime
Expand All @@ -64,7 +64,7 @@ def __pow__(self, exponent):

def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
raise TypeError('Cannot divide two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
# use fermat's little theorem:
Expand Down
Loading

0 comments on commit 7802243

Please sign in to comment.