#include <noise.h>
#include <rand.h>
+#include "bintab.h"
#include "bbs.h"
#include "dh.h"
#include "dsa.h"
#include "ectab.h"
#include "fibrand.h"
#include "getdate.h"
+#include "gfreduce.h"
#include "key.h"
#include "mp.h"
#include "mpmont.h"
if (k->curve) {
qd_parse qd;
+ group *g;
+ const char *e;
if (strcmp(k->curve, "list") == 0) {
unsigned i, w;
- LIST("Built-in prime groups", stdout, ptab[i].name, ptab[i].name);
+ LIST("Built-in prime fields", stdout, ptab[i].name, ptab[i].name);
exit(0);
}
qd.p = k->curve;
if (dh_parse(&qd, &dp))
- die(EXIT_FAILURE, "error in group spec: %s", qd.e);
+ die(EXIT_FAILURE, "error in field spec: %s", qd.e);
+ if (!qd_eofp(&qd))
+ die(EXIT_FAILURE, "junk at end of field spec");
+ if ((g = group_prime(&dp)) == 0)
+ die(EXIT_FAILURE, "invalid prime field");
+ if (!(k->f & f_quiet) && (e = G_CHECK(g, &rand_global)) != 0)
+ moan("WARNING! group check failed: %s", e);
+ G_DESTROYGROUP(g);
goto done;
}
-
+
if (!k->bits)
k->bits = 1024;
bbs_privfree(&bp);
}
+static void alg_binparam(keyopts *k)
+{
+ static const char *pl[] = { "p", "q", "g", 0 };
+ if (!copyparam(k, pl)) {
+ gbin_param gb;
+ qd_parse qd;
+ group *g;
+ const char *e;
+ key_data *kd = &k->k->k;
+
+ /* --- Decide on a field --- */
+
+ if (!k->bits) k->bits = 128;
+ if (k->curve && strcmp(k->curve, "list") == 0) {
+ unsigned i, w;
+ LIST("Built-in binary fields", stdout,
+ bintab[i].name, bintab[i].name);
+ exit(0);
+ }
+ if (!k->curve) {
+ if (k->bits <= 40) k->curve = "p1363-40";
+ else if (k->bits <= 56) k->curve = "p1363-56";
+ else if (k->bits <= 64) k->curve = "p1363-64";
+ else if (k->bits <= 80) k->curve = "p1363-80";
+ else if (k->bits <= 112) k->curve = "p1363-112";
+ else if (k->bits <= 128) k->curve = "p1363-128";
+ else {
+ die(EXIT_FAILURE,
+ "no built-in binary fields provide %u-bit security",
+ k->bits);
+ }
+ }
+
+ /* --- Check it --- */
+
+ qd.e = 0;
+ qd.p = k->curve;
+ if (dhbin_parse(&qd, &gb))
+ die(EXIT_FAILURE, "error in field spec: %s", qd.e);
+ if (!qd_eofp(&qd))
+ die(EXIT_FAILURE, "junk at end of field spec");
+ if ((g = group_binary(&gb)) == 0)
+ die(EXIT_FAILURE, "invalid binary field");
+ if (!(k->f & f_quiet) && (e = G_CHECK(g, &rand_global)) != 0)
+ moan("WARNING! group check failed: %s", e);
+ G_DESTROYGROUP(g);
+
+ /* --- Write out the answer --- */
+
+ key_structure(kd);
+ mpkey(kd, "p", gb.p, KCAT_SHARE);
+ mpkey(kd, "q", gb.q, KCAT_SHARE);
+ mpkey(kd, "g", gb.g, KCAT_SHARE);
+ mp_drop(gb.q);
+ mp_drop(gb.p);
+ mp_drop(gb.g);
+ }
+}
+
+static void alg_bin(keyopts *k)
+{
+ mp *x, *y;
+ mp *p, *q, *g;
+ gfreduce r;
+ key_data *kd = &k->k->k;
+
+ /* --- Get the shared parameters --- */
+
+ alg_binparam(k);
+ p = getmp(kd, "p");
+ q = getmp(kd, "q");
+ g = getmp(kd, "g");
+
+ /* --- Choose a suitable private key --- *
+ *
+ * Since %$g$% has order %$q$%, choose %$x < q$%.
+ */
+
+ x = mprand_range(MP_NEWSEC, q, k->r, 0);
+
+ /* --- Compute the public key %$y = g^x \bmod p$% --- */
+
+ gfreduce_create(&r, p);
+ y = gfreduce_exp(&r, MP_NEW, g, x);
+ gfreduce_destroy(&r);
+
+ /* --- Store everything away --- */
+
+ mpkey(kd, "y", y, KCAT_PUB);
+
+ kd = key_structcreate(kd, "private");
+ key_structure(kd);
+ mpkey(kd, "x", x, KCAT_PRIV | KF_BURN);
+ dolock(k, kd, "private");
+
+ mp_drop(x); mp_drop(y);
+}
+
static void alg_ecparam(keyopts *k)
{
static const char *pl[] = { "curve", 0 };
{ "binary", alg_binary, "Plain binary data" },
{ "des", alg_des, "Binary with DES-style parity" },
{ "rsa", alg_rsa, "RSA public-key encryption" },
+ { "bbs", alg_bbs, "Blum-Blum-Shub generator" },
{ "dsa", alg_dsa, "DSA digital signatures" },
{ "dsa-param", alg_dsaparam, "DSA shared parameters" },
{ "dh", alg_dh, "Diffie-Hellman key exchange" },
{ "dh-param", alg_dhparam, "Diffie-Hellman parameters" },
- { "bbs", alg_bbs, "Blum-Blum-Shub generator" },
+ { "bindh", alg_bin, "DH over a binary field" },
+ { "bindh-param", alg_binparam, "Binary-field DH parameters" },
{ "ec-param", alg_ecparam, "Elliptic curve parameters" },
{ "ec", alg_ec, "Elliptic curve crypto" },
{ 0, 0 }
ghashtab[i], ghashtab[i]->name) \
LI("Elliptic curves", ec, \
ectab[i].name, ectab[i].name) \
- LI("Diffie-Hellman groups", dh, \
+ LI("Prime Diffie-Hellman groups", dh, \
ptab[i].name, ptab[i].name) \
+ LI("Binary Diffie-Hellman groups", bindh, \
+ bintab[i].name, bintab[i].name) \
LI("Key-generation algorithms", keygen, \
algtab[i].name, algtab[i].name) \
LI("Random seeding algorithms", seed, \