forked from jimmysong/programmingbitcoin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanswers.py
126 lines (101 loc) · 2.63 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
'''
# tag::exercise1[]
==== Exercise 1
Determine which of these points are on the curve y^2^=x^3^+5x+7:
(2,4), (-1,-1), (18,77), (5,7)
# 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^+5x+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^+5x+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__