// The Main function of the program static void Main(string[] args) { // Initializes the Stopwatch used for time meassurements concerning the keyExchange. This stopwatch will be stopped at severel points, for example before printing text. Stopwatch SWForDHKE = new Stopwatch(); for (int p = 0; p < 500; p++) { SWForDHKE.Start(); // Decleration of the variables used by Person1 and Person2 Byte[] Person1PublicKey; Byte[] Person2PublicKey; Byte[] Person1SharedKey; Byte[] Person2SharedKey; SWForDHKE.Stop(); // Initializes the Stopwatch used for time meassurements concerning keyGeneration. Stopwatch SWForKeyGenration = new Stopwatch(); // Initialization of the Keysize for both the public and private keys int keySize = 521; SWForDHKE.Start(); // Sets the secret message that is going to be encrypted and decrypted by respectively Person1 and Person2 String secretMessage = "The secret message"; SWForDHKE.Stop(); SWForDHKE.Start(); // Starts the timer so we can see how long it takes for to genrate a random keyPair SWForKeyGenration.Start(); // Creates a CNG (Cryptography Next Genration) implimentiation of the ECDH (Elliptic Curve Diffie-Hellman) algorithm for Person1 with a randomly generated keyPair consisting of both a public and a private key using (ECDiffieHellmanCng ECDHCNGForPerson1 = new ECDiffieHellmanCng(keySize)) { // Stops the timer, as the keys have now been generated SWForKeyGenration.Stop(); SWForDHKE.Stop(); // Prints the time it took to generate the random keyPair Write("It took " + SWForKeyGenration.ElapsedMilliseconds + " milliseconds to generate a random key pair." + Environment.NewLine); Write("It took " + SWForKeyGenration.ElapsedTicks + " ticks to generate a random key pair." + Environment.NewLine + Environment.NewLine); // Prints Person1s private key, which is printed in a big-endian format Write("Person 1s private key is: "); foreach (Byte b in ECDHCNGForPerson1.ExportExplicitParameters(true).D) { Write($"{b} "); } Write(Environment.NewLine + Environment.NewLine); SWForDHKE.Start(); // Sets the method used for deriving the different shared keys as an ECDH-hash-function ECDHCNGForPerson1.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; // Sets the hashing algorithm used as the Sha256 algorithm ECDHCNGForPerson1.HashAlgorithm = CngAlgorithm.Sha256; // Sets Person1s public key as the public key generated by the ECDHCNG for Person1 Person1PublicKey = ECDHCNGForPerson1.PublicKey.ToByteArray(); SWForDHKE.Stop(); // Prints the contents of Person1s public key Write("Person 1s public key is: " + Environment.NewLine); foreach (Byte b in Person1PublicKey) { Write($"{b} "); } Write(Environment.NewLine + Environment.NewLine); SWForDHKE.Start(); // Creates a CNG (Cryptography Next Genration) implimentiation of the ECDH (Elliptic Curve Diffie-Hellman) algorithm for Person2 with a randomly generated keyPair consisting of both a public and a private key using (ECDiffieHellmanCng ECDHCNGForPerson2 = new ECDiffieHellmanCng(keySize)) { SWForDHKE.Stop(); // Prints Person2s private key, which is printed in a big-endian format Write("Person 2s private key is: "); foreach (Byte b in ECDHCNGForPerson2.ExportExplicitParameters(true).D) { Write($"{b} "); } Write(Environment.NewLine + Environment.NewLine); // Sets the method used for deriving the different shared keys as an ECDH-hash-function ECDHCNGForPerson2.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; // Sets the hashing algorithm used as the Sha256 algorithm ECDHCNGForPerson2.HashAlgorithm = CngAlgorithm.Sha256; // Sets Person2s public key as the public key generated by the ECDHCNG for Person2 Person2PublicKey = ECDHCNGForPerson2.PublicKey.ToByteArray(); SWForDHKE.Stop(); // Prints the contents of Person2s public key Write("Person 2s public key is: " + Environment.NewLine); foreach (Byte b in Person2PublicKey) { Write($"{b} "); } Write(Environment.NewLine + Environment.NewLine); SWForDHKE.Start(); // Sets the key used for deriving the shared key to the contents of Person1s public key, and this is used by Person1 CngKey k2 = CngKey.Import(Person1PublicKey, CngKeyBlobFormat.EccPublicBlob); // Creates the shared key that Person2 uses to the shared key derived from a key exchange Person2SharedKey = ECDHCNGForPerson2.DeriveKeyMaterial(k2); } // Sets the key used for deriving the shared key to the contents of Person2s public key, and this is used by Person1 CngKey k1 = CngKey.Import(Person2PublicKey, CngKeyBlobFormat.EccPublicBlob); // Creates the shared key that Person1 uses to the shared key derived from a key exchange Person1SharedKey = ECDHCNGForPerson1.DeriveKeyMaterial(k1); SWForDHKE.Stop(); // Prints the contents of both shared keys Write("Person 1s shared key is: " + Environment.NewLine); foreach (Byte b in Person1SharedKey) { Write($"{b} "); } Write(Environment.NewLine + Environment.NewLine); Write("Person 2s shared key is: " + Environment.NewLine); foreach (Byte b in Person2SharedKey) { Write($"{b} "); } Write(Environment.NewLine + Environment.NewLine); SWForDHKE.Start(); // Sends the secret message from Person1 using Person1s shared key to Person2 Send(Person1SharedKey, secretMessage, out Byte[] encryptedMessage, out Byte[] IV);