General utilities cleanup. Add signature support to catcrypt. Throw in
[u/mdw/catacomb] / mp-jacobi.c
index 69f697e..2562342 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: mp-jacobi.c,v 1.1 1999/11/22 20:50:37 mdw Exp $
+ * $Id: mp-jacobi.c,v 1.5 2004/04/08 01:36:15 mdw Exp $
  *
  * Compute Jacobi symbol
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: mp-jacobi.c,v $
- * Revision 1.1  1999/11/22 20:50:37  mdw
- * Add support for computing Jacobi symbols.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include "mp.h"
@@ -58,6 +50,8 @@ int mp_jacobi(mp *a, mp *n)
 {
   int s = 1;
 
+  assert(((void)"n must be odd in mp_jacobi", MP_LEN(n) && (n->v[0] & 1)));
+
   /* --- Take copies of the arguments --- */
 
   a = MP_COPY(a);
@@ -66,47 +60,27 @@ int mp_jacobi(mp *a, mp *n)
   /* --- Main recursive mess, flattened out into something nice --- */
 
   for (;;) {
+    mpw nn;
+    size_t e;
 
     /* --- Some simple special cases --- */
 
     MP_SHRINK(a);
-
     if (MP_LEN(a) == 0) {
       s = 0;
       goto done;
     }
 
-    /* --- Find the power-of-two factor in @a@ --- */
-
-    {
-      mpscan sc;
-      mpw nn;
-      unsigned e;
-
-      /* --- Scan for a set bit --- */
+    /* --- Main case with powers of two --- */
 
-      MP_SCAN(&sc, a);
-      e = 0;
-      while (MP_STEP(&sc) && !MP_BIT(&sc))
-       e++;
-
-      /* --- Do the shift --- */
-
-      if (e)
-       a = mp_lsr(a, a, e);
-
-      /* --- Maybe adjust the sign of @s@ --- */
-
-      nn = n->v[0] & 7;
-      if ((e & 1) && (nn == 3 || nn == 5))
-       s = -s;
-
-      if (MP_LEN(a) == 1 && a->v[0] == 1)
-       goto done;
-
-      if ((nn & 3) == 3 && (a->v[0] & 3) == 3)
-       s = -s;
-    }
+    a = mp_odd(a, a, &e);
+    nn = n->v[0] & 7;
+    if ((e & 1) && (nn == 3 || nn == 5))
+      s = -s;
+    if (MP_LEN(a) == 1 && a->v[0] == 1)
+      goto done;
+    if ((nn & 3) == 3 && (a->v[0] & 3) == 3)
+      s = -s;
 
     /* --- Reduce and swap --- */
 
@@ -147,6 +121,7 @@ static int verify(dstr *v)
 
   mp_drop(a);
   mp_drop(n);
+  assert(mparena_count(MPARENA_GLOBAL) == 0);
   return (ok);
 }