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