Rearrange the file tree.
[catacomb] / exp.h
diff --git a/exp.h b/exp.h
deleted file mode 100644 (file)
index 9ff6a24..0000000
--- a/exp.h
+++ /dev/null
@@ -1,422 +0,0 @@
-/* -*-c-*-
- *
- * $Id$
- *
- * Generalized exponentiation
- *
- * (c) 2001 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of Catacomb.
- *
- * Catacomb is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * Catacomb is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with Catacomb; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-#ifdef CATACOMB_EXP_H
-#  error "Multiple inclusion of <catacomb/exp.h>"
-#endif
-
-#define CATACOMB_EXP_H
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-/*----- Header files ------------------------------------------------------*/
-
-#include <stddef.h>
-
-#include <mLib/alloc.h>
-
-#ifndef CATACOMB_MP_H
-#  include "mp.h"
-#endif
-
-/*----- Data structures ---------------------------------------------------*/
-
-typedef struct exp_simulscan {
-  mpw w;
-  size_t len;
-  const mpw *v;
-} exp_simulscan;
-
-typedef struct exp_simul {
-  unsigned b;
-  size_t o, n;
-  exp_simulscan *s;
-} exp_simul;
-
-/*----- Macros provided ---------------------------------------------------*/
-
-/* --- Parameters --- */
-
-#ifndef EXP_WINSZ                      /* Sliding window size */
-#  define EXP_WINSZ 4                  /* Predefine if you need to */
-#endif
-
-/* --- These are determined from the window size --- *
- *
- * Given a %$k$%-bit exponent, I expect to do %$k/2$% multiplies if I use the
- * simple way.  If I use an n-bit sliding window, then I do %$2^n$%
- * multiplies up front, but I only do %$(2^n - 1)/2^n k/n$% multiplies for
- * the exponentiation.  This is a win when
- *
- *   %$k \ge \frac{n 2^{n+1}}{n - 2}$%
- */
-
-#define EXP_TABSZ (1 << EXP_WINSZ)
-#define EXP_THRESH                                                     \
-    ((EXP_WINSZ * (2 << EXP_WINSZ))/((EXP_WINSZ - 2) * MPW_BITS))
-
-/* --- Required operations --- *
- *
- * The macros here are independent of the underlying group elements.  You
- * must provide the necessary group operations and other definitions.  The
- * group operation is assumed to be written multiplicatively.
- *
- * @EXP_TYPE@                  The type of a group element, e.g., @mp *@.
- *
- * @EXP_COPY(d, x)@            Makes @d@ be a copy of @x@.
- *
- * @EXP_DROP(x)@               Discards the element @x@, reclaiming any
- *                             memory it used.
- *
- * @EXP_MUL(a, x)@             Multiplies @a@ by @x@ (writing the result
- *                             back to @a@).
- *
- * @EXP_FIX(x)@                        Makes @x@ be a canonical representation of
- *                             its value.  All multiplications have the
- *                             right argument canonical.
- *
- * @EXP_SQR(a)@                        Multiplies @a@ by itself.
- *
- * @EXP_SETMUL(d, x, y)@       Sets @d@ to be the product of @x@ and @y@.
- *                             The value @d@ has not been initialized.
- *
- * @EXP_SETSQR(d, x)@          Sets @d@ to be the square of @x@.
- *
- * Only @EXP_TYPE@, @EXP_MUL@ and @EXP_SQR@ are required for simple
- * exponentation.  Sliding window and simultaneous exponentation require all
- * of the operations.
- */
-
-#ifndef EXP_TYPE
-#  error "EXP_TYPE not defined for <catacomb/exp.h>"
-#endif
-
-/* --- @EXP_SIMPLE@ --- *
- *
- * Arguments:  @a@ = the result object, initially a multiplicative identity
- *             @g@ = the object to exponentiate
- *             @x@ = the exponent, as a multiprecision integer
- *
- * Use:                Performs a simple left-to-right exponentiation.  At the end
- *             of the code, the answer is left in @a@; @g@ and @x@ are
- *             unchanged.
- */
-
-#define EXP_SIMPLE(a, g, x) do {                                       \
-  mpscan sc;                                                           \
-  unsigned sq = 0;                                                     \
-                                                                       \
-  /* --- Begin scanning --- */                                         \
-                                                                       \
-  mp_rscan(&sc, x);                                                    \
-  if (!MP_RSTEP(&sc))                                                  \
-    goto exp_simple_exit;                                              \
-  while (!MP_RBIT(&sc))                                                        \
-    MP_RSTEP(&sc);                                                     \
-                                                                       \
-  /* --- Do the main body of the work --- */                           \
-                                                                       \
-  EXP_FIX(g);                                                          \
-  for (;;) {                                                           \
-    EXP_MUL(a, g);                                                     \
-    sq = 0;                                                            \
-    for (;;) {                                                         \
-      if (!MP_RSTEP(&sc))                                              \
-       goto exp_simple_done;                                           \
-      sq++;                                                            \
-      if (MP_RBIT(&sc))                                                        \
-       break;                                                          \
-    }                                                                  \
-    while (sq--) EXP_SQR(a);                                           \
-  }                                                                    \
-                                                                       \
-  /* --- Do a final round of squaring --- */                           \
-                                                                       \
-exp_simple_done:                                                       \
-  while (sq--) EXP_SQR(a);                                             \
-exp_simple_exit:;                                                      \
-} while (0)
-
-/* --- @EXP_WINDOW@ --- *
- *
- * Arguments:  @a@ = the result object, initially a multiplicative identity
- *             @g@ = the object to exponentiate
- *             @x@ = the exponent, as a multiprecision integer
- *
- * Use:                Performs a sliding-window exponentiation.  At the end of the
- *             code, the answer is left in @a@; @g@ and @x@ are unchanged.
- */
-
-#define EXP_WINDOW(a, g, x) do {                                       \
-  EXP_TYPE *v;                                                         \
-  EXP_TYPE g2;                                                         \
-  unsigned i, sq = 0;                                                  \
-  mpscan sc;                                                           \
-                                                                       \
-  /* --- Get going --- */                                              \
-                                                                       \
-  mp_rscan(&sc, x);                                                    \
-  if (!MP_RSTEP(&sc))                                                  \
-    goto exp_window_exit;                                              \
-                                                                       \
-  /* --- Do the precomputation --- */                                  \
-                                                                       \
-  EXP_FIX(g);                                                          \
-  EXP_SETSQR(g2, g);                                                   \
-  EXP_FIX(g2);                                                         \
-  v = xmalloc(EXP_TABSZ * sizeof(EXP_TYPE));                           \
-  EXP_COPY(v[0], g);                                                   \
-  for (i = 1; i < EXP_TABSZ; i++) {                                    \
-    EXP_SETMUL(v[i], v[i - 1], g2);                                    \
-    EXP_FIX(v[i]);                                                     \
-  }                                                                    \
-  EXP_DROP(g2);                                                                \
-                                                                       \
-  /* --- Skip top-end zero bits --- *                                  \
-   *                                                                   \
-   * If the initial step worked, there must be a set bit somewhere, so \
-   * keep stepping until I find it.                                    \
-   */                                                                  \
-                                                                       \
-  while (!MP_RBIT(&sc))                                                        \
-    MP_RSTEP(&sc);                                                     \
-                                                                       \
-  /* --- Now for the main work --- */                                  \
-                                                                       \
-  for (;;) {                                                           \
-    unsigned l = 1;                                                    \
-    unsigned z = 0;                                                    \
-                                                                       \
-    /* --- The next bit is set, so read a window index --- *           \
-     *                                                                 \
-     * Reset @i@ to zero and increment @sq@.  Then, until either I read        \
-     * @WINSZ@ bits or I run out of bits, scan in a bit: if it's clear,        \
-     * bump the @z@ counter; if it's set, push a set bit into @i@,     \
-     * shift it over by @z@ bits, bump @sq@ by @z + 1@ and clear @z@.  \
-     * By the end of this palaver, @i@ is an index to the precomputed  \
-     * value in @v@.                                                   \
-     */                                                                        \
-                                                                       \
-    i = 0;                                                             \
-    sq++;                                                              \
-    while (l < EXP_WINSZ && MP_RSTEP(&sc)) {                           \
-      l++;                                                             \
-      if (!MP_RBIT(&sc))                                               \
-       z++;                                                            \
-      else {                                                           \
-       i = ((i << 1) | 1) << z;                                        \
-       sq += z + 1;                                                    \
-       z = 0;                                                          \
-      }                                                                        \
-    }                                                                  \
-                                                                       \
-    /* --- Do the squaring --- *                                       \
-     *                                                                 \
-     * Remember that @sq@ carries over from the zero-skipping stuff    \
-     * below.                                                          \
-     */                                                                        \
-                                                                       \
-    while (sq--) EXP_SQR(a);                                           \
-                                                                       \
-    /* --- Do the multiply --- */                                      \
-                                                                       \
-    EXP_MUL(a, v[i]);                                                  \
-                                                                       \
-    /* --- Now grind along through the rest of the bits --- */         \
-                                                                       \
-    sq = z;                                                            \
-    for (;;) {                                                         \
-      if (!MP_RSTEP(&sc))                                              \
-       goto exp_window_done;                                           \
-      if (MP_RBIT(&sc))                                                        \
-       break;                                                          \
-      sq++;                                                            \
-    }                                                                  \
-  }                                                                    \
-                                                                       \
-  /* --- Do a final round of squaring --- */                           \
-                                                                       \
-exp_window_done:                                                       \
-  while (sq--) EXP_SQR(a);                                             \
-  for (i = 0; i < EXP_TABSZ; i++)                                      \
-    EXP_DROP(v[i]);                                                    \
-  xfree(v);                                                            \
-exp_window_exit:;                                                      \
-} while (0)
-
-/* --- @EXP_SIMUL@ --- *
- *
- * Arguments:  @a@ = the result object, initially a multiplicative identity
- *             @f@ = pointer to a vector of base/exp pairs
- *             @n@ = the number of base/exp pairs
- *
- * Use:                Performs a simultaneous sliding-window exponentiation.  The
- *             @f@ table is an array of structures containing members @base@
- *             of type @EXP_TYPE@, and @exp@ of type @mp *@.
- */
-
-#define EXP_SIMUL(a, f, n) do {                                                \
-  size_t i, j, jj, k;                                                  \
-  size_t vn = 1 << (EXP_WINSZ * n), m = (1 << n) - 1;                  \
-  EXP_TYPE *v = xmalloc(vn * sizeof(EXP_TYPE));                                \
-  exp_simul e;                                                         \
-  unsigned sq = 0;                                                     \
-                                                                       \
-  /* --- Fill in the precomputed table --- */                          \
-                                                                       \
-  j = 1;                                                               \
-  for (i = 0; i < n; i++) {                                            \
-    EXP_COPY(v[j], f[n - 1 - i].base);                                 \
-    EXP_FIX(v[j]);                                                     \
-    j <<= 1;                                                           \
-  }                                                                    \
-  k = n * EXP_WINSZ;                                                   \
-  jj = 1;                                                              \
-  for (; i < k; i++) {                                                 \
-    EXP_SETSQR(v[j], v[jj]);                                           \
-    EXP_FIX(v[j]);                                                     \
-    j <<= 1; jj <<= 1;                                                 \
-  }                                                                    \
-  for (i = 1; i < vn; i <<= 1) {                                       \
-    for (j = 1; j < i; j++) {                                          \
-      EXP_SETMUL(v[j + i], v[j], v[i]);                                        \
-      EXP_FIX(v[j + i]);                                               \
-    }                                                                  \
-  }                                                                    \
-                                                                       \
-  /* --- Set up the bitscanners --- *                                  \
-   *                                                                   \
-   * Got to use custom scanners, to keep them all in sync.             \
-   */                                                                  \
-                                                                       \
-  e.n = n;                                                             \
-  e.b = 0;                                                             \
-  e.s = xmalloc(n * sizeof(*e.s));                                     \
-  e.o = 0;                                                             \
-  for (i = 0; i < n; i++) {                                            \
-    MP_SHRINK(f[i].exp);                                               \
-    e.s[i].len = MP_LEN(f[i].exp);                                     \
-    e.s[i].v = f[i].exp->v;                                            \
-    if (e.s[i].len > e.o)                                              \
-      e.o = e.s[i].len;                                                        \
-  }                                                                    \
-                                                                       \
-  /* --- Skip as far as a nonzero column in the exponent matrix --- */ \
-                                                                       \
-  do {                                                                 \
-    if (!e.o && !e.b)                                                  \
-      goto exp_simul_done;                                             \
-    i = exp_simulnext(&e, 0);                                          \
-  } while (!(i & m));                                                  \
-                                                                       \
-  /* --- Now for the main work --- */                                  \
-                                                                       \
-  for (;;) {                                                           \
-    unsigned l = 1;                                                    \
-    unsigned z = 0;                                                    \
-                                                                       \
-    /* --- Just read a nonzero column, so read a window index --- *    \
-     *                                                                 \
-     * Clear high bits of @i@ and increment @sq@.  Then, until either I        \
-     * read @WINSZ@ columns or I run out, scan in a column and append  \
-     * it to @i@.  If it's zero, bump the @z@ counter; if it's nonzero,        \
-     * bump @sq@ by @z + 1@ and clear @z@.  By the end of this palaver,        \
-     * @i@ is an index to the precomputed value in @v@, followed by    \
-     * @n * z@ zero bits.                                              \
-     */                                                                        \
-                                                                       \
-    sq++;                                                              \
-    while (l < EXP_WINSZ && (e.o || e.b)) {                            \
-      l++;                                                             \
-      i = exp_simulnext(&e, i);                                                \
-      if (!(i & m))                                                    \
-       z++;                                                            \
-      else {                                                           \
-       sq += z + 1;                                                    \
-       z = 0;                                                          \
-      }                                                                        \
-    }                                                                  \
-                                                                       \
-    /* --- Do the squaring --- *                                       \
-     *                                                                 \
-     * Remember that @sq@ carries over from the zero-skipping stuff    \
-     * below.                                                          \
-     */                                                                        \
-                                                                       \
-    while (sq--) EXP_SQR(a);                                           \
-                                                                       \
-    /* --- Do the multiply --- */                                      \
-                                                                       \
-    i >>= (z * n);                                                     \
-    EXP_MUL(a, v[i]);                                                  \
-                                                                       \
-    /* --- Now grind along through the rest of the bits --- */         \
-                                                                       \
-    sq = z;                                                            \
-    for (;;) {                                                         \
-      if (!e.o && !e.b)                                                        \
-       goto exp_simul_done;                                            \
-      if ((i = exp_simulnext(&e, 0)) != 0)                             \
-       break;                                                          \
-      sq++;                                                            \
-    }                                                                  \
-  }                                                                    \
-                                                                       \
-  /* --- Do a final round of squaring --- */                           \
-                                                                       \
-exp_simul_done:                                                                \
-  while (sq--) EXP_SQR(a);                                             \
-  for (i = 1; i < vn; i++)                                             \
-    EXP_DROP(v[i]);                                                    \
-  xfree(v);                                                            \
-  xfree(e.s);                                                          \
-} while (0)
-
-/*----- Functions provided ------------------------------------------------*/
-
-/* --- @exp_simulnext@ --- *
- *
- * Arguments:  @exp_simul *e@ = pointer to state structure
- *             @size_t x@ = a current accumulator
- *
- * Returns:    The next column of bits.
- *
- * Use:                Scans the next column of bits for a simultaneous
- *             exponentiation.
- */
-
-extern size_t exp_simulnext(exp_simul */*e*/, size_t /*x*/);
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
-  }
-#endif