MTE Sequencing Verifier Code Samples
Purpose
Samples expand on our "Examples" by providing longer snippets of code demonstrating the entire processes. The objective of an MTE Sequencing Verifier "Samples" is to provide full samples of code of how to use the MTE Sequencing functions.
The sequencing verifier only affects the MTE decoder and should be enabled when lossy or asynchronous (out-of-order) communication is possible. The verifier has three different modes of operation (verification only mode, forward only mode, and async mode), determined by the sequence window setting in the decoder. For more information, please see the official MTE developer guides.
Encoder Creation
The encoder for sequencing is going to be the same no matter which sequencing we will use. Here is a quick sample of how to create the encoder for each example below.
- C
- C++
- CSharp
- Java
- Swift
- ObjC
- Python
- Go
- TypeScript
MTE_SIZE_T i;
/* Status. */
mte_status status;
/* Inputs. */
static const char* inputs[] =
{
"message 0",
"message 1",
"message 2",
"message 3"
};
MTE_SIZE_T input_bytes = (MTE_SIZE_T)strlen(inputs[0]);
/* Personalization string. */
static const char personal[] = "demo";
/* Options. */
mte_enc_init_info e_info = MTE_ENC_INIT_INFO_INIT(
MTE_DRBG_ENUM, MTE_TOKBYTES, MTE_VERIFIERS_ENUM, NULL, NULL);
mte_dec_init_info d_info = MTE_DEC_INIT_INFO_INIT(
MTE_DRBG_ENUM, MTE_TOKBYTES, MTE_VERIFIERS_ENUM, 1, 0, NULL, NULL);
mte_drbg_inst_info i_info =
{ &ei_cb, NULL, &n_cb, NULL, personal, sizeof(personal) - 1 };
/* Encoder. */
char* encodings[sizeof(inputs) / sizeof(inputs[0])];
MTE_HANDLE encoder = MTE_ALLOCA(mte_enc_state_bytes(&e_info));
mte_enc_args e_args = MTE_ENC_ARGS_INIT(NULL, 0, NULL, &t_cb, NULL);
/* Decoder. */
char* decoded;
MTE_UINT8_T* dsaved;
MTE_HANDLE decoderA = MTE_ALLOCA(mte_dec_state_bytes(&d_info));
mte_dec_args d_args = MTE_DEC_ARGS_INIT(NULL, 0, NULL, &t_cb, NULL);
/* Licensing. */
const char* company;
const char* license;
/* Suppress unused args. */
(void)argc;
(void)argv;
/* Initialize MTE. */
if (!mte_init(NULL, NULL))
{
fputs("MTE init error.", stderr);
return -1;
}
/* 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. */
if (!mte_license_init("YOUR_COMPANY", "YOUR_LICENSE"))
{
company = getenv("MTE_COMPANY");
license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
!mte_license_init(company, license))
{
fprintf(stderr, "License init error (%s): %s\n",
mte_base_status_name(mte_status_license_error),
mte_base_status_description(mte_status_license_error));
return mte_status_license_error;
}
}
/* Create the encoder. */
status = mte_enc_state_init(encoder, &e_info);
if (status != mte_status_success)
{
fprintf(stderr, "Encoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
status = mte_enc_instantiate(encoder, &i_info);
if (status != mte_status_success)
{
fprintf(stderr, "Encoder instantiate error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
/* Encode the inputs. */
for (i = 0; i < sizeof(inputs) / sizeof(inputs[0]); ++i)
{
encodings[i] = MTE_ALLOCA(mte_enc_buff_bytes_b64(encoder, input_bytes));
MTE_SET_ENC_IO(e_args, inputs[i], input_bytes, encodings[i]);
status = mte_enc_encode_b64(encoder, &e_args);
if (status != mte_status_success)
{
fprintf(stderr, "Encode error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
encodings[i] = e_args.encoded;
printf("Encode #%u: %s -> %s\n", (unsigned)i, inputs[i], encodings[i]);
}
// Status.
mte_status status;
// Inputs.
static const std::string inputs[] =
{
"message 0",
"message 1",
"message 2",
"message 3"
};
// Personalization string.
static const std::string personal("demo");
// 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.
if (!MteBase::initLicense("YOUR_COMPANY", "YOUR_LICENSE"))
{
const char *company = getenv("MTE_COMPANY");
const char *license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
!MteBase::initLicense(company, license))
{
std::cerr << "License init error ("
<< MteBase::getStatusName(mte_status_license_error)
<< "): "
<< MteBase::getStatusDescription(mte_status_license_error)
<< std::endl;
return mte_status_license_error;
}
}
// Create the encoder.
MteEnc encoder;
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
size_t entropyBytes = MteBase::getDrbgsEntropyMinBytes(encoder.getDrbg());
uint8_t *entropy = new uint8_t[entropyBytes];
memset(entropy, 0, entropyBytes);
// Instantiate the encoder.
encoder.setEntropy(entropy, entropyBytes);
encoder.setNonce(0);
status = encoder.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Encoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Encode the inputs.
std::vector<std::string> encodings;
for (size_t i = 0; i < sizeof(inputs) / sizeof(inputs[0]); ++i)
{
const char *encoded = encoder.encodeB64(inputs[i], status);
if (status != mte_status_success)
{
std::cerr << "Encode error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
encodings.push_back(encoded);
std::cout << "Encode #" << i << ": " << inputs[i]
<< " -> " << encoded << std::endl;
}
// Status.
MteStatus status;
// Inputs.
string[] inputs = {
"message 1",
"message 2",
"message 3",
"message 4"
};
// Personalization string.
string personal = "demo";
// 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;
}
}
// Create the Encoder.
MteEnc encoder = new MteEnc();
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
int entropyBytes = encoder.GetDrbgsEntropyMinBytes(encoder.GetDrbg());
byte[] entropy = new byte[entropyBytes];
// Instantiate the Encoder.
encoder.SetEntropy(entropy);
encoder.SetNonce(0);
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 inputs.
string[] encodings = new string[inputs.Length];
for (int i = 0; i < inputs.Length; ++i) {
encodings[i] = encoder.EncodeB64(inputs[i], out status);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Encode error ({0}): {1}",
encoder.GetStatusName(status),
encoder.GetStatusDescription(status));
return (int)status;
}
Console.WriteLine("Encode #{0}: {1} -> {2}",
i,
inputs[i],
encodings[i]);
}
// Status.
MteStatus status;
// Inputs.
String[] inputs =
{
"message 1",
"message 2",
"message 3",
"message 4"
};
// Personalization string.
String personal = "demo";
// 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.
if (!MteBase.initLicense("YOUR_COMPANY", "YOUR_LICENSE"))
{
String company = System.getenv("MTE_COMPANY");
String license = System.getenv("MTE_LICENSE");
if (company == null || license == null ||
!MteBase.initLicense(company, license))
{
status = MteStatus.mte_status_license_error;
System.err.println("Encode error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
}
// Create the Encoder.
MteEnc encoder = new MteEnc();
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
int entropyBytes = MteBase.getDrbgsEntropyMinBytes(encoder.getDrbg());
byte[] entropy = new byte[entropyBytes];
// Instantiate the Encoder.
encoder.setEntropy(entropy);
encoder.setNonce(0);
status = encoder.instantiate(personal);
if (status != MteStatus.mte_status_success)
{
System.err.println("Encoder instantiate error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
// Encode the inputs.
String[] encodings = new String[inputs.length];
for (int i = 0; i < inputs.length; ++i)
{
MteBase.StrStatus encoded = encoder.encodeB64(inputs[i]);
if (encoded.status != MteStatus.mte_status_success)
{
System.err.println("Encode error ("+
MteBase.getStatusName(encoded.status)+"): "+
MteBase.getStatusDescription(encoded.status));
System.exit(encoded.status.getValue());
}
encodings[i] = encoded.str;
System.out.printf("Encode #%d: %s -> %s\n", i, inputs[i], encodings[i]);
}
import Foundation;
// The timestamp window is hard coded for this demo.
let timestampWindow: UInt64 = 1
// Status.
var status: mte_status
// Inputs.
let inputs = [
"message 0",
"message 1",
"message 2",
"message 3"
]
// Personalization string.
let personal = "demo"
// 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.
if !MteBase.initLicense("YOUR_COMPANY", "YOUR_LICENSE") {
let company = ProcessInfo.processInfo.environment["MTE_COMPANY"]
let license = ProcessInfo.processInfo.environment["MTE_LICENSE"];
if company == nil || license == nil ||
!MteBase.initLicense(company!, license!) {
status = mte_status_license_error
print("License init error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
exit(Int32(status.rawValue))
}
}
// Create the encoder.
let encoder = try! MteEnc()
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
let entropyBytes = MteBase.getDrbgsEntropyMinBytes(encoder.getDrbg())
var entropy = [UInt8](repeating: 0, count: entropyBytes)
// Instantiate the encoder.
encoder.setEntropy(&entropy)
encoder.setNonce(0)
status = encoder.instantiate(personal)
if status != mte_status_success {
print("Encoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
exit(Int32(status.rawValue))
}
// Encode the inputs.
var encoded: String
var encodings = [String]()
for i in 0...inputs.count-1 {
(encoded, status) = encoder.encodeB64(inputs[i])
if status != mte_status_success {
print("Encode error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
exit(Int32(status.rawValue))
}
encodings.append(encoded)
print("Encode #\(i): \(inputs[i]) -> \(encoded)")
}
// Status.
mte_status status;
// Autorelease pool.
@autoreleasepool {
puts("****** Simple MTE Sequencing Console Demo ******");
// Inputs.
NSString *inputs[] =
{
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 0"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 1"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 2"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 3"])
};
// Personalization string.
NSString *personal =
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"demo"]);
// 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.
if (![MteBase initLicense:@"YOUR_COMPANY" code:@"YOUR_LICENSE"])
{
const char *company = getenv("MTE_COMPANY");
const char *license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
![MteBase initLicense:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:company])
code:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:license])])
{
status = mte_status_license_error;
fprintf(stderr, "License init error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
}
// Create the encoder.
MteEnc *encoder = MTE_AUTORELEASE([[MteEnc alloc] init]);
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
size_t entropyBytes = [MteBase getDrbgsEntropyMinBytes:[encoder getDrbg]];
uint8_t *entropy = calloc(entropyBytes, sizeof(uint8_t));
// Instantiate the encoder.
[encoder setEntropy:entropy bytes:entropyBytes];
[encoder setNonce:0];
status = [encoder instantiate:personal];
if (status != mte_status_success)
{
fprintf(stderr, "Encoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Encode the inputs.
NSString *encodings[sizeof(inputs) / sizeof(inputs[0])];
for (unsigned i = 0; i < sizeof(inputs) / sizeof(inputs[0]); ++i)
{
encodings[i] = [encoder encodeB64:inputs[i] status:&status];
if (status != mte_status_success)
{
fprintf(stderr, "Encode error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
printf("Encode #%u: %s -> %s\n",
i,
[inputs[i] UTF8String],
[encodings[i] UTF8String]);
}
free(entropy);
}
# Import relevant modules for the program.
from MteStatus import MteStatus
from MteBase import MteBase
from MteEnc import MteEnc
from MteDec import MteDec
import os
import sys
# Inputs.
inputs = [
"message 0",
"message 1",
"message 2",
"message 3"
]
# Personalization string.
personal_str = "demo"
# 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.
if not MteBase.init_license("YOUR_COMPANY", "YOUR_LICENSE"):
company = os.getenv("MTE_COMPANY")
license = os.getenv("MTE_LICENSE")
if company is None or \
license is None or \
not MteBase.init_license(company, license):
print("License init error ({0}): {1}".format(
MteBase.get_status_name(MteStatus.mte_status_license_error),
MteBase.get_status_description(MteStatus.mte_status_license_error)),
file=sys.stderr)
return MteStatus.mte_status_license_error.value
# Create the Encoder.
encoder = MteEnc.fromdefault()
# Create all-zero entropy for this demo. The nonce will also be set to zero.
# This should never be done in real applications.
entropy_bytes = MteBase.get_drbgs_entropy_min_bytes(encoder.get_drbg())
entropy = bytes(entropy_bytes)
# Instantiate the Encoder.
encoder.set_entropy(entropy)
encoder.set_nonce(0)
encoder_status = encoder.instantiate(personal_str)
if encoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(encoder_status),\
MteBase.get_status_description(encoder_status)
print("Encoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
return encoder_status.value
# Encode the inputs.
encodings = []
for i in range(len(inputs)):
(encoded_message, encoder_status) = encoder.encode_b64(inputs[i])
if encoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(encoder_status),\
MteBase.get_status_description(encoder_status)
print("Encode error ({0}): {1}".format(status,message),\
file=sys.stderr)
return encoder_status.value
encodings.append(encoded_message)
print(f'Encode #{i}: {inputs[i]} -> {encoded_message}')
// Status.
var status mte.Status
// Inputs.
inputs := [...]string{
"message 1",
"message 2",
"message 3",
"message 4"}
// Personalization string.
const personal = "demo"
// 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.
if !mte.InitLicense("YOUR_COMPANY", "YOUR_LICENSE") {
company := os.Getenv("MTE_COMPANY")
license := os.Getenv("MTE_LICENSE")
if len(company) == 0 || len(license) == 0 ||
!mte.InitLicense(company, license) {
fmt.Fprintf(os.Stderr, "License init error (%v): %v\n",
mte.GetStatusName(mte.Status_mte_status_license_error),
mte.GetStatusDescription(mte.Status_mte_status_license_error))
return int(mte.Status_mte_status_license_error)
}
}
// Create the Encoder.
encoder := mte.NewEncDef()
defer encoder.Destroy()
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
entropyBytes := mte.GetDrbgsEntropyMinBytes(encoder.GetDrbg())
entropy := make([]byte, entropyBytes)
// Instantiate the Encoder.
encoder.SetEntropy(entropy)
encoder.SetNonceInt(0)
status = encoder.InstantiateStr(personal)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
// Encode the inputs.
var encodings [len(inputs)]string
for i := 0; i < len(inputs); i++ {
encodings[i], status = encoder.EncodeStrB64(inputs[i])
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encode error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
fmt.Printf("Encode #%v: %v -> %v\n", i, inputs[i], encodings[i]);
}
import { MteBase, MteWasm, MteEnc, MteDec, MteStatus } from "./Mte";
import { exit } from "process";
// Create and instantiate the singleton WASM. The instantiate() call returns a
// promise that must be resolved before any other MTE objects can be created.
// The instantiated, resolved MteWasm object must be passed as an argument to
// create any other MTE objects.
let wasm = new MteWasm();
wasm.instantiate().then(() => { main(); });
// Status.
let stat: MteStatus;
// Inputs.
const inputs = [
"message 0",
"message 1",
"message 2",
"message 3"
];
// Personalization string.
const personal = "demo";
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped.
const base = new MteBase(wasm);
if (!base.initLicense("YOUR_COMPANY", "YOUR_LICENSE"))
{
const code = MteStatus.mte_status_license_error;
console.error("License init error (" + base.getStatusName(code) + "): " +
base.getStatusDescription(code));
exit(code);
}
// Create the encoder.
let encoder = MteEnc.fromdefault(wasm);
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
const entropyBytes = encoder.getDrbgsEntropyMinBytes(encoder.getDrbg());
const entropy = new Uint8Array(entropyBytes);
const nonce = "0";
// Instantiate the encoder.
encoder.setEntropyArr(entropy);
encoder.setNonce(nonce);
stat = encoder.instantiate(personal);
if (stat != MteStatus.mte_status_success) {
console.error("Encoder instantiate error (" +
encoder.getStatusName(stat) +
"): " +
encoder.getStatusDescription(stat));
exit(stat);
}
// Encode the inputs.
let encodings = Array<string>(inputs.length);
for (let i = 0; i < inputs.length; ++i) {
const encoded = encoder.encodeStrB64(inputs[i]);
if (encoded.status != MteStatus.mte_status_success) {
console.error("Encode error (" +
encoder.getStatusName(encoded.status) + "): " +
encoder.getStatusDescription(encoded.status));
exit(encoded.status);
}
encodings[i] = encoded.str!;
console.log("Encode #" + i + ": " + inputs[i] + " -> " + encodings[i]);
}
Verification-Only
In verification-only mode, which is enabled by setting the sequence window to 0, the sequence number is checked before decoding is attempted and if it is not the expected number, no decode is attempted and an error is returned. This may be useful in cases where missing data is not acceptable (e.g., real-time commands to a robot) and needs to be detected. For more information, please see the official MTE developer guides.
The following sample will highlight how the verification-only sequencing mode works by decoding the input messages in the following order:
- Message 1 – success
- Message 1 – error -- repeat message
- Message 3 – error -- message 1 expected
- Message 2 – success
- Message 3 – success
- Message 4 – success
- C
- C++
- CSharp
- Java
- Swift
- ObjC
- Python
- Go
- TypeScript
/* Create the Decoder. */
status = mte_dec_state_init(decoderV, &d_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
/* Instantiate the Decoder. */
status = mte_dec_instantiate(decoderV, &i_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
/* Allocate the buffer for decoding. */
decoded = MTE_ALLOCA(mte_dec_buff_bytes_b64(decoderV, e_args.bytes));
/* Decode in verification-only mode. */
puts("\nVerification-only mode (sequence window = 0):");
/* Decode the first message. */
/* Output: Decode #1: mte_status_success, message 1. */
MTE_SET_DEC_IO(d_args, encodings[0], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderV, &d_args);
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Try to decode the first message again -- out of sequence, should not work. */
/* Output: Decode #1: mte_status_seq_outside_window. */
MTE_SET_DEC_IO(d_args, encodings[0], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderV, &d_args);
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode the third message -- out of sequence should not work. */
/* Output: Decode #3: mte_status_seq_outside_window. */
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderV, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode the second message. */
/* Output: Decode #2: mte_status_success, message 2. */
MTE_SET_DEC_IO(d_args, encodings[1], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderV, &d_args);
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode the third message. */
/* Output: Decode #3: mte_status_success, message 3. */
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderV, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode the fourth message. */
/* Output: Decode #4: mte_status_success, message 4. */
MTE_SET_DEC_IO(d_args, encodings[3], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderV, &d_args);
printf("Decode #3: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
MteDec decoderV(0, 0);
decoderV.setEntropy(entropy, entropyBytes);
decoderV.setNonce(0);
status = decoderV.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Decoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// String to decode to.
std::string decoded;
// Decode in verification-only mode.
std::cout << "\nVerification-only mode (sequence window = 0):" << std::endl;
status = decoderV.decodeB64(encodings[0].c_str(), decoded);
std::cout << "Decode #0: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderV.decodeB64(encodings[0].c_str(), decoded);
std::cout << "Decode #0: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderV.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderV.decodeB64(encodings[1].c_str(), decoded);
std::cout << "Decode #1: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderV.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderV.decodeB64(encodings[3].c_str(), decoded);
std::cout << "Decode #3: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
// Create Decoder with Verification-only sequencing
// When constructing an MteDec the second argument is
// the sequence window (the first is the timestamp window)
MteDec decoderV = new MteDec(0, 0);
// Instantiate the Decoder.
decoderV.SetEntropy(entropy);
decoderV.SetNonce(0);
status = decoderV.Instantiate(personal);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decoder instantiate error ({0}): {1}",
decoderV.GetStatusName(status),
decoderV.GetStatusDescription(status));
return (int)status;
}
// Output that decoding is in verification-only sequencing mode
Console.WriteLine("\nVerification-only mode (sequence window = 0):");
// Decode the first message
// Output: Decode #1: mte_status_success, message 1
decoded = decoderV.DecodeStrB64(encodings[0], out status);
Console.WriteLine("Decode #1: {0}, {1}",
decoderV.GetStatusName(status),
decoded);
// Try to decode the first message again -- out of sequence, should not work
// Output: Decode #1: mte_status_seq_outside_window,
decoded = decoderV.DecodeStrB64(encodings[0], out status);
Console.WriteLine("Decode #1: {0}, {1}",
decoderV.GetStatusName(status),
decoded);
// Decode the third message -- out of sequence should not work
// Output: Decode #3: mte_status_seq_outside_window,
decoded = decoderV.DecodeStrB64(encodings[2], out status);
Console.WriteLine("Decode #3: {0}, {1}",
decoderV.GetStatusName(status),
decoded);
// Decode the second message
// Output: Decode #2: mte_status_success, message 2
decoded = decoderV.DecodeStrB64(encodings[1], out status);
Console.WriteLine("Decode #2: {0}, {1}",
decoderV.GetStatusName(status),
decoded);
// Decode the third message
// Output: Decode #3: mte_status_success, message 3
decoded = decoderV.DecodeStrB64(encodings[2], out status);
Console.WriteLine("Decode #3: {0}, {1}",
decoderV.GetStatusName(status),
decoded);
// Decode the fourth message
// Output: Decode #4: mte_status_success, message 4
decoded = decoderV.DecodeStrB64(encodings[3], out status);
Console.WriteLine("Decode #4: {0}, {1}",
decoderV.GetStatusName(status),
decoded);
// Create Verification-only Decoder
// When constructing an MteDec the second argument is
// the sequence window (the first is the timestamp window)
MteDec decoderV = new MteDec(0, 0);
// Instantiate the Decoder.
decoderV.setEntropy(entropy);
decoderV.setNonce(0);
status = decoderV.instantiate(personal);
if (status != MteStatus.mte_status_success)
{
System.err.println("Decoder instantiate error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
// String to decode to.
MteBase.StrStatus decoded;
// Output that decoding is in verification-only sequencing mode.
System.out.println("\nVerification-only mode (sequence window = 0):");
// Decode first message
// Output: Decode #1: mte_status_success, message 1
decoded = decoderV.decodeStrB64(encodings[0]);
System.out.println("Decode #1: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode first message again -- out of sequence, should not work
// Output: Decode #1: mte_status_seq_outside_window,
decoded = decoderV.decodeStrB64(encodings[0]);
System.out.println("Decode #1: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode third message - (out of sequence)
// Output: Decode #3: mte_status_seq_outside_window,
decoded = decoderV.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode second message
// Output: Decode #2: mte_status_success, message 2
decoded = decoderV.decodeStrB64(encodings[1]);
System.out.println("Decode #2: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode third message (in correct order)
// Output: Decode #3: mte_status_success, message 3
decoded = decoderV.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode fourth message
// Output: Decode #4: mte_status_success, message 4
decoded = decoderV.decodeStrB64(encodings[3]);
System.out.println("Decode #4: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
let decoderV = try! MteDec(0, 0)
decoderV.setEntropy(&entropy)
decoderV.setNonce(0)
status = decoderV.instantiate(personal
if status != mte_status_success {
print("Decoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
exit(Int32(status.rawValue))
}
// String to decode to.
var decoded: String
// Create the corrupt version of message #2.
let first = encodings[2][encodings[2].startIndex].asciiValue! + 1
var corrupt = encodings[2]
corrupt.remove(at: corrupt.startIndex)
corrupt.insert(Character(Unicode.Scalar(first)), at: corrupt.startIndex)
// Decode in verification-only mode.
print("\nVerification-only mode (sequence window = 0):")
(decoded, status) = decoderV.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderV.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderV.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderV.decodeStrB64(encodings[1])
print("Decode #1: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderV.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderV.decodeStrB64(encodings[3])
print("Decode #3: \(MteBase.getStatusName(status)), \(decoded)")
// Decode in forward-only mode.
print("\nForward-only mode (sequence window = 2):")
(decoded, status) = decoderF.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(corrupt)
print("Corrupt #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[1])
print("Decode #1: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[3])
print("Decode #3: \(MteBase.getStatusName(status)), \(decoded)")
// Status.
mte_status status;
// Autorelease pool.
@autoreleasepool {
puts("****** Simple MTE Sequencing Console Demo ******");
// Inputs.
NSString *inputs[] =
{
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 0"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 1"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 2"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 3"])
};
// Personalization string.
NSString *personal =
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"demo"]);
// 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.
if (![MteBase initLicense:@"YOUR_COMPANY" code:@"YOUR_LICENSE"])
{
const char *company = getenv("MTE_COMPANY");
const char *license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
![MteBase initLicense:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:company])
code:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:license])])
{
status = mte_status_license_error;
fprintf(stderr, "License init error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
}
// Create the encoder.
MteEnc *encoder = MTE_AUTORELEASE([[MteEnc alloc] init]);
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
size_t entropyBytes = [MteBase getDrbgsEntropyMinBytes:[encoder getDrbg]];
uint8_t *entropy = calloc(entropyBytes, sizeof(uint8_t));
// Instantiate the encoder.
[encoder setEntropy:entropy bytes:entropyBytes];
[encoder setNonce:0];
status = [encoder instantiate:personal];
if (status != mte_status_success)
{
fprintf(stderr, "Encoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Encode the inputs.
NSString *encodings[sizeof(inputs) / sizeof(inputs[0])];
for (unsigned i = 0; i < sizeof(inputs) / sizeof(inputs[0]); ++i)
{
encodings[i] = [encoder encodeB64:inputs[i] status:&status];
if (status != mte_status_success)
{
fprintf(stderr, "Encode error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
printf("Encode #%u: %s -> %s\n",
i,
[inputs[i] UTF8String],
[encodings[i] UTF8String]);
}
// Create decoder.
MteDec *decoderV = MTE_AUTORELEASE([[MteDec alloc] initWithTWindow:0
sWindow:0]);
// Instantiate the decoder.
[decoderV setEntropy:entropy bytes:entropyBytes];
[decoderV setNonce:0];
status = [decoderV instantiate:personal];
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Save the async decoder state.
size_t stateBytes;
const void *dsaved = [decoderV saveState:&stateBytes];
// String to decode to.
NSString *decoded;
// Create the corrupt version of message #2.
char first[] = { [encodings[2] UTF8String][0] + 1, '\0' };
NSString *nsfirst = [[NSString alloc] initWithUTF8String:first];
NSString *corrupt =
[encodings[2] stringByReplacingCharactersInRange:NSMakeRange(0, 1)
withString:nsfirst];
// Decode in verification-only mode.
puts("\nVerification-only mode (sequence window = 0):");
decoded = [decoderV decodeB64:encodings[0] status:&status];
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderV decodeB64:encodings[0] status:&status];
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderV decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderV decodeB64:encodings[1] status:&status];
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderV decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderV decodeB64:encodings[3] status:&status];
printf("Decode #3: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
free(entropy);
}
# Create Decoder with Verification-only sequencing.
# When constructing an MteDec the second argument is
# the sequence window (the first is the timestamp window which is set to zero).
decoder_v = MteDec.fromdefault(s_window=0)
# Instantiate the Decoder.
decoder_v.set_entropy(entropy)
decoder_v.set_nonce(0)
decoder_status = decoder_v.instantiate(personal_str)
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Decoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
return decoder_status.value
# Decode in verification-only mode.
print("\nVerification-only mode (sequence window = 0):")
# Decode the first message.
# Output: Decode #0: mte_status_success, message 0.
(decoded_message, status) = decoder_v.decode_str_b64(encodings[0])
print("Decode #0: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Try to decode the first message again -- out of sequence, should not work.
# Output: Decode #0: mte_status_seq_outside_window.
(decoded_message, status) = decoder_v.decode_str_b64(encodings[0])
print("Decode #0: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode the third message -- out of sequence should not work.
# Output: Decode #2: mte_status_seq_outside_window.
(decoded_message, status) = decoder_v.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode the second message.
# Output: Decode #1: mte_status_success, message 1.
(decoded_message, status) = decoder_v.decode_str_b64(encodings[1])
print("Decode #1: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode the third message.
# Output: Decode #2: mte_status_success, message 2.
(decoded_message, status) = decoder_v.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode the fourth message.
# Output: Decode #3: mte_status_success, message 3.
(decoded_message, status) = decoder_v.decode_str_b64(encodings[3])
print("Decode #3: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
// Create decoder with Verification-only sequencing
// when constructing an NewDecWin the second argument is
// the sequence window (the first is the timestamp window)
decoderV := mte.NewDecWin(0, 0);
// Instantiate the decoder.
decoderV.SetEntropy(entropy)
decoderV.SetNonceInt(0)
status = decoderV.InstantiateStr(personal)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
// String to decode to.
var decoded string
// Create the corrupt version of message #2.
first := true
corrupt := strings.Map(func(r rune) rune {
if first {
first = false
return r + 1
}
return r
}, encodings[2])
// Decode in verification-only mode.
fmt.Println("\nVerification-only mode (sequence window = 0):")
// Decode the first message
// Output: Decode #1: mte_status_success, message 1
decoded, status = decoderV.DecodeStrB64(encodings[0])
fmt.Printf("Decode #1: %v, %v\n", mte.GetStatusName(status), decoded)
// Try to decode the first message again -- out of sequence, should not work
// Output: Decode #1: mte_status_seq_outside_window,
decoded, status = decoderV.DecodeStrB64(encodings[0])
fmt.Printf("Decode #1: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode the third message -- out of sequence should not work
// Output: Decode #3: mte_status_seq_outside_window,
decoded, status = decoderV.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode the second message
// Output: Decode #2: mte_status_success, message 2
decoded, status = decoderV.DecodeStrB64(encodings[1])
fmt.Printf("Decode #2: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode the third message
// Output: Decode #3: mte_status_success, message 3
decoded, status = decoderV.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode the fourth message
// Output: Decode #4: mte_status_success, message 4
decoded, status = decoderV.DecodeStrB64(encodings[3])
fmt.Printf("Decode #4: %v, %v\n", mte.GetStatusName(status), decoded)
// Create Decoder with Verification-only sequencing
// When constructing an MteDec the second argument is
// the sequence window (the first is the timestamp window)
let decoderV = MteDec.fromdefault(wasm, 0, 0);
// Instantiate the Decoder
decoderV.setEntropyArr(entropy);
decoderV.setNonce(nonce);
stat = decoderV.instantiate(personal);
if (stat != MteStatus.mte_status_success) {
console.error("Decoder instantiate error (" +
decoderV.getStatusName(stat) +
"): " +
decoderV.getStatusDescription(stat));
exit(stat);
}
// Decode in verification-only sequencing mode
console.log("\nVerification-only mode (sequence window = 0):");
let decoded = decoderV.decodeStrB64(encodings[0]);
console.log("Decode #0: " +
decoderV.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderV.decodeStrB64(encodings[0]);
console.log("Decode #0: " +
decoderV.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderV.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderV.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderV.decodeStrB64(encodings[1]);
console.log("Decode #1: " +
decoderV.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderV.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderV.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderV.decodeStrB64(encodings[3]);
console.log("Decode #3: " +
decoderV.getStatusName(decoded.status) + ", " + decoded.str);
Forward-Only
In forward-only mode, which is enabled by setting the sequence window to a positive number, the sequence number is checked before decoding and if it is ahead of the expected number and within the window, a catch-up algorithm is invoked to skip over the missing messages in order to successfully decode the current message. This may be useful in cases where missing data is acceptable (e.g., streaming video dropping some frames) and the desire is to just get what comes through. For more information, please see the official MTE developer guides.
If the catch-up still results in a decode failure, the state is rolled back as if the decode had not been attempted, with the assumption that the message was corrupt.
If the sequence number was outside the window, an error is returned before attempting to decode.
This mode requires that all messages are the same length, so MTE can know how to get back in sync. There are many ways to ensure this, including add-ons like Fixed-Length and Managed-Key Encryption, or the SDK user may have their own way of knowing the input is always the same length. The Fixed-Length Add-On always produces messages of the same length. The Managed-Key Encryption Add-On always produces fixed-length (for sequencing purposes) messages while at the same time allowing variable-length data.
The following sample will highlight how the verification-only sequencing mode works by decoding the input messages in the following order:
- Message 1 – success
- Message 1 – error -- repeat message
- Corrupt Message 3 – error -- corrupted message
- Message 3 – success (ahead of what is expected but within window)
- Message 2 – error -- behind expected sequence number
- Message 3 – error -- repeat message
- Message 4 – success
- C
- C++
- CSharp
- Java
- Swift
- ObjC
- Python
- Go
- TypeScript
/* Create decoder. */
status = mte_dec_state_init(decoderF, &d_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
status = mte_dec_instantiate(decoderF, &i_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
/* Allocate the buffer for decoding. */
decoded = MTE_ALLOCA(mte_dec_buff_bytes_b64(decoderF, e_args.bytes));
/* Decode in forward-only mode. */
puts("\nForward-only mode (sequence window = 2):");
/* Decode first message. */
MTE_SET_DEC_IO(d_args, encodings[0], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderF, &d_args);
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode first message again -- out of sequence, should not work. */
/* Output: Decode #1: mte_status_seq_outside_window. */
MTE_SET_DEC_IO(d_args, encodings[0], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderF, &d_args);
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode corrupt message. */
/* Try to decode the corrupted second message -- should not work. */
/* Output: Corrupt #3: mte_status_seq_mismatch. */
++encodings[2][0];
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderF, &d_args);
printf("Corrupt #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode third message (within sequence window). */
/* Output: Decode #3: mte_status_success, message 3. */
--encodings[2][0];
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderF, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode non-corrupted second message. */
/* (after already decoding third -- out of sequence). */
/* Output: Decode #2: mte_status_seq_outside_window. */
MTE_SET_DEC_IO(d_args, encodings[1], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderF, &d_args);
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode third message again -- out of sequence, should not work. */
/* Output: Decode #3: mte_status_seq_outside_window. */
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderF, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode fourth message. */
/* Output: Decode #4: mte_status_success, message 4. */
MTE_SET_DEC_IO(d_args, encodings[3], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderF, &d_args);
printf("Decode #3: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
MteDec decoderF(0, 2);
decoderF.setEntropy(entropy, entropyBytes);
decoderF.setNonce(0);
status = decoderF.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Decoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// String to decode to.
std::string decoded;
// Decode in forward-only mode.
std::cout << "\nForward-only mode (sequence window = 2):" << std::endl;
status = decoderF.decodeB64(encodings[0].c_str(), decoded);
std::cout << "Decode #0: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderF.decodeB64(encodings[0].c_str(), decoded);
std::cout << "Decode #0: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
++encodings[2][0];
status = decoderF.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Corrupt #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
--encodings[2][0];
status = decoderF.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderF.decodeB64(encodings[1].c_str(), decoded);
std::cout << "Decode #1: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderF.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderF.decodeB64(encodings[3].c_str(), decoded);
std::cout << "Decode #3: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
// Create Forward-only Decoder
// For this sample sequence window is being set to 2
MteDec decoderF = new MteDec(0, 2);
// Instantiate the Decoder
decoderF.SetEntropy(entropy);
decoderF.SetNonce(0);
status = decoderF.Instantiate(personal);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decoder instantiate error ({0}): {1}",
decoderV.GetStatusName(status),
decoderV.GetStatusDescription(status));
return (int)status;
}
// String to decode to.
string decoded;
// Create the corrupt version of message #2.
// Doing this to ensure decode fails
char first = encodings[2][0];
++first;
string corrupt =
encodings[2].Substring(1).Insert(0, new string(first, 1));
// Output that decoding is in forward-only sequencing mode
Console.WriteLine("\nForward-only mode (sequence window = 2):");
// Decode first message
// Output: Decode #1: mte_status_success, message 1
decoded = decoderF.DecodeStrB64(encodings[0], out status);
Console.WriteLine("Decode #1: {0}, {1}",
decoderF.GetStatusName(status),
decoded);
// Decode first message again -- out of sequence, should not work
// Output: Decode #1: mte_status_seq_outside_window,
decoded = decoderF.DecodeStrB64(encodings[0], out status);
Console.WriteLine("Decode #1: {0}, {1}",
decoderF.GetStatusName(status),
decoded);
// Decode corrupt message,
// Try to decode the corrupted second message -- should not work
// Output: Corrupt #3: mte_status_seq_mismatch,
decoded = decoderF.DecodeStrB64(corrupt, out status);
Console.WriteLine("Corrupt #3: {0}, {1}",
decoderF.GetStatusName(status),
decoded);
// Decode third message (within sequence window)
// Output: Decode #3: mte_status_success, message 3
decoded = decoderF.DecodeStrB64(encodings[2], out status);
Console.WriteLine("Decode #3: {0}, {1}",
decoderF.GetStatusName(status),
decoded);
// Decode non-corrupted second message
// (after already decoding third -- out of sequence)
// Output: Decode #2: mte_status_seq_outside_window,
decoded = decoderF.DecodeStrB64(encodings[1], out status);
Console.WriteLine("Decode #2: {0}, {1}",
decoderF.GetStatusName(status),
decoded);
// Decode third message again -- out of sequence, should not work
// Output: Decode #3: mte_status_seq_outside_window,
decoded = decoderF.DecodeStrB64(encodings[2], out status);
Console.WriteLine("Decode #3: {0}, {1}",
decoderF.GetStatusName(status),
decoded);
// Decode fourth message
// Output: Decode #4: mte_status_success, message 4
decoded = decoderF.DecodeStrB64(encodings[3], out status);
Console.WriteLine("Decode #4: {0}, {1}",
decoderF.GetStatusName(status),
decoded);
// Create Forward-only Decoder
// For this sample sequence window is being set to 2
MteDec decoderF = new MteDec(0, 2);
// Instantiate the Decoder
decoderF.setEntropy(entropy);
decoderF.setNonce(0);
status = decoderF.instantiate(personal);
if (status != MteStatus.mte_status_success)
{
System.err.println("Decoder instantiate error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
// String to decode to.
MteBase.StrStatus decoded;
// Create the corrupt version of message #3.
// Doing this to ensure decode fails
char[] e2 = encodings[2].toCharArray();
++e2[0];
String corrupt = new String(e2);
// Output that decoding is in forward-only sequencing mode
System.out.println("\nForward-only mode (sequence window = 2):");
// Decode the first message
// Output: Decode #1: mte_status_success, message 1
decoded = decoderF.decodeStrB64(encodings[0]);
System.out.println("Decode #1: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode the first message again -- out of sequence, should not work
// Output: Decode #1: mte_status_seq_outside_window,
decoded = decoderF.decodeStrB64(encodings[0]);
System.out.println("Decode #1: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Try to decode the corrupted second message -- should not work
// Output: Corrupt #3: mte_status_seq_mismatch,
decoded = decoderF.decodeStrB64(corrupt);
System.out.println("Corrupt #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode the third message (out of sequence but in sequence window)
// Output: Decode #3: mte_status_success, message 3
decoded = decoderF.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
/// Decode non-corrupted second message
// (after already decoding third -- out of sequence)
// Output: Decode #2: mte_status_seq_outside_window,
decoded = decoderF.decodeStrB64(encodings[1]);
System.out.println("Decode #2: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode third message again -- out of sequence, should not work
// Output: Decode #3: mte_status_seq_outside_window,
decoded = decoderF.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode fourth message
// Output: Decode #4: mte_status_success, message 4
decoded = decoderF.decodeStrB64(encodings[3]);
System.out.println("Decode #4: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
let decoderF = try! MteDec(0, 2)
decoderF.setEntropy(&entropy)
decoderF.setNonce(0)
status = decoderF.instantiate(personal)
if status != mte_status_success {
print("Decoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
exit(Int32(status.rawValue))
}
// String to decode to.
var decoded: String
// Create the corrupt version of message #2.
let first = encodings[2][encodings[2].startIndex].asciiValue! + 1
var corrupt = encodings[2]
corrupt.remove(at: corrupt.startIndex)
corrupt.insert(Character(Unicode.Scalar(first)), at: corrupt.startIndex)
// Decode in forward-only mode.
print("\nForward-only mode (sequence window = 2):")
(decoded, status) = decoderF.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(corrupt)
print("Corrupt #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[1])
print("Decode #1: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderF.decodeStrB64(encodings[3])
print("Decode #3: \(MteBase.getStatusName(status)), \(decoded)")
// Inputs.
NSString *inputs[] =
{
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 0"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 1"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 2"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 3"])
};
// Personalization string.
NSString *personal =
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"demo"]);
// 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.
if (![MteBase initLicense:@"YOUR_COMPANY" code:@"YOUR_LICENSE"])
{
const char *company = getenv("MTE_COMPANY");
const char *license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
![MteBase initLicense:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:company])
code:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:license])])
{
status = mte_status_license_error;
fprintf(stderr, "License init error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
}
// Create the encoder.
MteEnc *encoder = MTE_AUTORELEASE([[MteEnc alloc] init]);
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
size_t entropyBytes = [MteBase getDrbgsEntropyMinBytes:[encoder getDrbg]];
uint8_t *entropy = calloc(entropyBytes, sizeof(uint8_t));
// Instantiate the encoder.
[encoder setEntropy:entropy bytes:entropyBytes];
[encoder setNonce:0];
status = [encoder instantiate:personal];
if (status != mte_status_success)
{
fprintf(stderr, "Encoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Encode the inputs.
NSString *encodings[sizeof(inputs) / sizeof(inputs[0])];
for (unsigned i = 0; i < sizeof(inputs) / sizeof(inputs[0]); ++i)
{
encodings[i] = [encoder encodeB64:inputs[i] status:&status];
if (status != mte_status_success)
{
fprintf(stderr, "Encode error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
printf("Encode #%u: %s -> %s\n",
i,
[inputs[i] UTF8String],
[encodings[i] UTF8String]);
}
// Create decoder.
MteDec *decoderF = MTE_AUTORELEASE([[MteDec alloc] initWithTWindow:0
sWindow:2]);
// Instantiate the decoder.
decoderF setEntropy:entropy bytes:entropyBytes];
[decoderF setNonce:0];
status = [decoderF instantiate:personal];
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Save the async decoder state.
size_t stateBytes;
const void *dsaved = [decoderF saveState:&stateBytes];
// String to decode to.
NSString *decoded;
// Create the corrupt version of message #2.
char first[] = { [encodings[2] UTF8String][0] + 1, '\0' };
NSString *nsfirst = [[NSString alloc] initWithUTF8String:first];
NSString *corrupt =
[encodings[2] stringByReplacingCharactersInRange:NSMakeRange(0, 1)
withString:nsfirst];
// Decode in forward-only mode.
puts("\nForward-only mode (sequence window = 2):");
decoded = [decoderF decodeB64:encodings[0] status:&status];
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderF decodeB64:encodings[0] status:&status];
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderF decodeB64:corrupt status:&status];
printf("Corrupt #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderF decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderF decodeB64:encodings[1] status:&status];
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderF decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderF decodeB64:encodings[3] status:&status];
printf("Decode #3: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
free(entropy);
}
# Create Forward-only Decoder.
# For this sample sequence window is being set to 2
decoder_f = MteDec.fromdefault(s_window=2)
# Instantiate the Decoder.
decoder_f.set_entropy(entropy)
decoder_f.set_nonce(0)
decoder_status = decoder_f.instantiate(personal_str)
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Decoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
return decoder_status.value
# Create the corrupt version of message #2.
# Doing this to ensure decode fails.
corrupt = chr(ord(encodings[2][0]) + 1) + encodings[2][1:]
# Output that decoding is in forward-only sequencing mode.
print("\nForward-only mode (sequence window = 2):")
# Decode first message.
# Output: Decode #0: mte_status_success, message 0.
(decoded_message, status) = decoder_f.decode_str_b64(encodings[0])
print("Decode #0: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode first message again -- out of sequence, should not work.
# Output: Decode #0: mte_status_seq_outside_window.
(decoded_message, status) = decoder_f.decode_str_b64(encodings[0])
print("Decode #0: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode corrupt message.
# Try to decode the corrupted second message -- should not work.
# Output: Corrupt #2: mte_status_seq_mismatch,
(decoded_message, status) = decoder_f.decode_str_b64(corrupt)
print("Corrupt #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode third message (within sequence window).
# Output: Decode #2: mte_status_success, message 2.
(decoded_message, status) = decoder_f.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode non-corrupted second message.
# (after already decoding third -- out of sequence).
# Output: Decode #1: mte_status_seq_outside_window.
(decoded_message, status) = decoder_f.decode_str_b64(encodings[1])
print("Decode #1: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode third message again -- out of sequence, should not work.
# Output: Decode #2: mte_status_seq_outside_window.
(decoded_message, status) = decoder_f.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode fourth message.
# Output: Decode #3: mte_status_success, message 3.
(decoded_message, status) = decoder_f.decode_str_b64(encodings[3])
print("Decode #3: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
// Create Forward-only Decoder
// For this sample sequence window is being set to 2
decoderF := mte.NewDecWin(0, 2);
// Instantiate the Decoder.
decoderF.SetEntropy(entropy)
decoderF.SetNonceInt(0)
status = decoderF.InstantiateStr(personal)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
// String to decode to.
var decoded string
// Create the corrupt version of message #2.
first := true
corrupt := strings.Map(func(r rune) rune {
if first {
first = false
return r + 1
}
return r
}, encodings[2])
// Decode in forward-only mode.
fmt.Println("\nForward-only mode (sequence window = 2):")
// Decode first message
// Output: Decode #1: mte_status_success, message 1
decoded, status = decoderF.DecodeStrB64(encodings[0])
fmt.Printf("Decode #1: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode first message again -- out of sequence, should not work
// Output: Decode #1: mte_status_seq_outside_window,
decoded, status = decoderF.DecodeStrB64(encodings[0])
fmt.Printf("Decode #1: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode corrupt message,
// Try to decode the corrupted second message -- should not work
// Output: Corrupt #3: mte_status_seq_mismatch,
decoded, status = decoderF.DecodeStrB64(corrupt)
fmt.Printf("Corrupt #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode third message (within sequence window)
// Output: Decode #3: mte_status_success, message 3
decoded, status = decoderF.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode non-corrupted second message
// (after already decoding third -- out of sequence)
// Output: Decode #2: mte_status_seq_outside_window,
decoded, status = decoderF.DecodeStrB64(encodings[1])
fmt.Printf("Decode #2: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode third message again -- out of sequence, should not work
// Output: Decode #3: mte_status_seq_outside_window,
decoded, status = decoderF.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode fourth message
// Output: Decode #4: mte_status_success, message 4
decoded, status = decoderF.DecodeStrB64(encodings[3])
fmt.Printf("Decode #4: %v, %v\n", mte.GetStatusName(status), decoded)
// Create forward-only Decoder
// For this sample, sequence window is being set to 2
let decoderF = MteDec.fromdefault(wasm, 0, 2);
decoderF.setEntropyArr(entropy);
decoderF.setNonce(nonce);
stat = decoderF.instantiate(personal);
if (stat != MteStatus.mte_status_success) {
console.error("Decoder instantiate error (" +
decoderF.getStatusName(stat) +
"): " +
decoderF.getStatusDescription(stat));
exit(stat);
}
// Create the corrupt version of message #2.
// Doing this to ensure decode fails
const corrupt = String.fromCharCode(encodings[2].charCodeAt(0)! + 1) +
encodings[2].substr(1, encodings[2].length - 1);
// Decode in forward-only sequencing mode
console.log("\nForward-only mode (sequence window = 2):");
decoded = decoderF.decodeStrB64(encodings[0]);
console.log("Decode #0: " +
decoderF.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderF.decodeStrB64(encodings[0]);
console.log("Decode #0: " +
decoderF.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderF.decodeStrB64(corrupt);
console.log("Corrupt #2: " +
decoderF.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderF.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderF.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderF.decodeStrB64(encodings[1]);
console.log("Decode #1: " +
decoderF.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderF.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderF.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderF.decodeStrB64(encodings[3]);
console.log("Decode #3: " +
decoderF.getStatusName(decoded.status) + ", " + decoded.str);
Async
In async mode, which is enabled by setting the sequence window to a negative number, the sequence number is checked before decoding and if it is ahead of the expected number and within the window, a catch-up algorithm is invoked to skip ahead to the current message, and the state is always rolled back to allow messages to be decoded out of order, as long as they are within the window. This is useful in any situation where out-of-order processing may occur (e.g., a web server handling async requests from a browser). The sequencing window continuously moves forward once all sequence numbers within the window have been seen or a sequence number is far enough behind that is assumed the packet was lost. For more information, please see the official MTE developer guides.
If the sequence number was outside the window, an error is returned before attempting to decode.
This mode requires that all messages are the same length, so MTE can know how to get back in sync. There are many ways to ensure this, including add-ons like Fixed-Length and Managed-Key Encryption, or the SDK user may have their own way of knowing the input is always the same length. The Fixed-Length Add-On always produces messages of the same length. The Managed-Key Encryption Add-On always produces fixed-length (for sequencing purposes) messages while at the same time allowing variable-length data.
The following sample will highlight how the verification-only sequencing mode works by decoding the input messages in the following order:
- Message 1 – success
- Message 1 – error -- repeat message
- Corrupt Message 3 – error -- corrupted message
- Message 3 – success (ahead of expected but within window)
- Message 2 – success (behind expected but within window) Message 2 – error -- repeat message
- Message 4 – success
Restore MTE state to show decoding in different order
- Message 4 – success
- Message 1 – error -- too far behind expected sequence
- Message 3 – success
- Message 2 – success
- C
- C++
- CSharp
- Java
- Swift
- ObjC
- Python
- Go
- TypeScript
/* Decoder. */
char* decoded;
MTE_UINT8_T* dsaved;
MTE_HANDLE decoderA = MTE_ALLOCA(mte_dec_state_bytes(&d_info));
mte_dec_args d_args = MTE_DEC_ARGS_INIT(NULL, 0, NULL, &t_cb, NULL);
/* Create the Decoder. */
status = mte_dec_state_init(decoderA, &d_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
/* Instantiate the Decoder. */
status = mte_dec_instantiate(decoderA, &i_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
/* Save the async decoder state. */
dsaved = MTE_ALLOCA(mte_dec_save_bytes(decoderA));
mte_dec_state_save(decoderA, dsaved);
/* Allocate the buffer for decoding. */
decoded = MTE_ALLOCA(mte_dec_buff_bytes_b64(decoderA, e_args.bytes));
/* Decode in async mode. */
puts("\nAsync mode (sequence window = -2):");
/* Decode the first message. */
MTE_SET_DEC_IO(d_args, encodings[0], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Try to decode the first message again -- out of sequence, should not work.*/
MTE_SET_DEC_IO(d_args, encodings[0], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Try to decode the corrupted second message -- should not work.*/
++encodings[2][0];
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Corrupt #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Try to decode the corrupted second message -- should not work.*/
--encodings[2][0];
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode third message.*/
/* Output: Decode #3: mte_status_success, message. 3 */
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode second message (async should work because we have NOT decoded yet) */
/* Output: Decode #2: mte_status_success, message 2 */
MTE_SET_DEC_IO(d_args, encodings[1], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode third message again (since after message 1 and 2 different error) */
/* Output: Decode #3: mte_status_seq_outside_window. */
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode fourth message. */
/* Output: Decode #4: mte_status_success, message 4. */
MTE_SET_DEC_IO(d_args, encodings[3], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #3: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Restore and decode again in a different order. */
mte_dec_state_restore(decoderA, dsaved);
puts("\nAsync mode (sequence window = -2):");
/* Decode fourth message first. */
/* Output: Decode #4: mte_status_success, message 4. */
MTE_SET_DEC_IO(d_args, encodings[3], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #4: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode first message (error - sequence window too large). */
/* Output: Decode #1: mte_status_seq_outside_window. */
MTE_SET_DEC_IO(d_args, encodings[0], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode third message (inside sequence window). */
/* Output: Decode #3: mte_status_success, message 3. */
MTE_SET_DEC_IO(d_args, encodings[2], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
/* Decode non-corrupted second message (still inside sequence window). */
/* Output: Decode #2: mte_status_success, message 2. */
MTE_SET_DEC_IO(d_args, encodings[1], e_args.bytes, decoded);
status = mte_dec_decode_b64(decoderA, &d_args);
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? (const char*)d_args.decoded : "");
}
static mte_status ei_cb(void* context, mte_drbg_ei_info* info)
{
/* Create all-zero entropy for this demo. This should never be done in real
applications. */
(void)context;
info->bytes = info->min_length;
memset(info->buff, 0, info->min_length);
return mte_status_success;
}
static void n_cb(void* context, mte_drbg_nonce_info* info)
{
/* Create all-zero nonce for this demo. This should never be done in real
applications. */
(void)context;
info->bytes = info->min_length;
memset(info->buff, 0, info->min_length);
}
static MTE_UINT64_T t_cb(void* context)
{
/* Return 0 for the timestamp. Real applications would request an actual
timestamp as appropriate for their system. */
(void)context;
return 0;
}
MteDec decoderA(0, -2);
decoderA.setEntropy(entropy, entropyBytes);
decoderA.setNonce(0);
status = decoderA.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Decoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Save the async decoder state.
size_t stateBytes;
const void* dsaved = decoderA.saveState(stateBytes);
// String to decode to.
std::string decoded;
Decode in async mode.
std::cout << "\nAsync mode (sequence window = -2):" << std::endl;
status = decoderA.decodeB64(encodings[0].c_str(), decoded);
std::cout << "Decode #0: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[0].c_str(), decoded);
std::cout << "Decode #0: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
++encodings[2][0];
status = decoderA.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Corrupt #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
--encodings[2][0];
status = decoderA.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[1].c_str(), decoded);
std::cout << "Decode #1: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[3].c_str(), decoded);
std::cout << "Decode #3: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
// Restore and decode again in a different order.
decoderA.restoreState(dsaved);
std::cout << "\nAsync mode (sequence window = -2):" << std::endl;
status = decoderA.decodeB64(encodings[3].c_str(), decoded);
std::cout << "Decode #3: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[0].c_str(), decoded);
std::cout << "Decode #0: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[2].c_str(), decoded);
std::cout << "Decode #2: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
status = decoderA.decodeB64(encodings[1].c_str(), decoded);
std::cout << "Decode #1: " << MteBase::getStatusName(status)
<< ", " << decoded << std::endl;
//For this sample sequence window is being set to -2
MteDec decoderA = new MteDec(0, -2);
// Instantiate the Decoder
decoderA.SetEntropy(entropy);
decoderA.SetNonce(0);
status = decoderA.Instantiate(personal);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decoder instantiate error ({0}): {1}",
decoderV.GetStatusName(status),
decoderV.GetStatusDescription(status));
return (int)status;
}
// Save the async Decoder state.
byte[] dsaved = decoderA.SaveState();
// String to decode to.
string decoded;
// Create the corrupt version of message #2.
// Doing this so we can intentionally fail
char first = encodings[2][0];
++first;
string corrupt =
encodings[2].Substring(1).Insert(0, new string(first, 1));
// Output that decoding is in Async sequencing mode
Console.WriteLine("\nAsync mode (sequence window = -2):");
// Decode the first message
// Output: Decode #1: mte_status_success, message 1
decoded = decoderA.DecodeStrB64(encodings[0], out status);
Console.WriteLine("Decode #0: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Try to decode the first message again -- out of sequence, should not work
// Output: Decode #0: mte_status_seq_outside_window,
decoded = decoderA.DecodeStrB64(encodings[0], out status);
Console.WriteLine("Decode #1: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Try to decode the corrupted second message -- should not work
// Output: Corrupt #3: mte_status_seq_mismatch,
decoded = decoderA.DecodeStrB64(corrupt, out status);
Console.WriteLine("Corrupt #3: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Decode third message
// Output: Decode #3: mte_status_success, message 3
decoded = decoderA.DecodeStrB64(encodings[2], out status);
Console.WriteLine("Decode #3: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Decode second message (async should work because we have NOT decoded yet)
// Output: Decode #2: mte_status_success, message 2
decoded = decoderA.DecodeStrB64(encodings[1], out status);
Console.WriteLine("Decode #2: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Decode third message again (since after message 1 and 2 different error)
// Output: Decode #3: mte_status_seq_outside_window,
decoded = decoderA.DecodeStrB64(encodings[2], out status);
Console.WriteLine("Decode #3: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Decode fourth message
// Output: Decode #4: mte_status_success, message 4
decoded = decoderA.DecodeStrB64(encodings[3], out status);
Console.WriteLine("Decode #4: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Restore and decode again in a different order.
decoderA.RestoreState(dsaved);
Console.WriteLine("\nAsync mode (sequence window = -2):");
// Decode fourth message first
// Output: Decode #4: mte_status_success, message 4
decoded = decoderA.DecodeStrB64(encodings[3], out status);
Console.WriteLine("Decode #4: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Decode first message (error - sequence window too large)
// Output: Decode #1: mte_status_seq_outside_window,
decoded = decoderA.DecodeStrB64(encodings[0], out status);
Console.WriteLine("Decode #1: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Decode third message (inside sequence window)
// Output: Decode #3: mte_status_success, message 3
decoded = decoderA.DecodeStrB64(encodings[2], out status);
Console.WriteLine("Decode #3: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
// Decode non-corrupted second message (still inside sequence window)
// Output: Decode #2: mte_status_success, message 2
decoded = decoderA.DecodeStrB64(encodings[1], out status);
Console.WriteLine("Decode #2: {0}, {1}",
decoderA.GetStatusName(status),
decoded);
//For this sample sequence window is being set to -2
MteDec decoderA = new MteDec(0, -2);
// Instantiate the Decoder
decoderA.setEntropy(entropy);
decoderA.setNonce(0);
status = decoderA.instantiate(personal);
if (status != MteStatus.mte_status_success)
{
System.err.println("Decoder instantiate error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
// Save the async Decoder state.
byte[] dsaved = decoderA.saveState();
// String to decode to.
MteBase.StrStatus decoded;
// Create the corrupt version of message #2.
// Doing this so we can intentionally fail
char[] e2 = encodings[2].toCharArray();
++e2[0];
String corrupt = new String(e2);
// Output that decoding is in Async sequencing mode
System.out.println("\nAsync mode (sequence window = -2):");
// Decode first message
// Output: Decode #1: mte_status_success, message 1
decoded = decoderA.decodeStrB64(encodings[0]);
System.out.println("Decode #1: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode first message again (error) -- out of sequence, should not work
// Output: Decode #1: mte_status_seq_outside_window,
decoded = decoderA.decodeStrB64(encodings[0]);
System.out.println("Decode #1: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode corrupt message
// Output: Corrupt #3: mte_status_seq_mismatch,
decoded = decoderA.decodeStrB64(corrupt);
System.out.println("Corrupt #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode third message
// Output: Decode #3: mte_status_success, message 3
decoded = decoderA.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode third message again -- out of sequence (repeat message), should not work
// Output: Decode #3: mte_status_seq_async_replay,
decoded = decoderA.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode second message (inside sequence window and can be out of order)
// Output: Decode #2: mte_status_success, message 2
decoded = decoderA.decodeStrB64(encodings[1]);
System.out.println("Decode #2: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode third message
// Output: Decode #3: mte_status_seq_outside_window,
decoded = decoderA.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode fourth message
// Output: Decode #4: mte_status_success, message 4
decoded = decoderA.decodeStrB64(encodings[3]);
System.out.println("Decode #4: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Restore and decode again in a different order.
decoderA.restoreState(dsaved);
System.out.println("\nAsync mode (sequence window = -2):");
// Decode fourth message
// Decode #4: mte_status_success, message 4
decoded = decoderA.decodeStrB64(encodings[3]);
System.out.println("Decode #4: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode first message (error - sequence window too large)
// Output: Decode #1: mte_status_seq_outside_window,
decoded = decoderA.decodeStrB64(encodings[0]);
System.out.println("Decode #1: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode third message (inside sequence window)
// Output: Decode #3: mte_status_success, message 3
decoded = decoderA.decodeStrB64(encodings[2]);
System.out.println("Decode #3: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
// Decode non-corrupted second message (still inside sequence window)
// Output: Decode #2: mte_status_success, message 2
decoded = decoderA.decodeStrB64(encodings[1]);
System.out.println("Decode #2: " + MteBase.getStatusName(decoded.status) +
", " + (decoded.str == null ? "" : decoded.str));
let decoderA = try! MteDec(0, -2)
decoderA.setEntropy(&entropy)
decoderA.setNonce(0)
status = decoderA.instantiate(personal)
if status != mte_status_success {
print("Decoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
exit(Int32(status.rawValue))
}
// Save the async decoder state.
let dsaved = decoderA.saveState()!
// String to decode to.
var decoded: String
// Create the corrupt version of message #2.
let first = encodings[2][encodings[2].startIndex].asciiValue! + 1
var corrupt = encodings[2]
corrupt.remove(at: corrupt.startIndex)
corrupt.insert(Character(Unicode.Scalar(first)), at: corrupt.startIndex)
// Decode in async mode.
print("\nAsync mode (sequence window = -2):")
(decoded, status) = decoderA.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(corrupt)
print("Corrupt #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[1])
print("Decode #1: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[3])
print("Decode #3: \(MteBase.getStatusName(status)), \(decoded)")
// Restore and decode again in a different order.
decoderA.restoreState(dsaved)
print("\nAsync mode (sequence window = -2):")
(decoded, status) = decoderA.decodeStrB64(encodings[3])
print("Decode #3: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[0])
print("Decode #0: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[2])
print("Decode #2: \(MteBase.getStatusName(status)), \(decoded)")
(decoded, status) = decoderA.decodeStrB64(encodings[1])
print("Decode #1: \(MteBase.getStatusName(status)), \(decoded)")
// Inputs.
NSString *inputs[] =
{
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 0"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 1"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 2"]),
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"message 3"])
};
// Personalization string.
NSString *personal =
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:"demo"]);
// 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.
if (![MteBase initLicense:@"YOUR_COMPANY" code:@"YOUR_LICENSE"])
{
const char *company = getenv("MTE_COMPANY");
const char *license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
![MteBase initLicense:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:company])
code:
MTE_AUTORELEASE([[NSString alloc] initWithUTF8String:license])])
{
status = mte_status_license_error;
fprintf(stderr, "License init error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
}
// Create the encoder.
MteEnc *encoder = MTE_AUTORELEASE([[MteEnc alloc] init]);
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
size_t entropyBytes = [MteBase getDrbgsEntropyMinBytes:[encoder getDrbg]];
uint8_t *entropy = calloc(entropyBytes, sizeof(uint8_t));
// Instantiate the encoder.
[encoder setEntropy:entropy bytes:entropyBytes];
[encoder setNonce:0];
status = [encoder instantiate:personal];
if (status != mte_status_success)
{
fprintf(stderr, "Encoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Encode the inputs.
NSString *encodings[sizeof(inputs) / sizeof(inputs[0])];
for (unsigned i = 0; i < sizeof(inputs) / sizeof(inputs[0]); ++i)
{
encodings[i] = [encoder encodeB64:inputs[i] status:&status];
if (status != mte_status_success)
{
fprintf(stderr, "Encode error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
printf("Encode #%u: %s -> %s\n",
i,
[inputs[i] UTF8String],
[encodings[i] UTF8String]);
}
// Create decoder.
MteDec *decoderA = MTE_AUTORELEASE([[MteDec alloc] initWithTWindow:0
sWindow:-2]);
// Instantiate the decoder.
[decoderA setEntropy:entropy bytes:entropyBytes];
[decoderA setNonce:0];
status = [decoderA instantiate:personal];
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Save the async decoder state.
size_t stateBytes;
const void *dsaved = [decoderA saveState:&stateBytes];
// String to decode to.
NSString *decoded;
// Create the corrupt version of message #2.
char first[] = { [encodings[2] UTF8String][0] + 1, '\0' };
NSString *nsfirst = [[NSString alloc] initWithUTF8String:first];
NSString *corrupt =
[encodings[2] stringByReplacingCharactersInRange:NSMakeRange(0, 1)
withString:nsfirst];
// Decode in async mode.
puts("\nAsync mode (sequence window = -2):");
decoded = [decoderA decodeB64:encodings[0] status:&status];
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[0] status:&status];
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:corrupt status:&status];
printf("Corrupt #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[1] status:&status];
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[3] status:&status];
printf("Decode #3: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
// Restore and decode again in a different order.
[decoderA restoreState:dsaved];
puts("\nAsync mode (sequence window = -2):");
decoded = [decoderA decodeB64:encodings[3] status:&status];
printf("Decode #3: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[0] status:&status];
printf("Decode #0: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[2] status:&status];
printf("Decode #2: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
decoded = [decoderA decodeB64:encodings[1] status:&status];
printf("Decode #1: %s, %s\n",
mte_base_status_name(status),
status == mte_status_success ? [decoded UTF8String] : "");
free(entropy);
}
# For this sample sequence window is being set to -2.
decoder_a = MteDec.fromdefault(s_window=-2)
# Instantiate Decoder.
decoder_a.set_entropy(entropy)
decoder_a.set_nonce(0)
decoder_status = decoder_a.instantiate(personal_str)
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Decoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
return decoder_status.value
# Save the async Decoder state.
decoder_save_state = decoder_a.save_state()
# Create the corrupt version of message #2.
# Doing this to ensure decode fails.
corrupt = chr(ord(encodings[2][0]) + 1) + encodings[2][1:]
# Output that decoding is in Async sequencing mode.
print("\nAsync mode (sequence window = -2):")
# Decode the first message.
# Output: Decode #0: mte_status_success, message 0.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[0])
print("Decode #0: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Try to decode the first message again -- out of sequence, should not work.
# Output: Decode #0: mte_status_seq_outside_window.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[0])
print("Decode #0: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Try to decode the corrupted second message -- should not work.
# Output: Corrupt #2: mte_status_seq_mismatch.
(decoded_message, status) = decoder_a.decode_str_b64(corrupt)
print("Corrupt #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode third message.
# Output: Decode #2: mte_status_success, message 2.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode third message again.
# Output: Decode #2: mte_status_seq_async_replay.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode second message (async should work because we have NOT decoded yet).
# Output: Decode #1: mte_status_success, message 1.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[1])
print("Decode #1: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode third message again (since after message 1 and 2 different error).
# Output: Decode #2: mte_status_seq_outside_window.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode fourth message.
# Output: Decode #3: mte_status_success, message 3.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[3])
print("Decode #3: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Restore and decode again in a different order.
decoder_a.restore_state(decoder_save_state)
print("\nAsync mode out of order (sequence window = -2):")
# Decode fourth message first.
# Output: Decode #3: mte_status_success, message 3.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[3])
print("Decode #3: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode first message (error - sequence window too large).
# Output: Decode #0: mte_status_seq_outside_window.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[0])
print("Decode #0: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode third message (inside sequence window).
# Output: Decode #2: mte_status_success, message 2.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[2])
print("Decode #2: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
# Decode non-corrupted second message (still inside sequence window).
# Output: Decode #1: mte_status_success, message 1.
(decoded_message, status) = decoder_a.decode_str_b64(encodings[1])
print("Decode #1: {0}, {1}".format(MteBase.get_status_name(status), decoded_message))
// Create Async decoder
// For this sample sequence window is being set to -2
decoderA := mte.NewDecWin(0, -2);
// Instantiate the Decoder.
decoderA.SetEntropy(entropy)
decoderA.SetNonceInt(0)
status = decoderA.InstantiateStr(personal)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
// Save the async Decoder state.
dsaved := decoderA.SaveState()
// String to decode to.
var decoded string
// Create the corrupt version of message #2.
first := true
corrupt := strings.Map(func(r rune) rune {
if first {
first = false
return r + 1
}
return r
}, encodings[2])
// Decode in async mode.
fmt.Println("\nAsync mode (sequence window = -2):")
// Decode the first message
// Output: Decode #1: mte_status_success, message 1
decoded, status = decoderA.DecodeStrB64(encodings[0])
fmt.Printf("Decode #1: %v, %v\n", mte.GetStatusName(status), decoded)
// Try to decode the first message again -- out of sequence, should not work
// Output: Decode #0: mte_status_seq_outside_window,
decoded, status = decoderA.DecodeStrB64(encodings[0])
fmt.Printf("Decode #1: %v, %v\n", mte.GetStatusName(status), decoded)
// Try to decode the corrupted second message -- should not work
// Output: Corrupt #3: mte_status_seq_mismatch,
decoded, status = decoderA.DecodeStrB64(corrupt)
fmt.Printf("Corrupt #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode third message
// Output: Decode #3: mte_status_success, message 3
decoded, status = decoderA.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode third message
// Output: Decode #3: mte_status_success, message 3
decoded, status = decoderA.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode second message (async should work because we have NOT decoded yet)
// Output: Decode #2: mte_status_success, message 2
decoded, status = decoderA.DecodeStrB64(encodings[1])
fmt.Printf("Decode #2: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode third message again (since after message 1 and 2 different error)
// Output: Decode #3: mte_status_seq_outside_window,
decoded, status = decoderA.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode fourth message
// Output: Decode #4: mte_status_success, message 4
decoded, status = decoderA.DecodeStrB64(encodings[3])
fmt.Printf("Decode #4: %v, %v\n", mte.GetStatusName(status), decoded)
// Restore and decode again in a different order.
decoderA.RestoreState(dsaved)
fmt.Println("\nAsync mode (sequence window = -2):")
// Decode fourth message first
// Output: Decode #4: mte_status_success, message 4
decoded, status = decoderA.DecodeStrB64(encodings[3])
fmt.Printf("Decode #4: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode first message (error - sequence window too large)
// Output: Decode #1: mte_status_seq_outside_window,
decoded, status = decoderA.DecodeStrB64(encodings[0])
fmt.Printf("Decode #1: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode third message (inside sequence window)
// Output: Decode #3: mte_status_success, message 3
decoded, status = decoderA.DecodeStrB64(encodings[2])
fmt.Printf("Decode #3: %v, %v\n", mte.GetStatusName(status), decoded)
// Decode non-corrupted second message (still inside sequence window)
// Output: Decode #2: mte_status_success, message 2
decoded, status = decoderA.DecodeStrB64(encodings[1])
fmt.Printf("Decode #2: %v, %v\n", mte.GetStatusName(status), decoded)
// For this sample, sequence window is being set to -2
let decoderA = MteDec.fromdefault(wasm, 0, -2);
// Instantiate the Decoder
decoderA.setEntropyArr(entropy);
decoderA.setNonce(nonce);
stat = decoderA.instantiate(personal);
if (stat != MteStatus.mte_status_success) {
console.error("Decoder instantiate error (" +
decoderA.getStatusName(stat) +
"): " +
decoderA.getStatusDescription(stat));
exit(stat);
}
// Save the async decoder state.
const dsaved = decoderA.saveState();
// Create the corrupt version of message #2.
// Doing this to ensure decode fails
const corrupt = String.fromCharCode(encodings[2].charCodeAt(0)! + 1) +
encodings[2].substr(1, encodings[2].length - 1);
// Decode in async mode.
console.log("\nAsync mode (sequence window = -2):");
decoded = decoderA.decodeStrB64(encodings[0]);
console.log("Decode #0: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[0]);
console.log("Decode #0: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(corrupt);
console.log("Corrupt #2: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[1]);
console.log("Decode #1: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[3]);
console.log("Decode #3: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
// Restore and decode again in a different order.
decoderA.restoreState(dsaved!);
console.log("\nAsync mode (sequence window = -2):");
decoded = decoderA.decodeStrB64(encodings[3]);
console.log("Decode #3: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[0]);
console.log("Decode #0: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[2]);
console.log("Decode #2: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
decoded = decoderA.decodeStrB64(encodings[1]);
console.log("Decode #1: " +
decoderA.getStatusName(decoded.status) + ", " + decoded.str);
Full Sequencing Sample Project
Eclypses has developed full sample projects demonstrating using MTE sequencing.