symm/gcm.c: Add low-level multiplication tests.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 13 Nov 2018 11:21:59 +0000 (11:21 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 8 Sep 2019 17:33:28 +0000 (18:33 +0100)
symm/Makefile.am
symm/gcm.c
symm/t/gcm [new file with mode: 0644]
utils/advmodes

index 82b1c96..cb20f3a 100644 (file)
@@ -324,6 +324,9 @@ pkginclude_HEADERS  += ocb.h
 BLKCAEADMODES          += ccm eax gcm ocb1 ocb3
 libsymm_la_SOURCES     += ccm.c gcm.c ocb.c
 
+TESTS                  += gcm.t$(EXEEXT)
+EXTRA_DIST             += t/gcm
+
 ###--------------------------------------------------------------------------
 ### Hash functions.
 
index 749f9d6..330ec7b 100644 (file)
@@ -267,6 +267,16 @@ void gcm_mulk_##nbits(uint32 *a, const uint32 *ktab)                       \
 }
 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@ --- *
@@ -327,21 +337,11 @@ static void mix(const gcm_params *p, uint32 *a,
 {
   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@ --- *
@@ -453,4 +453,107 @@ void gcm_concat(const gcm_params *p, uint32 *z, const uint32 *x,
   }
 }
 
+/*----- 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 -------------------------------------------------*/
diff --git a/symm/t/gcm b/symm/t/gcm
new file mode 100644 (file)
index 0000000..cf2b162
--- /dev/null
@@ -0,0 +1,976 @@
+### Low-level tests for GCM multiplication.
+
+gcm-mul64 {
+  cde4bef260d7bcda
+    163547d348b75511
+    c9ee47ed2b156ee9;
+  95e77022907dd1df
+    f7dac5c9941d26d0
+    6dbd5c9c416492a6;
+  c6eb14ad568f86ed
+    d1dc9268eeee5332
+    08bdf4e9bf8c1f93;
+  85a6ed810c9b689d
+    aaa9060d2d4b6003
+    0cf6ee6642648823;
+  062365b0a54364c7
+    6c160f11896c4794
+    79f08ae100e469b0;
+  846ecfa14a7130c9
+    f137120634c95198
+    9f105828be4871c9;
+  48a877ff77bf7919
+    2a5b50ade5d9cd73
+    474a0e6c8b786a42;
+  9a3d1f337f29549e
+    6b0d27a4ba234085
+    44071433860810ec;
+  406a6136512061f7
+    080cc07df0591d8f
+    a09f47fee5c90487;
+  a21f2dd88374d8cd
+    e8e160ad10997a21
+    d1a3ae2849f6e1b3;
+  635c6d62c9269029
+    df3e6057acc87638
+    4d02197152061f71;
+  f508046733d9ff61
+    cdbda3b3e9878731
+    3b567fc5b2fad254;
+  ebfedd4705e505da
+    1435dceaa7b1cc49
+    dee51993e134cdcf;
+  ae1d50c38201a894
+    476b3f102b752eb9
+    8e3e6132a84c2062;
+  529533966f27043e
+    b621b7f65b000961
+    262098e88d669837;
+  040ef2f9b2fc5fa4
+    50727a9b542cde52
+    ad129933b7f306e5;
+  ebfda19d0ccc520f
+    215eb57bb3a4f3eb
+    95e06cd4d7f6453a;
+  bbb18ac6c95a97a4
+    8030370c33d090c5
+    0acd90305b863292;
+  4215abd6b3ad54ef
+    c9a38378c5b93bf4
+    9f21b3656650b80d;
+  f2aad2605faee2b0
+    3fb648e27fff6310
+    53448ad6016b5a88;
+  2758fe2b69ac26af
+    a3349829b9458630
+    7a114f9030a64751;
+  6fed54154f8f2852
+    3c03d4de16001578
+    91532dc3dcd1b8fe;
+  46b710ee72807a22
+    19bfb474fd71d891
+    877c3092f14be92e;
+  f24bb65d1563259f
+    9eb53b571ea629c5
+    26fa6c3a6205f520;
+  4d57dd2d42f70800
+    df9fcbaca48b77db
+    baa61b8ee2efee4b;
+  a189196d1ebba10b
+    0467cb9fc2712a19
+    a7b5b29b8359b2d3;
+  9e533fa9156308cd
+    ec3f768281e040a9
+    30ae2526b8601e66;
+  b9a222bd689aef66
+    f5306ceb0c6b08ac
+    3656b2206364b85f;
+  8b0a22260c571b4a
+    42bb8fdb233bfa6a
+    351d3f9025791fb4;
+  5cfb0bad7d95214a
+    de49cb3b6f5fe836
+    3c571fdf110d88d3;
+  8131115c037ba323
+    fe1dc8151784873f
+    a5280a7d7bf3fbd5;
+  0eb5b647da6794c1
+    8b5337685a96ed65
+    15a80ceb4c5612d9;
+  b9aca338527ef19b
+    09c063c46f88de9f
+    506d2129368b3535;
+  d41e72d7b97e23e6
+    eabdff3bcd211499
+    a9485bc115054e16;
+  268878dbf30f1dad
+    89d4b9b12012e471
+    d33c8040301aa9d6;
+  3df46795630e7952
+    d22bb02d7100b8b6
+    c351d03535b15a43;
+  49377d20a8f08345
+    5b663e4ee1315f3c
+    659490124597d0ac;
+  8f2aebfa921451dc
+    d1af5813b70d30ce
+    a1265ff538452f9b;
+  2f1fef6ef315d079
+    8391805da08da3ae
+    090119c5295ce005;
+  fc5f8584b7c5e617
+    669c0f16e39815d4
+    fc0d6997230f9340;
+  e9cfce3ed1ecdf3d
+    264a7f16cb16c2e8
+    173b0d65b7f7defa;
+  15f422cdf0c8e303
+    08be3c31e6bc58c0
+    95789ad1072e5991;
+  b7cadcb658b970e4
+    7479a684b5aefa69
+    5681dbf13399af21;
+  a4cd52147ed12ca9
+    86981a874498ad0a
+    69266124234d8824;
+  bef8bc4fcb70e27e
+    98ef1f0446b42fb1
+    9ce3c0c2bd679e5d;
+  44d44b6d00f06dc1
+    88d472a784e0c6f2
+    d4d0dde377de138c;
+  1195a3b9f4ae9855
+    11265febd11c1647
+    324150243bf34600;
+  20eef9eb1c8dd0b0
+    0951f284649016ed
+    15cb17aa733f44ba;
+  00456331854bc78b
+    f43966eb0cfa9138
+    4c8fd598a01bf479;
+  ddc39908445608fe
+    95e81c2533e31c9c
+    5341133994016920;
+  1a9851bc2810d858
+    cbbc8424d126b807
+    470ff40df79063ab;
+  e6daa089c3f9099c
+    5ffb824173d7634c
+    0a778cecd0cafb7a;
+  04226f30cbb7f0e4
+    a973a8cd19010731
+    85a0294ea292354a;
+  4717a77456f3ff66
+    9c732b58db8f48af
+    636a37a3d5c97941;
+  65f7cc9e3fb90e17
+    21b730374ffc9bc5
+    64dccdd7dfb08b84;
+  97f56ccbb2f294b3
+    8766fc69f6a9f2c0
+    bf6f50d14cf7e5b8;
+  945ffd505003cc0c
+    ae9ce021a5f1fa4f
+    37035c953d053e5f;
+  fa91544485f1a125
+    8b2b9b8f0911e32d
+    9c50f40823733f0b;
+  65cc1770a18cbfe6
+    effd1ff6778554ac
+    11d7d33017171bc2;
+  f1270485b203a3c1
+    c4c967c0a458cb94
+    75e2e1a04e3ad3d7;
+  8bdd409b687fa3a6
+    827b480aa3a4c84c
+    e40958395d2015c9;
+  ef64f6c9b53bf8f9
+    57f4b03cf43e8995
+    cc0ff0246e3ea756;
+  7f9a3e8128f8743d
+    16687b7bb8deb9bd
+    e7afa3631ceb1d83;
+  205b70e04c091d20
+    5cdad9e9a79b1abf
+    295070cfdc2c3748;
+}
+
+gcm-mul96 {
+  cde4bef260d7bcda163547d3
+    48b7551195e77022907dd1df
+    4eec45fb8fc3b3e39aac7aae;
+  f7dac5c9941d26d0c6eb14ad
+    568f86edd1dc9268eeee5332
+    05134f056f51918c72e23289;
+  85a6ed810c9b689daaa9060d
+    2d4b6003062365b0a54364c7
+    bcfba16699cf54c7b4827b8c;
+  6c160f11896c4794846ecfa1
+    4a7130c9f137120634c95198
+    b831f2da94b112266bd6bc3e;
+  48a877ff77bf79192a5b50ad
+    e5d9cd739a3d1f337f29549e
+    5ad06fd826c670ca741020ec;
+  6b0d27a4ba234085406a6136
+    512061f7080cc07df0591d8f
+    e29fc44efee1497b3d29ef65;
+  a21f2dd88374d8cde8e160ad
+    10997a21635c6d62c9269029
+    5cc40a00243b31c565f37eba;
+  df3e6057acc87638f5080467
+    33d9ff61cdbda3b3e9878731
+    dccd19797b205b612986e298;
+  ebfedd4705e505da1435dcea
+    a7b1cc49ae1d50c38201a894
+    e8be723b884eb9f69e388db1;
+  476b3f102b752eb952953396
+    6f27043eb621b7f65b000961
+    bc04044aaaef558b55e3dd7b;
+  040ef2f9b2fc5fa450727a9b
+    542cde52ebfda19d0ccc520f
+    de533f5f43678c1072d64ef8;
+  215eb57bb3a4f3ebbbb18ac6
+    c95a97a48030370c33d090c5
+    861b3f005e294a74ae9d78b5;
+  4215abd6b3ad54efc9a38378
+    c5b93bf4f2aad2605faee2b0
+    bd3d716b1535654fc1336c3f;
+  3fb648e27fff63102758fe2b
+    69ac26afa3349829b9458630
+    9199c9fc5fe891d9b22fe7c5;
+  6fed54154f8f28523c03d4de
+    1600157846b710ee72807a22
+    66f5090ef7912cd1c4b4ebec;
+  19bfb474fd71d891f24bb65d
+    1563259f9eb53b571ea629c5
+    11a1ad6bd0e17aa45aa29d18;
+  4d57dd2d42f70800df9fcbac
+    a48b77dba189196d1ebba10b
+    5887206626c27472a811261c;
+  0467cb9fc2712a199e533fa9
+    156308cdec3f768281e040a9
+    f6c50c86da0692784633b96a;
+  b9a222bd689aef66f5306ceb
+    0c6b08ac8b0a22260c571b4a
+    6b5169d0ead2cf118bead4a1;
+  42bb8fdb233bfa6a5cfb0bad
+    7d95214ade49cb3b6f5fe836
+    23aeda3be39212e86bc0be3b;
+  8131115c037ba323fe1dc815
+    1784873f0eb5b647da6794c1
+    711e6d0a1d2f28008b8c1ff1;
+  8b5337685a96ed65b9aca338
+    527ef19b09c063c46f88de9f
+    5fcf403f2c1cbd40c5a2b2bf;
+  d41e72d7b97e23e6eabdff3b
+    cd211499268878dbf30f1dad
+    8f025a46e6a1c48a74cad7a4;
+  89d4b9b12012e4713df46795
+    630e7952d22bb02d7100b8b6
+    e147d342d3feee155226d69b;
+  49377d20a8f083455b663e4e
+    e1315f3c8f2aebfa921451dc
+    bd0327387c43f688f66cdbbe;
+  d1af5813b70d30ce2f1fef6e
+    f315d0798391805da08da3ae
+    08fa0a0c901d0d0965968170;
+  fc5f8584b7c5e617669c0f16
+    e39815d4e9cfce3ed1ecdf3d
+    98add0390bd310fa096f453f;
+  264a7f16cb16c2e815f422cd
+    f0c8e30308be3c31e6bc58c0
+    cd186496b610dd8764aa152d;
+  b7cadcb658b970e47479a684
+    b5aefa69a4cd52147ed12ca9
+    c2de0b36d4dea7af5bbaf035;
+  86981a874498ad0abef8bc4f
+    cb70e27e98ef1f0446b42fb1
+    9d2ab48640b402ade690ca33;
+  44d44b6d00f06dc188d472a7
+    84e0c6f21195a3b9f4ae9855
+    6c5c40b6a299efd5663d5010;
+  11265febd11c164720eef9eb
+    1c8dd0b00951f284649016ed
+    3c0b6a72988abb596a30e347;
+  00456331854bc78bf43966eb
+    0cfa9138ddc39908445608fe
+    7e180f9395090b8646d62aa4;
+  95e81c2533e31c9c1a9851bc
+    2810d858cbbc8424d126b807
+    78ae33d19f5d9ba3b2158f0a;
+  e6daa089c3f9099c5ffb8241
+    73d7634c04226f30cbb7f0e4
+    922a3fa3bb9704aa3cb0c627;
+  a973a8cd190107314717a774
+    56f3ff669c732b58db8f48af
+    f5996b9d374f4174367ca998;
+  65f7cc9e3fb90e1721b73037
+    4ffc9bc597f56ccbb2f294b3
+    799bda7e13675b504cc15d48;
+  8766fc69f6a9f2c0945ffd50
+    5003cc0cae9ce021a5f1fa4f
+    62aaf766cc72b312acf6b867;
+  fa91544485f1a1258b2b9b8f
+    0911e32d65cc1770a18cbfe6
+    5fe1f589f40181cef0aeaf9b;
+  effd1ff6778554acf1270485
+    b203a3c1c4c967c0a458cb94
+    8847d0b844fc9063ff111626;
+  8bdd409b687fa3a6827b480a
+    a3a4c84cef64f6c9b53bf8f9
+    1b937802f75d4ebc4f3d7a86;
+  57f4b03cf43e89957f9a3e81
+    28f8743d16687b7bb8deb9bd
+    a53eb13d45700a7885120b81;
+  205b70e04c091d205cdad9e9
+    a79b1abf91b0851e5ca605ac
+    d448d6ac6e6eb01171b14634;
+  8451399587011677508a15dd
+    e524af3e2bee0646541a42c2
+    dab29efd14f77990ca5d724a;
+  ecccb44d65bad397abfaf529
+    ee41cf9a05c7efedef340153
+    fea1ab4c3083794c01303a23;
+  9c51d2a90bbf7f1bfc338ab0
+    ef5746ea8fdcccd213e33f7e
+    74b7906ccadf56726f06016c;
+  8a5718fd25014107c8e7d715
+    a92add9589d1f5c054b2d983
+    20656261ca5136c2bf69b1d1;
+  514605ec590294a319b98020
+    68a9f891bc5ba5afabf8c312
+    55d0d749027044ab80ecfb46;
+  2d12d7ff3c41122d70d17d45
+    69eaff59a332ba58d5d5589b
+    a4de245c51057e4ca49e06d7;
+  fe079753ee1a957eb6d6699e
+    6b7ea2725cb2dac07ecde957
+    ad498f1966703fd2cbad5b6d;
+  59ac46fee6dda7abc8ad68da
+    ac90cfe22d2f1f2968cc42fa
+    f415976427d6fe6ff4547d08;
+  8b669ed3bb3542a9cf44bbc8
+    c6254d980398bd94e66eb456
+    afe3c9c5ded2010edc99564f;
+  3d405e51881e99027b8ab9ae
+    a3ccf860b0009740763d9683
+    1ee6d3bc94ea166843327955;
+  6c5f87b95460938de1288c69
+    d80ea12ff4bb5f069b8a2e86
+    046ba565c8674b84f22ac9a3;
+  041c1b9fc214e9ca2186ddf1
+    f6a7a3aa7e740da967828e36
+    9c0b170f7e8ca9958dcfc12f;
+  04b35b15ffaa6c36800d9645
+    563a308ba60076817523bd2a
+    cff407868fb153b9b51fface;
+  bf1261b089d8f23a9c283507
+    6a23faac2cdd67771cc667a8
+    7006da38a1cf3992ef37b338;
+  331f0a170b66283e4f834a06
+    148f302c3973accd56f6f24e
+    d493d3e118362ffe57ffce5a;
+  33958b8c2e2352fd61e4fa8f
+    ec816ac861a8b33779f09e7a
+    f700eeecf80cfd35a7c249c8;
+  10fc02a8f48afa3080ee119a
+    52a9a817e4f2b94b0820cab3
+    41f9bc5aceef5e3c164829d6;
+  83a8cffeea7c486315799dc8
+    75fba578c8ec4837898a9214
+    9ab99439ea7108fdd2b3a68a;
+  2b5b0677da1ac273117b45bc
+    fff5d5f8b6fde2893232a9f8
+    ed9e4c863cac39665c322566;
+  1d14517ffae475f6b94a43a6
+    7b3d380d2f9aaafe2dd721c0
+    a84bebd2a47410cb5320cd55;
+  095c8808847689211450ba80
+    95ffab1eaadf66fd22ac1976
+    09742e21f274088ba0c8fcc0;
+}
+
+gcm-mul128 {
+  cde4bef260d7bcda163547d348b75511
+    95e77022907dd1dff7dac5c9941d26d0
+    ae22821f55ada6b996c3818891f4ec1d;
+  c6eb14ad568f86edd1dc9268eeee5332
+    85a6ed810c9b689daaa9060d2d4b6003
+    c23e2072f3dbef54a6d43f840a45cd25;
+  062365b0a54364c76c160f11896c4794
+    846ecfa14a7130c9f137120634c95198
+    e4c3bf75dfae8f6201d306bb612d2757;
+  48a877ff77bf79192a5b50ade5d9cd73
+    9a3d1f337f29549e6b0d27a4ba234085
+    b5e1c1885725019124e64e12a7f7a284;
+  406a6136512061f7080cc07df0591d8f
+    a21f2dd88374d8cde8e160ad10997a21
+    83dc338673e6dce375f0c9e9c3853a3f;
+  635c6d62c9269029df3e6057acc87638
+    f508046733d9ff61cdbda3b3e9878731
+    48660987fa15f010812e499b7e448508;
+  ebfedd4705e505da1435dceaa7b1cc49
+    ae1d50c38201a894476b3f102b752eb9
+    1be7a7b553d5f4e88c6bdda1162fc56b;
+  529533966f27043eb621b7f65b000961
+    040ef2f9b2fc5fa450727a9b542cde52
+    7c48e4ab5e27e4f79f7c02e4e171cc2b;
+  ebfda19d0ccc520f215eb57bb3a4f3eb
+    bbb18ac6c95a97a48030370c33d090c5
+    45d12390797c08a0c3cc9244cd56b922;
+  4215abd6b3ad54efc9a38378c5b93bf4
+    f2aad2605faee2b03fb648e27fff6310
+    c53ccfdb25d06cd49acea8481c953bb7;
+  2758fe2b69ac26afa3349829b9458630
+    6fed54154f8f28523c03d4de16001578
+    413a6503df527330e38a5e62d61677da;
+  46b710ee72807a2219bfb474fd71d891
+    f24bb65d1563259f9eb53b571ea629c5
+    4c22f463e2528bfff499d3337d32a921;
+  4d57dd2d42f70800df9fcbaca48b77db
+    a189196d1ebba10b0467cb9fc2712a19
+    068a3e3a1cf5552b90d915e565c76c47;
+  9e533fa9156308cdec3f768281e040a9
+    b9a222bd689aef66f5306ceb0c6b08ac
+    1463b22c7b22f4b483ceff293a405c18;
+  8b0a22260c571b4a42bb8fdb233bfa6a
+    5cfb0bad7d95214ade49cb3b6f5fe836
+    d1be35fea22f3168cb22d7b044c4a53b;
+  8131115c037ba323fe1dc8151784873f
+    0eb5b647da6794c18b5337685a96ed65
+    39ee791290bd770cc3747c82e906de45;
+  b9aca338527ef19b09c063c46f88de9f
+    d41e72d7b97e23e6eabdff3bcd211499
+    5e39550b65471a1a5a8db0a1a36ba3a6;
+  268878dbf30f1dad89d4b9b12012e471
+    3df46795630e7952d22bb02d7100b8b6
+    f1f7219c57aca09072abd1a4b5dc211c;
+  49377d20a8f083455b663e4ee1315f3c
+    8f2aebfa921451dcd1af5813b70d30ce
+    c53ec2fa18d6dd8749295e7246056537;
+  2f1fef6ef315d0798391805da08da3ae
+    fc5f8584b7c5e617669c0f16e39815d4
+    ba9f8b1bbaaca05549621835352a0732;
+  e9cfce3ed1ecdf3d264a7f16cb16c2e8
+    15f422cdf0c8e30308be3c31e6bc58c0
+    e24b90e7ca7ee0094901641a6ed9efe3;
+  b7cadcb658b970e47479a684b5aefa69
+    a4cd52147ed12ca986981a874498ad0a
+    6a8831e02852976a844c69f551cd6617;
+  bef8bc4fcb70e27e98ef1f0446b42fb1
+    44d44b6d00f06dc188d472a784e0c6f2
+    d8ede7cda85607c85ca2aa454275cab5;
+  1195a3b9f4ae985511265febd11c1647
+    20eef9eb1c8dd0b00951f284649016ed
+    b7690610ba96abfaa395dc709830c17d;
+  00456331854bc78bf43966eb0cfa9138
+    ddc39908445608fe95e81c2533e31c9c
+    7b23455563491e6234d7f3976ed92534;
+  1a9851bc2810d858cbbc8424d126b807
+    e6daa089c3f9099c5ffb824173d7634c
+    4111b410f25d6c27ef36e4c0744e06dd;
+  04226f30cbb7f0e4a973a8cd19010731
+    4717a77456f3ff669c732b58db8f48af
+    f3ed8ac5133b62dc453bb3b845371f07;
+  65f7cc9e3fb90e1721b730374ffc9bc5
+    97f56ccbb2f294b38766fc69f6a9f2c0
+    97bd7eac33021557df0c54ca9b45c4b3;
+  945ffd505003cc0cae9ce021a5f1fa4f
+    fa91544485f1a1258b2b9b8f0911e32d
+    074736b8f03cfe2d058b60a60c1c42b2;
+  65cc1770a18cbfe6effd1ff6778554ac
+    f1270485b203a3c1c4c967c0a458cb94
+    e6159e8e83f7acbcd6e3c1530ec97a31;
+  8bdd409b687fa3a6827b480aa3a4c84c
+    ef64f6c9b53bf8f957f4b03cf43e8995
+    47c1e7905f2f87b6a522a2eb83b6e7cd;
+  7f9a3e8128f8743d16687b7bb8deb9bd
+    205b70e04c091d205cdad9e9a79b1abf
+    48d09e17f51f54cb44113d4f22d19bee;
+  91b0851e5ca605ac8451399587011677
+    508a15dde524af3e2bee0646541a42c2
+    7b880e45b35f9b942de7b817ad2d3921;
+  ecccb44d65bad397abfaf529ee41cf9a
+    05c7efedef3401539c51d2a90bbf7f1b
+    0f092a20ab3a445fa314921920e68a7b;
+  fc338ab0ef5746ea8fdcccd213e33f7e
+    8a5718fd25014107c8e7d715a92add95
+    b03bdb56bcea03d7a98444d06c4d9949;
+  89d1f5c054b2d983514605ec590294a3
+    19b9802068a9f891bc5ba5afabf8c312
+    7c950c3817abf217b1bb67c78dbc9ce1;
+  2d12d7ff3c41122d70d17d4569eaff59
+    a332ba58d5d5589bfe079753ee1a957e
+    22164f3d69c20fb9a211645810a980b5;
+  b6d6699e6b7ea2725cb2dac07ecde957
+    59ac46fee6dda7abc8ad68daac90cfe2
+    f916129ec57c478ffd99077e76fb9f0b;
+  2d2f1f2968cc42fa8b669ed3bb3542a9
+    cf44bbc8c6254d980398bd94e66eb456
+    ccacc0839b857afecba7bbd5ca6b2e2c;
+  3d405e51881e99027b8ab9aea3ccf860
+    b0009740763d96836c5f87b95460938d
+    b5dc31fc7ae8d1a7c4b638fa22490910;
+  e1288c69d80ea12ff4bb5f069b8a2e86
+    041c1b9fc214e9ca2186ddf1f6a7a3aa
+    9445b9b898beeb32a4d1ce0ab979c740;
+  7e740da967828e3604b35b15ffaa6c36
+    800d9645563a308ba60076817523bd2a
+    765a9b5e6dd62f8b3bba62382a58f149;
+  bf1261b089d8f23a9c2835076a23faac
+    2cdd67771cc667a8331f0a170b66283e
+    7ae006a4c122e24d4f7e3ff2c6f1354d;
+  4f834a06148f302c3973accd56f6f24e
+    33958b8c2e2352fd61e4fa8fec816ac8
+    2935d8d91408993ddb7a7d0d8db8516a;
+  61a8b33779f09e7a10fc02a8f48afa30
+    80ee119a52a9a817e4f2b94b0820cab3
+    ae4fd2f3a8d384e0b395461a8e326022;
+  83a8cffeea7c486315799dc875fba578
+    c8ec4837898a92142b5b0677da1ac273
+    9b0c75856b1c2972cb990106690d373b;
+  117b45bcfff5d5f8b6fde2893232a9f8
+    1d14517ffae475f6b94a43a67b3d380d
+    5b7b6a4fdfcf0c8a6d67f240458b70f3;
+  2f9aaafe2dd721c0095c880884768921
+    1450ba8095ffab1eaadf66fd22ac1976
+    729752ad6453d80b3d31e7433be19add;
+  063e113ab61f813e28a1397a7974a1d7
+    f4220c785fe426a5a0e80f678d404147
+    dc51774484281b3ab9cd2859a1f91063;
+  842941feeffdc2eb44dc8c0d5e8f444f
+    7f4e0c893959b74dc23a7bb40e7e0013
+    1a01406d34cf1da32e48b55e792b37e9;
+  e5150686d2301b43a15a84e81d7f5ced
+    aa49e2414ebf47970e560475cff20687
+    0e9125c21526a8dc35085476ffbd523d;
+  7de69146acc3ab6cf8556b7aa7769459
+    48d1b8834df2196c92ec1718dcdeee0d
+    31df775698abd477c7c389bbade1026b;
+  52d9539726d2810391b3f9d10c39b07a
+    e8f08ce7cee4758a386a9943e97dedfb
+    87800aad52281a95fb85fb4679774add;
+  e61e737882cd09c2b9a80f34c0fde11c
+    2481b11fc76bfa4dbf710a9e544e0c53
+    a3b71ba7cd2e15c70cd5d40d6d145d1b;
+  6ca1e040f9ad5b04140d98edabe08485
+    290a4d87d13b07398a1458c2c6b61dbd
+    fdba17a43c6d190d2318855a2645748b;
+  bc1cccada8c1a0a9aabb6c4e3c3554f8
+    fb1ef61614c270295dfc0ca6551ca4bd
+    c7eabdcdea64775c683fa87614816b9e;
+  b75359f91cb9d921056b7de74fc9a9b3
+    7154ce6c0b396179d31f06a1dd5982cb
+    a3fa226d9cd4183023e8061d3c3c7666;
+  c0d7cb23841da1ae8f4ae480cda98ad6
+    cf2bacf6f9fd3f821330c43f3df6c2b3
+    635a20300e343fbd26211c9ff3ea26d5;
+  fac7cbcf96523d4723f91801325eb855
+    3236651c96788d73d192ee53b3f3ebd6
+    1ac40bd24b41dcc095e25dd6f5647d68;
+  6ddd98cedbe88e245de25b1593b70f86
+    01562d90a9b59ed034a867642d25d547
+    fe9b405f0a0e3d917075a2ce8282a881;
+  56fa5c47f16f64b837bb4926214211a1
+    c696ba172010abb433922a22d9fd8815
+    384b8bc7a4a1135a6bdf3c36756b0774;
+  19165eb9d85197a21cc34ac0d5ae7be8
+    dbf98e4ffed2cf6b1372a5aa47b54fd9
+    0b197a28af39b496a4d82db88cfa51b2;
+  d70c70e117bf1cae71b3a56f0e7d839e
+    a59cc783443d64f2ed6a29b96856beca
+    ab4ef17dac09d42ecaaac8d50643d89a;
+  34fd6544bcf86b799e2a1681160ccf05
+    5f0fd3001da597a1406d465b7b1419ea
+    c964db11b22df7e476eac1448500114e;
+}
+
+gcm-mul192 {
+  cde4bef260d7bcda163547d348b7551195e77022907dd1df
+    f7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee5332
+    3bf1ea9b1ebee7e9444aaf08e585b09b31e67d3c95c9612d;
+  85a6ed810c9b689daaa9060d2d4b6003062365b0a54364c7
+    6c160f11896c4794846ecfa14a7130c9f137120634c95198
+    aa859fbc2a8ddcff234ac6e350b0e0c1a62f882f77219ce3;
+  48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e
+    6b0d27a4ba234085406a6136512061f7080cc07df0591d8f
+    6caddb90ad1aaf422acc28e99d650fa1a3d7b480101b3b32;
+  a21f2dd88374d8cde8e160ad10997a21635c6d62c9269029
+    df3e6057acc87638f508046733d9ff61cdbda3b3e9878731
+    f8d6b247d97ac3252c49a7544bbde8a0e45a999bc81b156b;
+  ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894
+    476b3f102b752eb9529533966f27043eb621b7f65b000961
+    27177d063a813ad4be51f4360cb3933bf6ccc1bb64c5cb32;
+  040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f
+    215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5
+    c03117b28345bbbbdf657e220e2f23de46743a5591e66d69;
+  4215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b0
+    3fb648e27fff63102758fe2b69ac26afa3349829b9458630
+    9c0ce16e01e9376fb28c571aa2401c7be69cabc249323ab4;
+  6fed54154f8f28523c03d4de1600157846b710ee72807a22
+    19bfb474fd71d891f24bb65d1563259f9eb53b571ea629c5
+    e869d24bde7293357bb17686c423591a891c40eb75e9cf8c;
+  4d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b
+    0467cb9fc2712a199e533fa9156308cdec3f768281e040a9
+    26ca24fde1d3d37a5e3dc72acf6d2b31ab1d084caa3dc205;
+  b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a
+    42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836
+    ee889525ce4e6531e0eb218a0e72bdad13ecc5a1842d16f6;
+  8131115c037ba323fe1dc8151784873f0eb5b647da6794c1
+    8b5337685a96ed65b9aca338527ef19b09c063c46f88de9f
+    12eeda395ce56e2170f6671f527f165f1992cc1940b552f7;
+  d41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad
+    89d4b9b12012e4713df46795630e7952d22bb02d7100b8b6
+    55153969c52056416bfd39a39cd2417339c800620227b450;
+  49377d20a8f083455b663e4ee1315f3c8f2aebfa921451dc
+    d1af5813b70d30ce2f1fef6ef315d0798391805da08da3ae
+    7e3e26d9c6514465ae7258f1ed4909c83ea1bbcb8a0b2947;
+  fc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d
+    264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0
+    8acad6c66a7d17fc4e55a164408cf9ad42974ee147d6fd0f;
+  b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca9
+    86981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb1
+    b62791c6430580b6921bda4e8f0dc67a3cd4c344ba87a56a;
+  44d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae9855
+    11265febd11c164720eef9eb1c8dd0b00951f284649016ed
+    9a063e0f09a4fc2e41a63b38564fc07c578df43375a31c9b;
+  00456331854bc78bf43966eb0cfa9138ddc39908445608fe
+    95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807
+    6eb9bc75eb709c4a6f63d8121d25b8777f5ea3af865ce812;
+  e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4
+    a973a8cd190107314717a77456f3ff669c732b58db8f48af
+    0b3e51503a58f410adb27a6203a8966d47657d481a302d23;
+  65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b3
+    8766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4f
+    82de8284669677b6832d83675af4fe5462636a530459d49a;
+  fa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6
+    effd1ff6778554acf1270485b203a3c1c4c967c0a458cb94
+    61d8b471ee449edb41627d254bfbfcbca10babbc1460d5f8;
+  8bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f9
+    57f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd
+    254a831b866aad0f5e51943fc70c5ccaa7b9adba85762f00;
+  205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac
+    8451399587011677508a15dde524af3e2bee0646541a42c2
+    418f551166e166e2e89fdc3d3a7a1e60e50e472c349da9de;
+  ecccb44d65bad397abfaf529ee41cf9a05c7efedef340153
+    9c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e
+    ecf94369195385ea66741348bd0e796c461293ad8b1d1895;
+  8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983
+    514605ec590294a319b9802068a9f891bc5ba5afabf8c312
+    245f715f907f93b9b5277b55f844f5b4aa732ac698a76f95;
+  2d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589b
+    fe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde957
+    233a36249df31b12a3da455a1ff4c34f457399aa9ae8194c;
+  59ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa
+    8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb456
+    db7a3e16e9aafeab616ce0fd985073f9eefbcb08c69985b7;
+  3d405e51881e99027b8ab9aea3ccf860b0009740763d9683
+    6c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86
+    7fc4a6d0b794e1bc893a00969479168876f166d1140aa9e7;
+  041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e36
+    04b35b15ffaa6c36800d9645563a308ba60076817523bd2a
+    da67471cfae7c99a25eb0f23d5081e6f05888ef4c7c5651a;
+  bf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8
+    331f0a170b66283e4f834a06148f302c3973accd56f6f24e
+    6a391d4b0a662c09d3807c90dfcb8f230e260dacb89943e0;
+  33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a
+    10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab3
+    8ae8f405accb95e13d86bed19e63f6d6efe47264a46960ca;
+  83a8cffeea7c486315799dc875fba578c8ec4837898a9214
+    2b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f8
+    72892f188dce0da69ee68b3782ead0d40f1748fbec7dfd06;
+  1d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0
+    095c8808847689211450ba8095ffab1eaadf66fd22ac1976
+    281ef0eff8afd5233318b564c8ed228e76c075ba61e7bd6b;
+  063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5
+    a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f
+    4fa4ca4d35e133d9d94815fc1bd294792bf73d2cb470eef3;
+  7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43
+    a15a84e81d7f5cedaa49e2414ebf47970e560475cff20687
+    9d7c763547460f559d2ace4bc185f365e0c634e9ddffe0fd;
+  7de69146acc3ab6cf8556b7aa776945948d1b8834df2196c
+    92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07a
+    33c5a1a6645c8ea5e2a1bd5c3d8a05ed1fbf25bc16b969b1;
+  e8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2
+    b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c53
+    14ed2a6864c16b031fe425f0edd51930c4e09a1672e28578;
+  6ca1e040f9ad5b04140d98edabe08485290a4d87d13b0739
+    8a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8
+    ae886c5aa093d9c66b6de64062eccf3c5d2c3fb763bdde09;
+  fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921
+    056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cb
+    877d80fe26e43415303f4590f934354f265aefc3aa7bf85c;
+  c0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f82
+    1330c43f3df6c2b3fac7cbcf96523d4723f91801325eb855
+    9ffdb8a099964dd83b1936e57a1c3511c92c68e0c712d1ba;
+  3236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e24
+    5de25b1593b70f8601562d90a9b59ed034a867642d25d547
+    6bd995f6829d0ac4d313f7ab100ea03ffbac19de700dce3a;
+  56fa5c47f16f64b837bb4926214211a1c696ba172010abb4
+    33922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8
+    1fbdf165adb07f53ff3ea39a33a82ab9a5cb243259c5ec1d;
+  dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae
+    71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca
+    14c2eb66e8aa8bdcd09978ebcb905473a8edff6c771da7f1;
+  34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1
+    406d465b7b1419ea51cf858f938f6daafbd656445a09898e
+    c1f403fe552c5a3d008512eb2d015705e149072ce1d3e69a;
+  aa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eed
+    b969ffe07669845ebb7a24c69f13d099f47166edf54538e8
+    a033fe30ee8714a173e1fd5c821ff2c5aeaeda27c3a9dcca;
+  8fbf433a7ff212085179e79771f6eee7283ab178ef2b800d
+    7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901
+    ecff14eb486025a840e4b7d8b43075a87de1cac31cf05804;
+  ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e90029
+    26ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb
+    936b458a28fc0c6de0ea6f10e49cc13892899a112fa175b4;
+  84241986c251f5b70be2367f047265264e0da72efe8995e6
+    c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279
+    c106ea40f0e1a1cab89dfd44d27bec7ad878e4bfdefb1c8a;
+  d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7
+    e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d
+    5962497cc337df2622d05213a1d8a5048ad7f017cc53b01e;
+  907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5
+    748729720a320fe14fd29cfc59314fe2079c0a2535ded561
+    cec57ed2e38528db38facc00e2cc658f681f371ccd55af54;
+  12d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9ca
+    f02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd1
+    d4186ea94ce6b6e90797ce6c5c09a2f136e758b7bbc332a0;
+  8c374fc43581d2f72a89584a2404a059f7f99c7241a0c879
+    d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3
+    55dc606dc9bad711515603b589f1e1227c03826c0d017b3d;
+  bc6d94238ab56d738e02abd651477cd726d6f3ebcd6fadea
+    b50906642a7de6496247060e7be3632ed9bd94bb42f45a87
+    97ef18739ec98e9cff77ca3f323b567df45c8ca5e5f3b310;
+  33b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad
+    09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86
+    5671fca885dd004ba927253cd0342c5e0bfbdaddc608dcd0;
+  c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b61
+    2ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c83983
+    e587e42c1e61c6ceadea37c68bfb715e01a15c47730ac81b;
+  9c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680
+    332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e
+    87aa1604b5d3a8bc2b6b8bc67d37a3dbfc3d12b19cbc43ae;
+  57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea
+    358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dc
+    9e06e282ca2a9286bedf70783876f36cc238cca76cf81dab;
+  c73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7
+    496993a25b072945d83f923e66b0a6689cf0969c003a8fca
+    54ce4a46639bb8b1627fcb98bb76270c615f5a4411c8c754;
+  80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b
+    9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee7
+    0b77cb7790f367b2b8465ddec635b6d272e78c5f8670dab0;
+  8ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf
+    2fb5b205e592c172a5cbc19456c95c1bea6079f3867e52d6
+    3dbca1bf0639237a10ee151674812fb5a4459614d405ea17;
+  63cb3884b2a0a8ff825df752423f3179bfeb89eca385f20d
+    dce5f1f23564672e370ffc37d400a31e8aac1d426ce10df7
+    3186bd4e2bd9b82499779406fa93fe98d2d74a9de4f94cfe;
+  3c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b6
+    27e7d01b38a84a6de738721ed80fd0d7f69fa658abb5a440
+    83f9caa8826f361ae7b7015fed42ed61d964258e4b9aa944;
+  d304128719b541a9451cead18e4c61d93d1f8fcc53574427
+    767396322b3bf7d02cec05093696cec07591ada462271b1d
+    a6cb63d9b94d2269e85bb551f019180b8daaf1461946a2f1;
+  1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a
+    34a8ba3037235e19a394be4d26ce47317d8087684456b4cf
+    25e012b33b54bb9734315020b02651a8476dd2af54fa9e39;
+  c5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb960
+    40d39040e632d562643ccb64286303040fcaf679e914eadd
+    b059b9be9e7700024accda083f56f569ac51e624ed72a7ed;
+}
+
+gcm-mul256 {
+  cde4bef260d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0
+    c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003
+    789615a0602ce0d6e57a94074e22645fcdca1c2530cdce6a3a9898eefa48f602;
+  062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c95198
+    48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085
+    ccd7a63e0f43d900d461f137b5f9a1b797580961dfe96d9e85ce0cc154f608ee;
+  406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21
+    635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731
+    5f81e704e9b04d5b517392c372c5d2756eacc4f7a9442ac98d4bf8bb8536fe89;
+  ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9
+    529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52
+    094e95ea9c8346285f98c6f07ddd15830aa193170953a8abc41712732c76c336;
+  ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5
+    4215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff6310
+    52d7772d1f860c1ce6cb4d1259577c2d43421ebfc44c89c43f05d0f424401b34;
+  2758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de16001578
+    46b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c5
+    ad51dbcde8d0216bc998500d67317c852d273252d39d2c6a555d22a4fd180959;
+  4d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a19
+    9e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac
+    f25c5e462dc2a069bedb1d39ee68b16d025c0596ca27efd01c46555b245f6087;
+  8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836
+    8131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65
+    934d35daaec3791e39e799c81c62f07b1628bcd3113eecc4cc13993fad10e629;
+  b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499
+    268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b6
+    99845195dba2f3b005653321a028907e11f546e597a641d652d85dae95e1775e;
+  49377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce
+    2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4
+    16edc22df1c67d480ba3d471d61097eeba54e40ca0bf06d6fdd84232677efd19;
+  e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0
+    b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0a
+    49b59d9642e48bb2116b5b2515b77ba746e6ae804e8e9ed83ca2322a800a9ae6;
+  bef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f2
+    1195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed
+    6d03d43d9d7afc91f749c061d63dde21753f303c5d070e34dde5193c27e13046;
+  00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c
+    1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c
+    fd315ad2958b91405b2895b81391997c56a599609bdcd17ce9f2d540689374c1;
+  04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af
+    65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0
+    4978b31536da1b90c44b6dfa1e874a37d4442a9e65979465998ae5ef0599fdfe;
+  945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d
+    65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb94
+    d64e275582ac14f23502aa43a0c2819e236e28770d72f3e9fe0d91b1cfe18d2d;
+  8bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e8995
+    7f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf
+    32223b066ce69f5963af0f7e121424ad3ab03d818562327eb0a495e7b0a0a844;
+  91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2
+    ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1b
+    98abd767205b0f7fe21909f48b6182430169836df1712981bc1ae96b4e5c1b2b;
+  fc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add95
+    89d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c312
+    35446e8c959e35b74ff4e8960a1c80c3a4fc60998fc074d3fa6d73e7787b2bdc;
+  2d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957e
+    b6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe2
+    b893278872133d6ae9370dd0c1bf7e6990438ef83b012db8b4ac0197ee115ac1;
+  2d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb456
+    3d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938d
+    b954c35b504dd99c3f95f2778ac8c69c9516eb5ecb279f01dca0cc5b1d33528f;
+  e1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa
+    7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2a
+    a947b0e3b6d5caa39dd7899d60cc739b86a306c9de07b826efe14d1565ae933c;
+  bf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e
+    4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac8
+    93c8e6eb9eb2a085c0fe1e424c031d75e3cb3924e6636a3d0fbd97a9057b1497;
+  61a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab3
+    83a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273
+    1a9447bbcab0bf9fa9d4f97b44df070a91e73465559561cf07bf66f253b74839;
+  117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d
+    2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976
+    19931b3731ce5cd2a6e0fd8db3528a01cf67f21c9f2b6536f617786536862f1b;
+  063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147
+    842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013
+    7814dc31116b923eff0567f1898f0dcfe5db31cea5f82d371c895b9cd0e1e626;
+  e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff20687
+    7de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d
+    bf48e4fcb2685f89934fe3b4e1f093795e48c129192425f8d83df0a859982026;
+  52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfb
+    e61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c53
+    3c2f3e81bbfcfe08da13e35354b1bac0f0af0da35266c33c3a85c7cfa2ee849e;
+  6ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbd
+    bc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bd
+    975de7c5d90df79434ad560bfa1f2d3acb2bb268bad74a40f40dfb0b0cc55d80;
+  b75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cb
+    c0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3
+    778ec7881d07957cb956ee98b77f4771f0b354eee8ad6ed146dc9848bb4e5a15;
+  fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd6
+    6ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d547
+    b41eff7927b5a1646b42fe8e7f3404366196b47be1d22a51819727a2987a12c5;
+  56fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd8815
+    19165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9
+    eb4d497d39f0ccce56894c544b916a5a32aabb5e8470197389918e758cf5bcbc;
+  d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca
+    34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea
+    ef9fd1957ea0125681170f801a2ff55cd40c11f1d8d03e28a47d07e530518d8f;
+  51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae648
+    25ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e8
+    b48119d50954fe55c7cb531c051c858b91a2cc0be497434ac06f1746d05200b1;
+  8fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1
+    ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f3
+    417db866feb0dc25af3bbff0a733e5220044c6933507f6d68d651a77b3371083;
+  1b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb
+    84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511edd
+    2093bb7f7243f7d09835512229a449b3fcfbebc4f158d1f360d61dfa33aba949;
+  b8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be740
+    88e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d
+    aadd61dcffddf277215a600d2a262375b40e8e8a00d2d1ee59d656ad63eca173;
+  907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe1
+    4fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3d
+    1ddab3418f7c2e73138a161d9480144100ac8a8c453cea6cbda181416ce835c1;
+  a84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd1
+    8c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce7
+    ac62a144b60cbcee96700e35a156c4ea04e8527600094b7c7c1fa57eb67c78c5;
+  57b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd7
+    26d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a87
+    6ac5d880e25effaad82da8efe77ed2245c9306d82e19c9b680b0a166b13db5cb;
+  33b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3ba
+    d8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24ed
+    6bc8ad093f2148dc06ee942ce06a6b6c41ad4fb2ae796f9351df4d7829d0b759;
+  fd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c83983
+    9c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680332bbded4883deea
+    7cdba7c767a1b2e0d8ea98db6d05d0e6dc5ec4add6d68cb3a0ed213ba91fb46f;
+  0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6
+    cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dc
+    4d19278b4626808b203535680f24d55aa0bcf39b89221ccdceef29212f738776;
+  c73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945
+    d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6
+    e82546a97e4d982315567afa93cc9cfbed1e6a9a553fb7209ac3c0c8a0f7d2a0;
+  d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee7
+    8ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c172
+    550b3822df20109989c3ad201218184ea69c16e7efc41e9ae40d163565ea52e2;
+  a5cbc19456c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179
+    bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8aac1d426ce10df7
+    b35239f297beda780ccb0168fadd0708fe02a09e29566b3cea47f8f1932321e2;
+  3c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6d
+    e738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d9
+    5c8cae06450a234fd67621baf1be40de09a7ee05227b7cc527bfffb14c861641;
+  3d1f8fcc53574427767396322b3bf7d02cec05093696cec07591ada462271b1d
+    1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a34a8ba3037235e19
+    0d07975a21745840a9528f6ad84812f76d981c7cbd51d23295b0a4c77647955a;
+  a394be4d26ce47317d8087684456b4cfc5555e925e3e7b2ebc829b2d0505ea61
+    7b0ca9531bcdb96040d39040e632d562643ccb64286303040fcaf679e914eadd
+    b11034402f9178618471341a208717e0db49389cc10169da3bbfd18c0b155dbf;
+  c05af8843ce6a427b99a5dc266de31c09165237eeefe4b58cc034b9f099f0467
+    8c2a9da898b39324cd3087a651014f6796f9c4881d89e127e62221e47e57badd
+    a3115e01610e03d14a9aa231f0af30c2f864724a9b827bee723862a2da21f67c;
+  678d490c2f320ff8fb1c42761bd439f3e96dc0ed1d5b2169912af1a4e2c533c5
+    2ba3e8c71c23a089e231480aa63c484fb34bd522397f102cb8ecf4f64e329884
+    f8fb5571f45bfe48a3e0a32c0152f4cf9f05fd9b6df1b16c135ac57b53140b1f;
+  fe73be257a753b38200bc23f94a079bde2dd98d813655dafa15b85419d15c41a
+    5153cce5d0e8c8702db2ba11927589678d4f7b8fcfad4818c411f15f45230090
+    f0eb21d7c095cbb71ce2a6e98cd274161a006a321bc6516d92e292d4f9d80fe5;
+  3874f9a532ee46496ae753a2340af7b91f9632fc5ae71ae18b40de751ab6b676
+    1ca16434a9935e466e11c1cb072f32a59c313dba3db646ae909a096697d9a7b0
+    2784404b966884dd1be5778471a98b8cd9ffc6fb4cef97e9f828f5a9976519ea;
+  556463ff1126ebc43263391424d02739d0787e804d8f1dccf6c897a8a4843132
+    4324041b5302ccd501b538bd03d5cb5c90d1fd3f7d2be187a787032c79ed9007
+    7a286ff42bd536174d2d471c7edf52d76cc1e2149ae5e89fe7c527d1baf61024;
+  64ee4ce1d3fc042c084f7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92d
+    bd873a8fe113090d401bea4d28ff49f10ff593adc258e091abd31b62dd173515
+    c4cf640c91c885ead4d5ad0de5769f1bf2fc7cc928ddb20ecd77903e78d60296;
+  8f98765970acc6602da063aae01a2a199d3a4f37a5f062d216d2053a83b5d3a0
+    488ab0d2df631b2892cdfcf9fdd0f37de9ed67179aeae82fe00009428b297b55
+    fd32af281c32754a7cb4b70f0856a6a595d53df2f655dfb5d065813b658f6e49;
+  3230a6d917fa0c1a233c9ebc8a4cba45b20543c540fc1b9dbce078b87a1534ac
+    f03897b95a3f372e9f6c5a5f2ae44a7dbce9ba43a39089de20de70d0544b5151
+    d717a2d8e24c431d7322091c4afa9291e6b2f642164fb5dd41b03d63eb3991ad;
+  db0a16e9769e8f2fc12c7f839fab269a0056284a697ffd4113a1cf43b5d5bdce
+    2d86dead83f5a356e9106bedf908db61f1119f9700260ea9379cc7232184d217
+    ad5a3798580a21a9af3a14a20c498e9ba81075c0d4c771481da0b3e6544bb711;
+  158fee8ca42e75614739e9007f234fbcd86b0ad8f641a0449b6d9b0f99d1cb4a
+    57a4d6f987feb0ade90aa1d81c4f497b3734be301da3e25fe692629db57311f4
+    feca63faa55407c1cbe7ba36da4101ed6fc318162d0834ef6ea91095e6fbb38c;
+  22f3a1573f9e0553a23e96265e4326fa532d7136863e5b4bc6c99ade3d4eb23c
+    acdf6e42ad8ca13187eba1532920ba31582b3793b05fa65e9f80c5814b91f4d3
+    c9ddac65e7d93033570d39fc200ea11df6f56cf19994e791092cab78342f8793;
+  c581c7b16c46b484859c6d19eebaf124681aa3be9943307fa4ef095ef8e7e50b
+    703dc0420e74227c9351366ef8e98e1e24b48aa989dbb8d0f10471ae5428a601
+    f1e437fdbee29a5838d58d6ca0abd51bf3fe4bed82ea86f5e3d2e8effa7dbee9;
+  2fbe4f5cb2dab2863e574842cc0b3774e00dcfa63b0db1716c7e916a26fc2e19
+    8f8db63ab59955989497782f16c5816270ef3fbe4ea22f484ddc12ec8f4bdbd6
+    c8721ce2f69e7d5d6fc5746fea4185ff8a7d296b99bcc17bbbad3e7036053bcb;
+  ebdfbafb21fcf5427dbee5f95b53a0b4cb6d7c128b79f4657895f4b0ba518dd6
+    1436140f20d40224baac3a602da83cb254a7e03f052c63c1f3f00f301cc944a1
+    f3298d9cfbd5fd3a98e1ecabe8a2aac82b1b54f2f65f09d7cf3bcd9ca8bd2bcf;
+  789133bb8048f07dc123f2ca7e20c83988e4bfea6d561ab5aea542db544a1437
+    6d5d52f7265c7a8d2fc4feef99b9dba89eb472f71d8eb5affe900d776e4cf74e
+    795de908ed1e3149d3e92fc4d2fb56c47db72b54097702f360c3de4363a1b38c;
+  52b6c86db981143082735c6473a86a5da3d2e8cbb8602ebbaf08bf9315fba15f
+    46714bfd2c8312fb5744dfe84615ddb93f15360161f2efb1fc39b8b6ad97427d
+    9e96a1dd18f2683365cb98a46a9cb8bf49f1766ac86eddec4a87dfa3f83339ce;
+}
index bee4e34..834771c 100755 (executable)
@@ -389,6 +389,15 @@ def gcmgen(bc):
           (bc.blksz - 4, bc.blksz + 3, 3*bc.blksz + 9),
           (bc.blksz - 1, 3*bc.blksz - 5, 3*bc.blksz + 5)]
 
+def gcm_mul_tests(nbits):
+  print 'gcm-mul%d {' % nbits
+  for i in xrange(64):
+    x = R.block(nbits/8)
+    y = R.block(nbits/8)
+    z = gcm_mul(x, y)
+    print '  %s\n    %s\n    %s;' % (hex(x), hex(y), hex(z))
+  print '}'
+
 ###--------------------------------------------------------------------------
 ### CCM.
 
@@ -975,6 +984,11 @@ MODEMAP = { 'eax-enc': (eaxgen, 3*[binarg] + [intarg], eaxenc),
             'pmac1': (pmacgen, [binarg], pmac1_pub) }
 
 mode = argv[1]
+if len(argv) == 3 and mode == 'gcm-mul':
+  VERBOSE = False
+  nbits = int(argv[2])
+  gcm_mul_tests(nbits)
+  exit(0)
 bc = None
 for d in CUSTOM, C.gcprps:
   try: bc = d[argv[2]]