Skip to content

Commit fc11345

Browse files
authored
🚫🥒 do not pickle the unpickleable RWLock (#199)
* 🚫🥒 do not pickle the unpickleable RWLock * As requested, acquired the lock before copying PointJacobi. When failing to acquire the lock, it now returns None. Think that's fine or prefer something else? Added `__ne__` for CurveFp. I think `test_inaquality_points_diff_types` from test_ellipticcurve.py was not actually testing equality. Because there was no `__ne__`, it was falling back to identity comparison, causing the test to pass. Now that there's a `__ne__`, it was getting NotImplemented which surprisingly bool casts to True. I changed the `__eq__` to return False for different types. Fix typo in `test_inaquality_points_diff_types` name. As requested, ran black on modified files. It reformmated some lines I hadn't modified. * ran black with `--line-length 79` as configured in travis-ci for the project * Revert to returning NotImplemented. For __ne__ use == instead of __eq__ so it handles NotImplemented when the types are different. Remove the not needed state declaration.
1 parent a776084 commit fc11345

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

src/ecdsa/ellipticcurve.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ def __eq__(self, other):
101101
)
102102
return NotImplemented
103103

104+
def __ne__(self, other):
105+
return not (self == other)
106+
104107
def __hash__(self):
105108
return hash((self.__p, self.__a, self.__b))
106109

@@ -185,6 +188,19 @@ def __init__(self, curve, x, y, z, order=None, generator=False):
185188
doubler = doubler.double().scale()
186189
self.__precompute.append((doubler.x(), doubler.y()))
187190

191+
def __getstate__(self):
192+
try:
193+
self._scale_lock.reader_acquire()
194+
state = self.__dict__.copy()
195+
finally:
196+
self._scale_lock.reader_release()
197+
del state["_scale_lock"]
198+
return state
199+
200+
def __setstate__(self, state):
201+
self.__dict__.update(state)
202+
self._scale_lock = RWLock()
203+
188204
def __eq__(self, other):
189205
"""Compare two points with each-other."""
190206
try:

src/ecdsa/test_ellipticcurve.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,6 @@ def test_inequality_points(self):
195195
p = Point(c, 100, 100, 100)
196196
self.assertNotEqual(self.g_23, p)
197197

198-
def test_inaquality_points_diff_types(self):
198+
def test_inequality_points_diff_types(self):
199199
c = CurveFp(100, -3, 100)
200200
self.assertNotEqual(self.g_23, c)

src/ecdsa/test_jacobi.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import pickle
2+
13
try:
24
import unittest2 as unittest
35
except ImportError:
@@ -6,7 +8,7 @@
68
import hypothesis.strategies as st
79
from hypothesis import given, assume, settings, example
810

9-
from .ellipticcurve import Point, PointJacobi, INFINITY
11+
from .ellipticcurve import CurveFp, Point, PointJacobi, INFINITY
1012
from .ecdsa import generator_256, curve_256, generator_224
1113
from .numbertheory import inverse_mod
1214

@@ -384,3 +386,12 @@ def test_mul_add_large(self):
384386
self.assertEqual(
385387
j_g * (0xFF00 + 255 * 0xF0F0), j_g.mul_add(0xFF00, b, 0xF0F0)
386388
)
389+
390+
def test_equality(self):
391+
pj1 = PointJacobi(curve=CurveFp(23, 1, 1, 1), x=2, y=3, z=1, order=1)
392+
pj2 = PointJacobi(curve=CurveFp(23, 1, 1, 1), x=2, y=3, z=1, order=1)
393+
self.assertEqual(pj1, pj2)
394+
395+
def test_pickle(self):
396+
pj = PointJacobi(curve=CurveFp(23, 1, 1, 1), x=2, y=3, z=1, order=1)
397+
self.assertEqual(pickle.loads(pickle.dumps(pj)), pj)

0 commit comments

Comments
 (0)