Skip to main content

Kyber Key Exchange Examples

Purpose

The objective of an MTE Kyber "Examples" is to provide a short example of basic MTE Kyber actions.

Simple demonstration of Kyber within one application.

using System;
using System.Globalization;
using System.Text;

namespace Eclypses.MTE {
class Program {

//*******************************************************************
// Helper function to convert a byte array to a hex string.
//
// Overview: convert a byte array to an ASCII hex representation
// Input: pointer to the input byte array
// length of the input byte array
// pointer to the output byte array
// size of the output byte array
// Output: pointer to the output byte array (convenience result)
//*******************************************************************
private static string BytesToHex(byte[] input) {
const string hex = "0123456789ABCDEF";
StringBuilder sb = new();
sb.Clear();
int i = 0;
while (i < input.Length) {
sb.Append(hex[(input[i] >> 4) & 0xF]);
sb.Append(hex[input[i] & 0xF]);
i++;
}
return sb.ToString();
}

private static byte[] publicKey;
private static byte[] encrypted;
private static byte[] secret;
private static byte[] secret2;

/*****************************************************
* Implementation of an application defined callback
* which is used to generate entropy for ecdhB and
* also to test the "zeroize" and "getRandom" methods.
****************************************************/
public class KyberCallback : IMteKyberEntropyCallback {
public unsafe int EntropyCallback(byte[] entropyInput, UInt32* entropySize, UInt32 minEntropySize, UInt32 maxEntropySize) {

Array.Fill(entropyInput, (byte)0xCC);
MteKyber.Zeroize(entropyInput);
for (int i = 0; i < entropyInput.Length; i++)
if (entropyInput[i] != 0)
return MteKyber.MemoryFail;
// Get random bytes.
byte[] temp = MteRandom.GetBytes((uint)minEntropySize);
if (temp.Length == 0) {
return MteKyber.EntropyFail;
}

*entropySize = (uint)temp.Length;

Array.Copy(temp, entropyInput, temp.Length);
return MteKyber.Success;
}
}

/*************************************************
* Main program.
************************************************/
static int Main() {
Console.WriteLine("Eclypses Kyber Demo Driver\n");
Console.WriteLine("-------------------------------------------------------\n\n");

// Init Kyber.
if (MteKyber.Init(MteKyber.KyberStrength.K512) == MteKyber.Success) {
bool stillValid = true;

// Create Kyber initiator.
MteKyber initiator = new MteKyber();

// Create keys with the initiator.
Console.WriteLine("Create key pair with the initiator:");
publicKey = new byte[MteKyber.PublicKeySize];
if (initiator.CreateKeyPair(publicKey) != MteKyber.Success) {
Console.WriteLine("Failed to create the key pair with the initiator.");
stillValid = false;
}

// Create Kyber responder.
MteKyber responder = new MteKyber();
KyberCallback kyberCallback = new();
responder.SetEntropyCallback(kyberCallback);

if (stillValid) {
string s = BytesToHex(publicKey);
Console.WriteLine("Public: {0}", s[..(Int32)MteKyber.PublicKeySize]);
Console.WriteLine(" {0}", s[(Int32)MteKyber.PublicKeySize..]);

encrypted = new byte[MteKyber.EncryptedSize];
secret = new byte[MteKyber.SecretSize];

// Use the responder to encrypt the peer public key, to get the encrypted and shared secret.
Console.WriteLine("Create secret with the responder:");
if (responder.CreateSecret(publicKey, secret, encrypted) != MteKyber.Success) {
Console.WriteLine("There was a problem attempting to create the secret with the responder.");
stillValid = false;
}
}

if (stillValid) {
Console.WriteLine("Secret from the responder:");
Console.WriteLine(BytesToHex(secret));

secret2 = new byte[MteKyber.SecretSize];

// Use the initiator to decrypt the encrypted output from the responder.
Console.WriteLine("Decrypt with the initiator:");
if (initiator.DecryptSecret(encrypted, secret2) != MteKyber.Success) {
Console.WriteLine("There was a problem attempting to decrypt the secret with the initiator.");
stillValid = false;
}
}

if (stillValid) {
Console.WriteLine("Secret from the initiator:");
Console.WriteLine(BytesToHex(secret2));

// Compare the secrets.
Console.Write("Compare secrets: ");
if (!secret.SequenceEqual(secret2)) {
Console.WriteLine("No match");
} else {
Console.WriteLine("Match");
}
}
} else {
Console.WriteLine("Kyber was not initiated with a valid strength value.");
}

return 0;
}
}
}