}
GCM_WIDTHS(DEF_MULK)
+#define GCM_MULK_CASE(nbits) \
+ case nbits/32: gcm_mulk_##nbits(_a, _ktab); break;
+#define MULK(n, a, ktab) do { \
+ uint32 *_a = (a); const uint32 *_ktab = (ktab); \
+ switch (n) { \
+ GCM_WIDTHS(GCM_MULK_CASE) \
+ default: abort(); \
+ } \
+} while (0)
+
/*----- Other utilities ---------------------------------------------------*/
/* --- @putlen@ --- *
{
unsigned i;
- /* Convert the block from bytes into words, using the appropriate
- * convention.
- */
if (p->f&GCMF_SWAP)
for (i = 0; i < p->n; i++) { a[i] ^= LOAD32_L(q); q += 4; }
else
for (i = 0; i < p->n; i++) { a[i] ^= LOAD32_B(q); q += 4; }
-
- /* Dispatch to the correct multiply-by-%$k$% function. */
- switch (p->n) {
-#define CASE(nbits) case nbits/32: gcm_mulk_##nbits(a, ktab); break;
- GCM_WIDTHS(CASE)
-#undef CASE
- default: abort();
- }
+ MULK(p->n, a, ktab);
}
/* --- @gcm_ghashdone@ --- *
}
}
+/*----- Test rig ----------------------------------------------------------*/
+
+#ifdef TEST_RIG
+
+#include <mLib/quis.h>
+#include <mLib/testrig.h>
+
+static void report_failure(const char *test, unsigned nbits,
+ dstr v[], dstr *d)
+{
+ printf("test %s failed (nbits = %u)", test, nbits);
+ printf("\n\tx = "); type_hex.dump(&v[0], stdout);
+ printf("\n\ty = "); type_hex.dump(&v[1], stdout);
+ printf("\n\tz = "); type_hex.dump(&v[2], stdout);
+ printf("\n\tz' = "); type_hex.dump(d, stdout);
+ putchar('\n');
+}
+
+static void mulk(unsigned nbits, uint32 *x, const uint32 *ktab)
+ { MULK(nbits/32, x, ktab); }
+
+static int test_mul(uint32 poly, dstr v[])
+{
+ uint32 x[GCM_NMAX], y[GCM_NMAX], z[GCM_NMAX], ktab[32*GCM_NMAX*GCM_NMAX];
+ gcm_params p;
+ dstr d = DSTR_INIT;
+ unsigned i, nbits;
+ int ok = 1;
+
+ nbits = 8*v[0].len; p.f = 0; p.n = nbits/32; p.poly = poly;
+ dstr_ensure(&d, nbits/8); d.len = nbits/8;
+
+ /* First, test plain multiply. */
+ for (i = 0; i < nbits/32; i++)
+ { x[i] = LOAD32_B(v[0].buf + 4*i); y[i] = LOAD32_B(v[1].buf + 4*i); }
+ mul(&p, z, x, y);
+ for (i = 0; i < nbits/32; i++) STORE32_B(d.buf + 4*i, z[i]);
+ if (memcmp(d.buf, v[2].buf, nbits/8) != 0)
+ { ok = 0; report_failure("gcm_mul", nbits, v, &d); }
+
+ /* Next, test big-endian prepared key. */
+ for (i = 0; i < nbits/32; i++)
+ { x[i] = LOAD32_B(v[0].buf + 4*i); y[i] = LOAD32_B(v[1].buf + 4*i); }
+ gcm_mktable(&p, ktab, y);
+ mulk(nbits, x, ktab);
+ for (i = 0; i < nbits/32; i++) STORE32_B(d.buf + 4*i, x[i]);
+ if (memcmp(d.buf, v[2].buf, nbits/8) != 0)
+ { ok = 0; report_failure("gcm_kmul_b(k = y)", nbits, v, &d); }
+
+ for (i = 0; i < nbits/32; i++)
+ { x[i] = LOAD32_B(v[0].buf + 4*i); y[i] = LOAD32_B(v[1].buf + 4*i); }
+ gcm_mktable(&p, ktab, x);
+ mulk(nbits, y, ktab);
+ for (i = 0; i < nbits/32; i++) STORE32_B(d.buf + 4*i, y[i]);
+ if (memcmp(d.buf, v[2].buf, nbits/8) != 0)
+ { ok = 0; report_failure("gcm_kmul_b(k = x)", nbits, v, &d); }
+
+ /* Finally, test little-endian prepared key. */
+ p.f = GCMF_SWAP;
+ for (i = 0; i < nbits/32; i++)
+ { x[i] = LOAD32_L(v[0].buf + 4*i); y[i] = LOAD32_L(v[1].buf + 4*i); }
+ gcm_mktable(&p, ktab, y);
+ mulk(nbits, x, ktab);
+ for (i = 0; i < nbits/32; i++) STORE32_L(d.buf + 4*i, x[i]);
+ if (memcmp(d.buf, v[2].buf, nbits/8) != 0)
+ { ok = 0; report_failure("gcm_kmul_l(k = y)", nbits, v, &d); }
+
+ for (i = 0; i < nbits/32; i++)
+ { x[i] = LOAD32_L(v[0].buf + 4*i); y[i] = LOAD32_L(v[1].buf + 4*i); }
+ gcm_mktable(&p, ktab, x);
+ mulk(nbits, y, ktab);
+ for (i = 0; i < nbits/32; i++) STORE32_L(d.buf + 4*i, y[i]);
+ if (memcmp(d.buf, v[2].buf, nbits/8) != 0)
+ { ok = 0; report_failure("gcm_kmul_l(k = x)", nbits, v, &d); }
+
+ /* All done. */
+ return (ok);
+}
+
+#define TEST(nbits) \
+static int test_mul_##nbits(dstr v[]) \
+ { return (test_mul(GCM_POLY_##nbits, v)); }
+GCM_WIDTHS(TEST)
+#undef TEST
+
+static test_chunk defs[] = {
+#define TEST(nbits) \
+ { "gcm-mul" #nbits, test_mul_##nbits, \
+ { &type_hex, &type_hex, &type_hex, 0 } },
+GCM_WIDTHS(TEST)
+#undef TEST
+ { 0, 0, { 0 } }
+};
+
+int main(int argc, char *argv[])
+{
+ ego(argv[0]);
+ test_run(argc, argv, defs, SRCDIR"/t/gcm");
+ return (0);
+}
+
+#endif
+
/*----- That's all, folks -------------------------------------------------*/