+/* --- x25519 --- */
+
+typedef struct x25519_jobctx {
+ octet k[X25519_KEYSZ];
+ octet p[X25519_PUBSZ];
+} x25519_jobctx;
+
+static void *x25519_jobinit(opts *o)
+{
+ x25519_jobctx *c = CREATE(x25519_jobctx);
+ rand_get(RAND_GLOBAL, c->k, sizeof(c->k));
+ rand_get(RAND_GLOBAL, c->p, sizeof(c->p));
+ return (c);
+}
+
+static void x25519_jobrun(void *cc)
+ { x25519_jobctx *c = cc; octet z[X25519_OUTSZ]; x25519(z, c->k, c->p); }
+
+/* --- x448 --- */
+
+typedef struct x448_jobctx {
+ octet k[X448_KEYSZ];
+ octet p[X448_PUBSZ];
+} x448_jobctx;
+
+static void *x448_jobinit(opts *o)
+{
+ x448_jobctx *c = CREATE(x448_jobctx);
+ rand_get(RAND_GLOBAL, c->k, sizeof(c->k));
+ rand_get(RAND_GLOBAL, c->p, sizeof(c->p));
+ return (c);
+}
+
+static void x448_jobrun(void *cc)
+ { x448_jobctx *c = cc; octet z[X448_OUTSZ]; x448(z, c->k, c->p); }
+
+/* --- Ed25519 --- */
+
+typedef struct ed25519_signctx {
+ octet k[ED25519_KEYSZ];
+ octet K[ED25519_PUBSZ];
+ octet m[64];
+} ed25519_signctx;
+
+typedef struct ed25519_vrfctx {
+ octet K[ED25519_PUBSZ];
+ octet m[64];
+ octet sig[ED25519_SIGSZ];
+} ed25519_vrfctx;
+
+static void *ed25519_signinit(opts *o)
+{
+ ed25519_signctx *c = CREATE(ed25519_signctx);
+
+ rand_get(RAND_GLOBAL, c->k, sizeof(c->k));
+ rand_get(RAND_GLOBAL, c->m, sizeof(c->m));
+ ed25519_pubkey(c->K, c->k, sizeof(c->k));
+ return (c);
+}
+
+static void ed25519_signrun(void *cc)
+{
+ ed25519_signctx *c = cc;
+ octet sig[ED25519_SIGSZ];
+
+ ed25519_sign(sig, c->k, sizeof(c->k), c->K, c->m, sizeof(c->m));
+}
+
+static void *ed25519_vrfinit(opts *o)
+{
+ octet k[ED25519_KEYSZ];
+ ed25519_vrfctx *c = CREATE(ed25519_vrfctx);
+
+ rand_get(RAND_GLOBAL, k, sizeof(k));
+ rand_get(RAND_GLOBAL, c->m, sizeof(c->m));
+ ed25519_pubkey(c->K, k, sizeof(k));
+ ed25519_sign(c->sig, k, sizeof(k), c->K, c->m, sizeof(c->m));
+ return (c);
+}
+
+static void ed25519_vrfrun(void *cc)
+{
+ ed25519_vrfctx *c = cc;
+ ed25519_verify(c->K, c->m, sizeof(c->m), c->sig);
+}
+
+/* --- Ed448 --- */
+
+typedef struct ed448_signctx {
+ octet k[ED448_KEYSZ];
+ octet K[ED448_PUBSZ];
+ octet m[64];
+} ed448_signctx;
+
+typedef struct ed448_vrfctx {
+ octet K[ED448_PUBSZ];
+ octet m[64];
+ octet sig[ED448_SIGSZ];
+} ed448_vrfctx;
+
+static void *ed448_signinit(opts *o)
+{
+ ed448_signctx *c = CREATE(ed448_signctx);
+
+ rand_get(RAND_GLOBAL, c->k, sizeof(c->k));
+ rand_get(RAND_GLOBAL, c->m, sizeof(c->m));
+ ed448_pubkey(c->K, c->k, sizeof(c->k));
+ return (c);
+}
+
+static void ed448_signrun(void *cc)
+{
+ ed448_signctx *c = cc;
+ octet sig[ED448_SIGSZ];
+
+ ed448_sign(sig, c->k, sizeof(c->k), c->K, 0, 0, 0, c->m, sizeof(c->m));
+}
+
+static void *ed448_vrfinit(opts *o)
+{
+ octet k[ED448_KEYSZ];
+ ed448_vrfctx *c = CREATE(ed448_vrfctx);
+
+ rand_get(RAND_GLOBAL, k, sizeof(k));
+ rand_get(RAND_GLOBAL, c->m, sizeof(c->m));
+ ed448_pubkey(c->K, k, sizeof(k));
+ ed448_sign(c->sig, k, sizeof(k), c->K, 0, 0, 0, c->m, sizeof(c->m));
+ return (c);
+}
+
+static void ed448_vrfrun(void *cc)
+{
+ ed448_vrfctx *c = cc;
+ ed448_verify(c->K, 0, 0, 0, c->m, sizeof(c->m), c->sig);
+}
+