11from __future__ import division
22
33from six import PY2
4- from . import der , ecdsa , ellipticcurve
4+ from . import der , ecdsa , ellipticcurve , eddsa
55from .util import orderlen , number_to_string , string_to_number
6- from ._compat import normalise_bytes
6+ from ._compat import normalise_bytes , bit_length
77
88
99# orderlen was defined in this module previously, so keep it in __all__,
3333 "BRAINPOOLP512r1" ,
3434 "PRIME_FIELD_OID" ,
3535 "CHARACTERISTIC_TWO_FIELD_OID" ,
36+ "Ed25519" ,
37+ "Ed448" ,
3638]
3739
3840
@@ -51,8 +53,16 @@ def __init__(self, name, curve, generator, oid, openssl_name=None):
5153 self .curve = curve
5254 self .generator = generator
5355 self .order = generator .order ()
54- self .baselen = orderlen (self .order )
55- self .verifying_key_length = 2 * orderlen (curve .p ())
56+ if isinstance (curve , ellipticcurve .CurveEdTw ):
57+ # EdDSA keys are special in that both private and public
58+ # are the same size (as it's defined only with compressed points)
59+
60+ # +1 for the sign bit and then round up
61+ self .baselen = (bit_length (curve .p ()) + 1 + 7 ) // 8
62+ self .verifying_key_length = self .baselen
63+ else :
64+ self .baselen = orderlen (self .order )
65+ self .verifying_key_length = 2 * orderlen (curve .p ())
5666 self .signature_length = 2 * self .baselen
5767 self .oid = oid
5868 if oid :
@@ -90,13 +100,23 @@ def to_der(self, encoding=None, point_encoding="uncompressed"):
90100 else :
91101 encoding = "explicit"
92102
103+ if encoding not in ("named_curve" , "explicit" ):
104+ raise ValueError (
105+ "Only 'named_curve' and 'explicit' encodings supported"
106+ )
107+
93108 if encoding == "named_curve" :
94109 if not self .oid :
95110 raise UnknownCurveError (
96111 "Can't encode curve using named_curve encoding without "
97112 "associated curve OID"
98113 )
99114 return der .encode_oid (* self .oid )
115+ elif isinstance (self .curve , ellipticcurve .CurveEdTw ):
116+ assert encoding == "explicit"
117+ raise UnknownCurveError (
118+ "Twisted Edwards curves don't support explicit encoding"
119+ )
100120
101121 # encode the ECParameters sequence
102122 curve_p = self .curve .p ()
@@ -408,6 +428,16 @@ def from_pem(cls, string, valid_encodings=None):
408428)
409429
410430
431+ Ed25519 = Curve (
432+ "Ed25519" , eddsa .curve_ed25519 , eddsa .generator_ed25519 , (1 , 3 , 101 , 112 ),
433+ )
434+
435+
436+ Ed448 = Curve (
437+ "Ed448" , eddsa .curve_ed448 , eddsa .generator_ed448 , (1 , 3 , 101 , 113 ),
438+ )
439+
440+
411441# no order in particular, but keep previously added curves first
412442curves = [
413443 NIST192p ,
@@ -427,6 +457,8 @@ def from_pem(cls, string, valid_encodings=None):
427457 SECP112r2 ,
428458 SECP128r1 ,
429459 SECP160r1 ,
460+ Ed25519 ,
461+ Ed448 ,
430462]
431463
432464
0 commit comments