#define FIELDOP(op) GLUE(FIELD, _##op)
#define REG_MEMBERS \
- uint8_t fe[FIELDOP(FESZ)];
+ struct { FIELD x; int ok; } fe;
#include "crypto-test.h"
enum {
NREG
};
+static void init_fe(union regval *v) { v->fe.ok = 1; }
+
static void parse_fe(union regval *v, char *p)
{
+ octet buf[FIELDOP(FESZ)];
size_t n = strlen(p);
- size_t sz = sizeof(v->fe);
+ size_t sz = sizeof(buf);
if (!*p)
- memset(v->fe, 0xff, sizeof(v->fe));
+ v->fe.ok = 0;
else {
if (sz > n/2) sz = n/2;
- parse_hex(v->fe, sz, p); memset(v->fe + sz, 0, sizeof(v->fe) - sz);
+ parse_hex(buf, sz, p); memset(buf + sz, 0, sizeof(buf) - sz);
+ FIELDOP(load)(&v->fe.x, buf);
}
}
static void dump_fe(FILE *fp, const union regval *v)
- { dump_hex(fp, v->fe, sizeof(v->fe)); }
+{
+ octet buf[FIELDOP(FESZ)];
+
+ if (!v->fe.ok)
+ fprintf(fp, "nil\n");
+ else {
+ FIELDOP(store)(buf, &v->fe.x);
+ dump_hex(fp, buf, sizeof(buf));
+ }
+}
static int eq_fe(const union regval *v0, const union regval *v1)
- { return (memcmp(v0->fe, v1->fe, sizeof(v0->fe)) == 0); }
+{
+ octet buf0[FIELDOP(FESZ)], buf1[FIELDOP(FESZ)];
+
+ if (!v0->fe.ok)
+ return (!v1->fe.ok);
+ else if (!v1->fe.ok)
+ return (0);
+ else {
+ FIELDOP(store)(buf0, &v0->fe.x);
+ FIELDOP(store)(buf1, &v1->fe.x);
+ return (memcmp(buf0, buf1, sizeof(buf0)) == 0);
+ }
+}
static const struct regty regty_fe = {
- trivial_regty_init,
+ init_fe,
parse_fe,
dump_fe,
eq_fe,
#define BINOP(op) \
static void test_##op(struct reg *out, \
const struct reg *in, void *ctx) \
- { \
- FIELD x, y, z; \
- \
- FIELDOP(load)(&x, in[RX].v.fe); \
- FIELDOP(load)(&y, in[RY].v.fe); \
- FIELDOP(op)(&z, &x, &y); \
- FIELDOP(store)(out[RZ].v.fe, &z); \
- }
+ { FIELDOP(op)(&out[RZ].v.fe.x, &in[RX].v.fe.x, &in[RY].v.fe.x); }
#define UNOP(op) \
static void test_##op(struct reg *out, \
const struct reg *in, void *ctx) \
- { \
- FIELD x, z; \
- \
- FIELDOP(load)(&x, in[RX].v.fe); \
- FIELDOP(op)(&z, &x); \
- FIELDOP(store)(out[RZ].v.fe, &z); \
- }
+ { FIELDOP(op)(&out[RZ].v.fe.x, &in[RX].v.fe.x); }
BINOP(add)
BINOP(sub)
UNOP(inv)
static void test_condneg(struct reg *out, const struct reg *in, void *ctx)
-{
- FIELD x, z;
-
- FIELDOP(load)(&x, in[RX].v.fe);
- FIELDOP(condneg)(&z, &x, in[RM].v.u);
- FIELDOP(store)(out[RZ].v.fe, &z);
-}
+ { FIELDOP(condneg)(&out[RZ].v.fe.x, &in[RX].v.fe.x, in[RM].v.u); }
static void test_mulconst(struct reg *out, const struct reg *in, void *ctx)
-{
- FIELD x, z;
-
- FIELDOP(load)(&x, in[RX].v.fe);
- FIELDOP(mulconst)(&z, &x, in[RA].v.i);
- FIELDOP(store)(out[RZ].v.fe, &z);
-}
+ { FIELDOP(mulconst)(&out[RZ].v.fe.x, &in[RX].v.fe.x, in[RA].v.i); }
static void test_condswap(struct reg *out, const struct reg *in, void *ctx)
{
- FIELD x, y;
-
- FIELDOP(load)(&x, in[RX].v.fe);
- FIELDOP(load)(&y, in[RY].v.fe);
- FIELDOP(condswap)(&x, &y, in[RM].v.u);
- FIELDOP(store)(out[RXX].v.fe, &x);
- FIELDOP(store)(out[RYY].v.fe, &y);
+ FIELD *x = &out[RXX].v.fe.x, *y = &out[RYY].v.fe.x;
+ *x = in[RX].v.fe.x; *y = in[RY].v.fe.x;
+ FIELDOP(condswap)(x, y, in[RM].v.u);
}
static void test_pick2(struct reg *out, const struct reg *in, void *ctx)
{
- FIELD x, y, z;
-
- FIELDOP(load)(&x, in[RX].v.fe);
- FIELDOP(load)(&y, in[RY].v.fe);
- FIELDOP(pick2)(&z, &x, &y, in[RM].v.u);
- FIELDOP(store)(out[RZ].v.fe, &z);
+ FIELDOP(pick2)(&out[RZ].v.fe.x,
+ &in[RX].v.fe.x, &in[RY].v.fe.x, in[RM].v.u);
}
static void test_pickn(struct reg *out, const struct reg *in, void *ctx)
{
- FIELD v[32], z;
- unsigned i;
+ FIELD v[32];
+ unsigned n;
- for (i = 0; in[RV0 + i].f®F_LIVE; i++)
- FIELDOP(load)(&v[i], in[RV0 + i].v.fe);
- FIELDOP(pickn)(&z, v, i, in[RI].v.u);
- FIELDOP(store)(out[RZ].v.fe, &z);
+ for (n = 0; in[RV0 + n].f®F_LIVE; n++) v[n] = in[RV0 + n].v.fe.x;
+ FIELDOP(pickn)(&out[RZ].v.fe.x, v, n, in[RI].v.u);
}
static void test_quosqrt(struct reg *out, const struct reg *in, void *ctx)
{
- FIELD x, y, z;
-
- FIELDOP(load)(&x, in[RX].v.fe);
- FIELDOP(load)(&y, in[RY].v.fe);
- if (FIELDOP(quosqrt)(&z, &x, &y))
- memset(out[RZ0].v.fe, 0xff, sizeof(out[RZ].v.fe));
- else
- FIELDOP(store)(out[RZ].v.fe, &z);
+ if (FIELDOP(quosqrt)(&out[RZ0].v.fe.x, &in[RX].v.fe.x, &in[RY].v.fe.x))
+ out[RZ0].v.fe.ok = 0;
}
static void run_quosqrt(struct test_state *state, const struct test *test)
/* ..._quosqrt returns an arbitrary square root. The test vector
* contains both. We win if we match either.
+ *
+ * So: we always copy the expected Z1 into the computed-Z1 slot. If we
+ * got Z0 wrong, then the test will still fail. If we got Z0 right, then
+ * we'll pass. If our computed Z0 matches the expected Z1, then /also/
+ * pretend we computed Z0 as expected, and then we'll pass.
*/
if (eq_fe(&state->in[RZ1].v, &state->out[RZ].v))
state->out[RZ0].v = state->in[RZ0].v;
static void test_sub_mulc_add_sub_mul(struct reg *out,
const struct reg *in, void *ctx)
{
- FIELD u, v, w, x, y, z;
-
- FIELDOP(load)(&u, in[RU].v.fe);
- FIELDOP(load)(&v, in[RV].v.fe);
- FIELDOP(load)(&w, in[RW].v.fe);
- FIELDOP(load)(&x, in[RX].v.fe);
- FIELDOP(load)(&y, in[RY].v.fe);
-
- FIELDOP(sub)(&z, &u, &v);
- FIELDOP(mulconst)(&z, &z, in[RA].v.i);
- FIELDOP(add)(&z, &z, &w);
- FIELDOP(sub)(&x, &x, &y);
- FIELDOP(mul)(&z, &z, &x);
- FIELDOP(store)(out[RZ].v.fe, &z);
+ FIELD t, u;
+
+ FIELDOP(sub)(&t, &in[RU].v.fe.x, &in[RV].v.fe.x);
+ FIELDOP(mulconst)(&t, &t, in[RA].v.i);
+ FIELDOP(add)(&t, &t, &in[RW].v.fe.x);
+ FIELDOP(sub)(&u, &in[RX].v.fe.x, &in[RY].v.fe.x);
+ FIELDOP(mul)(&out[RZ].v.fe.x, &t, &u);
}
#define REG_U { "u", RU, ®ty_fe, 0 }