Skip to content

Commit 3d00b32

Browse files
committed
work with curves that have x=0, y=0 as point on the curve
1 parent 8254038 commit 3d00b32

File tree

3 files changed

+191
-26
lines changed

3 files changed

+191
-26
lines changed

src/ecdsa/ellipticcurve.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ def __eq__(self, other):
633633
"""
634634
x1, y1, z1 = self.__coords
635635
if other is INFINITY:
636-
return (not x1 and not y1) or not z1
636+
return not z1
637637
if isinstance(other, Point):
638638
x2, y2, z2 = other.x(), other.y(), 1
639639
elif isinstance(other, PointJacobi):
@@ -723,8 +723,9 @@ def scale(self):
723723

724724
def to_affine(self):
725725
"""Return point in affine form."""
726-
_, y, z = self.__coords
727-
if not y or not z:
726+
_, _, z = self.__coords
727+
p = self.__curve.p()
728+
if not (z % p):
728729
return INFINITY
729730
self.scale()
730731
x, y, z = self.__coords
@@ -760,7 +761,7 @@ def _double_with_z_1(self, X1, Y1, p, a):
760761
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-mdbl-2007-bl
761762
XX, YY = X1 * X1 % p, Y1 * Y1 % p
762763
if not YY:
763-
return 0, 0, 1
764+
return 0, 0, 0
764765
YYYY = YY * YY % p
765766
S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p
766767
M = 3 * XX + a
@@ -774,13 +775,13 @@ def _double(self, X1, Y1, Z1, p, a):
774775
"""Add a point to itself, arbitrary z."""
775776
if Z1 == 1:
776777
return self._double_with_z_1(X1, Y1, p, a)
777-
if not Y1 or not Z1:
778-
return 0, 0, 1
778+
if not Z1:
779+
return 0, 0, 0
779780
# after:
780781
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
781782
XX, YY = X1 * X1 % p, Y1 * Y1 % p
782783
if not YY:
783-
return 0, 0, 1
784+
return 0, 0, 0
784785
YYYY = YY * YY % p
785786
ZZ = Z1 * Z1 % p
786787
S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p
@@ -796,14 +797,14 @@ def double(self):
796797
"""Add a point to itself."""
797798
X1, Y1, Z1 = self.__coords
798799

799-
if not Y1:
800+
if not Z1:
800801
return INFINITY
801802

802803
p, a = self.__curve.p(), self.__curve.a()
803804

804805
X3, Y3, Z3 = self._double(X1, Y1, Z1, p, a)
805806

806-
if not Y3 and not X3:
807+
if not Z3:
807808
return INFINITY
808809
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
809810

@@ -887,9 +888,9 @@ def __radd__(self, other):
887888

888889
def _add(self, X1, Y1, Z1, X2, Y2, Z2, p):
889890
"""add two points, select fastest method."""
890-
if (not X1 and not Y1) or not Z1:
891+
if not Z1:
891892
return X2 % p, Y2 % p, Z2 % p
892-
if (not X2 and not Y2) or not Z2:
893+
if not Z2:
893894
return X1 % p, Y1 % p, Z1 % p
894895
if Z1 == Z2:
895896
if Z1 == 1:
@@ -918,7 +919,7 @@ def __add__(self, other):
918919

919920
X3, Y3, Z3 = self._add(X1, Y1, Z1, X2, Y2, Z2, p)
920921

921-
if (not X3 and not Y3) or not Z3:
922+
if not Z3:
922923
return INFINITY
923924
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
924925

@@ -928,7 +929,7 @@ def __rmul__(self, other):
928929

929930
def _mul_precompute(self, other):
930931
"""Multiply point by integer with precomputation table."""
931-
X3, Y3, Z3, p = 0, 0, 1, self.__curve.p()
932+
X3, Y3, Z3, p = 0, 0, 0, self.__curve.p()
932933
_add = self._add
933934
for X2, Y2 in self.__precompute:
934935
if other % 2:
@@ -941,7 +942,7 @@ def _mul_precompute(self, other):
941942
else:
942943
other //= 2
943944

944-
if not Y3 or not Z3:
945+
if not Z3:
945946
return INFINITY
946947
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
947948

@@ -960,7 +961,7 @@ def __mul__(self, other):
960961

961962
self = self.scale()
962963
X2, Y2, _ = self.__coords
963-
X3, Y3, Z3 = 0, 0, 1
964+
X3, Y3, Z3 = 0, 0, 0
964965
p, a = self.__curve.p(), self.__curve.a()
965966
_double = self._double
966967
_add = self._add
@@ -973,7 +974,7 @@ def __mul__(self, other):
973974
elif i > 0:
974975
X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
975976

976-
if (not X3 and not Y3) or not Z3:
977+
if not Z3:
977978
return INFINITY
978979

979980
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
@@ -1002,7 +1003,7 @@ def mul_add(self, self_mul, other, other_mul):
10021003
other_mul = other_mul % self.__order
10031004

10041005
# (X3, Y3, Z3) is the accumulator
1005-
X3, Y3, Z3 = 0, 0, 1
1006+
X3, Y3, Z3 = 0, 0, 0
10061007
p, a = self.__curve.p(), self.__curve.a()
10071008

10081009
# as we have 6 unique points to work with, we can't scale all of them,
@@ -1026,7 +1027,7 @@ def mul_add(self, self_mul, other, other_mul):
10261027
# when the self and other sum to infinity, we need to add them
10271028
# one by one to get correct result but as that's very unlikely to
10281029
# happen in regular operation, we don't need to optimise this case
1029-
if not pApB_Y or not pApB_Z:
1030+
if not pApB_Z:
10301031
return self * self_mul + other * other_mul
10311032

10321033
# gmp object creation has cumulatively higher overhead than the
@@ -1071,7 +1072,7 @@ def mul_add(self, self_mul, other, other_mul):
10711072
assert B > 0
10721073
X3, Y3, Z3 = _add(X3, Y3, Z3, pApB_X, pApB_Y, pApB_Z, p)
10731074

1074-
if (not X3 and not Y3) or not Z3:
1075+
if not Z3:
10751076
return INFINITY
10761077

10771078
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
@@ -1155,6 +1156,8 @@ def __eq__(self, other):
11551156
11561157
Note: only points that lay on the same curve can be equal.
11571158
"""
1159+
if other is INFINITY:
1160+
return self.__x is None or self.__y is None
11581161
if isinstance(other, Point):
11591162
return (
11601163
self.__curve == other.__curve

src/ecdsa/test_ellipticcurve.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@ def test_inequality_points_diff_types(self):
251251
c = CurveFp(100, -3, 100)
252252
self.assertNotEqual(self.g_23, c)
253253

254+
def test_inequality_diff_y(self):
255+
p1 = Point(self.c_23, 6, 4)
256+
p2 = Point(self.c_23, 6, 19)
257+
258+
self.assertNotEqual(p1, p2)
259+
254260
def test_to_bytes_from_bytes(self):
255261
p = Point(self.c_23, 3, 10)
256262

0 commit comments

Comments
 (0)