diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs
index e5fc7bbbc21cc3..c058daab3bb2e3 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs
@@ -1,6 +1,7 @@
// 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.Diagnostics.CodeAnalysis;
namespace System.Security.Cryptography
@@ -8,8 +9,9 @@ namespace System.Security.Cryptography
///
/// Represents a specific algorithm within the ML-DSA family.
///
+ [DebuggerDisplay("{Name,nq}")]
[Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
- public sealed class MLDsaAlgorithm
+ public sealed class MLDsaAlgorithm : IEquatable
{
///
/// Gets the underlying string representation of the algorithm name.
@@ -117,5 +119,60 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI
_ => null,
};
}
+
+ ///
+ /// Compares two objects.
+ ///
+ ///
+ /// An object to be compared to the current object.
+ ///
+ ///
+ /// if the objects are considered equal; otherwise, .
+ ///
+ // This is a closed type, so all we need to compare are the names.
+ public bool Equals([NotNullWhen(true)] MLDsaAlgorithm? other) => other is not null && other.Name == Name;
+
+ ///
+ public override bool Equals([NotNullWhen(true)] object? obj) => obj is MLDsaAlgorithm alg && alg.Name == Name;
+
+ ///
+ public override int GetHashCode() => Name.GetHashCode();
+
+ ///
+ public override string ToString() => Name;
+
+ ///
+ /// Determines whether two objects specify the same algorithm name.
+ ///
+ ///
+ /// An object that specifies an algorithm name.
+ ///
+ ///
+ /// A second object, to be compared to the object that is identified by the parameter.
+ ///
+ ///
+ /// if the objects are considered equal; otherwise, .
+ ///
+ public static bool operator ==(MLDsaAlgorithm? left, MLDsaAlgorithm? right)
+ {
+ return left is null ? right is null : left.Equals(right);
+ }
+
+ ///
+ /// Determines whether two objects do not specify the same algorithm name.
+ ///
+ ///
+ /// An object that specifies an algorithm name.
+ ///
+ ///
+ /// A second object, to be compared to the object that is identified by the parameter.
+ ///
+ ///
+ /// if the objects are not considered equal; otherwise, .
+ ///
+ public static bool operator !=(MLDsaAlgorithm? left, MLDsaAlgorithm? right)
+ {
+ return !(left == right);
+ }
}
}
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/MLDsaAlgorithmTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/MLDsaAlgorithmTests.cs
new file mode 100644
index 00000000000000..7bbe01af87f2ee
--- /dev/null
+++ b/src/libraries/Common/tests/System/Security/Cryptography/MLDsaAlgorithmTests.cs
@@ -0,0 +1,75 @@
+// 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.Globalization;
+using Microsoft.DotNet.XUnitExtensions;
+using Xunit;
+
+namespace System.Security.Cryptography.Tests
+{
+ public static class MLDsaAlgorithmTests
+ {
+ [Fact]
+ public static void Algorithms_AreSame()
+ {
+ Assert.Same(MLDsaAlgorithm.MLDsa44, MLDsaAlgorithm.MLDsa44);
+ Assert.Same(MLDsaAlgorithm.MLDsa65, MLDsaAlgorithm.MLDsa65);
+ Assert.Same(MLDsaAlgorithm.MLDsa87, MLDsaAlgorithm.MLDsa87);
+ }
+
+ [Theory]
+ [MemberData(nameof(MLDsaAlgorithms))]
+ public static void Algorithms_Equal(MLDsaAlgorithm algorithm)
+ {
+ AssertExtensions.TrueExpression(algorithm.Equals(algorithm));
+ AssertExtensions.TrueExpression(algorithm.Equals((object)algorithm));
+ AssertExtensions.FalseExpression(algorithm.Equals(null));
+ }
+
+ [Theory]
+ [MemberData(nameof(MLDsaAlgorithms))]
+ public static void Algorithms_GetHashCode(MLDsaAlgorithm algorithm)
+ {
+ Assert.Equal(algorithm.Name.GetHashCode(), algorithm.GetHashCode());
+ }
+
+ [Fact]
+ public static void Algorithms_Equality()
+ {
+ AssertExtensions.TrueExpression(MLDsaAlgorithm.MLDsa44 == MLDsaAlgorithm.MLDsa44);
+ AssertExtensions.TrueExpression(MLDsaAlgorithm.MLDsa65 == MLDsaAlgorithm.MLDsa65);
+ AssertExtensions.TrueExpression(MLDsaAlgorithm.MLDsa87 == MLDsaAlgorithm.MLDsa87);
+
+ AssertExtensions.FalseExpression(MLDsaAlgorithm.MLDsa44 == MLDsaAlgorithm.MLDsa65);
+ AssertExtensions.FalseExpression(MLDsaAlgorithm.MLDsa65 == MLDsaAlgorithm.MLDsa87);
+ AssertExtensions.FalseExpression(MLDsaAlgorithm.MLDsa87 == MLDsaAlgorithm.MLDsa44);
+ }
+
+ [Fact]
+ public static void Algorithms_Inequality()
+ {
+ AssertExtensions.FalseExpression(MLDsaAlgorithm.MLDsa44 != MLDsaAlgorithm.MLDsa44);
+ AssertExtensions.FalseExpression(MLDsaAlgorithm.MLDsa65 != MLDsaAlgorithm.MLDsa65);
+ AssertExtensions.FalseExpression(MLDsaAlgorithm.MLDsa87 != MLDsaAlgorithm.MLDsa87);
+
+ AssertExtensions.TrueExpression(MLDsaAlgorithm.MLDsa44 != MLDsaAlgorithm.MLDsa65);
+ AssertExtensions.TrueExpression(MLDsaAlgorithm.MLDsa65 != MLDsaAlgorithm.MLDsa87);
+ AssertExtensions.TrueExpression(MLDsaAlgorithm.MLDsa87 != MLDsaAlgorithm.MLDsa44);
+ }
+
+ [Theory]
+ [MemberData(nameof(MLDsaAlgorithms))]
+ public static void Algorithms_ToString(MLDsaAlgorithm algorithm)
+ {
+ Assert.Equal(algorithm.Name, algorithm.ToString());
+ }
+
+ public static IEnumerable