Home | History | Annotate | Line # | Download | only in generic
bsqrtinv.c revision 1.1
      1  1.1  mrg /* mpn_bsqrtinv, compute r such that r^2 * y = 1 (mod 2^{b+1}).
      2  1.1  mrg 
      3  1.1  mrg    Contributed to the GNU project by Martin Boij (as part of perfpow.c).
      4  1.1  mrg 
      5  1.1  mrg Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
      6  1.1  mrg 
      7  1.1  mrg This file is part of the GNU MP Library.
      8  1.1  mrg 
      9  1.1  mrg The GNU MP Library is free software; you can redistribute it and/or modify
     10  1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     11  1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     12  1.1  mrg option) any later version.
     13  1.1  mrg 
     14  1.1  mrg The GNU MP Library is distributed in the hope that it will be useful, but
     15  1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16  1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     17  1.1  mrg License for more details.
     18  1.1  mrg 
     19  1.1  mrg You should have received a copy of the GNU Lesser General Public License
     20  1.1  mrg along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
     21  1.1  mrg 
     22  1.1  mrg #include "gmp.h"
     23  1.1  mrg #include "gmp-impl.h"
     24  1.1  mrg 
     25  1.1  mrg /* Compute r such that r^2 * y = 1 (mod 2^{b+1}).
     26  1.1  mrg    Return non-zero if such an integer r exists.
     27  1.1  mrg 
     28  1.1  mrg    Iterates
     29  1.1  mrg      r' <-- (3r - r^3 y) / 2
     30  1.1  mrg    using Hensel lifting.  Since we divide by two, the Hensel lifting is
     31  1.1  mrg    somewhat degenerates.  Therefore, we lift from 2^b to 2^{b+1}-1.
     32  1.1  mrg 
     33  1.1  mrg    FIXME:
     34  1.1  mrg      (1) Simplify to do precision book-keeping in limbs rather than bits.
     35  1.1  mrg 
     36  1.1  mrg      (2) Rewrite iteration as
     37  1.1  mrg 	   r' <-- r - r (r^2 y - 1) / 2
     38  1.1  mrg 	 and take advantage of zero low part of r^2 y - 1.
     39  1.1  mrg 
     40  1.1  mrg      (3) Use wrap-around trick.
     41  1.1  mrg 
     42  1.1  mrg      (4) Use a small table to get starting value.
     43  1.1  mrg */
     44  1.1  mrg int
     45  1.1  mrg mpn_bsqrtinv (mp_ptr rp, mp_srcptr yp, mp_bitcnt_t bnb, mp_ptr tp)
     46  1.1  mrg {
     47  1.1  mrg   mp_ptr tp2, tp3;
     48  1.1  mrg   mp_limb_t k;
     49  1.1  mrg   mp_size_t bn, order[GMP_LIMB_BITS + 1];
     50  1.1  mrg   int i, d;
     51  1.1  mrg 
     52  1.1  mrg   ASSERT (bnb > 0);
     53  1.1  mrg 
     54  1.1  mrg   bn = 1 + bnb / GMP_LIMB_BITS;
     55  1.1  mrg 
     56  1.1  mrg   tp2 = tp + bn;
     57  1.1  mrg   tp3 = tp + 2 * bn;
     58  1.1  mrg   k = 3;
     59  1.1  mrg 
     60  1.1  mrg   rp[0] = 1;
     61  1.1  mrg   if (bnb == 1)
     62  1.1  mrg     {
     63  1.1  mrg       if ((yp[0] & 3) != 1)
     64  1.1  mrg 	return 0;
     65  1.1  mrg     }
     66  1.1  mrg   else
     67  1.1  mrg     {
     68  1.1  mrg       if ((yp[0] & 7) != 1)
     69  1.1  mrg 	return 0;
     70  1.1  mrg 
     71  1.1  mrg       d = 0;
     72  1.1  mrg       for (; bnb != 2; bnb = (bnb + 2) >> 1)
     73  1.1  mrg 	order[d++] = bnb;
     74  1.1  mrg 
     75  1.1  mrg       for (i = d - 1; i >= 0; i--)
     76  1.1  mrg 	{
     77  1.1  mrg 	  bnb = order[i];
     78  1.1  mrg 	  bn = 1 + bnb / GMP_LIMB_BITS;
     79  1.1  mrg 
     80  1.1  mrg 	  mpn_mul_1 (tp, rp, bn, k);
     81  1.1  mrg 
     82  1.1  mrg 	  mpn_powlo (tp2, rp, &k, 1, bn, tp3);
     83  1.1  mrg 	  mpn_mullo_n (rp, yp, tp2, bn);
     84  1.1  mrg 
     85  1.1  mrg #if HAVE_NATIVE_mpn_rsh1sub_n
     86  1.1  mrg 	  mpn_rsh1sub_n (rp, tp, rp, bn);
     87  1.1  mrg #else
     88  1.1  mrg 	  mpn_sub_n (tp2, tp, rp, bn);
     89  1.1  mrg 	  mpn_rshift (rp, tp2, bn, 1);
     90  1.1  mrg #endif
     91  1.1  mrg 	}
     92  1.1  mrg     }
     93  1.1  mrg   return 1;
     94  1.1  mrg }
     95