Ejemplo n.º 1
0
        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
         });
     }
 }
Ejemplo n.º 3
0
        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");
        }