Overhaul of key management (again).
[u/mdw/catacomb] / bbs-gen.c
index 8780274..43b6990 100644 (file)
--- a/bbs-gen.c
+++ b/bbs-gen.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: bbs-gen.c,v 1.2 1999/12/22 15:52:28 mdw Exp $
+ * $Id: bbs-gen.c,v 1.3 2000/02/12 18:21:02 mdw Exp $
  *
  * Generate Blum integers
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: bbs-gen.c,v $
+ * Revision 1.3  2000/02/12 18:21:02  mdw
+ * Overhaul of key management (again).
+ *
  * Revision 1.2  1999/12/22 15:52:28  mdw
  * Reworking for new prime-search system.
  *
 #include "mp.h"
 #include "mprand.h"
 #include "pgen.h"
+#include "strongprime.h"
 
 /*----- Data structures ---------------------------------------------------*/
 
 typedef struct gcdctx {
-  mp *q;
+  mp *q, *jq;
+  pfilt p, jp;
   mp *r;
-  pfilt p;
 } gcdctx;
 
 /*----- Custom stepper ----------------------------------------------------*/
@@ -66,21 +70,40 @@ static int gcdstep(int rq, pgen_event *ev, void *p)
   mp *z = MP_NEW;
 
   switch (rq) {
+
+    /* --- Set everything up --- */
+
     case PGEN_BEGIN: {
-      mp *p = ev->m = mp_split(ev->m);
-      p->v[0] |= 3;
-      g->q = mp_lsr(MP_NEW, p, 1);
+      mp *p = ev->m;
+      if ((p->v[0] & 3) != 3)
+       p = mp_add(p, p, g->jp.m);
       rc = pfilt_create(&g->p, p);
+      g->q = mp_lsr(MP_NEW, p, 1);
+      g->jq = MP_COPY(g->jp.m);
+      pfilt_muladd(&g->jp, &g->jp, 2, 0);
+      g->jq = mp_lsr(MP_NEW, p, 1);
+      mp_drop(p);
     } break;
+
+    /* --- Grind through another iteration --- */
+
     case PGEN_TRY:
-      g->q = mp_add(g->q, g->q, MP_FOUR);
-      rc = pfilt_step(&g->p, 4);
+      mp_drop(ev->m);
+      rc = pfilt_jump(&g->p, &g->jp);
+      g->q = mp_add(g->q, g->q, g->jq);
       break;
+
+    /* --- Finished --- */
+
     case PGEN_DONE:
       pfilt_destroy(&g->p);
       mp_drop(g->q);
+      mp_drop(g->jq);
       return (PGEN_DONE);
   }
+
+  /* --- Step on until everything is OK --- */
+
   for (;;) {
     if (rc != PGEN_FAIL) {
       mp_gcd(&z, 0, 0, g->r, g->q);
@@ -89,12 +112,11 @@ static int gcdstep(int rq, pgen_event *ev, void *p)
     }
     if (rc != PGEN_FAIL)
       break;
-    g->q = mp_add(g->q, g->q, MP_FOUR);
-    rc = pfilt_step(&g->p, 4);
+    rc = pfilt_jump(&g->p, &g->jp);
+    g->q = mp_add(g->q, g->q, g->jq);
   }
 
   mp_drop(z);
-  mp_drop(ev->m);
   ev->m = MP_COPY(g->p.m);
   return (rc);
 }
@@ -104,8 +126,9 @@ static int gcdstep(int rq, pgen_event *ev, void *p)
 /* --- @bbs_gen@ --- *
  *
  * Arguments:  @bbs_param *bp@ = pointer to parameter block
- *             @mp *p, *q@ = initial numbers to search from
- *             @size_t n@ = number of attempts to make
+ *             @unsigned nbits@ = number of bits in the modulus
+ *             @grand *r@ = pointer to random number source
+ *             @unsigned n@ = number of attempts to make
  *             @pgen_proc *event@ = event handler function
  *             @void *ectx@ = argument for event handler
  *
@@ -118,38 +141,51 @@ static int gcdstep(int rq, pgen_event *ev, void *p)
  *             Shub pseudorandom bit generator.
  */
 
-int bbs_gen(bbs_param *bp, mp *p, mp *q, size_t n,
+int bbs_gen(bbs_param *bp, unsigned nbits, grand *r, unsigned n,
            pgen_proc *event, void *ectx)
 {
-  rabin r;
-  pgen_safestepctx c;
+  rabin rb;
+  pgen_safejumpctx j;
   gcdctx g;
+  unsigned nb = nbits/2;
+  mp *x = MP_NEW;
 
   /* --- Generate @p@ --- */
 
-  if ((bp->p = pgen("p", MP_NEW, p, event, ectx, n, pgen_safestep, &c,
-                   rabin_iters(mp_bits(p)), pgen_test, &r)) == 0)
+  if ((x = strongprime_setup("p", x, &j.jq, nb, r, n, event, ectx)) == 0)
+    goto fail_x;
+  bp->p = pgen("p", MP_NEW, x, event, ectx, n, pgen_safejump, &j,
+              rabin_iters(nb), pgen_test, &rb);
+  pfilt_destroy(&j.jq);
+  if (!bp->p)
     goto fail_p;
 
   /* --- Generate @q@ --- */
 
+  nb = nbits - nb;
+  if ((x = strongprime_setup("q", x, &g.jp, nb, r, n, event, ectx)) == 0)
+    goto fail_q;
   g.r = mp_lsr(MP_NEW, bp->p, 1);
-  if ((bp->q = pgen("q", MP_NEW, q, event, ectx, n, gcdstep, &g,
-                   rabin_iters(mp_bits(q)), pgen_test, &r)) == 0)
+  bp->q = pgen("q", MP_NEW, x, event, ectx, n, gcdstep, &g,
+              rabin_iters(nb), pgen_test, &rb);
+  pfilt_destroy(&g.jp);
+  mp_drop(g.r);
+  if (!bp->q)
     goto fail_q;
 
   /* --- Compute @n@ --- */
 
   bp->n = mp_mul(MP_NEW, bp->p, bp->q);
-  mp_drop(g.r);
+  mp_drop(x);
   return (PGEN_DONE);
 
   /* --- Tidy up if things went wrong --- */
 
 fail_q:
-  mp_drop(g.r);
   mp_drop(bp->p);
 fail_p:
+  mp_drop(x);
+fail_x:
   return (PGEN_ABORT);
 }