@@ -633,7 +633,7 @@ def __eq__(self, other):
633
633
"""
634
634
x1 , y1 , z1 = self .__coords
635
635
if other is INFINITY :
636
- return not y1 or not z1
636
+ return not z1
637
637
if isinstance (other , Point ):
638
638
x2 , y2 , z2 = other .x (), other .y (), 1
639
639
elif isinstance (other , PointJacobi ):
@@ -723,11 +723,13 @@ def scale(self):
723
723
724
724
def to_affine (self ):
725
725
"""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 ):
728
729
return INFINITY
729
730
self .scale ()
730
731
x , y , z = self .__coords
732
+ assert z == 1
731
733
return Point (self .__curve , x , y , self .__order )
732
734
733
735
@staticmethod
@@ -759,7 +761,7 @@ def _double_with_z_1(self, X1, Y1, p, a):
759
761
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-mdbl-2007-bl
760
762
XX , YY = X1 * X1 % p , Y1 * Y1 % p
761
763
if not YY :
762
- return 0 , 0 , 1
764
+ return 0 , 0 , 0
763
765
YYYY = YY * YY % p
764
766
S = 2 * ((X1 + YY ) ** 2 - XX - YYYY ) % p
765
767
M = 3 * XX + a
@@ -773,13 +775,13 @@ def _double(self, X1, Y1, Z1, p, a):
773
775
"""Add a point to itself, arbitrary z."""
774
776
if Z1 == 1 :
775
777
return self ._double_with_z_1 (X1 , Y1 , p , a )
776
- if not Y1 or not Z1 :
777
- return 0 , 0 , 1
778
+ if not Z1 :
779
+ return 0 , 0 , 0
778
780
# after:
779
781
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
780
782
XX , YY = X1 * X1 % p , Y1 * Y1 % p
781
783
if not YY :
782
- return 0 , 0 , 1
784
+ return 0 , 0 , 0
783
785
YYYY = YY * YY % p
784
786
ZZ = Z1 * Z1 % p
785
787
S = 2 * ((X1 + YY ) ** 2 - XX - YYYY ) % p
@@ -795,14 +797,14 @@ def double(self):
795
797
"""Add a point to itself."""
796
798
X1 , Y1 , Z1 = self .__coords
797
799
798
- if not Y1 :
800
+ if not Z1 :
799
801
return INFINITY
800
802
801
803
p , a = self .__curve .p (), self .__curve .a ()
802
804
803
805
X3 , Y3 , Z3 = self ._double (X1 , Y1 , Z1 , p , a )
804
806
805
- if not Y3 or not Z3 :
807
+ if not Z3 :
806
808
return INFINITY
807
809
return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
808
810
@@ -886,10 +888,10 @@ def __radd__(self, other):
886
888
887
889
def _add (self , X1 , Y1 , Z1 , X2 , Y2 , Z2 , p ):
888
890
"""add two points, select fastest method."""
889
- if not Y1 or not Z1 :
890
- return X2 , Y2 , Z2
891
- if not Y2 or not Z2 :
892
- return X1 , Y1 , Z1
891
+ if not Z1 :
892
+ return X2 % p , Y2 % p , Z2 % p
893
+ if not Z2 :
894
+ return X1 % p , Y1 % p , Z1 % p
893
895
if Z1 == Z2 :
894
896
if Z1 == 1 :
895
897
return self ._add_with_z_1 (X1 , Y1 , X2 , Y2 , p )
@@ -917,7 +919,7 @@ def __add__(self, other):
917
919
918
920
X3 , Y3 , Z3 = self ._add (X1 , Y1 , Z1 , X2 , Y2 , Z2 , p )
919
921
920
- if not Y3 or not Z3 :
922
+ if not Z3 :
921
923
return INFINITY
922
924
return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
923
925
@@ -927,7 +929,7 @@ def __rmul__(self, other):
927
929
928
930
def _mul_precompute (self , other ):
929
931
"""Multiply point by integer with precomputation table."""
930
- X3 , Y3 , Z3 , p = 0 , 0 , 1 , self .__curve .p ()
932
+ X3 , Y3 , Z3 , p = 0 , 0 , 0 , self .__curve .p ()
931
933
_add = self ._add
932
934
for X2 , Y2 in self .__precompute :
933
935
if other % 2 :
@@ -940,7 +942,7 @@ def _mul_precompute(self, other):
940
942
else :
941
943
other //= 2
942
944
943
- if not Y3 or not Z3 :
945
+ if not Z3 :
944
946
return INFINITY
945
947
return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
946
948
@@ -959,7 +961,7 @@ def __mul__(self, other):
959
961
960
962
self = self .scale ()
961
963
X2 , Y2 , _ = self .__coords
962
- X3 , Y3 , Z3 = 0 , 0 , 1
964
+ X3 , Y3 , Z3 = 0 , 0 , 0
963
965
p , a = self .__curve .p (), self .__curve .a ()
964
966
_double = self ._double
965
967
_add = self ._add
@@ -972,7 +974,7 @@ def __mul__(self, other):
972
974
elif i > 0 :
973
975
X3 , Y3 , Z3 = _add (X3 , Y3 , Z3 , X2 , Y2 , 1 , p )
974
976
975
- if not Y3 or not Z3 :
977
+ if not Z3 :
976
978
return INFINITY
977
979
978
980
return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
@@ -1001,7 +1003,7 @@ def mul_add(self, self_mul, other, other_mul):
1001
1003
other_mul = other_mul % self .__order
1002
1004
1003
1005
# (X3, Y3, Z3) is the accumulator
1004
- X3 , Y3 , Z3 = 0 , 0 , 1
1006
+ X3 , Y3 , Z3 = 0 , 0 , 0
1005
1007
p , a = self .__curve .p (), self .__curve .a ()
1006
1008
1007
1009
# as we have 6 unique points to work with, we can't scale all of them,
@@ -1025,7 +1027,7 @@ def mul_add(self, self_mul, other, other_mul):
1025
1027
# when the self and other sum to infinity, we need to add them
1026
1028
# one by one to get correct result but as that's very unlikely to
1027
1029
# happen in regular operation, we don't need to optimise this case
1028
- if not pApB_Y or not pApB_Z :
1030
+ if not pApB_Z :
1029
1031
return self * self_mul + other * other_mul
1030
1032
1031
1033
# gmp object creation has cumulatively higher overhead than the
@@ -1070,7 +1072,7 @@ def mul_add(self, self_mul, other, other_mul):
1070
1072
assert B > 0
1071
1073
X3 , Y3 , Z3 = _add (X3 , Y3 , Z3 , pApB_X , pApB_Y , pApB_Z , p )
1072
1074
1073
- if not Y3 or not Z3 :
1075
+ if not Z3 :
1074
1076
return INFINITY
1075
1077
1076
1078
return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
@@ -1154,6 +1156,8 @@ def __eq__(self, other):
1154
1156
1155
1157
Note: only points that lay on the same curve can be equal.
1156
1158
"""
1159
+ if other is INFINITY :
1160
+ return self .__x is None or self .__y is None
1157
1161
if isinstance (other , Point ):
1158
1162
return (
1159
1163
self .__curve == other .__curve
@@ -1220,7 +1224,12 @@ def leftmost_bit(x):
1220
1224
# From X9.62 D.3.2:
1221
1225
1222
1226
e3 = 3 * e
1223
- negative_self = Point (self .__curve , self .__x , - self .__y , self .__order )
1227
+ negative_self = Point (
1228
+ self .__curve ,
1229
+ self .__x ,
1230
+ (- self .__y ) % self .__curve .p (),
1231
+ self .__order ,
1232
+ )
1224
1233
i = leftmost_bit (e3 ) // 2
1225
1234
result = self
1226
1235
# print("Multiplying %s by %d (e3 = %d):" % (self, other, e3))
@@ -1247,7 +1256,6 @@ def __str__(self):
1247
1256
1248
1257
def double (self ):
1249
1258
"""Return a new point that is twice the old."""
1250
-
1251
1259
if self == INFINITY :
1252
1260
return INFINITY
1253
1261
@@ -1261,6 +1269,9 @@ def double(self):
1261
1269
* numbertheory .inverse_mod (2 * self .__y , p )
1262
1270
) % p
1263
1271
1272
+ if not l :
1273
+ return INFINITY
1274
+
1264
1275
x3 = (l * l - 2 * self .__x ) % p
1265
1276
y3 = (l * (self .__x - x3 ) - self .__y ) % p
1266
1277
0 commit comments