(root)/
gmp-6.3.0/
bootstrap.c
       1  /* Functions needed for bootstrapping the gmp build, based on mini-gmp.
       2  
       3  Copyright 2001, 2002, 2004, 2011, 2012, 2015 Free Software Foundation, Inc.
       4  
       5  This file is part of the GNU MP Library.
       6  
       7  The GNU MP Library is free software; you can redistribute it and/or modify
       8  it under the terms of either:
       9  
      10    * the GNU Lesser General Public License as published by the Free
      11      Software Foundation; either version 3 of the License, or (at your
      12      option) any later version.
      13  
      14  or
      15  
      16    * the GNU General Public License as published by the Free Software
      17      Foundation; either version 2 of the License, or (at your option) any
      18      later version.
      19  
      20  or both in parallel, as here.
      21  
      22  The GNU MP Library is distributed in the hope that it will be useful, but
      23  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      24  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      25  for more details.
      26  
      27  You should have received copies of the GNU General Public License and the
      28  GNU Lesser General Public License along with the GNU MP Library.  If not,
      29  see https://www.gnu.org/licenses/.  */
      30  
      31  
      32  #define MINI_GMP_DONT_USE_FLOAT_H 1
      33  #include "mini-gmp/mini-gmp.c"
      34  
      35  #define MIN(l,o) ((l) < (o) ? (l) : (o))
      36  #define PTR(x)   ((x)->_mp_d)
      37  #define SIZ(x)   ((x)->_mp_size)
      38  
      39  #define xmalloc gmp_default_alloc
      40  
      41  int
      42  isprime (unsigned long int t)
      43  {
      44    unsigned long int q, r, d;
      45  
      46    if (t < 32)
      47      return (0xa08a28acUL >> t) & 1;
      48    if ((t & 1) == 0)
      49      return 0;
      50  
      51    if (t % 3 == 0)
      52      return 0;
      53    if (t % 5 == 0)
      54      return 0;
      55    if (t % 7 == 0)
      56      return 0;
      57  
      58    for (d = 11;;)
      59      {
      60        q = t / d;
      61        r = t - q * d;
      62        if (q < d)
      63  	return 1;
      64        if (r == 0)
      65  	break;
      66        d += 2;
      67        q = t / d;
      68        r = t - q * d;
      69        if (q < d)
      70  	return 1;
      71        if (r == 0)
      72  	break;
      73        d += 4;
      74      }
      75    return 0;
      76  }
      77  
      78  int
      79  log2_ceil (int n)
      80  {
      81    int  e;
      82    assert (n >= 1);
      83    for (e = 0; ; e++)
      84      if ((1 << e) >= n)
      85        break;
      86    return e;
      87  }
      88  
      89  /* Set inv to the inverse of d, in the style of invert_limb, ie. for
      90     udiv_qrnnd_preinv.  */
      91  void
      92  mpz_preinv_invert (mpz_t inv, const mpz_t d, int numb_bits)
      93  {
      94    mpz_t  t;
      95    int    norm;
      96    assert (SIZ(d) > 0);
      97  
      98    norm = numb_bits - mpz_sizeinbase (d, 2);
      99    assert (norm >= 0);
     100    mpz_init (t);
     101    mpz_setbit (t, 2*numb_bits - norm);
     102    mpz_tdiv_q (inv, t, d);
     103    mpz_clrbit (inv, numb_bits);
     104  
     105    mpz_clear (t);
     106  }
     107  
     108  /* Calculate r satisfying r*a == 1 mod 2^n. */
     109  void
     110  mpz_invert_2exp (mpz_t r, const mpz_t a, unsigned long n)
     111  {
     112    mpz_t  mod;
     113  
     114    assert (mpz_odd_p (a));
     115  
     116    mpz_init (mod);
     117    mpz_setbit (mod, n);
     118  
     119    mpz_invert (r, a, mod);
     120  
     121    mpz_clear (mod);
     122  }
     123  
     124  /* Calculate inv satisfying r*a == 1 mod 2^n. */
     125  void
     126  mpz_invert_ui_2exp (mpz_t r, unsigned long a, unsigned long n)
     127  {
     128    mpz_t  az;
     129  
     130    mpz_init_set_ui (az, a);
     131    mpz_invert_2exp (r, az, n);
     132    mpz_clear (az);
     133  }