+/* --- Symmetric --- */
+
+typedef struct symm_ctx {
+ kem k;
+ key_packdef kp;
+ key_bin kb;
+} symm_ctx;
+
+static kem *symm_init(key *k, void *kd)
+{
+ symm_ctx *s;
+ dstr d = DSTR_INIT;
+ int err;
+
+ s = CREATE(symm_ctx);
+
+ key_fulltag(k, &d);
+ s->kp.e = KENC_BINARY;
+ s->kp.p = &s->kb;
+ s->kp.kd = 0;
+
+ if ((err = key_unpack(&s->kp, kd, &d)) != 0) {
+ die(EXIT_FAILURE, "failed to unpack symmetric key `%s': %s",
+ d.buf, key_strerror(err));
+ }
+ dstr_destroy(&d);
+ return (&s->k);
+}
+
+static int symm_decdoit(kem *k, dstr *d, ghash *h)
+{
+ symm_ctx *s = (symm_ctx *)k;
+
+ GH_HASH(h, s->kb.k, s->kb.sz);
+ GH_HASH(h, d->buf, d->len);
+ return (0);
+}
+
+static int symm_encdoit(kem *k, dstr *d, ghash *h)
+{
+ dstr_ensure(d, h->ops->c->hashsz);
+ d->len += h->ops->c->hashsz;
+ rand_get(RAND_GLOBAL, d->buf, d->len);
+ return (symm_decdoit(k, d, h));
+}
+
+static const char *symm_check(kem *k) { return (0); }
+
+static void symm_destroy(kem *k)
+ { symm_ctx *s = (symm_ctx *)k; key_unpackdone(&s->kp); }
+
+static const kemops symm_encops = {
+ 0, 0,
+ symm_init, symm_encdoit, symm_check, symm_destroy
+};
+
+static const kemops symm_decops = {
+ 0, 0,
+ symm_init, symm_decdoit, symm_check, symm_destroy
+};
+