Skip to main content

entropy_nonce_timestamp

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace MTE {
class CallbackSample {

class Cbs : MteEntropyCallback, MteNonceCallback, MteTimestampCallback {
~Cbs() {
if (myEntropyHandle.IsAllocated) {
myEntropyHandle.Free();
}
}

// Callbacks that will get entropy, nonce, and timestamp from stdin.
// THIS IS NOT A SECURE WAY TO CAPTURE THESE ITEMS AND IS ONLY FOR
// DEMONSTRATION PURPOSES.
public MteStatus EntropyCallback(int minEntropy,
int minLength,
UInt64 maxLength,
byte[] entropyInput,
ref UInt64 eiBytes,
out IntPtr entropyLong) {
// Set the long entropy to null in case we don't need it.
entropyLong = IntPtr.Zero;

// Display a prompt.
Console.Write("Enter {0}-{1} bytes of entropy> ", minLength, maxLength);

// Get a line of input.
string entropyStdin = Console.ReadLine();
byte[] entropy8 = UTF8Encoding.UTF8.GetBytes(entropyStdin.ToString());

// If the input was less than the minimum required, we must return an
// error.
if (entropy8.Length < minLength) {
return MteStatus.mte_status_drbg_catastrophic;
}

// Set the actual entropy length. It cannot exceed the maximum required.
int buffBytes = (int)eiBytes;
eiBytes = Math.Min((UInt64)entropy8.Length, maxLength);

// If the length is greater than the length of the provided buffer, we
// have to create our own buffer instead.
if ((int)eiBytes > buffBytes) {
if (myEntropyHandle.IsAllocated) {
myEntropyHandle.Free();
}
myEntropyHandle = GCHandle.Alloc(entropy8, GCHandleType.Pinned);
entropyLong = myEntropyHandle.AddrOfPinnedObject();
} else {
// Copy the entropy to the buffer and we got it successfully.
Array.Copy(entropy8, entropyInput, (int)eiBytes);
}

// Success.
return MteStatus.mte_status_success;
}
public void NonceCallback(int minLength,
int maxLength,
byte[] nonce,
out int nBytes) {

// Display a prompt.
Console.Write("Enter the nonce (decimal digits only)> ");

// Get the nonce.
UInt64 u64 = Convert.ToUInt64(Console.ReadLine());

// Copy the nonce in little-endian format to the nonce buffer.
int nCopied = Math.Min(nonce.Length, sizeof(UInt64));
for (int i = 0; i < nCopied; ++i) {
nonce[i] = (byte)(u64 >> (i * 8));
}

// If the minimum length is greater than the size of the nonce we got,
// fill up to that length with zeros.
if (nCopied < minLength) {
for (int i = nCopied; i < minLength; ++i) {
nonce[i] = 0;
}
nBytes = minLength;
} else {
nBytes = nCopied;
}
}
public UInt64 TimestampCallback() {

// Display a prompt.
Console.Write("Enter the timestamp (decimal digits only)> ");

// Get the timestamp.
string timestampStr = Console.ReadLine();
return Convert.ToUInt64(timestampStr);
}
private GCHandle myEntropyHandle;
}

// The timestamp window and sequencing window
private const UInt64 timestampWindow = 1;
private const Int32 sequenceWindow = 0;

static int Main(string[] args) {
// Status.
MteStatus status = MteStatus.mte_status_success;

// Options.
MteDrbgs drbg;
int tokBytes;
MteVerifiers verifiers;

// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped. This demo attempts to load the license
// info from the environment if required.
MteBase baseObj = new MteBase();
if (!baseObj.InitLicense("YOUR_COMPANY", "YOUR_LICENSE")) {
string company = Environment.GetEnvironmentVariable("MTE_COMPANY");
string license = Environment.GetEnvironmentVariable("MTE_LICENSE");
if (company == null || license == null ||
!baseObj.InitLicense(company, license)) {
status = MteStatus.mte_status_license_error;
Console.Error.WriteLine("License init error ({0}): {1}",
baseObj.GetStatusName(status),
baseObj.GetStatusDescription(status));
return (int)status;
}
}

// Get the input data.
Console.Write("Enter the data to encode> ");
string input = Console.ReadLine();

// Get the personalization string.
Console.Write("Enter the personalization> ");
string personal = Console.ReadLine();

// Set up the options to use the buildtime options if the library is built
// for that; otherwise prompt for the options.
if (baseObj.HasRuntimeOpts()) {
// Get the DRBG.
Console.Write("DRBGs:");
for (int i = 1; i < baseObj.GetDrbgsCount(); ++i) {
Console.Write(" {0}", baseObj.GetDrbgsName((MteDrbgs)i));
}
Console.WriteLine();
Console.Write("Enter the DRBG> ");
drbg = baseObj.GetDrbgsAlgo(Console.ReadLine());

// Get the token size.
Console.Write("Enter the token size in bytes> ");
tokBytes = Convert.ToInt32(Console.ReadLine());

// Get the verifiers.
Console.Write("Verifiers:");
for (int i = 0; i < baseObj.GetVerifiersCount(); ++i) {
Console.Write(" {0}", baseObj.GetVerifiersName((MteVerifiers)i));
}
Console.WriteLine();
Console.Write("Enter the verifiers> ");
verifiers = baseObj.GetVerifiersAlgo(Console.ReadLine());
} else {
drbg = baseObj.GetDefaultDrbg();
tokBytes = baseObj.GetDefaultTokBytes();
verifiers = baseObj.GetDefaultVerifiers();
}

// Create the callbacks to get entropy, nonce, and timestamp from stdin.
Cbs cbs = new Cbs();

// Create the Encoder.
MteEnc encoder = new MteEnc(drbg, tokBytes, verifiers);
encoder.SetEntropyCallback(cbs);
encoder.SetNonceCallback(cbs);
encoder.SetTimestampCallback(cbs);
status = encoder.Instantiate(personal);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Encoder instantiate error ({0}): {1}",
encoder.GetStatusName(status),
encoder.GetStatusDescription(status));
return (int)status;
}

// Encode the input.
string encoded = encoder.EncodeB64(input, out status);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Encode error ({0}): {1}",
encoder.GetStatusName(status),
encoder.GetStatusDescription(status));
return (int)status;
}

// Display the encoded message.
Console.WriteLine("Base64 message: {0}", encoded);

// Create the Decoder.
MteDec decoder = new MteDec(drbg,
tokBytes,
verifiers,
timestampWindow,
sequenceWindow);
decoder.SetEntropyCallback(cbs);
decoder.SetNonceCallback(cbs);
decoder.SetTimestampCallback(cbs);
status = decoder.Instantiate(personal);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decoder instantiate error ({0}): {1}",
decoder.GetStatusName(status),
decoder.GetStatusDescription(status));
return (int)status;
}

// Decode the message.
string decoded = decoder.DecodeStrB64(encoded, out status);
if (decoder.StatusIsError(status)) {
Console.Error.WriteLine("Decode error ({0}): {1}",
decoder.GetStatusName(status),
decoder.GetStatusDescription(status));
return (int)status;
} else if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decode warning ({0}): {1}",
decoder.GetStatusName(status),
decoder.GetStatusDescription(status));
}

// Output the decoded data.
Console.WriteLine("Decoded data: {0}", decoded);

// Output decode info.
Console.WriteLine("Encode timestamp: {0}", decoder.GetEncTs());
Console.WriteLine("Decode timestamp: {0}", decoder.GetDecTs());
Console.WriteLine("Messages skipped: {0}", decoder.GetMsgSkipped());

// Compare the decoded data against the original data.
if (decoded == input) {
Console.WriteLine("The original data and decoded data match.");
} else {
Console.WriteLine("The original data and decoded data DO NOT match.");
return -1;
}

// Success.
return 0;
}
}
}