Change interface for suggested destinations.
[u/mdw/catacomb] / dsa-gen.c
index cbddb70..b719a23 100644 (file)
--- a/dsa-gen.c
+++ b/dsa-gen.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: dsa-gen.c,v 1.2 1999/11/20 22:23:48 mdw Exp $
+ * $Id: dsa-gen.c,v 1.3 1999/12/10 23:18:38 mdw Exp $
  *
  * Generate DSA shared parameters
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: dsa-gen.c,v $
+ * Revision 1.3  1999/12/10 23:18:38  mdw
+ * Change interface for suggested destinations.
+ *
  * Revision 1.2  1999/11/20 22:23:48  mdw
  * Allow event handler to abort the search process.
  *
 #include <stdlib.h>
 
 #include "dsa.h"
+#include "fibrand.h"
 #include "mp.h"
+#include "mprand.h"
 #include "pgen.h"
 #include "rabin.h"
-#include "rc4.h"
 #include "sha.h"
 
 /*----- Main code ---------------------------------------------------------*/
@@ -57,8 +61,8 @@
  * Arguments:  @dsa_param *dp@ = where to store parameters
  *             @unsigned l@ = bitlength of @p@ in bits
  *             @const void *k@ = pointer to key material
- *             @int (*proc)(int ev, mp *m, void *p)@ = event procedure
  *             @size_t sz@ = size of key material
+ *             @int (*proc)(int ev, mp *m, void *p)@ = event procedure
  *
  * Returns:    Zero if all went well, nonzero if key material was
  *             unsuitable (one of the @DSAEV@ codes).
@@ -83,11 +87,11 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
   mp *q, *p, *g;
   mp *s = mp_loadb(MP_NEW, k, sz);
   octet *sbuf = xmalloc(sz);
-  rc4_ctx rc4;
+  grand *gr;
   int fail = 0;
 
   l /= 8;
-  rc4_init(&rc4, k, sz);
+  gr = fibrand_create(LOAD32(k));
 
   /* --- Generate @q@ --- */
 
@@ -115,6 +119,9 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
 
   /* --- Quick primality check --- */
 
+  if (proc && (fail = proc(DSAEV_FINDQ, 0, arg)) != 0)
+    goto fail_0;
+
   {
     pgen pg;
     int rc = pgen_create(&pg, q);
@@ -138,12 +145,10 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
     rabin r;
     int i;
     mp *g = MP_NEW;
-    octet gbuf[SHA_HASHSZ];
 
     rabin_create(&r, q);
     for (i = 0; i < 18; i++) {
-      rc4_encrypt(&rc4, 0, gbuf, sizeof(gbuf));
-      g = mp_loadb(g, gbuf, sizeof(gbuf));
+      g = mprand(g, 8 * SHA_HASHSZ, gr, 1);
       if (rabin_test(&r, g) == PGEN_COMPOSITE)
        break;
       if (proc && (fail = proc(DSAEV_PASSQ, q, arg)) != 0)
@@ -156,12 +161,14 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
     if (i < 18) {
       if (proc)
        fail = proc(DSAEV_FAILQ, q, arg);
-      if (fail)
+      if (!fail)
        fail = DSAEV_FAILQ;
       goto fail_0;
     }
     if (proc && (fail = proc(DSAEV_GOODQ, q, arg)) != 0)
       goto fail_0;
+    if (proc && (fail = proc(DSAEV_FINDP, 0, arg)) != 0)
+      goto fail_0;
   }
 
   /* --- Now generate @p@ --- *
@@ -241,8 +248,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
        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);
+         g = mprand(g, 8 * (psz - b), gr, 1);
          if (rabin_test(&r, g) == PGEN_COMPOSITE)
            break;
          if (proc && (fail = proc(DSAEV_PASSP, p, arg)) != 0)
@@ -263,6 +269,8 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
 
       if (proc)
        fail = proc(DSAEV_GOODP, p, arg);
+      if (proc && !fail)
+       fail = proc(DSAEV_FINDG, 0, arg);
       break;
     }
 
@@ -284,11 +292,8 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
 
     /* --- Calculate %$p' = (p - 1)/q$% --- */
 
-    {
-      mp *p1 = mp_sub(MP_NEW, p, MP_ONE);
-      mp_div(&pp, 0, p1, q);
-      mp_drop(p1);
-    }
+    pp = mp_sub(MP_NEW, p, MP_ONE);
+    mp_div(&pp, 0, pp, q);
 
     /* --- Now find %$h$% where %$g = h^{p'} \bmod p \ne 1$% --- */
 
@@ -298,7 +303,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
       hw = ptab[i];
       if (proc && (fail = proc(DSAEV_TRYH, &h, arg)) != 0)
        break;
-      g = mpmont_exp(&mm, &h, pp);
+      g = mpmont_exp(&mm, MP_NEW, &h, pp);
       if (MP_CMP(g, !=, MP_ONE))
        break;
       mp_drop(g);
@@ -306,6 +311,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
        break;
     }
     mp_drop(pp);
+    mpmont_destroy(&mm);
     if (fail)
       goto fail_1;
     if (i >= NPRIME) {
@@ -323,6 +329,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
   dp->q = q;
   mp_drop(s);
   free(sbuf);
+  gr->ops->destroy(gr);
   return (0);
 
   /* --- Tidy up after failure --- */
@@ -335,6 +342,7 @@ fail_0:
   mp_drop(q);
   mp_drop(s);
   free(sbuf);
+  gr->ops->destroy(gr);
   return (-1);
 }
 
@@ -389,6 +397,7 @@ static int verify(dstr *v)
   if (!rc) {
     mp_drop(dp.q); mp_drop(dp.p); mp_drop(dp.g);
   }
+  assert(mparena_count(MPARENA_GLOBAL) == 0);
   return (ok);
 }