from six import PY2 from . import der, ecdsa, ellipticcurve, eddsa from .util import orderlen, number_to_string, string_to_number from ._compat import normalise_bytes, bit_length
# orderlen was defined in this module previously, so keep it in __all__, # will need to mark it as deprecated later
__all__ = [ "UnknownCurveError", "orderlen", "Curve", "SECP112r1", "SECP112r2", "SECP128r1", "SECP160r1", "NIST192p", "NIST224p", "NIST256p", "NIST384p", "NIST521p", "curves", "find_curve", "curve_by_name", "SECP256k1", "BRAINPOOLP160r1", "BRAINPOOLP160t1", "BRAINPOOLP192r1", "BRAINPOOLP192t1", "BRAINPOOLP224r1", "BRAINPOOLP224t1", "BRAINPOOLP256r1", "BRAINPOOLP256t1", "BRAINPOOLP320r1", "BRAINPOOLP320t1", "BRAINPOOLP384r1", "BRAINPOOLP384t1", "BRAINPOOLP512r1", "BRAINPOOLP512t1", "PRIME_FIELD_OID", "CHARACTERISTIC_TWO_FIELD_OID", "Ed25519", "Ed448",
]
class Curve: def __init__(self, name, curve, generator, oid, openssl_name=None):
self.name = name
self.openssl_name = openssl_name # maybe None
self.curve = curve
self.generator = generator
self.order = generator.order() if isinstance(curve, ellipticcurve.CurveEdTw): # EdDSA keys are special in that both private and public # are the same size (as it's defined only with compressed points)
# +1 for the sign bit and then round up
self.baselen = (bit_length(curve.p()) + 1 + 7) // 8
self.verifying_key_length = self.baselen else:
self.baselen = orderlen(self.order)
self.verifying_key_length = 2 * orderlen(curve.p())
self.signature_length = 2 * self.baselen
self.oid = oid if oid:
self.encoded_oid = der.encode_oid(*oid)
def __eq__(self, other): if isinstance(other, Curve): return (
self.curve == other.curve and self.generator == other.generator
) return NotImplemented
def __ne__(self, other): returnnot self == other
def __repr__(self): return self.name
def to_der(self, encoding=None, point_encoding="uncompressed"): """Serialise the curve parameters to binary string.
:param str encoding: the format to save the curve parameters in.
Default is ``named_curve``, with fallback being the ``explicit`` if the OID isnot set for the curve.
:param str point_encoding: the point encoding of the generator when
explicit curve encoding is used. Ignored for ``named_curve``
format.
:return: DER encoded ECParameters structure
:rtype: bytes """ if encoding isNone: if self.oid:
encoding = "named_curve" else:
encoding = "explicit"
if encoding notin ("named_curve", "explicit"): raise ValueError( "Only 'named_curve' and 'explicit' encodings supported"
)
if encoding == "named_curve": ifnot self.oid: raise UnknownCurveError( "Can't encode curve using named_curve encoding without " "associated curve OID"
) return der.encode_oid(*self.oid) elif isinstance(self.curve, ellipticcurve.CurveEdTw): assert encoding == "explicit" raise UnknownCurveError( "Twisted Edwards curves don't support explicit encoding"
)
def to_pem(self, encoding=None, point_encoding="uncompressed"): """
Serialise the curve parameters to the :term:`PEM` format.
:param str encoding: the format to save the curve parameters in.
Default is ``named_curve``, with fallback being the ``explicit`` if the OID isnot set for the curve.
:param str point_encoding: the point encoding of the generator when
explicit curve encoding is used. Ignored for ``named_curve``
format.
@staticmethod def from_der(data, valid_encodings=None): """Decode the curve parameters from DER file.
:param data: the binary string to decode the parameters from
:type data: :term:`bytes-like object`
:param valid_encodings: set of names of allowed encodings, by default
all (set by passing ``None``), supported ones are ``named_curve`` and ``explicit``
:type valid_encodings: :term:`set-like object` """ ifnot valid_encodings:
valid_encodings = set(("named_curve", "explicit")) ifnot all(i in ["named_curve", "explicit"] for i in valid_encodings): raise ValueError( "Only named_curve and explicit encodings supported"
)
data = normalise_bytes(data) ifnot der.is_sequence(data): if"named_curve"notin valid_encodings: raise der.UnexpectedDER( "named_curve curve parameters not allowed"
)
oid, empty = der.remove_object(data) if empty: raise der.UnexpectedDER("Unexpected data after OID") return find_curve(oid)
if"explicit"notin valid_encodings: raise der.UnexpectedDER("explicit curve parameters not allowed")
seq, empty = der.remove_sequence(data) if empty: raise der.UnexpectedDER( "Unexpected data after ECParameters structure"
) # decode the ECParameters sequence
version, rest = der.remove_integer(seq) if version != 1: raise der.UnexpectedDER("Unknown parameter encoding format")
field_id, rest = der.remove_sequence(rest)
curve, rest = der.remove_sequence(rest)
base_bytes, rest = der.remove_octet_string(rest)
order, rest = der.remove_integer(rest)
cofactor = None if rest: # the ASN.1 specification of ECParameters allows for future # extensions of the sequence, so ignore the remaining bytes
cofactor, _ = der.remove_integer(rest)
# decode the ECParameters.fieldID sequence
field_type, rest = der.remove_object(field_id) if field_type == CHARACTERISTIC_TWO_FIELD_OID: raise UnknownCurveError("Characteristic 2 curves unsupported") if field_type != PRIME_FIELD_OID: raise UnknownCurveError( "Unknown field type: {0}".format(field_type)
)
prime, empty = der.remove_integer(rest) if empty: raise der.UnexpectedDER( "Unexpected data after ECParameters.fieldID.Prime-p element"
)
# decode the ECParameters.curve sequence
curve_a_bytes, rest = der.remove_octet_string(curve)
curve_b_bytes, rest = der.remove_octet_string(rest) # seed can be defined here, but we don't parse it, so ignore `rest`
# if the curve matches one of the well-known ones, use the well-known # one in preference, as it will have the OID and name associated for i in curves: if tmp_curve == i: return i return tmp_curve
@classmethod def from_pem(cls, string, valid_encodings=None): """Decode the curve parameters from PEM file.
:param str string: the text string to decode the parameters from
:param valid_encodings: set of names of allowed encodings, by default
all (set by passing ``None``), supported ones are ``named_curve`` and ``explicit``
:type valid_encodings: :term:`set-like object` """ ifnot PY2 and isinstance(string, str): # pragma: no branch
string = string.encode()
ec_param_index = string.find(b"-----BEGIN EC PARAMETERS-----") if ec_param_index == -1: raise der.UnexpectedDER("EC PARAMETERS PEM header not found")
# no order in particular, but keep previously added curves first
curves = [
NIST192p,
NIST224p,
NIST256p,
NIST384p,
NIST521p,
SECP256k1,
BRAINPOOLP160r1,
BRAINPOOLP192r1,
BRAINPOOLP224r1,
BRAINPOOLP256r1,
BRAINPOOLP320r1,
BRAINPOOLP384r1,
BRAINPOOLP512r1,
SECP112r1,
SECP112r2,
SECP128r1,
SECP160r1,
Ed25519,
Ed448,
BRAINPOOLP160t1,
BRAINPOOLP192t1,
BRAINPOOLP224t1,
BRAINPOOLP256t1,
BRAINPOOLP320t1,
BRAINPOOLP384t1,
BRAINPOOLP512t1,
]
def find_curve(oid_curve): """Select a curve based on its OID
:param tuple[int,...] oid_curve: ASN.1 Object Identifier of the
curve to return, like ``(1, 2, 840, 10045, 3, 1, 7)`` for ``NIST256p``.
:raises UnknownCurveError: When the oid doesn't match any of the supported
curves
:rtype: ~ecdsa.curves.Curve """ for c in curves: if c.oid == oid_curve: return c raise UnknownCurveError( "I don't know about the curve with oid %s." "I only know about these: %s" % (oid_curve, [c.name for c in curves])
)
def curve_by_name(name): """Select a curve based on its name.
Returns a :py:class:`~ecdsa.curves.Curve` object with a ``name`` name.
Note that ``name`` is case-sensitve.
:param str name: Name of the curve to return, like ``NIST256p`` or
``prime256v1``
:raises UnknownCurveError: When the name doesn't match any of the supported
curves
:rtype: ~ecdsa.curves.Curve """ for c in curves: if name == c.name or (c.openssl_name and name == c.openssl_name): return c raise UnknownCurveError( "Curve with name {0!r} unknown, only curves supported: {1}".format(
name, [c.name for c in curves]
)
)
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.33 Sekunden
(vorverarbeitet am 2026-08-23)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.