static void example_kem() { Console.WriteLine("Starting KEM example"); // get the list of enabled KEM mechanisms Console.WriteLine("Enabled KEM mechanisms: "); foreach (string alg in KEM.EnabledMechanisms) { Console.WriteLine(" - " + alg); } // Instantiate the client and server using (KEM client = new KEM("Kyber512"), server = new KEM("Kyber512")) { Console.WriteLine("Perform key exchange with Kyber512 mechanism"); // Print out some info about the mechanism Console.WriteLine("Mechanism details:"); Console.WriteLine(" - Alg name: " + client.AlgorithmName); Console.WriteLine(" - Alg version: " + client.AlgorithmVersion); Console.WriteLine(" - Claimed NIST level: " + client.ClaimedNistLevel); Console.WriteLine(" - Is IND-CCA?: " + client.IsIndCCA); Console.WriteLine(" - Secret key length: " + client.SecretKeyLength); Console.WriteLine(" - Public key length: " + client.PublicKeyLength); Console.WriteLine(" - Ciphertext length: " + client.CiphertextLength); Console.WriteLine(" - Shared secret length: " + client.SharedSecretLength); // Generate the client's key pair byte[] public_key; byte[] secret_key; client.keypair(out public_key, out secret_key); // The client sends the public key to the server // The server generates and encapsulates the shared secret byte[] ciphertext; byte[] server_shared_secret; server.encaps(out ciphertext, out server_shared_secret, public_key); // The server sends the ciphertext to the client // The client decapsulates the shared secret byte[] client_shared_secret; client.decaps(out client_shared_secret, ciphertext, secret_key); // The client and server now share a secret. Let's make sure it matches. if (server_shared_secret.SequenceEqual(client_shared_secret)) { Console.WriteLine("KEM completed successfully"); Console.WriteLine(); } else { Console.WriteLine("Error: shared secrets do not match!"); } } }
public async Task <ClientSharedSecret> DecapsulateSharedSecret([FromBody] SecretKey secretKey) { // The client decapsulates the shared secret byte[] clientSharedSecret; using (KEM client = new KEM(secretKey.KeyMechanism)) { byte[] secret_key; client.decaps(out clientSharedSecret, secretKey.CipherText, secretKey.Key); return(new ClientSharedSecret() { SharedSecret = clientSharedSecret }); } }
private static void TestKEM(string kemAlg) { byte[] public_key; byte[] secret_key; byte[] ciphertext; byte[] shared_secret_1; byte[] shared_secret_2; Random random = new Random(); // successful case KEM kem = new KEM(kemAlg); if (kemAlg != "DEFAULT") { Assert.AreEqual(kem.AlgorithmName, kemAlg); } Assert.IsTrue(kem.IsUsable, "IsUsable after constructor"); kem.keypair(out public_key, out secret_key); log("public_key: " + BytesToHex(public_key)); log("secret_key: " + BytesToHex(secret_key)); Assert.IsTrue((UInt64)public_key.Length <= kem.PublicKeyLength, "public key length"); Assert.IsTrue((UInt64)secret_key.Length <= kem.SecretKeyLength, "secret key length"); kem.encaps(out ciphertext, out shared_secret_1, public_key); log("ciphertext: " + BytesToHex(ciphertext)); log("shared_secret_1: " + BytesToHex(shared_secret_1)); Assert.IsTrue((UInt64)ciphertext.Length <= kem.CiphertextLength, "ciphertext length"); Assert.IsTrue((UInt64)shared_secret_1.Length <= kem.SharedSecretLength, "shared secret length"); kem.decaps(out shared_secret_2, ciphertext, secret_key); log("shared_secret_2: " + BytesToHex(shared_secret_2)); Assert.IsTrue(shared_secret_1.SequenceEqual(shared_secret_2), "shared secrets are not equal"); // failure cases // wrong ciphertext byte[] wrong_ciphertext = new byte[ciphertext.Length]; random.NextBytes(wrong_ciphertext); log("wrong_ciphertext: " + BytesToHex(wrong_ciphertext)); try { kem.decaps(out shared_secret_2, wrong_ciphertext, secret_key); // if the wrong value didn't trigger an exception, make sure the shared secret do not match Assert.IsFalse(shared_secret_1.SequenceEqual(shared_secret_2), "wrong ciphertext, shared secrets should have been different"); } catch (OQSException) { // exception expected } // wrong secret key byte[] wrong_secret_key = new byte[secret_key.Length]; random.NextBytes(wrong_secret_key); log("wrong_secret_key: " + BytesToHex(wrong_secret_key)); try { kem.decaps(out shared_secret_2, ciphertext, wrong_secret_key); // if the wrong value didn't trigger an exception, make sure the shared secret do not match Assert.IsFalse(shared_secret_1.SequenceEqual(shared_secret_2), "wrong ciphertext, shared secrets should have been different"); } catch (OQSException) { // exception expected } // clean-up kem.Dispose(); Assert.IsFalse(kem.IsUsable, "IsUsable after cleanup"); }