Skip to content

Commit 2d5acf3

Browse files
committed
add support for finding Curves by name
1 parent 522f480 commit 2d5acf3

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

src/ecdsa/curves.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"NIST521p",
2424
"curves",
2525
"find_curve",
26+
"curve_by_name",
2627
"SECP256k1",
2728
"BRAINPOOLP160r1",
2829
"BRAINPOOLP192r1",
@@ -476,3 +477,27 @@ def find_curve(oid_curve):
476477
"I don't know about the curve with oid %s."
477478
"I only know about these: %s" % (oid_curve, [c.name for c in curves])
478479
)
480+
481+
482+
def curve_by_name(name):
483+
"""Select a curve based on its name.
484+
485+
Returns a :py:class:`~ecdsa.curves.Curve` object with a ``name`` name.
486+
Note that ``name`` is case-sensitve.
487+
488+
:param str name: Name of the curve to return, like ``NIST256p`` or
489+
``prime256v1``
490+
491+
:raises UnknownCurveError: When the name doesn't match any of the supported
492+
curves
493+
494+
:rtype: ~ecdsa.curves.Curve
495+
"""
496+
for c in curves:
497+
if name == c.name or (c.openssl_name and name == c.openssl_name):
498+
return c
499+
raise UnknownCurveError(
500+
"Curve with name {0!r} unknown, only curves supported: {1}".format(
501+
name, [c.name for c in curves]
502+
)
503+
)

src/ecdsa/test_curves.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55

66
import base64
77
import pytest
8-
from .curves import Curve, NIST256p, curves, UnknownCurveError, PRIME_FIELD_OID
8+
from .curves import (
9+
Curve,
10+
NIST256p,
11+
curves,
12+
UnknownCurveError,
13+
PRIME_FIELD_OID,
14+
curve_by_name,
15+
)
916
from .ellipticcurve import CurveFp, PointJacobi, CurveEdTw
1017
from . import der
1118
from .util import number_to_string
@@ -288,6 +295,36 @@ def test_decode_malformed_garbage_after_prime(self):
288295
self.assertIn("Prime-p element", str(e.exception))
289296

290297

298+
class TestCurveSearching(unittest.TestCase):
299+
def test_correct_name(self):
300+
c = curve_by_name("NIST256p")
301+
self.assertIs(c, NIST256p)
302+
303+
def test_openssl_name(self):
304+
c = curve_by_name("prime256v1")
305+
self.assertIs(c, NIST256p)
306+
307+
def test_unknown_curve(self):
308+
with self.assertRaises(UnknownCurveError) as e:
309+
curve_by_name("foo bar")
310+
311+
self.assertIn(
312+
"name 'foo bar' unknown, only curves supported: "
313+
"['NIST192p', 'NIST224p'",
314+
str(e.exception),
315+
)
316+
317+
def test_with_None_as_parameter(self):
318+
with self.assertRaises(UnknownCurveError) as e:
319+
curve_by_name(None)
320+
321+
self.assertIn(
322+
"name None unknown, only curves supported: "
323+
"['NIST192p', 'NIST224p'",
324+
str(e.exception),
325+
)
326+
327+
291328
@pytest.mark.parametrize("curve", curves, ids=[i.name for i in curves])
292329
def test_curve_params_encode_decode_named(curve):
293330
ret = Curve.from_der(curve.to_der("named_curve"))

0 commit comments

Comments
 (0)