Skip to content

Commit 6c426b9

Browse files
authored
Merge pull request #374 from tlsfuzzer/bad_mul
Make base multiplication (not Jacobi) correct
2 parents 9b11104 + 8c5704e commit 6c426b9

2 files changed

Lines changed: 40 additions & 31 deletions

File tree

src/ecdsa/ellipticcurve.py

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,14 +1185,15 @@ def __add__(self, other):
11851185
if self == INFINITY:
11861186
return other
11871187
assert self.__curve == other.__curve
1188-
if self.__x == other.__x:
1189-
if (self.__y + other.__y) % self.__curve.p() == 0:
1188+
1189+
p = self.__curve.p()
1190+
1191+
if (self.__x - other.__x) % p == 0:
1192+
if (self.__y + other.__y) % p == 0:
11901193
return INFINITY
11911194
else:
11921195
return self.double()
11931196

1194-
p = self.__curve.p()
1195-
11961197
l = (
11971198
(other.__y - self.__y)
11981199
* numbertheory.inverse_mod(other.__x - self.__x, p)
@@ -1206,13 +1207,6 @@ def __add__(self, other):
12061207
def __mul__(self, other):
12071208
"""Multiply a point by an integer."""
12081209

1209-
def leftmost_bit(x):
1210-
assert x > 0
1211-
result = 1
1212-
while result <= x:
1213-
result = 2 * result
1214-
return result // 2
1215-
12161210
e = other
12171211
if e == 0 or (self.__order and e % self.__order == 0):
12181212
return INFINITY
@@ -1221,26 +1215,14 @@ def leftmost_bit(x):
12211215
if e < 0:
12221216
return (-self) * (-e)
12231217

1224-
# From X9.62 D.3.2:
1225-
1226-
e3 = 3 * e
1227-
negative_self = Point(
1228-
self.__curve,
1229-
self.__x,
1230-
(-self.__y) % self.__curve.p(),
1231-
self.__order,
1232-
)
1233-
i = leftmost_bit(e3) // 2
1234-
result = self
1235-
# print("Multiplying %s by %d (e3 = %d):" % (self, other, e3))
1236-
while i > 1:
1237-
result = result.double()
1238-
if (e3 & i) != 0 and (e & i) == 0:
1239-
result = result + self
1240-
if (e3 & i) == 0 and (e & i) != 0:
1241-
result = result + negative_self
1242-
# print(". . . i = %d, result = %s" % ( i, result ))
1243-
i = i // 2
1218+
i = e
1219+
temp = self
1220+
result = INFINITY
1221+
while i:
1222+
if i % 2 == 1:
1223+
result = result + temp
1224+
temp = temp.double()
1225+
i = i >> 1
12441226

12451227
return result
12461228

@@ -1289,6 +1271,9 @@ def curve(self):
12891271
def order(self):
12901272
return self.__order
12911273

1274+
def to_affine(self):
1275+
return self
1276+
12921277

12931278
class PointEdwards(AbstractPoint):
12941279
"""Point on Twisted Edwards curve.

src/ecdsa/test_ellipticcurve.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,20 @@ def test_add_and_mult_equivalence(p, m, check):
7171
assert p * m == check
7272

7373

74+
# from https://github.com/tlsfuzzer/python-ecdsa/issues/373
75+
curve = CurveFp(p=31, a=2, b=3)
76+
point = Point(curve, 6, 18)
77+
78+
79+
@pytest.mark.parametrize(
80+
"p, m, check",
81+
[(point, n, exp) for n, exp in enumerate(add_n_times(point, 16))],
82+
ids=["p31 test with mult {0}".format(i) for i in range(17)],
83+
)
84+
def test_add_and_mult_equivalence_2(p, m, check):
85+
assert p * m == check
86+
87+
7488
class TestCurve(unittest.TestCase):
7589
@classmethod
7690
def setUpClass(cls):
@@ -146,6 +160,16 @@ def setUpClass(cls):
146160
cls.c192 = CurveFp(p, -3, b)
147161
cls.p192 = Point(cls.c192, Gx, Gy, r)
148162

163+
def test_points_with_different_curves(self):
164+
with self.assertRaises(AssertionError):
165+
self.g_23 + self.p192
166+
167+
def test_add_point_to_negative(self):
168+
self.assertIs(self.g_23 + (-self.g_23), INFINITY)
169+
170+
def test_add_point_to_explicit_negative(self):
171+
self.assertIs(self.g_23 + Point(self.c_23, 13, -7), INFINITY)
172+
149173
def test_p192(self):
150174
# Checking against some sample computations presented
151175
# in X9.62:

0 commit comments

Comments
 (0)