Skip to content

Commit 2477ea5

Browse files
committed
test for r==0 and s==0 in signature creation
1 parent 533bc74 commit 2477ea5

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

src/ecdsa/test_keys.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
except NameError:
99
buffer = memoryview
1010

11+
import os
1112
import array
1213
import pytest
1314
import hashlib
@@ -23,7 +24,7 @@
2324
sigdecode_strings,
2425
)
2526
from .curves import NIST256p, Curve, BRAINPOOLP160r1
26-
from .ellipticcurve import Point
27+
from .ellipticcurve import Point, PointJacobi, CurveFp, INFINITY
2728
from .ecdsa import generator_brainpoolp160r1
2829

2930

@@ -296,6 +297,59 @@ def test_inequality_on_signing_keys_not_implemented(self):
296297
self.assertNotEqual(self.sk1, None)
297298

298299

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+
299353
# test VerifyingKey.verify()
300354
prv_key_str = (
301355
"-----BEGIN EC PRIVATE KEY-----\n"

0 commit comments

Comments
 (0)