Initial commit: 首次建仓,建立目录结构
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,159 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization
|
||||
|
||||
generate_parameters = rust_openssl.dh.generate_parameters
|
||||
|
||||
|
||||
DHPrivateNumbers = rust_openssl.dh.DHPrivateNumbers
|
||||
DHPublicNumbers = rust_openssl.dh.DHPublicNumbers
|
||||
DHParameterNumbers = rust_openssl.dh.DHParameterNumbers
|
||||
|
||||
|
||||
class DHParameters(metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def generate_private_key(self) -> DHPrivateKey:
|
||||
"""
|
||||
Generates and returns a DHPrivateKey.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def parameter_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.ParameterFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the parameters serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def parameter_numbers(self) -> DHParameterNumbers:
|
||||
"""
|
||||
Returns a DHParameterNumbers.
|
||||
"""
|
||||
|
||||
|
||||
DHParametersWithSerialization = DHParameters
|
||||
DHParameters.register(rust_openssl.dh.DHParameters)
|
||||
|
||||
|
||||
class DHPublicKey(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
The bit length of the prime modulus.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def parameters(self) -> DHParameters:
|
||||
"""
|
||||
The DHParameters object associated with this public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_numbers(self) -> DHPublicNumbers:
|
||||
"""
|
||||
Returns a DHPublicNumbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> DHPublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> DHPublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
DHPublicKeyWithSerialization = DHPublicKey
|
||||
DHPublicKey.register(rust_openssl.dh.DHPublicKey)
|
||||
|
||||
|
||||
class DHPrivateKey(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
The bit length of the prime modulus.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> DHPublicKey:
|
||||
"""
|
||||
The DHPublicKey associated with this private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def parameters(self) -> DHParameters:
|
||||
"""
|
||||
The DHParameters object associated with this private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def exchange(self, peer_public_key: DHPublicKey) -> bytes:
|
||||
"""
|
||||
Given peer's DHPublicKey, carry out the key exchange and
|
||||
return shared key as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_numbers(self) -> DHPrivateNumbers:
|
||||
"""
|
||||
Returns a DHPrivateNumbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> DHPrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> DHPrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
DHPrivateKeyWithSerialization = DHPrivateKey
|
||||
DHPrivateKey.register(rust_openssl.dh.DHPrivateKey)
|
||||
@ -0,0 +1,179 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
import typing
|
||||
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization, hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
|
||||
from cryptography.utils import Buffer
|
||||
|
||||
|
||||
class DSAParameters(metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def generate_private_key(self) -> DSAPrivateKey:
|
||||
"""
|
||||
Generates and returns a DSAPrivateKey.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def parameter_numbers(self) -> DSAParameterNumbers:
|
||||
"""
|
||||
Returns a DSAParameterNumbers.
|
||||
"""
|
||||
|
||||
|
||||
DSAParametersWithNumbers = DSAParameters
|
||||
DSAParameters.register(rust_openssl.dsa.DSAParameters)
|
||||
|
||||
|
||||
class DSAPrivateKey(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
The bit length of the prime modulus.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> DSAPublicKey:
|
||||
"""
|
||||
The DSAPublicKey associated with this private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def parameters(self) -> DSAParameters:
|
||||
"""
|
||||
The DSAParameters object associated with this private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(
|
||||
self,
|
||||
data: Buffer,
|
||||
algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
|
||||
) -> bytes:
|
||||
"""
|
||||
Signs the data
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_numbers(self) -> DSAPrivateNumbers:
|
||||
"""
|
||||
Returns a DSAPrivateNumbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> DSAPrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> DSAPrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
DSAPrivateKeyWithSerialization = DSAPrivateKey
|
||||
DSAPrivateKey.register(rust_openssl.dsa.DSAPrivateKey)
|
||||
|
||||
|
||||
class DSAPublicKey(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
The bit length of the prime modulus.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def parameters(self) -> DSAParameters:
|
||||
"""
|
||||
The DSAParameters object associated with this public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_numbers(self) -> DSAPublicNumbers:
|
||||
"""
|
||||
Returns a DSAPublicNumbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(
|
||||
self,
|
||||
signature: Buffer,
|
||||
data: Buffer,
|
||||
algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
|
||||
) -> None:
|
||||
"""
|
||||
Verifies the signature of the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> DSAPublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> DSAPublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
DSAPublicKeyWithSerialization = DSAPublicKey
|
||||
DSAPublicKey.register(rust_openssl.dsa.DSAPublicKey)
|
||||
|
||||
DSAPrivateNumbers = rust_openssl.dsa.DSAPrivateNumbers
|
||||
DSAPublicNumbers = rust_openssl.dsa.DSAPublicNumbers
|
||||
DSAParameterNumbers = rust_openssl.dsa.DSAParameterNumbers
|
||||
|
||||
|
||||
def generate_parameters(
|
||||
key_size: int, backend: typing.Any = None
|
||||
) -> DSAParameters:
|
||||
if key_size not in (1024, 2048, 3072, 4096):
|
||||
raise ValueError("Key size must be 1024, 2048, 3072, or 4096 bits.")
|
||||
|
||||
return rust_openssl.dsa.generate_parameters(key_size)
|
||||
|
||||
|
||||
def generate_private_key(
|
||||
key_size: int, backend: typing.Any = None
|
||||
) -> DSAPrivateKey:
|
||||
parameters = generate_parameters(key_size)
|
||||
return parameters.generate_private_key()
|
||||
@ -0,0 +1,369 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
import typing
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat._oid import ObjectIdentifier
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization, hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
|
||||
|
||||
|
||||
class EllipticCurveOID:
|
||||
SECP192R1 = ObjectIdentifier("1.2.840.10045.3.1.1")
|
||||
SECP224R1 = ObjectIdentifier("1.3.132.0.33")
|
||||
SECP256K1 = ObjectIdentifier("1.3.132.0.10")
|
||||
SECP256R1 = ObjectIdentifier("1.2.840.10045.3.1.7")
|
||||
SECP384R1 = ObjectIdentifier("1.3.132.0.34")
|
||||
SECP521R1 = ObjectIdentifier("1.3.132.0.35")
|
||||
BRAINPOOLP256R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.7")
|
||||
BRAINPOOLP384R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.11")
|
||||
BRAINPOOLP512R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.13")
|
||||
|
||||
|
||||
class EllipticCurve(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def name(self) -> str:
|
||||
"""
|
||||
The name of the curve. e.g. secp256r1.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
Bit size of a secret scalar for the curve.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def group_order(self) -> int:
|
||||
"""
|
||||
The order of the curve's group.
|
||||
"""
|
||||
|
||||
|
||||
class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def algorithm(
|
||||
self,
|
||||
) -> asym_utils.Prehashed | hashes.HashAlgorithm:
|
||||
"""
|
||||
The digest algorithm used with this signature.
|
||||
"""
|
||||
|
||||
|
||||
class EllipticCurvePrivateKey(metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def exchange(
|
||||
self, algorithm: ECDH, peer_public_key: EllipticCurvePublicKey
|
||||
) -> bytes:
|
||||
"""
|
||||
Performs a key exchange operation using the provided algorithm with the
|
||||
provided peer's public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> EllipticCurvePublicKey:
|
||||
"""
|
||||
The EllipticCurvePublicKey for this private key.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def curve(self) -> EllipticCurve:
|
||||
"""
|
||||
The EllipticCurve that this key is on.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
Bit size of a secret scalar for the curve.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(
|
||||
self,
|
||||
data: utils.Buffer,
|
||||
signature_algorithm: EllipticCurveSignatureAlgorithm,
|
||||
) -> bytes:
|
||||
"""
|
||||
Signs the data
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_numbers(self) -> EllipticCurvePrivateNumbers:
|
||||
"""
|
||||
Returns an EllipticCurvePrivateNumbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> EllipticCurvePrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> EllipticCurvePrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey
|
||||
EllipticCurvePrivateKey.register(rust_openssl.ec.ECPrivateKey)
|
||||
|
||||
|
||||
class EllipticCurvePublicKey(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def curve(self) -> EllipticCurve:
|
||||
"""
|
||||
The EllipticCurve that this key is on.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
Bit size of a secret scalar for the curve.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_numbers(self) -> EllipticCurvePublicNumbers:
|
||||
"""
|
||||
Returns an EllipticCurvePublicNumbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(
|
||||
self,
|
||||
signature: utils.Buffer,
|
||||
data: utils.Buffer,
|
||||
signature_algorithm: EllipticCurveSignatureAlgorithm,
|
||||
) -> None:
|
||||
"""
|
||||
Verifies the signature of the data.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_encoded_point(
|
||||
cls, curve: EllipticCurve, data: bytes
|
||||
) -> EllipticCurvePublicKey:
|
||||
utils._check_bytes("data", data)
|
||||
|
||||
if len(data) == 0:
|
||||
raise ValueError("data must not be an empty byte string")
|
||||
|
||||
if data[0] not in [0x02, 0x03, 0x04]:
|
||||
raise ValueError("Unsupported elliptic curve point type")
|
||||
|
||||
return rust_openssl.ec.from_public_bytes(curve, data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> EllipticCurvePublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> EllipticCurvePublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey
|
||||
EllipticCurvePublicKey.register(rust_openssl.ec.ECPublicKey)
|
||||
|
||||
EllipticCurvePrivateNumbers = rust_openssl.ec.EllipticCurvePrivateNumbers
|
||||
EllipticCurvePublicNumbers = rust_openssl.ec.EllipticCurvePublicNumbers
|
||||
|
||||
|
||||
class SECP521R1(EllipticCurve):
|
||||
name = "secp521r1"
|
||||
key_size = 521
|
||||
group_order = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409 # noqa: E501
|
||||
|
||||
|
||||
class SECP384R1(EllipticCurve):
|
||||
name = "secp384r1"
|
||||
key_size = 384
|
||||
group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973 # noqa: E501
|
||||
|
||||
|
||||
class SECP256R1(EllipticCurve):
|
||||
name = "secp256r1"
|
||||
key_size = 256
|
||||
group_order = (
|
||||
0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551
|
||||
)
|
||||
|
||||
|
||||
class SECP256K1(EllipticCurve):
|
||||
name = "secp256k1"
|
||||
key_size = 256
|
||||
group_order = (
|
||||
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
||||
)
|
||||
|
||||
|
||||
class SECP224R1(EllipticCurve):
|
||||
name = "secp224r1"
|
||||
key_size = 224
|
||||
group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D
|
||||
|
||||
|
||||
class SECP192R1(EllipticCurve):
|
||||
name = "secp192r1"
|
||||
key_size = 192
|
||||
group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831
|
||||
|
||||
|
||||
class BrainpoolP256R1(EllipticCurve):
|
||||
name = "brainpoolP256r1"
|
||||
key_size = 256
|
||||
group_order = (
|
||||
0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
|
||||
)
|
||||
|
||||
|
||||
class BrainpoolP384R1(EllipticCurve):
|
||||
name = "brainpoolP384r1"
|
||||
key_size = 384
|
||||
group_order = 0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565 # noqa: E501
|
||||
|
||||
|
||||
class BrainpoolP512R1(EllipticCurve):
|
||||
name = "brainpoolP512r1"
|
||||
key_size = 512
|
||||
group_order = 0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069 # noqa: E501
|
||||
|
||||
|
||||
_CURVE_TYPES: dict[str, EllipticCurve] = {
|
||||
"prime192v1": SECP192R1(),
|
||||
"prime256v1": SECP256R1(),
|
||||
"secp192r1": SECP192R1(),
|
||||
"secp224r1": SECP224R1(),
|
||||
"secp256r1": SECP256R1(),
|
||||
"secp384r1": SECP384R1(),
|
||||
"secp521r1": SECP521R1(),
|
||||
"secp256k1": SECP256K1(),
|
||||
"brainpoolP256r1": BrainpoolP256R1(),
|
||||
"brainpoolP384r1": BrainpoolP384R1(),
|
||||
"brainpoolP512r1": BrainpoolP512R1(),
|
||||
}
|
||||
|
||||
|
||||
class ECDSA(EllipticCurveSignatureAlgorithm):
|
||||
def __init__(
|
||||
self,
|
||||
algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
|
||||
deterministic_signing: bool = False,
|
||||
):
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if (
|
||||
deterministic_signing
|
||||
and not backend.ecdsa_deterministic_supported()
|
||||
):
|
||||
raise UnsupportedAlgorithm(
|
||||
"ECDSA with deterministic signature (RFC 6979) is not "
|
||||
"supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
self._algorithm = algorithm
|
||||
self._deterministic_signing = deterministic_signing
|
||||
|
||||
@property
|
||||
def algorithm(
|
||||
self,
|
||||
) -> asym_utils.Prehashed | hashes.HashAlgorithm:
|
||||
return self._algorithm
|
||||
|
||||
@property
|
||||
def deterministic_signing(
|
||||
self,
|
||||
) -> bool:
|
||||
return self._deterministic_signing
|
||||
|
||||
|
||||
generate_private_key = rust_openssl.ec.generate_private_key
|
||||
|
||||
|
||||
def derive_private_key(
|
||||
private_value: int,
|
||||
curve: EllipticCurve,
|
||||
backend: typing.Any = None,
|
||||
) -> EllipticCurvePrivateKey:
|
||||
if not isinstance(private_value, int):
|
||||
raise TypeError("private_value must be an integer type.")
|
||||
|
||||
if private_value <= 0:
|
||||
raise ValueError("private_value must be a positive integer.")
|
||||
|
||||
return rust_openssl.ec.derive_private_key(private_value, curve)
|
||||
|
||||
|
||||
class ECDH:
|
||||
pass
|
||||
|
||||
|
||||
_OID_TO_CURVE = {
|
||||
EllipticCurveOID.SECP192R1: SECP192R1,
|
||||
EllipticCurveOID.SECP224R1: SECP224R1,
|
||||
EllipticCurveOID.SECP256K1: SECP256K1,
|
||||
EllipticCurveOID.SECP256R1: SECP256R1,
|
||||
EllipticCurveOID.SECP384R1: SECP384R1,
|
||||
EllipticCurveOID.SECP521R1: SECP521R1,
|
||||
EllipticCurveOID.BRAINPOOLP256R1: BrainpoolP256R1,
|
||||
EllipticCurveOID.BRAINPOOLP384R1: BrainpoolP384R1,
|
||||
EllipticCurveOID.BRAINPOOLP512R1: BrainpoolP512R1,
|
||||
}
|
||||
|
||||
|
||||
def get_curve_for_oid(oid: ObjectIdentifier) -> type[EllipticCurve]:
|
||||
try:
|
||||
return _OID_TO_CURVE[oid]
|
||||
except KeyError:
|
||||
raise LookupError(
|
||||
"The provided object identifier has no matching elliptic "
|
||||
"curve class"
|
||||
)
|
||||
@ -0,0 +1,116 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization
|
||||
from cryptography.utils import Buffer
|
||||
|
||||
|
||||
class Ed25519PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: bytes) -> Ed25519PublicKey:
|
||||
return rust_openssl.ed25519.from_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(self, signature: Buffer, data: Buffer) -> None:
|
||||
"""
|
||||
Verify the signature.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> Ed25519PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> Ed25519PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
Ed25519PublicKey.register(rust_openssl.ed25519.Ed25519PublicKey)
|
||||
|
||||
|
||||
class Ed25519PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> Ed25519PrivateKey:
|
||||
return rust_openssl.ed25519.generate_key()
|
||||
|
||||
@classmethod
|
||||
def from_private_bytes(cls, data: Buffer) -> Ed25519PrivateKey:
|
||||
return rust_openssl.ed25519.from_private_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> Ed25519PublicKey:
|
||||
"""
|
||||
The Ed25519PublicKey derived from the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key.
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(self, data: Buffer) -> bytes:
|
||||
"""
|
||||
Signs the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> Ed25519PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> Ed25519PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
Ed25519PrivateKey.register(rust_openssl.ed25519.Ed25519PrivateKey)
|
||||
@ -0,0 +1,143 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization
|
||||
from cryptography.utils import Buffer
|
||||
|
||||
|
||||
class Ed448PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: bytes) -> Ed448PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.ed448_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ed448 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.ed448.from_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(self, signature: Buffer, data: Buffer) -> None:
|
||||
"""
|
||||
Verify the signature.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> Ed448PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> Ed448PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "ed448"):
|
||||
Ed448PublicKey.register(rust_openssl.ed448.Ed448PublicKey)
|
||||
|
||||
|
||||
class Ed448PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> Ed448PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.ed448_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ed448 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.ed448.generate_key()
|
||||
|
||||
@classmethod
|
||||
def from_private_bytes(cls, data: Buffer) -> Ed448PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.ed448_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ed448 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.ed448.from_private_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> Ed448PublicKey:
|
||||
"""
|
||||
The Ed448PublicKey derived from the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(self, data: Buffer) -> bytes:
|
||||
"""
|
||||
Signs the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key.
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> Ed448PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> Ed448PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "x448"):
|
||||
Ed448PrivateKey.register(rust_openssl.ed448.Ed448PrivateKey)
|
||||
@ -0,0 +1,441 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization
|
||||
from cryptography.utils import Buffer
|
||||
|
||||
|
||||
class MLDSA44PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: bytes) -> MLDSA44PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-44 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.from_mldsa44_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
|
||||
The public key is 1,312 bytes for MLDSA-44.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(
|
||||
self,
|
||||
signature: Buffer,
|
||||
data: Buffer,
|
||||
context: Buffer | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Verify the signature.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLDSA44PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLDSA44PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mldsa"):
|
||||
MLDSA44PublicKey.register(rust_openssl.mldsa.MLDSA44PublicKey)
|
||||
|
||||
|
||||
class MLDSA44PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> MLDSA44PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-44 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.generate_mldsa44_key()
|
||||
|
||||
@classmethod
|
||||
def from_seed_bytes(cls, data: Buffer) -> MLDSA44PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-44 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.from_mldsa44_seed_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> MLDSA44PublicKey:
|
||||
"""
|
||||
The MLDSA44PublicKey derived from the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
|
||||
This method only returns the serialization of the seed form of the
|
||||
private key, never the expanded one.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key.
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
|
||||
This method only returns the seed form of the private key (32 bytes).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(self, data: Buffer, context: Buffer | None = None) -> bytes:
|
||||
"""
|
||||
Signs the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLDSA44PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLDSA44PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mldsa"):
|
||||
MLDSA44PrivateKey.register(rust_openssl.mldsa.MLDSA44PrivateKey)
|
||||
|
||||
|
||||
class MLDSA65PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: bytes) -> MLDSA65PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-65 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.from_mldsa65_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
|
||||
The public key is 1,952 bytes for MLDSA-65.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(
|
||||
self,
|
||||
signature: Buffer,
|
||||
data: Buffer,
|
||||
context: Buffer | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Verify the signature.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLDSA65PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLDSA65PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mldsa"):
|
||||
MLDSA65PublicKey.register(rust_openssl.mldsa.MLDSA65PublicKey)
|
||||
|
||||
|
||||
class MLDSA65PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> MLDSA65PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-65 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.generate_mldsa65_key()
|
||||
|
||||
@classmethod
|
||||
def from_seed_bytes(cls, data: Buffer) -> MLDSA65PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-65 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.from_mldsa65_seed_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> MLDSA65PublicKey:
|
||||
"""
|
||||
The MLDSA65PublicKey derived from the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
|
||||
This method only returns the serialization of the seed form of the
|
||||
private key, never the expanded one.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key.
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
|
||||
This method only returns the seed form of the private key (32 bytes).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(self, data: Buffer, context: Buffer | None = None) -> bytes:
|
||||
"""
|
||||
Signs the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLDSA65PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLDSA65PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mldsa"):
|
||||
MLDSA65PrivateKey.register(rust_openssl.mldsa.MLDSA65PrivateKey)
|
||||
|
||||
|
||||
class MLDSA87PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: bytes) -> MLDSA87PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-87 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.from_mldsa87_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
|
||||
The public key is 2,592 bytes for MLDSA-87.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(
|
||||
self,
|
||||
signature: Buffer,
|
||||
data: Buffer,
|
||||
context: Buffer | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Verify the signature.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLDSA87PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLDSA87PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mldsa"):
|
||||
MLDSA87PublicKey.register(rust_openssl.mldsa.MLDSA87PublicKey)
|
||||
|
||||
|
||||
class MLDSA87PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> MLDSA87PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-87 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.generate_mldsa87_key()
|
||||
|
||||
@classmethod
|
||||
def from_seed_bytes(cls, data: Buffer) -> MLDSA87PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mldsa_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-DSA-87 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mldsa.from_mldsa87_seed_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> MLDSA87PublicKey:
|
||||
"""
|
||||
The MLDSA87PublicKey derived from the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
|
||||
This method only returns the serialization of the seed form of the
|
||||
private key, never the expanded one.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key.
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
|
||||
This method only returns the seed form of the private key (32 bytes).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(self, data: Buffer, context: Buffer | None = None) -> bytes:
|
||||
"""
|
||||
Signs the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLDSA87PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLDSA87PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mldsa"):
|
||||
MLDSA87PrivateKey.register(rust_openssl.mldsa.MLDSA87PrivateKey)
|
||||
@ -0,0 +1,278 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization
|
||||
from cryptography.utils import Buffer
|
||||
|
||||
|
||||
class MLKEM768PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: Buffer) -> MLKEM768PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mlkem_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-KEM-768 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mlkem.from_mlkem768_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def encapsulate(self) -> tuple[bytes, bytes]:
|
||||
"""
|
||||
Encapsulate: returns (shared_secret, ciphertext).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
|
||||
The public key is 1,184 bytes for ML-KEM-768.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLKEM768PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLKEM768PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mlkem"):
|
||||
MLKEM768PublicKey.register(rust_openssl.mlkem.MLKEM768PublicKey)
|
||||
|
||||
|
||||
class MLKEM768PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> MLKEM768PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mlkem_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-KEM-768 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mlkem.generate_mlkem768_key()
|
||||
|
||||
@classmethod
|
||||
def from_seed_bytes(cls, data: Buffer) -> MLKEM768PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mlkem_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-KEM-768 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mlkem.from_mlkem768_seed_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def decapsulate(self, ciphertext: Buffer) -> bytes:
|
||||
"""
|
||||
Decapsulate: returns shared_secret.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> MLKEM768PublicKey:
|
||||
"""
|
||||
The MLKEM768PublicKey derived from this private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key (64-byte seed).
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLKEM768PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLKEM768PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mlkem"):
|
||||
MLKEM768PrivateKey.register(rust_openssl.mlkem.MLKEM768PrivateKey)
|
||||
|
||||
|
||||
class MLKEM1024PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: Buffer) -> MLKEM1024PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mlkem_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-KEM-1024 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mlkem.from_mlkem1024_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def encapsulate(self) -> tuple[bytes, bytes]:
|
||||
"""
|
||||
Encapsulate: returns (shared_secret, ciphertext).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
|
||||
The public key is 1,568 bytes for ML-KEM-1024.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLKEM1024PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLKEM1024PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mlkem"):
|
||||
MLKEM1024PublicKey.register(rust_openssl.mlkem.MLKEM1024PublicKey)
|
||||
|
||||
|
||||
class MLKEM1024PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> MLKEM1024PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mlkem_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-KEM-1024 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mlkem.generate_mlkem1024_key()
|
||||
|
||||
@classmethod
|
||||
def from_seed_bytes(cls, data: Buffer) -> MLKEM1024PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.mlkem_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"ML-KEM-1024 is not supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.mlkem.from_mlkem1024_seed_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def decapsulate(self, ciphertext: Buffer) -> bytes:
|
||||
"""
|
||||
Decapsulate: returns shared_secret.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> MLKEM1024PublicKey:
|
||||
"""
|
||||
The MLKEM1024PublicKey derived from this private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key (64-byte seed).
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> MLKEM1024PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> MLKEM1024PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "mlkem"):
|
||||
MLKEM1024PrivateKey.register(rust_openssl.mlkem.MLKEM1024PrivateKey)
|
||||
@ -0,0 +1,111 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives._asymmetric import (
|
||||
AsymmetricPadding as AsymmetricPadding,
|
||||
)
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
|
||||
|
||||
class PKCS1v15(AsymmetricPadding):
|
||||
name = "EMSA-PKCS1-v1_5"
|
||||
|
||||
|
||||
class _MaxLength:
|
||||
"Sentinel value for `MAX_LENGTH`."
|
||||
|
||||
|
||||
class _Auto:
|
||||
"Sentinel value for `AUTO`."
|
||||
|
||||
|
||||
class _DigestLength:
|
||||
"Sentinel value for `DIGEST_LENGTH`."
|
||||
|
||||
|
||||
class PSS(AsymmetricPadding):
|
||||
MAX_LENGTH = _MaxLength()
|
||||
AUTO = _Auto()
|
||||
DIGEST_LENGTH = _DigestLength()
|
||||
name = "EMSA-PSS"
|
||||
_salt_length: int | _MaxLength | _Auto | _DigestLength
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
mgf: MGF,
|
||||
salt_length: int | _MaxLength | _Auto | _DigestLength,
|
||||
) -> None:
|
||||
self._mgf = mgf
|
||||
|
||||
if not isinstance(
|
||||
salt_length, (int, _MaxLength, _Auto, _DigestLength)
|
||||
):
|
||||
raise TypeError(
|
||||
"salt_length must be an integer, MAX_LENGTH, "
|
||||
"DIGEST_LENGTH, or AUTO"
|
||||
)
|
||||
|
||||
if isinstance(salt_length, int) and salt_length < 0:
|
||||
raise ValueError("salt_length must be zero or greater.")
|
||||
|
||||
self._salt_length = salt_length
|
||||
|
||||
@property
|
||||
def mgf(self) -> MGF:
|
||||
return self._mgf
|
||||
|
||||
|
||||
class OAEP(AsymmetricPadding):
|
||||
name = "EME-OAEP"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
mgf: MGF,
|
||||
algorithm: hashes.HashAlgorithm,
|
||||
label: bytes | None,
|
||||
):
|
||||
if not isinstance(algorithm, hashes.HashAlgorithm):
|
||||
raise TypeError("Expected instance of hashes.HashAlgorithm.")
|
||||
|
||||
self._mgf = mgf
|
||||
self._algorithm = algorithm
|
||||
self._label = label
|
||||
|
||||
@property
|
||||
def algorithm(self) -> hashes.HashAlgorithm:
|
||||
return self._algorithm
|
||||
|
||||
@property
|
||||
def mgf(self) -> MGF:
|
||||
return self._mgf
|
||||
|
||||
|
||||
class MGF(metaclass=abc.ABCMeta):
|
||||
_algorithm: hashes.HashAlgorithm
|
||||
|
||||
|
||||
class MGF1(MGF):
|
||||
def __init__(self, algorithm: hashes.HashAlgorithm):
|
||||
if not isinstance(algorithm, hashes.HashAlgorithm):
|
||||
raise TypeError("Expected instance of hashes.HashAlgorithm.")
|
||||
|
||||
self._algorithm = algorithm
|
||||
|
||||
|
||||
def calculate_max_pss_salt_length(
|
||||
key: rsa.RSAPrivateKey | rsa.RSAPublicKey,
|
||||
hash_algorithm: hashes.HashAlgorithm,
|
||||
) -> int:
|
||||
if not isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)):
|
||||
raise TypeError("key must be an RSA public or private key")
|
||||
# bit length - 1 per RFC 3447
|
||||
emlen = (key.key_size + 6) // 8
|
||||
salt_length = emlen - hash_algorithm.digest_size - 2
|
||||
assert salt_length >= 0
|
||||
return salt_length
|
||||
@ -0,0 +1,295 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
import random
|
||||
import typing
|
||||
from math import gcd, lcm
|
||||
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization, hashes
|
||||
from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding
|
||||
from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
|
||||
|
||||
|
||||
class RSAPrivateKey(metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes:
|
||||
"""
|
||||
Decrypts the provided ciphertext.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
The bit length of the public modulus.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> RSAPublicKey:
|
||||
"""
|
||||
The RSAPublicKey associated with this private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign(
|
||||
self,
|
||||
data: bytes,
|
||||
padding: AsymmetricPadding,
|
||||
algorithm: asym_utils.Prehashed
|
||||
| hashes.HashAlgorithm
|
||||
| asym_utils.NoDigestInfo,
|
||||
) -> bytes:
|
||||
"""
|
||||
Signs the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_numbers(self) -> RSAPrivateNumbers:
|
||||
"""
|
||||
Returns an RSAPrivateNumbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> RSAPrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> RSAPrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
RSAPrivateKeyWithSerialization = RSAPrivateKey
|
||||
RSAPrivateKey.register(rust_openssl.rsa.RSAPrivateKey)
|
||||
|
||||
|
||||
class RSAPublicKey(metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes:
|
||||
"""
|
||||
Encrypts the given plaintext.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def key_size(self) -> int:
|
||||
"""
|
||||
The bit length of the public modulus.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_numbers(self) -> RSAPublicNumbers:
|
||||
"""
|
||||
Returns an RSAPublicNumbers
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
Returns the key serialized as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(
|
||||
self,
|
||||
signature: bytes,
|
||||
data: bytes,
|
||||
padding: AsymmetricPadding,
|
||||
algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
|
||||
) -> None:
|
||||
"""
|
||||
Verifies the signature of the data.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def recover_data_from_signature(
|
||||
self,
|
||||
signature: bytes,
|
||||
padding: AsymmetricPadding,
|
||||
algorithm: hashes.HashAlgorithm | asym_utils.NoDigestInfo | None,
|
||||
) -> bytes:
|
||||
"""
|
||||
Recovers the original data from the signature.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> RSAPublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> RSAPublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
RSAPublicKeyWithSerialization = RSAPublicKey
|
||||
RSAPublicKey.register(rust_openssl.rsa.RSAPublicKey)
|
||||
|
||||
RSAPrivateNumbers = rust_openssl.rsa.RSAPrivateNumbers
|
||||
RSAPublicNumbers = rust_openssl.rsa.RSAPublicNumbers
|
||||
|
||||
|
||||
def generate_private_key(
|
||||
public_exponent: int,
|
||||
key_size: int,
|
||||
backend: typing.Any = None,
|
||||
) -> RSAPrivateKey:
|
||||
_verify_rsa_parameters(public_exponent, key_size)
|
||||
return rust_openssl.rsa.generate_private_key(public_exponent, key_size)
|
||||
|
||||
|
||||
def _verify_rsa_parameters(public_exponent: int, key_size: int) -> None:
|
||||
if public_exponent not in (3, 65537):
|
||||
raise ValueError(
|
||||
"public_exponent must be either 3 (for legacy compatibility) or "
|
||||
"65537. Almost everyone should choose 65537 here!"
|
||||
)
|
||||
|
||||
if key_size < 1024:
|
||||
raise ValueError("key_size must be at least 1024-bits.")
|
||||
|
||||
|
||||
def _modinv(e: int, m: int) -> int:
|
||||
"""
|
||||
Modular Multiplicative Inverse. Returns x such that: (x*e) mod m == 1
|
||||
"""
|
||||
x1, x2 = 1, 0
|
||||
a, b = e, m
|
||||
while b > 0:
|
||||
q, r = divmod(a, b)
|
||||
xn = x1 - q * x2
|
||||
a, b, x1, x2 = b, r, x2, xn
|
||||
return x1 % m
|
||||
|
||||
|
||||
def rsa_crt_iqmp(p: int, q: int) -> int:
|
||||
"""
|
||||
Compute the CRT (q ** -1) % p value from RSA primes p and q.
|
||||
"""
|
||||
if p <= 1 or q <= 1:
|
||||
raise ValueError("Values can't be <= 1")
|
||||
return _modinv(q, p)
|
||||
|
||||
|
||||
def rsa_crt_dmp1(private_exponent: int, p: int) -> int:
|
||||
"""
|
||||
Compute the CRT private_exponent % (p - 1) value from the RSA
|
||||
private_exponent (d) and p.
|
||||
"""
|
||||
if private_exponent <= 1 or p <= 1:
|
||||
raise ValueError("Values can't be <= 1")
|
||||
return private_exponent % (p - 1)
|
||||
|
||||
|
||||
def rsa_crt_dmq1(private_exponent: int, q: int) -> int:
|
||||
"""
|
||||
Compute the CRT private_exponent % (q - 1) value from the RSA
|
||||
private_exponent (d) and q.
|
||||
"""
|
||||
if private_exponent <= 1 or q <= 1:
|
||||
raise ValueError("Values can't be <= 1")
|
||||
return private_exponent % (q - 1)
|
||||
|
||||
|
||||
def rsa_recover_private_exponent(e: int, p: int, q: int) -> int:
|
||||
"""
|
||||
Compute the RSA private_exponent (d) given the public exponent (e)
|
||||
and the RSA primes p and q.
|
||||
|
||||
This uses the Carmichael totient function to generate the
|
||||
smallest possible working value of the private exponent.
|
||||
"""
|
||||
# This lambda_n is the Carmichael totient function.
|
||||
# The original RSA paper uses the Euler totient function
|
||||
# here: phi_n = (p - 1) * (q - 1)
|
||||
# Either version of the private exponent will work, but the
|
||||
# one generated by the older formulation may be larger
|
||||
# than necessary. (lambda_n always divides phi_n)
|
||||
if e <= 1 or p <= 1 or q <= 1:
|
||||
raise ValueError("Values can't be <= 1")
|
||||
return _modinv(e, lcm(p - 1, q - 1))
|
||||
|
||||
|
||||
# Controls the number of iterations rsa_recover_prime_factors will perform
|
||||
# to obtain the prime factors.
|
||||
_MAX_RECOVERY_ATTEMPTS = 500
|
||||
|
||||
|
||||
def rsa_recover_prime_factors(n: int, e: int, d: int) -> tuple[int, int]:
|
||||
"""
|
||||
Compute factors p and q from the private exponent d. We assume that n has
|
||||
no more than two factors. This function is adapted from code in PyCrypto.
|
||||
"""
|
||||
# reject invalid values early
|
||||
if d <= 1 or e <= 1:
|
||||
raise ValueError("d, e can't be <= 1")
|
||||
if 17 != pow(17, e * d, n):
|
||||
raise ValueError("n, d, e don't match")
|
||||
# See 8.2.2(i) in Handbook of Applied Cryptography.
|
||||
ktot = d * e - 1
|
||||
# The quantity d*e-1 is a multiple of phi(n), even,
|
||||
# and can be represented as t*2^s.
|
||||
t = ktot
|
||||
while t % 2 == 0:
|
||||
t = t // 2
|
||||
# Cycle through all multiplicative inverses in Zn.
|
||||
# The algorithm is non-deterministic, but there is a 50% chance
|
||||
# any candidate a leads to successful factoring.
|
||||
# See "Digitalized Signatures and Public Key Functions as Intractable
|
||||
# as Factorization", M. Rabin, 1979
|
||||
spotted = False
|
||||
tries = 0
|
||||
while not spotted and tries < _MAX_RECOVERY_ATTEMPTS:
|
||||
a = random.randint(2, n - 1)
|
||||
tries += 1
|
||||
k = t
|
||||
# Cycle through all values a^{t*2^i}=a^k
|
||||
while k < ktot:
|
||||
cand = pow(a, k, n)
|
||||
# Check if a^k is a non-trivial root of unity (mod n)
|
||||
if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1:
|
||||
# We have found a number such that (cand-1)(cand+1)=0 (mod n).
|
||||
# Either of the terms divides n.
|
||||
p = gcd(cand + 1, n)
|
||||
spotted = True
|
||||
break
|
||||
k *= 2
|
||||
if not spotted:
|
||||
raise ValueError("Unable to compute factors p and q from exponent d.")
|
||||
# Found !
|
||||
q, r = divmod(n, p)
|
||||
assert r == 0
|
||||
p, q = sorted((p, q), reverse=True)
|
||||
return (p, q)
|
||||
@ -0,0 +1,123 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import typing
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.hazmat.primitives.asymmetric import (
|
||||
dh,
|
||||
dsa,
|
||||
ec,
|
||||
ed448,
|
||||
ed25519,
|
||||
mldsa,
|
||||
mlkem,
|
||||
rsa,
|
||||
x448,
|
||||
x25519,
|
||||
)
|
||||
|
||||
# Every asymmetric key type
|
||||
PublicKeyTypes = typing.Union[
|
||||
dh.DHPublicKey,
|
||||
dsa.DSAPublicKey,
|
||||
rsa.RSAPublicKey,
|
||||
ec.EllipticCurvePublicKey,
|
||||
ed25519.Ed25519PublicKey,
|
||||
ed448.Ed448PublicKey,
|
||||
mldsa.MLDSA44PublicKey,
|
||||
mldsa.MLDSA65PublicKey,
|
||||
mldsa.MLDSA87PublicKey,
|
||||
mlkem.MLKEM768PublicKey,
|
||||
mlkem.MLKEM1024PublicKey,
|
||||
x25519.X25519PublicKey,
|
||||
x448.X448PublicKey,
|
||||
]
|
||||
PUBLIC_KEY_TYPES = PublicKeyTypes
|
||||
utils.deprecated(
|
||||
PUBLIC_KEY_TYPES,
|
||||
__name__,
|
||||
"Use PublicKeyTypes instead",
|
||||
utils.DeprecatedIn40,
|
||||
name="PUBLIC_KEY_TYPES",
|
||||
)
|
||||
# Every asymmetric key type
|
||||
PrivateKeyTypes = typing.Union[
|
||||
dh.DHPrivateKey,
|
||||
ed25519.Ed25519PrivateKey,
|
||||
ed448.Ed448PrivateKey,
|
||||
mldsa.MLDSA44PrivateKey,
|
||||
mldsa.MLDSA65PrivateKey,
|
||||
mldsa.MLDSA87PrivateKey,
|
||||
mlkem.MLKEM768PrivateKey,
|
||||
mlkem.MLKEM1024PrivateKey,
|
||||
rsa.RSAPrivateKey,
|
||||
dsa.DSAPrivateKey,
|
||||
ec.EllipticCurvePrivateKey,
|
||||
x25519.X25519PrivateKey,
|
||||
x448.X448PrivateKey,
|
||||
]
|
||||
PRIVATE_KEY_TYPES = PrivateKeyTypes
|
||||
utils.deprecated(
|
||||
PRIVATE_KEY_TYPES,
|
||||
__name__,
|
||||
"Use PrivateKeyTypes instead",
|
||||
utils.DeprecatedIn40,
|
||||
name="PRIVATE_KEY_TYPES",
|
||||
)
|
||||
# Just the key types we allow to be used for x509 signing. This mirrors
|
||||
# the certificate public key types
|
||||
CertificateIssuerPrivateKeyTypes = typing.Union[
|
||||
ed25519.Ed25519PrivateKey,
|
||||
ed448.Ed448PrivateKey,
|
||||
rsa.RSAPrivateKey,
|
||||
dsa.DSAPrivateKey,
|
||||
ec.EllipticCurvePrivateKey,
|
||||
]
|
||||
CERTIFICATE_PRIVATE_KEY_TYPES = CertificateIssuerPrivateKeyTypes
|
||||
utils.deprecated(
|
||||
CERTIFICATE_PRIVATE_KEY_TYPES,
|
||||
__name__,
|
||||
"Use CertificateIssuerPrivateKeyTypes instead",
|
||||
utils.DeprecatedIn40,
|
||||
name="CERTIFICATE_PRIVATE_KEY_TYPES",
|
||||
)
|
||||
# Just the key types we allow to be used for x509 signing. This mirrors
|
||||
# the certificate private key types
|
||||
CertificateIssuerPublicKeyTypes = typing.Union[
|
||||
dsa.DSAPublicKey,
|
||||
rsa.RSAPublicKey,
|
||||
ec.EllipticCurvePublicKey,
|
||||
ed25519.Ed25519PublicKey,
|
||||
ed448.Ed448PublicKey,
|
||||
]
|
||||
CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES = CertificateIssuerPublicKeyTypes
|
||||
utils.deprecated(
|
||||
CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES,
|
||||
__name__,
|
||||
"Use CertificateIssuerPublicKeyTypes instead",
|
||||
utils.DeprecatedIn40,
|
||||
name="CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES",
|
||||
)
|
||||
# This type removes DHPublicKey. x448/x25519 can be a public key
|
||||
# but cannot be used in signing so they are allowed here.
|
||||
CertificatePublicKeyTypes = typing.Union[
|
||||
dsa.DSAPublicKey,
|
||||
rsa.RSAPublicKey,
|
||||
ec.EllipticCurvePublicKey,
|
||||
ed25519.Ed25519PublicKey,
|
||||
ed448.Ed448PublicKey,
|
||||
x25519.X25519PublicKey,
|
||||
x448.X448PublicKey,
|
||||
]
|
||||
CERTIFICATE_PUBLIC_KEY_TYPES = CertificatePublicKeyTypes
|
||||
utils.deprecated(
|
||||
CERTIFICATE_PUBLIC_KEY_TYPES,
|
||||
__name__,
|
||||
"Use CertificatePublicKeyTypes instead",
|
||||
utils.DeprecatedIn40,
|
||||
name="CERTIFICATE_PUBLIC_KEY_TYPES",
|
||||
)
|
||||
@ -0,0 +1,28 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from cryptography.hazmat.bindings._rust import asn1
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
|
||||
decode_dss_signature = asn1.decode_dss_signature
|
||||
encode_dss_signature = asn1.encode_dss_signature
|
||||
|
||||
|
||||
class NoDigestInfo:
|
||||
pass
|
||||
|
||||
|
||||
class Prehashed:
|
||||
def __init__(self, algorithm: hashes.HashAlgorithm):
|
||||
if not isinstance(algorithm, hashes.HashAlgorithm):
|
||||
raise TypeError("Expected instance of HashAlgorithm.")
|
||||
|
||||
self._algorithm = algorithm
|
||||
self._digest_size = algorithm.digest_size
|
||||
|
||||
@property
|
||||
def digest_size(self) -> int:
|
||||
return self._digest_size
|
||||
@ -0,0 +1,134 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization
|
||||
from cryptography.utils import Buffer
|
||||
|
||||
|
||||
class X25519PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: bytes) -> X25519PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.x25519_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"X25519 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.x25519.from_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> X25519PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> X25519PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
X25519PublicKey.register(rust_openssl.x25519.X25519PublicKey)
|
||||
|
||||
|
||||
class X25519PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> X25519PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.x25519_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"X25519 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
|
||||
)
|
||||
return rust_openssl.x25519.generate_key()
|
||||
|
||||
@classmethod
|
||||
def from_private_bytes(cls, data: Buffer) -> X25519PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.x25519_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"X25519 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.x25519.from_private_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> X25519PublicKey:
|
||||
"""
|
||||
Returns the public key associated with this private key
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key.
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def exchange(self, peer_public_key: X25519PublicKey) -> bytes:
|
||||
"""
|
||||
Performs a key exchange operation using the provided peer's public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> X25519PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> X25519PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
X25519PrivateKey.register(rust_openssl.x25519.X25519PrivateKey)
|
||||
@ -0,0 +1,137 @@
|
||||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
||||
from cryptography.hazmat.primitives import _serialization
|
||||
from cryptography.utils import Buffer
|
||||
|
||||
|
||||
class X448PublicKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def from_public_bytes(cls, data: bytes) -> X448PublicKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.x448_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"X448 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.x448.from_public_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PublicFormat,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the public key.
|
||||
Equivalent to public_bytes(Raw, Raw).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""
|
||||
Checks equality.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> X448PublicKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> X448PublicKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "x448"):
|
||||
X448PublicKey.register(rust_openssl.x448.X448PublicKey)
|
||||
|
||||
|
||||
class X448PrivateKey(metaclass=abc.ABCMeta):
|
||||
@classmethod
|
||||
def generate(cls) -> X448PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.x448_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"X448 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.x448.generate_key()
|
||||
|
||||
@classmethod
|
||||
def from_private_bytes(cls, data: Buffer) -> X448PrivateKey:
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
if not backend.x448_supported():
|
||||
raise UnsupportedAlgorithm(
|
||||
"X448 is not supported by this version of OpenSSL.",
|
||||
_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
|
||||
)
|
||||
|
||||
return rust_openssl.x448.from_private_bytes(data)
|
||||
|
||||
@abc.abstractmethod
|
||||
def public_key(self) -> X448PublicKey:
|
||||
"""
|
||||
Returns the public key associated with this private key
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes(
|
||||
self,
|
||||
encoding: _serialization.Encoding,
|
||||
format: _serialization.PrivateFormat,
|
||||
encryption_algorithm: _serialization.KeySerializationEncryption,
|
||||
) -> bytes:
|
||||
"""
|
||||
The serialized bytes of the private key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def private_bytes_raw(self) -> bytes:
|
||||
"""
|
||||
The raw bytes of the private key.
|
||||
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def exchange(self, peer_public_key: X448PublicKey) -> bytes:
|
||||
"""
|
||||
Performs a key exchange operation using the provided peer's public key.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __copy__(self) -> X448PrivateKey:
|
||||
"""
|
||||
Returns a copy.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __deepcopy__(self, memo: dict) -> X448PrivateKey:
|
||||
"""
|
||||
Returns a deep copy.
|
||||
"""
|
||||
|
||||
|
||||
if hasattr(rust_openssl, "x448"):
|
||||
X448PrivateKey.register(rust_openssl.x448.X448PrivateKey)
|
||||
Reference in New Issue
Block a user