--- /dev/null
+#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);
+ }
+}