idempotency: Add more tests.
ADD
WalletWasabi.Tests/UnitTests/WabiSabi/Crypto/CredentialRequesting/RealCredentialsRequestTests.cs
+using NBitcoin.Secp256k1;
+using WalletWasabi.Crypto;
+using WalletWasabi.Crypto.Groups;
+using WalletWasabi.Crypto.ZeroKnowledge;
+using WalletWasabi.WabiSabi.Crypto;
+using WalletWasabi.WabiSabi.Crypto.CredentialRequesting;
+using Xunit;
+
+namespace WalletWasabi.Tests.UnitTests.WabiSabi.Crypto.CredentialRequesting
+{
+ /// <summary>
+ /// Tests for <see cref="RealCredentialsRequest"/> class.
+ /// </summary>
+ public class RealCredentialsRequestTests
+ {
+ [Fact]
+ public void EqualityTest()
+ {
+ // Request #1.
+ RealCredentialsRequest request1 = NewRealCredentialsRequest(1);
+
+ //// Request #2.
+ RealCredentialsRequest request2 = NewRealCredentialsRequest(1);
+
+ Assert.Equal(request1, request2);
+
+ //// Request #3.
+ RealCredentialsRequest request3 = NewRealCredentialsRequest(2);
+ Assert.NotEqual(request1, request3);
+ }
+
+ private static GroupElement NewGroupElement(int i) => Generators.FromText($"T{i}");
+
+ /// <param name="modifier">Modifier so that we generate a different request if we want.</param>
+ private static RealCredentialsRequest NewRealCredentialsRequest(int modifier) =>
+ new(
+ 123456L,
+ new[] { new CredentialPresentation(NewGroupElement(7), NewGroupElement(7), NewGroupElement(7), NewGroupElement(7), NewGroupElement(7)) },
+ new[] { new IssuanceRequest(ma: NewGroupElement(modifier * 1), bitCommitments: new GroupElement[] { NewGroupElement(2), NewGroupElement(3) }) },
+ new[] { new Proof(new GroupElementVector(NewGroupElement(13)), new ScalarVector(new Scalar(5))) });
+ }
+}

ADD
WalletWasabi.Tests/UnitTests/WabiSabi/Crypto/CredentialRequesting/ZeroCredentialsRequestTests.cs
+using NBitcoin.Secp256k1;
+using System.Linq;
+using WalletWasabi.Crypto;
+using WalletWasabi.Crypto.Groups;
+using WalletWasabi.Crypto.ZeroKnowledge;
+using WalletWasabi.WabiSabi.Crypto;
+using WalletWasabi.WabiSabi.Crypto.CredentialRequesting;
+using Xunit;
+
+namespace WalletWasabi.Tests.UnitTests.WabiSabi.Crypto.CredentialRequesting
+{
+ /// <summary>
+ /// Tests for <see cref="ZeroCredentialsRequest"/> class.
+ /// </summary>
+ public class ZeroCredentialsRequestTests
+ {
+ [Fact]
+ public void EqualityTest()
+ {
+ // Request #1.
+ ZeroCredentialsRequest request1 = GetZeroCredentialsRequest(1);
+
+ //// Request #2.
+ ZeroCredentialsRequest request2 = GetZeroCredentialsRequest(1);
+
+ Assert.Equal(request1, request2);
+
+ //// Request #3.
+ ZeroCredentialsRequest request3 = GetZeroCredentialsRequest(2);
+ Assert.NotEqual(request1, request3);
+ }
+
+ private static GroupElement NewGroupElement(int i) => Generators.FromText($"T{i}");
+
+ private static GroupElementVector NewGroupElementVector(params int[] arr) => new(arr.Select(i => NewGroupElement(i)));
+
+ private static ScalarVector NewScalarVector(params uint[] arr) => new(arr.Select(i => new Scalar(i)));
+
+ /// <remarks>Each instance represents the same request but a new object instance.</remarks>
+ private static ZeroCredentialsRequest GetZeroCredentialsRequest(int modifier = 1)
+ {
+ IssuanceRequest[] requested = new IssuanceRequest[]
+ {
+ new IssuanceRequest(ma: NewGroupElement(modifier * 1), bitCommitments: new GroupElement[] { NewGroupElement(2), NewGroupElement(3) })
+ };
+
+ return new(requested,
+ new Proof[] { new Proof(publicNonces: NewGroupElementVector(1, 2), responses: NewScalarVector(6, 7)) });
+ }
+ }
+}

ADD
WalletWasabi.Tests/UnitTests/WabiSabi/Crypto/OwnershipProofTests.cs
+using NBitcoin;
+using WalletWasabi.Crypto;
+using WalletWasabi.Tests.Helpers;
+using Xunit;
+
+namespace WalletWasabi.Tests.UnitTests.WabiSabi.Crypto
+{
+ /// <summary>
+ /// Tests for <see cref="OwnershipProof"/> class.
+ /// </summary>
+ public class OwnershipProofTests
+ {
+ [Fact]
+ public void EqualityTest()
+ {
+ using Key key = new();
+ uint256 roundHash = BitcoinFactory.CreateUint256();
+
+ // Request #1.
+ OwnershipProof request1 = CreateOwnershipProof(key, roundHash);
+
+ //// Request #2.
+ OwnershipProof request2 = CreateOwnershipProof(key, roundHash);
+
+ Assert.Equal(request1, request2);
+
+ //// Request #3.
+ using Key key2 = new();
+ OwnershipProof request3 = CreateOwnershipProof(key2, roundHash); // Key intentionally changed.
+ Assert.NotEqual(request1, request3);
+
+ //// Request #4.
+ OwnershipProof request4 = CreateOwnershipProof(key, roundHash: BitcoinFactory.CreateUint256()); // Round hash intentionally changed.
+ Assert.NotEqual(request1, request4);
+ }
+
+ /// <remarks>Each instance represents the same proof but a new object instance.</remarks>
+ public static OwnershipProof CreateOwnershipProof(Key key, uint256 roundHash)
+ => OwnershipProof.GenerateCoinJoinInputProof(
+ key,
+ new OwnershipIdentifier(Key.Parse("5KbdaBwc9Eit2LrmDp1WfZd815StNstwHanbRrPpGGN6wWJKyHe", Network.Main), key.PubKey.WitHash.ScriptPubKey),
+ new CoinJoinInputCommitmentData("CoinJoinCoordinatorIdentifier", roundHash));
+ }
+}

idempotency: Add more tests.