From f4bf00abf422ae452bce082a44bc179e67862cad Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 27 Sep 2019 01:04:07 +0100 Subject: [PATCH] ec-field-test.c: Make the field-element type use internal format. And add a flag to distinguish the `bad' output from `..._quosqrt'. --- ec-field-test.c | 136 ++++++++++++++++++++++++-------------------------------- 1 file changed, 59 insertions(+), 77 deletions(-) diff --git a/ec-field-test.c b/ec-field-test.c index 5c29704..51b3e64 100644 --- a/ec-field-test.c +++ b/ec-field-test.c @@ -45,7 +45,7 @@ #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 { @@ -56,27 +56,52 @@ 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, @@ -86,25 +111,12 @@ static const struct regty regty_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) @@ -114,65 +126,37 @@ UNOP(sqr) 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) @@ -181,6 +165,11 @@ 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; @@ -191,20 +180,13 @@ static void run_quosqrt(struct test_state *state, const struct test *test) 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 } -- 2.11.0