Generic interface.
[u/mdw/catacomb] / dsa-gen.c
index ac33088..cbddb70 100644 (file)
--- a/dsa-gen.c
+++ b/dsa-gen.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: dsa-gen.c,v 1.1 1999/11/19 19:28:00 mdw Exp $
+ * $Id: dsa-gen.c,v 1.2 1999/11/20 22:23:48 mdw Exp $
  *
  * Generate DSA shared parameters
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: dsa-gen.c,v $
+ * Revision 1.2  1999/11/20 22:23:48  mdw
+ * Allow event handler to abort the search process.
+ *
  * Revision 1.1  1999/11/19 19:28:00  mdw
  * Implementation of the Digital Signature Algorithm.
  *
@@ -54,7 +57,7 @@
  * Arguments:  @dsa_param *dp@ = where to store parameters
  *             @unsigned l@ = bitlength of @p@ in bits
  *             @const void *k@ = pointer to key material
- *             @void (*proc)(int ev, mp *m, void *p)@ = event procedure
+ *             @int (*proc)(int ev, mp *m, void *p)@ = event procedure
  *             @size_t sz@ = size of key material
  *
  * Returns:    Zero if all went well, nonzero if key material was
  *             The event procedure is informed of various happenings during
  *             generation.  It is passed an event code describing what
  *             happened, and a multiprecision number which pertains to the
- *             event code.
+ *             event code.  It may abort the search at any time by returning
+ *             a nonzero value, which is returned as the result of the
+ *             function.
  */
 
 int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
-               void (*proc)(int /*ev*/, mp */*m*/, void */*p*/), void *arg)
+            int (*proc)(int /*ev*/, mp */*m*/, void */*p*/), void *arg)
 {
   mp *q, *p, *g;
   mp *s = mp_loadb(MP_NEW, k, sz);
   octet *sbuf = xmalloc(sz);
   rc4_ctx rc4;
-  int fail;
+  int fail = 0;
 
   l /= 8;
   rc4_init(&rc4, k, sz);
@@ -95,7 +100,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
     sha_hash(&c, k, sz);
     sha_done(&c, xbuf);
 
-    MPX_UADDN(s->v, s->vl, 1);
+    mpx_uaddn(s->v, s->vl, 1);
     mp_storeb(s, sbuf, sz);
     sha_init(&c);
     sha_hash(&c, sbuf, sz);
@@ -116,8 +121,9 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
     pgen_destroy(&pg);
     if (rc == PGEN_COMPOSITE) {
       if (proc)
-       proc(DSAEV_FAILQ, q, arg);
-      fail = DSAEV_FAILQ;
+       fail = proc(DSAEV_FAILQ, q, arg);
+      if (!fail)
+       fail = DSAEV_FAILQ;
       goto fail_0;
     }
   }
@@ -140,19 +146,22 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
       g = mp_loadb(g, gbuf, sizeof(gbuf));
       if (rabin_test(&r, g) == PGEN_COMPOSITE)
        break;
-      if (proc)
-       proc(DSAEV_PASSQ, q, arg);
+      if (proc && (fail = proc(DSAEV_PASSQ, q, arg)) != 0)
+       break;
     }
     mp_drop(g);
     rabin_destroy(&r);
+    if (fail)
+      goto fail_0;
     if (i < 18) {
       if (proc)
-       proc(DSAEV_FAILQ, q, arg);
-      fail = DSAEV_FAILQ;
+       fail = proc(DSAEV_FAILQ, q, arg);
+      if (fail)
+       fail = DSAEV_FAILQ;
       goto fail_0;
     }
-    if (proc)
-      proc(DSAEV_GOODQ, q, arg);
+    if (proc && (fail = proc(DSAEV_GOODQ, q, arg)) != 0)
+      goto fail_0;
   }
 
   /* --- Now generate @p@ --- *
@@ -184,7 +193,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
        octet *pp = pbuf + SHA_HASHSZ * n;
 
        for (i = 0; i <= n; i++) {
-         MPX_UADDN(s->v, s->vl, 1);
+         mpx_uaddn(s->v, s->vl, 1);
          mp_storeb(s, sbuf, sz);
          sha_init(&c);
          sha_hash(&c, sbuf, sz);
@@ -228,23 +237,24 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
        rabin r;
        mp *g = MP_NEW;
 
-       if (proc)
-         proc(DSAEV_TRYP, p, arg);
        rabin_create(&r, p);
+       if (proc && (fail = proc(DSAEV_TRYP, p, arg)) != 0)
+         break;
        for (i = 0; i < 5; i++) {
          rc4_encrypt(&rc4, 0, pbuf, psz - b);
          g = mp_loadb(g, pbuf, psz - b);
          if (rabin_test(&r, g) == PGEN_COMPOSITE)
            break;
-         if (proc)
-           proc(DSAEV_PASSP, p, arg);
+         if (proc && (fail = proc(DSAEV_PASSP, p, arg)) != 0)
+           break;
        }
        mp_drop(g);
        rabin_destroy(&r);
+       if (fail)
+         break;
        if (i < 5) {
-         if (proc)
-           proc(DSAEV_FAILP, p, arg);
-         fail = DSAEV_FAILP;
+         if (proc && (fail = proc(DSAEV_FAILP, p, arg)) != 0)
+           break;
          continue;
        }
       }
@@ -252,14 +262,14 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
       /* --- It worked! --- */
 
       if (proc)
-       proc(DSAEV_GOODP, p, arg);
+       fail = proc(DSAEV_GOODP, p, arg);
       break;
     }
 
     free(pbuf);
     mp_drop(q2);
     mp_drop(ll);
-    if (j >= 4096)
+    if (j >= 4096 || fail)
       goto fail_1;
   }
 
@@ -286,34 +296,39 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
     mpmont_create(&mm, p);
     for (i = 0; i < NPRIME; i++) {
       hw = ptab[i];
-      if (proc)
-       proc(DSAEV_TRYH, &h, arg);
+      if (proc && (fail = proc(DSAEV_TRYH, &h, arg)) != 0)
+       break;
       g = mpmont_exp(&mm, &h, pp);
       if (MP_CMP(g, !=, MP_ONE))
        break;
-      if (proc)
-       proc(DSAEV_FAILH, &h, arg);
       mp_drop(g);
+      if (proc && (fail = proc(DSAEV_FAILH, &h, arg)) != 0)
+       break;
     }
     mp_drop(pp);
+    if (fail)
+      goto fail_1;
     if (i >= NPRIME) {
       fail = DSAEV_FAILH;
       goto fail_1;
     }
   }
-  if (proc)
-    proc(DSAEV_GOODG, g, arg);
+  if (proc && (fail = proc(DSAEV_GOODG, g, arg) != 0))
+    goto fail_2;
 
   /* --- Return the important information that I succeeded --- */
 
+  dp->g = g;
   dp->p = p;
   dp->q = q;
-  dp->g = g;
+  mp_drop(s);
   free(sbuf);
   return (0);
 
   /* --- Tidy up after failure --- */
 
+fail_2:
+  mp_drop(g);
 fail_1:
   mp_drop(p);
 fail_0:
@@ -330,7 +345,7 @@ fail_0:
 static char baton[] = "/-\\|";
 static char *b = baton;
 
-static void event(int ev, mp *m, void *p)
+static int event(int ev, mp *m, void *p)
 {
   if (ev == DSAEV_TRYP || ev == DSAEV_PASSP) {
     fputc(*b++, stdout);
@@ -339,6 +354,7 @@ static void event(int ev, mp *m, void *p)
     if (!*b)
       b = baton;
   }
+  return (0);
 }
 
 static int verify(dstr *v)