pub/rsa-gen.c, progs/key.c: Overhaul RSA key generation.
[catacomb] / progs / cc-sig.c
index 14f5e10..f14b4b8 100644 (file)
 #include "rand.h"
 #include "sha.h"
 #include "has160.h"
+#include "sha512.h"
 
+#include "ct.h"
 #include "ec.h"
 #include "ec-keys.h"
 #include "dh.h"
 #include "gdsa.h"
 #include "gkcdsa.h"
 #include "rsa.h"
+#include "ed25519.h"
 
 #include "cc.h"
 
@@ -571,6 +574,61 @@ static const sigops eckcdsa_vrf = {
   eckcdsa_vrfinit, kcdsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy
 };
 
+/* --- Ed25519 --- */
+
+static sig *ed25519_siginit(key *k, void *kd, const gchash *hc)
+  { sig *s = CREATE(sig); s->h = 0; return (s); }
+
+static int ed25519_sigdoit(sig *s, dstr *d)
+{
+  ed25519_priv *k = s->kd;
+
+  dstr_ensure(d, ED25519_SIGSZ);
+  ed25519_sign((octet *)d->buf, k->priv.k, k->priv.sz, k->pub.k,
+              GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz);
+  d->len += ED25519_SIGSZ;
+  return (0);
+}
+
+static const char *ed25519_sigcheck(sig *s)
+{
+  ed25519_priv *k = s->kd;
+
+  if (k->pub.sz != ED25519_PUBSZ)
+    return ("incorrect Ed25519 public key length");
+  return (0);
+}
+
+static void ed25519_sigdestroy(sig *s) { DESTROY(s); }
+
+static const sigops ed25519_sig = {
+  ed25519_privfetch, sizeof(ed25519_priv),
+  ed25519_siginit, ed25519_sigdoit, ed25519_sigcheck, ed25519_sigdestroy
+};
+
+static int ed25519_vrfdoit(sig *s, dstr *d)
+{
+  ed25519_pub *k = s->kd;
+
+  if (d->len != ED25519_SIGSZ) return (-1);
+  return (ed25519_verify(k->pub.k, GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz,
+                        (const octet *)d->buf));
+}
+
+static const char *ed25519_vrfcheck(sig *s)
+{
+  ed25519_pub *k = s->kd;
+
+  if (k->pub.sz != ED25519_PUBSZ)
+    return ("incorrect Ed25519 public key length");
+  return (0);
+}
+
+static const sigops ed25519_vrf = {
+  ed25519_pubfetch, sizeof(ed25519_pub),
+  ed25519_siginit, ed25519_vrfdoit, ed25519_vrfcheck, ed25519_sigdestroy
+};
+
 /* --- Symmetric message authentication --- */
 
 typedef struct mac_ctx {
@@ -634,7 +692,7 @@ static int mac_vrfdoit(sig *s, dstr *d)
   const octet *t;
 
   t = GH_DONE(m->s.h, 0);
-  if (d->len != m->mc->hashsz || memcmp(d->buf, t, d->len) != 0)
+  if (d->len != m->mc->hashsz || !ct_memeq(d->buf, t, d->len))
     return (-1);
   return (0);
 }
@@ -669,6 +727,7 @@ const struct sigtab sigtab[] = {
   { "kcdsa",   &kcdsa_sig,     &kcdsa_vrf,     &has160 },
   { "binkcdsa",        &binkcdsa_sig,  &binkcdsa_vrf,  &has160 },
   { "eckcdsa", &eckcdsa_sig,   &eckcdsa_vrf,   &has160 },
+  { "ed25519", &ed25519_sig,   &ed25519_vrf,   &sha512 },
   { "mac",     &mac_sig,       &mac_vrf,       &rmd160 },
   { 0,         0,              0 }
 };