Add multiply-and-add function for Diffie-Hellman safe prime generation.
authormdw <mdw>
Sat, 20 Nov 1999 22:23:05 +0000 (22:23 +0000)
committermdw <mdw>
Sat, 20 Nov 1999 22:23:05 +0000 (22:23 +0000)
pgen.c
pgen.h

diff --git a/pgen.c b/pgen.c
index 503b153..a57c30a 100644 (file)
--- a/pgen.c
+++ b/pgen.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: pgen.c,v 1.1 1999/11/19 13:17:57 mdw Exp $
+ * $Id: pgen.c,v 1.2 1999/11/20 22:23:05 mdw Exp $
  *
  * Finding and testing prime numbers
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: pgen.c,v $
+ * Revision 1.2  1999/11/20 22:23:05  mdw
+ * Add multiply-and-add function for Diffie-Hellman safe prime generation.
+ *
  * Revision 1.1  1999/11/19 13:17:57  mdw
  * Prime number generator and tester.
  *
@@ -121,14 +124,14 @@ void pgen_destroy(pgen *p)
 
 int pgen_step(pgen *p, mpw step)
 {
-  mp s;
   int rc = PGEN_MAYBE;
   int i;
 
   /* --- Add the step on to the number --- */
 
-  mp_build(&s, &step, &step + 1);
-  p->m = mp_add(p->m, p->m, &s);
+  p->m = mp_modify(p->m, MP_LEN(p->m) + 1);
+  mpx_uaddn(p->m->v, p->m->vl, step);
+  mp_shrink(p->m);
 
   /* --- Update the residue table --- */
 
@@ -142,11 +145,77 @@ int pgen_step(pgen *p, mpw step)
     }
   }
 
+  /* --- Small numbers must be prime --- */
+
+  if (rc == PGEN_MAYBE && MP_LEN(p->m) == 1 &&
+      p->m->v[0] < MAXPRIME * MAXPRIME)
+    rc = PGEN_PRIME;
+
   /* --- Done --- */
 
   return (rc);
 }
 
+/* --- @pgen_muladd@ --- *
+ *
+ * Arguments:  @pgen *p@ = destination prime generation context
+ *             @const pgen *q@ = source prime generation context
+ *             @mpw m@ = number to multiply by
+ *             @mpw a@ = number to add
+ *
+ * Returns:    One of the @PGEN@ constants above.
+ *
+ * Use:                Multiplies the number in a prime generation context by a
+ *             small value and then adds a small value.  The destination
+ *             should either be uninitialized or the same as the source.
+ *
+ *             Common things to do include multiplying by 2 and adding 0 to
+ *             turn a prime into a jump for finding other primes with @q@ as
+ *             a factor of @p - 1@, or multiplying by 2 and adding 1.
+ */
+
+int pgen_muladd(pgen *p, const pgen *q, mpw m, mpw a)
+{
+  int rc = PGEN_MAYBE;
+  int i;
+
+  /* --- Multiply the big number --- */
+
+  {
+    mp *d = mp_create(MP_LEN(q->m) + 2);
+    mpx_umuln(d->v, d->vl, q->m->v, q->m->vl, m);
+    mpx_uaddn(d->v, d->vl, a);
+    d->f = q->m->f;
+    if (p == q)
+      mp_drop(p->m);
+    mp_shrink(d);
+    p->m = d;
+  }
+
+  /* --- Gallivant through the residue table --- */
+      
+  for (i = 0; i < NPRIME; i++) {
+    p->r[i] = (q->r[i] * m + a) % ptab[i];
+    if (!p->r[i] && rc == PGEN_MAYBE) {
+      if (MP_LEN(p->m) == 1 && p->m->v[0] == ptab[i])
+       rc = PGEN_PRIME;
+      else
+       rc = PGEN_COMPOSITE;
+    }
+  }
+
+  /* --- Small numbers must be prime --- */
+
+  if (rc == PGEN_MAYBE && MP_LEN(p->m) == 1 &&
+      p->m->v[0] < MAXPRIME * MAXPRIME)
+    rc = PGEN_PRIME;
+
+  /* --- Finished --- */
+
+  return (rc);
+}
+
+
 /* --- @pgen_jump@ --- *
  *
  * Arguments:  @pgen *p@ = pointer to prime generation context
@@ -188,6 +257,12 @@ int pgen_jump(pgen *p, pgen *j)
     }
   }
 
+  /* --- Small numbers must be prime --- */
+
+  if (rc == PGEN_MAYBE && MP_LEN(p->m) == 1 &&
+      p->m->v[0] < MAXPRIME * MAXPRIME)
+    rc = PGEN_PRIME;
+
   /* --- Done --- */
 
   return (rc);
diff --git a/pgen.h b/pgen.h
index 536ba0a..6f2000c 100644 (file)
--- a/pgen.h
+++ b/pgen.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: pgen.h,v 1.1 1999/11/19 13:17:57 mdw Exp $
+ * $Id: pgen.h,v 1.2 1999/11/20 22:23:05 mdw Exp $
  *
  * Finding and testing prime numbers
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: pgen.h,v $
+ * Revision 1.2  1999/11/20 22:23:05  mdw
+ * Add multiply-and-add function for Diffie-Hellman safe prime generation.
+ *
  * Revision 1.1  1999/11/19 13:17:57  mdw
  * Prime number generator and tester.
  *
@@ -108,6 +111,26 @@ extern void pgen_destroy(pgen */*p*/);
 
 extern int pgen_step(pgen */*p*/, mpw /*step*/);
 
+/* --- @pgen_muladd@ --- *
+ *
+ * Arguments:  @pgen *p@ = destination prime generation context
+ *             @const pgen *q@ = source prime generation context
+ *             @mpw m@ = number to multiply by
+ *             @mpw a@ = number to add
+ *
+ * Returns:    One of the @PGEN@ constants above.
+ *
+ * Use:                Multiplies the number in a prime generation context by a
+ *             small value and then adds a small value.  The destination
+ *             should either be uninitialized or the same as the source.
+ *
+ *             Common things to do include multiplying by 2 and adding 0 to
+ *             turn a prime into a jump for finding other primes with @q@ as
+ *             a factor of @p - 1@, or multiplying by 2 and adding 1.
+ */
+
+extern int pgen_muladd(pgen */*p*/, const pgen */*q*/, mpw /*m*/, mpw /*a*/);
+
 /* --- @pgen_jump@ --- *
  *
  * Arguments:  @pgen *p@ = pointer to prime generation context