ec-field-test.c: Make the field-element type use internal format. mdw/xdh
authorMark Wooding <mdw@distorted.org.uk>
Fri, 27 Sep 2019 00:04:07 +0000 (01:04 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 27 Sep 2019 00:04:07 +0000 (01:04 +0100)
And add a flag to distinguish the `bad' output from `..._quosqrt'.

ec-field-test.c

index 5c29704..51b3e64 100644 (file)
@@ -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&REGF_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&REGF_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, &regty_fe, 0 }