-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Labels
area-System.Securitycryptographic-docs-impactIssues impacting cryptographic docs. Cleared and reused after documentation is updated each release.Issues impacting cryptographic docs. Cleared and reused after documentation is updated each release.
Milestone
Description
As part of the Post-Quantum Cryptography effort, we should add support for Module-Lattice-Based Digital Signature Algorithm (ML-DSA).
As a signature algorithm, ML-DSA should be available as a primitive, as well as integrated into:
- X509Certificate2
- SignedXml
- COSE
- TLS (no API required, carried with the certificate)
Based on Elliptic-Curve Digital Signature Algorithm's name of "EC-DSA" becoming ECDsa
, the class name for ML-DSA is proposed as MLDsa
.
namespace System.Security.Cryptography
{
[Experimental("SYSLIB5006")]
public abstract class MLDsa : IDisposable
{
public static bool IsSupported { get; }
protected MLDsa(MLDsaAlgorithm algorithm);
public MLDsaAlgorithm Algorithm { get; }
public int SignatureSizeInBytes { get; }
public void Dispose();
public int SignData(
ReadOnlySpan<byte> data,
Span<byte> destination,
ReadOnlySpan<byte> context = default);
public bool VerifyData(
ReadOnlySpan<byte> data,
ReadOnlySpan<byte> signature,
ReadOnlySpan<byte> context = default);
public int SignPreHash(
ReadOnlySpan<byte> hash,
Span<byte> destination,
HashAlgorithmName preHashAlgorithm,
ReadOnlySpan<byte> context = default);
public bool SignPreHash(
ReadOnlySpan<byte> hash,
ReadOnlySpan<byte> signature,
HashAlgorithmName preHashAlgorithm,
ReadOnlySpan<byte> context = default);
public byte[] ExportSubjectPublicKeyInfo();
public bool TryExportSubjectPublicKeyInfo(Span<byte> destination, out int bytesWritten);
public string ExportSubjectPublicKeyInfoPem();
public byte[] ExportPkcs8PrivateKey();
public bool TryExportPkcs8PrivateKey(Span<byte> destination, out int bytesWritten);
public string ExportPkcs8PrivateKeyPem();
public byte[] ExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<char> password,
PbeParameters pbeParameters);
public byte[] ExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<byte> passwordBytes,
PbeParameters pbeParameters);
public bool TryExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<char> password,
PbeParameters pbeParameters,
Span<byte> destination,
out int bytesWritten);
public bool TryExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<byte> passwordBytes,
PbeParameters pbeParameters,
Span<byte> destination,
out int bytesWritten);
public string ExportEncryptedPkcs8PrivateKeyPem(
ReadOnlySpan<char> password,
PbeParameters pbeParameters);
public string ExportEncryptedPkcs8PrivateKeyPem(
ReadOnlySpan<byte> passwordBytes,
PbeParameters pbeParameters);
public int ExportMLDsaPublicKey(Span<byte> destination);
public int ExportMLDsaSecretKey(Span<byte> destination);
public int ExportMLDsaPrivateSeed(Span<byte> destination);
public static MLDsa GenerateMLDsa44Key();
public static MLDsa GenerateMLDsa65Key();
public static MLDsa GenerateMLDsa87Key();
public static MLDsa ImportSubjectPublicKeyInfo(ReadOnlySpan<byte> source);
public static MLDsa ImportPkcs8PrivateKey(ReadOnlySpan<byte> source);
public static MLDsa ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, ReadOnlySpan<byte> source);
public static MLDsa ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, ReadOnlySpan<byte> source);
public static MLDsa ImportFromPem(ReadOnlySpan<char> source);
public static MLDsa ImportFromEncryptedPem(ReadOnlySpan<char> source, ReadOnlySpan<char> password);
public static MLDsa ImportFromEncryptedPem(ReadOnlySpan<char> source, ReadOnlySpan<byte> passwordBytes);
public static MLDsa ImportMLDsaPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source);
public static MLDsa ImportMLDsaSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source);
public static MLDsa ImportMLDsaPrivateSeed(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source);
protected void ThrowIfDisposed();
protected virtual void Dispose(bool disposing);
protected abstract void SignDataCore(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, Span<byte> destination);
protected abstract bool VerifyDataCore(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, ReadOnlySpan<byte> signature);
protected abstract void SignPreHashCore(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> context, HashAlgorithmName preHashAlgorithm, Span<byte> destination);
protected abstract bool VerifyPreHashCore(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> context, HashAlgorithmName preHashAlgorithm, ReadOnlySpan<byte> signature);
protected abstract void ExportMLDsaPublicKeyCore(Span<byte> destination);
protected abstract void ExportMLDsaSecretKeyCore(Span<byte> destination);
protected abstract void ExportMLDsaPrivateSeedCore(Span<byte> destination);
}
[DebuggerDisplay("{Name,nq}")]
[Experimental("SYSLIB5006")]
public sealed class MLDsaAlgorithm
{
private MLDsaAlgorithm();
public static MLDsaAlgorithm MLDsa44 { get; }
public static MLDsaAlgorithm MLDsa65 { get; }
public static MLDsaAlgorithm MLDsa87 { get; }
public string Name { get; }
public int PublicKeySizeInBytes { get; }
public int SecretKeySizeInBytes { get; }
public int SignatureSizeInBytes { get; }
}
[Experimental("SYSLIB5006")]
public class MLDsaCng : MLDsa
{
public MLDsaCng(CngKey key);
// On ECDsaCng this is an allocating property. Changed to a method here.
public CngKey GetCngKey();
}
[Experimental("SYSLIB5006")]
public class MLDsaOpenSsl : MLDsa
{
public MLDsaOpenSsl(SafeEvpPKeyHandle keyHandle);
public SafeEvpPKeyHandle DuplicateKeyHandle();
}
}
namespace System.Security.Cryptography.X509Certificates
{
// Extension class to enable porting to Microsoft.Bcl.Cryptography
[Experimental("SYSLIB5006")]
public sealed class MLDsaCertificateExtensions
{
public static MLDsa GetMLDsaPublicKey(this X509Certificate2 certificate);
public static MLDsa GetMLDsaPrivateKey(this X509Certificate2 certificate);
}
public partial class CertificateRequest
{
[Experimental("SYSLIB5006")]
public CertificateRequest(string subjectName, MLDsa key);
[Experimental("SYSLIB5006")]
public CertificateRequest(X500DistinguishedName subjectName, MLDsa key);
}
#if NET10_OR_GREATER
public partial class X509SignatureGenerator
{
[Experimental("SYSLIB5006")]
public static X509SignatureGenerator CreateForMLDsa(MLDsa key);
}
#endif
}
#if NET10_OR_GREATER
namespace System.Security.Cryptography.Pkcs
{
public partial class CmsSigner
{
[Experimental("SYSLIB5006")]
public CmsSigner(
X509Certificate2 certificate,
MLDsa privateKey,
SubjectIdentifierType signerIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier);
}
}
#endif
namespace System.Security.Cryptography.Cose
{
public partial class CoseSigner
{
// As PrivateKey is marked as non-nullable, this will set it to an instance of a non-public type that wraps the key.
[Experimental("SYSLIB5006")]
public CoseSigner(MLDsa key);
}
}
Sub-issues
Metadata
Metadata
Assignees
Labels
area-System.Securitycryptographic-docs-impactIssues impacting cryptographic docs. Cleared and reused after documentation is updated each release.Issues impacting cryptographic docs. Cleared and reused after documentation is updated each release.