Update the in-tree GMP; fixes trac #832
[ghc-hetmet.git] / rts / gmp / randraw.c
diff --git a/rts/gmp/randraw.c b/rts/gmp/randraw.c
deleted file mode 100644 (file)
index c0c3889..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-/* _gmp_rand (rp, state, nbits) -- Generate a random bitstream of
-   length NBITS in RP.  RP must have enough space allocated to hold
-   NBITS.
-
-Copyright (C) 1999, 2000 Free Software Foundation, Inc.
-
-This file is part of the GNU MP Library.
-
-The GNU MP Library is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or (at your
-option) any later version.
-
-The GNU MP Library 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 Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-MA 02111-1307, USA. */
-
-#include "gmp.h"
-#include "gmp-impl.h"
-#include "longlong.h"
-
-/* For linear congruential (LC), we use one of algorithms (1) or (2).
-   (gmp-3.0 uses algorithm (1) with 'm' as a power of 2.)
-
-LC algorithm (1).
-
-       X = (aX + c) mod m
-
-[D. Knuth, "The Art of Computer Programming: Volume 2, Seminumerical Algorithms",
-Third Edition, Addison Wesley, 1998, pp. 184-185.]
-
-       X is the seed and the result
-       a is chosen so that
-           a mod 8 = 5 [3.2.1.2] and [3.2.1.3]
-           .01m < a < .99m
-           its binary or decimal digits is not a simple, regular pattern
-           it has no large quotients when Euclid's algorithm is used to find
-             gcd(a, m) [3.3.3]
-           it passes the spectral test [3.3.4]
-           it passes several tests of [3.3.2]
-       c has no factor in common with m (c=1 or c=a can be good)
-       m is large (2^30)
-         is a power of 2 [3.2.1.1]
-
-The least significant digits of the generated number are not very
-random.  It should be regarded as a random fraction X/m.  To get a
-random integer between 0 and n-1, multiply X/m by n and truncate.
-(Don't use X/n [ex 3.4.1-3])
-
-The ``accuracy'' in t dimensions is one part in ``the t'th root of m'' [3.3.4].
-
-Don't generate more than about m/1000 numbers without changing a, c, or m.
-
-The sequence length depends on chosen a,c,m.
-
-
-LC algorithm (2).
-
-       X = a * (X mod q) - r * (long) (X/q)
-       if X<0 then X+=m
-
-[Knuth, pp. 185-186.]
-
-       X is the seed and the result
-         as a seed is nonzero and less than m
-       a is a primitive root of m (which means that a^2 <= m)
-       q is (long) m / a
-       r is m mod a
-       m is a prime number near the largest easily computed integer
-
-which gives
-
-       X = a * (X % ((long) m / a)) -
-           (M % a) * ((long) (X / ((long) m / a)))
-
-Since m is prime, the least-significant bits of X are just as random as
-the most-significant bits. */
-
-/* Blum, Blum, and Shub.
-
-   [Bruce Schneier, "Applied Cryptography", Second Edition, John Wiley
-   & Sons, Inc., 1996, pp. 417-418.]
-
-   "Find two large prime numbers, p and q, which are congruent to 3
-   modulo 4.  The product of those numbers, n, is a blum integer.
-   Choose another random integer, x, which is relatively prime to n.
-   Compute
-       x[0] = x^2 mod n
-   That's the seed for the generator."
-
-   To generate a random bit, compute
-       x[i] = x[i-1]^2 mod n
-   The least significant bit of x[i] is the one we want.
-
-   We can use more than one bit from x[i], namely the
-       log2(bitlength of x[i])
-   least significant bits of x[i].
-
-   So, for a 32-bit seed we get 5 bits per computation.
-
-   The non-predictability of this generator is based on the difficulty
-   of factoring n.
- */
-
-/* -------------------------------------------------- */
-
-/* lc (rp, state) -- Generate next number in LC sequence.  Return the
-   number of valid bits in the result.  NOTE: If 'm' is a power of 2
-   (m2exp != 0), discard the lower half of the result.  */
-
-static
-unsigned long int
-#if __STDC__
-lc (mp_ptr rp, gmp_randstate_t rstate)
-#else
-lc (rp, rstate)
-     mp_ptr rp;
-     gmp_randstate_t rstate;
-#endif
-{
-  mp_ptr tp, seedp, ap;
-  mp_size_t ta;
-  mp_size_t tn, seedn, an;
-  mp_size_t retval;
-  int shiftcount = 0;
-  unsigned long int m2exp;
-  mp_limb_t c;
-  TMP_DECL (mark);
-
-  m2exp = rstate->algdata.lc->m2exp;
-  c = (mp_limb_t) rstate->algdata.lc->c;
-
-  seedp = PTR (rstate->seed);
-  seedn = SIZ (rstate->seed);
-
-  if (seedn == 0)
-    {
-      /* Seed is 0.  Result is C % M.  */
-      *rp = c;
-
-      if (m2exp != 0)
-       {
-         /* M is a power of 2.  */
-         if (m2exp < BITS_PER_MP_LIMB)
-           {
-             /* Only necessary when M may be smaller than C.  */
-             *rp &= (((mp_limb_t) 1 << m2exp) - 1);
-           }
-       }
-      else
-       {
-         /* M is not a power of 2.  */
-         abort ();             /* FIXME.  */
-       }
-
-      /* Save result as next seed.  */
-      *seedp = *rp;
-      SIZ (rstate->seed) = 1;
-      return BITS_PER_MP_LIMB;
-    }
-
-  ap = PTR (rstate->algdata.lc->a);
-  an = SIZ (rstate->algdata.lc->a);
-
-  /* Allocate temporary storage.  Let there be room for calculation of
-     (A * seed + C) % M, or M if bigger than that.  */
-
-  ASSERT_ALWAYS (m2exp != 0);  /* FIXME.  */
-
-  TMP_MARK (mark);
-  ta = an + seedn + 1;
-  tp = (mp_ptr) TMP_ALLOC (ta * BYTES_PER_MP_LIMB);
-  MPN_ZERO (tp, ta);
-
-  /* t = a * seed */
-  if (seedn >= an)
-    mpn_mul_basecase (tp, seedp, seedn, ap, an);
-  else
-    mpn_mul_basecase (tp, ap, an, seedp, seedn);
-  tn = an + seedn;
-
-  /* t = t + c */
-  mpn_incr_u (tp, c);
-
-  /* t = t % m */
-  if (m2exp != 0)
-    {
-      /* M is a power of 2.  The mod operation is trivial.  */
-
-      tp[m2exp / BITS_PER_MP_LIMB] &= ((mp_limb_t) 1 << m2exp % BITS_PER_MP_LIMB) - 1;
-      tn = (m2exp + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
-    }
-  else
-    {
-      abort ();                        /* FIXME.  */
-    }
-
-  /* Save result as next seed.  */
-  MPN_COPY (PTR (rstate->seed), tp, tn);
-  SIZ (rstate->seed) = tn;
-
-  if (m2exp != 0)
-    {
-      /* Discard the lower half of the result.  */
-      unsigned long int discardb = m2exp / 2;
-      mp_size_t discardl = discardb / BITS_PER_MP_LIMB;
-
-      tn -= discardl;
-      if (tn > 0)
-       {
-         if (discardb % BITS_PER_MP_LIMB != 0)
-           {
-             mpn_rshift (tp, tp + discardl, tn, discardb % BITS_PER_MP_LIMB);
-             MPN_COPY (rp, tp, (discardb + BITS_PER_MP_LIMB -1) / BITS_PER_MP_LIMB);
-           }
-         else                  /* Even limb boundary.  */
-           MPN_COPY_INCR (rp, tp + discardl, tn);
-       }
-    }
-  else
-    {
-      MPN_COPY (rp, tp, tn);
-    }
-
-  TMP_FREE (mark);
-
-  /* Return number of valid bits in the result.  */
-  if (m2exp != 0)
-    retval = (m2exp + 1) / 2;
-  else
-    retval = SIZ (rstate->algdata.lc->m) * BITS_PER_MP_LIMB - shiftcount;
-  return retval;
-}
-
-#ifdef RAWRANDEBUG
-/* Set even bits to EVENBITS and odd bits to ! EVENBITS in RP.
-   Number of bits is m2exp in state.  */
-/* FIXME: Remove.  */
-unsigned long int
-lc_test (mp_ptr rp, gmp_randstate_t s, const int evenbits)
-{
-  unsigned long int rn, nbits;
-  int f;
-
-  nbits = s->algdata.lc->m2exp / 2;
-  rn = nbits / BITS_PER_MP_LIMB + (nbits % BITS_PER_MP_LIMB != 0);
-  MPN_ZERO (rp, rn);
-
-  for (f = 0; f < nbits; f++)
-    {
-      mpn_lshift (rp, rp, rn, 1);
-      if (f % 2 == ! evenbits)
-       rp[0] += 1;
-    }
-
-  return nbits;
-}
-#endif /* RAWRANDEBUG */
-
-void
-#if __STDC__
-_gmp_rand (mp_ptr rp, gmp_randstate_t rstate, unsigned long int nbits)
-#else
-_gmp_rand (rp, rstate, nbits)
-     mp_ptr rp;
-     gmp_randstate_t rstate;
-     unsigned long int nbits;
-#endif
-{
-  mp_size_t rn;                        /* Size of R.  */
-
-  rn = (nbits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
-
-  switch (rstate->alg)
-    {
-    case GMP_RAND_ALG_LC:
-      {
-       unsigned long int rbitpos;
-       int chunk_nbits;
-       mp_ptr tp;
-       mp_size_t tn;
-       TMP_DECL (lcmark);
-
-       TMP_MARK (lcmark);
-
-       chunk_nbits = rstate->algdata.lc->m2exp / 2;
-       tn = (chunk_nbits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
-
-       tp = (mp_ptr) TMP_ALLOC (tn * BYTES_PER_MP_LIMB);
-
-       rbitpos = 0;
-       while (rbitpos + chunk_nbits <= nbits)
-         {
-           mp_ptr r2p = rp + rbitpos / BITS_PER_MP_LIMB;
-
-           if (rbitpos % BITS_PER_MP_LIMB != 0)
-             {
-               mp_limb_t savelimb, rcy;
-               /* Target of of new chunk is not bit aligned.  Use temp space
-                  and align things by shifting it up.  */
-               lc (tp, rstate);
-               savelimb = r2p[0];
-               rcy = mpn_lshift (r2p, tp, tn, rbitpos % BITS_PER_MP_LIMB);
-               r2p[0] |= savelimb;
-/* bogus */    if ((chunk_nbits % BITS_PER_MP_LIMB + rbitpos % BITS_PER_MP_LIMB)
-                   > BITS_PER_MP_LIMB)
-                 r2p[tn] = rcy;
-             }
-           else
-             {
-               /* Target of of new chunk is bit aligned.  Let `lc' put bits
-                  directly into our target variable.  */
-               lc (r2p, rstate);
-             }
-           rbitpos += chunk_nbits;
-         }
-
-       /* Handle last [0..chunk_nbits) bits.  */
-       if (rbitpos != nbits)
-         {
-           mp_ptr r2p = rp + rbitpos / BITS_PER_MP_LIMB;
-           int last_nbits = nbits - rbitpos;
-           tn = (last_nbits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
-           lc (tp, rstate);
-           if (rbitpos % BITS_PER_MP_LIMB != 0)
-             {
-               mp_limb_t savelimb, rcy;
-               /* Target of of new chunk is not bit aligned.  Use temp space
-                  and align things by shifting it up.  */
-               savelimb = r2p[0];
-               rcy = mpn_lshift (r2p, tp, tn, rbitpos % BITS_PER_MP_LIMB);
-               r2p[0] |= savelimb;
-               if (rbitpos + tn * BITS_PER_MP_LIMB - rbitpos % BITS_PER_MP_LIMB < nbits)
-                 r2p[tn] = rcy;
-             }
-           else
-             {
-               MPN_COPY (r2p, tp, tn);
-             }
-           /* Mask off top bits if needed.  */
-           if (nbits % BITS_PER_MP_LIMB != 0)
-             rp[nbits / BITS_PER_MP_LIMB]
-               &= ~ ((~(mp_limb_t) 0) << nbits % BITS_PER_MP_LIMB);
-         }
-
-       TMP_FREE (lcmark);
-       break;
-      }
-
-    default:
-      gmp_errno |= GMP_ERROR_UNSUPPORTED_ARGUMENT;
-      break;
-    }
-}