1 /* auxiliary routines on GMP data-types */
2 
3 #include "cado.h" // IWYU pragma: keep
4 #include <stdbool.h>
5 #include <stdint.h>
6 #include <limits.h>     /* for INT_MAX */
7 #include <gmp.h>
8 #include "gmp_aux.h"
9 #include "getprime.h"  // for getprime_mt, prime_info_clear, prime_info_init
10 #include "macros.h"    // for ASSERT_ALWAYS // IWYU pragma: keep
11 
12 /* old versions of GMP do not provide mpn_neg (was mpn_neg_n) and mpn_xor_n */
13 #if !GMP_VERSION_ATLEAST(5,0,0)
14 mp_limb_t
mpn_neg(mp_limb_t * rp,const mp_limb_t * sp,mp_size_t n)15 mpn_neg (mp_limb_t *rp, const mp_limb_t *sp, mp_size_t n)
16 {
17   mp_size_t i;
18 
19   for (i = 0; i < n; i++)
20     rp[i] = ~sp[i];
21   return mpn_add_1 (rp, rp, n, 1);
22 }
23 
24 void
mpn_xor_n(mp_limb_t * rp,const mp_limb_t * s1p,const mp_limb_t * s2p,mp_size_t n)25 mpn_xor_n (mp_limb_t *rp, const mp_limb_t *s1p, const mp_limb_t *s2p,
26 	   mp_size_t n)
27 {
28   mp_size_t i;
29 
30   for (i = 0; i < n; i++)
31     rp[i] = s1p[i] ^ s2p[i];
32 }
33 
34 void
mpn_zero(mp_limb_t * rp,mp_size_t n)35 mpn_zero(mp_limb_t *rp, mp_size_t n)
36 {
37     memset(rp, 0, n * sizeof(mp_limb_t));
38 }
39 void
mpn_copyi(mp_limb_t * rp,const mp_limb_t * up,mp_size_t n)40 mpn_copyi(mp_limb_t *rp, const mp_limb_t *up, mp_size_t n)
41 {
42     memmove(rp, up, n * sizeof(mp_limb_t));
43 }
44 void
mpn_copyd(mp_limb_t * rp,const mp_limb_t * up,mp_size_t n)45 mpn_copyd(mp_limb_t *rp, const mp_limb_t *up, mp_size_t n)
46 {
47     memmove(rp, up, n * sizeof(mp_limb_t));
48 }
49 #endif
50 
51 #if !GMP_VERSION_ATLEAST(6,1,0)
mpn_zero_p(const mp_limb_t * rp,mp_size_t n)52 int mpn_zero_p(const mp_limb_t *rp, mp_size_t n)
53 {
54     for( ; n-- ; ) if (rp[n]) return 0;
55     return 1;
56 }
57 #endif
58 
59 #if ULONG_BITS < 64
60 /* Set z to q. Warning: on 32-bit machines, we cannot use mpz_set_ui! */
61 void
mpz_set_uint64(mpz_ptr z,uint64_t q)62 mpz_set_uint64 (mpz_ptr z, uint64_t q)
63 {
64   if (q <= ULONG_MAX)
65     mpz_set_ui (z, (unsigned long) q);
66   else
67     {
68       ASSERT_ALWAYS (sizeof (unsigned long) == 4);
69       mpz_set_ui (z, (unsigned long) (q >> 32));
70       mpz_mul_2exp (z, z, 32);
71       /* The & here should be optimized into a direct cast to a 32-bit
72        * register in most cases (TODO: check) */
73       mpz_add_ui (z, z, (unsigned long) (q & 4294967295UL));
74     }
75 }
76 
77 void
mpz_set_int64(mpz_ptr z,int64_t q)78 mpz_set_int64 (mpz_ptr z, int64_t q)
79 {
80   if (LONG_MIN <= q && q <= LONG_MAX)
81     mpz_set_si (z, (long) q);
82   else if (q >= 0)
83     mpz_set_uint64 (z, (uint64_t) q);
84   else
85     {
86       mpz_set_uint64 (z, -(uint64_t)q);
87       mpz_neg (z, z);
88     }
89 }
90 
mpz_init_set_uint64(mpz_ptr z,uint64_t x)91 void mpz_init_set_uint64 (mpz_ptr z, uint64_t x)
92 {
93     mpz_init2(z, 64);
94     mpz_set_uint64(z, x);
95 }
96 
mpz_init_set_int64(mpz_ptr z,int64_t x)97 void mpz_init_set_int64 (mpz_ptr z, int64_t x)
98 {
99     mpz_init2(z, 64);
100     mpz_set_int64(z, x);
101 }
102 
103 uint64_t
mpz_get_uint64(mpz_srcptr z)104 mpz_get_uint64 (mpz_srcptr z)
105 {
106     uint64_t q;
107 
108     if (sizeof (unsigned long) == 8)
109         q = mpz_get_ui (z);
110     else
111     {
112         ASSERT_ALWAYS (sizeof (unsigned long) == 4);
113         ASSERT_ALWAYS (sizeof (mp_limb_t) == 4);
114         ASSERT_ALWAYS (GMP_LIMB_BITS == 32);
115         q = mpz_get_ui (z); /* get the low word of z */
116         q += ((uint64_t) mpz_getlimbn(z,1)) << 32;
117     }
118     return q;
119 }
120 
121 int
mpz_fits_uint64_p(mpz_srcptr z)122 mpz_fits_uint64_p (mpz_srcptr z)
123 {
124     if (mpz_sgn(z) < 0)
125         return 0;
126     size_t l = mpz_sizeinbase(z, 2);
127     return (l <= 64);
128 }
129 
130 int64_t
mpz_get_int64(mpz_srcptr z)131 mpz_get_int64 (mpz_srcptr z)
132 {
133     const uint64_t l = mpz_get_uint64(z);
134     if (mpz_sgn(z) >= 0)
135         return l & (uint64_t) INT64_MAX;
136     /* We want 1 -> -1, 2 -> -2, ...,
137        2^63-1 -> -2^63+1, 2^63 -> -2^63, 2^63+1 -> -1 */
138     return (int64_t) -(((l - 1) & (uint64_t) INT64_MAX) + 1);
139 }
140 
141 int
mpz_fits_sint64_p(mpz_srcptr z)142 mpz_fits_sint64_p (mpz_srcptr z)
143 {
144     size_t l = mpz_sizeinbase(z, 2);
145     if (l <= 63) return 1;
146     /* Also accept -2^63, which is INT64_MIN */
147     if (mpz_sgn(z) < 0 && l == 64  && mpz_scan1(z, 0) == 63) return 1;
148     return 0;
149 }
150 
151 void
mpz_mul_uint64(mpz_ptr a,mpz_srcptr b,uint64_t c)152 mpz_mul_uint64 (mpz_ptr a, mpz_srcptr b, uint64_t c)
153 {
154   if (c <= ULONG_MAX)
155     mpz_mul_ui (a, b, (unsigned long) c);
156   else
157     {
158       mpz_t d;
159       mpz_init_set_uint64 (d, c);
160       mpz_mul (a, b, d);
161       mpz_clear (d);
162     }
163 }
164 
165 int
mpz_cmp_uint64(mpz_srcptr a,uint64_t c)166 mpz_cmp_uint64 (mpz_srcptr a, uint64_t c)
167 {
168   if (c <= ULONG_MAX)
169     return mpz_cmp_ui (a, (unsigned long) c);
170   else
171     {
172       mpz_t d;
173       mpz_init_set_uint64 (d, c);
174       int r = mpz_cmp (a, d);
175       mpz_clear (d);
176       return r;
177     }
178 }
179 
180 int
mpz_cmp_int64(mpz_srcptr a,int64_t c)181 mpz_cmp_int64 (mpz_srcptr a, int64_t c)
182 {
183   if (LONG_MIN <= c && c <= LONG_MAX)
184     return mpz_cmp_si (a, (long) c);
185   else
186     {
187       mpz_t d;
188       mpz_init_set_int64 (d, c);
189       int r = mpz_cmp (a, d);
190       mpz_clear (d);
191       return r;
192     }
193 }
194 
195 void
mpz_add_uint64(mpz_ptr a,mpz_srcptr b,uint64_t c)196 mpz_add_uint64 (mpz_ptr a, mpz_srcptr b, uint64_t c)
197 {
198   if (c <= ULONG_MAX)
199     mpz_add_ui (a, b, (unsigned long) c);
200   else
201     {
202       mpz_t d;
203       mpz_init_set_uint64 (d, c);
204       mpz_add (a, b, d);
205       mpz_clear (d);
206     }
207 }
208 
209 void
mpz_add_int64(mpz_ptr a,mpz_srcptr b,int64_t c)210 mpz_add_int64 (mpz_ptr a, mpz_srcptr b, int64_t c)
211 {
212   if (c >= 0)
213     mpz_add_uint64 (a, b, (uint64_t) c);
214   else
215     mpz_sub_uint64 (a, b, -(uint64_t) c);
216 }
217 
218 void
mpz_sub_uint64(mpz_ptr a,mpz_srcptr b,uint64_t c)219 mpz_sub_uint64 (mpz_ptr a, mpz_srcptr b, uint64_t c)
220 {
221   if (c <= ULONG_MAX)
222     mpz_sub_ui (a, b, (unsigned long) c);
223   else
224     {
225       mpz_t d;
226       mpz_init_set_uint64 (d, c);
227       mpz_sub (a, b, d);
228       mpz_clear (d);
229     }
230 }
231 
232 void
mpz_sub_int64(mpz_ptr a,mpz_srcptr b,int64_t c)233 mpz_sub_int64 (mpz_ptr a, mpz_srcptr b, int64_t c)
234 {
235   if (c >= 0)
236     mpz_sub_uint64 (a, b, (uint64_t) c);
237   else
238     mpz_add_uint64 (a, b, -(uint64_t) c);
239 }
240 
241 void
mpz_addmul_uint64(mpz_ptr a,mpz_srcptr b,uint64_t c)242 mpz_addmul_uint64 (mpz_ptr a, mpz_srcptr b, uint64_t c)
243 {
244   if (c <= ULONG_MAX)
245     mpz_addmul_ui (a, b, (unsigned long) c);
246   else
247     {
248       mpz_t d;
249       mpz_init_set_uint64 (d, c);
250       mpz_addmul (a, b, d);
251       mpz_clear (d);
252     }
253 }
254 
255 void
mpz_submul_uint64(mpz_ptr a,mpz_srcptr b,uint64_t c)256 mpz_submul_uint64 (mpz_ptr a, mpz_srcptr b, uint64_t c)
257 {
258   if (c <= ULONG_MAX)
259     mpz_submul_ui (a, b, (unsigned long) c);
260   else
261     {
262       mpz_t d;
263       mpz_init_set_uint64 (d, c);
264       mpz_submul (a, b, d);
265       mpz_clear (d);
266     }
267 }
268 
269 void
mpz_divexact_uint64(mpz_ptr a,mpz_srcptr b,uint64_t c)270 mpz_divexact_uint64 (mpz_ptr a, mpz_srcptr b, uint64_t c)
271 {
272   if (c <= ULONG_MAX)
273     mpz_divexact_ui (a, b, (unsigned long) c);
274   else
275     {
276       mpz_t d;
277       mpz_init_set_uint64 (d, c);
278       mpz_divexact (a, b, d);
279       mpz_clear (d);
280     }
281 }
282 
283 int
mpz_divisible_uint64_p(mpz_ptr a,uint64_t c)284 mpz_divisible_uint64_p (mpz_ptr a, uint64_t c)
285 {
286   if (c <= ULONG_MAX)
287     return mpz_divisible_ui_p (a, (unsigned long) c);
288   else
289     {
290       mpz_t d;
291       int ret;
292 
293       mpz_init_set_uint64 (d, c);
294       ret = mpz_divisible_p (a, d);
295       mpz_clear (d);
296       return ret;
297     }
298 }
299 
300 void
mpz_mul_int64(mpz_ptr a,mpz_srcptr b,int64_t c)301 mpz_mul_int64 (mpz_ptr a, mpz_srcptr b, int64_t c)
302 {
303   if (LONG_MIN <= c && c <= LONG_MAX)
304     mpz_mul_si (a, b, (long) c);
305   else
306     {
307       mpz_t d;
308       mpz_init_set_int64 (d, c);
309       mpz_mul (a, b, d);
310       mpz_clear (d);
311     }
312 }
313 
314 uint64_t
uint64_nextprime(uint64_t q)315 uint64_nextprime (uint64_t q)
316 {
317   mpz_t z;
318 
319   mpz_init_set_uint64 (z, q);
320   mpz_nextprime (z, z);
321   q = mpz_get_uint64 (z);
322   mpz_clear (z);
323   return q;
324 }
325 
326 uint64_t
mpz_tdiv_qr_uint64(mpz_ptr Q,mpz_ptr R,mpz_srcptr N,uint64_t d)327 mpz_tdiv_qr_uint64 (mpz_ptr Q, mpz_ptr R, mpz_srcptr N, uint64_t d)
328 {
329     mpz_t D;
330     mpz_init_set_uint64 (D, d);
331     mpz_tdiv_qr (Q, R, N, D);
332     uint64_t r = mpz_get_uint64 (R);
333     mpz_clear (D);
334     return r;
335 }
336 
337 uint64_t
mpz_tdiv_q_uint64(mpz_ptr Q,mpz_srcptr N,uint64_t d)338 mpz_tdiv_q_uint64 (mpz_ptr Q, mpz_srcptr N, uint64_t d)
339 {
340     mpz_t R;
341     mpz_init2 (R, 64);
342     uint64_t r = mpz_tdiv_qr_uint64 (Q, R, N, d);
343     mpz_clear (R);
344     return r;
345 }
346 
347 uint64_t
mpz_tdiv_r_uint64(mpz_ptr R,mpz_srcptr N,uint64_t d)348 mpz_tdiv_r_uint64 (mpz_ptr R, mpz_srcptr N, uint64_t d)
349 {
350     mpz_t D;
351     mpz_init_set_uint64 (D, d);
352     mpz_tdiv_r (R, N, D);
353     uint64_t r = mpz_get_uint64 (R);
354     mpz_clear (D);
355     return r;
356 }
357 
358 uint64_t
mpz_tdiv_uint64(mpz_srcptr N,uint64_t d)359 mpz_tdiv_uint64 (mpz_srcptr N, uint64_t d)
360 {
361     mpz_t R;
362     mpz_init2 (R, 64);
363     uint64_t r = mpz_tdiv_r_uint64 (R, N, d);
364     mpz_clear (R);
365     return r;
366 }
367 
368 #endif
369 
370 
371 void
mpz_submul_int64(mpz_ptr a,mpz_srcptr b,int64_t c)372 mpz_submul_int64 (mpz_ptr a, mpz_srcptr b, int64_t c)
373 {
374   if (c >= 0)
375     mpz_submul_uint64 (a, b, (uint64_t) c);
376   else
377     mpz_addmul_uint64 (a, b, -(uint64_t) c);
378 }
379 
380 /* a <- a + b * c */
381 void
mpz_addmul_int64(mpz_ptr a,mpz_srcptr b,int64_t c)382 mpz_addmul_int64 (mpz_ptr a, mpz_srcptr b, int64_t c)
383 {
384   if (c >= 0)
385     mpz_addmul_uint64 (a, b, (uint64_t) c);
386   else
387     mpz_submul_uint64 (a, b, -(uint64_t) c);
388 }
389 
390 /* returns the smallest prime p, q < p <= ULONG_MAX, or 0 if no such prime
391    exists. guaranteed correct for q < 300M */
392 unsigned long
ulong_nextprime(unsigned long q)393 ulong_nextprime (unsigned long q)
394 {
395   mpz_t p;
396   unsigned long s[] = {16661633, 18790021, 54470491, 73705633, 187546133,
397                        300164287, (unsigned long) (-1L)};
398   int i;
399 
400   mpz_init (p);
401   mpz_set_ui (p, q);
402   do
403     {
404       mpz_nextprime (p, p);
405       if (mpz_fits_ulong_p (p))
406         q = mpz_get_ui (p);
407       else {
408         q = 0;
409         break;
410       }
411       for (i = 0; q > s[i]; i++);
412     }
413   while (q == s[i]);
414   mpz_clear (p);
415   return q;
416 }
417 
418 #define REPS 3 /* number of Miller-Rabin tests in isprime */
419 
420 /* For GMP 6.1.2:
421    with REPS=1, the smallest composite reported prime is 1537381
422                 (then 1803601, 1943521, 2237017, 3604201, 5095177, ...);
423    with REPS=2, it is 1943521 (then 16661633, 18790021, 54470491, ...);
424    with REPS=3, it is 465658903 (then 2242724851, 5969607379, 6635692801, ...);
425    with REPS=4, it is 239626837621 (then 277376554153, 537108528133,
426                       898547205403, and no other <= 10^12).
427    See also https://en.wikipedia.org/wiki/Miller–Rabin_primality_test
428    and http://www.trnicely.net/misc/mpzspsp.html.
429 */
430 int
ulong_isprime(unsigned long p)431 ulong_isprime (unsigned long p)
432 {
433   mpz_t P;
434   int res;
435 
436   mpz_init_set_ui (P, p);
437   res = mpz_probab_prime_p (P, REPS);
438   mpz_clear (P);
439   return res;
440 }
441 
442 /* returns the smallest composite >= q with factors >= pmin */
443 unsigned long
ulong_nextcomposite(unsigned long q,unsigned long pmin)444 ulong_nextcomposite (unsigned long q, unsigned long pmin)
445 {
446   ASSERT_ALWAYS(q >= 2);
447   for (;;q++)
448     {
449       if (ulong_isprime (q))
450         continue;
451       unsigned long p;
452       for (p = 2; p < pmin && q % p; p += 1UL + (p > 2));
453       if (p >= pmin)
454         break;
455     }
456   return q;
457 }
458 
459 /* Put in r the smallest legitimate value that it at least s + diff (note
460    that if s+diff is already legitimate, then r = s+diff will result.
461 
462    Here, legitimate means prime or squarefree composite, with the constraint
463    that all the prime factors must be in [pmin, pmax[ .
464 
465    The prime factors of r are put in factor_r, and the number of them is
466    returned. The caller must have allocated factor_r with enough space.
467    */
468 int
next_mpz_with_factor_constraints(mpz_ptr r,unsigned long factor_r[],mpz_srcptr s,unsigned long diff,unsigned long pmin,unsigned long pmax)469 next_mpz_with_factor_constraints(mpz_ptr r,
470         unsigned long factor_r[],
471         mpz_srcptr s,
472         unsigned long diff,
473         unsigned long pmin,
474         unsigned long pmax)
475 {
476     ASSERT_ALWAYS(pmin > 2);
477     mpz_add_ui(r, s, diff);
478     if (mpz_cmp_ui(r, pmin) < 0) {
479         mpz_set_ui(r, pmin);
480     }
481     if (mpz_even_p(r)) {
482         mpz_add_ui(r, r, 1);
483     }
484     while (1) {
485         /* This function is used for the composite special-q code, and it
486          * is really important that no composite special-q is considered
487          * prime.*/
488         if (mpz_probab_prime_p(r, 10)) {
489             if (mpz_cmp_ui(r, pmax) < 0) {
490                 factor_r[0] = mpz_get_ui(r);
491                 return 1;
492             }
493         } else { // r is composite. Check its factorization.
494             // Work with unsigned long
495             unsigned long rr = mpz_get_ui(r);
496             int nf = 0;
497             prime_info pi;
498             prime_info_init(pi);
499             unsigned long p = getprime_mt(pi); // p=3
500             bool ok = true;
501             while (p < pmin && ok) {
502                 if ((rr % p) == 0) {
503                     ok = false;
504                 }
505                 p = getprime_mt(pi);
506             }
507             if (!ok) {
508                 // r is divisible by a prime < pmin.
509                 // try next candidate.
510                 prime_info_clear(pi);
511                 mpz_add_ui(r, r, 2);
512                 continue;
513             }
514             // Compute the factorization
515             while (rr > 1 && p < pmax) {
516                 if ((rr % p) == 0) {
517                     int c = 0;
518                     do {
519                         rr = rr / p;
520                         c ++;
521                     } while ((rr % p) == 0);
522                     // so p divides exactly c times r.
523                     if (c > 1) {
524                         // Force p=pmax to break the loop.
525                         p = pmax;
526                         continue;
527                     }
528                     factor_r[nf++] = p;
529                     // check primality of cofactor.
530                     bool cofac_prime;
531                     {
532                         mpz_t xxx;
533                         mpz_init_set_ui(xxx, rr);
534                         cofac_prime = mpz_probab_prime_p(xxx, 10);
535                         mpz_clear(xxx);
536                     }
537                     if (cofac_prime) {
538                         if (rr < pmax) {
539                             // We have a winner.
540                             factor_r[nf++] = rr;
541                             prime_info_clear(pi);
542                             return nf;
543                         } else {
544                             break;
545                         }
546                     }
547                 }
548                 p = getprime_mt(pi);
549             }
550             prime_info_clear(pi);
551             // We have still a composite in rr, it must have a prime > pmax.
552             // This is a fail. Continue with next candidate.
553         }
554         mpz_add_ui(r, r, 2); // only odd values are considered.
555     }
556     ASSERT_ALWAYS(0); // Should never get there.
557 }
558 
559 /* return the number of bits of p, counting from the least significant end */
nbits(uintmax_t p)560 int nbits (uintmax_t p)
561 {
562   int k;
563 
564   for (k = 0; p != 0; p >>= 1, k ++);
565   return k;
566 }
567 
568 /* q <- n/d rounded to nearest, assuming d <> 0
569    r <- n - q*d
570    Output: -d/2 <= r < d/2
571 */
572 void
mpz_ndiv_qr(mpz_ptr q,mpz_ptr r,mpz_srcptr n,mpz_srcptr d)573 mpz_ndiv_qr (mpz_ptr q, mpz_ptr r, mpz_srcptr n, mpz_srcptr d)
574 {
575   int s;
576 
577   ASSERT (mpz_cmp_ui (d, 0) != 0);
578   mpz_fdiv_qr (q, r, n, d); /* round towards -inf, r has same sign as d */
579   mpz_mul_2exp (r, r, 1);
580   s = mpz_cmpabs (r, d);
581   mpz_div_2exp (r, r, 1);
582   if (s > 0) /* |r| > |d|/2 */
583     {
584       mpz_add_ui (q, q, 1);
585       mpz_sub (r, r, d);
586     }
587 }
588 
589 void
mpz_ndiv_qr_ui(mpz_ptr q,mpz_ptr r,mpz_srcptr n,unsigned long int d)590 mpz_ndiv_qr_ui (mpz_ptr q, mpz_ptr r, mpz_srcptr n, unsigned long int d)
591 {
592   int s;
593 
594   ASSERT (d != 0);
595   mpz_fdiv_qr_ui (q, r, n, d); /* round towards -inf, r has same sign as d */
596   mpz_mul_2exp (r, r, 1);
597   s = mpz_cmpabs_ui (r, d);
598   mpz_div_2exp (r, r, 1);
599   if (s > 0) /* |r| > |d|/2 */
600     {
601       mpz_add_ui (q, q, 1);
602       mpz_sub_ui (r, r, d);
603     }
604 }
605 
606 /* q <- n/d rounded to nearest, assuming d <> 0
607    Output satisfies |n-q*d| <= |d|/2
608 */
609 void
mpz_ndiv_q(mpz_ptr q,mpz_srcptr n,mpz_srcptr d)610 mpz_ndiv_q (mpz_ptr q, mpz_srcptr n, mpz_srcptr d)
611 {
612   mpz_t r;
613 
614   mpz_init (r);
615   mpz_ndiv_qr (q, r, n, d);
616   mpz_clear (r);
617 }
618 
619 void
mpz_ndiv_q_ui(mpz_ptr q,mpz_srcptr n,unsigned long int d)620 mpz_ndiv_q_ui (mpz_ptr q, mpz_srcptr n, unsigned long int d)
621 {
622   mpz_t r;
623 
624   mpz_init (r);
625   mpz_ndiv_qr_ui (q, r, n, d);
626   mpz_clear (r);
627 }
628 
629 /* a <- b cmod c with -c/2 <= a < c/2 */
630 void
mpz_ndiv_r(mpz_ptr a,mpz_srcptr b,mpz_srcptr c)631 mpz_ndiv_r (mpz_ptr a, mpz_srcptr b, mpz_srcptr c)
632 {
633   mpz_mod (a, b, c); /* now 0 <= a < c */
634 
635   mp_size_t n = (mp_size_t) mpz_size (c);
636   mp_limb_t aj, cj;
637   int sub = 0, sh = GMP_NUMB_BITS - 1;
638 
639   if (n == 0) {
640       mpz_set_ui (a, 0);
641       return;
642   }
643 
644   if (mpz_getlimbn (a, n-1) >= (mp_limb_t) 1 << sh)
645     sub = 1;
646   else
647     {
648       while (n-- > 0)
649 	{
650 	  cj = mpz_getlimbn (c, n);
651 	  aj = mpz_getlimbn (a, n) << 1;
652 	  if (n > 0)
653 	    aj |= mpz_getlimbn (a, n-1) >> sh;
654 	  if (aj > cj)
655 	    {
656 	      sub = 1;
657 	      break;
658 	    }
659 	  else if (aj < cj)
660 	    break;
661 	}
662     }
663   if (sub)
664     mpz_sub (a, a, c);
665 }
666 
mpz_rdiv_q(mpz_ptr q,mpz_srcptr a,mpz_srcptr b)667 int mpz_rdiv_q(mpz_ptr q, mpz_srcptr a, mpz_srcptr b)
668 {
669     /* Return the relative integer q which is closest to a/b. We
670      * guarantee -1/2<=a/b-q<1/2.
671      * It's a pity that this is not supported directly by gmp... */
672     mpz_t r;
673     mpz_init(r);
674 
675     mpz_fdiv_qr(q,r,a,b);
676     /* b>0: We want -b/2 <= a-bq < b/2 */
677     /* b<0: We want  b/2 < a-bq <= -b/2 */
678     mpz_mul_2exp(r,r,1);
679     if (mpz_cmp(r,b) * mpz_sgn(b) >= 0) {
680         mpz_add_ui(q, q, 1);
681     }
682     mpz_clear(r);
683 
684     return 1;
685 }
686 
687 /* Return non-zero if a and b are coprime, else return 0 if gcd(a, b) != 1 */
688 int
mpz_coprime_p(mpz_srcptr a,mpz_srcptr b)689 mpz_coprime_p (mpz_srcptr a, mpz_srcptr b)
690 {
691   mpz_t g;
692   mpz_init(g);
693   mpz_gcd (g, a, b);
694   int ret = mpz_cmp_ui (g, 1);
695   mpz_clear(g);
696   return (ret == 0) ? 1 : 0;
697 }
698 
699 long double
mpz_get_ld(mpz_srcptr z)700 mpz_get_ld (mpz_srcptr z)
701 {
702   long double ld;
703   double d;
704   mpz_t t;
705 
706   d = mpz_get_d (z);
707   mpz_init (t);
708   mpz_set_d (t, d);
709   mpz_sub (t, z, t);
710   ld = (long double) d + (long double) mpz_get_d (t);
711   mpz_clear (t);
712   return ld;
713 }
714 
715 /* returns the p-valuation of a, where p is expected to be prime. INT_MAX
716  * is returned if a==0 */
mpz_p_valuation(mpz_srcptr a,mpz_srcptr p)717 int mpz_p_valuation(mpz_srcptr a, mpz_srcptr p)
718 {
719     mpz_t c;
720     mpz_init(c);
721     int v = 0;
722     if (mpz_size(a) == 0) return INT_MAX;
723     mpz_set(c, a);
724     for( ; mpz_divisible_p(c, p) ; v++)
725         mpz_fdiv_q(c, c, p);
726     mpz_clear(c);
727     return v;
728 }
729 
730 /* returns the p-valuation of a, where p is expected to be prime. INT_MAX
731  * is returned if a==0 */
mpz_p_valuation_ui(mpz_srcptr a,unsigned long p)732 int mpz_p_valuation_ui(mpz_srcptr a, unsigned long p)
733 {
734     mpz_t c;
735     mpz_init(c);
736     int v = 0;
737     if (mpz_size(a) == 0) return INT_MAX;
738     mpz_set(c, a);
739     for( ; mpz_divisible_ui_p(c, p) ; v++)
740         mpz_fdiv_q_ui(c, c, p);
741     mpz_clear(c);
742     return v;
743 }
744 
memfill_random(void * p,size_t s,gmp_randstate_t rstate)745 void memfill_random(void *p, size_t s, gmp_randstate_t rstate)
746 {
747     size_t w = sizeof(mp_limb_t);
748     mp_limb_t * pw = (mp_limb_t *)p;
749     for( ; s >= w ; pw++, s -= w) *pw = gmp_urandomb_ui(rstate, GMP_LIMB_BITS);
750     char * pc = (char*) pw;
751     for( ; s ; pc++, s--) *pc = gmp_urandomb_ui(rstate, CHAR_BIT);
752 }
753 
754