Support subgroups of binary fields.
[u/mdw/catacomb] / cc-kem.c
index 8ba29fd..aaa21bd 100644 (file)
--- a/cc-kem.c
+++ b/cc-kem.c
@@ -169,14 +169,16 @@ typedef struct dh_encctx {
   ge *y;
 } dh_encctx;
 
-static dh_encctx *dh_doinit(key *k, const gprime_param *gp, mp *y)
+static dh_encctx *dh_doinit(key *k, const gprime_param *gp, mp *y, 
+                           group *(*makegroup)(const gprime_param *),
+                           const char *what)
 {
   dh_encctx *de = CREATE(dh_encctx);
   dstr t = DSTR_INIT;
 
   key_fulltag(k, &t);
-  if ((de->g = group_prime(gp)) == 0)
-    die(EXIT_FAILURE, "bad prime group in key `%s'", t.buf);
+  if ((de->g = makegroup(gp)) == 0)
+    die(EXIT_FAILURE, "bad %s group in key `%s'", what, t.buf);
   de->x = MP_NEW;
   de->y = G_CREATE(de->g);
   if (G_FROMINT(de->g, de->y, y))
@@ -207,7 +209,14 @@ static dh_encctx *ec_doinit(key *k, const char *cstr, const ec *y)
 static kem *dh_encinit(key *k, void *kd)
 {
   dh_pub *dp = kd;
-  dh_encctx *de = dh_doinit(k, &dp->dp, dp->y);
+  dh_encctx *de = dh_doinit(k, &dp->dp, dp->y, group_prime, "prime");
+  return (&de->k);
+}
+
+static kem *bindh_encinit(key *k, void *kd)
+{
+  dh_pub *dp = kd;
+  dh_encctx *de = dh_doinit(k, &dp->dp, dp->y, group_binary, "binary");
   return (&de->k);
 }
 
@@ -267,6 +276,11 @@ static const kemops dh_encops = {
   dh_encinit, dh_encdoit, dh_enccheck, dh_encdestroy
 };
 
+static const kemops bindh_encops = {
+  dh_pubfetch, sizeof(dh_pub),
+  bindh_encinit, dh_encdoit, dh_enccheck, dh_encdestroy
+};
+
 static const kemops ec_encops = {
   ec_pubfetch, sizeof(ec_pub),
   ec_encinit, dh_encdoit, dh_enccheck, dh_encdestroy
@@ -275,7 +289,15 @@ static const kemops ec_encops = {
 static kem *dh_decinit(key *k, void *kd)
 {
   dh_priv *dp = kd;
-  dh_encctx *de = dh_doinit(k, &dp->dp, dp->y);
+  dh_encctx *de = dh_doinit(k, &dp->dp, dp->y, group_prime, "prime");
+  de->x = MP_COPY(dp->x);
+  return (&de->k);
+}
+
+static kem *bindh_decinit(key *k, void *kd)
+{
+  dh_priv *dp = kd;
+  dh_encctx *de = dh_doinit(k, &dp->dp, dp->y, group_binary, "binary");
   de->x = MP_COPY(dp->x);
   return (&de->k);
 }
@@ -317,6 +339,11 @@ static const kemops dh_decops = {
   dh_decinit, dh_decdoit, dh_enccheck, dh_encdestroy
 };
 
+static const kemops bindh_decops = {
+  dh_privfetch, sizeof(dh_priv),
+  bindh_decinit, dh_decdoit, dh_enccheck, dh_encdestroy
+};
+
 static const kemops ec_decops = {
   ec_privfetch, sizeof(ec_priv),
   ec_decinit, dh_decdoit, dh_enccheck, dh_encdestroy
@@ -327,6 +354,7 @@ static const kemops ec_decops = {
 const struct kemtab kemtab[] = {
   { "rsa",     &rsa_encops,    &rsa_decops },
   { "dh",      &dh_encops,     &dh_decops },
+  { "bindh",   &bindh_encops,  &bindh_decops },
   { "ec",      &ec_encops,     &ec_decops },
   { 0,         0,              0 }
 };