Danger
This is a “Hazardous Materials” module. You should ONLY use it if you’re 100% absolutely sure that you know what you’re doing because this module is full of land mines, dragons, and dinosaurs with laser guns.
ML-DSA signing
ML-DSA is a post-quantum digital signature algorithm based on module lattices, standardized in FIPS 204.
Signing & Verification
>>> from cryptography.hazmat.primitives.asymmetric.mldsa import MLDSA65PrivateKey
>>> private_key = MLDSA65PrivateKey.generate()
>>> signature = private_key.sign(b"my authenticated message")
>>> public_key = private_key.public_key()
>>> public_key.verify(signature, b"my authenticated message")
Context-based Signing & Verification
ML-DSA supports context strings to bind additional information to signatures. The context can be up to 255 bytes and is used to differentiate signatures in different contexts or protocols.
>>> from cryptography.hazmat.primitives.asymmetric.mldsa import MLDSA65PrivateKey
>>> private_key = MLDSA65PrivateKey.generate()
>>> context = b"email-signature-v1"
>>> signature = private_key.sign(b"my authenticated message", context)
>>> public_key = private_key.public_key()
>>> # Verification requires the same context
>>> public_key.verify(signature, b"my authenticated message", context)
External mu
ML-DSA supports an “external mu” mode, where the message representative
mu is computed separately from signing and verification (see
MLDSA65PrivateKey.sign_mu() and MLDSA65PublicKey.verify_mu()).
MLDSAMuHasher computes mu incrementally, which is useful when the
message is large or only available as a stream.
>>> from cryptography.hazmat.primitives.asymmetric import mldsa
>>> private_key = mldsa.MLDSA65PrivateKey.generate()
>>> public_key = private_key.public_key()
>>> hasher = mldsa.MLDSAMuHasher(public_key)
>>> hasher.update(b"my authenticated ")
>>> hasher.update(b"message")
>>> mu = hasher.finalize()
>>> signature = private_key.sign_mu(mu)
>>> public_key.verify_mu(signature, mu)
Key interfaces
- class cryptography.hazmat.primitives.asymmetric.mldsa.MLDSA44PrivateKey[source]
Added in version 47.0.0.
- classmethod generate()[source]
Generate an ML-DSA-44 private key.
- Returns:
- Raises:
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-44 is not supported by the backend
cryptographyis using.
- classmethod from_seed_bytes(data)[source]
Load an ML-DSA-44 private key from seed bytes.
- Parameters:
data (bytes-like) – 32 byte seed.
- Returns:
- Raises:
ValueError – If the seed is not 32 bytes.
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-44 is not supported by the backend
cryptographyis using.
>>> from cryptography.hazmat.primitives.asymmetric import mldsa >>> private_key = mldsa.MLDSA44PrivateKey.generate() >>> seed = private_key.private_bytes_raw() >>> same_key = mldsa.MLDSA44PrivateKey.from_seed_bytes(seed)
- sign(data, context=None)[source]
Sign the data using ML-DSA-44. An optional context string can be provided.
- Parameters:
data (bytes-like) – The data to sign.
context (bytes-like or
None) – An optional context string (up to 255 bytes).
- Returns bytes:
The signature (2420 bytes).
- Raises:
ValueError – If the context is longer than 255 bytes.
- sign_mu(mu)[source]
Added in version 49.0.0.
Sign a precomputed
mu(message representative) using ML-DSA-44, the “external mu” variant from FIPS 204.mucan be computed incrementally withMLDSAMuHasher.- Parameters:
mu (bytes-like) – The 64-byte message representative.
- Returns bytes:
The signature (2420 bytes).
- Raises:
ValueError – If
muis not 64 bytes.
- private_bytes(encoding, format, encryption_algorithm)[source]
Allows serialization of the key to bytes. Encoding (
PEM,DER, orRaw) and format (PKCS8orRaw) are chosen to define the exact serialization.This method only returns the serialization of the seed form of the private key, never the expanded one.
- Parameters:
encoding – A value from the
Encodingenum.format – A value from the
PrivateFormatenum. If theencodingisRawthenformatmust beRaw, otherwise it must bePKCS8.encryption_algorithm – An instance of an object conforming to the
KeySerializationEncryptioninterface.
- Return bytes:
Serialized key.
- private_bytes_raw()[source]
Allows serialization of the key to raw bytes. This method is a convenience shortcut for calling
private_bytes()withRawencoding,Rawformat, andNoEncryption.This method only returns the seed form of the private key (32 bytes).
- Return bytes:
Raw key (32-byte seed).
- class cryptography.hazmat.primitives.asymmetric.mldsa.MLDSA44PublicKey[source]
Added in version 47.0.0.
- classmethod from_public_bytes(data)[source]
- Parameters:
data (bytes) – 1312 byte public key.
- Returns:
- Raises:
ValueError – If the public key is not 1312 bytes.
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-44 is not supported by the backend
cryptographyis using.
>>> from cryptography.hazmat.primitives import serialization >>> from cryptography.hazmat.primitives.asymmetric import mldsa >>> private_key = mldsa.MLDSA44PrivateKey.generate() >>> public_key = private_key.public_key() >>> public_bytes = public_key.public_bytes( ... encoding=serialization.Encoding.Raw, ... format=serialization.PublicFormat.Raw ... ) >>> loaded_public_key = mldsa.MLDSA44PublicKey.from_public_bytes(public_bytes)
- public_bytes(encoding, format)[source]
Allows serialization of the key to bytes. Encoding (
PEM,DER, orRaw) and format (SubjectPublicKeyInfoorRaw) are chosen to define the exact serialization.- Parameters:
encoding – A value from the
Encodingenum.format – A value from the
PublicFormatenum. If theencodingisRawthenformatmust beRaw, otherwise it must beSubjectPublicKeyInfo.
- Returns bytes:
The public key bytes.
- public_bytes_raw()[source]
Allows serialization of the key to raw bytes. This method is a convenience shortcut for calling
public_bytes()withRawencoding andRawformat.- Return bytes:
1312-byte raw public key.
- verify(signature, data, context=None)[source]
Verify a signature using ML-DSA-44. If a context string was used during signing, the same context must be provided for verification to succeed.
- Parameters:
signature (bytes-like) – The signature to verify.
data (bytes-like) – The data to verify.
context (bytes-like or
None) – An optional context string (up to 255 bytes) that was used during signing.
- Returns:
None
- Raises:
cryptography.exceptions.InvalidSignature – Raised when the signature cannot be verified.
ValueError – If the context is longer than 255 bytes.
- verify_mu(signature, mu)[source]
Added in version 49.0.0.
Verify a signature over a precomputed
mu(message representative), the “external mu” variant from FIPS 204.mucan be computed incrementally withMLDSAMuHasher.- Parameters:
signature (bytes-like) – The signature to verify.
mu (bytes-like) – The 64-byte message representative.
- Returns:
None
- Raises:
cryptography.exceptions.InvalidSignature – Raised when the signature cannot be verified.
ValueError – If
muis not 64 bytes.
- class cryptography.hazmat.primitives.asymmetric.mldsa.MLDSA65PrivateKey[source]
Added in version 47.0.0.
- classmethod generate()[source]
Generate an ML-DSA-65 private key.
- Returns:
- Raises:
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-65 is not supported by the backend
cryptographyis using.
- classmethod from_seed_bytes(data)[source]
Load an ML-DSA-65 private key from seed bytes.
- Parameters:
data (bytes-like) – 32 byte seed.
- Returns:
- Raises:
ValueError – If the seed is not 32 bytes.
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-65 is not supported by the backend
cryptographyis using.
>>> from cryptography.hazmat.primitives.asymmetric import mldsa >>> private_key = mldsa.MLDSA65PrivateKey.generate() >>> seed = private_key.private_bytes_raw() >>> same_key = mldsa.MLDSA65PrivateKey.from_seed_bytes(seed)
- sign(data, context=None)[source]
Sign the data using ML-DSA-65. An optional context string can be provided.
- Parameters:
data (bytes-like) – The data to sign.
context (bytes-like or
None) – An optional context string (up to 255 bytes).
- Returns bytes:
The signature (3309 bytes).
- Raises:
ValueError – If the context is longer than 255 bytes.
- sign_mu(mu)[source]
Added in version 49.0.0.
Sign a precomputed
mu(message representative) using ML-DSA-65, the “external mu” variant from FIPS 204.mucan be computed incrementally withMLDSAMuHasher.- Parameters:
mu (bytes-like) – The 64-byte message representative.
- Returns bytes:
The signature (3309 bytes).
- Raises:
ValueError – If
muis not 64 bytes.
- private_bytes(encoding, format, encryption_algorithm)[source]
Allows serialization of the key to bytes. Encoding (
PEM,DER, orRaw) and format (PKCS8orRaw) are chosen to define the exact serialization.This method only returns the serialization of the seed form of the private key, never the expanded one.
- Parameters:
encoding – A value from the
Encodingenum.format – A value from the
PrivateFormatenum. If theencodingisRawthenformatmust beRaw, otherwise it must bePKCS8.encryption_algorithm – An instance of an object conforming to the
KeySerializationEncryptioninterface.
- Return bytes:
Serialized key.
- private_bytes_raw()[source]
Allows serialization of the key to raw bytes. This method is a convenience shortcut for calling
private_bytes()withRawencoding,Rawformat, andNoEncryption.This method only returns the seed form of the private key (32 bytes).
- Return bytes:
Raw key (32-byte seed).
- class cryptography.hazmat.primitives.asymmetric.mldsa.MLDSA65PublicKey[source]
Added in version 47.0.0.
- classmethod from_public_bytes(data)[source]
- Parameters:
data (bytes) – 1952 byte public key.
- Returns:
- Raises:
ValueError – If the public key is not 1952 bytes.
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-65 is not supported by the backend
cryptographyis using.
>>> from cryptography.hazmat.primitives import serialization >>> from cryptography.hazmat.primitives.asymmetric import mldsa >>> private_key = mldsa.MLDSA65PrivateKey.generate() >>> public_key = private_key.public_key() >>> public_bytes = public_key.public_bytes( ... encoding=serialization.Encoding.Raw, ... format=serialization.PublicFormat.Raw ... ) >>> loaded_public_key = mldsa.MLDSA65PublicKey.from_public_bytes(public_bytes)
- public_bytes(encoding, format)[source]
Allows serialization of the key to bytes. Encoding (
PEM,DER, orRaw) and format (SubjectPublicKeyInfoorRaw) are chosen to define the exact serialization.- Parameters:
encoding – A value from the
Encodingenum.format – A value from the
PublicFormatenum. If theencodingisRawthenformatmust beRaw, otherwise it must beSubjectPublicKeyInfo.
- Returns bytes:
The public key bytes.
- public_bytes_raw()[source]
Allows serialization of the key to raw bytes. This method is a convenience shortcut for calling
public_bytes()withRawencoding andRawformat.- Return bytes:
1952-byte raw public key.
- verify(signature, data, context=None)[source]
Verify a signature using ML-DSA-65. If a context string was used during signing, the same context must be provided for verification to succeed.
- Parameters:
signature (bytes-like) – The signature to verify.
data (bytes-like) – The data to verify.
context (bytes-like or
None) – An optional context string (up to 255 bytes) that was used during signing.
- Returns:
None
- Raises:
cryptography.exceptions.InvalidSignature – Raised when the signature cannot be verified.
ValueError – If the context is longer than 255 bytes.
- verify_mu(signature, mu)[source]
Added in version 49.0.0.
Verify a signature over a precomputed
mu(message representative), the “external mu” variant from FIPS 204.mucan be computed incrementally withMLDSAMuHasher.- Parameters:
signature (bytes-like) – The signature to verify.
mu (bytes-like) – The 64-byte message representative.
- Returns:
None
- Raises:
cryptography.exceptions.InvalidSignature – Raised when the signature cannot be verified.
ValueError – If
muis not 64 bytes.
- class cryptography.hazmat.primitives.asymmetric.mldsa.MLDSA87PrivateKey[source]
Added in version 47.0.0.
- classmethod generate()[source]
Generate an ML-DSA-87 private key.
- Returns:
- Raises:
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-87 is not supported by the backend
cryptographyis using.
- classmethod from_seed_bytes(data)[source]
Load an ML-DSA-87 private key from seed bytes.
- Parameters:
data (bytes-like) – 32 byte seed.
- Returns:
- Raises:
ValueError – If the seed is not 32 bytes.
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-87 is not supported by the backend
cryptographyis using.
>>> from cryptography.hazmat.primitives.asymmetric import mldsa >>> private_key = mldsa.MLDSA87PrivateKey.generate() >>> seed = private_key.private_bytes_raw() >>> same_key = mldsa.MLDSA87PrivateKey.from_seed_bytes(seed)
- sign(data, context=None)[source]
Sign the data using ML-DSA-87. An optional context string can be provided.
- Parameters:
data (bytes-like) – The data to sign.
context (bytes-like or
None) – An optional context string (up to 255 bytes).
- Returns bytes:
The signature (4627 bytes).
- Raises:
ValueError – If the context is longer than 255 bytes.
- sign_mu(mu)[source]
Added in version 49.0.0.
Sign a precomputed
mu(message representative) using ML-DSA-87, the “external mu” variant from FIPS 204.mucan be computed incrementally withMLDSAMuHasher.- Parameters:
mu (bytes-like) – The 64-byte message representative.
- Returns bytes:
The signature (4627 bytes).
- Raises:
ValueError – If
muis not 64 bytes.
- private_bytes(encoding, format, encryption_algorithm)[source]
Allows serialization of the key to bytes. Encoding (
PEM,DER, orRaw) and format (PKCS8orRaw) are chosen to define the exact serialization.This method only returns the serialization of the seed form of the private key, never the expanded one.
- Parameters:
encoding – A value from the
Encodingenum.format – A value from the
PrivateFormatenum. If theencodingisRawthenformatmust beRaw, otherwise it must bePKCS8.encryption_algorithm – An instance of an object conforming to the
KeySerializationEncryptioninterface.
- Return bytes:
Serialized key.
- private_bytes_raw()[source]
Allows serialization of the key to raw bytes. This method is a convenience shortcut for calling
private_bytes()withRawencoding,Rawformat, andNoEncryption.This method only returns the seed form of the private key (32 bytes).
- Return bytes:
Raw key (32-byte seed).
- class cryptography.hazmat.primitives.asymmetric.mldsa.MLDSA87PublicKey[source]
Added in version 47.0.0.
- classmethod from_public_bytes(data)[source]
- Parameters:
data (bytes) – 2592 byte public key.
- Returns:
- Raises:
ValueError – If the public key is not 2592 bytes.
cryptography.exceptions.UnsupportedAlgorithm – If ML-DSA-87 is not supported by the backend
cryptographyis using.
>>> from cryptography.hazmat.primitives import serialization >>> from cryptography.hazmat.primitives.asymmetric import mldsa >>> private_key = mldsa.MLDSA87PrivateKey.generate() >>> public_key = private_key.public_key() >>> public_bytes = public_key.public_bytes( ... encoding=serialization.Encoding.Raw, ... format=serialization.PublicFormat.Raw ... ) >>> loaded_public_key = mldsa.MLDSA87PublicKey.from_public_bytes(public_bytes)
- public_bytes(encoding, format)[source]
Allows serialization of the key to bytes. Encoding (
PEM,DER, orRaw) and format (SubjectPublicKeyInfoorRaw) are chosen to define the exact serialization.- Parameters:
encoding – A value from the
Encodingenum.format – A value from the
PublicFormatenum. If theencodingisRawthenformatmust beRaw, otherwise it must beSubjectPublicKeyInfo.
- Returns bytes:
The public key bytes.
- public_bytes_raw()[source]
Allows serialization of the key to raw bytes. This method is a convenience shortcut for calling
public_bytes()withRawencoding andRawformat.- Return bytes:
2592-byte raw public key.
- verify(signature, data, context=None)[source]
Verify a signature using ML-DSA-87. If a context string was used during signing, the same context must be provided for verification to succeed.
- Parameters:
signature (bytes-like) – The signature to verify.
data (bytes-like) – The data to verify.
context (bytes-like or
None) – An optional context string (up to 255 bytes) that was used during signing.
- Returns:
None
- Raises:
cryptography.exceptions.InvalidSignature – Raised when the signature cannot be verified.
ValueError – If the context is longer than 255 bytes.
- verify_mu(signature, mu)[source]
Added in version 49.0.0.
Verify a signature over a precomputed
mu(message representative), the “external mu” variant from FIPS 204.mucan be computed incrementally withMLDSAMuHasher.- Parameters:
signature (bytes-like) – The signature to verify.
mu (bytes-like) – The 64-byte message representative.
- Returns:
None
- Raises:
cryptography.exceptions.InvalidSignature – Raised when the signature cannot be verified.
ValueError – If
muis not 64 bytes.
- class cryptography.hazmat.primitives.asymmetric.mldsa.MLDSAMuHasher(public_key, context=None)
Added in version 50.0.0.
Incrementally computes the ML-DSA
mu(message representative) for the “external mu” signing and verification APIs. The message is supplied incrementally withupdate(), so it need not be buffered in memory.- Parameters:
public_key (An ML-DSA public key, e.g.
MLDSA65PublicKey.) – The ML-DSA public key themuis bound to.context (bytes-like or
None) – An optional context string (up to 255 bytes). It must match the context later passed toMLDSA65PublicKey.verify().
- Raises:
TypeError – If
public_keyis not an ML-DSA public key.ValueError – If the context is longer than 255 bytes.
cryptography.exceptions.UnsupportedAlgorithm – If the backend does not support computing
mu.
- update(data)
- Parameters:
data (bytes-like) – The bytes to hash into
mu.- Raises:
cryptography.exceptions.AlreadyFinalized – If
finalize()has already been called.
- copy()
Copy the current state so that
mucan be computed over a common prefix and then diverging suffixes.- Returns:
A new
MLDSAMuHasherwith the same internal state.- Raises:
cryptography.exceptions.AlreadyFinalized – If
finalize()has already been called.
- finalize()
Finalize the hasher and return the computed
mu. After calling this the hasher can no longer be used.- Return bytes:
The 64-byte message representative
mu.- Raises:
cryptography.exceptions.AlreadyFinalized – If
finalize()has already been called.