forked from jimmysong/programmingbitcoin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
answers.py
131 lines (105 loc) · 2.76 KB
/
answers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
'''
# tag::exercise1[]
==== Exercise 1
Determine which of these points are on the curve __y__^2^ = __x__^3^ + 5__x__ + 7:
++++
<ul class="simplelist">
<li>(2,4), (–1,–1), (18,77), (5,7)</li>
</ul>
++++
# end::exercise1[]
# tag::answer1[]
>>> def on_curve(x, y):
... return y**2 == x**3 + 5*x + 7
>>> print(on_curve(2,4))
False
>>> print(on_curve(-1,-1))
True
>>> print(on_curve(18,77))
True
>>> print(on_curve(5,7))
False
# end::answer1[]
# tag::exercise4[]
==== Exercise 4
For the curve __y__^2^ = __x__^3^ + 5__x__ + 7, what is (2,5) + (–1,–1)?
# end::exercise4[]
# tag::answer4[]
>>> x1, y1 = 2, 5
>>> x2, y2 = -1, -1
>>> s = (y2 - y1) / (x2 - x1)
>>> x3 = s**2 - x1 - x2
>>> y3 = s * (x1 - x3) - y1
>>> print(x3, y3)
3.0 -7.0
# end::answer4[]
# tag::exercise6[]
==== Exercise 6
For the curve __y__^2^ = __x__^3^ + 5__x__ + 7, what is (–1,–1) + (–1,–1)?
# end::exercise6[]
# tag::answer6[]
>>> a, x1, y1 = 5, -1, -1
>>> s = (3 * x1**2 + a) / (2 * y1)
>>> x3 = s**2 - 2*x1
>>> y3 = s*(x1-x3)-y1
>>> print(x3,y3)
18.0 77.0
# end::answer6[]
'''
from unittest import TestCase
from ecc import Point
'''
# tag::exercise2[]
==== Exercise 2
Write the `__ne__` method for `Point`.
# end::exercise2[]
'''
# tag::answer2[]
def __ne__(self, other):
return not (self == other)
# end::answer2[]
'''
# tag::exercise3[]
==== Exercise 3
Handle the case where the two points are additive inverses (that is, they have the same `x` but a different `y`, causing a vertical line). This should return the point at infinity.
# end::exercise3[]
# tag::exercise5[]
==== Exercise 5
Write the `__add__` method where __x__~1~ ≠ __x__~2~.
# end::exercise5[]
# tag::exercise7[]
==== Exercise 7
Write the `__add__` method when __P__~1~ = __P__~2~.
# end::exercise7[]
'''
def __add__(self, other):
if self.a != other.a or self.b != other.b:
raise TypeError
if self.x is None:
return other
if other.x is None:
return self
# tag::answer3[]
if self.x == other.x and self.y != other.y:
return self.__class__(None, None, self.a, self.b)
# end::answer3[]
# tag::answer5[]
if self.x != other.x:
s = (other.y - self.y) / (other.x - self.x)
x = s**2 - self.x - other.x
y = s * (self.x - x) - self.y
return self.__class__(x, y, self.a, self.b)
# end::answer5[]
if self == other and self.y == 0 * self.x:
return self.__class__(None, None, self.a, self.b)
# tag::answer7[]
if self == other:
s = (3 * self.x**2 + self.a) / (2 * self.y)
x = s**2 - 2 * self.x
y = s * (self.x - x) - self.y
return self.__class__(x, y, self.a, self.b)
# end::answer7[]
class ChapterTest(TestCase):
def test_apply(self):
Point.__ne__ = __ne__
Point.__add__ = __add__