diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs index ace8f116be1a51..0e23b6c4663b33 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs @@ -89,8 +89,15 @@ protected CompositeMLDsa(CompositeMLDsaAlgorithm algorithm) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsAlgorithmSupported(CompositeMLDsaAlgorithm algorithm) => - CompositeMLDsaImplementation.IsAlgorithmSupportedImpl(algorithm); + /// + /// is . + /// + public static bool IsAlgorithmSupported(CompositeMLDsaAlgorithm algorithm) + { + ArgumentNullException.ThrowIfNull(algorithm); + + return CompositeMLDsaImplementation.IsAlgorithmSupportedImpl(algorithm); + } /// /// Signs the specified data. @@ -136,23 +143,32 @@ public byte[] SignData(byte[] data, byte[]? context = default) ThrowIfDisposed(); - // TODO If we know exact size of signature, then we can allocate instead of renting and copying. - byte[] rented = CryptoPool.Rent(Algorithm.MaxSignatureSizeInBytes); - - try + if (Algorithm.SignatureSize.IsExact) { - if (!TrySignDataCore(new ReadOnlySpan(data), new ReadOnlySpan(context), rented, out int written)) + byte[] signature = new byte[Algorithm.MaxSignatureSizeInBytes]; + int bytesWritten = SignDataCore(new ReadOnlySpan(data), new ReadOnlySpan(context), signature); + + if (signature.Length != bytesWritten) { - Debug.Fail($"Signature exceeds {nameof(Algorithm.MaxSignatureSizeInBytes)} ({Algorithm.MaxSignatureSizeInBytes})."); throw new CryptographicException(); } - return rented.AsSpan(0, written).ToArray(); + return signature; } - finally + + using (CryptoPoolLease lease = CryptoPoolLease.Rent(Algorithm.MaxSignatureSizeInBytes, skipClear: true)) { - // Signature does not contain sensitive information. - CryptoPool.Return(rented, clearSize: 0); + int bytesWritten = SignDataCore( + new ReadOnlySpan(data), + new ReadOnlySpan(context), + lease.Span); + + if (!Algorithm.SignatureSize.IsValidSize(bytesWritten)) + { + throw new CryptographicException(); + } + + return lease.Span.Slice(0, bytesWritten).ToArray(); } } @@ -163,20 +179,18 @@ public byte[] SignData(byte[] data, byte[]? context = default) /// The data to sign. /// /// - /// The buffer to receive the signature. + /// The buffer to receive the signature. Its length must be at least . /// /// /// An optional context-specific value to limit the scope of the signature. /// The default value is an empty buffer. /// - /// - /// When this method returns, contains the number of bytes written to the buffer. - /// This parameter is treated as uninitialized. - /// /// - /// if was large enough to hold the result; - /// otherwise, . + /// The number of bytes written to the buffer. /// + /// + /// is less than in length. + /// /// /// has a in excess of /// 255 bytes. @@ -189,10 +203,7 @@ public byte[] SignData(byte[] data, byte[]? context = default) /// -or- /// An error occurred while signing the data. /// - /// - /// The signature will be at most in length. - /// - public bool TrySignData(ReadOnlySpan data, Span destination, out int bytesWritten, ReadOnlySpan context = default) + public int SignData(ReadOnlySpan data, Span destination, ReadOnlySpan context = default) { if (context.Length > MaxContextLength) { @@ -202,15 +213,24 @@ public bool TrySignData(ReadOnlySpan data, Span destination, out int SR.Argument_SignatureContextTooLong255); } + if (destination.Length < Algorithm.MaxSignatureSizeInBytes) + { + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + } + ThrowIfDisposed(); - if (destination.Length < Algorithm.MLDsaAlgorithm.SignatureSizeInBytes) + int bytesWritten = SignDataCore(data, context, destination.Slice(0, Algorithm.MaxSignatureSizeInBytes)); + + // Make sure minimum size is also satisfied. + if (!Algorithm.SignatureSize.IsValidSize(bytesWritten)) { - bytesWritten = 0; - return false; + CryptographicOperations.ZeroMemory(destination); + + throw new CryptographicException(); } - return TrySignDataCore(data, context, destination, out bytesWritten); + return bytesWritten; } /// @@ -224,20 +244,15 @@ public bool TrySignData(ReadOnlySpan data, Span destination, out int /// The signature context. /// /// - /// The buffer to receive the signature, whose length will be at least the ML-DSA component's signature size. - /// - /// - /// When this method returns, contains the number of bytes written to the buffer. - /// This parameter is treated as uninitialized. + /// The buffer to receive the signature, whose length will be exactly . /// /// - /// if was large enough to hold the result; - /// otherwise, . + /// The number of bytes written to the buffer. /// /// /// An error occurred while signing the data. /// - protected abstract bool TrySignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination, out int bytesWritten); + protected abstract int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination); /// /// Verifies that the specified signature is valid for this key and the provided data. @@ -316,7 +331,7 @@ public bool VerifyData(ReadOnlySpan data, ReadOnlySpan signature, Re ThrowIfDisposed(); - if (signature.Length < Algorithm.MLDsaAlgorithm.SignatureSizeInBytes) + if (!Algorithm.SignatureSize.IsValidSize(signature.Length)) { return false; } @@ -660,9 +675,9 @@ static void SubjectPublicKeyReader(ReadOnlyMemory key, in AlgorithmIdentif { CompositeMLDsaAlgorithm algorithm = GetAlgorithmIdentifier(in identifier); - if (key.Length < algorithm.MLDsaAlgorithm.PublicKeySizeInBytes) + if (!algorithm.PublicKeySize.IsValidSize(key.Length)) { - throw new CryptographicException(SR.Argument_PublicKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm); } dsa = CompositeMLDsaImplementation.ImportCompositeMLDsaPublicKeyImpl(algorithm, key.Span); @@ -859,15 +874,27 @@ static void PrivateKeyReader( throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - if (key.Length < algorithm.MLDsaAlgorithm.PrivateSeedSizeInBytes) + if (!algorithm.PrivateKeySize.IsValidSize(key.Length)) { - throw new CryptographicException(SR.Argument_PrivateKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); } dsa = CompositeMLDsaImplementation.ImportCompositeMLDsaPrivateKeyImpl(algorithm, key); } } + /// + /// + /// or is . + /// + public static CompositeMLDsa ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm algorithm, byte[] source) + { + ArgumentNullException.ThrowIfNull(algorithm); + ArgumentNullException.ThrowIfNull(source); + + return ImportCompositeMLDsaPublicKey(algorithm, new ReadOnlySpan(source)); + } + /// /// Imports a Composite ML-DSA public key. /// @@ -895,15 +922,29 @@ static void PrivateKeyReader( /// public static CompositeMLDsa ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) { + ArgumentNullException.ThrowIfNull(algorithm); ThrowIfNotSupported(algorithm); - if (source.Length < algorithm.MLDsaAlgorithm.PublicKeySizeInBytes) + if (!algorithm.PublicKeySize.IsValidSize(source.Length)) { - throw new CryptographicException(SR.Argument_PublicKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm); } return CompositeMLDsaImplementation.ImportCompositeMLDsaPublicKeyImpl(algorithm, source); } + + /// + /// + /// or is . + /// + public static CompositeMLDsa ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm algorithm, byte[] source) + { + ArgumentNullException.ThrowIfNull(algorithm); + ArgumentNullException.ThrowIfNull(source); + + return ImportCompositeMLDsaPrivateKey(algorithm, new ReadOnlySpan(source)); + } + /// /// Imports a Composite ML-DSA private key. /// @@ -931,11 +972,12 @@ public static CompositeMLDsa ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorit /// public static CompositeMLDsa ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) { + ArgumentNullException.ThrowIfNull(algorithm); ThrowIfNotSupported(algorithm); - if (source.Length < algorithm.MLDsaAlgorithm.PrivateSeedSizeInBytes) + if (!algorithm.PrivateKeySize.IsValidSize(source.Length)) { - throw new CryptographicException(SR.Argument_PrivateKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); } return CompositeMLDsaImplementation.ImportCompositeMLDsaPrivateKeyImpl(algorithm, source); @@ -1346,7 +1388,7 @@ public bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritte // The bound can be tightened but private key length of some traditional algorithms, // can vary and aren't worth the complex calculation. - int minimumPossiblePkcs8Key = Algorithm.MLDsaAlgorithm.PrivateSeedSizeInBytes; + int minimumPossiblePkcs8Key = Algorithm.PrivateKeySize.MinimumSizeInBytes; if (destination.Length < minimumPossiblePkcs8Key) { @@ -1465,6 +1507,13 @@ public byte[] ExportCompositeMLDsaPublicKey() { ThrowIfDisposed(); + if (Algorithm.PublicKeySize.IsExact) + { + return ExportExactSize( + Algorithm.PublicKeySize.MinimumSizeInBytes, + static (key, dest, out written) => key.TryExportCompositeMLDsaPublicKey(dest, out written)); + } + return ExportPublicKeyCallback(static publicKey => publicKey.ToArray()); } @@ -1492,9 +1541,28 @@ public bool TryExportCompositeMLDsaPublicKey(Span destination, out int byt { ThrowIfDisposed(); - // TODO short-circuit based on known required length lower bounds + if (Algorithm.PublicKeySize.IsAlwaysLargerThan(destination.Length)) + { + bytesWritten = 0; + return false; + } + + if (TryExportCompositeMLDsaPublicKeyCore(destination, out int written)) + { + if (!Algorithm.PublicKeySize.IsValidSize(written)) + { + CryptographicOperations.ZeroMemory(destination); - return TryExportCompositeMLDsaPublicKeyCore(destination, out bytesWritten); + bytesWritten = 0; + throw new CryptographicException(); + } + + bytesWritten = written; + return true; + } + + bytesWritten = 0; + return false; } /// @@ -1513,12 +1581,16 @@ public byte[] ExportCompositeMLDsaPrivateKey() { ThrowIfDisposed(); - // TODO The private key has a max size so add it as CompositeMLDsaAlgorithm.MaxPrivateKeySize and use it here. - int initalSize = 1; + if (Algorithm.PrivateKeySize.IsExact) + { + return ExportExactSize( + Algorithm.PrivateKeySize.MinimumSizeInBytes, + static (key, dest, out written) => key.TryExportCompositeMLDsaPrivateKey(dest, out written)); + } return ExportWithCallback( - initalSize, - static (key, dest, out written) => key.TryExportCompositeMLDsaPrivateKeyCore(dest, out written), + Algorithm.PrivateKeySize.InitialExportBufferSizeInBytes, + static (key, dest, out written) => key.TryExportCompositeMLDsaPrivateKey(dest, out written), static privateKey => privateKey.ToArray()); } @@ -1546,9 +1618,28 @@ public bool TryExportCompositeMLDsaPrivateKey(Span destination, out int by { ThrowIfDisposed(); - // TODO short-circuit based on known required length lower bounds + if (Algorithm.PrivateKeySize.IsAlwaysLargerThan(destination.Length)) + { + bytesWritten = 0; + return false; + } + + if (TryExportCompositeMLDsaPrivateKeyCore(destination, out int written)) + { + if (!Algorithm.PrivateKeySize.IsValidSize(written)) + { + CryptographicOperations.ZeroMemory(destination); + + bytesWritten = 0; + throw new CryptographicException(); + } + + bytesWritten = written; + return true; + } - return TryExportCompositeMLDsaPrivateKeyCore(destination, out bytesWritten); + bytesWritten = 0; + return false; } /// @@ -1570,7 +1661,7 @@ public bool TryExportCompositeMLDsaPrivateKey(Span destination, out int by /// /// An error occurred while exporting the key. /// - protected abstract bool TryExportCompositeMLDsaPublicKeyCore(ReadOnlySpan destination, out int bytesWritten); + protected abstract bool TryExportCompositeMLDsaPublicKeyCore(Span destination, out int bytesWritten); /// /// When overridden in a derived class, attempts to export the private key portion of the current key. @@ -1591,7 +1682,7 @@ public bool TryExportCompositeMLDsaPrivateKey(Span destination, out int by /// /// An error occurred while exporting the key. /// - protected abstract bool TryExportCompositeMLDsaPrivateKeyCore(ReadOnlySpan destination, out int bytesWritten); + protected abstract bool TryExportCompositeMLDsaPrivateKeyCore(Span destination, out int bytesWritten); /// /// Releases all resources used by the class. @@ -1670,8 +1761,7 @@ private AsnWriter WritePkcs8ToAsnWriter() private TResult ExportPkcs8PrivateKeyCallback(ProcessExportedContent func) { - // TODO Pick a good estimate for the initial size of the buffer. - int initialSize = 1; + int initialSize = Algorithm.PrivateKeySize.InitialExportBufferSizeInBytes; return ExportWithCallback( initialSize, @@ -1708,13 +1798,9 @@ private AsnWriter WriteSubjectPublicKeyToAsnWriter() private TResult ExportPublicKeyCallback(ProcessExportedContent func) { - // TODO RSA is the only algo without a strict max size. The exponent can be arbitrarily large, - // but in practice it is always 65537. Add an internal CompositeMLDsaAlgorithm.EstimatedMaxPublicKeySizeInBytes and use that here. - int initialSize = 1; - return ExportWithCallback( - initialSize, - static (key, dest, out written) => key.TryExportCompositeMLDsaPublicKeyCore(dest, out written), + Algorithm.PublicKeySize.InitialExportBufferSizeInBytes, + static (key, dest, out written) => key.TryExportCompositeMLDsaPublicKey(dest, out written), func); } @@ -1756,6 +1842,20 @@ private TResult ExportWithCallback( } } + private byte[] ExportExactSize(int exactSize, TryExportFunc tryExportFunc) + { + byte[] ret = new byte[exactSize]; + + if (!tryExportFunc(this, ret, out int written) || written != exactSize) + { + CryptographicOperations.ZeroMemory(ret); + + throw new CryptographicException(); + } + + return ret; + } + private static CompositeMLDsaAlgorithm GetAlgorithmIdentifier(ref readonly AlgorithmIdentifierAsn identifier) { CompositeMLDsaAlgorithm? algorithm = CompositeMLDsaAlgorithm.GetAlgorithmFromOid(identifier.Algorithm); @@ -1771,7 +1871,7 @@ private static CompositeMLDsaAlgorithm GetAlgorithmIdentifier(ref readonly Algor return algorithm; } - internal static void ThrowIfNotSupported() + private static void ThrowIfNotSupported() { if (!IsSupported) { @@ -1779,7 +1879,7 @@ internal static void ThrowIfNotSupported() } } - internal static void ThrowIfNotSupported(CompositeMLDsaAlgorithm algorithm) + private static void ThrowIfNotSupported(CompositeMLDsaAlgorithm algorithm) { if (!IsSupported || !IsAlgorithmSupported(algorithm)) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs index 60caef2db61fcb..f7b7239204b124 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; using Internal.Cryptography; @@ -14,6 +15,8 @@ namespace System.Security.Cryptography [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public sealed class CompositeMLDsaAlgorithm : IEquatable { + internal const int RandomizerSizeInBytes = 32; + /// /// Gets the name of the algorithm. /// @@ -28,22 +31,28 @@ public sealed class CompositeMLDsaAlgorithm : IEquatable /// The maximum signature size in bytes for the composite algorithm. /// - public int MaxSignatureSizeInBytes { get; } + public int MaxSignatureSizeInBytes => SignatureSize.MaximumSizeInBytes!.Value; - internal MLDsaAlgorithm MLDsaAlgorithm { get; } + internal SizeRange SignatureSize { get; } + internal SizeRange PrivateKeySize { get; } + internal SizeRange PublicKeySize { get; } internal string Oid { get; } private CompositeMLDsaAlgorithm( string name, - MLDsaAlgorithm mlDsaAlgorithm, - int maxTraditionalSignatureSize, + SizeRange signatureSize, + SizeRange privateKeySize, + SizeRange publicKeySize, string oid) { + Debug.Assert(signatureSize.MaximumSizeInBytes is not null); + Name = name; - MLDsaAlgorithm = mlDsaAlgorithm; - MaxSignatureSizeInBytes = MLDsaAlgorithm.SignatureSizeInBytes + maxTraditionalSignatureSize; Oid = oid; + SignatureSize = signatureSize; + PrivateKeySize = privateKeySize; + PublicKeySize = publicKeySize; } /// @@ -53,7 +62,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and 2048-bit RSASSA-PSS with SHA256 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithRSA2048Pss { get; } = - new("MLDSA44-RSA2048-PSS-SHA256", MLDsaAlgorithm.MLDsa44, 2048 / 8, Oids.MLDsa44WithRSA2048PssPreHashSha256); + CreateRsa( + "MLDSA44-RSA2048-PSS-SHA256", + MLDsaAlgorithm.MLDsa44, + 2048, + Oids.MLDsa44WithRSA2048PssPreHashSha256); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-44 and 2048-bit RSASSA-PKCS1-v1_5 with SHA256 algorithm. @@ -62,7 +75,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and 2048-bit RSASSA-PKCS1-v1_5 with SHA256 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithRSA2048Pkcs15 { get; } = - new("MLDSA44-RSA2048-PKCS15-SHA256", MLDsaAlgorithm.MLDsa44, 2048 / 8, Oids.MLDsa44WithRSA2048Pkcs15PreHashSha256); + CreateRsa( + "MLDSA44-RSA2048-PKCS15-SHA256", + MLDsaAlgorithm.MLDsa44, + 2048, + Oids.MLDsa44WithRSA2048Pkcs15PreHashSha256); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-44 and Ed25519 algorithm. @@ -71,7 +88,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and Ed25519 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithEd25519 { get; } = - new("MLDSA44-Ed25519-SHA512", MLDsaAlgorithm.MLDsa44, 64, Oids.MLDsa44WithEd25519PreHashSha512); + CreateEdDsa( + "MLDSA44-Ed25519-SHA512", + MLDsaAlgorithm.MLDsa44, + 32 * 8, + Oids.MLDsa44WithEd25519PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-44 and ECDSA P-256 with SHA256 algorithm. @@ -80,7 +101,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and ECDSA P-256 with SHA256 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithECDsaP256 { get; } = - new("MLDSA44-ECDSA-P256-SHA256", MLDsaAlgorithm.MLDsa44, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(256), Oids.MLDsa44WithECDsaP256PreHashSha256); + CreateECDsa( + "MLDSA44-ECDSA-P256-SHA256", + MLDsaAlgorithm.MLDsa44, + 256, + Oids.MLDsa44WithECDsaP256PreHashSha256); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PSS with SHA512 algorithm. @@ -89,7 +114,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA3072Pss { get; } = - new("MLDSA65-RSA3072-PSS-SHA512", MLDsaAlgorithm.MLDsa65, 3072 / 8, Oids.MLDsa65WithRSA3072PssPreHashSha512); + CreateRsa( + "MLDSA65-RSA3072-PSS-SHA512", + MLDsaAlgorithm.MLDsa65, + 3072, + Oids.MLDsa65WithRSA3072PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. @@ -98,7 +127,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA3072Pkcs15 { get; } = - new("MLDSA65-RSA3072-PKCS15-SHA512", MLDsaAlgorithm.MLDsa65, 3072 / 8, Oids.MLDsa65WithRSA3072Pkcs15PreHashSha512); + CreateRsa( + "MLDSA65-RSA3072-PKCS15-SHA512", + MLDsaAlgorithm.MLDsa65, + 3072, + Oids.MLDsa65WithRSA3072Pkcs15PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PSS with SHA512 algorithm. @@ -107,7 +140,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA4096Pss { get; } = - new("MLDSA65-RSA4096-PSS-SHA512", MLDsaAlgorithm.MLDsa65, 4096 / 8, Oids.MLDsa65WithRSA4096PssPreHashSha512); + CreateRsa( + "MLDSA65-RSA4096-PSS-SHA512", + MLDsaAlgorithm.MLDsa65, + 4096, + Oids.MLDsa65WithRSA4096PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. @@ -116,7 +153,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA4096Pkcs15 { get; } = - new("MLDSA65-RSA4096-PKCS15-SHA512", MLDsaAlgorithm.MLDsa65, 4096 / 8, Oids.MLDsa65WithRSA4096Pkcs15PreHashSha512); + CreateRsa( + "MLDSA65-RSA4096-PKCS15-SHA512", + MLDsaAlgorithm.MLDsa65, + 4096, + Oids.MLDsa65WithRSA4096Pkcs15PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-256 with SHA512 algorithm. @@ -125,7 +166,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-256 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithECDsaP256 { get; } = - new("MLDSA65-ECDSA-P256-SHA512", MLDsaAlgorithm.MLDsa65, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(256), Oids.MLDsa65WithECDsaP256PreHashSha512); + CreateECDsa( + "MLDSA65-ECDSA-P256-SHA512", + MLDsaAlgorithm.MLDsa65, + 256, + Oids.MLDsa65WithECDsaP256PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-384 with SHA512 algorithm. @@ -134,7 +179,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-384 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithECDsaP384 { get; } = - new("MLDSA65-ECDSA-P384-SHA512", MLDsaAlgorithm.MLDsa65, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(384), Oids.MLDsa65WithECDsaP384PreHashSha512); + CreateECDsa( + "MLDSA65-ECDSA-P384-SHA512", + MLDsaAlgorithm.MLDsa65, + 384, + Oids.MLDsa65WithECDsaP384PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA BrainpoolP256r1 with SHA512 algorithm. @@ -143,7 +192,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA BrainpoolP256r1 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithECDsaBrainpoolP256r1 { get; } = - new("MLDSA65-ECDSA-brainpoolP256r1-SHA512", MLDsaAlgorithm.MLDsa65, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(256), Oids.MLDsa65WithECDsaBrainpoolP256r1PreHashSha512); + CreateECDsa( + "MLDSA65-ECDSA-brainpoolP256r1-SHA512", + MLDsaAlgorithm.MLDsa65, + 256, + Oids.MLDsa65WithECDsaBrainpoolP256r1PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and Ed25519 algorithm. @@ -152,7 +205,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and Ed25519 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithEd25519 { get; } = - new("MLDSA65-Ed25519-SHA512", MLDsaAlgorithm.MLDsa65, 64, Oids.MLDsa65WithEd25519PreHashSha512); + CreateEdDsa( + "MLDSA65-Ed25519-SHA512", + MLDsaAlgorithm.MLDsa65, + 32 * 8, + Oids.MLDsa65WithEd25519PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-384 with SHA512 algorithm. @@ -161,7 +218,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-384 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithECDsaP384 { get; } = - new("MLDSA87-ECDSA-P384-SHA512", MLDsaAlgorithm.MLDsa87, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(384), Oids.MLDsa87WithECDsaP384PreHashSha512); + CreateECDsa( + "MLDSA87-ECDSA-P384-SHA512", + MLDsaAlgorithm.MLDsa87, + 384, + Oids.MLDsa87WithECDsaP384PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA BrainpoolP384r1 with SHA512 algorithm. @@ -170,7 +231,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA BrainpoolP384r1 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithECDsaBrainpoolP384r1 { get; } = - new("MLDSA87-ECDSA-brainpoolP384r1-SHA512", MLDsaAlgorithm.MLDsa87, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(384), Oids.MLDsa87WithECDsaBrainpoolP384r1PreHashSha512); + CreateECDsa( + "MLDSA87-ECDSA-brainpoolP384r1-SHA512", + MLDsaAlgorithm.MLDsa87, + 384, + Oids.MLDsa87WithECDsaBrainpoolP384r1PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and Ed448 algorithm. @@ -179,7 +244,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and Ed448 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithEd448 { get; } = - new("MLDSA87-Ed448-SHAKE256", MLDsaAlgorithm.MLDsa87, 114, Oids.MLDsa87WithEd448PreHashShake256_512); + CreateEdDsa( + "MLDSA87-Ed448-SHAKE256", + MLDsaAlgorithm.MLDsa87, + 57 * 8, + Oids.MLDsa87WithEd448PreHashShake256_512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and 3072-bit RSASSA-PSS with SHA512 algorithm. @@ -188,7 +257,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and 3072-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithRSA3072Pss { get; } = - new("MLDSA87-RSA3072-PSS-SHA512", MLDsaAlgorithm.MLDsa87, 3072 / 8, Oids.MLDsa87WithRSA3072PssPreHashSha512); + CreateRsa( + "MLDSA87-RSA3072-PSS-SHA512", + MLDsaAlgorithm.MLDsa87, + 3072, + Oids.MLDsa87WithRSA3072PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and 4096-bit RSASSA-PSS with SHA512 algorithm. @@ -197,7 +270,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and 4096-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithRSA4096Pss { get; } = - new("MLDSA87-RSA4096-PSS-SHA512", MLDsaAlgorithm.MLDsa87, 4096 / 8, Oids.MLDsa87WithRSA4096PssPreHashSha512); + CreateRsa( + "MLDSA87-RSA4096-PSS-SHA512", + MLDsaAlgorithm.MLDsa87, + 4096, + Oids.MLDsa87WithRSA4096PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-521 with SHA512 algorithm. @@ -206,7 +283,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-521 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithECDsaP521 { get; } = - new("MLDSA87-ECDSA-P521-SHA512", MLDsaAlgorithm.MLDsa87, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(521), Oids.MLDsa87WithECDsaP521PreHashSha512); + CreateECDsa( + "MLDSA87-ECDSA-P521-SHA512", + MLDsaAlgorithm.MLDsa87, + 521, + Oids.MLDsa87WithECDsaP521PreHashSha512); /// /// Compares two objects. @@ -289,5 +370,141 @@ private CompositeMLDsaAlgorithm( _ => null, }; } + + private static CompositeMLDsaAlgorithm CreateRsa( + string name, + MLDsaAlgorithm algorithm, + int keySizeInBits, + string oid) + { + Debug.Assert(keySizeInBits % 8 == 0); + int keySizeInBytes = keySizeInBits / 8; + + SizeRange signatureSize = SizeRange.CreateExact(RandomizerSizeInBytes + algorithm.SignatureSizeInBytes + keySizeInBytes); + + SizeRange privateKeySize = SizeRange.CreateUnbounded( + // n must be modulus length, but other parameters can vary. This is a weak lower bound. + minimumSize: algorithm.PrivateSeedSizeInBytes + keySizeInBytes, + // n and d are about modulus length, p, q, dP, dQ, qInv are about half modulus length. + // Estimate that version and e are usually small (65537 = 3 bytes) and 64 bytes for ASN.1 overhead. + initialExportBufferSize: algorithm.PrivateSeedSizeInBytes + keySizeInBytes * 2 + (keySizeInBytes / 2) * 5 + 64); + + SizeRange publicKeySize = SizeRange.CreateUnbounded( + // n must be modulus length, but other parameters can vary. This is a weak lower bound. + minimumSize: algorithm.PublicKeySizeInBytes + keySizeInBytes, + // Estimated that e is usually small (65537 = 3 bytes) and 16 bytes for ASN.1 overhead. + initialExportBufferSize: algorithm.PublicKeySizeInBytes + keySizeInBytes + 16); + + return new CompositeMLDsaAlgorithm(name, signatureSize, privateKeySize, publicKeySize, oid); + } + + private static CompositeMLDsaAlgorithm CreateECDsa( + string name, + MLDsaAlgorithm algorithm, + int keySizeInBits, + string oid) + { + int keySizeInBytes = (keySizeInBits + 7) / 8; + + SizeRange signatureSize = SizeRange.CreateBounded( + RandomizerSizeInBytes + algorithm.SignatureSizeInBytes, + RandomizerSizeInBytes + algorithm.SignatureSizeInBytes + AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(keySizeInBits)); + + SizeRange privateKeySize = SizeRange.CreateUnbounded( + minimumSize: algorithm.PrivateSeedSizeInBytes + 1 + keySizeInBytes, + // Add optional uncompressed public key and estimate 32 bytes for version, optional ECParameters and ASN.1 overhead. + initialExportBufferSize: algorithm.PrivateSeedSizeInBytes + 1 + keySizeInBytes + 1 + 2 * keySizeInBytes + 32); + + SizeRange publicKeySize = SizeRange.CreateExact(algorithm.PublicKeySizeInBytes + 1 + 2 * keySizeInBytes); + + return new CompositeMLDsaAlgorithm(name, signatureSize, privateKeySize, publicKeySize, oid); + } + + private static CompositeMLDsaAlgorithm CreateEdDsa( + string name, + MLDsaAlgorithm algorithm, + int keySizeInBits, + string oid) + { + Debug.Assert(keySizeInBits % 8 == 0); + int keySizeInBytes = keySizeInBits / 8; + + SizeRange signatureSize = SizeRange.CreateExact(RandomizerSizeInBytes + algorithm.SignatureSizeInBytes + 2 * keySizeInBytes); + SizeRange privateKeySize = SizeRange.CreateExact(algorithm.PrivateSeedSizeInBytes + keySizeInBytes); + SizeRange publicKeySize = SizeRange.CreateExact(algorithm.PublicKeySizeInBytes + keySizeInBytes); + + return new CompositeMLDsaAlgorithm(name, signatureSize, privateKeySize, publicKeySize, oid); + } + + internal abstract class SizeRange + { + internal abstract bool IsExact { get; } + internal abstract int MinimumSizeInBytes { get; } + internal abstract int? MaximumSizeInBytes { get; } + internal abstract int InitialExportBufferSizeInBytes { get; } + + internal static SizeRange CreateExact(int size) + { + Debug.Assert(size >= 0); + + return new ExactSize(size); + } + + internal static SizeRange CreateBounded(int minimumSize, int maximumSize) + { + Debug.Assert(minimumSize >= 0); + Debug.Assert(maximumSize >= minimumSize); + + return minimumSize == maximumSize ? new ExactSize(minimumSize) : new VariableSize(minimumSize, maximumSize, maximumSize); + } + + internal static SizeRange CreateUnbounded(int minimumSize, int initialExportBufferSize) + { + Debug.Assert(minimumSize >= 0); + Debug.Assert(initialExportBufferSize >= minimumSize); + + return new VariableSize(minimumSize, null, initialExportBufferSize); + } + + internal bool IsValidSize(int size) + { + return size >= MinimumSizeInBytes && size <= MaximumSizeInBytes.GetValueOrDefault(int.MaxValue); + } + + internal bool IsAlwaysLargerThan(int size) + { + return size < MinimumSizeInBytes; + } + + private sealed class ExactSize : SizeRange + { + private readonly int _size; + + internal ExactSize(int size) + { + _size = size; + } + + internal override bool IsExact => true; + internal override int MinimumSizeInBytes => _size; + internal override int? MaximumSizeInBytes => _size; + internal override int InitialExportBufferSizeInBytes => _size; + } + + private sealed class VariableSize : SizeRange + { + internal VariableSize(int minimumSize, int? maximumSize, int initialExportBufferSize) + { + MinimumSizeInBytes = minimumSize; + MaximumSizeInBytes = maximumSize; + InitialExportBufferSizeInBytes = initialExportBufferSize; + } + + internal override bool IsExact => false; + internal override int MinimumSizeInBytes { get; } + internal override int? MaximumSizeInBytes { get; } + internal override int InitialExportBufferSizeInBytes { get; } + } + } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs index 7cc6ae81d277d0..7c7210100aa1f2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs @@ -15,20 +15,20 @@ public CompositeMLDsaImplementation(CompositeMLDsaAlgorithm algorithm) throw new PlatformNotSupportedException(); } - internal static bool SupportsAny() => false; + internal static partial bool SupportsAny() => false; - internal static bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) => false; + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) => false; - internal static CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => throw new PlatformNotSupportedException(); - internal static CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - internal static CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - protected override bool TrySignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination, out int bytesWritten) => + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => throw new PlatformNotSupportedException(); protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => @@ -37,10 +37,10 @@ protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan destination, out int bytesWritten) => throw new PlatformNotSupportedException(); - protected override bool TryExportCompositeMLDsaPublicKeyCore(ReadOnlySpan destination, out int bytesWritten) => + protected override bool TryExportCompositeMLDsaPublicKeyCore(Span destination, out int bytesWritten) => throw new PlatformNotSupportedException(); - protected override bool TryExportCompositeMLDsaPrivateKeyCore(ReadOnlySpan destination, out int bytesWritten) => + protected override bool TryExportCompositeMLDsaPrivateKeyCore(Span destination, out int bytesWritten) => throw new PlatformNotSupportedException(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs new file mode 100644 index 00000000000000..a425f7366b6212 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaImplementation : CompositeMLDsa + { + private CompositeMLDsaImplementation(CompositeMLDsaAlgorithm algorithm) + : base(algorithm) + { + throw new PlatformNotSupportedException(); + } + + internal static partial bool SupportsAny() + { +#if !NETFRAMEWORK + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return false; + } +#endif + + return CompositeMLDsaManaged.SupportsAny(); + } + + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) + { +#if !NETFRAMEWORK + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return false; + } +#endif + + return CompositeMLDsaManaged.IsAlgorithmSupportedImpl(algorithm); + } + + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => + throw new PlatformNotSupportedException(); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { +#if !NETFRAMEWORK + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new PlatformNotSupportedException(); + } +#endif + + return CompositeMLDsaManaged.ImportCompositeMLDsaPublicKeyImpl(algorithm, source); + } + + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { +#if !NETFRAMEWORK + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new PlatformNotSupportedException(); + } +#endif + + return CompositeMLDsaManaged.ImportCompositeMLDsaPrivateKeyImpl(algorithm, source); + } + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => + throw new PlatformNotSupportedException(); + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportCompositeMLDsaPublicKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportCompositeMLDsaPrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.cs new file mode 100644 index 00000000000000..c565db17ef39dd --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaImplementation : CompositeMLDsa + { + internal static partial bool SupportsAny(); + + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm); + + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs new file mode 100644 index 00000000000000..ad5b058229009a --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs @@ -0,0 +1,316 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Formats.Asn1; + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaManaged + { + private sealed class RsaComponent : ComponentAlgorithm +#if DESIGNTIMEINTERFACES +#pragma warning disable SA1001 // Commas should be spaced correctly + , IComponentAlgorithmFactory +#pragma warning restore SA1001 // Commas should be spaced correctly +#endif + { + private readonly HashAlgorithmName _hashAlgorithmName; + private readonly RSASignaturePadding _padding; + + private RSA _rsa; + + private RsaComponent(RSA rsa, HashAlgorithmName hashAlgorithmName, RSASignaturePadding padding) + { + Debug.Assert(rsa is not null); + Debug.Assert(padding is not null); + + _rsa = rsa; + _hashAlgorithmName = hashAlgorithmName; + _padding = padding; + } + + public static bool IsAlgorithmSupported(RsaAlgorithm _) => true; + +#if NETFRAMEWORK + // RSA-PSS requires RSACng on .NET Framework + private static RSACng CreateRSA() => new RSACng(); +#else + private static RSA CreateRSA() => RSA.Create(); +#endif + + internal override int SignData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + Span destination) + { +#if NET + return _rsa.SignData(data, destination, _hashAlgorithmName, _padding); +#else + // Composite ML-DSA virtual methods only accept ROS so we need to allocate for signature + byte[] signature = _rsa.SignData(data, _hashAlgorithmName, _padding); + + if (signature.AsSpan().TryCopyTo(destination)) + { + return signature.Length; + } + + CryptographicOperations.ZeroMemory(destination); + + throw new CryptographicException(); +#endif + } + + internal override bool VerifyData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + ReadOnlySpan signature) + { +#if NET + return _rsa.VerifyData(data, signature, _hashAlgorithmName, _padding); +#else + // Composite ML-DSA virtual methods only accept ROS so we need to use ToArray() for signature + return _rsa.VerifyData(data, signature.ToArray(), _hashAlgorithmName, _padding); +#endif + } + + public static RsaComponent GenerateKey(RsaAlgorithm algorithm) => + throw new NotImplementedException(); + + public static RsaComponent ImportPrivateKey(RsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupported(algorithm)); + + RSA? rsa = null; + + try + { + rsa = CreateRSA(); + +#if NET + rsa.ImportRSAPrivateKey(source, out int bytesRead); + + if (bytesRead != source.Length) + { + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); + } +#else + ConvertRSAPrivateKeyToParameters(algorithm, source, (in parameters) => + { + rsa.ImportParameters(parameters); + }); +#endif + } + catch (CryptographicException) + { + rsa?.Dispose(); + throw; + } + + return new RsaComponent(rsa, algorithm.HashAlgorithmName, algorithm.Padding); + } + + public static RsaComponent ImportPublicKey(RsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupported(algorithm)); + + RSA? rsa = null; + + try + { + rsa = CreateRSA(); + +#if NET + rsa.ImportRSAPublicKey(source, out int bytesRead); + + if (bytesRead != source.Length) + { + throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm); + } +#else + ConvertRSAPublicKeyToParameters(algorithm, source, (in parameters) => + { + rsa.ImportParameters(parameters); + }); +#endif + } + catch (CryptographicException) + { + rsa?.Dispose(); + throw; + } + + return new RsaComponent(rsa, algorithm.HashAlgorithmName, algorithm.Padding); + } + + internal override bool TryExportPublicKey(Span destination, out int bytesWritten) + { +#if NET + return _rsa.TryExportRSAPublicKey(destination, out bytesWritten); +#else + RSAParameters parameters = _rsa.ExportParameters(includePrivateParameters: false); + AsnWriter writer = RSAKeyFormatHelper.WritePkcs1PublicKey(in parameters); + return writer.TryEncode(destination, out bytesWritten); +#endif + } + + internal override bool TryExportPrivateKey(Span destination, out int bytesWritten) + { +#if NET + return _rsa.TryExportRSAPrivateKey(destination, out bytesWritten); +#else + RSAParameters parameters = _rsa.ExportParameters(includePrivateParameters: true); + + using (PinAndClear.Track(parameters.D)) + using (PinAndClear.Track(parameters.P)) + using (PinAndClear.Track(parameters.Q)) + using (PinAndClear.Track(parameters.DP)) + using (PinAndClear.Track(parameters.DQ)) + using (PinAndClear.Track(parameters.InverseQ)) + { + AsnWriter? writer = null; + + try + { + writer = RSAKeyFormatHelper.WritePkcs1PrivateKey(in parameters); + return writer.TryEncode(destination, out bytesWritten); + } + finally + { + writer?.Reset(); + } + } +#endif + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _rsa?.Dispose(); + _rsa = null!; + } + + base.Dispose(disposing); + } + +#if !NET + private delegate void ConvertRSAKeyToParametersCallback(in RSAParameters source); + + private static unsafe void ConvertRSAPublicKeyToParameters( + RsaAlgorithm algorithm, + ReadOnlySpan key, + ConvertRSAKeyToParametersCallback callback) + { + Debug.Assert(algorithm.KeySizeInBits % 8 == 0); + int modulusLength = algorithm.KeySizeInBits / 8; + RSAParameters parameters = default; + + try + { + AsnValueReader reader = new AsnValueReader(key, AsnEncodingRules.BER); + AsnValueReader sequenceReader = reader.ReadSequence(Asn1Tag.Sequence); + + parameters.Modulus = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + if (parameters.Modulus.Length != modulusLength) + { + throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); + } + + parameters.Exponent = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + sequenceReader.ThrowIfNotEmpty(); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + callback(in parameters); + } + + private static unsafe void ConvertRSAPrivateKeyToParameters( + RsaAlgorithm algorithm, + ReadOnlySpan key, + ConvertRSAKeyToParametersCallback callback) + { + int modulusLength = algorithm.KeySizeInBits / 8; + int halfModulusLength = modulusLength / 2; + + RSAParameters parameters = new() + { + D = new byte[modulusLength], + P = new byte[halfModulusLength], + Q = new byte[halfModulusLength], + DP = new byte[halfModulusLength], + DQ = new byte[halfModulusLength], + InverseQ = new byte[halfModulusLength], + }; + + using (PinAndClear.Track(parameters.D)) + using (PinAndClear.Track(parameters.P)) + using (PinAndClear.Track(parameters.Q)) + using (PinAndClear.Track(parameters.DP)) + using (PinAndClear.Track(parameters.DQ)) + using (PinAndClear.Track(parameters.InverseQ)) + { + try + { + AsnValueReader reader = new AsnValueReader(key, AsnEncodingRules.BER); + AsnValueReader sequenceReader = reader.ReadSequence(Asn1Tag.Sequence); + + if (!sequenceReader.TryReadInt32(out int version)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + const int MaxSupportedVersion = 0; + + if (version > MaxSupportedVersion) + { + throw new CryptographicException( + SR.Format( + SR.Cryptography_RSAPrivateKey_VersionTooNew, + version, + MaxSupportedVersion)); + } + + parameters.Modulus = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + if (parameters.Modulus.Length != modulusLength) + { + throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); + } + + parameters.Exponent = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.D); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.P); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.Q); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.DP); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.DQ); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.InverseQ); + + sequenceReader.ThrowIfNotEmpty(); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + callback(in parameters); + } + } +#endif + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs new file mode 100644 index 00000000000000..2484a31c5f3186 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs @@ -0,0 +1,692 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using Internal.Cryptography; + +namespace System.Security.Cryptography +{ +#if !SYSTEM_SECURITY_CRYPTOGRAPHY + // System.Security.Cryptography excludes browser at build time, but we need to rely on UnsupportedOSPlatform for Microsoft.Bcl.Cryptography. + [UnsupportedOSPlatform("browser")] +#endif + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + internal sealed partial class CompositeMLDsaManaged : CompositeMLDsa + { + private static readonly Dictionary s_algorithmMetadata = CreateAlgorithmMetadata(); + private static readonly ConcurrentDictionary s_algorithmSupport = new(); + + private static ReadOnlySpan MessageRepresentativePrefix => "CompositeAlgorithmSignatures2025"u8; + + private MLDsa _mldsa; + private ComponentAlgorithm _componentAlgorithm; + + private AlgorithmMetadata AlgorithmDetails => field ??= s_algorithmMetadata[Algorithm]; + + private CompositeMLDsaManaged(CompositeMLDsaAlgorithm algorithm, MLDsa mldsa, ComponentAlgorithm componentAlgorithm) + : base(algorithm) + { + _mldsa = mldsa; + _componentAlgorithm = componentAlgorithm; + } + + internal static bool SupportsAny() => MLDsaImplementation.SupportsAny(); + + internal static bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) + { + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + return s_algorithmSupport.GetOrAdd( + algorithm, + alg => MLDsaImplementation.IsAlgorithmSupported(metadata.MLDsaAlgorithm) && metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.IsAlgorithmSupported(rsaAlgorithm), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.IsAlgorithmSupported(ecdsaAlgorithm), + _ => false, + }); + } + + internal static CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => + throw new PlatformNotSupportedException(); + + internal static CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupportedImpl(algorithm)); + + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.1 + // 1. Parse each constituent encoded public key. + // The length of the mldsaKey is known based on the size of + // the ML-DSA component key length specified by the Object ID. + // + // switch ML-DSA do + // case ML-DSA-44: + // mldsaPK = bytes[:1312] + // tradPK = bytes[1312:] + // case ML-DSA-65: + // mldsaPK = bytes[:1952] + // tradPK = bytes[1952:] + // case ML-DSA-87: + // mldsaPK = bytes[:2592] + // tradPK = bytes[2592:] + // + // Note that while ML-DSA has fixed-length keys, RSA and ECDSA + // may not, depending on encoding, so rigorous length - checking + // of the overall composite key is not always possible. + // + // 2. Output the component public keys + // + // output(mldsaPK, tradPK) + + ReadOnlySpan mldsaKey = source.Slice(0, metadata.MLDsaAlgorithm.PublicKeySizeInBytes); + ReadOnlySpan tradKey = source.Slice(metadata.MLDsaAlgorithm.PublicKeySizeInBytes); + + MLDsaImplementation mldsa = MLDsaImplementation.ImportPublicKey(metadata.MLDsaAlgorithm, mldsaKey); + ComponentAlgorithm componentAlgorithm = metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.ImportPublicKey(rsaAlgorithm, tradKey), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.ImportPublicKey(ecdsaAlgorithm, tradKey), + _ => throw FailAndGetException(), + }; + + static CryptographicException FailAndGetException() + { + Debug.Fail("Only supported algorithms should reach here."); + return new CryptographicException(); + } + + return new CompositeMLDsaManaged(algorithm, mldsa, componentAlgorithm); + } + + internal static CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupportedImpl(algorithm)); + + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.2 + // 1. Parse each constituent encoded key. + // The length of an ML-DSA private key is always a 32 byte seed + // for all parameter sets. + // + // mldsaSeed = bytes[:32] + // tradSK = bytes[32:] + // + // Note that while ML-DSA has fixed-length keys, RSA and ECDSA + // may not, depending on encoding, so rigorous length-checking + // of the overall composite key is not always possible. + // + // 2. Output the component private keys + // + // output (mldsaSeed, tradSK) + + ReadOnlySpan mldsaKey = source.Slice(0, metadata.MLDsaAlgorithm.PrivateSeedSizeInBytes); + ReadOnlySpan tradKey = source.Slice(metadata.MLDsaAlgorithm.PrivateSeedSizeInBytes); + + MLDsaImplementation mldsa = MLDsaImplementation.ImportSeed(metadata.MLDsaAlgorithm, mldsaKey); + ComponentAlgorithm componentAlgorithm = metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.ImportPrivateKey(rsaAlgorithm, tradKey), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.ImportPrivateKey(ecdsaAlgorithm, tradKey), + _ => throw FailAndGetException(), + }; + + static CryptographicException FailAndGetException() + { + Debug.Fail("Only supported algorithms should reach here."); + return new CryptographicException(); + } + + return new CompositeMLDsaManaged(algorithm, mldsa, componentAlgorithm); + } + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 4.2 + // 1. If len(ctx) > 255: + // return error + + Debug.Assert(context.Length <= 255, $"Caller should have checked context.Length, got {context.Length}"); + + // 2. Compute the Message representative M'. + // As in FIPS 204, len(ctx) is encoded as a single unsigned byte. + // Randomize the message representative + // + // r = Random(32) + // M' := Prefix || Domain || len(ctx) || ctx || r + // || PH( M ) + + Span r = stackalloc byte[CompositeMLDsaAlgorithm.RandomizerSizeInBytes]; + RandomNumberGenerator.Fill(r); + + byte[] M_prime = GetMessageRepresentative(AlgorithmDetails, context, r, data); + + // 3. Separate the private key into component keys + // and re-generate the ML-DSA key from seed. + // + // (mldsaSeed, tradSK) = DeserializePrivateKey(sk) + // (_, mldsaSK) = ML-DSA.KeyGen(mldsaSeed) + + /* no-op */ + + // 4. Generate the two component signatures independently by calculating + // the signature over M' according to their algorithm specifications. + // + // mldsaSig = ML-DSA.Sign( mldsaSK, M', ctx=Domain ) + // tradSig = Trad.Sign( tradSK, M' ) + + // Note that in step 4 above, both component signature processes are + // invoked, and no indication is given about which one failed.This + // SHOULD be done in a timing-invariant way to prevent side-channel + // attackers from learning which component algorithm failed. + + Span randomizer = destination.Slice(0, CompositeMLDsaAlgorithm.RandomizerSizeInBytes); + Span mldsaSig = destination.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes, AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + Span tradSig = destination.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes + AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + + bool mldsaSigned = false; + bool tradSigned = false; + + try + { + _mldsa.SignData(M_prime, mldsaSig, AlgorithmDetails.DomainSeparator); + mldsaSigned = true; + } + catch (CryptographicException) + { + } + + int tradBytesWritten = 0; + + try + { + tradBytesWritten = _componentAlgorithm.SignData(M_prime, tradSig); + tradSigned = true; + } + catch (CryptographicException) + { + } + + // 5. If either ML-DSA.Sign() or Trad.Sign() return an error, then this + // process MUST return an error. + // + // if NOT mldsaSig or NOT tradSig: + // output "Signature generation error" + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + static bool Or(bool x, bool y) => x | y; + + if (Or(!mldsaSigned, !tradSigned)) + { + CryptographicOperations.ZeroMemory(destination); + throw new CryptographicException(SR.Cryptography_CompositeSignDataError); + } + + // 6. Output the encoded composite signature value. + // + // s = SerializeSignatureValue(r, mldsaSig, tradSig) + // return s + + r.CopyTo(randomizer); + return randomizer.Length + mldsaSig.Length + tradBytesWritten; + } + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 4.3 + // 1. If len(ctx) > 255 + // return error + + Debug.Assert(context.Length <= 255, $"Caller should have checked context.Length, got {context.Length}"); + + // 2. Separate the keys and signatures + // + // (mldsaPK, tradPK) = DeserializePublicKey(pk) + // (r, mldsaSig, tradSig) = DeserializeSignatureValue(s) + // + // If Error during deserialization, or if any of the component + // keys or signature values are not of the correct type or + // length for the given component algorithm then output + // "Invalid signature" and stop. + + ReadOnlySpan r = signature.Slice(0, CompositeMLDsaAlgorithm.RandomizerSizeInBytes); + ReadOnlySpan mldsaSig = signature.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes, AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + ReadOnlySpan tradSig = signature.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes + AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + + // 3. Compute a Hash of the Message. + // As in FIPS 204, len(ctx) is encoded as a single unsigned byte. + // + // M' = Prefix || Domain || len(ctx) || ctx || r + // || PH( M ) + + byte[] M_prime = GetMessageRepresentative(AlgorithmDetails, context, r, data); + + // 4. Check each component signature individually, according to its + // algorithm specification. + // If any fail, then the entire signature validation fails. + // + // if not ML-DSA.Verify( mldsaPK, M', mldsaSig, ctx=Domain ) then + // output "Invalid signature" + // + // if not Trad.Verify( tradPK, M', tradSig ) then + // output "Invalid signature" + // + // if all succeeded, then + // output "Valid signature" + + // We don't short circuit here because we want to avoid revealing which component signature failed. + // This is not required in the spec, but it is a good practice to avoid timing attacks. + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + static bool And(bool x, bool y) => x & y; + + return And(_mldsa.VerifyData(M_prime, mldsaSig, AlgorithmDetails.DomainSeparator), _componentAlgorithm.VerifyData(M_prime, tradSig)); + } + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportCompositeMLDsaPublicKeyCore(Span destination, out int bytesWritten) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.1 + // 1. Combine and output the encoded public key + // + // output mldsaPK || tradPK + + _mldsa.ExportMLDsaPublicKey(destination.Slice(0, AlgorithmDetails.MLDsaAlgorithm.PublicKeySizeInBytes)); + + if (_componentAlgorithm.TryExportPublicKey(destination.Slice(AlgorithmDetails.MLDsaAlgorithm.PublicKeySizeInBytes), out int componentBytesWritten)) + { + bytesWritten = AlgorithmDetails.MLDsaAlgorithm.PublicKeySizeInBytes + componentBytesWritten; + return true; + } + + bytesWritten = 0; + return false; + } + + protected override bool TryExportCompositeMLDsaPrivateKeyCore(Span destination, out int bytesWritten) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.2 + // 1. Combine and output the encoded private key + // + // output mldsaSeed || tradSK + + try + { + _mldsa.ExportMLDsaPrivateSeed(destination.Slice(0, AlgorithmDetails.MLDsaAlgorithm.PrivateSeedSizeInBytes)); + + if (_componentAlgorithm.TryExportPrivateKey(destination.Slice(AlgorithmDetails.MLDsaAlgorithm.PrivateSeedSizeInBytes), out int componentBytesWritten)) + { + bytesWritten = AlgorithmDetails.MLDsaAlgorithm.PrivateSeedSizeInBytes + componentBytesWritten; + return true; + } + + bytesWritten = 0; + return false; + } + catch (CryptographicException) + { + CryptographicOperations.ZeroMemory(destination); + throw; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _mldsa?.Dispose(); + _mldsa = null!; + + _componentAlgorithm?.Dispose(); + _componentAlgorithm = null!; + } + + base.Dispose(disposing); + } + + private static byte[] GetMessageRepresentative( + AlgorithmMetadata metadata, + ReadOnlySpan context, + ReadOnlySpan r, + ReadOnlySpan message) + { + checked + { + Debug.Assert(r.Length is CompositeMLDsaAlgorithm.RandomizerSizeInBytes); + + // M' = Prefix || Domain || len(ctx) || ctx || r || PH( M ) + + using (IncrementalHash hash = IncrementalHash.CreateHash(metadata.HashAlgorithmName)) + { +#if NET + int hashLength = hash.HashLengthInBytes; +#else + int hashLength = hash.GetHashLengthInBytes(); +#endif + + int length = + MessageRepresentativePrefix.Length + // Prefix + metadata.DomainSeparator.Length + // Domain + 1 + // len(ctx) + context.Length + // ctx + r.Length + // r + hashLength; // PH( M ) + + // The representative message will often be < 256 bytes so we can stackalloc with a callback. + // That gets a little messy on .NET Framework where by-ref generics aren't supported, so we just allocate. + byte[] M_prime = new byte[length]; + + int offset = 0; + + // Prefix + MessageRepresentativePrefix.CopyTo(M_prime.AsSpan(offset, MessageRepresentativePrefix.Length)); + offset += MessageRepresentativePrefix.Length; + + // Domain + metadata.DomainSeparator.AsSpan().CopyTo(M_prime.AsSpan(offset, metadata.DomainSeparator.Length)); + offset += metadata.DomainSeparator.Length; + + // len(ctx) + M_prime[offset] = (byte)context.Length; + offset++; + + // ctx + context.CopyTo(M_prime.AsSpan(offset, context.Length)); + offset += context.Length; + + // r + r.CopyTo(M_prime.AsSpan(offset, r.Length)); + offset += r.Length; + + // PH( M ) + hash.AppendData(message); +#if NET + hash.GetHashAndReset(M_prime.AsSpan(offset, hashLength)); +#else + byte[] hashBytes = hash.GetHashAndReset(); + hashBytes.CopyTo(M_prime.AsSpan(offset, hashLength)); +#endif + offset += hashLength; + + Debug.Assert(offset == M_prime.Length); + + return M_prime; + } + } + } + +#if DESIGNTIMEINTERFACES + private interface IComponentAlgorithmFactory + where TComponentAlgorithm : ComponentAlgorithm, IComponentAlgorithmFactory + { + internal static abstract bool IsAlgorithmSupported(TAlgorithmDescriptor algorithm); + internal static abstract TComponentAlgorithm GenerateKey(TAlgorithmDescriptor algorithm); + internal static abstract TComponentAlgorithm ImportPrivateKey(TAlgorithmDescriptor algorithm, ReadOnlySpan source); + internal static abstract TComponentAlgorithm ImportPublicKey(TAlgorithmDescriptor algorithm, ReadOnlySpan source); + } +#endif + + private abstract class ComponentAlgorithm : IDisposable + { + private bool _disposed; + + internal abstract bool TryExportPublicKey(Span destination, out int bytesWritten); + internal abstract bool TryExportPrivateKey(Span destination, out int bytesWritten); + + internal abstract int SignData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + Span destination); + + internal abstract bool VerifyData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + ReadOnlySpan signature); + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + Dispose(true); + GC.SuppressFinalize(this); + } + } + + protected virtual void Dispose(bool disposing) + { + } + } + + private sealed class ECDsaComponent : ComponentAlgorithm +#if DESIGNTIMEINTERFACES +#pragma warning disable SA1001 // Commas should be spaced correctly + , IComponentAlgorithmFactory +#pragma warning restore SA1001 // Commas should be spaced correctly +#endif + { + public static bool IsAlgorithmSupported(ECDsaAlgorithm _) => false; + public static ECDsaComponent GenerateKey(ECDsaAlgorithm algorithm) => throw new NotImplementedException(); + public static ECDsaComponent ImportPrivateKey(ECDsaAlgorithm algorithm, ReadOnlySpan source) => throw new NotImplementedException(); + public static ECDsaComponent ImportPublicKey(ECDsaAlgorithm algorithm, ReadOnlySpan source) => throw new NotImplementedException(); + + internal override bool TryExportPrivateKey(Span destination, out int bytesWritten) => throw new NotImplementedException(); + internal override bool TryExportPublicKey(Span destination, out int bytesWritten) => throw new NotImplementedException(); + + internal override bool VerifyData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + ReadOnlySpan signature) => throw new NotImplementedException(); + + internal override int SignData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + Span destination) => throw new NotImplementedException(); + } + + private static Dictionary CreateAlgorithmMetadata() + { + const int count = 18; + + Dictionary algorithmMetadata = new(count) + { + { + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + new RsaAlgorithm(2048, HashAlgorithmName.SHA256, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x00], + HashAlgorithmName.SHA256) + }, + { + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + new RsaAlgorithm(2048, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x01], + HashAlgorithmName.SHA256) + }, + { + CompositeMLDsaAlgorithm.MLDsa44WithEd25519, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + new EdDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x02], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + new ECDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x03], + HashAlgorithmName.SHA256) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(3072, HashAlgorithmName.SHA512, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x04], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(3072, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x05], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(4096, HashAlgorithmName.SHA512, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x06], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(4096, HashAlgorithmName.SHA384, RSASignaturePadding.Pkcs1), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x07], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new ECDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x08], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new ECDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x09], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new ECDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0A], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithEd25519, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new EdDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0B], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new ECDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0C], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new ECDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0D], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithEd448, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new EdDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0E], + new HashAlgorithmName("SHAKE256")) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new RsaAlgorithm(3072, HashAlgorithmName.SHA512, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0F], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new RsaAlgorithm(4096, HashAlgorithmName.SHA512, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x10], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new ECDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x11], + HashAlgorithmName.SHA512) + } + }; + + Debug.Assert(count == algorithmMetadata.Count); + + return algorithmMetadata; + } + + private sealed class AlgorithmMetadata( + MLDsaAlgorithm mldsaAlgorithm, + object traditionalAlgorithm, + byte[] domainSeparator, + HashAlgorithmName hashAlgorithmName) + { + internal MLDsaAlgorithm MLDsaAlgorithm { get; } = mldsaAlgorithm; + internal object TraditionalAlgorithm { get; } = traditionalAlgorithm; + internal byte[] DomainSeparator { get; } = domainSeparator; + internal HashAlgorithmName HashAlgorithmName { get; } = hashAlgorithmName; + } + + private sealed class RsaAlgorithm(int keySizeInBits, HashAlgorithmName hashAlgorithmName, RSASignaturePadding padding) + { + internal int KeySizeInBits { get; } = keySizeInBits; + internal HashAlgorithmName HashAlgorithmName { get; } = hashAlgorithmName; + internal RSASignaturePadding Padding { get; } = padding; + } + + private sealed class ECDsaAlgorithm + { + } + + private sealed class EdDsaAlgorithm + { + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs index 40d07a69e24999..a761d7264225c9 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs @@ -7,39 +7,10 @@ namespace System.Security.Cryptography { - internal static class KeyBlobHelpers + internal static partial class KeyBlobHelpers { - internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory, int length) + internal static byte[] ToUnsignedIntegerBytes(this ReadOnlySpan span) { - if (memory.Length == length) - { - return memory.ToArray(); - } - - ReadOnlySpan span = memory.Span; - - if (memory.Length == length + 1) - { - if (span[0] == 0) - { - return span.Slice(1).ToArray(); - } - } - - if (span.Length > length) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - byte[] target = new byte[length]; - span.CopyTo(target.AsSpan(length - span.Length)); - return target; - } - - internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory) - { - ReadOnlySpan span = memory.Span; - if (span.Length > 1 && span[0] == 0) { return span.Slice(1).ToArray(); @@ -48,22 +19,32 @@ internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory) return span.ToArray(); } - internal static byte[] ExportKeyParameter(this BigInteger value, int length) + internal static void ToUnsignedIntegerBytes(this ReadOnlySpan span, Span destination) { - byte[] target = new byte[length]; + int length = destination.Length; - if (value.TryWriteBytes(target, out int bytesWritten, isUnsigned: true, isBigEndian: true)) + if (span.Length == length) { - if (bytesWritten < length) + span.CopyTo(destination); + return; + } + + if (span.Length == length + 1) + { + if (span[0] == 0) { - Buffer.BlockCopy(target, 0, target, length - bytesWritten, bytesWritten); - target.AsSpan(0, length - bytesWritten).Clear(); + span.Slice(1).CopyTo(destination); + return; } + } - return target; + if (span.Length > length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + destination.Slice(0, destination.Length - span.Length).Clear(); + span.CopyTo(destination.Slice(length - span.Length)); } internal static void WriteKeyParameterInteger(this AsnWriter writer, ReadOnlySpan integer) diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs index f42e3221690baa..c79071595dd271 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs @@ -16,6 +16,8 @@ private MLDsaImplementation(MLDsaAlgorithm algorithm) internal static partial bool SupportsAny() => false; + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm) => false; + // The instance override methods are unreachable, as the constructor will always throw. protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => throw new PlatformNotSupportedException(); diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs index 5b62f4a6e4048e..5999f2fd736379 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs @@ -34,6 +34,9 @@ private MLDsaImplementation( [MemberNotNullWhen(true, nameof(s_algHandle))] internal static partial bool SupportsAny() => s_algHandle is not null; + [MemberNotNullWhen(true, nameof(s_algHandle))] + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm) => SupportsAny(); + protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) { if (!_hasSecretKey) diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs index b3ca249c345ea9..63c4ee70dafad2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs @@ -10,6 +10,7 @@ namespace System.Security.Cryptography internal sealed partial class MLDsaImplementation : MLDsa { internal static partial bool SupportsAny(); + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm); internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algorithm); internal static partial MLDsaImplementation ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source); diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs new file mode 100644 index 00000000000000..d8a6783f15e572 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Diagnostics; +using System.Formats.Asn1; +using System.Security.Cryptography.Asn1; + +namespace System.Security.Cryptography +{ + internal static partial class RSAKeyFormatHelper + { + internal static AsnWriter WritePkcs1PublicKey(in RSAParameters rsaParameters) + { + if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) + { + throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); + } + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + writer.PushSequence(); + writer.WriteKeyParameterInteger(rsaParameters.Modulus); + writer.WriteKeyParameterInteger(rsaParameters.Exponent); + writer.PopSequence(); + + return writer; + } + + internal static AsnWriter WritePkcs1PrivateKey(in RSAParameters rsaParameters) + { + if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) + { + throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); + } + + if (rsaParameters.D == null || + rsaParameters.P == null || + rsaParameters.Q == null || + rsaParameters.DP == null || + rsaParameters.DQ == null || + rsaParameters.InverseQ == null) + { + throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); + } + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + writer.PushSequence(); + + // Format version 0 + writer.WriteInteger(0); + writer.WriteKeyParameterInteger(rsaParameters.Modulus); + writer.WriteKeyParameterInteger(rsaParameters.Exponent); + writer.WriteKeyParameterInteger(rsaParameters.D); + writer.WriteKeyParameterInteger(rsaParameters.P); + writer.WriteKeyParameterInteger(rsaParameters.Q); + writer.WriteKeyParameterInteger(rsaParameters.DP); + writer.WriteKeyParameterInteger(rsaParameters.DQ); + writer.WriteKeyParameterInteger(rsaParameters.InverseQ); + + writer.PopSequence(); + return writer; + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs index c77944c204c658..c3732580830a6a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs @@ -15,6 +15,10 @@ internal static partial class RSAKeyFormatHelper Oids.Rsa, }; + // TODO Currently reading PKCS#1 keys uses BigInteger which is not optimal and uses APIs that are not + // available downlevel. These methods should eventually be replaced with a more efficient implementation + // and they should be moved into the RSAKeyFormatHelper.Pkcs1 (which is shared between S.S.C. and M.B.C.). + internal static void FromPkcs1PrivateKey( ReadOnlyMemory keyData, in AlgorithmIdentifierAsn algId, @@ -254,57 +258,5 @@ private static void WriteAlgorithmIdentifier(AsnWriter writer) writer.PopSequence(); } - - internal static AsnWriter WritePkcs1PublicKey(in RSAParameters rsaParameters) - { - if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) - { - throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); - } - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - writer.PushSequence(); - writer.WriteKeyParameterInteger(rsaParameters.Modulus); - writer.WriteKeyParameterInteger(rsaParameters.Exponent); - writer.PopSequence(); - - return writer; - } - - internal static AsnWriter WritePkcs1PrivateKey(in RSAParameters rsaParameters) - { - if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) - { - throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); - } - - if (rsaParameters.D == null || - rsaParameters.P == null || - rsaParameters.Q == null || - rsaParameters.DP == null || - rsaParameters.DQ == null || - rsaParameters.InverseQ == null) - { - throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); - } - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - - writer.PushSequence(); - - // Format version 0 - writer.WriteInteger(0); - writer.WriteKeyParameterInteger(rsaParameters.Modulus); - writer.WriteKeyParameterInteger(rsaParameters.Exponent); - writer.WriteKeyParameterInteger(rsaParameters.D); - writer.WriteKeyParameterInteger(rsaParameters.P); - writer.WriteKeyParameterInteger(rsaParameters.Q); - writer.WriteKeyParameterInteger(rsaParameters.DP); - writer.WriteKeyParameterInteger(rsaParameters.DQ); - writer.WriteKeyParameterInteger(rsaParameters.InverseQ); - - writer.PopSequence(); - return writer; - } } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaContractTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaContractTests.cs new file mode 100644 index 00000000000000..c4c0f754db9aba --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaContractTests.cs @@ -0,0 +1,633 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Linq; +using Xunit; +using Xunit.Sdk; + +using CompositeMLDsaTestVector = System.Security.Cryptography.Tests.CompositeMLDsaTestData.CompositeMLDsaTestVector; + +namespace System.Security.Cryptography.Tests +{ + public static class CompositeMLDsaContractTests + { + public static IEnumerable ArgumentValidationData => + from algorithm in CompositeMLDsaTestData.AllAlgorithms + from shouldDispose in new[] { true, false } + select new object[] { algorithm, shouldDispose }; + + [Theory] + [MemberData(nameof(ArgumentValidationData))] + public static void NullArgumentValidation(CompositeMLDsaAlgorithm algorithm, bool shouldDispose) + { + using CompositeMLDsa dsa = CompositeMLDsaMockImplementation.Create(algorithm); + + if (shouldDispose) + { + // Test that argument validation exceptions take precedence over ObjectDisposedException + dsa.Dispose(); + } + + AssertExtensions.Throws("data", () => dsa.SignData(null)); + AssertExtensions.Throws("data", () => dsa.VerifyData(null, null)); + + AssertExtensions.Throws("signature", () => dsa.VerifyData(Array.Empty(), null)); + } + + [Fact] + public static void ArgumentValidation_Ctor_NullAlgorithm() + { + AssertExtensions.Throws("algorithm", static () => new CompositeMLDsaMockImplementation(null)); + } + + [Theory] + [MemberData(nameof(ArgumentValidationData))] + public static void ArgumentValidation(CompositeMLDsaAlgorithm algorithm, bool shouldDispose) + { + using CompositeMLDsa dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int maxSignatureSize = algorithm.MaxSignatureSizeInBytes; + + if (shouldDispose) + { + // Test that argument validation exceptions take precedence over ObjectDisposedException + dsa.Dispose(); + } + + AssertExtensions.Throws("destination", () => dsa.SignData(ReadOnlySpan.Empty, new byte[maxSignatureSize - 1], [])); + + // Context length must be less than 256 + AssertExtensions.Throws("context", () => dsa.SignData(ReadOnlySpan.Empty, new byte[maxSignatureSize], new byte[256])); + AssertExtensions.Throws("context", () => dsa.SignData(Array.Empty(), new byte[256])); + AssertExtensions.Throws("context", () => dsa.VerifyData(ReadOnlySpan.Empty, new byte[maxSignatureSize], new byte[256])); + AssertExtensions.Throws("context", () => dsa.VerifyData(Array.Empty(), new byte[maxSignatureSize], new byte[256])); + } + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPublicKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PublicKeySizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPublicKey(new byte[lowerBound - 1], out int bytesWritten)); + Assert.Equal(0, bytesWritten); + + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = (destination, out bytesWritten) => + { + AssertExtensions.LessThanOrEqualTo(lowerBound, destination.Length); + bytesWritten = lowerBound; + return true; + }; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(new byte[lowerBound], out bytesWritten)); + Assert.Equal(lowerBound, bytesWritten); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(new byte[lowerBound + 1], out bytesWritten)); + Assert.Equal(lowerBound, bytesWritten); + + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = (destination, out bytesWritten) => + { + // Writing less than lower bound isn't allowed. + bytesWritten = lowerBound - 1; + return true; + }; + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPublicKey(new byte[lowerBound], out bytesWritten)); + Assert.Equal(0, bytesWritten); + + Assert.Throws(dsa.ExportCompositeMLDsaPublicKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPublicKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int? upperBoundOrNull = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PublicKeySizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => default(int?), + ecdsa => 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + + if (upperBoundOrNull is null) + { + return; + } + + int upperBound = upperBoundOrNull.Value; + + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = (destination, out bytesWritten) => + { + bytesWritten = upperBound; + return true; + }; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(new byte[upperBound], out int bytesWritten)); + Assert.Equal(upperBound, bytesWritten); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(new byte[upperBound + 1], out bytesWritten)); + Assert.Equal(upperBound, bytesWritten); + + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = (destination, out bytesWritten) => + { + // Writing more than upper bound isn't allowed. + bytesWritten = upperBound + 1; + return true; + }; + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPublicKey(new byte[upperBound + 1], out bytesWritten)); + Assert.Equal(0, bytesWritten); + + Assert.Throws(dsa.ExportCompositeMLDsaPublicKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPrivateKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => 1 + ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPrivateKey(new byte[lowerBound - 1], out int bytesWritten)); + Assert.Equal(0, bytesWritten); + + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = (destination, out bytesWritten) => + { + AssertExtensions.LessThanOrEqualTo(lowerBound, destination.Length); + bytesWritten = lowerBound; + return true; + }; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(new byte[lowerBound], out bytesWritten)); + Assert.Equal(lowerBound, bytesWritten); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(new byte[lowerBound + 1], out bytesWritten)); + Assert.Equal(lowerBound, bytesWritten); + + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = (destination, out bytesWritten) => + { + // Writing less than lower bound isn't allowed. + bytesWritten = lowerBound - 1; + return true; + }; + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPrivateKey(new byte[lowerBound], out bytesWritten)); + Assert.Equal(0, bytesWritten); + + Assert.Throws(dsa.ExportCompositeMLDsaPrivateKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPrivateKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int? upperBoundOrNull = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => default(int?), + ecdsa => default(int?), + eddsa => eddsa.KeySizeInBits / 8); + + if (upperBoundOrNull is null) + { + return; + } + + int upperBound = upperBoundOrNull.Value; + + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = (destination, out bytesWritten) => + { + bytesWritten = upperBound; + return true; + }; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(new byte[upperBound], out int bytesWritten)); + Assert.Equal(upperBound, bytesWritten); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(new byte[upperBound + 1], out bytesWritten)); + Assert.Equal(upperBound, bytesWritten); + + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = (destination, out bytesWritten) => + { + // Writing more than upper bound isn't allowed. + bytesWritten = upperBound + 1; + return true; + }; + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPrivateKey(new byte[upperBound + 1], out bytesWritten)); + Assert.Equal(0, bytesWritten); + + Assert.Throws(dsa.ExportCompositeMLDsaPrivateKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void SignData_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].SignatureSizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => 0, + eddsa => 2 * eddsa.KeySizeInBits / 8); + + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[lowerBound - 1])); + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes - 1])); + + dsa.SignDataCoreHook = (data, context, destination) => + { + AssertExtensions.LessThanOrEqualTo(lowerBound, destination.Length); + return lowerBound; + }; + + Assert.Equal(lowerBound, dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes])); + Assert.Equal(lowerBound, dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes + 1])); + + AssertExtensions.GreaterThanOrEqualTo(algorithm.MaxSignatureSizeInBytes, lowerBound); + + dsa.SignDataCoreHook = (data, context, destination) => + { + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes])); + Assert.Throws(() => dsa.SignData([])); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void SignData_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + + int upperBound = algorithm.MaxSignatureSizeInBytes; + + dsa.SignDataCoreHook = (data, context, destination) => + { + Assert.Equal(upperBound, destination.Length); + return upperBound; + }; + + Assert.Equal(upperBound, dsa.SignData(ReadOnlySpan.Empty, new byte[upperBound])); + Assert.Equal(upperBound, dsa.SignData(ReadOnlySpan.Empty, new byte[upperBound + 1])); + + dsa.SignDataCoreHook = (data, context, destination) => + { + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[upperBound + 1])); + Assert.Throws(() => dsa.SignData([])); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void VerifyData_Threshold(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int threshold = + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + _ => algorithm.MaxSignatureSizeInBytes, + _ => 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].SignatureSizeInBytes, + _ => algorithm.MaxSignatureSizeInBytes); + + AssertExtensions.FalseExpression(dsa.VerifyData(ReadOnlySpan.Empty, new byte[threshold - 1])); + + dsa.VerifyDataCoreHook = (data, signature, context) => true; + + AssertExtensions.TrueExpression(dsa.VerifyData(ReadOnlySpan.Empty, new byte[threshold])); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPublicKey_InitialBuffer(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + int initialBufferSize = -1; + + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = (destination, out bytesWritten) => + { + // Buffer is always big enough, but it may bee too big for a valid key, so bound it with an actual key. + bytesWritten = Math.Min(vector.PublicKey.Length, destination.Length); + initialBufferSize = destination.Length; + return true; + }; + + _ = dsa.ExportCompositeMLDsaPublicKey(); + + int mldsaKeySize = CompositeMLDsaTestHelpers.MLDsaAlgorithms[vector.Algorithm].PublicKeySizeInBytes; + + CompositeMLDsaTestHelpers.ExecuteComponentAction( + vector.Algorithm, + // RSA doesn't have an exact size, so it will use pooled buffers. Their sizes are powers of two. + rsa => AssertExtensions.LessThanOrEqualTo(mldsaKeySize + (rsa.KeySizeInBits / 8) * 2 + 16, initialBufferSize), + ecdsa => Assert.Equal(mldsaKeySize + 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), initialBufferSize), + eddsa => Assert.Equal(mldsaKeySize + eddsa.KeySizeInBits / 8, initialBufferSize)); + + AssertExtensions.Equal(1, dsa.TryExportCompositeMLDsaPublicKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPrivateKey_InitialBuffer(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + int initialBufferSize = -1; + + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = (destination, out bytesWritten) => + { + // Buffer is always big enough, but it may be too big for a valid key, so bound it with an actual key. + bytesWritten = Math.Min(vector.SecretKey.Length, destination.Length); + initialBufferSize = destination.Length; + return true; + }; + + _ = dsa.ExportCompositeMLDsaPrivateKey(); + + int mldsaKeySize = CompositeMLDsaTestHelpers.MLDsaAlgorithms[vector.Algorithm].PrivateSeedSizeInBytes; + + CompositeMLDsaTestHelpers.ExecuteComponentAction( + vector.Algorithm, + // RSA and ECDSA don't have an exact size, so it will use pooled buffers. Their sizes are powers of two. + rsa => AssertExtensions.LessThanOrEqualTo(mldsaKeySize + (rsa.KeySizeInBits / 8) * 2 + (rsa.KeySizeInBits / 8) / 2 * 5 + 64, initialBufferSize), + ecdsa => AssertExtensions.LessThanOrEqualTo(mldsaKeySize + 1 + ((ecdsa.KeySizeInBits + 7) / 8) + 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8) + 64, initialBufferSize), + eddsa => Assert.Equal(mldsaKeySize + eddsa.KeySizeInBits / 8, initialBufferSize)); + + AssertExtensions.Equal(1, dsa.TryExportCompositeMLDsaPrivateKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void SignData_BufferSize(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + int testSignatureSize = vector.Algorithm.MaxSignatureSizeInBytes - + // Test returning less than maximum size for non-fixed size signatures. + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + vector.Algorithm, + rsa => 0, + ecdsa => 1, + eddsa => 0); + + dsa.SignDataCoreHook = (data, context, destination) => + { + Assert.Equal(vector.Algorithm.MaxSignatureSizeInBytes, destination.Length); + return testSignatureSize; + }; + + byte[] signature = dsa.SignData(vector.Message); + Assert.Equal(testSignatureSize, signature.Length); + + signature = new byte[vector.Algorithm.MaxSignatureSizeInBytes]; + dsa.AddSignatureBufferIsSameAssertion(signature); + + Assert.Equal(testSignatureSize, dsa.SignData(vector.Message, signature, [])); + + AssertExtensions.Equal(2, dsa.SignDataCoreCallCount); + } + + private const int PaddingSize = 10; + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPublicKey_CallsCore(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = (_, out x) => { x = 42; return true; }; + dsa.AddFillDestination(vector.PublicKey); + + byte[] exported = dsa.ExportCompositeMLDsaPublicKey(); + AssertExtensions.LessThan(0, dsa.TryExportCompositeMLDsaPublicKeyCoreCallCount); + AssertExtensions.SequenceEqual(exported, vector.PublicKey); + + byte[] publicKey = CreatePaddedFilledArray(vector.PublicKey.Length, 42); + + // Extra bytes in destination buffer should not be touched + Memory destination = publicKey.AsMemory(PaddingSize, vector.PublicKey.Length); + dsa.AddDestinationBufferIsSameAssertion(destination); + dsa.TryExportCompositeMLDsaPublicKeyCoreCallCount = 0; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(destination.Span, out int bytesWritten)); + Assert.Equal(vector.PublicKey.Length, bytesWritten); + Assert.Equal(1, dsa.TryExportCompositeMLDsaPublicKeyCoreCallCount); + AssertExpectedFill(publicKey, vector.PublicKey, PaddingSize, 42); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPrivateKey_CallsCore(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = (_, out x) => { x = 42; return true; }; + dsa.AddFillDestination(vector.SecretKey); + + byte[] exported = dsa.ExportCompositeMLDsaPrivateKey(); + AssertExtensions.LessThan(0, dsa.TryExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.SequenceEqual(exported, vector.SecretKey); + + byte[] secretKey = CreatePaddedFilledArray(vector.SecretKey.Length, 42); + + // Extra bytes in destination buffer should not be touched + Memory destination = secretKey.AsMemory(PaddingSize, vector.SecretKey.Length); + dsa.AddDestinationBufferIsSameAssertion(destination); + dsa.TryExportCompositeMLDsaPrivateKeyCoreCallCount = 0; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(destination.Span, out int bytesWritten)); + Assert.Equal(vector.SecretKey.Length, bytesWritten); + Assert.Equal(1, dsa.TryExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExpectedFill(secretKey, vector.SecretKey, PaddingSize, 42); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TrySignData_CallsCore(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.SignDataCoreHook = (_, _, _) => { return -1; }; + dsa.AddFillDestination(vector.Signature); + dsa.AddDataBufferIsSameAssertion(vector.Message); + dsa.AddContextBufferIsSameAssertion(Array.Empty()); + + byte[] exported = dsa.SignData(vector.Message, Array.Empty()); + AssertExtensions.LessThan(0, dsa.SignDataCoreCallCount); + AssertExtensions.SequenceEqual(exported, vector.Signature); + + byte[] signature = CreatePaddedFilledArray(vector.Signature.Length, 42); + + // Extra bytes in destination buffer should not be touched + Memory destination = signature.AsMemory(PaddingSize, vector.Algorithm.MaxSignatureSizeInBytes); + dsa.AddDestinationBufferIsSameAssertion(destination); + dsa.SignDataCoreCallCount = 0; + + int bytesWritten = dsa.SignData(vector.Message, destination.Span, Array.Empty()); + Assert.Equal(vector.Signature.Length, bytesWritten); + Assert.Equal(1, dsa.SignDataCoreCallCount); + AssertExpectedFill(signature, vector.Signature, PaddingSize, 42); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void VerifyData_CallsCore(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.VerifyDataCoreHook = (_, _, _) => true; + dsa.AddDataBufferIsSameAssertion(vector.Message); + dsa.AddSignatureBufferIsSameAssertion(vector.Signature); + dsa.AddContextBufferIsSameAssertion(Array.Empty()); + + AssertExtensions.TrueExpression(dsa.VerifyData(vector.Message, vector.Signature, Array.Empty())); + AssertExtensions.Equal(1, dsa.VerifyDataCoreCallCount); + + AssertExtensions.TrueExpression(dsa.VerifyData(vector.Message, vector.Signature, Array.Empty())); + AssertExtensions.Equal(2, dsa.VerifyDataCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPublicKey_CoreReturnsFals(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = (_, out w) => { w = 0; return false; }; + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPublicKey(new byte[vector.PublicKey.Length], out int bytesWritten)); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPrivateKey_CoreReturnsFalse(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = (_, out w) => { w = 0; return false; }; + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPrivateKey(new byte[vector.SecretKey.Length], out int bytesWritten)); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void VerifyData_CoreReturnsFalse(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.VerifyDataCoreHook = (_, _, _) => false; + AssertExtensions.FalseExpression(dsa.VerifyData(vector.Message, vector.Signature, Array.Empty())); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportPublicKeyCore_ExactSize_ReturnFalse(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int? exactPublicKeySize = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PublicKeySizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => default(int?), + ecdsa => 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + + if (exactPublicKeySize is null) + return; + + dsa.TryExportCompositeMLDsaPublicKeyCoreHook = + (destination, out w) => + { + int expectedSize = exactPublicKeySize.Value; + Assert.Equal(expectedSize, destination.Length); + + // Destination is exactly sized, so this should never return false. + // Caller should validate and throw. + w = 0; + return false; + }; + + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportPrivateKeyCore_ExactSize_ReturnFalse(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int? exactPrivateKeySize = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => default(int?), + ecdsa => default(int?), + eddsa => eddsa.KeySizeInBits / 8); + + if (exactPrivateKeySize is null) + return; + + dsa.TryExportCompositeMLDsaPrivateKeyCoreHook = + (destination, out w) => + { + int expectedSize = exactPrivateKeySize.Value; + Assert.Equal(expectedSize, destination.Length); + + // Destination is exactly sized, so this should never return false. + // Caller should validate and throw. + w = 0; + return false; + }; + + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void Dispose_CallsVirtual(CompositeMLDsaAlgorithm algorithm) + { + CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + bool disposeCalled = false; + + // First Dispose call should invoke overridden Dispose should be called + dsa.DisposeHook = (bool disposing) => + { + AssertExtensions.TrueExpression(disposing); + disposeCalled = true; + }; + + dsa.Dispose(); + AssertExtensions.TrueExpression(disposeCalled); + + // Subsequent Dispose calls should be a no-op + dsa.DisposeHook = _ => Assert.Fail(); + + dsa.Dispose(); + dsa.Dispose(); // no throw + + CompositeMLDsaTestHelpers.VerifyDisposed(dsa); + } + + private static void AssertExpectedFill(ReadOnlySpan buffer, ReadOnlySpan content, int offset, byte paddingElement) + { + // Ensure that the data was filled correctly + AssertExtensions.SequenceEqual(content, buffer.Slice(offset, content.Length)); + + // And that the padding was not touched + AssertExtensions.FilledWith(paddingElement, buffer.Slice(0, offset)); + AssertExtensions.FilledWith(paddingElement, buffer.Slice(offset + content.Length)); + } + + private static byte[] CreatePaddedFilledArray(int size, byte filling) + { + byte[] publicKey = new byte[size + 2 * PaddingSize]; + publicKey.AsSpan().Fill(filling); + return publicKey; + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs index 66cf09da1100e7..69b7838be7bf7f 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs @@ -1,21 +1,250 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Linq; +using Microsoft.DotNet.RemoteExecutor; using Xunit; +using Xunit.Sdk; namespace System.Security.Cryptography.Tests { public static class CompositeMLDsaFactoryTests { [Fact] - public static void NoSupportYet() + public static void NullArgumentValidation() { - AssertExtensions.FalseExpression(CompositeMLDsa.IsSupported); - AssertExtensions.FalseExpression(CompositeMLDsa.IsAlgorithmSupported(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss)); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.IsAlgorithmSupported(null)); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(null, Array.Empty())); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(null, ReadOnlySpan.Empty)); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPublicKey(null, Array.Empty())); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPublicKey(null, ReadOnlySpan.Empty)); - Assert.Throws(() => CompositeMLDsa.GenerateKey(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss)); - Assert.Throws(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes])); - Assert.Throws(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, new byte[MLDsaAlgorithm.MLDsa44.PublicKeySizeInBytes])); + AssertExtensions.Throws("source", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, null)); + AssertExtensions.Throws("source", static () => CompositeMLDsa.ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, null)); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_Empty(CompositeMLDsaAlgorithm algorithm) + { + AssertImportBadPrivateKey(algorithm, Array.Empty()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_ShortMLDsaSeed(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPrivateKey(algorithm, new byte[mldsaVector.PrivateSeed.Length - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_OnlyMLDsaSeed(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPrivateKey(algorithm, mldsaVector.PrivateSeed.ToArray()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_ShortTradKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + byte[] shortTradKey = mldsaVector.PrivateSeed; + Array.Resize(ref shortTradKey, shortTradKey.Length + 1); + + AssertImportBadPrivateKey(algorithm, shortTradKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPrivateKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + int bound = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => 1 + ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + + AssertImportBadPrivateKey(algorithm, new byte[bound - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPrivateKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + int? bound = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => default(int?), + ecdsa => default(int?), + eddsa => eddsa.KeySizeInBits / 8); + + if (bound.HasValue) + AssertImportBadPrivateKey(algorithm, new byte[bound.Value + 1]); + } + + private static void AssertImportBadPrivateKey(CompositeMLDsaAlgorithm algorithm, byte[] key) + { + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => AssertThrowIfNotSupported( + () => AssertExtensions.Throws(() => import()), + algorithm), + algorithm, + key); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_Empty(CompositeMLDsaAlgorithm algorithm) + { + AssertImportBadPublicKey(algorithm, Array.Empty()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_ShortMLDsaKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPublicKey(algorithm, new byte[mldsaVector.PublicKey.Length - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_OnlyMLDsaKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPublicKey(algorithm, mldsaVector.PublicKey.ToArray()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_ShortTradKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + byte[] shortTradKey = mldsaVector.PublicKey; + Array.Resize(ref shortTradKey, shortTradKey.Length + 1); + + AssertImportBadPublicKey(algorithm, shortTradKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPublicKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + int bound = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PublicKeySizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + + AssertImportBadPublicKey(algorithm, new byte[bound - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPublicKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + int? bound = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].PublicKeySizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => default(int?), + ecdsa => 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + + if (bound.HasValue) + AssertImportBadPublicKey(algorithm, new byte[bound.Value + 1]); + } + + private static void AssertImportBadPublicKey(CompositeMLDsaAlgorithm algorithm, byte[] key) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey( + import => AssertThrowIfNotSupported( + () => AssertExtensions.Throws(() => import()), + algorithm), + algorithm, + key); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void AlgorithmMatches_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey(import => + AssertThrowIfNotSupported(() => + Assert.Equal(vector.Algorithm, import().Algorithm)), vector.Algorithm, vector.PublicKey); + + CompositeMLDsaTestHelpers.AssertImportPrivateKey(import => + AssertThrowIfNotSupported(() => + Assert.Equal(vector.Algorithm, import().Algorithm)), vector.Algorithm, vector.SecretKey); + } + + [Fact] + public static void IsSupported_AgreesWithPlatform() + { + // Composites are supported everywhere MLDsa is supported + Assert.Equal(MLDsa.IsSupported && !PlatformDetection.IsLinux, CompositeMLDsa.IsSupported); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void IsAlgorithmSupported_AgreesWithPlatform(CompositeMLDsaAlgorithm algorithm) + { + bool supported = CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + _ => MLDsa.IsSupported && !PlatformDetection.IsLinux, + _ => false, + _ => false); + + Assert.Equal( + supported, + CompositeMLDsa.IsAlgorithmSupported(algorithm)); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void IsSupported_InitializesCrypto() + { + string arg = CompositeMLDsa.IsSupported ? "1" : "0"; + + // This ensures that Composite ML-DSA is the first cryptographic algorithm touched in the process, which kicks off + // the initialization of the crypto layer on some platforms. Running in a remote executor ensures no other + // test has pre-initialized anything. + RemoteExecutor.Invoke(static (string isSupportedStr) => + { + bool isSupported = isSupportedStr == "1"; + return CompositeMLDsa.IsSupported == isSupported ? RemoteExecutor.SuccessExitCode : 0; + }, arg).Dispose(); + } + + /// + /// Asserts that on platforms that do not support Composite ML-DSA, the input test throws PlatformNotSupportedException. + /// If the test does pass, it implies that the test is validating code after the platform check. + /// + /// The test to run. + private static void AssertThrowIfNotSupported(Action test, CompositeMLDsaAlgorithm? algorithm = null) + { + if (algorithm == null ? CompositeMLDsa.IsSupported : CompositeMLDsa.IsAlgorithmSupported(algorithm)) + { + test(); + } + else + { + try + { + test(); + } + catch (PlatformNotSupportedException pnse) + { + Assert.Contains("CompositeMLDsa", pnse.Message); + } + catch (ThrowsException te) when (te.InnerException is PlatformNotSupportedException pnse) + { + Assert.Contains("CompositeMLDsa", pnse.Message); + } + } } } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs new file mode 100644 index 00000000000000..2842370bb018e7 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + [ConditionalClass(typeof(CompositeMLDsa), nameof(CompositeMLDsa.IsSupported))] + public sealed class CompositeMLDsaImplementationTests : CompositeMLDsaTestsBase + { + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void CompositeMLDsaIsOnlyPublicAncestor_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector info) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey( + AssertCompositeMLDsaIsOnlyPublicAncestor, info.Algorithm, info.PublicKey); + + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + AssertCompositeMLDsaIsOnlyPublicAncestor, info.Algorithm, info.SecretKey); + } + + private static void AssertCompositeMLDsaIsOnlyPublicAncestor(Func createKey) + { + using CompositeMLDsa key = createKey(); + Type keyType = key.GetType(); + while (keyType != null && keyType != typeof(CompositeMLDsa)) + { + AssertExtensions.FalseExpression(keyType.IsPublic); + keyType = keyType.BaseType; + } + + Assert.Equal(typeof(CompositeMLDsa), keyType); + } + + #region Roundtrip by importing then exporting + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void RoundTrip_Import_Export_PublicKey(CompositeMLDsaTestData.CompositeMLDsaTestVector info) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey(import => + CompositeMLDsaTestHelpers.AssertExportPublicKey(export => + CompositeMLDsaTestHelpers.WithDispose(import(), dsa => + CompositeMLDsaTestHelpers.AssertPublicKeyEquals(info.Algorithm, info.PublicKey, export(dsa)))), + info.Algorithm, + info.PublicKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void RoundTrip_Import_Export_PrivateKey(CompositeMLDsaTestData.CompositeMLDsaTestVector info) + { + CompositeMLDsaTestHelpers.AssertImportPrivateKey(import => + CompositeMLDsaTestHelpers.AssertExportPrivateKey(export => + CompositeMLDsaTestHelpers.WithDispose(import(), dsa => + CompositeMLDsaTestHelpers.AssertPrivateKeyEquals(info.Algorithm, info.SecretKey, export(dsa)))), + info.Algorithm, + info.SecretKey); + } + + #endregion Roundtrip by importing then exporting + + protected override CompositeMLDsa ImportPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, source); + + protected override CompositeMLDsa ImportPrivateKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, source); + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaMockImplementation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaMockImplementation.cs new file mode 100644 index 00000000000000..ba41d527b80c0e --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaMockImplementation.cs @@ -0,0 +1,264 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + internal sealed class CompositeMLDsaMockImplementation : CompositeMLDsa + { + internal static CompositeMLDsaMockImplementation Create(CompositeMLDsaAlgorithm algorithm) => + new CompositeMLDsaMockImplementation(algorithm); + + public CompositeMLDsaMockImplementation(CompositeMLDsaAlgorithm algorithm) + : base(algorithm) + { + } + + internal delegate int SignDataFunc(ReadOnlySpan data, ReadOnlySpan context, Span destination); + internal delegate bool VerifyDataFunc(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature); + internal delegate bool TryExportFunc(Span destination, out int bytesWritten); + internal delegate void DisposeAction(bool disposing); + + public int SignDataCoreCallCount = 0; + public int VerifyDataCoreCallCount = 0; + public int TryExportCompositeMLDsaPublicKeyCoreCallCount = 0; + public int TryExportCompositeMLDsaPrivateKeyCoreCallCount = 0; + public int DisposeCallCount = 0; + + public SignDataFunc SignDataCoreHook { get; set; } = (_, _, _) => { Assert.Fail(); return 0; }; + public VerifyDataFunc VerifyDataCoreHook { get; set; } = (_, _, _) => { Assert.Fail(); return false; }; + public TryExportFunc TryExportCompositeMLDsaPublicKeyCoreHook { get; set; } = (_, out bytesWritten) => { Assert.Fail(); bytesWritten = 0; return false; }; + public TryExportFunc TryExportCompositeMLDsaPrivateKeyCoreHook { get; set; } = (_, out bytesWritten) => { Assert.Fail(); bytesWritten = 0; return false; }; + public DisposeAction DisposeHook { get; set; } = _ => { }; + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) + { + SignDataCoreCallCount++; + return SignDataCoreHook(data, context, destination); + } + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) + { + VerifyDataCoreCallCount++; + return VerifyDataCoreHook(data, context, signature); + } + + protected override bool TryExportCompositeMLDsaPublicKeyCore(Span destination, out int bytesWritten) + { + TryExportCompositeMLDsaPublicKeyCoreCallCount++; + return TryExportCompositeMLDsaPublicKeyCoreHook(destination, out bytesWritten); + } + + protected override bool TryExportCompositeMLDsaPrivateKeyCore(Span destination, out int bytesWritten) + { + TryExportCompositeMLDsaPrivateKeyCoreCallCount++; + return TryExportCompositeMLDsaPrivateKeyCoreHook(destination, out bytesWritten); + } + + protected override void Dispose(bool disposing) + { + DisposeCallCount++; + DisposeHook(disposing); + } + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) + { + throw new NotImplementedException(); + } + + public void AddLengthAssertion() + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.LessThanOrEqualTo( + 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].SignatureSizeInBytes, // randomizer + mldsaSig + destination.Length); + return ret; + }; + + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.LessThanOrEqualTo( + 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].SignatureSizeInBytes, // randomizer + mldsaSig + signature.Length); + return ret; + }; + + TryExportFunc oldTryExportCompositeMLDsaPublicKeyCoreHook = TryExportCompositeMLDsaPublicKeyCoreHook; + TryExportCompositeMLDsaPublicKeyCoreHook = (Span destination, out int bytesWritten) => + { + bool ret = oldTryExportCompositeMLDsaPublicKeyCoreHook(destination, out bytesWritten); + AssertExtensions.LessThanOrEqualTo( + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].PublicKeySizeInBytes, + destination.Length); + return ret; + }; + + TryExportFunc oldTryExportCompositeMLDsaPrivateKeyCoreHook = TryExportCompositeMLDsaPrivateKeyCoreHook; + TryExportCompositeMLDsaPrivateKeyCoreHook = (Span destination, out int bytesWritten) => + { + bool ret = oldTryExportCompositeMLDsaPrivateKeyCoreHook(destination, out bytesWritten); + AssertExtensions.LessThanOrEqualTo( + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].PrivateSeedSizeInBytes, + destination.Length); + return ret; + }; + } + + public void AddDestinationBufferIsSameAssertion(ReadOnlyMemory buffer) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.Same(buffer.Span, destination); + return ret; + }; + + TryExportFunc oldTryExportCompositeMLDsaPublicKeyCoreHook = TryExportCompositeMLDsaPublicKeyCoreHook; + TryExportCompositeMLDsaPublicKeyCoreHook = (Span destination, out int bytesWritten) => + { + bool ret = oldTryExportCompositeMLDsaPublicKeyCoreHook(destination, out bytesWritten); + AssertExtensions.Same(buffer.Span, destination); + return ret; + }; + + TryExportFunc oldTryExportCompositeMLDsaPrivateKeyCoreHook = TryExportCompositeMLDsaPrivateKeyCoreHook; + TryExportCompositeMLDsaPrivateKeyCoreHook = (Span destination, out int bytesWritten) => + { + bool ret = oldTryExportCompositeMLDsaPrivateKeyCoreHook(destination, out bytesWritten); + AssertExtensions.Same(buffer.Span, destination); + return ret; + }; + } + + public void AddContextBufferIsSameAssertion(ReadOnlyMemory buffer) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.Same(buffer.Span, context); + return ret; + }; + + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.Same(buffer.Span, context); + return ret; + }; + } + + public void AddSignatureBufferIsSameAssertion(ReadOnlyMemory buffer) + { + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.Same(buffer.Span, signature); + return ret; + }; + } + + public void AddDataBufferIsSameAssertion(ReadOnlyMemory buffer) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.Same(buffer.Span, data); + return ret; + }; + + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.Same(buffer.Span, data); + return ret; + }; + } + + public void AddFillDestination(byte b) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + _ = oldTrySignDataCoreHook(data, context, destination); + destination.Fill(b); + return destination.Length; + }; + + TryExportFunc oldExportCompositeMLDsaPublicKeyCoreHook = TryExportCompositeMLDsaPublicKeyCoreHook; + TryExportCompositeMLDsaPublicKeyCoreHook = (Span destination, out int bytesWritten) => + { + _ = oldExportCompositeMLDsaPublicKeyCoreHook(destination, out _); + destination.Fill(b); + bytesWritten = destination.Length; + return true; + }; + + TryExportFunc oldExportCompositeMLDsaPrivateKeyCoreHook = TryExportCompositeMLDsaPrivateKeyCoreHook; + TryExportCompositeMLDsaPrivateKeyCoreHook = (Span destination, out int bytesWritten) => + { + _ = oldExportCompositeMLDsaPrivateKeyCoreHook(destination, out _); + destination.Fill(b); + bytesWritten = destination.Length; + return true; + }; + } + + public void AddFillDestination(byte[] fillContents) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + _ = oldTrySignDataCoreHook(data, context, destination); + + if (fillContents.AsSpan().TryCopyTo(destination)) + { + return fillContents.Length; + } + + return 0; + }; + + TryExportFunc oldExportCompositeMLDsaPublicKeyCoreHook = TryExportCompositeMLDsaPublicKeyCoreHook; + TryExportCompositeMLDsaPublicKeyCoreHook = (Span destination, out int bytesWritten) => + { + _ = oldExportCompositeMLDsaPublicKeyCoreHook(destination, out _); + + if (fillContents.AsSpan().TryCopyTo(destination)) + { + bytesWritten = fillContents.Length; + return true; + } + + bytesWritten = 0; + return false; + }; + + TryExportFunc oldExportCompositeMLDsaPrivateKeyCoreHook = TryExportCompositeMLDsaPrivateKeyCoreHook; + TryExportCompositeMLDsaPrivateKeyCoreHook = (Span destination, out int bytesWritten) => + { + _ = oldExportCompositeMLDsaPrivateKeyCoreHook(destination, out _); + + if (fillContents.AsSpan().TryCopyTo(destination)) + { + bytesWritten = fillContents.Length; + return true; + } + + bytesWritten = 0; + return false; + }; + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.Raw.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.Raw.cs new file mode 100644 index 00000000000000..65a09e4f910661 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.Raw.cs @@ -0,0 +1,157 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.Tests +{ + public static partial class CompositeMLDsaTestData + { + // https://github.com/lamps-wg/draft-composite-sigs/blob/656445f814e83e2d6c553f756911b9328e454d46/src/testvectors.json + internal static partial CompositeMLDsaTestVector[] AllIetfVectors => field ??= + [ + new("id-MLDSA44-RSA2048-PSS-SHA256", + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, + "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"), + new("id-MLDSA44-RSA2048-PKCS15-SHA256", + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, + "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"), + new("id-MLDSA44-Ed25519-SHA512", + CompositeMLDsaAlgorithm.MLDsa44WithEd25519, + "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"), + new("id-MLDSA44-ECDSA-P256-SHA256", + CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, + "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"), + new("id-MLDSA65-RSA3072-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, + "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"), + new("id-MLDSA65-RSA3072-PKCS15-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, + "ON3XikpbvBewjpNR8rnp+8tVdMBo2BzLBAQ1rU+o77qBeY47fa8v6M052pVdA1Sk8ZjXfn6L2EaPV2YfOaFRxbwV9jrukEEI8PiPCDx9WFvBmDYg28ngTvhhke1x77iX48JTmC+OVPCQT3WaSR9YRJzYndv4iOeTCLBYiM/fyjTkXdgoQtcM75lAhXCbaWepXe6zV3fBKOkoeXjCM36CfPsQ1rzynWn82OAmhMNYajoDOpyp2734ZizRwzrTh8MqNtNBEJtoGRiL9qgUxo4xN12UBciP4xz4mVwK+CGN2ofVUHiSPgm3FKzs8oCJjWchU7G3a3sXMXJjuhf/2d8QSYIHcM8VyeK3+7l0BIEo7z5hHW5tltuf1wM6xBY/mfOmX56D5In4qv4jr3MLK1BIwV/FUaCjCzMiz6RVvFi/Z80IR1AYQDP/MIzErnk0M4nfrrKmJkOHicDZOIp44pUW/tMyq8McoUKdKGXKWOms5FToY7V+7Mw2NuOQHacVu5tfA12TjfGfH/3H6hIN1/lIhruRqY+dIo8CqM50IGK47VzFYuxCViTlPWjMopx05OKldrdj/mGTTVzRaD3sJ6QBzQgRAzLDYPQEf3gIu68YKNwlGkVkexvPWgnFRTeuK3T25Wpzgl0z9QU3apKvj4Zg5x256Pz51TYA0+SBMeyVwqBb1zXBjs9UgrgkQL4jLFwK9tqf7PWZ0nLWaMzS/RtgMfa6KuPY7wD5bnSjgMzaz9W+y6+hEFxmvNkIiIUSU8t+pZTmFZF8h4R0t/HwXOWnXSlH/voM5SN9rPcaqXDY7rNXtfJQnkKCS9Shl7KxggBodfSrfcqJmNYk+3tZPvxAde/AyygNCYyXr6ZyrDYEWq0kynQm6oWumsgLTB/QmXClU8PhmNDwP0m7ECl3XtSH72ibxsM1qvm7cX+6oolKFXVgkV+MhH7UBcrTJ9mF4fn0YsUrvhj85UnPwRae/Ga10YnLE1SPHcZ31IttFRx1w1pZ1OXPU1Fq9gcxdrVbstoFabpwQIvo9RUPgQL8/NG2suMdBfxKrETNL2rHLRcXZFJhxmMmWWtLtFqkP1OubiI2By7rVPW9eLhUMkzzAzeIRD9Z8QxNv0mxopEZYLCnfT+LMx6EKe/toT3LVTECo4+el+e7XVl8UrxANpIWr25vaqSi7O2iuVpvNQqWf8jAxrTowutIMk9vdKppwOQ5uVVswj0vsvSqyPYVq6hJMIaL5HB+3v30jMTDiI3zOGV72ts31hSrcprObWUO+KhafvU2scyqa4Nq5grCcmoyjbRyV2YnPjn5x9TOHUEHIp4oukk7guvu14woMs0dGj6CenYm1QnbO3y4xZmNwQ4ki8b3hZ1XPRay2G326tA1tnmP8/RA7sq7QDarNIUH8Y8myGArlnyFG23z1LlPTDQIvCs3b7muJafPRfnhkGUSe/YnMbw7OFuRNlUtJLpg5iZ7C99bSp4QmEd/aX3LhklrN41Oxj0tNUeav6ZLx1GK0Dx0KJhphyS1p6m8PzZDiXEHvCEg+rWAwrDoGypzAlxEDBNn+BEdCkb7eBe36cWvQow+IDlTIPaBG6xVgnj/31OxeKQN5zHO1QJmUV+0Hh2EdP9PW1rg8vVCn5trvIclo8gjWsfWyy9jwcDXN0ZGcBsEQUF6W/6s4MCygrVLQuxK9t59dSNFP7Y5smOKPnV3l8DnP11f+AlUWH0kka4JkxtUr8qICmUi/U4e7OHrwzM7cN+2sBU+0LG1lTeMQIV9Y/KxfCHKnCkEYrznlVXWvir0lv/VWE+7r548bdqb3YdMT7/YTzkJPbGtn+ZYdwPhF4Tl4VjFyAJyDgrbBUnvxG/mRBxnX+QZtTXso9vmwFk+9BkmSaSFexdjs/6E9bh8Ih7DbOeNEbrO5086EvCOELZKB5HlNeJe/iMTRbcoMeQiyRuMvxPLee7QfuGi/5JvjZyegzi28rDfUzImE0Qk3DAhGX2N7C7Qw8Qc3M3jefEobPGBsyWNKbzkPlb1UsUxGfhcISeQCCjSIV4LrIWK9q166t/LGz4sihfaTRp9gNPliL0402jIUF1PnmEvaneuoV7FcYnYM7h1oGndDhsVpnX3FG7RpmIl+P1n1uwXQQa/xjL0KL5kfr+n6ejOcYlF+xQg/PNEyC5++1ms/QYx7M+JNcmiIE5Uyctd2R3gELe9r5GjCNUREN34pV4XFoW9ssLcGUIWZf3ieIkLQBu+qS7ImBJj/hUnzpwawCk4BiaB6ZNOJLmsXTm3rBbZ9ylCMKM9WWOchVF7I2CTjYzYV3ZKE2MKn4O+h5rVVLrsBgzoxxWLLxfF8/k87OCk50nl5xKR3nDUYVGTWt8HzcCovoHWv/bDoRHKixCm4npZhckx5S7+gYS9etIb9t5CcJmVFOtsBCNUNX4TqsEWT8pPa9gmDlifvnDNxL9HMxXE01SwnhGvpbz/jZv5aBs/T6tVNpouCxVLBXZlHmh0cFMPL8qraEqfZO8xe19vcVjBVUIj1k7DrRCvwk7NBnFkpLxgVlrh/7rrG175EjRPBisX9Umk2o7EfmNtpUmZL97kj3ltuaKEu1HofY3BgM3k12Vz9b4hUiowggGKAoIBgQDW8xw3Iw3DjQv5sCYzbOtMyCCGkPANAF7HOwiHy2DtMxsxIhaRNpJXIY8KBxSs3RQqDHOZwRPoEMw8qXnc0xMabh23Q0PlPPxBweXxpHppZqZ8eUccOCNrlgO7Eg/xtI9mAKy7pfE0R3mbEK3sDZdCcZX3IMs0mzlVX4OPE6lzgR4pKqu8QvMrpcfbCpTcKXw7RXBKxj4SWp/vvpI+KwoGvqCGMhgmpOva0FsD+SHFwC9IY8q/OLBc/aWJZ/hx3IyGQIqFZ69VsJugQIvz8aO3HHb3GzIF+RKCoUCnfapng12iss/JQqLl9FCtB/sKLhkNd1CkMw4pymFcZlowxoDNhPKn9O+XSl1k03fQrnNb4Hdw4qk2RTGZ63VXTndZF0TIJK8xLOudnNIIllVZzvBUhU6cGz/ApwIlKia/S20TbO2DZ2hFolkPLMF37ipAjTZ9WS4LVAJmg23XPFMKIxv7Euy/O7eK+KBw+LFhZzbaP3iovKwVjWqAlnopaaLKg/0CAwEAAQ==", + "MIIY4TCCCjygAwIBAgIUcqJjYblhiRXFcfQQ8OSYxOhJugIwDQYLYIZIAYb6a1AJAQUwSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNjUtUlNBMzA3Mi1QS0NTMTUtU0hBNTEyMB4XDTI1MDcwNTA3MzIxMloXDTM1MDcwNjA3MzIxMlowSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNjUtUlNBMzA3Mi1QS0NTMTUtU0hBNTEyMIIJQjANBgtghkgBhvprUAkBBQOCCS8AON3XikpbvBewjpNR8rnp+8tVdMBo2BzLBAQ1rU+o77qBeY47fa8v6M052pVdA1Sk8ZjXfn6L2EaPV2YfOaFRxbwV9jrukEEI8PiPCDx9WFvBmDYg28ngTvhhke1x77iX48JTmC+OVPCQT3WaSR9YRJzYndv4iOeTCLBYiM/fyjTkXdgoQtcM75lAhXCbaWepXe6zV3fBKOkoeXjCM36CfPsQ1rzynWn82OAmhMNYajoDOpyp2734ZizRwzrTh8MqNtNBEJtoGRiL9qgUxo4xN12UBciP4xz4mVwK+CGN2ofVUHiSPgm3FKzs8oCJjWchU7G3a3sXMXJjuhf/2d8QSYIHcM8VyeK3+7l0BIEo7z5hHW5tltuf1wM6xBY/mfOmX56D5In4qv4jr3MLK1BIwV/FUaCjCzMiz6RVvFi/Z80IR1AYQDP/MIzErnk0M4nfrrKmJkOHicDZOIp44pUW/tMyq8McoUKdKGXKWOms5FToY7V+7Mw2NuOQHacVu5tfA12TjfGfH/3H6hIN1/lIhruRqY+dIo8CqM50IGK47VzFYuxCViTlPWjMopx05OKldrdj/mGTTVzRaD3sJ6QBzQgRAzLDYPQEf3gIu68YKNwlGkVkexvPWgnFRTeuK3T25Wpzgl0z9QU3apKvj4Zg5x256Pz51TYA0+SBMeyVwqBb1zXBjs9UgrgkQL4jLFwK9tqf7PWZ0nLWaMzS/RtgMfa6KuPY7wD5bnSjgMzaz9W+y6+hEFxmvNkIiIUSU8t+pZTmFZF8h4R0t/HwXOWnXSlH/voM5SN9rPcaqXDY7rNXtfJQnkKCS9Shl7KxggBodfSrfcqJmNYk+3tZPvxAde/AyygNCYyXr6ZyrDYEWq0kynQm6oWumsgLTB/QmXClU8PhmNDwP0m7ECl3XtSH72ibxsM1qvm7cX+6oolKFXVgkV+MhH7UBcrTJ9mF4fn0YsUrvhj85UnPwRae/Ga10YnLE1SPHcZ31IttFRx1w1pZ1OXPU1Fq9gcxdrVbstoFabpwQIvo9RUPgQL8/NG2suMdBfxKrETNL2rHLRcXZFJhxmMmWWtLtFqkP1OubiI2By7rVPW9eLhUMkzzAzeIRD9Z8QxNv0mxopEZYLCnfT+LMx6EKe/toT3LVTECo4+el+e7XVl8UrxANpIWr25vaqSi7O2iuVpvNQqWf8jAxrTowutIMk9vdKppwOQ5uVVswj0vsvSqyPYVq6hJMIaL5HB+3v30jMTDiI3zOGV72ts31hSrcprObWUO+KhafvU2scyqa4Nq5grCcmoyjbRyV2YnPjn5x9TOHUEHIp4oukk7guvu14woMs0dGj6CenYm1QnbO3y4xZmNwQ4ki8b3hZ1XPRay2G326tA1tnmP8/RA7sq7QDarNIUH8Y8myGArlnyFG23z1LlPTDQIvCs3b7muJafPRfnhkGUSe/YnMbw7OFuRNlUtJLpg5iZ7C99bSp4QmEd/aX3LhklrN41Oxj0tNUeav6ZLx1GK0Dx0KJhphyS1p6m8PzZDiXEHvCEg+rWAwrDoGypzAlxEDBNn+BEdCkb7eBe36cWvQow+IDlTIPaBG6xVgnj/31OxeKQN5zHO1QJmUV+0Hh2EdP9PW1rg8vVCn5trvIclo8gjWsfWyy9jwcDXN0ZGcBsEQUF6W/6s4MCygrVLQuxK9t59dSNFP7Y5smOKPnV3l8DnP11f+AlUWH0kka4JkxtUr8qICmUi/U4e7OHrwzM7cN+2sBU+0LG1lTeMQIV9Y/KxfCHKnCkEYrznlVXWvir0lv/VWE+7r548bdqb3YdMT7/YTzkJPbGtn+ZYdwPhF4Tl4VjFyAJyDgrbBUnvxG/mRBxnX+QZtTXso9vmwFk+9BkmSaSFexdjs/6E9bh8Ih7DbOeNEbrO5086EvCOELZKB5HlNeJe/iMTRbcoMeQiyRuMvxPLee7QfuGi/5JvjZyegzi28rDfUzImE0Qk3DAhGX2N7C7Qw8Qc3M3jefEobPGBsyWNKbzkPlb1UsUxGfhcISeQCCjSIV4LrIWK9q166t/LGz4sihfaTRp9gNPliL0402jIUF1PnmEvaneuoV7FcYnYM7h1oGndDhsVpnX3FG7RpmIl+P1n1uwXQQa/xjL0KL5kfr+n6ejOcYlF+xQg/PNEyC5++1ms/QYx7M+JNcmiIE5Uyctd2R3gELe9r5GjCNUREN34pV4XFoW9ssLcGUIWZf3ieIkLQBu+qS7ImBJj/hUnzpwawCk4BiaB6ZNOJLmsXTm3rBbZ9ylCMKM9WWOchVF7I2CTjYzYV3ZKE2MKn4O+h5rVVLrsBgzoxxWLLxfF8/k87OCk50nl5xKR3nDUYVGTWt8HzcCovoHWv/bDoRHKixCm4npZhckx5S7+gYS9etIb9t5CcJmVFOtsBCNUNX4TqsEWT8pPa9gmDlifvnDNxL9HMxXE01SwnhGvpbz/jZv5aBs/T6tVNpouCxVLBXZlHmh0cFMPL8qraEqfZO8xe19vcVjBVUIj1k7DrRCvwk7NBnFkpLxgVlrh/7rrG175EjRPBisX9Umk2o7EfmNtpUmZL97kj3ltuaKEu1HofY3BgM3k12Vz9b4hUiowggGKAoIBgQDW8xw3Iw3DjQv5sCYzbOtMyCCGkPANAF7HOwiHy2DtMxsxIhaRNpJXIY8KBxSs3RQqDHOZwRPoEMw8qXnc0xMabh23Q0PlPPxBweXxpHppZqZ8eUccOCNrlgO7Eg/xtI9mAKy7pfE0R3mbEK3sDZdCcZX3IMs0mzlVX4OPE6lzgR4pKqu8QvMrpcfbCpTcKXw7RXBKxj4SWp/vvpI+KwoGvqCGMhgmpOva0FsD+SHFwC9IY8q/OLBc/aWJZ/hx3IyGQIqFZ69VsJugQIvz8aO3HHb3GzIF+RKCoUCnfapng12iss/JQqLl9FCtB/sKLhkNd1CkMw4pymFcZlowxoDNhPKn9O+XSl1k03fQrnNb4Hdw4qk2RTGZ63VXTndZF0TIJK8xLOudnNIIllVZzvBUhU6cGz/ApwIlKia/S20TbO2DZ2hFolkPLMF37ipAjTZ9WS4LVAJmg23XPFMKIxv7Euy/O7eK+KBw+LFhZzbaP3iovKwVjWqAlnopaaLKg/0CAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEFA4IOjgAJyGBur9tggfghUgqLKeXb7+XPqetPeefENBrlPfPTQR5I8iDspEo4OBvBj+KKW+Qcy/jcGpe/1/gjByBUYT3i/nzs0MaQxFQy6fIReEbd1s+6f377PBkMgp+INcEleqms/Ha/4HesdPWk1npzza3KCabma8RoI/dg8yVfg8m5byRqx4G34NuypK9zOXU21dhk7TPPf5RdAiUxNM1ceEvPyvsYxj+OcYYJH+0UatUysZevUrh6o7TEqrg+meSTNQIuezoK2KOR4GDlXWi1iChvv14tWUBa8AQpEaGtMRF9etlX9xn7XMJxyWxaf1sCxD7cLYHmr2ITwcBErA3sRAE2Si7qMoWdaoub5jNs/6zmFwmgG6GiICRVvwstXvr/F9sven06T7BzOqwn0vA/YUs9EZdGtPm2JjsyovrLLu2IlG1Xy7y56GT2gTcw0+2xvAeUsHA1eWD3A9KpHuHV5E2zvwRHApoXVcnwXNeJiD4vlYNdfe2Q+yYWCRSV6RHgzT2fpdQDL/20izo+erQrQORyX5FRESED7yTveJhBdjuaDxPm3zhr9h9pLq9eqgEIz+q+342Ki1gjMPS6VnOejnxvxNIwHdBYkEotKvC1AWpB9X36GyhJgq8lzLtKqXnxxtUGfpyKIXXfXPX8Q7x7mICs4G4PCJr03qeTBK67rMeO2obPcFrDNhOG6vEh7lIRYAyh2ImfDjRBPOcfhRU678JNO90lepuXZDiYLTuxGsCZR9XF+MzqvjlzQzzQjaSwOjpk0oV7pspVz2AO0W73jo/I82q3tCvzzOUEswGGh22r4j3BgPtCozPkJZ8TZQGxhM8Y4RGTkko0qd7YWVWkrGHyVTjqNotnGUHc9thlqM1SijIJoe3g3AS4dqORdNz4aPsvbFqviqAth4JiLNEpbZx1AcIg7p9mUXv9pilnu6NKjEjuzB6u13wh/c+0fVShps/wG4jct5Y9Up6Yy61d/gE+d8OOmK7QJNXLqXdrKCFgYUffu3BGpUZ4YnXeMXGjeS8qYh02Ntr43NjAjYjxIYQ5iAY0nZpSdJdFiMtH9Uf0YHtUkbdgJ4dUVegEJGCp8tt7OPnK7olGJGvZnGlp3gXnJPz7t0gMUFPAL3itfll5GKkEVwUAZTMx04o5R1JA7m0awCrImPX5QZTsmcPQSlTyByySJn7ivuPPsFo4ATpliiqhCqsW6FijP1bEw6BYoLeYcj87LLixHTGqvL/A5OVx/fCE0RfEYVgW65bbhOr9N0rgguEx2Fr34CL7ef90FEX2+Fg/6hnunFHk9VbneUzKabx5QcQXo/ZdNzGBEC/Thhzvz9IYEg53HjepgMnef01aJGP0MyfQsBmAVpq821/gqm/HHPlzQ0Ri/nnLamLA1tELo8ffFHecB/15bMdougCHTxDLtRaf3J5IAxdhs/IjLpKiXLIpgxyNOKLppbz2CXQrPEOmst4XJZpdLi/vlTyvTwXNr+nv+D2xb62tZ4IS/LtyyIHvGeEwdSgzCr1PfRAWp+bA73AnaT9Dk1fY4SSEHgc5hwVHfD+B5R2M0kG551jCJ+yDzlhUELNRxtSHqpAaEuKGBv3Yqmz2KQmJMkUeNafpRvX2vT9FnyiSZc0esA0dx5gNl9dOaDMge2rZhEwpZY4qQCcFuF63f5xYwb2uK0LX4rteX2yX/x4CcZmIkqDECZQocuVA9bw18ad6YhbhW0JoloZzMXXoOtEZy8bW6tiGWAFhZ4gTn1gJYO5b7JocgQjPL+puA4Gzr2YUGpeRDkaaspXjF/YwOlbSBbMo6i/Z2Yqzc1ZsgWQAybB03GDbbB1SetPE2HKYdeopWyQY+m6e++yoyBWxkbQ49w2ZakWVKoSj61CRo3pjZkN6Ur/ibtfdu4Tmv+t2G5MSKcI5sAin8f0LoqnbbiKnrZA/SooPR3d40tiz9LgbW/bckTc7XacrqzEIfMpKOLUQmfCAZYjLuno3DBBWYGCt5iWdpaOAl1zKZSiM99DMrlq0LuObOrlBC2Tflm/RvMZ+E2g4MN88uTNTO/Q/rg1qXD4SNXH8UyKnl/tBOIKDP1g3UyjBsw4XxQ3bOUwr7CQ+YaEQEHJGKqQ0TBALRiJ7uzv2Hj8+IpyPZEwlYuQ5maN7WPaescgMYahwPGoWUPbUCrARpWTE3F4lkjnizKrFVIySCtww6YBkRe8B4hf+omMBIchHdcGBYADxaUJxu3iY7aSbJGDA0eunWBqxCofkTodfLlgmh7BRwratoc4usG2yExOJNYrHJAiQFJQOzjmzMLpIE/Dfrp2/i6ABULbF6peNKWXAl0BjtCPhSXB4A84tOHkISU2TfuXH84/B0KenCniylz4zsryW3SraD6byz6THmkDuNLZzsbu+C8ZRu2IXPB7MCO6Pw95GIsI2XgOpxrZXwNvm/m47zZLnH/W5k+p6eTXukmzesrqmYRVWpLPAQeiWF3cBfBL6aCO0tftsYtrQFeS0MK2tnPOT5ylcIx/r9q/Dcj6mNZNovp4Gb4A8E6lIlaK5Q0vRuwPQtsHlPv5ndMQZ8o46K4zBXacPi6DuLKzA72jxePO+ywWIOV17Wk1sPDBAHcF28y0VhBGacN96vcRSLHpBOqlbvFSXhxTDWBwJpH9X8csxfZXg7M8IXtrORDdh9IJgyAZctYxWWE4326Dzh3saXY8eMH6nndbV9n7PcF7r5g2JSVlDkqCp169mIBZZHpvI0fCF6Cr72To9CYJuR+/ZPFWKCI9lOWoj9+D4Txv2tlA7x+Fc7QLUUhGJ6Tt2KeJ3JbsrY7NujuLcLejpjOCUiuHA0/HYsVAHxGF9YrQcbuxE93qE4U3aovMYfLbeTwMzLd2Ciqw9vh7W1tx3djIH1UF1oQr46dyloSFMH3EAS6kMJ05RXfDMAfedyDjPmbq0iEjHlnTKa38iv+RNHT9j8KBVvU78+rA5+QMF54Tzo0GFIK17wa66vs9XJpGxYkwMcGZ32+LW9eJJ2ipX5RatnxMt/sd9lZIq4X4yYmjDzMRwsrmaUzkULiyHIZs6Pey/PwzVXuPCdLWMHo4JSdIHZOOtOjQACr/v68Y7A35fg9WH8mcrX/dT63YUAxT9dZ62YHno53+4hb801Md8wsBhNFBwqBB74FU0qyzzoBi1tK6yJ227GVa1z8mgynnjg7OaMIsOapTcHEkxTTSrYxMOrvBhZ287Nbj/nK8cMEz3awYGorzUzhD1oxRZZ89PhYnX7lqMFM3BSj77S3L+vwwENKfxvTaFMKFRo8DtvnxV7cPTKqP6nTqudF9JGleJi0i8GNGld2mFeh3kvq9Ekd+xhzMHuhL8uzqSEmu6tktUHEIsCNexOy5eiTxpi/R/T2pRsMdmtmjLaDEslVAngIrJSYeYDSJltcCamiGQ8XavNbsV0UY9ehyKHe4ugifAkysHCBNFHYCSRoQrIkADv8MtzqN1I1kaz94cDLcCz/D9m4qrTXsD3lHE9oxdLwszG5zCTOCmt/qj1CKco37JouhF3OFWxNAZaM5OtS8VFT26UyCHCyY4A/V80UAhNW8AiaH7umlVZKstdBJxLvnZABfLfaLixoVZoGXuHyuA+RCHOE3oShpqwPNbW3MzHXkd0Zstr3+CrmnCyOA00cFgF6a689aBisGDR3VWsWQpHXMh7bZjkvXmdzI2rdUQrZVN5P7OgRQqgA4uAvs6LTtSkvmNsJDuBjEqfgM32sXhoE4GH5pv2/WS3NYsGuGgHfVkoQ0KEsqYfACqoGgj5dknd4aZ/0Pw/MTrncg5McfLvTMGq3vKKScwAFxRCzND5ak9QcW5dxM0lnJu7fAWzeuFfZS9o3rZLQ3bmFM4X97vzURbg/T4L+MoHgmDRxHSOOZf+dpywvKqMZv/DjTXFd1euF4aHjzwJjYL+cbUG5igFGCQ18X7baeYPO62IOa+hwy4Nf4o8++ddWrMfEWVUHvLztYc2tnmAb259QNYZYDzwR8sBbWqeXOMV2LsYniPwUrtulaeD8ifOT0pl8Q/8LtaC3YGCL5+6rARD1vDiktVz/CxBJAV1HlZ2FnXDO5YFNMjLYe9MiYKxcGnIBTboxdk5Tzt06BOAsa53rVbOBtsy4L6b7ez3HBf5W8TSuhZpZZCve1/Gg/5dTEqPpoY9mgHmwvmX8APCR9fzv7LtkrXaPQVYjG8qsStJ9YrijJt4dxQGMP99juZPDahUvqEb1etWKR1T8KXGQ07/00PV98U+C4i5mjVERQ7E5f230+Ot0bYBKgxHo6vHzJSqj0KFcyAO8xyIqxFTauLd9bmqFENSEFEKOpzPqXZY7TvtGPZeH/ePOLkCGf8fEFcIuuAu4ND0Jo//sqcz/SK33KbrEz89WMI1E17jqlk9hPpEyE4Ok9aXWivzNL2+P40cp+jscbXPUZJbHvQ2+hqhMLU5+1Thbg3P+YAAAAAAAAAAAAAAAAAAA4VHSMmKXQbliiv3WOvfcmg0sBaKz0+P3q8yNqQluSx3IqEliB156Kh1CBxndVWlEUfW+16S1pkbrZgoXzhf/TC+kfD1pLFw92V69IeTzXko1O2SfGjRcBgIXko4bJuV026m7VlUBjKIHPsTyOScwAwlbXZyLnvHt77hRd2t30Qvv9BzgWNHFeGL5ybdGKnyAnocsCBcrKJrgaMsIWE8OKTYm3Ex7G0DB7GQwfo+ivkfXmdTmAQnIfK5hp6N6NGYw3BAyjuXXFm46ESPb2jt9sN4jLtoBNuZx3WsJ9ucQXkGKMIhHQxzyJ2sfQhnRUyDO2YZE3aJfykBDLcthkC6Ikqn5pV7NQCJMAIajVOXLXxBbYmkF0vanlZTGMRfC/QKsRV6LdHWBYR8HVyx2ZUO3Jh0ycAS0cfnHlKMlXS1h2xA05nYCVU7TMhP+zWk0slVEPZkC9cLrXoGCiHIdhH54mXmV/c1zdrUToWllvgtXBFq6Z6OhihSFzKvOU4B2yMidDIT1JXwg==", + "WmSvRuLzS4DsGnR1H79utDMD3n+msYHUNNulBKvy54kwggbkAgEAAoIBgQDW8xw3Iw3DjQv5sCYzbOtMyCCGkPANAF7HOwiHy2DtMxsxIhaRNpJXIY8KBxSs3RQqDHOZwRPoEMw8qXnc0xMabh23Q0PlPPxBweXxpHppZqZ8eUccOCNrlgO7Eg/xtI9mAKy7pfE0R3mbEK3sDZdCcZX3IMs0mzlVX4OPE6lzgR4pKqu8QvMrpcfbCpTcKXw7RXBKxj4SWp/vvpI+KwoGvqCGMhgmpOva0FsD+SHFwC9IY8q/OLBc/aWJZ/hx3IyGQIqFZ69VsJugQIvz8aO3HHb3GzIF+RKCoUCnfapng12iss/JQqLl9FCtB/sKLhkNd1CkMw4pymFcZlowxoDNhPKn9O+XSl1k03fQrnNb4Hdw4qk2RTGZ63VXTndZF0TIJK8xLOudnNIIllVZzvBUhU6cGz/ApwIlKia/S20TbO2DZ2hFolkPLMF37ipAjTZ9WS4LVAJmg23XPFMKIxv7Euy/O7eK+KBw+LFhZzbaP3iovKwVjWqAlnopaaLKg/0CAwEAAQKCAYAINFhX3G0qkSgrXCdhIB+tGxhuunqHLIPxm9W8BS3KcAByNChjW49jZwMEMXf/DyM1ZatF66I8YePBzwA5Rw88G4bj11vwlI7WXbXOruYDPulM5/4oXBYyBZRX4B0erzMoBA+TzAY0ZiQEoLLaxzwGS7qbJ7PJ6sDZ+t7VJ714jK2fiaLreSy59kZ2HGXJL4Yv5vsdx4pX/gCL0JzZZaAo2L7c0G2uj+32uKw4rxo0Z50GaNS0zs+ghQf8Ai1v/yiGEN2HtKuk87dB/iEJc9P+3DcjicrE08YdpDll0k6BX8fXSKEQEC0HPeJwsjuHggUraDekq0g47o6YBxP/lmln5XoIsSsGm1yg6EyZXi2imzDuRlaOKavls24yxfCGTCAczP1LrLpYJVgYP/Jqmv+QvLJ/bHQrg/f1D3RJ8UbDViI5K4f6/ksTjnB87jvTsPZOAsAE8D3fwDKWtje10q8mnjU9DDnJR3XFB7O+iKpzJpCHG3Xh7A8sgicoW+sizPsCgcEA7BDIrnTvk5ZWakWSTLLWZlLePR7rZ80H0gQKL1Nkk/De/Oz0UXg5QOM5Csz3Wnn2zhe2X5zrq/i27uno5qAU92UIHwTateP+o4EVpzgov8oHY4FqD2PtfmMqzfQH/qe/IxhllU9xS1l+CdcMxU9zV+ikjm44UpFIsxABj/wrSvqTmjpSchrrznKX8b3gptf0JbqLH95g0ShVO5c8jkUsKgR8qR+cVJBCccpFIpsUWu7Ju9KK5623uZ/0YODzMZBrAoHBAOkZ2M6wgAo251hTmO9bTwKuehnvWYnNYmcZpwmEJM3CxsooRYWvLmYwSXbfWNvOd8JGrZIDZG1DQkocSvJnaCv/r8Z5S5p9oMmEK6ZJamhsp3jb6rjx8OtZOciIgg6WXmfJtNfIMH84tiDSWkd/NwOlfhYsygeuUGRl1w9Sdag4eP2eJ20PYF+hv/mnsLbYT37cZQlrAdVpl+0taStWV0ABgbauxkVgBYauNzWyzsCA3dSCDWOBVRRMKbqBeLi3NwKBwCI9pP45E+8SZWJwyPG7FwIsjvPKolaiFLpPv7JxpCsZSx7gt+eBSrywuLtqU46aFkR6iAeCWWTOZKpu30tkeOYRj4YATEEJ2wuYU623paF8CmpSgTHOSsqEU9cfyHEVn9HVXha0OTi2uGNw//c2uQJNSmEmd6DyVdszPSbHavgrNHGwd/j5Eq8VTBjSc91/gXhfgIKU3PI5qXNFUpFIU0mc8QAPB7v0WM7sie6lE+TEsho+RcupFPclzmqm9l+AFQKBwQChfDCA8DGj4elffXqjx6Py/aDFOtXS66BSQKlBpHRCv78r6b5QIM6KKMWcPpq2nFDHHGO+le8K6t+PrA4X5J98a8QAQaOowYOUV6ZNquq2sR9MUT5JJgN7Z/LqA/fl1zJLwKcyHhPK7yTtlAzLH0yjkBDLl/fWXmJ/SzYz/TJZedYIDXrOySpA1jPC5vM7mJtqDZFJdwJsMJz5yM3lIgmL4/9S6b2d7iml5ieFYfxtzFjhkb9owf6I80KtXGifvv0CgcEAjaFygKCsH0elrhDQ5nf4JwbscRLZU1sRzp3K+uI2gVlyuwjMbAG2PFgP1NRpgG7G/G0SGZIsqU7K4inRw+uWXEco+6JZ6u7b4ikTo7XTNsRxyxsiSoHosiqBflqvFghmFzuSkQv4MPy6piqqR/55K6hgvhc+VKxqPDUCkVeqYvBkRqmX5wNhOIYztBT/UFZxRelO8wmH3+xbXMCOTNz6qT5bCZCRRO4K96Z9gj6UdS7sCvE0LhFKOOS9NH56OXYt", + "MIIHHgIBADANBgtghkgBhvprUAkBBQSCBwhaZK9G4vNLgOwadHUfv260MwPef6axgdQ026UEq/LniTCCBuQCAQACggGBANbzHDcjDcONC/mwJjNs60zIIIaQ8A0AXsc7CIfLYO0zGzEiFpE2klchjwoHFKzdFCoMc5nBE+gQzDypedzTExpuHbdDQ+U8/EHB5fGkemlmpnx5Rxw4I2uWA7sSD/G0j2YArLul8TRHeZsQrewNl0JxlfcgyzSbOVVfg48TqXOBHikqq7xC8yulx9sKlNwpfDtFcErGPhJan+++kj4rCga+oIYyGCak69rQWwP5IcXAL0hjyr84sFz9pYln+HHcjIZAioVnr1Wwm6BAi/Pxo7ccdvcbMgX5EoKhQKd9qmeDXaKyz8lCouX0UK0H+wouGQ13UKQzDinKYVxmWjDGgM2E8qf075dKXWTTd9Cuc1vgd3DiqTZFMZnrdVdOd1kXRMgkrzEs652c0giWVVnO8FSFTpwbP8CnAiUqJr9LbRNs7YNnaEWiWQ8swXfuKkCNNn1ZLgtUAmaDbdc8UwojG/sS7L87t4r4oHD4sWFnNto/eKi8rBWNaoCWeilposqD/QIDAQABAoIBgAg0WFfcbSqRKCtcJ2EgH60bGG66eocsg/Gb1bwFLcpwAHI0KGNbj2NnAwQxd/8PIzVlq0Xrojxh48HPADlHDzwbhuPXW/CUjtZdtc6u5gM+6Uzn/ihcFjIFlFfgHR6vMygED5PMBjRmJASgstrHPAZLupsns8nqwNn63tUnvXiMrZ+Jout5LLn2RnYcZckvhi/m+x3Hilf+AIvQnNlloCjYvtzQba6P7fa4rDivGjRnnQZo1LTOz6CFB/wCLW//KIYQ3Ye0q6Tzt0H+IQlz0/7cNyOJysTTxh2kOWXSToFfx9dIoRAQLQc94nCyO4eCBStoN6SrSDjujpgHE/+WaWflegixKwabXKDoTJleLaKbMO5GVo4pq+WzbjLF8IZMIBzM/UusulglWBg/8mqa/5C8sn9sdCuD9/UPdEnxRsNWIjkrh/r+SxOOcHzuO9Ow9k4CwATwPd/AMpa2N7XSryaeNT0MOclHdcUHs76IqnMmkIcbdeHsDyyCJyhb6yLM+wKBwQDsEMiudO+TllZqRZJMstZmUt49HutnzQfSBAovU2ST8N787PRReDlA4zkKzPdaefbOF7ZfnOur+Lbu6ejmoBT3ZQgfBNq14/6jgRWnOCi/ygdjgWoPY+1+YyrN9Af+p78jGGWVT3FLWX4J1wzFT3NX6KSObjhSkUizEAGP/CtK+pOaOlJyGuvOcpfxveCm1/Qluosf3mDRKFU7lzyORSwqBHypH5xUkEJxykUimxRa7sm70ornrbe5n/Rg4PMxkGsCgcEA6RnYzrCACjbnWFOY71tPAq56Ge9Zic1iZxmnCYQkzcLGyihFha8uZjBJdt9Y2853wkatkgNkbUNCShxK8mdoK/+vxnlLmn2gyYQrpklqaGyneNvquPHw61k5yIiCDpZeZ8m018gwfzi2INJaR383A6V+FizKB65QZGXXD1J1qDh4/Z4nbQ9gX6G/+aewtthPftxlCWsB1WmX7S1pK1ZXQAGBtq7GRWAFhq43NbLOwIDd1IINY4FVFEwpuoF4uLc3AoHAIj2k/jkT7xJlYnDI8bsXAiyO88qiVqIUuk+/snGkKxlLHuC354FKvLC4u2pTjpoWRHqIB4JZZM5kqm7fS2R45hGPhgBMQQnbC5hTrbeloXwKalKBMc5KyoRT1x/IcRWf0dVeFrQ5OLa4Y3D/9za5Ak1KYSZ3oPJV2zM9Jsdq+Cs0cbB3+PkSrxVMGNJz3X+BeF+AgpTc8jmpc0VSkUhTSZzxAA8Hu/RYzuyJ7qUT5MSyGj5Fy6kU9yXOaqb2X4AVAoHBAKF8MIDwMaPh6V99eqPHo/L9oMU61dLroFJAqUGkdEK/vyvpvlAgzoooxZw+mracUMccY76V7wrq34+sDhfkn3xrxABBo6jBg5RXpk2q6raxH0xRPkkmA3tn8uoD9+XXMkvApzIeE8rvJO2UDMsfTKOQEMuX99ZeYn9LNjP9Mll51ggNes7JKkDWM8Lm8zuYm2oNkUl3AmwwnPnIzeUiCYvj/1LpvZ3uKaXmJ4Vh/G3MWOGRv2jB/ojzQq1caJ++/QKBwQCNoXKAoKwfR6WuENDmd/gnBuxxEtlTWxHOncr64jaBWXK7CMxsAbY8WA/U1GmAbsb8bRIZkiypTsriKdHD65ZcRyj7olnq7tviKROjtdM2xHHLGyJKgeiyKoF+Wq8WCGYXO5KRC/gw/LqmKqpH/nkrqGC+Fz5UrGo8NQKRV6pi8GRGqZfnA2E4hjO0FP9QVnFF6U7zCYff7FtcwI5M3PqpPlsJkJFE7gr3pn2CPpR1LuwK8TQuEUo45L00fno5di0=", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "txD6wM842HhrEm3CpA4YX827z/fuSN+nCw+Rj06MzmW67zQCY1QW3YKoYhoV/A/2QpA8LMQ4bUAbJfAa+ECo4YESRuk9quxAiTIWWo2BrmnVcL+BUBzAmINLS9s0aEvjqwFhoD4O5e9zrJRtG36jLeb+AGhF4bXMErTPE4LsbAkH4APvPQ3Pzn+X+fmZ9Zj4bIV0ZYxJ8szqibMCowj63aLtJILaQflWjmWBYfMEfhDvNvmwOarMfARLqNIXP7KC08zWWjEU7PccphBsSR8RrznOl+BYXQU1jr910iexxOMkNoMKPwO3UvGFyx0Uq37JFh0mWnuO8gj6PSPb3PntGBUZn+HDRw5iaOZUKGwIqF2Hev8IblVDJ4arbeEhbNa8W7Xz8h/0Zen6b5wJ7/05zUPLBRnVNF4+PnBhxetBWE/2n9y2Rv63jwXJm3wMpbSk8V/P9t3JhATkhMLu0E6GulAphr5tGQAzGyFMgFPIU1uUc1vGfIT4sqiqU7IQs0l3zslMJkMwHOfUzeAlFEddo328C3uPhMBB/DMF6R4Q4RWxyGM6QGMpN75k8IcXg07m2NKNXW1T+WbPe6hAO9AeQ14fevTF3+J2Lz0PLdBoiTnZ/yrhzUX7JTz/rFfpTG++wmatgocMQoPwPUgt7SejaGfiDd0FlExzAYOCzcUwQ+vNq/Qb9cl/P1UvOwcJW9qrD2sN7EN8zB2pfCdAdlxLMBnpbK/lDZ3lYEIIF5rwC2q1dIa2nqC32E6mtcEevrCi+nIb/ItCKlirLO6j+gfck3XGziGwIs1ZHb9XNpiuSrpr4x9e9zq6q6dT7RiTxlgHoIT+aQZV5MFOobv/leqBA7uPin6mOyVIdCUyXbt5SGgOs8VFABIil6L15wSgBaTEvETwapb0bRZQ7Bi9gSihglSI1lG+aYn/yWNH6I400ocp1AUoP51rkKCK/221KqsvvNd0ikFuk/8BFs+7LCtPEi8R4AZ4asIeRfglziML5TOL6W8aw9jmX8zFnHwBpvrovAg7+GKHnq5oEna3CmrvulKyKrMmKPUoxXKIjH4umgleHo9hu11zH9pbyasNwBzmn+j6dqfhBseq/sTUwAxyIO2cxbPxmAHDlIUv/UrbUqvOxFc9EGADvocPNgGW4pL8vaXdffiNt+qlB09sjRNph3d4ch0nXvP/F2FQ07TLyEXJe9Wv0Ri1AFHCNN7wUA8Xin0DC1s06PHXUgnQbreWD3S2Hk07HKPVsGOXiozL65pSDpribgg1xa3KRKzFU5EOW7zqtXxDs/2CqZGHzxfD/cCq0KaScy98YQ5uUqGQHlVl3h48qsGsQlNED/2KFXhR4ZAUHrXYqeiiDBOEIxAKobw5EjdmGzdE2M+VqiqB6mCyAQhA+HzVVdzGznOxwo7NSdlN0tnCzSbN9Rf0IMTFYBdo7SHr1uyOH6nyNPhc+lELlmP7RjDPjpRphXEytzANG4Y3Cex/aJ+e39Zx3tDaL2L8coXAeQGtZVfkgx/FYULGuM/nw2TlqYzaaZUy+R2iYNt4WAx9CZmiXwwSexAPawMkrv/b3x9b0S1WIJCOX+Aa3xVTSObua9PHYkGuUtOq2QwOpcCC3k4BMW4HVI+btua+dyGjibSzuUkOviqvO3mUlvjs+ks7quycttm3RNbyhPKh3J2Qz1qTlg8Dcw0WHEvMHXfbPpSvHPpcC0zTNkcG8S0Tivq+9Z8pmHsAh4bLPGRIZb+qqq8JV0Z9SWHFO7rub4HFX6V+shaWriCz13vBcZ4CB3d2nBICFOEe85RGZ5tTg/aZhtjE730DUYL7R148YCfjh739g0hLA0OICSETlv2C+1jhMY0nKb7/InavUVUH9mydp+mdeQvV4ul4nuo3Eo6AQrOrkHh+6egoWdRGhWrnZapw1fqf6vpWEiWFpJH3kl9YP8dfWipe/WwF6Dyhtzy1b3S3rHJ9p+1ToA24JEXzRWmcHv+nRLkMLSrEquNpaIq9InpaWTmA3JMErZGKZjh10gbPO310jUSDWKFBJai8Ka1mVra2rshBP5yz46TyI+Zu3o/Qccw6+ZbPNs+jilq2rYhk1g0qSBamez05A8NJHQLz9ya63JvBGpeQ3FkLjjQ/gZ6E61eiWW+eZ2TPhA34P8tnD6HMnDlNeUn6jtSTR8libkP8MkTWByrB68sngqXvPqukewHvUySDmllaUnA5HNEbvy/LyEWrBaK4dXa1P44zFlk/KNCfVW+VAT1SVfgOEQmqkC4vU3URDL2tyzZ4NB/Lg1ktAT5lXTk5/wbjqUwHd5LpfR1Ijd+L6Lww4TiXZPkd0HVLwDpJmhMTm4sMz5V2+Nuci723QDVHDiYumqaL0/a18ZPihT85FmtrEQ1EVrhl3GQXH4HirR7q7cYa67jz6PK3NivevfUV7WmGCf/h8kfp13IAyzy+QzbWabvc4Y4kBpEgQxk40jiRw3U5qI9KYP7Z/squYkVqDh9ke7cb3ePQS+GsQNpoDGu6Y5j3GMyM3XOWNFcTChlQGpG684gRyaYoVbBXbSN8M0UrD8WpPYjItIn3eAeNEJSqwkBcZeu0LHImwD9xhFyOf89BPfbn0wccF2uz62SbW0310YLQxTDjg/RoDX7Y3CDfl6RbOMJ+Y33oWi8Nxy4d2YklNLfIarSXc/V7+OLmu88KrJ/JIfHVUWuOtm5KVgPcArNuD4QppuBQBbYd4NqfNbhf1aH9jJTRJWUN6t+Xadn6LYPOPCRPlvZc8Ajo4o1c4GScSGLqdMa17EW9aXQoR9saOhzUtJCuiN/0eXfQgTe074kXgV92FE5VT+aqM1jZK2E+mqOffKl4rGhGf64GEHe54ZWNk5RFut7iQPxNu6wB4ybGz6E8UI5Mh8U7lq1bf1Ex4rEfsY5GGTumfrZBAUvmQ8o2DxQLSMWvqwOdoVvnrWP0K5KO4y8+rr1abMbVzNKgv7jcaAw37cdC+FrO/ha+PlKGZGzs21tKYXCAAfnceW9gtN4cLLctWhMW42c9hws3n3fwYp11ivsRzUMA+sEaQ1EaNkbFgrzF2TWN6uSPEH0BxW7K1gG62K/8vnCxZoQKfuQ1EiIbtLjq35cG0UVJYYfCvlnwdjlk0ZhO1wm8YTSB/N+A9FOl/aSqbbfSUTd++CBmABuRZWbEZijTAGkYsxr/b2mXRxoPmouiV+WkGa+72YK+cWdFavo+GY5iHRUgI9VSe35D8AGw96G/lAOnM1SGLwTNAFU7dixDD+n6xSS+jicgu24/59uKP1BnAmNM6sKTSZn+/DzGa2HQOoTBTKAH4Ka1dp1vTtD3V6dxhHLh50w9W+b1ydR9G/qjw/ycYNd6eT7fTDQBn31R5efzsheFWhLdomMmUaHnrM7k/93yuIjRN0yC0O83THhkQ2yPQCEG8gmpFIMBXvIUXxCMT9nx5jy8i0Y0fyerrGBxZdd6p/wBQDkLa2wbwxwl5dRASgGIizVoS5ffZiOdJnEIvtcHVQnQoB4XYrwZ+KUkvHiHWFLdC/OFsbhBMHkvnmIQiv6GW+J9qx1ez1zol2jOwgk5oR564soeKuoy6OKXpYyBDwhnquOrjp2KRfGTNzCL+QQZaCn+8CN7vt2Edg6O5MJdQjuXR+UDr0TFaw0vEyB0aKpM5iqo8Xsph178Y09nYoeewYzKXNys0fSBOXHRLPizlsUoJQKXXjcWe3N1sYGOtwEfhdAEk12sSTK3OrbfmOPWymO724YUHQyG3ZRv7MmBtYNcOSWF1MOQakvXtkBleX7TL+NNgyv8D1pXCfJVCMlQxR3V5PtQLHWyRJYk5OQ8W0Ko6QDpM9D0SbwsbQqiR/zd30XYkWGkSTW5/2MjaPfFXSMdqA3fiOKKwPnF0U+aT5P/Tm8d15Zc+SEu8RAfpyuvVnC0kZwWbsi56xMwwF7FZf7HVb5q5sFQP+sUOuzM0Skv4ks6BItteTGXMUgoyXPfBWnE/2Fy7fzu2y/XblQQFoHK3GNIv2vQXy7ahO2g4Ym4TpkXAmjlUeiPCr8nkodGo/YtZOUEqzdLhqEiuQBlgiFN0qombAvngi2S5RJx/w7yu2xYbFXG75OzfoTbBIXK/NY+7VuseOfnVASx/WPbkLQ3X90aIDc/HzPt2ApJr0hGhkGqKZURwbHTfroXB7E7vA7TvdghmBzxNnnB2xQyH6mgf6ySRRMsNhK+Km+baFkva/SQveipT2Dr+O0x0TqjTG3bCvSaRfX0GCg4Qc/4nOvnE817j0R0flg7Vnp/R8eQlp4ShYS+RYudUbU+m4GY1fxgkpBZhvLQqGWZSmLnMjCCVG8wtcah3TtfKgTbsT7L3VTvT1T0BRfxl8oSOOoFodKzHh6uZq5IlWumIT+AZIcSMxUZARAXRVBxeM0tZZUDFyRBbo2SleIDFTZHYt02e46aAQYUFRg9Rn+Wn6TjAAAAAAAAAAAAAAAAAAAHChMZHSnWqnRb9HwB+Z61r0Fu6usby1qOhT2RRtguDy7oTbOtsu/l9pX7izc1pLYoEffDbHKkZ6gNcSejHc08kEaTz7okMQvh+erR1gkLChmDQVwMLfsok8VYssY8NSdWJsUW12e+gmzS3Idi4iT/vaHHmk2GkwygQxlUwUKb7AhwD+VRF5XfsM5/D8FC77hCxWBw/zSjD2G9jbiIUfTxg4GNw57NqqfzM10/0VcmUXBH1fd5y7R1BZqAj4yGtbOb0XFcLynfWGXKy834VkesP1r6vQ6EL2cHTKnJjSWIAzBzg4o3P2gPJPcj5lBNDVi4t4Q0BWihBOeR2MD6Dq9LFMZV6+/AjZxkzeUajztOyj4OGL0rBZ5/ScdfaUd9Ko83H0liVtCa4gauNhfCz9txhm9XYUFNG4qJwlyzWidLcY9E/isdHfH+j8v9Lp165ltKkzOgTpqBBStAohCLTb9zATLm+ZxAfTDa4Z6Tw3OUsY62jZpd0tHEMgj1BNkNyq7ufM9zPJc="), + new("id-MLDSA65-RSA4096-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, + "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"), + new("id-MLDSA65-RSA4096-PKCS15-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, + "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"), + new("id-MLDSA65-ECDSA-P256-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, + "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"), + new("id-MLDSA65-ECDSA-P384-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, + "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"), + new("id-MLDSA65-ECDSA-brainpoolP256r1-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, + "Mnlu3G29jKF9NLXiQGa2YmeT5x+HBkUREAWPIIRvHCpgyUXUIXqRDTiey0pXFwd1R6mcYCbENcW22BCtUo6D4mxRAfLUWpqsyzxl4Wuc4HevE4Tt4ErlLmvtC/BFODoL7sgqGo5WN56+0OcFItjqzd1/wBhWrh6tbL2PohY2w+AMBTIzDlB3I37wT/l7DW9yCWm8Rvb+agEoJ9jJmGlRYlhLTYSf0n/lKo+KG5u9Kw5rl1LV+AWMsgdc8Ett3zcPk3EbehcjaG4hXWLX6g7s4kXGrSYp6bIgskUlizrcb0G1/yk+WeMqrLYNywAWcQgPNXRyP55ve5+R2mzTGIhYEZt05WZQjHnzJbvXnuT08H0Uf8vjeNJpvAkp2XmVzMOXzTnTqyqYIVoTOeSGLl8dj9+hd13oq46Oik1ZseXkpexr+r3M5ZHSa2RcYssJ97els6ZGy2uL22CUkN6Ok/M/SL9fPES2IwsCf/deQpvZHDb6Y9csEn7VzBubUCrxThb0NXSAGoYwpPIVwvqYmQcpfFiwlTdjkpwu7bm69XR6yXeerYFzUbh6R7rJYjkOPp255vb2TRHoeB/fvxvOiLcFuXhaGmoYgo8XnZA50x1aWJfSSC9VHvcCrQyICKahtK2UcP0f+wEFo/9tL+AFAMwWEsI0hPtnPlf27ZyQg6iLDY92V21FCUjGMZPIZQfdV0C33aR0pXQHafFd07I8VpvFRyQdXcQg8GpXs6jpqFoLvMikkzDbccGlxPP2NzjlliE08eurG8+XUUjBs2q8oDobfPcz+ESRJQ8gZIqxCcGK/P/+i4Teqs3gnkxNteJTA/Z5ENFV9Nujlh1AF6f/SpVhTSrviR9aTsl6rQuXZKKjyV6vptLpK0QuzbHWUCjiUUtRvVC0hL1EbUP76XL4nZfA7Ph6S9PWEcRoCu+BCBOxXg9ciXOc7BY+1w5XoNgQPDKNR2gtjuuaqV4fDscmBnvPZOTYBRGZ7lvLf6bP8AvicUSX/YBD6lXxwKleIrV3L8E3X0D7NB4ncOIG+/JyPF/sHTmjed2q1bgs4A5q4KoRJLd660dR7pbG5+vNzU5Wn7vkDIdE2v4553V0YVecBixNiV/ShLvBo31CcRdwqQYFUPRaL13zlATiYOC8w/gstuCVVUQQuSrJpHAD5d2FXWux8XzD1qpl+gn7EbOWS0fLIR84YFx2iFO2MSJpmc4YihW5ps619xJsKZ5OylEs7cPkJesRAyxN9O3xKsbQc2o4ZCRG33eL/hOF6bG9HI/SanS0RQlzngN0AwpcD0+O2MhmT4gDVskY7Kk5JbG/5ImRZ1jIDhHtHcXGDMG37sHnH5am24xLvsSeS/i0u7s6M7SlaxJPJXafPwYRiEZuH/QlueP1ik5ZdTMRUnueyJosYp4TIwSm6g24PpUFU3QkHTUfYAosDMSJ5vdh8MG6pxQ8T9YoW98rrkvlJhwySjk97QVdl8nj3GeYfCnibtRa/T/1zl9crHo1UShUnD5+d8te7Ys/svdG6mmTM+6FjwgqsE1crHMloAWvcXlXXz4Z124zE+wOqeelKDZs24YhCuNwFWXyZ3mMYYba8hGiK3Ghw0Jww5KH5IUnReyjZEdjslD9/CCi55NmKXoqyfLD1uAY68O5QNE+OXzE3khKupDUUnwp42qAWpqHYC3k19lkKbgkg18yBN6B/QFVB1GbEidMVAxNlwbwQveC7mGeQAehx2LcL63ZsCh5/TFIkReypafJ9Dve2uxOXpQK25XheciP68knQvQREvsExnUlkG993h9jdXyI+n2GJoOvf22woy/fIiCOf9CNiM+GEAqXer8X9mfxfpfbLDJcweU493Tk5oM2th7yD1c54CGu10LsPT90FNkUJKh9qwEyQ0jDlaC6OUWh/eWdn4BFr3ngmpyakUGgtZpK4vhrnZlAIq75yyTj6WYsVdfp7h8ut05KX5AziQwL5mPaeo2iLinGd6r2t9n9ge258fVpvT+x0bkeAXO3wG173VbOlswTRH+HIzmgEuF1kK3gcv6+4etxHCmxFlQZSNv/o9TWNhIkXipyTuPpBqSTojIc4JqGN1Y61XwJIJCQyveaSQAdkLFXjkJfCoLuFcHBCQDjmN/PfK9aYSD/KW/W1wLkNLYsDvZIdGMmSc2OaoPKKAwW/gLBOx3+6ASppR0FGo0JJDFSH+1Kk0EADFTqfJr2TtUoSL5U7ZhBXR6sRVfUScPMayklSRB+rOLi9iRRw5MXO8ajNvWPTywT/elgsF2zWUfAo6KbJYgaEPJFjnmEwS58et2xGU8x9Jhc+QYhcTEbU2Yavy56naezemIx9hnmvEGwLlj6oo9TE/jZ5jbfnhJzdRK2j2RZlE4TMYcdTkImuJVjRyqvbkSoHshK9MJWOoZD4s/h5Jxd9QGAIu9zOhzU8Li0NqVLDI2dMOHWpCaKRJOx4RomAzvXxzRDN4njcBMoqTMbyWObDLOrfZrRJyGcr9mzQfMC8rIKpa2zt1lIcj+rJFeEGhSCBhBdNPd15NdUA5ebFLSL0dJZEx6nYWR7VOi2ipDGiIxMWgd122CBGzqQxdnFqys6tiJCyIp/5Bvu2ozIgscxSIAEFC+V25uPcDFrLUGDpRYQey06nV7pDtTLtqJLgtQhKpyLVwhjzPcaJ56fAw+0VKNmYzsOArvVdAq1HvqaC12JYA==", + "MIIWajCCCP2gAwIBAgIUZ6+lMTPPu5tk2bVDNg9Pen9j3qEwDQYLYIZIAYb6a1AJAQowUTENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxMDAuBgNVBAMMJ2lkLU1MRFNBNjUtRUNEU0EtYnJhaW5wb29sUDI1NnIxLVNIQTUxMjAeFw0yNTA3MDUwNzMyMTRaFw0zNTA3MDYwNzMyMTRaMFExDTALBgNVBAoMBElFVEYxDjAMBgNVBAsMBUxBTVBTMTAwLgYDVQQDDCdpZC1NTERTQTY1LUVDRFNBLWJyYWlucG9vbFAyNTZyMS1TSEE1MTIwggf1MA0GC2CGSAGG+mtQCQEKA4IH4gAyeW7cbb2MoX00teJAZrZiZ5PnH4cGRREQBY8ghG8cKmDJRdQhepENOJ7LSlcXB3VHqZxgJsQ1xbbYEK1SjoPibFEB8tRamqzLPGXha5zgd68ThO3gSuUua+0L8EU4OgvuyCoajlY3nr7Q5wUi2OrN3X/AGFauHq1svY+iFjbD4AwFMjMOUHcjfvBP+XsNb3IJabxG9v5qASgn2MmYaVFiWEtNhJ/Sf+Uqj4obm70rDmuXUtX4BYyyB1zwS23fNw+TcRt6FyNobiFdYtfqDuziRcatJinpsiCyRSWLOtxvQbX/KT5Z4yqstg3LABZxCA81dHI/nm97n5HabNMYiFgRm3TlZlCMefMlu9ee5PTwfRR/y+N40mm8CSnZeZXMw5fNOdOrKpghWhM55IYuXx2P36F3Xeirjo6KTVmx5eSl7Gv6vczlkdJrZFxiywn3t6WzpkbLa4vbYJSQ3o6T8z9Iv188RLYjCwJ/915Cm9kcNvpj1ywSftXMG5tQKvFOFvQ1dIAahjCk8hXC+piZByl8WLCVN2OSnC7tubr1dHrJd56tgXNRuHpHusliOQ4+nbnm9vZNEeh4H9+/G86ItwW5eFoaahiCjxedkDnTHVpYl9JIL1Ue9wKtDIgIpqG0rZRw/R/7AQWj/20v4AUAzBYSwjSE+2c+V/btnJCDqIsNj3ZXbUUJSMYxk8hlB91XQLfdpHSldAdp8V3TsjxWm8VHJB1dxCDwalezqOmoWgu8yKSTMNtxwaXE8/Y3OOWWITTx66sbz5dRSMGzarygOht89zP4RJElDyBkirEJwYr8//6LhN6qzeCeTE214lMD9nkQ0VX026OWHUAXp/9KlWFNKu+JH1pOyXqtC5dkoqPJXq+m0ukrRC7NsdZQKOJRS1G9ULSEvURtQ/vpcvidl8Ds+HpL09YRxGgK74EIE7FeD1yJc5zsFj7XDleg2BA8Mo1HaC2O65qpXh8OxyYGe89k5NgFEZnuW8t/ps/wC+JxRJf9gEPqVfHAqV4itXcvwTdfQPs0Hidw4gb78nI8X+wdOaN53arVuCzgDmrgqhEkt3rrR1Hulsbn683NTlafu+QMh0Ta/jnndXRhV5wGLE2JX9KEu8GjfUJxF3CpBgVQ9FovXfOUBOJg4LzD+Cy24JVVRBC5KsmkcAPl3YVda7HxfMPWqmX6CfsRs5ZLR8shHzhgXHaIU7YxImmZzhiKFbmmzrX3Emwpnk7KUSztw+Ql6xEDLE307fEqxtBzajhkJEbfd4v+E4Xpsb0cj9JqdLRFCXOeA3QDClwPT47YyGZPiANWyRjsqTklsb/kiZFnWMgOEe0dxcYMwbfuwecflqbbjEu+xJ5L+LS7uzoztKVrEk8ldp8/BhGIRm4f9CW54/WKTll1MxFSe57ImixinhMjBKbqDbg+lQVTdCQdNR9gCiwMxInm92HwwbqnFDxP1ihb3yuuS+UmHDJKOT3tBV2XyePcZ5h8KeJu1Fr9P/XOX1ysejVRKFScPn53y17tiz+y90bqaZMz7oWPCCqwTVyscyWgBa9xeVdfPhnXbjMT7A6p56UoNmzbhiEK43AVZfJneYxhhtryEaIrcaHDQnDDkofkhSdF7KNkR2OyUP38IKLnk2YpeirJ8sPW4Bjrw7lA0T45fMTeSEq6kNRSfCnjaoBamodgLeTX2WQpuCSDXzIE3oH9AVUHUZsSJ0xUDE2XBvBC94LuYZ5AB6HHYtwvrdmwKHn9MUiRF7Klp8n0O97a7E5elArbleF5yI/rySdC9BES+wTGdSWQb33eH2N1fIj6fYYmg69/bbCjL98iII5/0I2Iz4YQCpd6vxf2Z/F+l9ssMlzB5Tj3dOTmgza2HvIPVzngIa7XQuw9P3QU2RQkqH2rATJDSMOVoLo5RaH95Z2fgEWveeCanJqRQaC1mkri+GudmUAirvnLJOPpZixV1+nuHy63TkpfkDOJDAvmY9p6jaIuKcZ3qva32f2B7bnx9Wm9P7HRuR4Bc7fAbXvdVs6WzBNEf4cjOaAS4XWQreBy/r7h63EcKbEWVBlI2/+j1NY2EiReKnJO4+kGpJOiMhzgmoY3VjrVfAkgkJDK95pJAB2QsVeOQl8Kgu4VwcEJAOOY3898r1phIP8pb9bXAuQ0tiwO9kh0YyZJzY5qg8ooDBb+AsE7Hf7oBKmlHQUajQkkMVIf7UqTQQAMVOp8mvZO1ShIvlTtmEFdHqxFV9RJw8xrKSVJEH6s4uL2JFHDkxc7xqM29Y9PLBP96WCwXbNZR8CjopsliBoQ8kWOeYTBLnx63bEZTzH0mFz5BiFxMRtTZhq/Lnqdp7N6YjH2Gea8QbAuWPqij1MT+NnmNt+eEnN1EraPZFmUThMxhx1OQia4lWNHKq9uRKgeyEr0wlY6hkPiz+HknF31AYAi73M6HNTwuLQ2pUsMjZ0w4dakJopEk7HhGiYDO9fHNEM3ieNwEyipMxvJY5sMs6t9mtEnIZyv2bNB8wLysgqlrbO3WUhyP6skV4QaFIIGEF0093Xk11QDl5sUtIvR0lkTHqdhZHtU6LaKkMaIjExaB3XbYIEbOpDF2cWrKzq2IkLIin/kG+7ajMiCxzFIgAQUL5Xbm49wMWstQYOlFhB7LTqdXukO1Mu2okuC1CEqnItXCGPM9xonnp8DD7RUo2ZjOw4Cu9V0CrUe+poLXYlgoxIwEDAOBgNVHQ8BAf8EBAMCB4AwDQYLYIZIAYb6a1AJAQoDgg1WABdVag2IIk4o8yrtDnejpJByJE7byNdbjZ3rAfY5pDPjO95y/TokbqRNONiDV4Uu1F5Zax5CDEFk8LO5uKHw3y62plQ0tmsBNsAQjU1QDGVSPQp9vWBLy2sTNBQypkh5f7YMxmly6RF7sb70PTnvclT44OWawM2DKosmDqRXcIacRePEXy0BucCLridnQWwGTUaY39knxyUYfD0KGdt5QDMW6UDvk6EO2cxzR5QKDrExST39Kb3+SJwr7Lf+BA4OIdHmB1fzzrN7om2pIX0JO/qBDn1oHYSFihDaWHFJ1zfuBfKzNOzO+/YluEa1FLsngJjij8XJc9fMf95enUifccyfeMveNqi8O1e+Ztr1GjDhGumP2qeDbgqrcKz8LIuDCFoq9Lz2JJUCn3kSTcR4SPdF7KgHIhh1pCZ994DjGVkhkfnPRs3+46Bf/6SKtSK/UaBzqW14jjUcCu+JeLp+rWqvvPWHDLnlSZpEKDmHIQZVpcQcLvcZyDYwCZEEI7l22WtZrgmBSNLHCQ5gHlBpCpGb49D82wjZbtTE1baz05cwlGMNve6oeIEadglZ6j/h1prXtBJ7shM6DqXUh298XgPrysIQVqfaPOYcO7/j6rZ660PIa6+sIiGT+Q2hG5cQua8PLF0Cqfe4lZykuglheg3K3+176uVDDgDmZtqH1a27MFwe8qTUBWgvPEeSenHxNrHxXmYEu41vhgqBIE1/CDUf2WTz6xRk1PHJ3rM49h/oROecPM78EcGTuTGpJRbYlh/+PybM04lfnG+bQOXcWEiSlM44+PSzij+zIx6m3qfjEzqQEWt1cVa+NyXt6p0+KBOGhfxHx2TohFsImDK/7jdsTz36u9LohniCv4cjSvoCQYivxb+PbdApxP3TL94XR916OkiQYgELmbKhhqT4pZ8PirWPVtl3juEW6HAXAW9HYOaT9kJ2+f78qCjNWvN80Pw1O4J6fY4V35Bfnx6UhdYsezYb9yujOY0oLnEUdMrJVXPxewj8o9LecR5Y/LFjttBCgBWwx0irSQOrs9XMZG73VtyrGZFP00rMRRAtn/4IH7Vnr2zjfPbJYpBvDIwshjjhykdI7COxr9f1cCe4sNDT4miAhZ2ah+knOoQs2tKIdK3hQD190b4LiMDbpCGM8y6Cby7/0A+fOVhzkTtN20ukAUxqbXw5XnInbzBkySbnQaZiEBj+j3JDAfG/RcEfzZe7yqGj9ZVegMASkMdscGD57v5i+YmZ8fEALseSqXzmfCe7bKrwaKbazFZHe0q3bLft6WExgSAVKFKdgpadjrFszIEt2Tp/KrWnf5sR9qg549rEpBgtDuALtdXbN+jhgrJ4/UuiqRUbjONUotMT9QvpQmkCdTcjuSdmbHyBSWKPDdAguRJ6t+5zvwDyqv3mr8w6mV/yJBJN/f6OTGQntxSuKmFA0gP3wQfo4R1ZXlr78KyoWNQXjR7iRlP1FuM/ElcEsG1wZf0kF9LKtey1ZJld8V9T+RoR3g1vRxxUi7UkDcLe2NqhEj2PnNfScafM2WYHZgif2s49d9aPkLPwktPfGnwwpY/3EsbdvmxPftW2A3e+QbIP7mJ1IodOiRsfcU4LsrHxwn+Xb5jwCywIOSOAymFrZR+p6vjV/I+c6NEhtaAzMou5F7+DAkjiKNqAK6owKklpOCEKW3gql4YxT4hI3xHHf7iHFgD/5iuF7leGmW3JNZnPwdyTeF+OvdLLFzESVtUHCM+XkqiwFGj80pgFF7xy6XI5FqupDPaMmqQvpaJv5o4uB8ejhn2u5yR5C++/GPBRrNjCPqNKz+yJzAmq//706qRxWKh+xl69xOcgfOJRXV6Lf41jkgZoR7wcU2t/Nsi8naiUWHbIimZr3rxbXojgORjSxQezGGfPEYm1T3scjBPkusnWrEbXa+3FqBUnEWWy8oai+73F1ddyaCqjnPryAC8X3nrfD251V6vR/4CDyub8i9sr9BueOy/TjBQ0B9gnuMpO9kzMl7NAaurXkWCBlTPHoLnYoekEAnzj3N0YVaZQyI4VcV4Q5MmNTi+WFNnF5JnOgIJ2S+mAA0PfXt9Q42V3emfeAMc1/EENMhipSqm7fk6tZui6jbuGL3L/owIkvMyj4ea+g/G7MYX0GBkoJ1gNVahQFsGay4fouotyIaqmvQgaFvM70yjJTgenj45BRUV5CEkES1PgewjT7Szup1uO03lLklYDw/hhy/iYZJJbQp1uTvfmdYSTtK5L332NHddLjLdUvY6JEWrhGIXwD1eROVdMVPVcpOIsiXMZ9/Xng1aXGkWlxNCKIQD84EuoFs8DLLehaXo/h6nBqsUZHSEpxdWEcv42NBYJraRAqJOlJy4lQnMwz68I4N4f9mXHyGWDguilTiic0X3pTUwyx5W/V2rZg34aN4Q1vYMUmOOAOAJcGlyWSCAD+5RIaQAiWFmiAKslPtC9wrwPuGlQt48UMN7+gdU2F+9tt4fLTpyjkmq7kbySOoRiwwzNDBnLTCAo2WxwmDj1nru2wKCNqryD3bOEQJ1GXvL0ulies7+ywTFAXkVeFFuul3nflNrJC5LjUPx6kNapjCgRQE+Qc6G1GGT315p8et0mGJ+QncwY3v9rAudQrsolSAb632X9zjEVj8bUlKgY5rZB8D8r7FWaM65kddEgcFrqjwhRcgNNXOMSftymM1+Y0D9ue4ls8YJP3+L7E7FYH7KTcgJ6tq1pm/mHOunHODsfQa7nm2sIUDZERUbiKQG9IQwnZSHVNEGesARfe/vZzj/fT2hmPw2waaLq21ekloxXjpm6hHwDLTK+CkgaQZ1IzXNrbk8JsJYTAUhCBMyOdM/Jup5V9rl2JDNwZleCvaHIVqs3GE67gtKSY6+eNojt4Cx9MsWygYx3yy0KC9SDKpqQlORo0LAuglIg3ye5snLzVjGrE69k3EU+lEEGtmaC06VP/YVTVlT6lNoHUF/XgQSu9N83QobyfBvtFMyDT2MC5fC+zz+6Ql1uvUj5xehjTO+KyB+RLemhjSyWYMHqaMnjszZYEDo2lG97tT72eiIIOG7ADv8u0re2PI3DWeuaWKNUlv1l3IKRfiAydEvU4cAexzoK0tawEjVVc9RasPA+0Li8mqiwzt9mod6DXO+Tjl8nds9Ps4FMZZgKWfuYohBEWvcdOnDSeyerDHqDGKk9LUnUZ4ZTBpGlPbQwH3qJd/JRkU3Y280tiXdSEpoLU/PvgZ5AJH9yqUBLCsfiGMegSj+zVA51KzmDVek5w090fmOcLLNSDjnyneBJMEd8opnSPmhIljTICNFO5aH0us9tPiR3xRRYSx+FdqiYDJpbgyCIwXk3zDVHdWJrNMUV6R/YBES2ZpwDzFNAvzgzmRWpjUVMApmCOEowbGTKGlDK6QJRichodf4xOaheLExESrpkFanTMDooNblJBP4ib9/emCN6kOaUFDqp5GqmGv6SUG6dafLGUMoVlWqrirtXbJ+XeqfRSUQtBRTLMdbWNX7GRZJS61Qk77OnaLF7ZqdvqwskiEd+iyhcPG0gWLGM//IksLmNpuBhJ5KByBTzCRcivDnVAWRzm0hdu3wVqKtO+LorPz7V2bEt4kzx20io7hwF9CEfW5zJwWHHQmUVhguqEjAsYgNq5YX6BlcQin35jo0Dg4aj2B7scJn81Xn8fEnS/Z+zo/HOCn/3Utp3eoRed8eOFckxKTUt4K7B9dL01dG1E4OGJ+niNHVTo5mO9PQGyD7ToHRrPJYZzYAb7WHkNRrGiY/7EnXrHwrvKQIEaDQm6kU/hDq3KV2yXVR61FQ5nG6D9RqeiJOOK0AAkdnHmblBwFuLfC0wjuUqXXsBjiLmnKZImDrB2FOJrbu/Toaz7QAEwj5dvdVgef8Xcf3STWhKWQ8x7o05en7h/atJkOMuiqaBFK3HQowdsJ8Ngah9n6yvXpccChkhFKgMGkv3lPZpx9oLWLNvwkhisCXaaLHqU/gGB6uWz8wUxbsyCLsxdEVmMtREh7UE1kOLD9jwLzDxWgcehSBDpvwLXTSYFU0M8AABUPjC33gBZJXlNsxFJPAkgH82guRA6Kzedj+MzktLLmifVtdauOW5IAVN6XGdKN2ceFsQVVPXMhBkMrzDTIfNkvZXicPeWrS96iBDUKQIWIg+B2uMbtgQzBBAHaC1tdsGli79iNUgpThih/pf9sI2cGK5xTRqOhWvH8QoVLFbF6B0J4D1Ymxm8H5FJp9aMxzyofxiFPE0XWke5acgJr+F6M+AFPAjCpSMsr0KaHlgWmZ+uSsf2f25Z0LuDlAyVy+3ATjELnf/1fRbwbT+94OEVL+2dziAfuwshgd7k/miJcnNFx9PpWL9mmrDdZG6IGKufrJWt3wYLDTX5MAXIyhFTlNkbm+W0CCF1PwOGURcg5CYowQLDSaQzPn8/xpbfpqiu8T/n8DE1uEAAAAAAAAAAAAACw8XICgtMEYCIQCpfWCzk+R9J0Koj+o9imvXFwd3hIu3DjBuB1aAcmwG5gIhAJtcm/LWla/4PUwbdrAesWViHIzswhI+RH2KiyoHGZHX", + "gWACAjdWNkSmcD5yjooq+3dVpk8BAOWBygOkrjYMPHkweAIBAQQgYwQb9T+9zN4WDYdIHCsQ8QBMBJYLbZx3vLrE0I9nJkKgCwYJKyQDAwIIAQEHoUQDQgAEFC+V25uPcDFrLUGDpRYQey06nV7pDtTLtqJLgtQhKpyLVwhjzPcaJ56fAw+0VKNmYzsOArvVdAq1HvqaC12JYA==", + "MIGvAgEAMA0GC2CGSAGG+mtQCQEKBIGagWACAjdWNkSmcD5yjooq+3dVpk8BAOWBygOkrjYMPHkweAIBAQQgYwQb9T+9zN4WDYdIHCsQ8QBMBJYLbZx3vLrE0I9nJkKgCwYJKyQDAwIIAQEHoUQDQgAEFC+V25uPcDFrLUGDpRYQey06nV7pDtTLtqJLgtQhKpyLVwhjzPcaJ56fAw+0VKNmYzsOArvVdAq1HvqaC12JYA==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "68Znq3SPyXMT1o+OPEmc6wAnuWXPskOhI4EjqTKdC+Fea+Ci1EEc/CRkIOFXh2r0lYv/NWhZEwx7tkBL5w5FNTQlMSJJnXPII0G7QaFoLLr9Bf7BFZ2T/zkJqF0cgIjOINzUyHXqZeP2cqLq4qCoTlZzohWee3vEzUdjh+kBBu0I+NlSFYmBBj3/wlaCaQUPqVbzTQP2f7LB96M0q3DgkVC5Do59eHNXFxMdDuuBjeOW/jyBhsq5hyMB1vS2DBtef6t1kb/VLE9ZKOjkeq9WtwejTGxsh2NxTeMwydQv7ekfg48rLXY9so3uhz14r8YrWdiAZlCCLe810Mwtr/c8RU0xfJjsYQI0THlUKKP+bMpBsxmO7ulz2y8H/HMWd29QJD5lV5ogS4IH2nt/96wYdbmwhOfOwYXo1YrBy7WrHUBKzHcZeV1QlnVk+ZBAmyRNhqD2HCtwK81rJ2tWEAvXZq1zYbVdpZeseoT/4/U6RNw8x+fmBid11v4km64UC2bkIIIn3+VWTN9Tn1Z+qevjlvipgCdSH5JUy/kYZr0M46S2OYq5xjBr4KgZZL0A6FzpwActziqfEU10xTSiUNtIPFmDvn3hwxnb4jUr/OMzMJB7kS1u2r7qkOiBHR8eGgU+INHp+tf7GefkSBegn1P9GrxGf+nzfD2pJKvNgcbF/9mdj0YFuyutNUgwdKOQyD4JPgq0M4lvTXag4gf1vOrbreslA59+AquxB97NDtR8WbZkwWJ6e/Wv68ZNyJHIRTHqjzc9Fq1/wjXKt+L12blp8phq84L8PUv74LIKwo91g5oihnVvb7DZa7RHY466+LKjGkc4vcDMwJsVZueCTdQ55ZhNeKAKIqS+obS6K61ZvuQvQ0wvgbK2zekp8B4y/9Y5diqnTvsv5lym9ReHh+85z/22hXvtP6V1rStesxWV7duNAuBt2VIzYspdh9ivktp56+k4/4YZGq/QhzjOArrOU6jG8FSQfkOWHlro+i+St7YiZ7/APV+ehkU/IXHTbFLK49cgwGLz2eswMmtkO6ZMewuYCzHTXrvEcFMT+KauYfz0lktz0PFVMld6/mC0a4hwDsqdCkW1YJgVA3lP7MUtsyfGQ/Tx+nMVfSerd5cjUELXeWKlPhy+8a7GrfsGkqQ6FR88ru1e+mQ9k0+VQFpffAiYR5UBuTPDYhEOKDRTJERXSy/pNfaJ6fDJkwqCcJE/asfeziVZ2erfNMQBUF8Kt66G+9al8+f1jrCXosKVQQH1wSLJW0O8SbZiBrrqM6Tbcmub7MgQqyG2z77dqioJW+WdzGM7i6RWp4kfIAEbJP/tYEZRBA2a8p2SSGLP+cqG0VAe7pO0ynv478sZSXcyKHrTAI1GFUrmwtFudGhmc9vQABBemEMhG8wESMhvFCeznRRFkxKuCAhFZeynaKp+EF921kVglSgqeW6BUGa+hCSUP0FQLreYzDr6t21esRwXEh7cS28VzoCsS914Mg43JQI8pKlNf98cNzyIch2t6wKEPtp/JQ8bedgsyabyAQLQ7BJ95lF4oYrWReLg5tmjzKv/n+gv7JeeKfg+C/Bun+BbTF8kyV+n7+XolL/ajGPlQTCgzmruvKI/YPh0vBQwOQ7yhp6Pr5dxU4n0zglcv3gBW5Asmd/OhtoSyHy2KuJDS5v/Ot1Dhm8WDW2FPbs/CJmKze53SJEgiKDEMXGvqL7gT/BJPqKSDKdGcsRAukJRSRAxg176hICeNWW6ER/KicmNdNOS6XEPZKGwofVgBh3XcGNY4kRNNFUJrUqiZHlityaHYGRqmKyK+CPytsjsgkeJ1VFImOBlZ5yINOQovArH4YGKBm2fgN7S0/NGM1XEBp7/502fnX/qLucVLXYLljeMW2qtFysVbw2Yuv40fgIDtYNWJ7eCSYk7K5eMhdgrQmhrYEa2QGpLMknnAk3S1WT8IVcNMPAFn8JzmV+ujgwmh9a9negUP5m7sBNYOD3anBIICwFYEArumSABTocvZ+JpmFsIxiMho8xzWiLw7caaaoKOkT0RiyZw5tLPLXnK03XKjNfpUrTUEzFe8f+rDeCPHkZhQ3ycFQaOjKlJjRixriJWMUFRA8vsvd7GndumWgySc0XiDsr29kKJvfaUkSREWBuBFXcbMCHcL2iyaLHemrACf3d0IqyZAPrs/FlR787L1lX6uGgVVLa9aDbaOPjn8lhGbjifPr/L7POuqFGbZtHygUpGGWQCbT61X5oYLqx8BMx+hGaTCPBPn8IyOsi1Tt5eWy6OZedNKaD8hIYhay7r1AwjoLFyJ9KRMFuSsjTKTLIqHa5khfkJ0QjtJ3cA6pT/e9eK/5xQKEeu7r6pIA8SNeYxVUocIE4Uu8sIwTzOX8mBuAb/LQqSu3OFaP8gQ0k1abIQVQeDcw2lGV/JNnXu20vpuntWS3Xy6oiGNkbeWqzgaFI0k6z9ZlwcmAjHqkD927do34WtK5CKwBFkMw1fTdVDgOw9mXoK7rmkqcWuxCIimjLvXDnVCUyxz00AKl/KB+T46dby4Ur9mvx80G2cDUSVz+pghgMyqwoBgJOvXnS+nrI4kYaChlHFB7tL/uTz+kKTcIBjW0Pp1+xOMIo6IHxE4Ma1rXVR3Ft0WB35kRkiT2wt1IrzYwbSF6W9+TblyhEkDPxvWmfKU4zQ2Qo9duZ2u5ImNmr4vKrVJEuHUqI7J3VbKPjHKOb2JYKkFhEgf5ftgVU/x8/kZOkmJsSFUWHtLRQmd7QAmqQ0rxFjv49nyep+LerhGqApY73KCn8sUj3/Ne26+oGXbRj8K/8hgAlhsB9heYR4mP8im3y5ll8fet9A0cK7aIWTyoLvOcp1PdYVSMLppsyZ2GAzMpj+g4Zb022IkfeU7F1sahy57UsUrXYfMMamzybHAHJzT16OpqO0O8mzRXi7xBtVOd1uufySE5/2gOag/6kTHo2aph89jHfcPB5SMccIjjB1AqLnxh6ex4gXb4vcZIK4CNZtYMmbxTR9LDm4qP/YBdSS0SgJEvbRhrQBCUFahWbaYOdQNulMrLLco65Htd4bl4wq8svbFBZFbEu9dnlvrHUpSCDsWEWg3wC28ckSs1BD4PEYMO0inhZTE6P+Elzj2dPamTAmV0M42Sb13MDAZdyv2GX6vRLd/yWiF1bZO19wS5nTlyEKeTaWUP5FIkbbP2XAJ9AlBE+Ljcoj5yABCK9BdPCexaYdoAMaSOnlztl3hYe8/+zPngd6PnzoUN2BSfrCIuA6cd6gLVwZwOjaD7DiTimIsbcbzv+zJ1N+z3vd9mi17WaUXlNX7+A5j+iO0057/2EoY/XsjERNKiQGRzRTQ9WhckM6v+7L6TAVflXPhSMzpxpIT3bDI1KOkxiX73MRcQwQuQj4S1iv2Y4m8rHMUe9//h7bka4KkYhLno2MbakTMRtuVTE8ZeNEOadvn4TcCXWuYzZI2dMjirmEWA5j9qoINYNv9heeFBhKi54WnIB/UmRtqDZrS6v8Z5k8V2/mkqKn42AGxa2fn6bNvGsVwWBzC2UkPVDaqvYsP2tH4Vev93Prk2DL7Stuf9U1W0t09X6AEKwvb9naevRzTudtTlQ76FGvn4hz1tkkLOTfNF1QaAFG4mvK8OyS9yzCgz41rhlgLRJv66yHgwljanQLRaokniPIbGbmxJvULt5EyNdyj7Un33QHMxh7VsZuoOekoAngdckGgHD6M69FEEiCWmWpOjkQGacUbOBu+naoKM8hyfi3GSRMcj5pg+v+YURYHJOtai10QLVjwGbohYuP4i0Ltv4ICHZZIUdm5gczkiQK0Arno36/Lcu5A7vsBPywFPkFxGf0vgDCzXPtSbHub/KAVTC7ROlu+7q34ZPMrxzj5KShick7B2SF+qmwiu9X36i++kt/WUb2Z9NKscU8nY8ehWeetq2zlZspGsRGV2E/wXEpNZRrFNbmJVg22LiP0IS/Av3urhRMqxE3p6FoKHMejSmfO9OjWQM2hiLhUAjCYcPl/EoOurscRiq95uRC03fthEp3hb0oqm52+ErAw4LxZ8csaSqxLiRDpoYqFgF/uvvu8T95P4X0oJu1wIQ1A1PXDlks3FudR3RZQFaRvrX7PsKlhbS7P/TcfnY1Ce+uIIZziNTf25YHu8aYCIdp2PVj28iopjuy+O/GOfC/l7cNUUgH2GpRDZoQYdFM/4Ie+poxNZIvow93Pqy4OMU05xiXG3cw+1w1U7VGZNt34SmaFvfYfSPyPg7+5HsZjMd9SyJDCfnG6dtBl3NwYLV+r7+liQQojJkvL/o0+OLf4PBK/SxFKOxyyWiFjI+NuuDzra18s63fxpDsbmgg3+95clljxvW4Wis2tS3HgvJWttKS4LYfpTPKKhC+uik5ZLe5vsTd5fBGXmV5fqvD1TxScH+ys8HpIFl8gZ6j6etcdr7g5wYyPp2yAAAAAAAAAAAAAAAKEhoiJywwRAIgUZ9UG0E6AJxZra8fGgara3nzRuwM9FeBg4UG6w1MTpYCIHYyAqEVRM62qL2lnmFZo/vtXss0jax+xQ4KVLjzWnEB"), + new("id-MLDSA65-Ed25519-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithEd25519, + "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"), + new("id-MLDSA87-ECDSA-P384-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, + "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"), + new("id-MLDSA87-ECDSA-brainpoolP384r1-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, + "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"), + new("id-MLDSA87-Ed448-SHAKE256", + CompositeMLDsaAlgorithm.MLDsa87WithEd448, + "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"), + new("id-MLDSA87-RSA3072-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, + "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"), + new("id-MLDSA87-RSA4096-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, + "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"), + new("id-MLDSA87-ECDSA-P521-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, + "ondI5qKMczlFOkLTV6jv0cyl4sU9MTRvF27z3kAkyfKeqvEvKKg2WAV0Jzf9tdhYz6Tb0N6FPFuoRz9VwmA4pu4ApsqDooG2KTRd17YnErx61i/e+M7oSUSwwTRs9Z6gWSYqEeuasdbAycInW8kpkY4ptQ+z3hBTJ8oxuZuZM/EgtPsib5k/FuQlzLeDI1G6KygsrrgDzwXiWqV/okJdnywGWk/rPa6Cj908/t1ATjnnjNAH1rR21pgVe7G2rBxAcYCsfLdaxq8iHiU5PUddbHg+0OQXjct8i/8UMsSjELepgxn3XmR/lsxPq5Iolap5Dr1kF9waTxzWuqaw94gK2Zt1O6mF++SaPXw/qzsYNe/3WbsH+QhNNIFgetd8zvVFmI//BC2udxNu/AoVTjK88fbnpo/kAvJB/ZM3SBojyqqz3Z16EiegR+5qVG78buRH+mJjV43om5RlrFIvjCSQeSjEHPapUNvhkUP7OBg9/fqxD+uYyZJgVndcnVQ9sd6IazUOmOiRcuP0ByKewm/AcLsM4VOTg6GAcQWI/oCdxEN+egYNzkOfc+96HZPRW9QRhMqvgPAipPJBp+vbqwqraflVLivynznnGHnPauXQBrWnbaiIq3bxuoOCt9D8xelFCfqXsvIqvWnxCrGsmCbQltlYzT2i3pVSM2sw5MUUprEkLS8IXvNkO3YEscg/9YKJ8WV5VoaaqNjisY8o7Uk1ROuGQZUwQg2LS3ab1u0X33fbWJD0CZhMi67S6RCw4VRnYTXpRuR40bUDBzUtBrGhSLujNaWKT3X0dpH2o32o8m3KLakfmYtVUM6aHpw5OcAs/vz8buX1e+SEo93fzsZqgo2Gw7/OLu0wdtRH5gZw7SZHKYqmW3oF0L6kvGKQlliDhtZ96oyHaAtMlnRPJrS8X2087yZyxWs8At9VomrrvYr1XlNTY4QrfBMqzqKXIAM6mZKDZtdL65kUuw54C8fpfjjfFE8m2ZWtVSptquvvuTAaYwtUNAhSmHdSoNVG5u0NcKk1RWtpWt68IXIhKkCxyU8nIQUREtw4bLE9kYBUYRr6SipADhPpZVjjZ4IjlRK8y/IdHCGCINTgZwxhRBPqCzruBFMYDjs7q02KAXJpjW99SuNWVfwTIXqpkXsCyjpQC5LaVfWpNZcWkq6ujmKSpGB4vkn+9OAquvnJDIcW0uV3yKvKrZ+4MxTPgmTiQh17x6q6FMjwonWpw5xTL2m0zoMVYqYw4I4AQHeBZn3rPyY7ZN5pSVRjh3uIHAvJbXw3yX+rc+7LRYJaNbvxq0QWnUuXJvxxmauivds5pBi0G8vWPC9k3irL0jaWkrAHd44zneSMkAET+88WPH8hUJb5G/LL/ql3WBb/MuCX8+BnRYrrS0CenYWiBaEKIIjkBVD3zscZawCb5pCK8aL0PBHQzOkNWffHNlauQji8HiMn58t+IWAYT6r3qZR+aYvsbyVH/E15UQeF7fpRU47sodogJUTY3XmL4UbEvNc3M9BLgVtHhjRc8K3izP9PKxHd3uvdmwgUNIv+Sskt1GH4kG4d4IqngEGE/iELUMrZRqzpLMiaj9qgtgoxjRSgEmM03lpDMN1Vn1/CoRkpvjuOkGZpaRHiUH+99UARr7jy5VjS5hV86KemRoSCbuav7T7x5P0TBXESXa1oeD/K8K1yIZmsLXynlaglo+c8pVE05jfZaQzAyp6Rft2iPK208PKiqFvo5sAZQgcWZBWZdXzuHrLC5D8cCXEpItujMh6wKG0ui6mSmu65+hcN39lqREadVUtvwsrvtU8Llj30R6aQ6TCOphQEAEOaXM/ZnGNjdxZKeMjTgFu3/Ye5DSFQ7dNR+YIbDTNjJnf/JDS0GKiIqh5mQKnymJQ7tVXFaEUbVnJ38UpamCm0zKwOpuoz8+cJ/OPLTd9v+6G2/HiASmgvmfJdh7WE7QMNQS+0FVvgGrZAb7KNSEU5T/qaXGJp6p85+CIyeRE6dvRQpczecQPNTe+8T4nsrh+qZg6U/wG2BGN3UQf753xpHU8bywBztCbhVMbMVneo97SZV5Ln9QKhIJhwe/Xq0zILFS/fK1O2kTJlVO/NET06osji7/G2z+DYR0lr7Xtlvh8AwITS0iZ/+9NAG/I2tg+ONYTZhQeqd73vhv5bsL6ZY4P63rJN0EqtdMN3qemOwwR4G7n/wKPoJO7N997NMM5V7msIjuT6raAet5ud2y/GBPVPloBv+cvZFuNRE9UDDP496Zp2BXom4MqcW2b/TLvhHAmSEpn0Jc0jalu7HmPW5YH+Wm5jZRRoKOXqEFgtPGiXCzJSOvp5kU9aNYIuG3YCFZBjCps5Efkn7Rm43Cvp1X6LEE7fAgQ8SwWfexAYKQd7jNhyhBbQgJlskIoKl1gsj8ylMZ8pZnQhKXOPXW+nQCenHZhvdZddtJUNBEfmqYENlOyzkTeiqlahi368eI/LZtPdgZE+vS4G+RiQbukZPTPdpNn0wvrYLr9gVZx27UASWwN8s9sZO5KVXFzrRSgmPJv04ousMVLAFvpUucsBjCF9tSaOMSUrK4eltCHG6TiLzztE0Ry0DO4zRZM+Kp/JoE8ULvXnz2i9bVTh0nJMYasJe+mAtlF1CL8ULFb256AVCRL/2G46pGp9913QAJgwd5v0s4/5psb3SM6kEFOcUVH8UI/iUobGiNhIpB7BJJdsY84OmNog5DVyTyZlG3GnrjxmKqxCNp00BTtgSPgHqyYYlL+gbU7joGY9+MpROspfpXzItAZTZhGJ9U9M1jGZ6TuDrvyJaqp+VTeRbkw9hD52mRgsdVK44CAPsvCswAT7gV+UH+DSpi6LqHFhHPdMZd/1LKUkWfzLSi2x8qKijmgmR7ZYT4+Y5Bt3zLGCy9zSZj3T7Ym2FWUbq5/98wiD4Y1ETLIRbPVLJZ5Ozz55fnibLecyzMBXTJQDcaiKSNLP0kxasEZ9KgFjEb0654imEbfL4fvuiffjOCD7/O/YsdPIM+TzeaQrmoCcocgcSFfxVCSoeicJMFOEgxsN9pEmd+6Lc2RDzzWU0iYhbE5HljOMMUWhXN5/oHTjUZx8SWoyHF3tMZY1NsHGjh/O+b4jUT0gny5iHfftgSUS9NORILLHvkd/1JCouw6pp3ysA8rCNt+FmrLNKA3Bcpthd/5pN5mVx5d24AQtlVJ6/jdggKe0rAcqxUOuZBHyJ7dtL1NAIAAzNdWPB3TpL5t+n6wGOTaH0mF8AXd6+7Ysk8v7eOHceBPMPX59n8HPgQTX7drCjBLYUb/pDbWEvgygjoo1Dppy7sOC3Vh82JNmsVd5WIgiVNfL10kl5s8jTnCLbgUB3pLBBnOAtmkC7lqOclTAsQTt9uLq9jDhdtXkp6tDZ99UWshHCMtc4W/Yi5T45CA8ySMUlWVLpEpnD+ITFt4pfrjtr4A1Jmat2gri3uFtM9r4s5AnlPRxgO1eBAGzKkSTa/OjXKmlCebxkPAialHumUsqeX2jGHs+zyoOMvpBQDhtd3XgA6tAWjYkWcHUsyrI1QhbIVPBApe82BfXAAEjksDIKWv5JfrVbdZBOJD/X2g39Z2TPvm1X+H4KJZLjPlCkJE1gCxA6DvXF5Bv8+GuDMB8mYCz1/peFkxaxdpbzQ==", + "MIIegDCCC6ugAwIBAgIUJVm1nNojyECsLTq1yEgODui/LqcwDQYLYIZIAYb6a1AJAREwRjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJTAjBgNVBAMMHGlkLU1MRFNBODctRUNEU0EtUDUyMS1TSEE1MTIwHhcNMjUwNzA1MDczMjE2WhcNMzUwNzA2MDczMjE2WjBGMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzElMCMGA1UEAwwcaWQtTUxEU0E4Ny1FQ0RTQS1QNTIxLVNIQTUxMjCCCrkwDQYLYIZIAYb6a1AJAREDggqmAKJ3SOaijHM5RTpC01eo79HMpeLFPTE0bxdu895AJMnynqrxLyioNlgFdCc3/bXYWM+k29DehTxbqEc/VcJgOKbuAKbKg6KBtik0Xde2JxK8etYv3vjO6ElEsME0bPWeoFkmKhHrmrHWwMnCJ1vJKZGOKbUPs94QUyfKMbmbmTPxILT7Im+ZPxbkJcy3gyNRuisoLK64A88F4lqlf6JCXZ8sBlpP6z2ugo/dPP7dQE4554zQB9a0dtaYFXuxtqwcQHGArHy3WsavIh4lOT1HXWx4PtDkF43LfIv/FDLEoxC3qYMZ915kf5bMT6uSKJWqeQ69ZBfcGk8c1rqmsPeICtmbdTuphfvkmj18P6s7GDXv91m7B/kITTSBYHrXfM71RZiP/wQtrncTbvwKFU4yvPH256aP5ALyQf2TN0gaI8qqs92dehInoEfualRu/G7kR/piY1eN6JuUZaxSL4wkkHkoxBz2qVDb4ZFD+zgYPf36sQ/rmMmSYFZ3XJ1UPbHeiGs1DpjokXLj9AcinsJvwHC7DOFTk4OhgHEFiP6AncRDfnoGDc5Dn3Pveh2T0VvUEYTKr4DwIqTyQafr26sKq2n5VS4r8p855xh5z2rl0Aa1p22oiKt28bqDgrfQ/MXpRQn6l7LyKr1p8QqxrJgm0JbZWM09ot6VUjNrMOTFFKaxJC0vCF7zZDt2BLHIP/WCifFleVaGmqjY4rGPKO1JNUTrhkGVMEINi0t2m9btF99321iQ9AmYTIuu0ukQsOFUZ2E16UbkeNG1Awc1LQaxoUi7ozWlik919HaR9qN9qPJtyi2pH5mLVVDOmh6cOTnALP78/G7l9XvkhKPd387GaoKNhsO/zi7tMHbUR+YGcO0mRymKplt6BdC+pLxikJZYg4bWfeqMh2gLTJZ0Tya0vF9tPO8mcsVrPALfVaJq672K9V5TU2OEK3wTKs6ilyADOpmSg2bXS+uZFLsOeAvH6X443xRPJtmVrVUqbarr77kwGmMLVDQIUph3UqDVRubtDXCpNUVraVrevCFyISpAsclPJyEFERLcOGyxPZGAVGEa+koqQA4T6WVY42eCI5USvMvyHRwhgiDU4GcMYUQT6gs67gRTGA47O6tNigFyaY1vfUrjVlX8EyF6qZF7Aso6UAuS2lX1qTWXFpKuro5ikqRgeL5J/vTgKrr5yQyHFtLld8iryq2fuDMUz4Jk4kIde8equhTI8KJ1qcOcUy9ptM6DFWKmMOCOAEB3gWZ96z8mO2TeaUlUY4d7iBwLyW18N8l/q3Puy0WCWjW78atEFp1Llyb8cZmror3bOaQYtBvL1jwvZN4qy9I2lpKwB3eOM53kjJABE/vPFjx/IVCW+Rvyy/6pd1gW/zLgl/PgZ0WK60tAnp2FogWhCiCI5AVQ987HGWsAm+aQivGi9DwR0MzpDVn3xzZWrkI4vB4jJ+fLfiFgGE+q96mUfmmL7G8lR/xNeVEHhe36UVOO7KHaICVE2N15i+FGxLzXNzPQS4FbR4Y0XPCt4sz/TysR3d7r3ZsIFDSL/krJLdRh+JBuHeCKp4BBhP4hC1DK2Uas6SzImo/aoLYKMY0UoBJjNN5aQzDdVZ9fwqEZKb47jpBmaWkR4lB/vfVAEa+48uVY0uYVfOinpkaEgm7mr+0+8eT9EwVxEl2taHg/yvCtciGZrC18p5WoJaPnPKVRNOY32WkMwMqekX7dojyttPDyoqhb6ObAGUIHFmQVmXV87h6ywuQ/HAlxKSLbozIesChtLoupkpruufoXDd/ZakRGnVVLb8LK77VPC5Y99EemkOkwjqYUBABDmlzP2ZxjY3cWSnjI04Bbt/2HuQ0hUO3TUfmCGw0zYyZ3/yQ0tBioiKoeZkCp8piUO7VVxWhFG1Zyd/FKWpgptMysDqbqM/PnCfzjy03fb/uhtvx4gEpoL5nyXYe1hO0DDUEvtBVb4Bq2QG+yjUhFOU/6mlxiaeqfOfgiMnkROnb0UKXM3nEDzU3vvE+J7K4fqmYOlP8BtgRjd1EH++d8aR1PG8sAc7Qm4VTGzFZ3qPe0mVeS5/UCoSCYcHv16tMyCxUv3ytTtpEyZVTvzRE9OqLI4u/xts/g2EdJa+17Zb4fAMCE0tImf/vTQBvyNrYPjjWE2YUHqne974b+W7C+mWOD+t6yTdBKrXTDd6npjsMEeBu5/8Cj6CTuzffezTDOVe5rCI7k+q2gHrebndsvxgT1T5aAb/nL2RbjURPVAwz+PemadgV6JuDKnFtm/0y74RwJkhKZ9CXNI2pbux5j1uWB/lpuY2UUaCjl6hBYLTxolwsyUjr6eZFPWjWCLht2AhWQYwqbORH5J+0ZuNwr6dV+ixBO3wIEPEsFn3sQGCkHe4zYcoQW0ICZbJCKCpdYLI/MpTGfKWZ0ISlzj11vp0Anpx2Yb3WXXbSVDQRH5qmBDZTss5E3oqpWoYt+vHiPy2bT3YGRPr0uBvkYkG7pGT0z3aTZ9ML62C6/YFWcdu1AElsDfLPbGTuSlVxc60UoJjyb9OKLrDFSwBb6VLnLAYwhfbUmjjElKyuHpbQhxuk4i887RNEctAzuM0WTPiqfyaBPFC71589ovW1U4dJyTGGrCXvpgLZRdQi/FCxW9uegFQkS/9huOqRqffdd0ACYMHeb9LOP+abG90jOpBBTnFFR/FCP4lKGxojYSKQewSSXbGPODpjaIOQ1ck8mZRtxp648ZiqsQjadNAU7YEj4B6smGJS/oG1O46BmPfjKUTrKX6V8yLQGU2YRifVPTNYxmek7g678iWqqflU3kW5MPYQ+dpkYLHVSuOAgD7LwrMAE+4FflB/g0qYui6hxYRz3TGXf9SylJFn8y0otsfKioo5oJke2WE+PmOQbd8yxgsvc0mY90+2JthVlG6uf/fMIg+GNREyyEWz1SyWeTs8+eX54my3nMszAV0yUA3GoikjSz9JMWrBGfSoBYxG9OueIphG3y+H77on34zgg+/zv2LHTyDPk83mkK5qAnKHIHEhX8VQkqHonCTBThIMbDfaRJnfui3NkQ881lNImIWxOR5YzjDFFoVzef6B041GcfElqMhxd7TGWNTbBxo4fzvm+I1E9IJ8uYh337YElEvTTkSCyx75Hf9SQqLsOqad8rAPKwjbfhZqyzSgNwXKbYXf+aTeZlceXduAELZVSev43YICntKwHKsVDrmQR8ie3bS9TQCAAMzXVjwd06S+bfp+sBjk2h9JhfAF3evu2LJPL+3jh3HgTzD1+fZ/Bz4EE1+3awowS2FG/6Q21hL4MoI6KNQ6acu7Dgt1YfNiTZrFXeViIIlTXy9dJJebPI05wi24FAd6SwQZzgLZpAu5ajnJUwLEE7fbi6vYw4XbV5KerQ2ffVFrIRwjLXOFv2IuU+OQgPMkjFJVlS6RKZw/iExbeKX647a+ANSZmrdoK4t7hbTPa+LOQJ5T0cYDtXgQBsypEk2vzo1yppQnm8ZDwImpR7plLKnl9oxh7Ps8qDjL6QUA4bXd14AOrQFo2JFnB1LMqyNUIWyFTwQKXvNgX1wABI5LAyClr+SX61W3WQTiQ/19oN/Wdkz75tV/h+CiWS4z5QpCRNYAsQOg71xeQb/PhrgzAfJmAs9f6XhZMWsXaW82jEjAQMA4GA1UdDwEB/wQEAwIHgDANBgtghkgBhvprUAkBEQOCEr4AHoEPJHUdSNmKGNjCxm1NkixA+ICtWDUt9oKzrlci0MhE+4OehL0ODx1Pju50Q+eBAgonzpYfmQRtg0Zg/Bdh//irj3wTebK6E7SETqAopInRGxp0w+FmJpLMN7KYVPyj+5kNEbs/5IoVwfBJhUth8SH4zSdyfePH9Ml7dNr970nKyKPswmejy26k0CkuTMxJw37pJ2BrmDHu/AxDlMls6my7W/P3LctYuX9TiCcw/J7DvssBjwnhSH/IQ0x6ee7ZflBjMSNmLAmu/q+kIQONwyJo+ICJPpXN8Ast2UILgJIDTMqo23hreGNbM5MH/TPqXn8ff9xv2VZimfm7XiYj8Zkfs2dObiWi71wXhwfzOusFMp7cajOQbDjREYKaocoNEAbXlE8d1JBt242Q1d9mN5tvoY99wEJ0d8/7QWtK+XRzbZ+fidE+D+RXgBWELNGyD7Yj/KPl63wpPWmZdcl8sz2sovmPSi3lpy4T8wktJRAnvkS1zOLRQfIxVCo2EK1hZOMNI8V/NNLp+fz4YNpJIKRRGfuncUHqVKsG7asfXt+mQzilCx5hyrZkOoVf2kaAt75I8xe8m3xn5pvqiPzSXTPej+f/dw+i10Fi1h52DcHgbnyVHhCL0AV74Hrfiktlxup0rfmEODXqxjskLM7raavt/bVpZdMAoRKqidLXHUkmjInwlMWfnyIrfbIiRJ0CUfXrPLdd/TPrhyKcr3WvYIU9mlKk2xey3ONmq+SfKzqRBD1/xZe9fVg9K7JsM6DfEXAdEVlW/px3ad8gidVH0FVmHPGL6qR+SXY/vg+FWaPBlDXOzrL43Guj8pgtMYr7xCJGoijRe3tnVbKtKS/+9xbjr7peuxrZfULKGFpcKeJIv4D7950QQhATSZTp2A0ZB30jUUfs+QO68uoauIcEy/Iivk8S5vF2uqc4vSI4L2C40SfnBx4hNH7JOZz0ZV/39G91KuVlpFYPdUE2eW7Su0LYB+9Q4JQTLLutqsXfmC73O8QDTb2/Z2GXDe/2n1cSAQeRlG+0llSICXU7hwPg9C0LonqTVvG6rGQMk+acGp40XwT701zCj7PsUxwwdWFfr4RtbxBa0feJuSTnelysuPmDAWW6Dq7CtjBl1Y0unhwF9SGE7IKjEoccv2HHyqUA5Liz3nFK1mAa5ZC+lx43hrEBuFMA5ydTUfCti4UvAQKgFtxcMLVMtw09K5UldZS+ImlDDPSHjDsULg1AoQWNCCXsXYlO2dcgiGQkMvMcuIr7QN0M0GzZFeW1vK4YNbcQQEbu3FNkW3CnASjhxzton/GidN2bb7Gpd7RY7Fbe8X86iEIAUgjLvdXEn/amdS+PrG3gmE0vJ38uPGuggmmM00Bdpqq3zz3tethEgJr+HzvtaXdxVX2RqtXU2XijDty4Q6C8cPVQLG0EPVj+XooOgirfsQnEPBkBrwvRWbLFld4ZRBOVwsj+MobKps4W3Ci6H9rOqfVbyRo0P8iKnpCURdxEYrL3w234BBunQCk9kHIRQtswQlabtJABMBney/P7ykGpEF1O+zL80StHu0hS4aApSkxIAtlS+ZhKs6PSzNTBeBxELoi0kEEiwkDe9iG2yV3D1is9MdX1L7PN+bkC3Ip3h9IYqgIb+89AmDtW7vu2tP7ryJNMca4mnDCmHAFHBxPJgBnp81p69q1yrQ+pJW6rAFhh4Jcl0vSWIdPOurvLBTtvOyjTOb5wOfzPweecJgYGiFUgYsDQkdfG0KJudjNRsjSw8MW92su76J3q1KipzSXO+YxN5sVlfIdjovelGAGOZAQIgLYTdaOxEDKrlTLKMgUf8OsggdaoAI88weYeNf/WuxWgo+lfSwL8KTmy7+csNSZob7p6ISNwhvdMvVzdEIqwUR0tTlTZgfvdYBWdFs4NJEm5TpRtOZAtP0RUBYer51nRiDfuhjcXcXErLiKJs0x8TNdZ/Vjj+sV/o5Gn24vBHhPG9c3k/xv7q7Ddlo83HIPA01fJHWiFacfCYviNYEDIYKpIp3m3IYrbulIcdSyU29O28HL8hcunhEPZ4Iluo6SUj+A5Jqqa6icnK6ycGUVNwuf2oXlzRUCytHSwITnYm3p37TdbuojjkzCQ2Mz+Brx8XGzY6AkGfyhI7u0TDc16Ax/i4JGy/1/jMcahw6s4AU0WbBUmZY6TdzQ3CVkbL/KwNiKm79RcoQ7ex8wsuLti97MR0ewtWjWcH60DPjseCgZhc8BdhE4KhM3h6S1ZrIRFyiuL1SDB/nWz6v3+3npAyG+vpiaDybkCy8usQP/F9QwZ627lHseoeV73644vz/l6W+GVJS11xbSVTSvkhHh3SF5llYcGp3G/iqsKFPo3fJLjzOOveOxwHqLrBF9eVlhO/xZnlVtxUUnjHyHTgLUMlT9KhztmlHo0oMDc/bD7kMvm3yxVypnztg1VuFbUid3l/8Aiey3ve4a4XYBopE5WLKUBXFyY3mTB6XMl6CVb5Q02Lxmpz0Ye8YGAlqiiMXxByE5Agp+4XTj3qIiYWQaB59gyPO5jXFYESx4fpB0LJ0v6rudqGXbpH3DQ5J8cewCV2IGHAvK03DoxwBOR8rcFUSA38SumFOVVZU/U4F9B99PXvNRC/P0/cAqfFywxbau13uJNxldQDH2XRp1bFKpZlbEmJ6uz3RenHT+TbdtJk+AiFfJ59V5sNPGJyzGfQTS3s3ZoW/B+NcEL9sM+fQ1Wq8uOkwpwz792jzvqGFIfGtzi9JUoV83vgZ8qfcXsKIJUIZMd6IHy3azeozeTpoIeJjZ3Re+6QYjQPGQBvfDWSnoApHp+7PGCQZ+8ypEgikUw1K93x0F3BpFJzTDt9RtzS9KgFaubpslJAU55VtLd5jEpV0wUpbzpbKrjD/yDFKXI13JDtgrofO7Du+rFYuk2WGw0+GOGytmPEO7wJNP5t0rx/YQqq8BInswuKaDyuYlg3i7V4aQZCd2UeOctgfPvvgNneRQKnFe5ueQuc/P11+5rM/omAtk7/GztlyXmffiGLUuFTolMKZpzR0DC9UTGPgJlstlWRy/MoDegfPxzko4Uj383kWNzSuGSXaqiicR8qM+/iZxlkcm5tgIMUvrEYgNlg9fyTnbBzA7SDltjjA1OBgguxNpNvw4jK+gn5K5NLAZXTNBEgOrixbYKb9142Rtea7MPqWp8P3y4fzqRJ4kh9HDUaI0Mz5HM3AvqMgIek2wURP10wN8v/fR7wxBD0CAiTVAWcFTMUsgTcaKIaAKvCAJ0iJ36qSMk7MWk1rHR/TfB5LF9TTX4Elu5m3TjIT3/STg0WBZagtQZUJO9Q/Yht+/Xb9sCcSR0jgoP2AOeLCb7U1Kwp3t2aWi0Ar0Q9F9/aeNrrrxfL5Xb6MQesaSuwBUab1dc3ZseeDAaes3uMpkKW/EGGuch9FoHRzmK96MjP1mKHC+XOPXP5zjni5WKOmrQ4MQaHLMGW/qICzOIsgs3QlUNBUlWP90A2sJdWU3O0oh6J8kbVPgEszTcnNczF6Dkqt/xuEV854Otf1iR1flzv9Swo/yy5X+0WJEJbqVm87GKdj9D5sLV2Z/bVf1UZB6KpYfFs00t/I3z2L8QY6Arp1xBegeov97Hzre53G18J29LSqCAdqM/Vjn0rMGOc6EvTcTV4AtBtxCWk3un/pquA+JfenAaIi3qm4nxzu9Ui9rkhJON+F7fAS/m+CUMbR5vbUkSCOZHIvqTNqUYq+Qz31Pxm0IySin+RiRfCU3eoTLopqhWWBKQN7VuSV+8h/rGm0fNfI/o2TzWZencOfTJ+/Wu2NVsVO+yR8oz3pPr5MxO3OkSZyexqfrHGvMs3dOCQNd4jE/eJBqyUDuoR+VXHP2bfvufata60oEUEGdELeWIo3z6tybD3zuVq34ec9vUInvScox9aulsnN9/bT9co97HUZKdk1vUEiq+eNX7RDoRnE8rd6sTyUvJplCV3RIYR+ehUsK23s7x1/t7DdzVIzahld88hZ5pLry78hfshKNuCXqPojQH4TZm1SzWrvam6wtudFfrA4sgqk/+2CAS8FDYc/t8GzVU08uh037m+Hcl2usJezFW4LNLvzigDbdgP80VrQDfnq8nhDUsufmALctg3IFaBH5t6ob+qDQBqLt11Y2aVGetKYffuqjPWpPM5kZqplKTKpJHBj3IZjoJYuRsl5En7qTG98FAG/WMpCo5SUj2S2kAWw6jrET6SR/WE33+To7I6pX31G5qaI+mOhLObEyl36V/LfdOxMB+SL7H5HaV19Zc9Yyjlmi4FDHQxbd8jzukG2LPBthSFxYMmAbkzGwBQMYgyZ5cy+Z+r07TrbTL51j5PaFC6NUfJ5JSNwIYxXe2g5LjcrI8Hpt+Do9I5eTyX+Zopw9fDDWlyU1heDzv/u+OsNYy9FLKqNYc0OZ80wAM+1akaTYyx2StH5Od4M2qdGJGVxvXsq0PlciptT/JhVzOJHcC/zKJMpek9XEo2DYcosWuSm8pn8liAQv3oMNNMjrpXDBr0x/lBDd57RfMLZDkboEmDBxhusYu0B4L/QABDQWRTceS8O4F5eZdSjjWixHwfQ3OQjvrOl7e+1uVOGcTtiOiaZKm3FPewAUfxPLJLkJ1UwqsIZCKgDN6BJBWxQhvFVKxGDYIEATSWjGp8g0QI2ZGq8ysAZffJkzo//p7CwAdxmDSD2dZBrmJOtogvHehuQ09Wzjv3nTsBhGFUW97eMVjsA0BCW7ZO0rSWYYyr7saEvU2U23qGD7Gsj3Wv3dq59RG30bQcjVyuDmicR9dHy33WRR7Ww71gWMI7jQKd/+i6Xd6S56UWiuQss4Yx9HlTqgtMqIJLQv/DMtAmPwwEBNryV8ZQ5haChcH6gTOJN50fxIiscB88U/LXGBbkr9WzGN19eUnEbMDymI9q/67liSEAZrCM/8ffUr/JOgZ/m+x6MY80WP5EwumgbJuhB2Qr1u7oRxIHbtD0Fj5fseyuFGs2m/OsUqgrAs/1xWGUvYswAW9a+IfFrk+6PBY0Lw8eyQ6KJfe6ib0PHAiionw7f8Bu0qyHX5pyXvkTSIW/Tvht2tOBKcLYgyULkqmWnj7ogMu5luyl/hKhyfOyMjUQYivIqYCR85IcH3Fv0Xu3Cn+u1htzvmZwbwyx7oujxQHWnZdjqMTAVRWZdXhq4iTDZX1PhSe+mLzDmRbLQrn3GoHBJCegaP5lTBtWbHauVxHmB3lK//gFt/ILaLGgtjBJuDJuK/mBbS9fhiLR7IsIbkdBFmlVKnzwK/LAOvlRJ7RBxEhopqsobZcS3cbaJVncOHV80DudTN38exUsvg5qx0q713+pHvqTe6jUchaD+ewzVL4VUp/yD/uIDQLTs19prXB8tyLdBREuHbH5UjOmx3m+ifxL1HbaRFrbo6k/MkOEIHhxIYNlYhdvVG/7C70RPflMfYyMdUGGbKvRH5Ch54+TfdluwdH88ds+7zCZEQbvpTWe2tSFakni1ggjuuxJsJ/oZOhj8MFGMP4lToKgsqDsghJXe4Kcn/8l8obSViXw944lBFGytdElgFzJKjpx6cZnlVzhWo5Vd+2fFrRX+Fl3H+ksHSi9asllTYp8JPdds/FF3LgqkttkwsNA3kYSwWlKdRdhtgDwVIWtLSzOG2wFaBpEsz3FBUdLDloPqPCMVVwlD1EQEpF4fRoXGVoMUJnxXBErBlpVe/IyxT246MVii0+4uKuj1EKNG62gIyR8nM3NZs69g/wqU/g0Oen2WEOeKz/senpRNKsXDxhHIsvm49I+FS0RoLZ/kd27fvXfKiit0E/CaN1uYvRMwmkK4txEy0RvXnZGsZEpAMHB+UT9Az+uSh5BKViqVt+pATp5L/K2XylydewJwodVOyamb7SNym7iTjGg3D6pet6k4tkoE3aoEgaJuwydfci9U8lRkiOBAMLc/UpewcMbccnn0l6hM12tdY7tPk3AczFq13aykcWaAZJqYNnc+Ec4/w5PLPkXkPk+5jAaAmzRrEsBdlbqSKl7unqAReeFygyTbSOhjIjY2+dhRCJ0GWqIWUWlEhunig2Q2ad+TpCxYxa7rXURm55axmacgSA8cyC/egUMIwMp/noWydgNkO1GAc6UVt7gZmcn6LI5v8eWh9i4gQMKVRepLHCH3b3G1BopKoHM4KLBzI0TllfhbfU3ef+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0PEhodIiYyMIGHAkIBCC18QEJCKsOa/owbxIOM5EEEhOlVC/NmvqTG8TBrPoUv7ZtQTR8aYxgUmzZIr6u12grMtl0KdDIHefiprv0Ne+4CQX/8lWshkB3R8xzmNq2gQ3fnHksbfw4BOid6V3F8OXFNw21RVh0rfoWUy8cg7t8SXHrWOCU8wSoR4htxqIHaxUOl", + "3pKHQo+Ce+Pew13JoSi0plhpeyPV1JRG3vxeM46rueswgdwCAQEEQgBMgPA0oxbH0Nd7i5P7wePqOzNfIrmlw4zctM+Y1c/K9xFsJujqnhqTqSyUyZ0lXgNK7VzB4ETw9KqBT/9npt/DtaAHBgUrgQQAI6GBiQOBhgAEAbMqRJNr86NcqaUJ5vGQ8CJqUe6ZSyp5faMYez7PKg4y+kFAOG13deADq0BaNiRZwdSzKsjVCFshU8ECl7zYF9cAASOSwMgpa/kl+tVt1kE4kP9faDf1nZM++bVf4fgolkuM+UKQkTWALEDoO9cXkG/z4a4MwHyZgLPX+l4WTFrF2lvN", + "MIIBFAIBADANBgtghkgBhvprUAkBEQSB/96Sh0KPgnvj3sNdyaEotKZYaXsj1dSURt78XjOOq7nrMIHcAgEBBEIATIDwNKMWx9DXe4uT+8Hj6jszXyK5pcOM3LTPmNXPyvcRbCbo6p4ak6kslMmdJV4DSu1cweBE8PSqgU//Z6bfw7WgBwYFK4EEACOhgYkDgYYABAGzKkSTa/OjXKmlCebxkPAialHumUsqeX2jGHs+zyoOMvpBQDhtd3XgA6tAWjYkWcHUsyrI1QhbIVPBApe82BfXAAEjksDIKWv5JfrVbdZBOJD/X2g39Z2TPvm1X+H4KJZLjPlCkJE1gCxA6DvXF5Bv8+GuDMB8mYCz1/peFkxaxdpbzQ==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "GHaUq6Q2xqznSDk9y6A7Zmo+e01TrbxvP/bmvIlJB7uXiUp15fInDH8RLQDnCCeWR6heD6ZbIMJG23Apg+4O8qgs1nfCmGXK1wrstz7jzEsR+7qnw3ASCghBXhW5n+4RE2YTMtfhbaIF7K6/Zuk1ARCyvIFVtOz8hl88ADhLbvhrSji509v5VUXn3tVxwDOPDRuwZIZhZmfUrTByL8d+Zq/WBeRNlXl584bz++oU4svhTetTg1PAGREbeGle1Ni2ehZ1wpRPvT+0eNQlxynVPU4uKjVzF2IPRoerjKNpy92EhiLjPK+u6caqtvquMlflndkGhj0cqSvRL+rGileyZs6ZN+Dyx/BeBOwocDVrCJeF/HeaOSiCiEq4uImdtArBsq5UCg+dcKlakYCkO9im0fljTCQxyINIBzb+HraA5GuVprEdBaCj0aDTn2zRD5G69LcwU4GBuelk7XfLwWat887KMrVKrXQuE/C1qCFYoKBhFMpJ8KLFdtg+UKcrT90oGCuuIc2Ds6UYG83sXXGLuU383QBw1X/IkgT/d13BplvyGP/EUhnyVkREFxxA6JfkMJ8Z86NHKbugjqcdg42YoAdi/voiuLhDdudNQksaJ2bx4aCAhEGxsE7dYzkyHK8qNWouPjs5nmF6CPfxl2QcA3PV5HrLJylS8c+V2X/mJNL4W557ntYWFlM0MON2Skovm8fHo6MYmlri0I2jWv9yihuKLkHIl3Qr5EQmYNjZn/LTbT6mqVlPqT2vIC1nNqO4kSiTKmxMQFup5rNsJ+tbZg3HjrLloyW2QQhtB6E9dBg/x/aKUl+B92OSwQzDR+fsdc5VqQWd4F0xeEwCXqpQ2J6xHsSfU63hBMGeegxlq/irCdRD1TFkSWFFkySTlnQ/VCU1kV6H4YsWii8zA2V8MyG5rplyrZUzfmFxcSJlQmH4+ESXxkKeLUPHHRdbIRjsRE6ghd+ZoRtJzANcb6a+LStXEw8wkNfjROE5VrNZKaBqzTwBM3UaZ1nvle4YFv3l5c6zlUifLuBkuToiPumbAJ4f9KiP26rXA6pbvfD8lMzQAEequI8OR4hrAxV74uy3sqYHteNmTR6woHXUPniD0GPCLX47C/Syh7A7gtABtXGgq4ZDAriXR4uS5m5prU3xTL3ghOU6t3jOeBYmhdlJp9I5xHFkfchNNpFA+icYZDce5U7C3Y554HG6apfITTyKcyDsjp3N4aYkeyC8uWY46FMKie37FMKWMKoPJ93UoZd6gaPQCbzlmcEbo2MAkvlyt7F+A3fy2G9FeZPiniV70vRasJbT+mL8GvEQIzH9KVkbu7HKnjP3WlrESeker3U/GdRsIDEFgyv2aienKEsIo/mhQUpUW7Ghy4vZo+IEfaKHQ7VUm+4BYUosa6Tqb1nBL0DUs/ezSZV280wlL0E/lRb7Tnhqf9FVNyMN+9C2EzAcxNDV42ldEEwgB2jVsdsSrROPE3UpJ6qNy46mzt6pPfqHs8F8ptCs64+JwztCPwQbX5e/LjC3/kVs+drY6XHkOLmuVzC67OmitPDA/z97mZHxtjgjItObYSwuqjL6Etk4Om5l82LAsUSlJk6+QWF+XAXKWZbtX+Emd0vW68Ia1AL4Hw8FmFX8MX1L4eMTXeAQZDLx5uMDzAZKfYXSSkHvz6Eo94tIO4vqjfHZfDewEt9Cq5clubklGpRM4JuPjvBZRMi7LSeDOCHS5HvF7X+tTA/hebCl4v/TkkqN3yix6syMVxxqfzlrLUiwW7KZTFvrpFgTjWWUE+L0UAY2qWFohOS6CUwrjbIWq3VjL3jmYfwBEFxjGLtn4cOpfhvzbb/lxTJ+YVKa5v/iJuei5b/me5xRi/2ulzlAsUgWnYtEQF3iaJk6ydtBSYEXF9Z4wEr53Ed9l8N0foPQU14P7mQFAyNQJ9jxpiqrpxKU8QK+1kDwPLQYazpySMjL9igNJMqQJ2AOa+Jq0ABGqVtVE0Zr6sQ1xviI2of1OcTPTT01tRN1Mu2ivcza17xBTKLVFM+n8EdVWyKlxCvsk8hkIZlkRZrxPZTRVia3+ruo0Oduyq9G8gROtsbX4+WGbZwFK46hTHPsZKs1p2IsFEWtWaOGn7i0I4GLKYIKGnu2Suyqkymlw93RbboBVYNhCHdIITFzJ4nmuVyvAjAk2CBYTll6bII5pZdSgJyRz6o2HdO6T7p14QrsWafgvnqUiBaABnMd41BAFtwqD1qcvTEQjxuhTptvLe3BUtPW6txK+7rocNtfy118dtAjfv/qwvE/sr7ovmuZwb6gQkfd4IQlc5PPlSEagdHeTu8xtkQkXdgBaFeztiEk3xOw5PnoP8FmXcKTNp3myxSq1LZM5N/C5Wof9DvZ4sGJBea1OGrK5cyJ7vpawb8Itqjg6M7eKS4aH7ncFz/wfgDbKeg77tqKWCI3FO4eUwLQTlRlKaZL046cqUXygK6ApXQDGEBJD5ClcSOJe03Aq1BBch8xBBy6Bj7JQzOuBeNHROQCewFHabUwguqdd/WfdbqrKReLMW0RMiGW8cYMVohQErHrLt2duqpxNPPCRJSywGbVgZjvoNVN3aOenpA23srxTPXFWtAesvHj0FIV5bilWlOmbfaUnhd4AHpeO7hYN/2pwMfqMXoTtHLdYmuGJZBxWwiGFBGwtIRihnrdc8d43h4wJButeL1AbmVa9ioh9FP5vX5pfq6j9mSlnaDLDcBXcf3exq8Co9if6VolfeNjQglINZStaJtF9OH4FhuN0RedZNFYSF6MpBfV5Ie8nk7NuiPy4BIKppQyS+cZEix75QUiF41X+9Ayn0/ipg1zR+w9azzZHZzSLJKVewwhTxw7v1j4+PpCNe54W7NW3+DGYVN4MOZqrjw7LXgOaWtIISsKCzZtVSHZ3D0yshm0lZkXtVKS3aIoIqT5U5PAHtXLqZWqeRZzrrJd3idnCtQG9PDUlf7vLcTiOwoAHoVb0q+weBrupP2K5nBtU23i5O8bTORUUoHa7D+YyU+eSaMAJnYvrP1zET6SrVpibf7vWVCWEfhRRdfXP66IDNSisqWJP8ZDu402tl9zhHb9+N0YOd/dFeM04zBmsJbYDJdJJIvsMdEs1XXqsni6+c518wbve6vcseGqTmQcOfZeJJa5w31l2MgZGgrcoOm3SBb1qcK9dZQ9V2vuKyGkXmZ8G8LJ7Sr1ufD5xEFPvCqlalmlX6QyHgORHBXTD1L2RY8EkLplcqfKSFsLDqYdskJu7Kk+OsDPH70qd7AaFDKfMwRCamvOFxdRotzEwbeOsqRhACxHuJU/2POvIRmz/bsSQhJ3BlQvnBi8YPFXSPL5Kat/L6/H7HipONfn6ausWtAK4ggv5bLqVECnB8F6DciWH7sOZGS6ixka5oCQZ4xT01VSaHeNvTU/omT1aCa/0EkLd/IV6O/F8zeI06uLyPHlnoV/PSGQRZT47krcfwk6q/+EOsQrFuaI2M00DOGwqip4f7XCXFllPs/w02IM+WUrGnQIX+895RvR8/ogFc3h85EMGlaVcY6YncXiBC9eAEfCVzWiXekFZKA43as5Jt3ah+/jPCXBaTEbYBoaxkJ6F0DvfYX0SE8gC6Vij7L+IckLAFS0N9AQWYl9xz6u9xU3+zFdyufx8+wFyC8TzmVSCTfyPzzXEmvpnGH4eco4pDBgiyxCj2TDi0/OgYjOyNMPYNk8LMbTu20f9RfukhFHzLGlfp2ZIzursw/9v7iLDlXFZyWEEA/ysSPKAi60+zBxgHySR1knr3HYDV1hnabAsTtFSpB0laMNYrtx4j4KCEv1l2xrzqSBFj1aEsIxyuHSatU9Of+SF+XpR9QMlbUBnpfQ/tiINYpwFgI0Z/xNeNDDOVwxON8tUN/WhIr50q7KUhIINoXWg6Sl7rG2DjcmUVfBxfmawtfARFVtJdy/2udVpAbuYj4VqbPaH/Ls+ULFai5gAKHaB9dd/7Gl0Lj1j/CLidLYMlbKl01eyjhumqez1iCH+xgsmPqaNBwK7jQOsJQ348TGifH4vRZ+7sHg0urBb4JbeweS+9M3FC9fl0GrAoiISUudjIvuASDx45O/suWwqaTurFkrrLUPnHhiCOtZvqjFHB3kNH3uItEKZL8ExvDi8FcOV8h1E2yjdd8o3+rT07OotfEA2GIuLmOGlOZUyK+Xii3dxkqqxsrE4D6PWj4dac+TmcluPWShfxro7edc2xxDHRfC0tQD0B2yDSx4OX0JQ/cvILo6XExuhy6YVYeypS/hWmbCFJhBq0+TuYDMmt30KyAib6xZFwhRxNmv0VNFTcjpMjbMZFV+UeobdiHoVcxnOiR1CJN6rGWpJ0KZi9/0oGzGnKh0GvAQYJ1r1dIkWz+Byyvww5enMNhqHroCZ81aIacg0CNvEr5Kwqhpwt4FzhMCeuzh1kFYKIx/1X+DXplVtBOBc7Px1WiISHPk5MGc+DtiTvFciIQ2hjBpnoYESyDe/wJ0/+f8ij0CmxVlA4o1ih6qpPr/sUDTZvju3nnWSWdDYF26NxvpKGXCxjKmTGbwpHiiUgghRgcZIu0x6+wXslKF/G+5JKcDRLi5uWAZ+iYlgl+JGcFsb3PqG3D/pnDUho477hb9f2BQtZG0VtRsEUIUOAzi5nSiA8D09Upk5usG4vyyD13Oop2GDFL6+Z5dzi+jqGjl0WPE4iw66HCv71YYJsX/zlZcx1KyerLJ0rbRlQ+7Mx6j891doT1hnMdDYUrjZl2B924gLhsA3ImJjbuloN8/Wna1X7SOxpZlqZ6VZyKRQ5EKlRKsUHSQgIyQHVvZyKYTrW1ciVF6fzrik5F/QWMWSFJNPsOhlU4V75nwamrPf9IXVNrRvd7h7cnw7idP2jauZkRJQkxneMphxLe9l5+OZzFAX+7HfzlZZmT34jON1CoUKi2T1/eNycIcENUFd7L7YFC9xBCWtYzgYdRkX/Wkg3X/ZcYJn6RF6iNFwZhWiNRQSCXQEYx3QNJcXDvWArFUD+x6ElYsY4YnCJ8HlwX2UedDEOhQFf/mnQ4IJ9OTZ7dEug9aJK0tO54gMCUn13qS8rTPFL0U58zMhYG2PckhMxaI+49jA2xWYCqxJ21KGttjcgNhpjFbi99oPVsMXGzQS12mZ9dcvkUAnfZSMqh3VNQ7AQIbDOI3EG6T6xdOwq3dnpckQHOgyva4R8pfrPx1cdDl7Y8VANz6a9DHYAvncIx+NvCR5ZI9S7OCNVOKURP+CF7dbofoyNSDbs1Kbpc/va71drgOAgxE9lNnjsRD53m2p1qisZuLNBOhGMWGH5Gs/MeYLUeD1sSw/KJnTzPmzpf8m+5XnUEMW3U3dDoNInloifs9nmwuXgeBZwRC9XKImbtCjrdZrD6Md3JnLANqmcoTqhER5L4fMhP2nM0ASylHxSajIPOOwF9VpQPiKMJKHjfnlFdICC0cdqC0IHQL0r5UPU12WKOygaexqaswD1AjC+R15SdcWt1px2+bQbRehOB4lhInrDsHe/Ypg15Z8IvJ5KokZIAktjNti0xa28AaQf6sqbDG31kv03IUVTEfzm86k+c/F9ivWS9jo5d0SwB0jBmZmEc8i/tadSqgaxOsJJEVA8D2ts0MDJLhv0CBwTqQaTjbwjDYs+qRHwKKqMsqaf76fs4+5OZqFdfsjDuliNM75aBqZhx8wM6OpINJ3hNCl9PJdYs4z6jR7UAPzs98tICKKGdfF1E7p3si64qfJbLRobcTqsMB53B3y/3uvj/qBbOZXO2weUffUYUL2NnjTO0GEBpHKPRH9sX2AYxJn1UtTRkzDgBdlWInD2C0wtpoALaDQZ7E1dH1oebJz7kJLzCZj16KdW3uwACS2kTVSm44kWvGwezOlSyf8HT2gM8irvxL0BYo1gxSnsQ59E6H1zRsbKclzO7uyFnLiDwJlP/rrDw7TWZ1BeynONiSVA9M9s145b7HBDDd4JjU0E3OeqIXgNKncF9mIHIsfsd8LGNVL4945EQdxjXGIlTm9DtBLCAnmAdDkLxKu03xy+ey3zBY88bMWOCl0rfVCmZ8U7/SEtBJzaSB0Ws/9pYbYkXLONIQhtgUqWjex/qGaI0n1uf9kr34ahH2KAwyg8bMzuYVUYGcISZ0GyFsps3h8fJMo67L8BZxlbozVWiC/hVEc32jzPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcLDhYbHyQrMIGIAkIB3dQe9dAvklsOHPEGXlCRA6HWWvCDaDDPTuE3NtmsI+7J9ZJH/U9C+ftViUZdSW7Fb0Eauda0ejgS5pg8TbqlCycCQgHY4QYS3XXtyDWlrtefZYsXhjfx3Ega5xD/FOtpDNhtRCRC8g8i86Yk66rjQm/e2iSWDFPgqIIxcAdb1D0o83z7TA=="), + ]; + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs new file mode 100644 index 00000000000000..6dc346fcbb1a74 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Linq; +using Xunit.Sdk; + +namespace System.Security.Cryptography.Tests +{ + public static partial class CompositeMLDsaTestData + { + public class CompositeMLDsaTestVector + { + internal string Id { get; } + internal CompositeMLDsaAlgorithm Algorithm { get; } + internal byte[] Message { get; } + internal byte[] PublicKey { get; } + internal byte[] Certificate { get; } + internal byte[] SecretKey { get; } + internal byte[] Pkcs8 { get; } + internal byte[] Signature { get; } + + internal CompositeMLDsaTestVector(string tcId, CompositeMLDsaAlgorithm algo, string pk, string x5c, string sk, string sk_pkcs8, string m, string s) + { + Id = tcId; + Algorithm = algo; + PublicKey = Convert.FromBase64String(pk); + Certificate = Convert.FromBase64String(x5c); + SecretKey = Convert.FromBase64String(sk); + Pkcs8 = Convert.FromBase64String(sk_pkcs8); + Message = Convert.FromBase64String(m); + Signature = Convert.FromBase64String(s); + } + + public override string ToString() => Id; + } + + internal static partial CompositeMLDsaTestVector[] AllIetfVectors { get; } + + public static IEnumerable AllIetfVectorsTestData => + AllIetfVectors.Select(v => new object[] { v }); + + internal static CompositeMLDsaTestVector[] SupportedAlgorithmIetfVectors => + field ??= AllIetfVectors.Where(v => CompositeMLDsa.IsAlgorithmSupported(v.Algorithm)).ToArray(); + + public static IEnumerableSupportedAlgorithmIetfVectorsTestData => + SupportedAlgorithmIetfVectors.Select(v => new object[] { v }); + + internal static CompositeMLDsaAlgorithm[] AllAlgorithms => field ??= + [ + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, + CompositeMLDsaAlgorithm.MLDsa44WithEd25519, + CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, + CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, + CompositeMLDsaAlgorithm.MLDsa65WithEd25519, + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, + CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, + CompositeMLDsaAlgorithm.MLDsa87WithEd448, + CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, + CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, + ]; + + public static IEnumerable AllAlgorithmsTestData => + AllAlgorithms.Select(v => new object[] { v }); + + internal static MLDsaKeyInfo GetMLDsaIetfTestVector(CompositeMLDsaAlgorithm algorithm) + { + MLDsaAlgorithm mldsaAlgorithm = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm]; + + if (mldsaAlgorithm == MLDsaAlgorithm.MLDsa44) + { + return MLDsaTestsData.IetfMLDsa44; + } + else if (mldsaAlgorithm == MLDsaAlgorithm.MLDsa65) + { + return MLDsaTestsData.IetfMLDsa65; + } + else if (mldsaAlgorithm == MLDsaAlgorithm.MLDsa87) + { + return MLDsaTestsData.IetfMLDsa87; + } + else + { + throw new XunitException($"Algorithm '{algorithm.Name}' doesn't have ML-DSA component."); + } + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestHelpers.cs new file mode 100644 index 00000000000000..5baa26ec226062 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestHelpers.cs @@ -0,0 +1,323 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Formats.Asn1; +using Xunit; +using Xunit.Sdk; + +namespace System.Security.Cryptography.Tests +{ + internal static class CompositeMLDsaTestHelpers + { + internal static readonly Dictionary MLDsaAlgorithms = new() + { + { CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, MLDsaAlgorithm.MLDsa44 }, + { CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, MLDsaAlgorithm.MLDsa44 }, + { CompositeMLDsaAlgorithm.MLDsa44WithEd25519, MLDsaAlgorithm.MLDsa44 }, + { CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, MLDsaAlgorithm.MLDsa44 }, + + { CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithEd25519, MLDsaAlgorithm.MLDsa65 }, + + { CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithEd448, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, MLDsaAlgorithm.MLDsa87 }, + }; + + internal static void AssertImportPublicKey(Action> action, CompositeMLDsaAlgorithm algorithm, byte[] publicKey) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, publicKey)); + + if (publicKey?.Length == 0) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, Array.Empty().AsSpan())); + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, ReadOnlySpan.Empty)); + } + else + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, publicKey.AsSpan())); + } + } + + internal static void AssertImportPrivateKey(Action> action, CompositeMLDsaAlgorithm algorithm, byte[] privateKey) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, privateKey)); + + if (privateKey?.Length == 0) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, Array.Empty().AsSpan())); + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, ReadOnlySpan.Empty)); + } + else + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, privateKey.AsSpan())); + } + } + + internal class RsaAlgorithm(int keySizeInBits) + { + internal int KeySizeInBits { get; } = keySizeInBits; + } + + internal class ECDsaAlgorithm(int keySizeInBits) + { + internal int KeySizeInBits { get; } = keySizeInBits; + } + + internal class EdDsaAlgorithm(int keySizeInBits) + { + internal int KeySizeInBits { get; } = keySizeInBits; + } + + internal static void ExecuteComponentAction( + CompositeMLDsaAlgorithm algo, + Action rsaFunc, + Action ecdsaFunc, + Action eddsaFunc) + { + ExecuteComponentFunc( + algo, + info => { rsaFunc(info); return true; }, + info => { ecdsaFunc(info); return true; }, + info => { eddsaFunc(info); return true; }); + } + + internal static T ExecuteComponentFunc( + CompositeMLDsaAlgorithm algo, + Func rsaFunc, + Func ecdsaFunc, + Func eddsaFunc) + { + if (algo == CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15 || + algo == CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss) + { + return rsaFunc(new RsaAlgorithm(2048)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss || + algo == CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss) + { + return rsaFunc(new RsaAlgorithm(3072)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss || + algo == CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss) + { + return rsaFunc(new RsaAlgorithm(4096)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256) + { + return ecdsaFunc(new ECDsaAlgorithm(256)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384 || + algo == CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1 || + algo == CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384) + { + return ecdsaFunc(new ECDsaAlgorithm(384)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521) + { + return ecdsaFunc(new ECDsaAlgorithm(521)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa44WithEd25519 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithEd25519) + { + return eddsaFunc(new EdDsaAlgorithm(256)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa87WithEd448) + { + return eddsaFunc(new EdDsaAlgorithm(456)); + } + else + { + throw new XunitException($"Unsupported algorithm: {algo}"); + } + } + + internal static void AssertExportPublicKey(Action> callback) + { + callback(dsa => dsa.ExportCompositeMLDsaPublicKey()); + callback(dsa => DoTryUntilDone(dsa.TryExportCompositeMLDsaPublicKey)); + } + + internal static void AssertExportPrivateKey(Action> callback) + { + callback(dsa => dsa.ExportCompositeMLDsaPrivateKey()); + callback(dsa => DoTryUntilDone(dsa.TryExportCompositeMLDsaPrivateKey)); + } + + internal static void WithDispose(T disposable, Action callback) + where T : IDisposable + { + using (disposable) + { + callback(disposable); + } + } + + internal static void AssertPublicKeyEquals(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan expected, ReadOnlySpan actual) + { + AssertExtensions.SequenceEqual(expected, actual); + } + + internal static void AssertPrivateKeyEquals(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan expected, ReadOnlySpan actual) + { + ReadOnlySpan expectedMLDsaKey = expected.Slice(0, MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes); + ReadOnlySpan actualMLDsaKey = actual.Slice(0, MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes); + + AssertExtensions.SequenceEqual(expectedMLDsaKey, actualMLDsaKey); + + byte[] expectedTradKey = expected.Slice(expectedMLDsaKey.Length).ToArray(); + byte[] actualTradKey = actual.Slice(actualMLDsaKey.Length).ToArray(); + + ExecuteComponentAction( + algorithm, + _ => + { + RSAParameters expectedRsaParameters = RSAParametersFromRawPrivateKey(expectedTradKey); + RSAParameters actualRsaParameters = RSAParametersFromRawPrivateKey(actualTradKey); + + Rsa.Tests.ImportExport.AssertKeyEquals(expectedRsaParameters, actualRsaParameters); + }, + _ => Assert.Equal(expectedTradKey, actualTradKey), + _ => Assert.Equal(expectedTradKey, actualTradKey)); + } + + private static RSAParameters RSAParametersFromRawPrivateKey(ReadOnlySpan key) + { + RSAParameters parameters = default; + + AsnValueReader reader = new AsnValueReader(key, AsnEncodingRules.BER); + AsnValueReader sequenceReader = reader.ReadSequence(Asn1Tag.Sequence); + + if (!sequenceReader.TryReadInt32(out int version)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + const int MaxSupportedVersion = 0; + + if (version > MaxSupportedVersion) + { + throw new CryptographicException( + SR.Format( + SR.Cryptography_RSAPrivateKey_VersionTooNew, + version, + MaxSupportedVersion)); + } + + parameters.Modulus = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + int modulusLength = parameters.Modulus.Length; + int halfModulusLength = modulusLength / 2; + + if (parameters.Modulus.Length != modulusLength) + { + throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); + } + + parameters.Exponent = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + // We're not pinning and clearing the arrays here because this is a test helper. + // In production code, you should always pin and clear sensitive data. + parameters.D = new byte[modulusLength]; + parameters.P = new byte[halfModulusLength]; + parameters.Q = new byte[halfModulusLength]; + parameters.DP = new byte[halfModulusLength]; + parameters.DQ = new byte[halfModulusLength]; + parameters.InverseQ = new byte[halfModulusLength]; + + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.D); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.P); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.Q); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.DP); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.DQ); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.InverseQ); + + sequenceReader.ThrowIfNotEmpty(); + reader.ThrowIfNotEmpty(); + + return parameters; + } + + private static byte[] ToUnsignedIntegerBytes(this ReadOnlySpan span) + { + if (span.Length > 1 && span[0] == 0) + { + return span.Slice(1).ToArray(); + } + + return span.ToArray(); + } + + private static void ToUnsignedIntegerBytes(this ReadOnlySpan span, Span destination) + { + int length = destination.Length; + + if (span.Length == length) + { + span.CopyTo(destination); + return; + } + + if (span.Length == length + 1) + { + if (span[0] == 0) + { + span.Slice(1).CopyTo(destination); + return; + } + } + + if (span.Length > length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + destination.Slice(0, destination.Length - span.Length).Clear(); + span.CopyTo(destination.Slice(length - span.Length)); + } + + internal static void VerifyDisposed(CompositeMLDsa dsa) + { + // A signature-sized buffer can be reused for keys as well + byte[] tempBuffer = new byte[dsa.Algorithm.MaxSignatureSizeInBytes]; + + Assert.Throws(() => dsa.SignData([], tempBuffer, [])); + Assert.Throws(() => dsa.SignData([])); + Assert.Throws(() => dsa.VerifyData(ReadOnlySpan.Empty, ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => dsa.VerifyData(Array.Empty(), Array.Empty(), Array.Empty())); + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPrivateKey([], out _)); + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey()); + Assert.Throws(() => dsa.TryExportCompositeMLDsaPublicKey([], out _)); + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey()); + } + + private delegate bool TryExportFunc(Span destination, out int bytesWritten); + private static byte[] DoTryUntilDone(TryExportFunc func) + { + byte[] buffer = new byte[512]; + int written; + + while (!func(buffer, out written)) + { + Array.Resize(ref buffer, buffer.Length * 2); + } + + return buffer.AsSpan(0, written).ToArray(); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs new file mode 100644 index 00000000000000..0420014503628d --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs @@ -0,0 +1,201 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + [ConditionalClass(typeof(CompositeMLDsa), nameof(CompositeMLDsa.IsSupported))] + public abstract class CompositeMLDsaTestsBase + { + protected abstract CompositeMLDsa ImportPrivateKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + protected abstract CompositeMLDsa ImportPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportExportVerify(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using (CompositeMLDsa privateKey = ImportPrivateKey(vector.Algorithm, vector.SecretKey)) + { + byte[] exportedSecretKey = privateKey.ExportCompositeMLDsaPrivateKey(); + CompositeMLDsaTestHelpers.AssertPrivateKeyEquals(vector.Algorithm, vector.SecretKey, exportedSecretKey); + + byte[] exportedPublicKey = privateKey.ExportCompositeMLDsaPublicKey(); + CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, exportedPublicKey); + + ExerciseSuccessfulVerify(privateKey, vector.Message, vector.Signature, []); + } + + using (CompositeMLDsa publicKey = ImportPublicKey(vector.Algorithm, vector.PublicKey)) + { + Assert.Throws(publicKey.ExportCompositeMLDsaPrivateKey); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => Assert.Throws(() => export(publicKey))); + + byte[] exportedPublicKey = publicKey.ExportCompositeMLDsaPublicKey(); + CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, exportedPublicKey); + + ExerciseSuccessfulVerify(publicKey, vector.Message, vector.Signature, []); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportSignVerify(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] signature; + + using (CompositeMLDsa privateKey = ImportPrivateKey(vector.Algorithm, vector.SecretKey)) + { + signature = privateKey.SignData(vector.Message, null); + + Assert.Equal(vector.Signature.Length, signature.Length); + + ExerciseSuccessfulVerify(privateKey, vector.Message, signature, []); + } + + using (CompositeMLDsa publicKey = ImportPublicKey(vector.Algorithm, vector.PublicKey)) + { + ExerciseSuccessfulVerify(publicKey, vector.Message, signature, []); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPublicKey_Export(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPublicKey(vector.Algorithm, vector.PublicKey); + + CompositeMLDsaTestHelpers.AssertExportPublicKey( + export => CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, export(dsa))); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => Assert.Throws(() => export(dsa))); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPrivateKey_Export(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPrivateKey(vector.Algorithm, vector.SecretKey); + + CompositeMLDsaTestHelpers.AssertExportPublicKey( + export => CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, export(dsa))); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => CompositeMLDsaTestHelpers.AssertPrivateKeyEquals(vector.Algorithm, vector.SecretKey, export(dsa))); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void SignData_PublicKeyOnlyThrows(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPublicKey(vector.Algorithm, vector.PublicKey); + + CryptographicException ce = + Assert.ThrowsAny(() => dsa.SignData("hello"u8.ToArray())); + + Assert.DoesNotContain("unknown", ce.Message, StringComparison.OrdinalIgnoreCase); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void TryExportPrivateKey_BufferTooSmall(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPrivateKey(vector.Algorithm, vector.SecretKey); + byte[] key = dsa.ExportCompositeMLDsaPrivateKey(); + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPrivateKey(key.AsSpan(0, key.Length - 1), out int bytesWritten)); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void TryExportPublicKey_BufferTooSmall(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPublicKey(vector.Algorithm, vector.PublicKey); + byte[] key = dsa.ExportCompositeMLDsaPublicKey(); + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPublicKey(key.AsSpan(0, key.Length - 1), out int bytesWritten)); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPrivateKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] secretKeyWithTrailingData = vector.SecretKey; + Array.Resize(ref secretKeyWithTrailingData, vector.SecretKey.Length + 1); + Assert.Throws(() => ImportPrivateKey(vector.Algorithm, secretKeyWithTrailingData)); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPublicKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] publicKeyWithTrailingData = vector.PublicKey; + Array.Resize(ref publicKeyWithTrailingData, vector.PublicKey.Length + 1); + Assert.Throws(() => ImportPublicKey(vector.Algorithm, publicKeyWithTrailingData)); + } + + protected static void ExerciseSuccessfulVerify(CompositeMLDsa dsa, byte[] data, byte[] signature, byte[] context) + { + ReadOnlySpan buffer = [0, 1, 2, 3]; + + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, context)); + + if (data.Length > 0) + { + AssertExtensions.FalseExpression(dsa.VerifyData(Array.Empty(), signature, context)); + AssertExtensions.FalseExpression(dsa.VerifyData(ReadOnlySpan.Empty, signature, context)); + + data[0] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + data[0] ^= 1; + } + else + { + AssertExtensions.TrueExpression(dsa.VerifyData(Array.Empty(), signature, context)); + AssertExtensions.TrueExpression(dsa.VerifyData(ReadOnlySpan.Empty, signature, context)); + + AssertExtensions.FalseExpression(dsa.VerifyData(buffer.Slice(0, 1), signature, context)); + AssertExtensions.FalseExpression(dsa.VerifyData(buffer.Slice(1, 3), signature, context)); + } + + // Flip randomizer + signature[0] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + signature[0] ^= 1; + + // Flip mldsaSig + signature[32] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + signature[32] ^= 1; + + // Flip tradSig + int tradSigOffset = 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[dsa.Algorithm].SignatureSizeInBytes; + signature[tradSigOffset] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + signature[tradSigOffset] ^= 1; + + if (context.Length > 0) + { + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, Array.Empty())); + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, ReadOnlySpan.Empty)); + + context[0] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + context[0] ^= 1; + } + else + { + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, Array.Empty())); + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, ReadOnlySpan.Empty)); + + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, buffer.Slice(0, 1))); + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, buffer.Slice(1, 3))); + } + + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, context)); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.Shared.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.Shared.cs new file mode 100644 index 00000000000000..6f47cca124c765 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.Shared.cs @@ -0,0 +1,90 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Numerics; +using Xunit; + +namespace System.Security.Cryptography.Rsa.Tests +{ + // TODO This is used in multiple tests files, so move this into a common Helpers class. + public partial class ImportExport + { + internal static void AssertKeyEquals(in RSAParameters expected, in RSAParameters actual) + { + Assert.Equal(expected.Modulus, actual.Modulus); + Assert.Equal(expected.Exponent, actual.Exponent); + + Assert.Equal(expected.P, actual.P); + Assert.Equal(expected.DP, actual.DP); + Assert.Equal(expected.Q, actual.Q); + Assert.Equal(expected.DQ, actual.DQ); + Assert.Equal(expected.InverseQ, actual.InverseQ); + + if (expected.D == null) + { + Assert.Null(actual.D); + } + else + { + Assert.NotNull(actual.D); + + // If the value matched expected, take that as valid and shortcut the math. + // If it didn't, we'll test that the value is at least legal. + if (!expected.D.SequenceEqual(actual.D)) + { + VerifyDValue(actual); + } + } + } + + private static void VerifyDValue(in RSAParameters rsaParams) + { + if (rsaParams.P == null) + { + return; + } + + // Verify that the formula (D * E) % LCM(p - 1, q - 1) == 1 + // is true. + // + // This is NOT the same as saying D = ModInv(E, LCM(p - 1, q - 1)), + // because D = ModInv(E, (p - 1) * (q - 1)) is a valid choice, but will + // still work through this formula. + BigInteger p = PositiveBigInteger(rsaParams.P); + BigInteger q = PositiveBigInteger(rsaParams.Q); + BigInteger e = PositiveBigInteger(rsaParams.Exponent); + BigInteger d = PositiveBigInteger(rsaParams.D); + + BigInteger lambda = LeastCommonMultiple(p - 1, q - 1); + + BigInteger modProduct = (d * e) % lambda; + Assert.Equal(BigInteger.One, modProduct); + } + + private static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b) + { + BigInteger gcd = BigInteger.GreatestCommonDivisor(a, b); + return BigInteger.Abs(a) / gcd * BigInteger.Abs(b); + } + + private static BigInteger PositiveBigInteger(byte[] bigEndianBytes) + { + byte[] littleEndianBytes; + + if (bigEndianBytes[0] >= 0x80) + { + // Insert a padding 00 byte so the number is treated as positive. + littleEndianBytes = new byte[bigEndianBytes.Length + 1]; + Buffer.BlockCopy(bigEndianBytes, 0, littleEndianBytes, 1, bigEndianBytes.Length); + } + else + { + littleEndianBytes = (byte[])bigEndianBytes.Clone(); + + } + + Array.Reverse(littleEndianBytes); + return new BigInteger(littleEndianBytes); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs index 72ffbef169263a..47805e24928fa9 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs @@ -327,34 +327,6 @@ public static void ImportZeroModulus(bool includePrivateParameters) Assert.ThrowsAny(() => RSAFactory.Create(zeroModulus)); } - internal static void AssertKeyEquals(in RSAParameters expected, in RSAParameters actual) - { - Assert.Equal(expected.Modulus, actual.Modulus); - Assert.Equal(expected.Exponent, actual.Exponent); - - Assert.Equal(expected.P, actual.P); - Assert.Equal(expected.DP, actual.DP); - Assert.Equal(expected.Q, actual.Q); - Assert.Equal(expected.DQ, actual.DQ); - Assert.Equal(expected.InverseQ, actual.InverseQ); - - if (expected.D == null) - { - Assert.Null(actual.D); - } - else - { - Assert.NotNull(actual.D); - - // If the value matched expected, take that as valid and shortcut the math. - // If it didn't, we'll test that the value is at least legal. - if (!expected.D.SequenceEqual(actual.D)) - { - VerifyDValue(actual); - } - } - } - internal static void ValidateParameters(ref RSAParameters rsaParams) { Assert.NotNull(rsaParams.Modulus); @@ -393,56 +365,6 @@ internal static RSAParameters MakePublic(in RSAParameters rsaParams) }; } - private static void VerifyDValue(in RSAParameters rsaParams) - { - if (rsaParams.P == null) - { - return; - } - - // Verify that the formula (D * E) % LCM(p - 1, q - 1) == 1 - // is true. - // - // This is NOT the same as saying D = ModInv(E, LCM(p - 1, q - 1)), - // because D = ModInv(E, (p - 1) * (q - 1)) is a valid choice, but will - // still work through this formula. - BigInteger p = PositiveBigInteger(rsaParams.P); - BigInteger q = PositiveBigInteger(rsaParams.Q); - BigInteger e = PositiveBigInteger(rsaParams.Exponent); - BigInteger d = PositiveBigInteger(rsaParams.D); - - BigInteger lambda = LeastCommonMultiple(p - 1, q - 1); - - BigInteger modProduct = (d * e) % lambda; - Assert.Equal(BigInteger.One, modProduct); - } - - private static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b) - { - BigInteger gcd = BigInteger.GreatestCommonDivisor(a, b); - return BigInteger.Abs(a) / gcd * BigInteger.Abs(b); - } - - private static BigInteger PositiveBigInteger(byte[] bigEndianBytes) - { - byte[] littleEndianBytes; - - if (bigEndianBytes[0] >= 0x80) - { - // Insert a padding 00 byte so the number is treated as positive. - littleEndianBytes = new byte[bigEndianBytes.Length + 1]; - Buffer.BlockCopy(bigEndianBytes, 0, littleEndianBytes, 1, bigEndianBytes.Length); - } - else - { - littleEndianBytes = (byte[])bigEndianBytes.Clone(); - - } - - Array.Reverse(littleEndianBytes); - return new BigInteger(littleEndianBytes); - } - private static bool TestRsa16384() { try diff --git a/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs index 15e54c330f6f5b..2c312d55101aba 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs @@ -15,75 +15,75 @@ public static void AlgorithmsHaveExpectedParameters() algorithm = CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss; Assert.Equal("MLDSA44-RSA2048-PSS-SHA256", algorithm.Name); - Assert.Equal(2676, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + RSA2048 (256) + Assert.Equal(32 + 2420 + 256, algorithm.MaxSignatureSizeInBytes); // Randomizer + ML-DSA + Traditional Signature algorithm = CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15; Assert.Equal("MLDSA44-RSA2048-PKCS15-SHA256", algorithm.Name); - Assert.Equal(2676, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + RSA2048 (256) + Assert.Equal(32 + 2420 + 256, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa44WithEd25519; Assert.Equal("MLDSA44-Ed25519-SHA512", algorithm.Name); - Assert.Equal(2484, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + Ed25519 (64) + Assert.Equal(32 + 2420 + 64, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256; Assert.Equal("MLDSA44-ECDSA-P256-SHA256", algorithm.Name); - Assert.Equal(2492, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + ECDSA-P256 (72) + Assert.Equal(32 + 2420 + 72, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss; Assert.Equal("MLDSA65-RSA3072-PSS-SHA512", algorithm.Name); - Assert.Equal(3693, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA3072 (384) + Assert.Equal(32 + 3309 + 384, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15; Assert.Equal("MLDSA65-RSA3072-PKCS15-SHA512", algorithm.Name); - Assert.Equal(3693, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA3072 (384) + Assert.Equal(32 + 3309 + 384, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss; Assert.Equal("MLDSA65-RSA4096-PSS-SHA512", algorithm.Name); - Assert.Equal(3821, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA4096 (512) + Assert.Equal(32 + 3309 + 512, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15; Assert.Equal("MLDSA65-RSA4096-PKCS15-SHA512", algorithm.Name); - Assert.Equal(3821, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA4096 (512) + Assert.Equal(32 + 3309 + 512, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256; Assert.Equal("MLDSA65-ECDSA-P256-SHA512", algorithm.Name); - Assert.Equal(3381, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + ECDSA-P256 (72) + Assert.Equal(32 + 3309 + 72, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384; Assert.Equal("MLDSA65-ECDSA-P384-SHA512", algorithm.Name); - Assert.Equal(3413, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + ECDSA-P384 (104) + Assert.Equal(32 + 3309 + 104, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1; Assert.Equal("MLDSA65-ECDSA-brainpoolP256r1-SHA512", algorithm.Name); - Assert.Equal(3381, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + ECDSA-brainpoolP256r1 (72) + Assert.Equal(32 + 3309 + 72, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithEd25519; Assert.Equal("MLDSA65-Ed25519-SHA512", algorithm.Name); - Assert.Equal(3373, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + Ed25519 (64) + Assert.Equal(32 + 3309 + 64, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384; Assert.Equal("MLDSA87-ECDSA-P384-SHA512", algorithm.Name); - Assert.Equal(4731, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + ECDSA-P384 (104) + Assert.Equal(32 + 4627 + 104, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1; Assert.Equal("MLDSA87-ECDSA-brainpoolP384r1-SHA512", algorithm.Name); - Assert.Equal(4731, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + ECDSA-brainpoolP384r1 (104) + Assert.Equal(32 + 4627 + 104, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithEd448; Assert.Equal("MLDSA87-Ed448-SHAKE256", algorithm.Name); - Assert.Equal(4741, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + Ed448 (114) + Assert.Equal(32 + 4627 + 114, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss; Assert.Equal("MLDSA87-RSA3072-PSS-SHA512", algorithm.Name); - Assert.Equal(5011, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + RSA3072 (384) + Assert.Equal(32 + 4627 + 384, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss; Assert.Equal("MLDSA87-RSA4096-PSS-SHA512", algorithm.Name); - Assert.Equal(5139, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + RSA4096 (512) + Assert.Equal(32 + 4627 + 512, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521; Assert.Equal("MLDSA87-ECDSA-P521-SHA512", algorithm.Name); - Assert.Equal(4766, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + ECDSA-P521 (139) + Assert.Equal(32 + 4627 + 139, algorithm.MaxSignatureSizeInBytes); } [Fact] diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj b/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj index 97e90e69a91187..c2cc1de2a16646 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj @@ -186,6 +186,8 @@ Link="Common\System\Security\Cryptography\CryptoPool.cs" /> + + @@ -337,8 +341,6 @@ Link="Common\System\Security\Cryptography\AesAEAD.cs" /> - @@ -375,6 +377,8 @@ Link="Common\Interop\Windows\BCrypt\Interop.BCryptFinalizeKey.cs" /> + + + + + - + - An encrypted key was found, but no password was provided. Use ImportFromEncryptedPem to import this key. - - The private key is too short for the indicated algorithm. - - - The public key is too short for the indicated algorithm. + + The private key is not the correct size for the indicated algorithm. The public key is not the correct size for the indicated algorithm. @@ -153,6 +150,9 @@ The computed authentication tag did not match the input authentication tag. + + Composite signature generation failed due to an error in one or both of the components. + ASN1 corrupted data. @@ -180,6 +180,9 @@ Invalid OID format. + + The specified RSA parameters are not valid. Exponent and Modulus are required. If D is present, it must have the same length as Modulus. If D is present, P, Q, DP, DQ, and InverseQ are required and must have half the length of Modulus, rounded up, otherwise they must be omitted. + The specified PKCS#8 key contains a seed that does not match the expanded key. @@ -222,6 +225,9 @@ The current instance does not contain a seed. + + The provided RSAPrivateKey value has version '{0}', but version '{1}' is the maximum supported. + The algorithm identified by '{0}' is unknown, not valid for the requested usage, or was not handled. diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs index c51de135ddd9b4..2d50b4bd4b445c 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs @@ -65,5 +65,55 @@ internal static ReadOnlyMemory DecodeOctetStringAsMemory(ReadOnlyMemory buffer) + { + if (buffer.Length > 0) + { + fixed (byte* pbBuffer = buffer) + { + Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(IntPtr.Zero, pbBuffer, buffer.Length, Interop.BCrypt.BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (status != Interop.BCrypt.NTSTATUS.STATUS_SUCCESS) + throw Interop.BCrypt.CreateCryptographicException(status); + } + } + } + } +#endif } } diff --git a/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj b/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj index ad425c6cc3819d..e284c3c841bbc4 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj +++ b/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj @@ -156,8 +156,22 @@ Link="CommonTest\System\Security\Cryptography\SP800108HmacCounterKdfTests.Helpers.cs" /> + + + + + + + + + + + source) { throw null; } + public static System.Security.Cryptography.CompositeMLDsa ImportCompositeMLDsaPublicKey(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.CompositeMLDsa ImportCompositeMLDsaPublicKey(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.CompositeMLDsa ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.CompositeMLDsa ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source) { throw null; } @@ -598,18 +600,18 @@ protected virtual void Dispose(bool disposing) { } public static System.Security.Cryptography.CompositeMLDsa ImportSubjectPublicKeyInfo(System.ReadOnlySpan source) { throw null; } public static bool IsAlgorithmSupported(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm) { throw null; } public byte[] SignData(byte[] data, byte[]? context = null) { throw null; } + public int SignData(System.ReadOnlySpan data, System.Span destination, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } + protected abstract int SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination); public bool TryExportCompositeMLDsaPrivateKey(System.Span destination, out int bytesWritten) { throw null; } - protected abstract bool TryExportCompositeMLDsaPrivateKeyCore(System.ReadOnlySpan destination, out int bytesWritten); + protected abstract bool TryExportCompositeMLDsaPrivateKeyCore(System.Span destination, out int bytesWritten); public bool TryExportCompositeMLDsaPublicKey(System.Span destination, out int bytesWritten) { throw null; } - protected abstract bool TryExportCompositeMLDsaPublicKeyCore(System.ReadOnlySpan destination, out int bytesWritten); + protected abstract bool TryExportCompositeMLDsaPublicKeyCore(System.Span destination, out int bytesWritten); public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportEncryptedPkcs8PrivateKey(string password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportPkcs8PrivateKey(System.Span destination, out int bytesWritten) { throw null; } protected abstract bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten); public bool TryExportSubjectPublicKeyInfo(System.Span destination, out int bytesWritten) { throw null; } - public bool TrySignData(System.ReadOnlySpan data, System.Span destination, out int bytesWritten, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } - protected abstract bool TrySignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination, out int bytesWritten); public bool VerifyData(byte[] data, byte[] signature, byte[]? context = null) { throw null; } public bool VerifyData(System.ReadOnlySpan data, System.ReadOnlySpan signature, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } protected abstract bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature); diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index 88f15f22fa5654..f159f6ba522706 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -141,15 +141,15 @@ The specified private seed is not the correct length for the ML-KEM algorithm. + + The private key is not the correct size for the indicated algorithm. + The public key is not the correct size for the indicated algorithm. The secret key is not the correct size for the indicated algorithm. - - The private key is too short for the indicated algorithm. - The private seed is not the correct size for the indicated algorithm. @@ -327,6 +327,9 @@ The specified CipherMode '{0}' is not supported. + + Composite signature generation failed due to an error in one or both of the components. + Concurrent operations from multiple threads on this type are not supported. diff --git a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj index b90ce60810e4d9..9a20a59f785336 100644 --- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj @@ -382,8 +382,8 @@ Link="Common\System\Security\Cryptography\CompositeMLDsa.cs" /> - + + + @@ -823,6 +826,8 @@ Link="Common\Interop\Browser\Interop.Libraries.cs" /> + + + + + + + memory) => memory.Span.ToUnsignedIntegerBytes(); + + internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory, int length) + { + if (memory.Length == length) + { + return memory.ToArray(); + } + + ReadOnlySpan span = memory.Span; + + if (memory.Length == length + 1) + { + if (span[0] == 0) + { + return span.Slice(1).ToArray(); + } + } + + if (span.Length > length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + byte[] target = new byte[length]; + span.CopyTo(target.AsSpan(length - span.Length)); + return target; + } + + internal static byte[] ExportKeyParameter(this BigInteger value, int length) + { + byte[] target = new byte[length]; + + if (value.TryWriteBytes(target, out int bytesWritten, isUnsigned: true, isBigEndian: true)) + { + if (bytesWritten < length) + { + Buffer.BlockCopy(target, 0, target, length - bytesWritten, bytesWritten); + target.AsSpan(0, length - bytesWritten).Clear(); + } + + return target; + } + + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs index 3986c70142ef68..903fd1c92e9594 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs @@ -46,6 +46,27 @@ internal static partial bool SupportsAny() => Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa65 != null || Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa87 != null; + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm) + { + if (algorithm == MLDsaAlgorithm.MLDsa44) + { + return Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa44 != null; + } + else if (algorithm == MLDsaAlgorithm.MLDsa65) + { + return Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa65 != null; + } + else if (algorithm == MLDsaAlgorithm.MLDsa87) + { + return Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa87 != null; + } + else + { + Debug.Fail($"Unexpected algorithm: {algorithm}"); + return false; + } + } + internal SafeEvpPKeyHandle DuplicateHandle() { return _key.DuplicateHandle(); diff --git a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj index c9de581f8160b3..44ff86f081339d 100644 --- a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj +++ b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj @@ -271,8 +271,22 @@ Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\AES\AesFactory.cs" /> + + + + + + + +