文章目录
《区块链编程》第二章
椭圆曲线
练习1
p32
代码实现
def onCurve(x, y):
return y**2 == x**3 + 5 * x + 7
if __name__ == '__main__':
print(onCurve(2, 4))
print(onCurve(-1, -1))
print(onCurve(18, 77))
print(onCurve(5, 7))
测试
False
True
True
False
[Finished in 237ms]
练习2
p32
代码实现
class Point():
def __init__(self, x, y, a, b):
self.x = x
self.y = y
self.a = a
self.b = b
if self.y ** 2 != self.x ** 3 + a * x + b:
raise ValueError('({},{}) is not on the curve'.format(x, y))
def __eq__(self, other):
return self.x == other.x and self.y == other.y \
and self.a == other.a and self.b == other.b
def __ne__(self, other):
# this is my answer,but it is error. oh no, I am a rookie
# oh, I found my error, the function __eq__() requires only one parameter
# but I give it two. "==" and self.__eq__(..) is equivalent.
# return not self.__eq__(self, other)
return not (self == other)
if __name__ == '__main__':
a = Point(-1, -1, 5, 7)
b = Point(-1, -2, 5, 7)
print(a != b)
测试
-1,-2 不在曲线上, 报错。
Traceback (most recent call last):
File "temp.py", line 31, in <module>
b = Point(-1, -2, 5, 7)
File "temp.py", line 15, in __init__
raise ValueError('({},{}) is not on the curve'.format(x, y))
ValueError: (-1,-2) is not on the curve
[Finished in 237ms]
实现加法恒等元的点加法运算
p37
代码实现
# -*- coding: utf-8 -*-
# @Author: 从化北(喵星人)
# @Date: 2021-12-20 21:31:48
# @Last Modified by: 从化北
# @Last Modified time: 2021-12-20 23:06:44
class Point():
def __init__(self, x, y, a, b):
self.x = x
self.y = y
self.a = a
self.b = b
# if the point is infinity point , return null
if self.x is None and self.y is None:
return
if self.y ** 2 != self.x ** 3 + a * x + b:
raise ValueError('({},{}) is not on the curve'.format(x, y))
def __repr__(self):
if self.x == None:
return "Point(infinity)"
return "Point({}, {})_{}_{}".format(self.x, self.y, self.a, self.b)
def __add__(self, other):
if self.a != other.a or self.b != other.b:
raise TypeError('Points {}, {} are not on the same curve.'.format(self, other))
# if self.x is None, then the self point is infinity point.
if self.x is None:
return other
if other.x is None:
return self
# add this sentence for a straight line that can't reach zero point.
# this is temp programme
return self.__class__(None, None, self.a, self.b)
def __eq__(self, other):
return self.x == other.x and self.y == other.y \
and self.a == other.a and self.b == other.b
def __ne__(self, other):
# this is my answer,but it is error. oh no, I am a rookie
# oh, I found my error, the function __eq__() requires only one parameter
# but I give it two. "==" and self.__eq__(..) is equivalent.
# return not self.__eq__(self, other)
return not (self == other)
def onCurve(x, y):
return y**2 == x**3 + 5 * x + 7
if __name__ == '__main__':
a = Point(-1, -1, 5, 7)
b = Point(-1, 1, 5, 7)
inf = Point(None, None, 5, 7)
print(a + inf)
print(a + b)
测试
Point(-1, -1)_5_7
Point(infinity)
[Finished in 406ms]
练习3
p38
代码实现
class Point():
...
if self.x == other.x and self.y != other.y:
return self.__class__(None, None, self.a, self.b)
练习4
p40
代码实现
if __name__ == '__main__':
x1, y1 = 2, 5
x2, y2 = -1, -1
s = (y2 - y1) / (x2 - x1)
x3 = s ** 2 - x1 - x2
y3 = s * (x1 - x3) - y1
print("({}, {})".format(x3, y3))
运行结果
(3.0, -7.0)
[Finished in 250ms]
练习5
p40
实现x1 != x2 时的点加法
代码实现
class Point():
...
def __add__(self, other):
...
if self.x != other.x:
s = (other.y - self.y) / (other.x - self.x)
x3 = s**2 - self.x - other.x
y3 = s * (self.x - x3) - self.y
return self.__class__(x3, y3, self.a, self.b)
if __name__ == '__main__':
a = Point(x=3, y=7, a=5, b=7)
b = Point(x=-1, y=-1, a=5, b=7)
print(a + b, Point(x=2, y=-5, a=5, b=7))
运行结果
Point(2.0, -5.0)_5_7 Point(2, -5)_5_7
[Finished in 270ms]
练习6
p42
注意: 书中这里给的点是(-1,-1)
代码实现
if __name__ == '__main__':
a, b = 5, 7
x1, y1 = -1, -1
s = (3 * x1**2 + a) / (2 * y1)
x3 = s ** 2 - 2 * x1
y3 = s * (x1 - x3) - y1
print("({}, {})".format(x3, y3))
运行结果
(18.0, 77.0)
[Finished in 259ms]
练习7
p42
实现p1 = p2 时的点加法
代码实现
class Point():
...
def __add__(self, other):
...
# this is for P1 = P2
if self.x == other.x and self.y == other.y:
s = (3 * self.x**2 + self.a) / (2 * self.y)
x3 = s ** 2 - 2 * self.x
y3 = s * (self.x - x3) - self.y
return self.__class__(x3, y3, self.a, self.b)
if __name__ == '__main__':
a = Point(x=-1, y=-1, a=5, b=7)
b = Point(x=-1, y=-1, a=5, b=7)
print(a + b)
运行结果
Point(18.0, 77.0)_5_7
[Finished in 251ms]
本章完整代码
这里为了将所有代码都放在一个文件中, 所以相比参考答案做了一点修改
# -*- coding: utf-8 -*-
# @Author: 从化北(喵星人)
# @Date: 2021-12-20 21:31:48
# @Last Modified by: 从化北
# @Last Modified time: 2021-12-21 11:21:59
from unittest import TestSuite, TextTestRunner, TestCase
def run(test):
suite = TestSuite()
suite.addTest(test)
TextTestRunner().run(suite)
class Point():
def __init__(self, x, y, a, b):
self.x = x
self.y = y
self.a = a
self.b = b
# if the point is infinity point , return null
if self.x is None and self.y is None:
return
if self.y ** 2 != self.x ** 3 + a * x + b:
raise ValueError('({},{}) is not on the curve'.format(x, y))
def __repr__(self):
if self.x == None:
return "Point(infinity)"
return "Point({}, {})_{}_{}".format(self.x, self.y, self.a, self.b)
def __add__(self, other):
# premise verification
if self.a != other.a or self.b != other.b:
raise TypeError('Points {}, {} are not on the same curve.'.format(self, other))
# drop this notes: if self.x is None, then the self point is infinity point.
# this is in order to have an infinity point situation
if self.x is None:
return other
if other.x is None:
return self
if self.x == other.x and self.y != other.y:
return self.__class__(None, None, self.a, self.b)
# this is for P1 = P2
if self.x == other.x and self.y == other.y:
s = (3 * self.x**2 + self.a) / (2 * self.y)
x3 = s ** 2 - 2 * self.x
y3 = s * (self.x - x3) - self.y
return self.__class__(x3, y3, self.a, self.b)
# this is to deal with a special case that is P1 = P2 and there y coordinate is 0
if self == other and self.y == 0 * self.x:
return self.__class__(None, None, self.a, self.b)
# this is for x1 != x2
if self.x != other.x:
s = (other.y - self.y) / (other.x - self.x)
x3 = s**2 - self.x - other.x
y3 = s * (self.x - x3) - self.y
return self.__class__(x3, y3, self.a, self.b)
def __eq__(self, other):
return self.x == other.x and self.y == other.y \
and self.a == other.a and self.b == other.b
def __ne__(self, other):
# this is my answer,but it is error. oh no, I am a rookie
# oh, I found my error, the function __eq__() requires only one parameter
# but I give it two. "==" and self.__eq__(..) is equivalent.
# return not self.__eq__(self, other)
return not (self == other)
class PointTest(TestCase):
def test_ne(self):
a = Point(x=3, y=-7, a=5, b=7)
b = Point(x=18, y=77, a=5, b=7)
self.assertTrue(a != b)
self.assertFalse(a != a)
def test_add0(self):
a = Point(x=None, y=None, a=5, b=7)
b = Point(x=2, y=5, a=5, b=7)
c = Point(x=2, y=-5, a=5, b=7)
self.assertEqual(a + b, b)
self.assertEqual(b + a, b)
self.assertEqual(b + c, a)
def test_add1(self):
a = Point(x=3, y=7, a=5, b=7)
b = Point(x=-1, y=-1, a=5, b=7)
self.assertEqual(a + b, Point(x=2, y=-5, a=5, b=7))
def test_add2(self):
a = Point(x=-1, y=-1, a=5, b=7)
self.assertEqual(a + a, Point(x=18, y=77, a=5, b=7))
def onCurve(x, y):
return y**2 == x**3 + 5 * x + 7
if __name__ == '__main__':
run(PointTest("test_ne"))
run(PointTest("test_add0"))
run(PointTest("test_add1"))
run(PointTest("test_add2"))
测试结果
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
[Finished in 287ms]