Files
failnix/targets/wasm-module/cored.cpp

130 lines
2.8 KiB
C++

#include <stdint.h>
#include "../lib.h"
typedef uint16_t enc_t;
typedef uint8_t plain_t;
typedef int8_t sign_t;
#define REPLICA_COUNT 3
#define check(vc, A, B) (((vc - B) % A) == 0)
#define encode(v, A, B) ((((plain_t)v) * ((sign_t)A)) + ((sign_t)B))
#define decode(vc, A, B) ((vc - B) / A)
#define equals(vc1, vc2, B1, B2) ((vc1 - vc2) == (B1 - B2))
#define THE_A 110
// CONSTANT Replica results signatures
#define SIG_X 32
#define SIG_Y 23
#define SIG_Z 67
#define SIG_MAX SIG_Z
// CONSTANT Voter Result Signatures
#define SIG_s_XYZ ((SIG_X - SIG_Y) + (SIG_X - SIG_Z))
#define SIG_s_XY (SIG_X - SIG_Y)
#define SIG_s_YZ (SIG_Y - SIG_Z)
#define SIG_s_XZ (SIG_X - SIG_Z)
#define XC sum_out[0]
#define YC sum_out[1]
#define ZC sum_out[2]
static enc_t cored_res;
static enc_t sum_out[REPLICA_COUNT];
// The prints here can't happen because they're disabled under test ¯\_(ツ)_/¯
static INLINE enc_t apply(enc_t vc, sign_t bdyn) {
if (bdyn > SIG_MAX) {
HOST_PRINT("signature overflow.\n");
fail_marker_detected();
}
return vc + bdyn;
}
static sign_t cored_vote(void) {
if (equals(XC, YC, SIG_X, SIG_Y)) {
if (equals(XC, ZC, SIG_X, SIG_Z)) {
cored_res = apply(XC, (XC - YC) + (XC - ZC));
return SIG_s_XYZ;
} else {
cored_res = apply(XC, (XC - YC));
return SIG_s_XY;
}
} else if (equals(YC, ZC, SIG_Y, SIG_Z)) {
cored_res = apply(YC, (YC - ZC));
return SIG_s_YZ;
} else if (equals(XC, ZC, SIG_X, SIG_Z)) {
cored_res = apply(XC, (XC - ZC));
return SIG_s_XZ;
} else {
HOST_PRINT("all replicas differ.\n");
fail_marker_detected();
return 0;
}
}
template <const unsigned int N, const sign_t S> static INLINE void sum(void) {
int sum = 0;
for (int i = 0; i < 100; ++i) {
sum += 1;
}
sum_out[N] = encode(sum, THE_A, S);
}
extern "C" EXPORT("wasm_module") int wasm_module(void) {
XC = 0;
YC = 0;
ZC = 0;
fail_start_trace();
sum<0, SIG_X>();
sum<1, SIG_Y>();
sum<2, SIG_Z>();
sign_t static_sig = cored_vote();
fail_stop_trace();
sign_t vote_result_sig;
switch (static_sig) {
case SIG_s_XYZ:
case SIG_s_XY:
case SIG_s_XZ:
vote_result_sig = SIG_X;
break;
case SIG_s_YZ:
vote_result_sig = SIG_Y;
break;
default:
HOST_PRINT("unknown static_sig.\n");
break;
}
// Inversely apply constant program flow signature.
cored_res -= static_sig;
/* Validate Vote result */
if (!check(cored_res, THE_A, vote_result_sig)) {
HOST_PRINT("voted result invalid.\n");
fail_marker_detected();
return 2;
}
plain_t res = decode(cored_res, THE_A, vote_result_sig);
if (res == 100) {
HOST_PRINT("cored success.\n");
fail_marker_positive();
return 0;
} else {
HOST_PRINT("undetected error.\n");
fail_marker_negative();
return 1;
}
}