symm/sha3.[ch]: Add support for SHA3 and related functions based on Keccak.
[catacomb] / progs / rspit.c
index f3de422..9781333 100644 (file)
@@ -73,6 +73,7 @@
 #include "salsa20.h"
 #include "salsa20-core.h"
 #include "seal.h"
+#include "sha3.h"
 
 #include "des-ofb.h"
 #include "des3-ofb.h"
@@ -241,6 +242,27 @@ static const struct {
 #undef E
 };
 
+#define SHAKES E(128) E(256)
+
+enum {
+#define E(sz) SHAKE##sz##_INDEX,
+  SHAKES
+#undef E
+  SHAKE__LIMIT
+};
+
+static const struct {
+  const octet *ksz;
+  grand *(*shake)(const void *, size_t, const void *, size_t,
+                 const void *, size_t);
+  grand *(*kmac)(const void *, size_t,
+                const void *, size_t);
+} shaketab[] = {
+#define E(sz) { shake##sz##_keysz, cshake##sz##_rand, kmac##sz##_rand },
+  SHAKES
+#undef E
+};
+
 /*----- Miscellaneous static data -----------------------------------------*/
 
 static FILE *outfp;
@@ -1078,6 +1100,113 @@ static grand *gen_mgf(unsigned i)
   return (r);
 }
 
+/* --- SHAKE generators --- */
+
+static grand *gen_shake(unsigned i)
+{
+  dstr d = DSTR_INIT;
+  const char *func = 0, *perso = 0;
+  grand *r;
+
+  static struct option opts[] = {
+    { "function",      OPTF_ARGREQ,    0,      'F' },
+    { "personalization", OPTF_ARGREQ,  0,      'P' },
+    { "key",           OPTF_ARGREQ,    0,      'k' },
+    { "hex",           OPTF_ARGREQ,    0,      'H' },
+    { 0,               0,              0,      0 }
+  };
+
+  addopts("F:P:k:H:", opts);
+
+  for (;;) {
+    int o = opt();
+    if (o < 0)
+      break;
+    switch (o) {
+      case 'F':
+       func = optarg;
+       break;
+      case 'P':
+       perso = optarg;
+       break;
+      case 'k':
+       DRESET(&d);
+       textkey(&d, optarg, shaketab[i].ksz);
+       break;
+      case 'H':
+       DRESET(&d);
+       hexkey(&d, optarg, shaketab[i].ksz);
+       break;
+      default:
+       return (0);
+    }
+  }
+
+  if (!d.len) randkey(&d, shaketab[i].ksz);
+  r = shaketab[i].shake(func, func ? strlen(func) : 0,
+                       perso, perso ? strlen(perso) : 0,
+                       d.buf, d.len);
+  dstr_destroy(&d);
+  return (r);
+}
+
+/* --- KMAC generators --- */
+
+static grand *gen_kmac(unsigned i)
+{
+  dstr d = DSTR_INIT, m = DSTR_INIT;
+  const char *perso = 0;
+  char *q;
+  grand *r;
+
+  static struct option opts[] = {
+    { "personalization", OPTF_ARGREQ,  0,      'P' },
+    { "key",           OPTF_ARGREQ,    0,      'k' },
+    { "hex",           OPTF_ARGREQ,    0,      'H' },
+    { "message",       OPTF_ARGREQ,    0,      'M' },
+    { "msghex",                OPTF_ARGREQ,    0,      'N' },
+    { 0,               0,              0,      0 }
+  };
+
+  addopts("P:k:H:M:N:", opts);
+
+  for (;;) {
+    int o = opt();
+    if (o < 0)
+      break;
+    switch (o) {
+      case 'P':
+       perso = optarg;
+       break;
+      case 'k':
+       DRESET(&d);
+       textkey(&d, optarg, shaketab[i].ksz);
+       break;
+      case 'H':
+       DRESET(&d);
+       hexkey(&d, optarg, shaketab[i].ksz);
+       break;
+      case 'M':
+       DRESET(&m);
+       DPUTS(&d, optarg);
+       break;
+      case 'N':
+       DRESET(&m);
+       unhex(optarg, &q, &m);
+       if (*q) die(EXIT_FAILURE, "bad hex");
+       break;
+      default:
+       return (0);
+    }
+  }
+
+  if (!d.len) randkey(&d, shaketab[i].ksz);
+  r = shaketab[i].kmac(perso, perso ? strlen(perso) : 0, d.buf, d.len);
+  r->ops->misc(r, GRAND_SEEDBLOCK, (void *)m.buf, m.len);
+  dstr_destroy(&d); dstr_destroy(&m);
+  return (r);
+}
+
 /* --- Fibonacci generator --- */
 
 static grand *gen_fib(unsigned i)
@@ -1189,6 +1318,16 @@ gen generators[] = {
     "[-k KEY-PHRASE] [-H HEX-KEY] [-n NONCE]" },
   SALSAE
 #undef E
+#define E(sz)                                                          \
+  { "shake" #sz,       gen_shake,      SHAKE##sz##_INDEX,              \
+    "[-k KEY-PHRASE] [-H HEX-KEY]" },
+  SHAKES
+#undef E
+#define E(sz)                                                          \
+  { "kmac" #sz,                gen_kmac,       SHAKE##sz##_INDEX,              \
+    "[-k KEY-PHRASE] [-H HEX-KEY] [-m MSG]" },
+  SHAKES
+#undef E
   { "rc4",             gen_rc4,        0,
     "[-k KEY-PHRASE] [-H HEX-KEY]" },
   { "seal",            gen_seal,       0,