|
8 | 8 | except NameError: |
9 | 9 | buffer = memoryview |
10 | 10 |
|
| 11 | +import os |
11 | 12 | import array |
12 | 13 | import pytest |
13 | 14 | import hashlib |
|
23 | 24 | sigdecode_strings, |
24 | 25 | ) |
25 | 26 | from .curves import NIST256p, Curve, BRAINPOOLP160r1 |
26 | | -from .ellipticcurve import Point |
| 27 | +from .ellipticcurve import Point, PointJacobi, CurveFp, INFINITY |
27 | 28 | from .ecdsa import generator_brainpoolp160r1 |
28 | 29 |
|
29 | 30 |
|
@@ -296,6 +297,59 @@ def test_inequality_on_signing_keys_not_implemented(self): |
296 | 297 | self.assertNotEqual(self.sk1, None) |
297 | 298 |
|
298 | 299 |
|
| 300 | +class TestTrivialCurve(unittest.TestCase): |
| 301 | + @classmethod |
| 302 | + def setUpClass(cls): |
| 303 | + # To test what happens with r or s in signing happens to be zero we |
| 304 | + # need to find a scalar that creates one of the points on a curve that |
| 305 | + # has x coordinate equal to zero. |
| 306 | + # Even for secp112r2 curve that's non trivial so use this toy |
| 307 | + # curve, for which we can iterate over all points quickly |
| 308 | + curve = CurveFp(163, 84, 58) |
| 309 | + gen = PointJacobi(curve, 2, 87, 1, 167, generator=True) |
| 310 | + |
| 311 | + cls.toy_curve = Curve("toy_p8", curve, gen, (1, 2, 0)) |
| 312 | + |
| 313 | + cls.sk = SigningKey.from_secret_exponent( |
| 314 | + 140, cls.toy_curve, hashfunc=hashlib.sha1, |
| 315 | + ) |
| 316 | + |
| 317 | + def test_generator_sanity(self): |
| 318 | + gen = self.toy_curve.generator |
| 319 | + |
| 320 | + self.assertEqual(gen * gen.order(), INFINITY) |
| 321 | + |
| 322 | + def test_public_key_sanity(self): |
| 323 | + self.assertEqual(self.sk.verifying_key.to_string(), b"\x98\x1e") |
| 324 | + |
| 325 | + def test_deterministic_sign(self): |
| 326 | + sig = self.sk.sign_deterministic(b"message") |
| 327 | + |
| 328 | + self.assertEqual(sig, b"-.") |
| 329 | + |
| 330 | + self.assertTrue(self.sk.verifying_key.verify(sig, b"message")) |
| 331 | + |
| 332 | + def test_deterministic_sign_random_message(self): |
| 333 | + msg = os.urandom(32) |
| 334 | + sig = self.sk.sign_deterministic(msg) |
| 335 | + self.assertEqual(len(sig), 2) |
| 336 | + self.assertTrue(self.sk.verifying_key.verify(sig, msg)) |
| 337 | + |
| 338 | + def test_deterministic_sign_that_rises_R_zero_error(self): |
| 339 | + # the raised RSZeroError is caught and handled internally by |
| 340 | + # sign_deterministic methods |
| 341 | + msg = b"\x00\x4f" |
| 342 | + sig = self.sk.sign_deterministic(msg) |
| 343 | + self.assertEqual(sig, b"\x36\x9e") |
| 344 | + self.assertTrue(self.sk.verifying_key.verify(sig, msg)) |
| 345 | + |
| 346 | + def test_deterministic_sign_that_rises_S_zero_error(self): |
| 347 | + msg = b"\x01\x6d" |
| 348 | + sig = self.sk.sign_deterministic(msg) |
| 349 | + self.assertEqual(sig, b"\x49\x6c") |
| 350 | + self.assertTrue(self.sk.verifying_key.verify(sig, msg)) |
| 351 | + |
| 352 | + |
299 | 353 | # test VerifyingKey.verify() |
300 | 354 | prv_key_str = ( |
301 | 355 | "-----BEGIN EC PRIVATE KEY-----\n" |
|
0 commit comments