The X25519 elliptic-curve Diffie-Hellman algorithm is used heavily where security is paramount, and is currently in use in a number of critical infrastructural components:

It is, technically, available in .NET 10, but requires a bit of elbow grease to correctly configure and use.

using (var alice = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256))
{
  using (var bob = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256))
  {
      // Get alice's secret in a byte array
      var aliceSecret = alice.DeriveKeyMaterial(bob.PublicKey);
      // Get bob's secret in a byte array
      var bobSecret = bob.DeriveKeyMaterial(alice.PublicKey);

      // verify the secrets match
      var match = CryptographicOperations.FixedTimeEquals(aliceSecret, bobSecret);
      Console.WriteLine(match);
  }
}

This should print true.

A couple of things to note here:

  • You are responsible for creating the ECDH infrastucture yourself
  • The static Create method requires specification of an appropriate curve. The one you choose matters

This has been simplified in .NET 11, where a dedicated type has been introduced for this function.

The equivalent code is as follows:

// Generate key pairs for alice
using (var alice = X25519DiffieHellman.GenerateKey())
{
  // Generate key pairs for bob
  using (var bob = X25519DiffieHellman.GenerateKey())
  {
    // get alice's secret with bob's key
    byte[] aliceShared = alice.DeriveRawSecretAgreement(bob);
    // get boob's secret with alice's key
    byte[] bobShared = bob.DeriveRawSecretAgreement(alice);
    // Check if they are equal
    Console.WriteLine(CryptographicOperations.FixedTimeEquals(aliceShared, bobShared));
  }
}

Purists would use using declarations and write the code as follows:

// Generate key pairs for alice
using var alice = X25519DiffieHellman.GenerateKey();
// Generate key pairs for bob
using var bob = X25519DiffieHellman.GenerateKey();
// get alice's secret with bob's key
byte[] aliceShared = alice.DeriveRawSecretAgreement(bob);
// get boob's secret with alice's key
byte[] bobShared = bob.DeriveRawSecretAgreement(alice);
// Check if they are equal
Console.WriteLine(CryptographicOperations.FixedTimeEquals(aliceShared, bobShared));

Personally, I prefer the previous because I can visually see the scope. The choice is yours!

TLDR

.NET 11 simplifies working with X25519 elliptic-curve Diffie-Hellman operations.

The code is in my GitHub,

Happy hacking!