Support subgroups of binary fields.
[u/mdw/catacomb] / utils / bingen.c
diff --git a/utils/bingen.c b/utils/bingen.c
new file mode 100644 (file)
index 0000000..cfbd8e0
--- /dev/null
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "rand.h"
+#include "group.h"
+#include "gfreduce.h"
+
+int main(int argc, char *argv[])
+{
+  mp *p, *q, *g, *gg, *t, *h;
+  gfreduce r;
+  group *grp;
+  gbin_param gb;
+  const char *e;
+  int i;
+
+  t = MP_NEW;
+  q = mp_readstring(MP_NEW, argv[1], 0, 0);
+  p = MP_ZERO;
+  for (i = 2; i < argc; i++) {
+    t = mp_lsl(t, MP_ONE, atoi(argv[i]));
+    p = mp_add(p, p, t);
+  }
+  gfreduce_create(&r, p);
+  t = mp_lsl(t, MP_ONE, mp_bits(p) - 1);
+  t = mp_sub(t, t, MP_ONE);
+  h = MP_NEW;
+  mp_div(&h, &t, t, q);
+  assert(MP_ZEROP(t));
+  g = MP_NEW;
+  gg = MP_TWO;
+  for (;;) {
+    g = gfreduce_exp(&r, g, gg, h);
+    t = gfreduce_exp(&r, t, g, q);
+    if (MP_EQ(t, MP_ONE) && !MP_EQ(g, MP_ONE)) {
+      gb.p = p;
+      gb.q = q;
+      gb.g = g;
+      grp = group_binary(&gb);
+      assert(grp);
+      if ((e = G_CHECK(grp, &rand_global)) != 0) {
+       fprintf(stderr, "badness: %s\n", e);
+       exit(1);
+      }
+      fputs("  p 0x", stdout);
+      mp_writefile(p, stdout, 16);
+      putchar('\n');
+      fputs("  q 0x", stdout);
+      mp_writefile(q, stdout, 16);
+      putchar('\n');
+      fputs("  g 0x", stdout);
+      mp_writefile(g, stdout, 16);
+      putchar('\n');
+      return (0);
+    }
+    gg = mp_add(gg, gg, MP_ONE);
+  }
+}