key/key-io.c: Add low-level `key_mergeline' and `key_extractline' functions.
[catacomb] / progs / key.c
index e85107a..0c817d4 100644 (file)
@@ -73,6 +73,7 @@
 #include "x25519.h"
 #include "x448.h"
 #include "ed25519.h"
+#include "ed448.h"
 
 #include "cc.h"
 #include "sha-mgf.h"
@@ -945,59 +946,63 @@ static void alg_ec(keyopts *k)
   mp_drop(x);
 }
 
-static void alg_x25519(keyopts *k)
-{
-  key_data *kd, *kkd;
-  octet priv[X25519_KEYSZ], pub[X25519_PUBSZ];
-
-  copyparam(k, 0);
-  k->r->ops->fill(k->r, priv, sizeof(priv));
-  x25519(pub, priv, x25519_base);
-  kkd = key_newstruct();
-  key_structsteal(kkd, "priv",
-                 key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv)));
-  kd = key_newstruct();
-  key_structsteal(kd, "private", kkd);
-  key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub)));
-
-  key_setkeydata(k->kf, k->k, kd);
-}
-
-static void alg_x448(keyopts *k)
-{
-  key_data *kd, *kkd;
-  octet priv[X448_KEYSZ], pub[X448_PUBSZ];
-
-  copyparam(k, 0);
-  k->r->ops->fill(k->r, priv, sizeof(priv));
-  x448(pub, priv, x448_base);
-  kkd = key_newstruct();
-  key_structsteal(kkd, "priv",
-                 key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv)));
-  kd = key_newstruct();
-  key_structsteal(kd, "private", kkd);
-  key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub)));
-
-  key_setkeydata(k->kf, k->k, kd);
-}
-
-static void alg_ed25519(keyopts *k)
-{
-  key_data *kd, *kkd;
-  octet priv[ED25519_KEYSZ], pub[ED25519_PUBSZ];
+#define XDHS(_)                                                                \
+  _(x25519, X25519, "X25519")                                          \
+  _(x448, X448, "X448")
+
+#define XDHALG(xdh, XDH, name)                                         \
+                                                                       \
+  static void alg_##xdh(keyopts *k)                                    \
+  {                                                                    \
+    key_data *kd, *kkd;                                                        \
+    octet priv[XDH##_KEYSZ], pub[XDH##_PUBSZ];                         \
+                                                                       \
+    copyparam(k, 0);                                                   \
+    k->r->ops->fill(k->r, priv, sizeof(priv));                         \
+    xdh(pub, priv, xdh##_base);                                                \
+    kkd = key_newstruct();                                             \
+    key_structsteal(kkd, "priv",                                       \
+                   key_newbinary(KCAT_PRIV | KF_BURN,                  \
+                                 priv, sizeof(priv)));                 \
+    kd = key_newstruct();                                              \
+    key_structsteal(kd, "private", kkd);                               \
+    key_structsteal(kd, "pub",                                         \
+                   key_newbinary(KCAT_PUB, pub, sizeof(pub)));         \
+                                                                       \
+    key_setkeydata(k->kf, k->k, kd);                                   \
+  }
 
-  copyparam(k, 0);
-  k->r->ops->fill(k->r, priv, sizeof(priv));
-  ed25519_pubkey(pub, priv, sizeof(priv));
-  kkd = key_newstruct();
-  key_structsteal(kkd, "priv",
-                 key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv)));
-  kd = key_newstruct();
-  key_structsteal(kd, "private", kkd);
-  key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub)));
+XDHS(XDHALG)
+#undef XDHALG
+
+#define EDDSAS(_)                                                      \
+  _(ed25519, ED25519, "Ed25519")                                       \
+  _(ed448, ED448, "Ed448")
+
+#define EDDSAALG(ed, ED, name)                                         \
+                                                                       \
+  static void alg_##ed(keyopts *k)                                     \
+  {                                                                    \
+    key_data *kd, *kkd;                                                        \
+    octet priv[ED##_KEYSZ], pub[ED##_PUBSZ];                           \
+                                                                       \
+    copyparam(k, 0);                                                   \
+    k->r->ops->fill(k->r, priv, sizeof(priv));                         \
+    ed##_pubkey(pub, priv, sizeof(priv));                              \
+    kkd = key_newstruct();                                             \
+    key_structsteal(kkd, "priv",                                       \
+                   key_newbinary(KCAT_PRIV | KF_BURN,                  \
+                                 priv, sizeof(priv)));                 \
+    kd = key_newstruct();                                              \
+    key_structsteal(kd, "private", kkd);                               \
+    key_structsteal(kd, "pub",                                         \
+                   key_newbinary(KCAT_PUB, pub, sizeof(pub)));         \
+                                                                       \
+    key_setkeydata(k->kf, k->k, kd);                                   \
+  }
 
-  key_setkeydata(k->kf, k->k, kd);
-}
+EDDSAS(EDDSAALG)
+#undef EDDSAALG
 
 /* --- The algorithm tables --- */
 
@@ -1020,9 +1025,14 @@ static keyalg algtab[] = {
   { "bindh-param",     alg_binparam,   "Binary-field DH parameters" },
   { "ec-param",                alg_ecparam,    "Elliptic curve parameters" },
   { "ec",              alg_ec,         "Elliptic curve crypto" },
-  { "x25519",          alg_x25519,     "X25519 key exchange" },
-  { "x448",            alg_x448,       "X448 key exchange" },
-  { "ed25519",         alg_ed25519,    "Ed25519 digital signatures" },
+#define XDHTAB(xdh, XDH, name)                                         \
+  { #xdh,              alg_##xdh,      "" name " key exchange" },
+  XDHS(XDHTAB)
+#undef XDHTAB
+#define EDDSATAB(ed, ED, name)                                         \
+  { #ed,               alg_##ed,       "" name " digital signatures" },
+  EDDSAS(EDDSATAB)
+#undef EDDSATAB
   { "empty",           alg_empty,      "Empty parametrs-only key" },
   { 0,                 0 }
 };