Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py: 76%
217 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 07:26 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 07:26 +0000
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
5from __future__ import annotations
7import abc
8import typing
10from cryptography import utils
11from cryptography.hazmat._oid import ObjectIdentifier
12from cryptography.hazmat.bindings._rust import openssl as rust_openssl
13from cryptography.hazmat.primitives import _serialization, hashes
14from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
17class EllipticCurveOID:
18 SECP192R1 = ObjectIdentifier("1.2.840.10045.3.1.1")
19 SECP224R1 = ObjectIdentifier("1.3.132.0.33")
20 SECP256K1 = ObjectIdentifier("1.3.132.0.10")
21 SECP256R1 = ObjectIdentifier("1.2.840.10045.3.1.7")
22 SECP384R1 = ObjectIdentifier("1.3.132.0.34")
23 SECP521R1 = ObjectIdentifier("1.3.132.0.35")
24 BRAINPOOLP256R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.7")
25 BRAINPOOLP384R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.11")
26 BRAINPOOLP512R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.13")
27 SECT163K1 = ObjectIdentifier("1.3.132.0.1")
28 SECT163R2 = ObjectIdentifier("1.3.132.0.15")
29 SECT233K1 = ObjectIdentifier("1.3.132.0.26")
30 SECT233R1 = ObjectIdentifier("1.3.132.0.27")
31 SECT283K1 = ObjectIdentifier("1.3.132.0.16")
32 SECT283R1 = ObjectIdentifier("1.3.132.0.17")
33 SECT409K1 = ObjectIdentifier("1.3.132.0.36")
34 SECT409R1 = ObjectIdentifier("1.3.132.0.37")
35 SECT571K1 = ObjectIdentifier("1.3.132.0.38")
36 SECT571R1 = ObjectIdentifier("1.3.132.0.39")
39class EllipticCurve(metaclass=abc.ABCMeta):
40 @property
41 @abc.abstractmethod
42 def name(self) -> str:
43 """
44 The name of the curve. e.g. secp256r1.
45 """
47 @property
48 @abc.abstractmethod
49 def key_size(self) -> int:
50 """
51 Bit size of a secret scalar for the curve.
52 """
55class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta):
56 @property
57 @abc.abstractmethod
58 def algorithm(
59 self,
60 ) -> asym_utils.Prehashed | hashes.HashAlgorithm:
61 """
62 The digest algorithm used with this signature.
63 """
66class EllipticCurvePrivateKey(metaclass=abc.ABCMeta):
67 @abc.abstractmethod
68 def exchange(
69 self, algorithm: ECDH, peer_public_key: EllipticCurvePublicKey
70 ) -> bytes:
71 """
72 Performs a key exchange operation using the provided algorithm with the
73 provided peer's public key.
74 """
76 @abc.abstractmethod
77 def public_key(self) -> EllipticCurvePublicKey:
78 """
79 The EllipticCurvePublicKey for this private key.
80 """
82 @property
83 @abc.abstractmethod
84 def curve(self) -> EllipticCurve:
85 """
86 The EllipticCurve that this key is on.
87 """
89 @property
90 @abc.abstractmethod
91 def key_size(self) -> int:
92 """
93 Bit size of a secret scalar for the curve.
94 """
96 @abc.abstractmethod
97 def sign(
98 self,
99 data: bytes,
100 signature_algorithm: EllipticCurveSignatureAlgorithm,
101 ) -> bytes:
102 """
103 Signs the data
104 """
106 @abc.abstractmethod
107 def private_numbers(self) -> EllipticCurvePrivateNumbers:
108 """
109 Returns an EllipticCurvePrivateNumbers.
110 """
112 @abc.abstractmethod
113 def private_bytes(
114 self,
115 encoding: _serialization.Encoding,
116 format: _serialization.PrivateFormat,
117 encryption_algorithm: _serialization.KeySerializationEncryption,
118 ) -> bytes:
119 """
120 Returns the key serialized as bytes.
121 """
124EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey
125EllipticCurvePrivateKey.register(rust_openssl.ec.ECPrivateKey)
128class EllipticCurvePublicKey(metaclass=abc.ABCMeta):
129 @property
130 @abc.abstractmethod
131 def curve(self) -> EllipticCurve:
132 """
133 The EllipticCurve that this key is on.
134 """
136 @property
137 @abc.abstractmethod
138 def key_size(self) -> int:
139 """
140 Bit size of a secret scalar for the curve.
141 """
143 @abc.abstractmethod
144 def public_numbers(self) -> EllipticCurvePublicNumbers:
145 """
146 Returns an EllipticCurvePublicNumbers.
147 """
149 @abc.abstractmethod
150 def public_bytes(
151 self,
152 encoding: _serialization.Encoding,
153 format: _serialization.PublicFormat,
154 ) -> bytes:
155 """
156 Returns the key serialized as bytes.
157 """
159 @abc.abstractmethod
160 def verify(
161 self,
162 signature: bytes,
163 data: bytes,
164 signature_algorithm: EllipticCurveSignatureAlgorithm,
165 ) -> None:
166 """
167 Verifies the signature of the data.
168 """
170 @classmethod
171 def from_encoded_point(
172 cls, curve: EllipticCurve, data: bytes
173 ) -> EllipticCurvePublicKey:
174 utils._check_bytes("data", data)
176 if not isinstance(curve, EllipticCurve):
177 raise TypeError("curve must be an EllipticCurve instance")
179 if len(data) == 0:
180 raise ValueError("data must not be an empty byte string")
182 if data[0] not in [0x02, 0x03, 0x04]:
183 raise ValueError("Unsupported elliptic curve point type")
185 return rust_openssl.ec.from_public_bytes(curve, data)
187 @abc.abstractmethod
188 def __eq__(self, other: object) -> bool:
189 """
190 Checks equality.
191 """
194EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey
195EllipticCurvePublicKey.register(rust_openssl.ec.ECPublicKey)
198class SECT571R1(EllipticCurve):
199 name = "sect571r1"
200 key_size = 570
203class SECT409R1(EllipticCurve):
204 name = "sect409r1"
205 key_size = 409
208class SECT283R1(EllipticCurve):
209 name = "sect283r1"
210 key_size = 283
213class SECT233R1(EllipticCurve):
214 name = "sect233r1"
215 key_size = 233
218class SECT163R2(EllipticCurve):
219 name = "sect163r2"
220 key_size = 163
223class SECT571K1(EllipticCurve):
224 name = "sect571k1"
225 key_size = 571
228class SECT409K1(EllipticCurve):
229 name = "sect409k1"
230 key_size = 409
233class SECT283K1(EllipticCurve):
234 name = "sect283k1"
235 key_size = 283
238class SECT233K1(EllipticCurve):
239 name = "sect233k1"
240 key_size = 233
243class SECT163K1(EllipticCurve):
244 name = "sect163k1"
245 key_size = 163
248class SECP521R1(EllipticCurve):
249 name = "secp521r1"
250 key_size = 521
253class SECP384R1(EllipticCurve):
254 name = "secp384r1"
255 key_size = 384
258class SECP256R1(EllipticCurve):
259 name = "secp256r1"
260 key_size = 256
263class SECP256K1(EllipticCurve):
264 name = "secp256k1"
265 key_size = 256
268class SECP224R1(EllipticCurve):
269 name = "secp224r1"
270 key_size = 224
273class SECP192R1(EllipticCurve):
274 name = "secp192r1"
275 key_size = 192
278class BrainpoolP256R1(EllipticCurve):
279 name = "brainpoolP256r1"
280 key_size = 256
283class BrainpoolP384R1(EllipticCurve):
284 name = "brainpoolP384r1"
285 key_size = 384
288class BrainpoolP512R1(EllipticCurve):
289 name = "brainpoolP512r1"
290 key_size = 512
293_CURVE_TYPES: dict[str, type[EllipticCurve]] = {
294 "prime192v1": SECP192R1,
295 "prime256v1": SECP256R1,
296 "secp192r1": SECP192R1,
297 "secp224r1": SECP224R1,
298 "secp256r1": SECP256R1,
299 "secp384r1": SECP384R1,
300 "secp521r1": SECP521R1,
301 "secp256k1": SECP256K1,
302 "sect163k1": SECT163K1,
303 "sect233k1": SECT233K1,
304 "sect283k1": SECT283K1,
305 "sect409k1": SECT409K1,
306 "sect571k1": SECT571K1,
307 "sect163r2": SECT163R2,
308 "sect233r1": SECT233R1,
309 "sect283r1": SECT283R1,
310 "sect409r1": SECT409R1,
311 "sect571r1": SECT571R1,
312 "brainpoolP256r1": BrainpoolP256R1,
313 "brainpoolP384r1": BrainpoolP384R1,
314 "brainpoolP512r1": BrainpoolP512R1,
315}
318class ECDSA(EllipticCurveSignatureAlgorithm):
319 def __init__(
320 self,
321 algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
322 ):
323 self._algorithm = algorithm
325 @property
326 def algorithm(
327 self,
328 ) -> asym_utils.Prehashed | hashes.HashAlgorithm:
329 return self._algorithm
332def generate_private_key(
333 curve: EllipticCurve, backend: typing.Any = None
334) -> EllipticCurvePrivateKey:
335 return rust_openssl.ec.generate_private_key(curve)
338def derive_private_key(
339 private_value: int,
340 curve: EllipticCurve,
341 backend: typing.Any = None,
342) -> EllipticCurvePrivateKey:
343 if not isinstance(private_value, int):
344 raise TypeError("private_value must be an integer type.")
346 if private_value <= 0:
347 raise ValueError("private_value must be a positive integer.")
349 if not isinstance(curve, EllipticCurve):
350 raise TypeError("curve must provide the EllipticCurve interface.")
352 return rust_openssl.ec.derive_private_key(private_value, curve)
355class EllipticCurvePublicNumbers:
356 def __init__(self, x: int, y: int, curve: EllipticCurve):
357 if not isinstance(x, int) or not isinstance(y, int):
358 raise TypeError("x and y must be integers.")
360 if not isinstance(curve, EllipticCurve):
361 raise TypeError("curve must provide the EllipticCurve interface.")
363 self._y = y
364 self._x = x
365 self._curve = curve
367 def public_key(self, backend: typing.Any = None) -> EllipticCurvePublicKey:
368 return rust_openssl.ec.from_public_numbers(self)
370 @property
371 def curve(self) -> EllipticCurve:
372 return self._curve
374 @property
375 def x(self) -> int:
376 return self._x
378 @property
379 def y(self) -> int:
380 return self._y
382 def __eq__(self, other: object) -> bool:
383 if not isinstance(other, EllipticCurvePublicNumbers):
384 return NotImplemented
386 return (
387 self.x == other.x
388 and self.y == other.y
389 and self.curve.name == other.curve.name
390 and self.curve.key_size == other.curve.key_size
391 )
393 def __hash__(self) -> int:
394 return hash((self.x, self.y, self.curve.name, self.curve.key_size))
396 def __repr__(self) -> str:
397 return (
398 "<EllipticCurvePublicNumbers(curve={0.curve.name}, x={0.x}, "
399 "y={0.y}>".format(self)
400 )
403class EllipticCurvePrivateNumbers:
404 def __init__(
405 self, private_value: int, public_numbers: EllipticCurvePublicNumbers
406 ):
407 if not isinstance(private_value, int):
408 raise TypeError("private_value must be an integer.")
410 if not isinstance(public_numbers, EllipticCurvePublicNumbers):
411 raise TypeError(
412 "public_numbers must be an EllipticCurvePublicNumbers "
413 "instance."
414 )
416 self._private_value = private_value
417 self._public_numbers = public_numbers
419 def private_key(
420 self, backend: typing.Any = None
421 ) -> EllipticCurvePrivateKey:
422 return rust_openssl.ec.from_private_numbers(self)
424 @property
425 def private_value(self) -> int:
426 return self._private_value
428 @property
429 def public_numbers(self) -> EllipticCurvePublicNumbers:
430 return self._public_numbers
432 def __eq__(self, other: object) -> bool:
433 if not isinstance(other, EllipticCurvePrivateNumbers):
434 return NotImplemented
436 return (
437 self.private_value == other.private_value
438 and self.public_numbers == other.public_numbers
439 )
441 def __hash__(self) -> int:
442 return hash((self.private_value, self.public_numbers))
445class ECDH:
446 pass
449_OID_TO_CURVE = {
450 EllipticCurveOID.SECP192R1: SECP192R1,
451 EllipticCurveOID.SECP224R1: SECP224R1,
452 EllipticCurveOID.SECP256K1: SECP256K1,
453 EllipticCurveOID.SECP256R1: SECP256R1,
454 EllipticCurveOID.SECP384R1: SECP384R1,
455 EllipticCurveOID.SECP521R1: SECP521R1,
456 EllipticCurveOID.BRAINPOOLP256R1: BrainpoolP256R1,
457 EllipticCurveOID.BRAINPOOLP384R1: BrainpoolP384R1,
458 EllipticCurveOID.BRAINPOOLP512R1: BrainpoolP512R1,
459 EllipticCurveOID.SECT163K1: SECT163K1,
460 EllipticCurveOID.SECT163R2: SECT163R2,
461 EllipticCurveOID.SECT233K1: SECT233K1,
462 EllipticCurveOID.SECT233R1: SECT233R1,
463 EllipticCurveOID.SECT283K1: SECT283K1,
464 EllipticCurveOID.SECT283R1: SECT283R1,
465 EllipticCurveOID.SECT409K1: SECT409K1,
466 EllipticCurveOID.SECT409R1: SECT409R1,
467 EllipticCurveOID.SECT571K1: SECT571K1,
468 EllipticCurveOID.SECT571R1: SECT571R1,
469}
472def get_curve_for_oid(oid: ObjectIdentifier) -> type[EllipticCurve]:
473 try:
474 return _OID_TO_CURVE[oid]
475 except KeyError:
476 raise LookupError(
477 "The provided object identifier has no matching elliptic "
478 "curve class"
479 )