MLDsa Class
Definition
- Namespace
- Bodu.Security.Cryptography
- Assembly
- Bodu.Security.Cryptography.dll
- Package
- Bodu.Security.Cryptography 1.2.0
- Source
- MLDsa.KeyFormats.cs
Provides the family base class for the ML-DSA module-lattice digital signature algorithm standardized by NIST FIPS 204, exposed through the standard AsymmetricAlgorithm framework. Use the sealed MLDsa44, MLDsa65, or MLDsa87 parameter sets.
public abstract class MLDsa : RawKeyAsymmetricAlgorithm, IDisposable
- Inheritance
-
MLDsa
- Implements
- Derived
- Inherited Members
- Extension Methods
Examples
using var signer = MLDsa65.Create();
signer.GenerateKey();
byte[] signature = signer.SignData(message);
using var verifier = MLDsa65.Create();
verifier.ImportPublicKey(signer.ExportPublicKey());
bool valid = verifier.VerifyData(message, signature);
Remarks
ML-DSA is a digital signature scheme believed secure against quantum adversaries (its hardness rests on the Module-LWE and SelfTargetMSIS problems). Signing accepts an optional context string of at most 255 bytes that domain-separates signatures across applications; a signature created with a context verifies only with the same context.
Hedged versus deterministic signing. By default signing is hedged: each signature mixes 32 fresh random bytes into the nonce derivation, which is the FIPS 204 default and protects against fault-injection and randomness-disclosure attacks. Setting DeterministicSigning to true substitutes the all-zero string, making signatures reproducible for a fixed key and message. Both variants are standard; verification is unaffected.
KeySize semantics. The reported key size is the FIPS 204 parameter-set designator (44, 65, or 87) identifying the matrix dimensions and security category - it is not a key length in bits.
Scope. This type implements pure ML-DSA (the ML-DSA.Sign / ML-DSA.Verify external functions). The pre-hash variant HashML-DSA is deliberately out of scope for this version. Only the raw FIPS 204 byte encodings are supported: the 32-byte seed ξ via ImportPrivateSeed(ReadOnlySpan<byte>) and the encoded keys via ImportPrivateKey(ReadOnlySpan<byte>) (which cross-checks the embedded public-key hash) and ImportPublicKey(ReadOnlySpan<byte>) . The PKCS#8 / SubjectPublicKeyInfo members inherited from AsymmetricAlgorithm are not implemented and retain their base (throwing) behavior.
Memory. When a key is generated or imported, the instance also keeps the values FIPS 204 derives from it on every operation - the matrix Â, the hash tr, and the key's vectors in the form the arithmetic uses - so that signing and verification do not recompute them. Beside the encoded keys they take about 32, 53 and 87 KiB for ML-DSA-44, 65 and 87, or 20, 36 and 64 KiB for an instance holding only a public key.
Verification returns false (never throws) for malformed, non-canonical, or wrong-length signatures. Private key material, the cached secret vectors included, is zeroed on dispose. This implementation offers best-effort side-channel resistance and has not been independently audited.
Fields
MaxContextSizeInBytes
The maximum length, in bytes, of the signature context string.
public const int MaxContextSizeInBytes = 255
Field Value
PrivateSeedSizeInBytes
The size, in bytes, of the private seed ξ accepted by ImportPrivateSeed(ReadOnlySpan<byte>).
public const int PrivateSeedSizeInBytes = 32
Field Value
Properties
AlgorithmName
Gets the FIPS 204 parameter-set name, such as "ML-DSA-65".
public string AlgorithmName { get; }
Property Value
- string
The parameter-set name selected when the instance was created.
Remarks
Unlike the inherited KeySize, which reports a fixed parameter-set designator rather than a meaningful bit length for a post-quantum scheme, this property names the parameter set directly.
DeterministicSigning
Gets or sets a value indicating whether signing is deterministic instead of hedged.
public bool DeterministicSigning { get; set; }
Property Value
HasPrivateKey
Gets a value indicating whether the instance currently holds a private key.
public bool HasPrivateKey { get; }
Property Value
Exceptions
- ObjectDisposedException
The instance has been disposed.
HasPublicKey
Gets a value indicating whether the instance currently holds a public key.
public bool HasPublicKey { get; }
Property Value
Exceptions
- ObjectDisposedException
The instance has been disposed.
KeyExchangeAlgorithm
When overridden in a derived class, gets the name of the key exchange algorithm. Otherwise, throws an NotImplementedException.
public override string? KeyExchangeAlgorithm { get; }
Property Value
- string
The name of the key exchange algorithm.
PrivateKeySizeInBytes
Gets the size, in bytes, of the encoded private key.
public int PrivateKeySizeInBytes { get; }
Property Value
- int
2560, 4032, or 4896 depending on the parameter set.
Exceptions
- ObjectDisposedException
The instance has been disposed.
PublicKeySizeInBytes
Gets the size, in bytes, of the encoded public key.
public int PublicKeySizeInBytes { get; }
Property Value
- int
1312, 1952, or 2592 depending on the parameter set.
Exceptions
- ObjectDisposedException
The instance has been disposed.
SecurityStrengthBits
Gets the claimed security strength of the selected parameter set, in bits (128, 192, or 256 for ML-DSA-44, ML-DSA-65, and ML-DSA-87 respectively, corresponding to NIST security categories 2, 3, and 5).
public int SecurityStrengthBits { get; }
Property Value
- int
The security strength in bits.
SignatureAlgorithm
When implemented in a derived class, gets the name of the signature algorithm. Otherwise, always throws a NotImplementedException.
public override string? SignatureAlgorithm { get; }
Property Value
- string
The name of the signature algorithm.
SignatureSizeInBytes
Gets the size, in bytes, of an encoded signature.
public int SignatureSizeInBytes { get; }
Property Value
- int
2420, 3309, or 4627 depending on the parameter set.
Exceptions
- ObjectDisposedException
The instance has been disposed.
Methods
ExportPrivateKey()
Exports the encoded FIPS 204 private key.
public byte[] ExportPrivateKey()
Returns
- byte[]
A fresh copy of the encoded private key.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- CryptographicException
The instance does not hold a private key.
ExportPublicKey()
Exports the encoded FIPS 204 public key.
public byte[] ExportPublicKey()
Returns
- byte[]
A fresh copy of the encoded public key.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- CryptographicException
The instance does not hold a public key.
FromXmlString(string)
When overridden in a derived class, reconstructs an AsymmetricAlgorithm object from an XML string. Otherwise, throws a NotImplementedException.
public override void FromXmlString(string xmlString)
Parameters
xmlStringstringThe XML string to use to reconstruct the AsymmetricAlgorithm object.
GenerateKey()
Generates a fresh random key pair, replacing any existing key material on the instance.
public void GenerateKey()
Remarks
The 32-byte seed ξ is drawn from a cryptographically secure random source. Any previously held private key is zeroed before being replaced.
Exceptions
- ObjectDisposedException
The instance has been disposed.
ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte>, ReadOnlySpan<byte>, out int)
When overridden in a derived class, imports the public/private keypair from a PKCS#8 EncryptedPrivateKeyInfo structure after decrypting with a byte-based password, replacing the keys for this object.
public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, ReadOnlySpan<byte> source, out int bytesRead)
Parameters
passwordBytesReadOnlySpan<byte>The bytes to use as a password when decrypting the key material.
sourceReadOnlySpan<byte>The bytes of a PKCS#8 EncryptedPrivateKeyInfo structure in the ASN.1-BER encoding.
bytesReadintWhen this method returns, contains a value that indicates the number of bytes read from
source. This parameter is treated as uninitialized.
Exceptions
- CryptographicException
The password is incorrect.
-or-
The contents of
sourceindicate the Key Derivation Function (KDF) to apply is the legacy PKCS#12 KDF, which requires char-based passwords.-or-
The contents of
sourcedo not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.-or-
The contents of
sourceindicate the key is for an algorithm other than the algorithm represented by this instance.-or-
The contents of
sourcerepresent the key in a format that is not supported.-or-
The algorithm-specific key import failed.
- NotImplementedException
A derived type has not overriden this member.
ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<char>, ReadOnlySpan<byte>, out int)
When overridden in a derived class, imports the public/private keypair from a PKCS#8 EncryptedPrivateKeyInfo structure after decrypting with a char-based password, replacing the keys for this object.
public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, ReadOnlySpan<byte> source, out int bytesRead)
Parameters
passwordReadOnlySpan<char>The password to use for decrypting the key material.
sourceReadOnlySpan<byte>The bytes of a PKCS#8 EncryptedPrivateKeyInfo structure in the ASN.1-BER encoding.
bytesReadintWhen this method returns, contains a value that indicates the number of bytes read from
source. This parameter is treated as uninitialized.
Exceptions
- CryptographicException
The password is incorrect.
-or-
The contents of
sourcedo not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.-or-
The contents of
sourceindicate the key is for an algorithm other than the algorithm represented by this instance.-or-
The contents of
sourcerepresent the key in a format that is not supported.-or-
The algorithm-specific key import failed.
- NotImplementedException
A derived type has not overriden this member.
ImportPkcs8PrivateKey(ReadOnlySpan<byte>, out int)
When overriden in a derived class, imports the public/private keypair from a PKCS#8 PrivateKeyInfo structure after decryption, replacing the keys for this object.
public override void ImportPkcs8PrivateKey(ReadOnlySpan<byte> source, out int bytesRead)
Parameters
sourceReadOnlySpan<byte>The bytes of a PKCS#8 PrivateKeyInfo structure in the ASN.1-BER encoding.
bytesReadintWhen this method returns, contains a value that indicates the number of bytes read from
source. This parameter is treated as uninitialized.
Exceptions
- CryptographicException
The contents of
sourcedo not represent an ASN.1-BER-encoded PKCS#8 PrivateKeyInfo structure.-or-
The contents of
sourceindicate the key is for an algorithm other than the algorithm represented by this instance.-or-
The contents of
sourcerepresent the key in a format that is not supported.-or-
The algorithm-specific key import failed.
- NotImplementedException
A derived type has not overriden this member.
ImportPrivateKey(ReadOnlySpan<byte>)
Imports an encoded FIPS 204 private key, recomputing and caching the matching public key, and replacing any existing key material on the instance.
public void ImportPrivateKey(ReadOnlySpan<byte> privateKey)
Parameters
privateKeyReadOnlySpan<byte>The encoded private key ρ ‖ K ‖ tr ‖ s₁ ‖ s₂ ‖ t₀.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- ArgumentException
privateKeydoes not have the exact parameter-set length; encodes an s₁ or s₂ coefficient outside its canonical [−η, η] range; carries a t₀ vector inconsistent with the low bits recomputed from the secret vectors; or its embedded tr hash does not match the public key recomputed from those vectors.
ImportPrivateSeed(ReadOnlySpan<byte>)
Imports the FIPS 204 32-byte private seed ξ and regenerates the full key pair from it, replacing any existing key material on the instance.
public void ImportPrivateSeed(ReadOnlySpan<byte> seed)
Parameters
seedReadOnlySpan<byte>The 32-byte key-generation seed ξ.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- ArgumentException
seedis not exactly 32 bytes long.
ImportPublicKey(ReadOnlySpan<byte>)
Imports an encoded FIPS 204 public key, replacing any existing key material on the instance.
public void ImportPublicKey(ReadOnlySpan<byte> publicKey)
Parameters
publicKeyReadOnlySpan<byte>The encoded public key ρ ‖ t₁.
Remarks
Any private key previously held by the instance is zeroed and discarded, leaving a verify-only instance.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- ArgumentException
publicKeydoes not have the exact parameter-set length.
ImportSubjectPublicKeyInfo(ReadOnlySpan<byte>, out int)
When overriden in a derived class, imports the public key from an X.509 SubjectPublicKeyInfo structure after decryption, replacing the keys for this object.
public override void ImportSubjectPublicKeyInfo(ReadOnlySpan<byte> source, out int bytesRead)
Parameters
sourceReadOnlySpan<byte>The bytes of an X.509 SubjectPublicKeyInfo structure in the ASN.1-DER encoding.
bytesReadintWhen this method returns, contains a value that indicates the number of bytes read from
source. This parameter is treated as uninitialized.
Exceptions
- CryptographicException
The contents of
sourcedo not represent an ASN.1-DER-encoded X.509 SubjectPublicKeyInfo structure.-or-
The contents of
sourceindicate the key is for an algorithm other than the algorithm represented by this instance.-or-
The contents of
sourcerepresent the key in a format that is not supported.-or-
The algorithm-specific key import failed.
- NotImplementedException
A derived type has not overriden this member.
SignData(ReadOnlySpan<byte>)
Signs the supplied data with an empty context string.
public byte[] SignData(ReadOnlySpan<byte> data)
Parameters
dataReadOnlySpan<byte>The message bytes to sign. May be empty.
Returns
- byte[]
The encoded signature.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- CryptographicException
The instance does not hold a private key.
SignData(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Signs the supplied data under a context string.
public byte[] SignData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context)
Parameters
dataReadOnlySpan<byte>The message bytes to sign. May be empty.
contextReadOnlySpan<byte>The domain-separation context string of at most 255 bytes. May be empty.
Returns
- byte[]
The encoded signature.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- ArgumentException
contextis longer than 255 bytes.- CryptographicException
The instance does not hold a private key.
SignData(ReadOnlySpan<byte>, ReadOnlySpan<byte>, Span<byte>)
Signs the supplied data under a context string, writing the encoded signature into
destination.
public void SignData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, Span<byte> destination)
Parameters
dataReadOnlySpan<byte>The message bytes to sign. May be empty.
contextReadOnlySpan<byte>The domain-separation context string of at most 255 bytes. May be empty.
destinationSpan<byte>The span receiving the signature. Must be exactly SignatureSizeInBytes bytes.
Exceptions
- ObjectDisposedException
The instance has been disposed.
- ArgumentException
contextis longer than 255 bytes, ordestinationdoes not have the exact signature length.- CryptographicException
The instance does not hold a private key.
ToXmlString(bool)
When overridden in a derived class, creates and returns an XML string representation of the current AsymmetricAlgorithm object. Otherwise, throws a NotImplementedException.
public override string ToXmlString(bool includePrivateParameters)
Parameters
Returns
- string
An XML string encoding of the current AsymmetricAlgorithm object.
TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte>, PbeParameters, Span<byte>, out int)
When overridden in a derived class, attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo format into a provided buffer, using a byte-based password.
public override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, PbeParameters pbeParameters, Span<byte> destination, out int bytesWritten)
Parameters
passwordBytesReadOnlySpan<byte>The bytes to use as a password when encrypting the key material.
pbeParametersPbeParametersThe password-based encryption (PBE) parameters to use when encrypting the key material.
destinationSpan<byte>The byte span to receive the PKCS#8 EncryptedPrivateKeyInfo data.
bytesWrittenintWhen this method returns, contains a value that indicates the number of bytes written to
destination. This parameter is treated as uninitialized.
Returns
Exceptions
- CryptographicException
The key could not be exported.
-or-
pbeParametersindicates that TripleDes3KeyPkcs12 should be used, which requires char-based passwords.- NotImplementedException
A derived type has not overriden this member.
TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<char>, PbeParameters, Span<byte>, out int)
When overriden in a derived class, attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo format into a provided buffer, using a char-based password.
public override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, PbeParameters pbeParameters, Span<byte> destination, out int bytesWritten)
Parameters
passwordReadOnlySpan<char>The password to use when encrypting the key material.
pbeParametersPbeParametersThe password-based encryption (PBE) parameters to use when encrypting the key material.
destinationSpan<byte>The byte span to receive the PKCS#8 EncryptedPrivateKeyInfo data.
bytesWrittenintWhen this method returns, contains a value that indicates the number of bytes written to
destination. This parameter is treated as uninitialized.
Returns
Exceptions
- CryptographicException
The key could not be exported.
- NotImplementedException
A derived type has not overriden this member.
TryExportPkcs8PrivateKey(Span<byte>, out int)
When overridden in a derived class, attempts to export the current key in the PKCS#8 PrivateKeyInfo format into a provided buffer.
public override bool TryExportPkcs8PrivateKey(Span<byte> destination, out int bytesWritten)
Parameters
destinationSpan<byte>The byte span to receive the PKCS#8 PrivateKeyInfo data.
bytesWrittenintWhen this method returns, contains a value that indicates the number of bytes written to
destination. This parameter is treated as uninitialized.
Returns
Exceptions
- CryptographicException
The key could not be exported.
- NotImplementedException
A derived type has not overriden this member.
TryExportSubjectPublicKeyInfo(Span<byte>, out int)
When overridden in a derived class, attempts to export the current key in the X.509 SubjectPublicKeyInfo format into a provided buffer.
public override bool TryExportSubjectPublicKeyInfo(Span<byte> destination, out int bytesWritten)
Parameters
destinationSpan<byte>The byte span to receive the X.509 SubjectPublicKeyInfo data.
bytesWrittenintWhen this method returns, contains a value that indicates the number of bytes written to
destination. This parameter is treated as uninitialized.
Returns
Exceptions
- CryptographicException
The key could not be exported.
- NotImplementedException
A derived type has not overriden this member.
VerifyData(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Verifies a signature over the supplied data with an empty context string.
public bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature)
Parameters
dataReadOnlySpan<byte>The message bytes that were signed. May be empty.
signatureReadOnlySpan<byte>The candidate encoded signature.
Returns
Exceptions
- ObjectDisposedException
The instance has been disposed.
- CryptographicException
The instance does not hold a public key.
VerifyData(ReadOnlySpan<byte>, ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Verifies a signature over the supplied data under a context string.
public bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, ReadOnlySpan<byte> context)
Parameters
dataReadOnlySpan<byte>The message bytes that were signed. May be empty.
signatureReadOnlySpan<byte>The candidate encoded signature.
contextReadOnlySpan<byte>The domain-separation context string used at signing time. May be empty.
Returns
Exceptions
- ObjectDisposedException
The instance has been disposed.
- ArgumentException
contextis longer than 255 bytes.- CryptographicException
The instance does not hold a public key.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |