]> Git Repo - VerusCoin.git/blame - src/mini-gmp.c
test
[VerusCoin.git] / src / mini-gmp.c
CommitLineData
d019c447 1/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
2
3 Contributed to the GNU project by Niels Möller
4
5Copyright 1991-1997, 1999-2015 Free Software Foundation, Inc.
6
7This file is part of the GNU MP Library.
8
9The GNU MP Library is free software; you can redistribute it and/or modify
10it under the terms of either:
11
12 * the GNU Lesser General Public License as published by the Free
13 Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
15
16or
17
18 * the GNU General Public License as published by the Free Software
19 Foundation; either version 2 of the License, or (at your option) any
20 later version.
21
22or both in parallel, as here.
23
24The GNU MP Library is distributed in the hope that it will be useful, but
25WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27for more details.
28
29You should have received copies of the GNU General Public License and the
30GNU Lesser General Public License along with the GNU MP Library. If not,
31see https://www.gnu.org/licenses/. */
32
33/* NOTE: All functions in this file which are not declared in
34 mini-gmp.h are internal, and are not intended to be compatible
35 neither with GMP nor with future versions of mini-gmp. */
36
37/* Much of the material copied from GMP files, including: gmp-impl.h,
38 longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c,
39 mpn/generic/lshift.c, mpn/generic/mul_1.c,
40 mpn/generic/mul_basecase.c, mpn/generic/rshift.c,
41 mpn/generic/sbpi1_div_qr.c, mpn/generic/sub_n.c,
42 mpn/generic/submul_1.c. */
43
44#include <assert.h>
45#include <ctype.h>
46#include <limits.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50
51#include "mini-gmp.h"
52
53\f
54/* Macros */
55#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
56
57#define GMP_LIMB_MAX (~ (mp_limb_t) 0)
58#define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1))
59
60#define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2))
61#define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1)
62
63#define GMP_ULONG_BITS (sizeof(uint64_t) * CHAR_BIT)
64#define GMP_ULONG_HIGHBIT ((uint64_t) 1 << (GMP_ULONG_BITS - 1))
65
66#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x))
67#define GMP_NEG_CAST(T,x) (-(int64_t)((T)((x) + 1) - 1))
68
69#define GMP_MIN(a, b) ((a) < (b) ? (a) : (b))
70#define GMP_MAX(a, b) ((a) > (b) ? (a) : (b))
71
72#define gmp_assert_nocarry(x) do { \
ba8f3043 73 mp_limb_t __cy = x; if ( __cy != 0 ) {} \
d019c447 74 assert (__cy == 0); \
75 } while (0)
76
77#define gmp_clz(count, x) do { \
78 mp_limb_t __clz_x = (x); \
79 uint32_t __clz_c; \
80 for (__clz_c = 0; \
81 (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \
82 __clz_c += 8) \
83 __clz_x <<= 8; \
84 for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \
85 __clz_x <<= 1; \
86 (count) = __clz_c; \
87 } while (0)
88
89#define gmp_ctz(count, x) do { \
90 mp_limb_t __ctz_x = (x); \
91 uint32_t __ctz_c = 0; \
92 gmp_clz (__ctz_c, __ctz_x & - (int64_t)__ctz_x); \
93 (count) = GMP_LIMB_BITS - 1 - (int64_t)__ctz_c; \
94 } while (0)
95
96#define gmp_add_ssaaaa(sh, sl, ah, al, bh, bl) \
97 do { \
98 mp_limb_t __x; \
99 __x = (al) + (bl); \
100 (sh) = (ah) + (bh) + (__x < (al)); \
101 (sl) = __x; \
102 } while (0)
103
104#define gmp_sub_ddmmss(sh, sl, ah, al, bh, bl) \
105 do { \
106 mp_limb_t __x; \
107 __x = (al) - (bl); \
108 (sh) = (ah) - (bh) - ((al) < (bl)); \
109 (sl) = __x; \
110 } while (0)
111
112#define gmp_umul_ppmm(w1, w0, u, v) \
113 do { \
114 mp_limb_t __x0, __x1, __x2, __x3; \
115 uint32_t __ul, __vl, __uh, __vh; \
116 mp_limb_t __u = (u), __v = (v); \
117 \
118 __ul = __u & GMP_LLIMB_MASK; \
119 __uh = __u >> (GMP_LIMB_BITS / 2); \
120 __vl = __v & GMP_LLIMB_MASK; \
121 __vh = __v >> (GMP_LIMB_BITS / 2); \
122 \
123 __x0 = (mp_limb_t) __ul * __vl; \
124 __x1 = (mp_limb_t) __ul * __vh; \
125 __x2 = (mp_limb_t) __uh * __vl; \
126 __x3 = (mp_limb_t) __uh * __vh; \
127 \
128 __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \
129 __x1 += __x2; /* but this indeed can */ \
130 if (__x1 < __x2) /* did we get it? */ \
131 __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \
132 \
133 (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \
134 (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \
135 } while (0)
136
137#define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
138 do { \
139 mp_limb_t _qh, _ql, _r, _mask; \
140 gmp_umul_ppmm (_qh, _ql, (nh), (di)); \
141 gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \
142 _r = (nl) - _qh * (d); \
143 _mask = -(_r > _ql); /* both > and >= are OK */ \
144 _qh += _mask; \
145 _r += _mask & (d); \
146 if (_r >= (d)) \
147 { \
148 _r -= (d); \
149 _qh++; \
150 } \
151 \
152 (r) = _r; \
153 (q) = _qh; \
154 } while (0)
155
156#define gmp_udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \
157 do { \
158 mp_limb_t _q0, _t1, _t0, _mask; \
159 gmp_umul_ppmm ((q), _q0, (n2), (dinv)); \
160 gmp_add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \
161 \
162 /* Compute the two most significant limbs of n - q'd */ \
163 (r1) = (n1) - (d1) * (q); \
164 gmp_sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \
165 gmp_umul_ppmm (_t1, _t0, (d0), (q)); \
166 gmp_sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \
167 (q)++; \
168 \
169 /* Conditionally adjust q and the remainders */ \
170 _mask = -((r1) >= _q0); \
171 (q) += _mask; \
172 gmp_add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \
173 if ((r1) >= (d1)) \
174 { \
175 if ((r1) > (d1) || (r0) >= (d0)) \
176 { \
177 (q)++; \
178 gmp_sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
179 } \
180 } \
181 } while (0)
182
183/* Swap macros. */
184#define MP_LIMB_T_SWAP(x, y) \
185 do { \
186 mp_limb_t __mp_limb_t_swap__tmp = (x); \
187 (x) = (y); \
188 (y) = __mp_limb_t_swap__tmp; \
189 } while (0)
190#define MP_SIZE_T_SWAP(x, y) \
191 do { \
192 mp_size_t __mp_size_t_swap__tmp = (x); \
193 (x) = (y); \
194 (y) = __mp_size_t_swap__tmp; \
195 } while (0)
196#define MP_SIZE_sT_SWAP(x, y) \
197do { \
198uint32_t __mp_size_t_swap__tmp = (x); \
199(x) = (y); \
200(y) = __mp_size_t_swap__tmp; \
201} while (0)
202
203#define MP_BITCNT_T_SWAP(x,y) \
204 do { \
205 mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \
206 (x) = (y); \
207 (y) = __mp_bitcnt_t_swap__tmp; \
208 } while (0)
209#define MP_PTR_SWAP(x, y) \
210 do { \
211 mp_ptr __mp_ptr_swap__tmp = (x); \
212 (x) = (y); \
213 (y) = __mp_ptr_swap__tmp; \
214 } while (0)
215#define MP_SRCPTR_SWAP(x, y) \
216 do { \
217 mp_srcptr __mp_srcptr_swap__tmp = (x); \
218 (x) = (y); \
219 (y) = __mp_srcptr_swap__tmp; \
220 } while (0)
221
222#define MPN_PTR_SWAP(xp,xs, yp,ys) \
223 do { \
224 MP_PTR_SWAP (xp, yp); \
225 MP_SIZE_T_SWAP (xs, ys); \
226 } while(0)
227#define MPN_SRCPTR_SWAP(xp,xs, yp,ys) \
228 do { \
229 MP_SRCPTR_SWAP (xp, yp); \
230 MP_SIZE_T_SWAP (xs, ys); \
231 } while(0)
232
233#define MPZ_PTR_SWAP(x, y) \
234 do { \
235 mpz_ptr __mpz_ptr_swap__tmp = (x); \
236 (x) = (y); \
237 (y) = __mpz_ptr_swap__tmp; \
238 } while (0)
239#define MPZ_SRCPTR_SWAP(x, y) \
240 do { \
241 mpz_srcptr __mpz_srcptr_swap__tmp = (x); \
242 (x) = (y); \
243 (y) = __mpz_srcptr_swap__tmp; \
244 } while (0)
245
246/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */
247#define MPZ_REALLOC(z,n) ((n) > (z)->_mp_alloc \
248? mpz_realloc(z,n) \
249: (z)->_mp_d)
250
251
252struct gmp_div_inverse
253{
254 /* Normalization shift count. */
255 uint32_t shift;
256 /* Normalized divisor (d0 unused for mpn_div_qr_1) */
257 mp_limb_t d1, d0;
258 /* Inverse, for 2/1 or 3/2. */
259 mp_limb_t di;
260};
261
262/* MPZ division */
263enum mpz_div_round_mode { GMP_DIV_FLOOR, GMP_DIV_CEIL, GMP_DIV_TRUNC };
264
265
266const int mp_bits_per_limb = GMP_LIMB_BITS;
267
268struct mpn_base_info
269{
270 /* bb is the largest power of the base which fits in one limb, and
271 exp is the corresponding exponent. */
272 uint32_t exp;
273 mp_limb_t bb;
274};
275
276
277#ifdef nonessential
278/* Memory allocation and other helper functions. */
279
280static void *
281gmp_default_alloc (size_t size)
282{
283 void *p;
284
285 assert (size > 0);
286
287 p = malloc (size);
288 if (!p)
289 gmp_die("gmp_default_alloc: Virtual memory exhausted.");
290
291 return p;
292}
293
294static void *
295gmp_default_realloc (void *old, size_t old_size, size_t new_size)
296{
297 void * p;
298
299 p = realloc (old, new_size);
300
301 if (!p)
302 gmp_die("gmp_default_realloc: Virtual memory exhausted.");
303
304 return p;
305}
306
307static void
308gmp_default_free (void *p, size_t size)
309{
310 free (p);
311}
312
313static void * (*gmp_allocate_func) (size_t) = gmp_default_alloc;
314static void * (*gmp_reallocate_func) (void *, size_t, size_t) = gmp_default_realloc;
315static void (*gmp_free_func) (void *, size_t) = gmp_default_free;
316
317void
318mp_get_memory_functions (void *(**alloc_func) (size_t),
319 void *(**realloc_func) (void *, size_t, size_t),
320 void (**free_func) (void *, size_t))
321{
322 if (alloc_func)
323 *alloc_func = gmp_allocate_func;
324
325 if (realloc_func)
326 *realloc_func = gmp_reallocate_func;
327
328 if (free_func)
329 *free_func = gmp_free_func;
330}
331
332void
333mp_set_memory_functions (void *(*alloc_func) (size_t),
334 void *(*realloc_func) (void *, size_t, size_t),
335 void (*free_func) (void *, size_t))
336{
337 if (!alloc_func)
338 alloc_func = gmp_default_alloc;
339 if (!realloc_func)
340 realloc_func = gmp_default_realloc;
341 if (!free_func)
342 free_func = gmp_default_free;
343
344 gmp_allocate_func = alloc_func;
345 gmp_reallocate_func = realloc_func;
346 gmp_free_func = free_func;
347}
348
349#define gmp_xalloc(size) ((*gmp_allocate_func)((size)))
350#define gmp_free(p) ((*gmp_free_func) ((p), 0))
351
352\f
353/* MPN interface */
354
355
356
357
358
359
360int mpn_zero_p(mp_srcptr rp, mp_size_t n)
361{
362 return mpn_normalized_size (rp, n) == 0;
363}
364
365
366
367
368void
369mpn_mul_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
370{
371 mpn_mul (rp, ap, n, bp, n);
372}
373
374void
375mpn_sqr (mp_ptr rp, mp_srcptr ap, mp_size_t n)
376{
377 mpn_mul (rp, ap, n, ap, n);
378}
379
380
381
382static mp_bitcnt_t
383mpn_common_scan (mp_limb_t limb, mp_size_t i, mp_srcptr up, mp_size_t un,
384 mp_limb_t ux)
385{
386 uint32_t cnt;
387
388 assert (ux == 0 || ux == GMP_LIMB_MAX);
389 assert (0 <= i && i <= un );
390
391 while (limb == 0)
392 {
393 i++;
394 if (i == un)
395 return (ux == 0 ? ~(mp_bitcnt_t) 0 : un * GMP_LIMB_BITS);
396 limb = ux ^ up[i];
397 }
398 gmp_ctz (cnt, limb);
399 return (mp_bitcnt_t) i * GMP_LIMB_BITS + cnt;
400}
401
402mp_bitcnt_t
403mpn_scan1 (mp_srcptr ptr, mp_bitcnt_t bit)
404{
405 mp_size_t i;
406 i = bit / GMP_LIMB_BITS;
407
408 return mpn_common_scan ( ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)),
409 i, ptr, i, 0);
410}
411
412mp_bitcnt_t
413mpn_scan0 (mp_srcptr ptr, mp_bitcnt_t bit)
414{
415 mp_size_t i;
416 i = bit / GMP_LIMB_BITS;
417
418 return mpn_common_scan (~ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)),
419 i, ptr, i, GMP_LIMB_MAX);
420}
421
422
423
424
425
426
427
428#if 0
429static void
430mpn_div_qr_2 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
431 mp_limb_t d1, mp_limb_t d0)
432{
433 struct gmp_div_inverse inv;
434 assert (nn >= 2);
435
436 mpn_div_qr_2_invert (&inv, d1, d0);
437 mpn_div_qr_2_preinv (qp, rp, np, nn, &inv);
438}
439#endif
440
441\f
442/* MPN base conversion. */
443
444static mp_bitcnt_t
445mpn_limb_size_in_base_2 (mp_limb_t u)
446{
447 uint32_t shift;
448
449 assert (u > 0);
450 gmp_clz (shift, u);
451 return GMP_LIMB_BITS - shift;
452}
453
454static size_t
455mpn_get_str_bits (uint8_t *sp, uint32_t bits, mp_srcptr up, mp_size_t un)
456{
457 uint8_t mask;
458 size_t sn, j;
459 mp_size_t i;
460 int shift;
461
462 sn = ((un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1])
463 + bits - 1) / bits;
464
465 mask = (1U << bits) - 1;
466
467 for (i = 0, j = sn, shift = 0; j-- > 0;)
468 {
469 uint8_t digit = up[i] >> shift;
470
471 shift += bits;
472
473 if (shift >= GMP_LIMB_BITS && ++i < un)
474 {
475 shift -= GMP_LIMB_BITS;
476 digit |= up[i] << (bits - shift);
477 }
478 sp[j] = digit & mask;
479 }
480 return sn;
481}
482
483/* We generate digits from the least significant end, and reverse at
484 the end. */
485static size_t
486mpn_limb_get_str (uint8_t *sp, mp_limb_t w,
487 const struct gmp_div_inverse *binv)
488{
489 mp_size_t i;
490 for (i = 0; w > 0; i++)
491 {
492 mp_limb_t h, l, r;
493
494 h = w >> (GMP_LIMB_BITS - binv->shift);
495 l = w << binv->shift;
496
497 gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di);
498 assert ( (r << (GMP_LIMB_BITS - binv->shift)) == 0);
499 r >>= binv->shift;
500
501 sp[i] = r;
502 }
503 return i;
504}
505
506static size_t
507mpn_get_str_other (uint8_t *sp,
508 int base, const struct mpn_base_info *info,
509 mp_ptr up, mp_size_t un)
510{
511 struct gmp_div_inverse binv;
512 size_t sn;
513 size_t i;
514
515 mpn_div_qr_1_invert (&binv, base);
516
517 sn = 0;
518
519 if (un > 1)
520 {
521 struct gmp_div_inverse bbinv;
522 mpn_div_qr_1_invert (&bbinv, info->bb);
523
524 do
525 {
526 mp_limb_t w;
527 size_t done;
528 w = mpn_div_qr_1_preinv (up, up, un, &bbinv);
529 un -= (up[un-1] == 0);
530 done = mpn_limb_get_str (sp + sn, w, &binv);
531
532 for (sn += done; done < info->exp; done++)
533 sp[sn++] = 0;
534 }
535 while (un > 1);
536 }
537 sn += mpn_limb_get_str (sp + sn, up[0], &binv);
538
539 /* Reverse order */
540 for (i = 0; 2*i + 1 < sn; i++)
541 {
542 uint8_t t = sp[i];
543 sp[i] = sp[sn - i - 1];
544 sp[sn - i - 1] = t;
545 }
546
547 return sn;
548}
549
550size_t
551mpn_get_str (uint8_t *sp, int base, mp_ptr up, mp_size_t un)
552{
553 uint32_t bits;
554
555 assert (un > 0);
556 assert (up[un-1] > 0);
557
558 bits = mpn_base_power_of_two_p (base);
559 if (bits)
560 return mpn_get_str_bits (sp, bits, up, un);
561 else
562 {
563 struct mpn_base_info info;
564
565 mpn_get_base_info (&info, base);
566 return mpn_get_str_other (sp, base, &info, up, un);
567 }
568}
569
570mp_size_t
571mpn_set_str (mp_ptr rp, const uint8_t *sp, size_t sn, int base)
572{
573 uint32_t bits;
574
575 if (sn == 0)
576 return 0;
577
578 bits = mpn_base_power_of_two_p (base);
579 if (bits)
580 return mpn_set_str_bits (rp, sp, sn, bits);
581 else
582 {
583 struct mpn_base_info info;
584
585 mpn_get_base_info (&info, base);
586 return mpn_set_str_other (rp, sp, sn, base, &info);
587 }
588}
589
590\f
591/* MPZ interface */
592
593
594
595\f
596/* MPZ assignment and basic conversions. */
597
598void
599mpz_init_set_si (mpz_t r, int64_t x)
600{
601 mpz_init (r);
602 mpz_set_si (r, x);
603}
604
605
606
607
608int
609mpz_fits_slong_p (const mpz_t u)
610{
611 mp_size_t us = u->_mp_size;
612
613 if (us == 1)
614 return u->_mp_d[0] < GMP_LIMB_HIGHBIT;
615 else if (us == -1)
616 return u->_mp_d[0] <= GMP_LIMB_HIGHBIT;
617 else
618 return (us == 0);
619}
620
621int
622mpz_fits_ulong_p (const mpz_t u)
623{
624 mp_size_t us = u->_mp_size;
625
626 return (us == (us > 0));
627}
628
629long int
630mpz_get_si (const mpz_t u)
631{
632 mp_size_t us = u->_mp_size;
633
634 if (us > 0)
635 return (long) (u->_mp_d[0] & ~GMP_LIMB_HIGHBIT);
636 else if (us < 0)
637 return (long) (- u->_mp_d[0] | GMP_LIMB_HIGHBIT);
638 else
639 return 0;
640}
641
642
643
644size_t
645mpz_size (const mpz_t u)
646{
647 return GMP_ABS (u->_mp_size);
648}
649
650mp_limb_t
651mpz_getlimbn (const mpz_t u, mp_size_t n)
652{
653 if (n >= 0 && n < GMP_ABS (u->_mp_size))
654 return u->_mp_d[n];
655 else
656 return 0;
657}
658
659void
660mpz_realloc2 (mpz_t x, mp_bitcnt_t n)
661{
662 mpz_realloc (x, 1 + (n - (n != 0)) / GMP_LIMB_BITS);
663}
664
665mp_srcptr
666mpz_limbs_read (mpz_srcptr x)
667{
668 return x->_mp_d;;
669}
670
671mp_ptr
672mpz_limbs_modify (mpz_t x, mp_size_t n)
673{
674 assert (n > 0);
675 return MPZ_REALLOC (x, n);
676}
677
678mp_ptr
679mpz_limbs_write (mpz_t x, mp_size_t n)
680{
681 return mpz_limbs_modify (x, n);
682}
683
684void
685mpz_limbs_finish (mpz_t x, mp_size_t xs)
686{
687 mp_size_t xn;
688 xn = mpn_normalized_size (x->_mp_d, GMP_ABS (xs));
689 x->_mp_size = xs < 0 ? -xn : xn;
690}
691
692mpz_srcptr
693mpz_roinit_n (mpz_t x, mp_srcptr xp, mp_size_t xs)
694{
695 x->_mp_alloc = 0;
696 x->_mp_d = (mp_ptr) xp;
697 mpz_limbs_finish (x, xs);
698 return x;
699}
700
701\f
702/* Conversions and comparison to double. */
703void
704mpz_set_d (mpz_t r, double x)
705{
706 int sign;
707 mp_ptr rp;
708 mp_size_t rn, i;
709 double B;
710 double Bi;
711 mp_limb_t f;
712
713 /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is
714 zero or infinity. */
715 if (x != x || x == x * 0.5)
716 {
717 r->_mp_size = 0;
718 return;
719 }
720
721 sign = x < 0.0 ;
722 if (sign)
723 x = - x;
724
725 if (x < 1.0)
726 {
727 r->_mp_size = 0;
728 return;
729 }
730 B = 2.0 * (double) GMP_LIMB_HIGHBIT;
731 Bi = 1.0 / B;
732 for (rn = 1; x >= B; rn++)
733 x *= Bi;
734
735 rp = MPZ_REALLOC (r, rn);
736
737 f = (mp_limb_t) x;
738 x -= f;
739 assert (x < 1.0);
740 i = rn-1;
741 rp[i] = f;
742 while (--i >= 0)
743 {
744 x = B * x;
745 f = (mp_limb_t) x;
746 x -= f;
747 assert (x < 1.0);
748 rp[i] = f;
749 }
750
751 r->_mp_size = sign ? - rn : rn;
752}
753
754void
755mpz_init_set_d (mpz_t r, double x)
756{
757 mpz_init (r);
758 mpz_set_d (r, x);
759}
760
761double
762mpz_get_d (const mpz_t u)
763{
764 mp_size_t un;
765 double x;
766 double B = 2.0 * (double) GMP_LIMB_HIGHBIT;
767
768 un = GMP_ABS (u->_mp_size);
769
770 if (un == 0)
771 return 0.0;
772
773 x = u->_mp_d[--un];
774 while (un > 0)
775 x = B*x + u->_mp_d[--un];
776
777 if (u->_mp_size < 0)
778 x = -x;
779
780 return x;
781}
782
783int
784mpz_cmpabs_d (const mpz_t x, double d)
785{
786 mp_size_t xn;
787 double B, Bi;
788 mp_size_t i;
789
790 xn = x->_mp_size;
791 d = GMP_ABS (d);
792
793 if (xn != 0)
794 {
795 xn = GMP_ABS (xn);
796
797 B = 2.0 * (double) GMP_LIMB_HIGHBIT;
798 Bi = 1.0 / B;
799
800 /* Scale d so it can be compared with the top limb. */
801 for (i = 1; i < xn; i++)
802 d *= Bi;
803
804 if (d >= B)
805 return -1;
806
807 /* Compare floor(d) to top limb, subtract and cancel when equal. */
808 for (i = xn; i-- > 0;)
809 {
810 mp_limb_t f, xl;
811
812 f = (mp_limb_t) d;
813 xl = x->_mp_d[i];
814 if (xl > f)
815 return 1;
816 else if (xl < f)
817 return -1;
818 d = B * (d - f);
819 }
820 }
821 return - (d > 0.0);
822}
823
824int
825mpz_cmp_d (const mpz_t x, double d)
826{
827 if (x->_mp_size < 0)
828 {
829 if (d >= 0.0)
830 return -1;
831 else
832 return -mpz_cmpabs_d (x, d);
833 }
834 else
835 {
836 if (d < 0.0)
837 return 1;
838 else
839 return mpz_cmpabs_d (x, d);
840 }
841}
842
843\f
844/* MPZ comparisons and the like. */
845int
846mpz_sgn (const mpz_t u)
847{
848 mp_size_t usize = u->_mp_size;
849
850 return (usize > 0) - (usize < 0);
851}
852
853int
854mpz_cmp_si (const mpz_t u, long v)
855{
856 mp_size_t usize = u->_mp_size;
857
858 if (usize < -1)
859 return -1;
860 else if (v >= 0)
861 return mpz_cmp_ui (u, v);
862 else if (usize >= 0)
863 return 1;
864 else /* usize == -1 */
865 {
866 mp_limb_t ul = u->_mp_d[0];
867 if ((mp_limb_t)GMP_NEG_CAST (uint64_t, v) < ul)
868 return -1;
869 else
870 return (mp_limb_t)GMP_NEG_CAST (uint64_t, v) > ul;
871 }
872}
873
874int
875mpz_cmp_ui (const mpz_t u, uint64_t v)
876{
877 mp_size_t usize = u->_mp_size;
878
879 if (usize > 1)
880 return 1;
881 else if (usize < 0)
882 return -1;
883 else
884 {
885 mp_limb_t ul = (usize > 0) ? u->_mp_d[0] : 0;
886 return (ul > v) - (ul < v);
887 }
888}
889
890int
891mpz_cmpabs_ui (const mpz_t u, uint64_t v)
892{
893 mp_size_t un = GMP_ABS (u->_mp_size);
894 mp_limb_t ul;
895
896 if (un > 1)
897 return 1;
898
899 ul = (un == 1) ? u->_mp_d[0] : 0;
900
901 return (ul > v) - (ul < v);
902}
903
904int
905mpz_cmpabs (const mpz_t u, const mpz_t v)
906{
907 return mpn_cmp4 (u->_mp_d, GMP_ABS (u->_mp_size),
908 v->_mp_d, GMP_ABS (v->_mp_size));
909}
910
911void
912mpz_abs (mpz_t r, const mpz_t u)
913{
914 mpz_set (r, u);
915 r->_mp_size = GMP_ABS (r->_mp_size);
916}
917
918void
919mpz_neg (mpz_t r, const mpz_t u)
920{
921 mpz_set (r, u);
922 r->_mp_size = -r->_mp_size;
923}
924
925
926\f
927/* MPZ addition and subtraction */
928
929
930
931
932
933
934
935void
936mpz_ui_sub (mpz_t r, uint64_t a, const mpz_t b)
937{
938 if (b->_mp_size < 0)
939 r->_mp_size = mpz_abs_add_ui (r, b, a);
940 else
941 r->_mp_size = -mpz_abs_sub_ui (r, b, a);
942}
943
944
945
946
947\f
948/* MPZ multiplication */
949void
950mpz_mul_si (mpz_t r, const mpz_t u, long int v)
951{
952 if (v < 0)
953 {
954 mpz_mul_ui (r, u, GMP_NEG_CAST (uint64_t, v));
955 mpz_neg (r, r);
956 }
957 else
958 mpz_mul_ui (r, u, (uint64_t) v);
959}
960
961
962
963
964void
965mpz_addmul_ui (mpz_t r, const mpz_t u, uint64_t v)
966{
967 mpz_t t;
968 mpz_init (t);
969 mpz_mul_ui (t, u, v);
970 mpz_add (r, r, t);
971 mpz_clear (t);
972}
973
974void
975mpz_submul_ui (mpz_t r, const mpz_t u, uint64_t v)
976{
977 mpz_t t;
978 mpz_init (t);
979 mpz_mul_ui (t, u, v);
980 mpz_sub (r, r, t);
981 mpz_clear (t);
982}
983
984void
985mpz_addmul (mpz_t r, const mpz_t u, const mpz_t v)
986{
987 mpz_t t;
988 mpz_init (t);
989 mpz_mul (t, u, v);
990 mpz_add (r, r, t);
991 mpz_clear (t);
992}
993
994void
995mpz_submul (mpz_t r, const mpz_t u, const mpz_t v)
996{
997 mpz_t t;
998 mpz_init (t);
999 mpz_mul (t, u, v);
1000 mpz_sub (r, r, t);
1001 mpz_clear (t);
1002}
1003
1004\f
1005
1006
1007void
1008mpz_fdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
1009{
1010 mpz_div_qr (q, r, n, d, GMP_DIV_FLOOR);
1011}
1012
1013
1014void
1015mpz_cdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
1016{
1017 mpz_div_qr (q, NULL, n, d, GMP_DIV_CEIL);
1018}
1019
1020void
1021mpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
1022{
1023 mpz_div_qr (q, NULL, n, d, GMP_DIV_FLOOR);
1024}
1025
1026void
1027mpz_tdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
1028{
1029 mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC);
1030}
1031
1032void
1033mpz_cdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
1034{
1035 mpz_div_qr (NULL, r, n, d, GMP_DIV_CEIL);
1036}
1037
1038void
1039mpz_fdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
1040{
1041 mpz_div_qr (NULL, r, n, d, GMP_DIV_FLOOR);
1042}
1043
1044void
1045mpz_tdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
1046{
1047 mpz_div_qr (NULL, r, n, d, GMP_DIV_TRUNC);
1048}
1049
1050void
1051mpz_mod (mpz_t r, const mpz_t n, const mpz_t d)
1052{
1053 mpz_div_qr (NULL, r, n, d, d->_mp_size >= 0 ? GMP_DIV_FLOOR : GMP_DIV_CEIL);
1054}
1055
1056static void
1057mpz_div_q_2exp (mpz_t q, const mpz_t u, mp_bitcnt_t bit_index,
1058 enum mpz_div_round_mode mode)
1059{
1060 mp_size_t un, qn;
1061 mp_size_t limb_cnt;
1062 mp_ptr qp;
1063 int adjust;
1064
1065 un = u->_mp_size;
1066 if (un == 0)
1067 {
1068 q->_mp_size = 0;
1069 return;
1070 }
1071 limb_cnt = bit_index / GMP_LIMB_BITS;
1072 qn = GMP_ABS (un) - limb_cnt;
1073 bit_index %= GMP_LIMB_BITS;
1074
1075 if (mode == ((un > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* un != 0 here. */
1076 /* Note: Below, the final indexing at limb_cnt is valid because at
1077 that point we have qn > 0. */
1078 adjust = (qn <= 0
1079 || !mpn_zero_p (u->_mp_d, limb_cnt)
1080 || (u->_mp_d[limb_cnt]
1081 & (((mp_limb_t) 1 << bit_index) - 1)));
1082 else
1083 adjust = 0;
1084
1085 if (qn <= 0)
1086 qn = 0;
1087
1088 else
1089 {
1090 qp = MPZ_REALLOC (q, qn);
1091
1092 if (bit_index != 0)
1093 {
1094 mpn_rshift (qp, u->_mp_d + limb_cnt, qn, bit_index);
1095 qn -= qp[qn - 1] == 0;
1096 }
1097 else
1098 {
1099 mpn_copyi (qp, u->_mp_d + limb_cnt, qn);
1100 }
1101 }
1102
1103 q->_mp_size = qn;
1104
1105 if (adjust)
1106 mpz_add_ui (q, q, 1);
1107 if (un < 0)
1108 mpz_neg (q, q);
1109}
1110
1111static void
1112mpz_div_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bit_index,
1113 enum mpz_div_round_mode mode)
1114{
1115 mp_size_t us, un, rn;
1116 mp_ptr rp;
1117 mp_limb_t mask;
1118
1119 us = u->_mp_size;
1120 if (us == 0 || bit_index == 0)
1121 {
1122 r->_mp_size = 0;
1123 return;
1124 }
1125 rn = (bit_index + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
1126 assert (rn > 0);
1127
1128 rp = MPZ_REALLOC (r, rn);
1129 un = GMP_ABS (us);
1130
1131 mask = GMP_LIMB_MAX >> (rn * GMP_LIMB_BITS - bit_index);
1132
1133 if (rn > un)
1134 {
1135 /* Quotient (with truncation) is zero, and remainder is
1136 non-zero */
1137 if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */
1138 {
1139 /* Have to negate and sign extend. */
1140 mp_size_t i;
1141 mp_limb_t cy;
1142
1143 for (cy = 1, i = 0; i < un; i++)
1144 {
1145 mp_limb_t s = ~u->_mp_d[i] + cy;
1146 cy = s < cy;
1147 rp[i] = s;
1148 }
1149 assert (cy == 0);
1150 for (; i < rn - 1; i++)
1151 rp[i] = GMP_LIMB_MAX;
1152
1153 rp[rn-1] = mask;
1154 us = -us;
1155 }
1156 else
1157 {
1158 /* Just copy */
1159 if (r != u)
1160 mpn_copyi (rp, u->_mp_d, un);
1161
1162 rn = un;
1163 }
1164 }
1165 else
1166 {
1167 if (r != u)
1168 mpn_copyi (rp, u->_mp_d, rn - 1);
1169
1170 rp[rn-1] = u->_mp_d[rn-1] & mask;
1171
1172 if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */
1173 {
1174 /* If r != 0, compute 2^{bit_count} - r. */
1175 mp_size_t i;
1176
1177 for (i = 0; i < rn && rp[i] == 0; i++)
1178 ;
1179 if (i < rn)
1180 {
1181 /* r > 0, need to flip sign. */
1182 rp[i] = ~rp[i] + 1;
1183 while (++i < rn)
1184 rp[i] = ~rp[i];
1185
1186 rp[rn-1] &= mask;
1187
1188 /* us is not used for anything else, so we can modify it
1189 here to indicate flipped sign. */
1190 us = -us;
1191 }
1192 }
1193 }
1194 rn = mpn_normalized_size (rp, rn);
1195 r->_mp_size = us < 0 ? -rn : rn;
1196}
1197
1198void
1199mpz_cdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
1200{
1201 mpz_div_q_2exp (r, u, cnt, GMP_DIV_CEIL);
1202}
1203
1204void
1205mpz_fdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
1206{
1207 mpz_div_q_2exp (r, u, cnt, GMP_DIV_FLOOR);
1208}
1209
1210void
1211mpz_tdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
1212{
1213 mpz_div_q_2exp (r, u, cnt, GMP_DIV_TRUNC);
1214}
1215
1216void
1217mpz_cdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
1218{
1219 mpz_div_r_2exp (r, u, cnt, GMP_DIV_CEIL);
1220}
1221
1222void
1223mpz_fdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
1224{
1225 mpz_div_r_2exp (r, u, cnt, GMP_DIV_FLOOR);
1226}
1227
1228void
1229mpz_tdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
1230{
1231 mpz_div_r_2exp (r, u, cnt, GMP_DIV_TRUNC);
1232}
1233
1234void
1235mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d)
1236{
1237 gmp_assert_nocarry (mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC));
1238}
1239
1240int
1241mpz_divisible_p (const mpz_t n, const mpz_t d)
1242{
1243 return mpz_div_qr (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0;
1244}
1245
1246int
1247mpz_congruent_p (const mpz_t a, const mpz_t b, const mpz_t m)
1248{
1249 mpz_t t;
1250 int res;
1251
1252 /* a == b (mod 0) iff a == b */
1253 if (mpz_sgn (m) == 0)
1254 return (mpz_cmp (a, b) == 0);
1255
1256 mpz_init (t);
1257 mpz_sub (t, a, b);
1258 res = mpz_divisible_p (t, m);
1259 mpz_clear (t);
1260
1261 return res;
1262}
1263
1264
1265uint64_t
1266mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d)
1267{
1268 return mpz_div_qr_ui (q, r, n, d, GMP_DIV_CEIL);
1269}
1270
1271uint64_t
1272mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d)
1273{
1274 return mpz_div_qr_ui (q, r, n, d, GMP_DIV_FLOOR);
1275}
1276
1277uint64_t
1278mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d)
1279{
1280 return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC);
1281}
1282
1283uint64_t
1284mpz_cdiv_q_ui (mpz_t q, const mpz_t n, uint64_t d)
1285{
1286 return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_CEIL);
1287}
1288
1289uint64_t
1290mpz_fdiv_q_ui (mpz_t q, const mpz_t n, uint64_t d)
1291{
1292 return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_FLOOR);
1293}
1294
1295uint64_t
1296mpz_tdiv_q_ui (mpz_t q, const mpz_t n, uint64_t d)
1297{
1298 return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC);
1299}
1300
1301uint64_t
1302mpz_cdiv_r_ui (mpz_t r, const mpz_t n, uint64_t d)
1303{
1304 return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_CEIL);
1305}
1306uint64_t
1307mpz_fdiv_r_ui (mpz_t r, const mpz_t n, uint64_t d)
1308{
1309 return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR);
1310}
1311uint64_t
1312mpz_tdiv_r_ui (mpz_t r, const mpz_t n, uint64_t d)
1313{
1314 return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_TRUNC);
1315}
1316
1317uint64_t
1318mpz_cdiv_ui (const mpz_t n, uint64_t d)
1319{
1320 return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_CEIL);
1321}
1322
1323uint64_t
1324mpz_fdiv_ui (const mpz_t n, uint64_t d)
1325{
1326 return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_FLOOR);
1327}
1328
1329uint64_t
1330mpz_tdiv_ui (const mpz_t n, uint64_t d)
1331{
1332 return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC);
1333}
1334
1335uint64_t
1336mpz_mod_ui (mpz_t r, const mpz_t n, uint64_t d)
1337{
1338 return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR);
1339}
1340
1341void
1342mpz_divexact_ui (mpz_t q, const mpz_t n, uint64_t d)
1343{
1344 gmp_assert_nocarry (mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC));
1345}
1346
1347int
1348mpz_divisible_ui_p (const mpz_t n, uint64_t d)
1349{
1350 return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0;
1351}
1352
1353\f
1354/* GCD */
1355static mp_limb_t
1356mpn_gcd_11 (mp_limb_t u, mp_limb_t v)
1357{
1358 uint32_t shift;
1359
1360 assert ( (u | v) > 0);
1361
1362 if (u == 0)
1363 return v;
1364 else if (v == 0)
1365 return u;
1366
1367 gmp_ctz (shift, u | v);
1368
1369 u >>= shift;
1370 v >>= shift;
1371
1372 if ( (u & 1) == 0)
1373 MP_LIMB_T_SWAP (u, v);
1374
1375 while ( (v & 1) == 0)
1376 v >>= 1;
1377
1378 while (u != v)
1379 {
1380 if (u > v)
1381 {
1382 u -= v;
1383 do
1384 u >>= 1;
1385 while ( (u & 1) == 0);
1386 }
1387 else
1388 {
1389 v -= u;
1390 do
1391 v >>= 1;
1392 while ( (v & 1) == 0);
1393 }
1394 }
1395 return u << shift;
1396}
1397
1398uint64_t
1399mpz_gcd_ui (mpz_t g, const mpz_t u, uint64_t v)
1400{
1401 mp_size_t un;
1402
1403 if (v == 0)
1404 {
1405 if (g)
1406 mpz_abs (g, u);
1407 }
1408 else
1409 {
1410 un = GMP_ABS (u->_mp_size);
1411 if (un != 0)
1412 v = mpn_gcd_11 (mpn_div_qr_1 (NULL, u->_mp_d, un, v), v);
1413
1414 if (g)
1415 mpz_set_ui (g, v);
1416 }
1417
1418 return v;
1419}
1420
1421static mp_bitcnt_t
1422mpz_make_odd (mpz_t r)
1423{
1424 mp_bitcnt_t shift;
1425
1426 assert (r->_mp_size > 0);
1427 /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */
1428 shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0);
1429 mpz_tdiv_q_2exp (r, r, shift);
1430
1431 return shift;
1432}
1433
1434void
1435mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v)
1436{
1437 mpz_t tu, tv;
1438 mp_bitcnt_t uz, vz, gz;
1439
1440 if (u->_mp_size == 0)
1441 {
1442 mpz_abs (g, v);
1443 return;
1444 }
1445 if (v->_mp_size == 0)
1446 {
1447 mpz_abs (g, u);
1448 return;
1449 }
1450
1451 mpz_init (tu);
1452 mpz_init (tv);
1453
1454 mpz_abs (tu, u);
1455 uz = mpz_make_odd (tu);
1456 mpz_abs (tv, v);
1457 vz = mpz_make_odd (tv);
1458 gz = GMP_MIN (uz, vz);
1459
1460 if (tu->_mp_size < tv->_mp_size)
1461 mpz_swap (tu, tv);
1462
1463 mpz_tdiv_r (tu, tu, tv);
1464 if (tu->_mp_size == 0)
1465 {
1466 mpz_swap (g, tv);
1467 }
1468 else
1469 for (;;)
1470 {
1471 int c;
1472
1473 mpz_make_odd (tu);
1474 c = mpz_cmp (tu, tv);
1475 if (c == 0)
1476 {
1477 mpz_swap (g, tu);
1478 break;
1479 }
1480 if (c < 0)
1481 mpz_swap (tu, tv);
1482
1483 if (tv->_mp_size == 1)
1484 {
1485 mp_limb_t vl = tv->_mp_d[0];
1486 mp_limb_t ul = mpz_tdiv_ui (tu, vl);
1487 mpz_set_ui (g, mpn_gcd_11 (ul, vl));
1488 break;
1489 }
1490 mpz_sub (tu, tu, tv);
1491 }
1492 mpz_clear (tu);
1493 mpz_clear (tv);
1494 mpz_mul_2exp (g, g, gz);
1495}
1496
1497void
1498mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
1499{
1500 mpz_t tu, tv, s0, s1, t0, t1;
1501 mp_bitcnt_t uz, vz, gz;
1502 mp_bitcnt_t power;
1503
1504 if (u->_mp_size == 0)
1505 {
1506 /* g = 0 u + sgn(v) v */
1507 int64_t sign = mpz_sgn (v);
1508 mpz_abs (g, v);
1509 if (s)
1510 mpz_set_ui (s, 0);
1511 if (t)
1512 mpz_set_si (t, sign);
1513 return;
1514 }
1515
1516 if (v->_mp_size == 0)
1517 {
1518 /* g = sgn(u) u + 0 v */
1519 int64_t sign = mpz_sgn (u);
1520 mpz_abs (g, u);
1521 if (s)
1522 mpz_set_si (s, sign);
1523 if (t)
1524 mpz_set_ui (t, 0);
1525 return;
1526 }
1527
1528 mpz_init (tu);
1529 mpz_init (tv);
1530 mpz_init (s0);
1531 mpz_init (s1);
1532 mpz_init (t0);
1533 mpz_init (t1);
1534
1535 mpz_abs (tu, u);
1536 uz = mpz_make_odd (tu);
1537 mpz_abs (tv, v);
1538 vz = mpz_make_odd (tv);
1539 gz = GMP_MIN (uz, vz);
1540
1541 uz -= gz;
1542 vz -= gz;
1543
1544 /* Cofactors corresponding to odd gcd. gz handled later. */
1545 if (tu->_mp_size < tv->_mp_size)
1546 {
1547 mpz_swap (tu, tv);
1548 MPZ_SRCPTR_SWAP (u, v);
1549 MPZ_PTR_SWAP (s, t);
1550 MP_BITCNT_T_SWAP (uz, vz);
1551 }
1552
1553 /* Maintain
1554 *
1555 * u = t0 tu + t1 tv
1556 * v = s0 tu + s1 tv
1557 *
1558 * where u and v denote the inputs with common factors of two
1559 * eliminated, and det (s0, t0; s1, t1) = 2^p. Then
1560 *
1561 * 2^p tu = s1 u - t1 v
1562 * 2^p tv = -s0 u + t0 v
1563 */
1564
1565 /* After initial division, tu = q tv + tu', we have
1566 *
1567 * u = 2^uz (tu' + q tv)
1568 * v = 2^vz tv
1569 *
1570 * or
1571 *
1572 * t0 = 2^uz, t1 = 2^uz q
1573 * s0 = 0, s1 = 2^vz
1574 */
1575
1576 mpz_setbit (t0, uz);
1577 mpz_tdiv_qr (t1, tu, tu, tv);
1578 mpz_mul_2exp (t1, t1, uz);
1579
1580 mpz_setbit (s1, vz);
1581 power = uz + vz;
1582
1583 if (tu->_mp_size > 0)
1584 {
1585 mp_bitcnt_t shift;
1586 shift = mpz_make_odd (tu);
1587 mpz_mul_2exp (t0, t0, shift);
1588 mpz_mul_2exp (s0, s0, shift);
1589 power += shift;
1590
1591 for (;;)
1592 {
1593 int c;
1594 c = mpz_cmp (tu, tv);
1595 if (c == 0)
1596 break;
1597
1598 if (c < 0)
1599 {
1600 /* tv = tv' + tu
1601 *
1602 * u = t0 tu + t1 (tv' + tu) = (t0 + t1) tu + t1 tv'
1603 * v = s0 tu + s1 (tv' + tu) = (s0 + s1) tu + s1 tv' */
1604
1605 mpz_sub (tv, tv, tu);
1606 mpz_add (t0, t0, t1);
1607 mpz_add (s0, s0, s1);
1608
1609 shift = mpz_make_odd (tv);
1610 mpz_mul_2exp (t1, t1, shift);
1611 mpz_mul_2exp (s1, s1, shift);
1612 }
1613 else
1614 {
1615 mpz_sub (tu, tu, tv);
1616 mpz_add (t1, t0, t1);
1617 mpz_add (s1, s0, s1);
1618
1619 shift = mpz_make_odd (tu);
1620 mpz_mul_2exp (t0, t0, shift);
1621 mpz_mul_2exp (s0, s0, shift);
1622 }
1623 power += shift;
1624 }
1625 }
1626
1627 /* Now tv = odd part of gcd, and -s0 and t0 are corresponding
1628 cofactors. */
1629
1630 mpz_mul_2exp (tv, tv, gz);
1631 mpz_neg (s0, s0);
1632
1633 /* 2^p g = s0 u + t0 v. Eliminate one factor of two at a time. To
1634 adjust cofactors, we need u / g and v / g */
1635
1636 mpz_divexact (s1, v, tv);
1637 mpz_abs (s1, s1);
1638 mpz_divexact (t1, u, tv);
1639 mpz_abs (t1, t1);
1640
1641 while (power-- > 0)
1642 {
1643 /* s0 u + t0 v = (s0 - v/g) u - (t0 + u/g) v */
1644 if (mpz_odd_p (s0) || mpz_odd_p (t0))
1645 {
1646 mpz_sub (s0, s0, s1);
1647 mpz_add (t0, t0, t1);
1648 }
1649 mpz_divexact_ui (s0, s0, 2);
1650 mpz_divexact_ui (t0, t0, 2);
1651 }
1652
1653 /* Arrange so that |s| < |u| / 2g */
1654 mpz_add (s1, s0, s1);
1655 if (mpz_cmpabs (s0, s1) > 0)
1656 {
1657 mpz_swap (s0, s1);
1658 mpz_sub (t0, t0, t1);
1659 }
1660 if (u->_mp_size < 0)
1661 mpz_neg (s0, s0);
1662 if (v->_mp_size < 0)
1663 mpz_neg (t0, t0);
1664
1665 mpz_swap (g, tv);
1666 if (s)
1667 mpz_swap (s, s0);
1668 if (t)
1669 mpz_swap (t, t0);
1670
1671 mpz_clear (tu);
1672 mpz_clear (tv);
1673 mpz_clear (s0);
1674 mpz_clear (s1);
1675 mpz_clear (t0);
1676 mpz_clear (t1);
1677}
1678
1679void
1680mpz_lcm (mpz_t r, const mpz_t u, const mpz_t v)
1681{
1682 mpz_t g;
1683
1684 if (u->_mp_size == 0 || v->_mp_size == 0)
1685 {
1686 r->_mp_size = 0;
1687 return;
1688 }
1689
1690 mpz_init (g);
1691
1692 mpz_gcd (g, u, v);
1693 mpz_divexact (g, u, g);
1694 mpz_mul (r, g, v);
1695
1696 mpz_clear (g);
1697 mpz_abs (r, r);
1698}
1699
1700void
1701mpz_lcm_ui (mpz_t r, const mpz_t u, uint64_t v)
1702{
1703 if (v == 0 || u->_mp_size == 0)
1704 {
1705 r->_mp_size = 0;
1706 return;
1707 }
1708
1709 v /= mpz_gcd_ui (NULL, u, v);
1710 mpz_mul_ui (r, u, v);
1711
1712 mpz_abs (r, r);
1713}
1714
1715int
1716mpz_invert (mpz_t r, const mpz_t u, const mpz_t m)
1717{
1718 mpz_t g, tr;
1719 int invertible;
1720
1721 if (u->_mp_size == 0 || mpz_cmpabs_ui (m, 1) <= 0)
1722 return 0;
1723
1724 mpz_init (g);
1725 mpz_init (tr);
1726
1727 mpz_gcdext (g, tr, NULL, u, m);
1728 invertible = (mpz_cmp_ui (g, 1) == 0);
1729
1730 if (invertible)
1731 {
1732 if (tr->_mp_size < 0)
1733 {
1734 if (m->_mp_size >= 0)
1735 mpz_add (tr, tr, m);
1736 else
1737 mpz_sub (tr, tr, m);
1738 }
1739 mpz_swap (r, tr);
1740 }
1741
1742 mpz_clear (g);
1743 mpz_clear (tr);
1744 return invertible;
1745}
1746
1747\f
1748/* Higher level operations (sqrt, pow and root) */
1749
1750void
1751mpz_pow_ui (mpz_t r, const mpz_t b, uint64_t e)
1752{
1753 uint64_t bit;
1754 mpz_t tr;
1755 mpz_init_set_ui (tr, 1);
1756
1757 bit = GMP_ULONG_HIGHBIT;
1758 do
1759 {
1760 mpz_mul (tr, tr, tr);
1761 if (e & bit)
1762 mpz_mul (tr, tr, b);
1763 bit >>= 1;
1764 }
1765 while (bit > 0);
1766
1767 mpz_swap (r, tr);
1768 mpz_clear (tr);
1769}
1770
1771void
1772mpz_ui_pow_ui (mpz_t r, uint64_t blimb, uint64_t e)
1773{
1774 mpz_t b;
1775 mpz_pow_ui (r, mpz_roinit_n (b, &blimb, 1), e);
1776}
1777
1778void
1779mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
1780{
1781 mpz_t tr;
1782 mpz_t base;
1783 mp_size_t en, mn;
1784 mp_srcptr mp;
1785 struct gmp_div_inverse minv;
1786 uint32_t shift;
1787 mp_ptr tp = NULL;
1788
1789 en = GMP_ABS (e->_mp_size);
1790 mn = GMP_ABS (m->_mp_size);
1791 if (mn == 0)
1792 gmp_die ("mpz_powm: Zero modulo.");
1793
1794 if (en == 0)
1795 {
1796 mpz_set_ui (r, 1);
1797 return;
1798 }
1799
1800 mp = m->_mp_d;
1801 mpn_div_qr_invert (&minv, mp, mn);
1802 shift = minv.shift;
1803
1804 if (shift > 0)
1805 {
1806 /* To avoid shifts, we do all our reductions, except the final
1807 one, using a *normalized* m. */
1808 minv.shift = 0;
1809
1810 tp = gmp_xalloc_limbs (mn);
1811 gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift));
1812 mp = tp;
1813 }
1814
1815 mpz_init (base);
1816
1817 if (e->_mp_size < 0)
1818 {
1819 if (!mpz_invert (base, b, m))
1820 gmp_die ("mpz_powm: Negative exponent and non-invertible base.");
1821 }
1822 else
1823 {
1824 mp_size_t bn;
1825 mpz_abs (base, b);
1826
1827 bn = base->_mp_size;
1828 if (bn >= mn)
1829 {
1830 mpn_div_qr_preinv (NULL, base->_mp_d, base->_mp_size, mp, mn, &minv);
1831 bn = mn;
1832 }
1833
1834 /* We have reduced the absolute value. Now take care of the
1835 sign. Note that we get zero represented non-canonically as
1836 m. */
1837 if (b->_mp_size < 0)
1838 {
1839 mp_ptr bp = MPZ_REALLOC (base, mn);
1840 gmp_assert_nocarry (mpn_sub (bp, mp, mn, bp, bn));
1841 bn = mn;
1842 }
1843 base->_mp_size = mpn_normalized_size (base->_mp_d, bn);
1844 }
1845 mpz_init_set_ui (tr, 1);
1846
1847 while (--en >= 0)
1848 {
1849 mp_limb_t w = e->_mp_d[en];
1850 mp_limb_t bit;
1851
1852 bit = GMP_LIMB_HIGHBIT;
1853 do
1854 {
1855 mpz_mul (tr, tr, tr);
1856 if (w & bit)
1857 mpz_mul (tr, tr, base);
1858 if (tr->_mp_size > mn)
1859 {
1860 mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv);
1861 tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
1862 }
1863 bit >>= 1;
1864 }
1865 while (bit > 0);
1866 }
1867
1868 /* Final reduction */
1869 if (tr->_mp_size >= mn)
1870 {
1871 minv.shift = shift;
1872 mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv);
1873 tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
1874 }
1875 if (tp)
1876 gmp_free (tp);
1877
1878 mpz_swap (r, tr);
1879 mpz_clear (tr);
1880 mpz_clear (base);
1881}
1882
1883void
1884mpz_powm_ui (mpz_t r, const mpz_t b, uint64_t elimb, const mpz_t m)
1885{
1886 mpz_t e;
1887 mpz_powm (r, b, mpz_roinit_n (e, &elimb, 1), m);
1888}
1889
1890/* x=trunc(y^(1/z)), r=y-x^z */
1891void
1892mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, uint64_t z)
1893{
1894 int sgn;
1895 mpz_t t, u;
1896
1897 sgn = y->_mp_size < 0;
1898 if ((~z & sgn) != 0)
1899 gmp_die ("mpz_rootrem: Negative argument, with even root.");
1900 if (z == 0)
1901 gmp_die ("mpz_rootrem: Zeroth root.");
1902
1903 if (mpz_cmpabs_ui (y, 1) <= 0) {
1904 if (x)
1905 mpz_set (x, y);
1906 if (r)
1907 r->_mp_size = 0;
1908 return;
1909 }
1910
1911 mpz_init (u);
1912 {
1913 mp_bitcnt_t tb;
1914 tb = mpz_sizeinbase (y, 2) / z + 1;
1915 mpz_init2 (t, tb + 1);
1916 mpz_setbit (t, tb);
1917 }
1918
1919 if (z == 2) /* simplify sqrt loop: z-1 == 1 */
1920 do {
1921 mpz_swap (u, t); /* u = x */
1922 mpz_tdiv_q (t, y, u); /* t = y/x */
1923 mpz_add (t, t, u); /* t = y/x + x */
1924 mpz_tdiv_q_2exp (t, t, 1); /* x'= (y/x + x)/2 */
1925 } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
1926 else /* z != 2 */ {
1927 mpz_t v;
1928
1929 mpz_init (v);
1930 if (sgn)
1931 mpz_neg (t, t);
1932
1933 do {
1934 mpz_swap (u, t); /* u = x */
1935 mpz_pow_ui (t, u, z - 1); /* t = x^(z-1) */
1936 mpz_tdiv_q (t, y, t); /* t = y/x^(z-1) */
1937 mpz_mul_ui (v, u, z - 1); /* v = x*(z-1) */
1938 mpz_add (t, t, v); /* t = y/x^(z-1) + x*(z-1) */
1939 mpz_tdiv_q_ui (t, t, z); /* x'=(y/x^(z-1) + x*(z-1))/z */
1940 } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
1941
1942 mpz_clear (v);
1943 }
1944
1945 if (r) {
1946 mpz_pow_ui (t, u, z);
1947 mpz_sub (r, y, t);
1948 }
1949 if (x)
1950 mpz_swap (x, u);
1951 mpz_clear (u);
1952 mpz_clear (t);
1953}
1954
1955int
1956mpz_root (mpz_t x, const mpz_t y, uint64_t z)
1957{
1958 int res;
1959 mpz_t r;
1960
1961 mpz_init (r);
1962 mpz_rootrem (x, r, y, z);
1963 res = r->_mp_size == 0;
1964 mpz_clear (r);
1965
1966 return res;
1967}
1968
1969/* Compute s = floor(sqrt(u)) and r = u - s^2. Allows r == NULL */
1970void
1971mpz_sqrtrem (mpz_t s, mpz_t r, const mpz_t u)
1972{
1973 mpz_rootrem (s, r, u, 2);
1974}
1975
1976void
1977mpz_sqrt (mpz_t s, const mpz_t u)
1978{
1979 mpz_rootrem (s, NULL, u, 2);
1980}
1981
1982int
1983mpz_perfect_square_p (const mpz_t u)
1984{
1985 if (u->_mp_size <= 0)
1986 return (u->_mp_size == 0);
1987 else
1988 return mpz_root (NULL, u, 2);
1989}
1990
1991int
1992mpn_perfect_square_p (mp_srcptr p, mp_size_t n)
1993{
1994 mpz_t t;
1995
1996 assert (n > 0);
1997 assert (p [n-1] != 0);
1998 return mpz_root (NULL, mpz_roinit_n (t, p, n), 2);
1999}
2000
2001mp_size_t
2002mpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr p, mp_size_t n)
2003{
2004 mpz_t s, r, u;
2005 mp_size_t res;
2006
2007 assert (n > 0);
2008 assert (p [n-1] != 0);
2009
2010 mpz_init (r);
2011 mpz_init (s);
2012 mpz_rootrem (s, r, mpz_roinit_n (u, p, n), 2);
2013
2014 assert (s->_mp_size == (n+1)/2);
2015 mpn_copyd (sp, s->_mp_d, s->_mp_size);
2016 mpz_clear (s);
2017 res = r->_mp_size;
2018 if (rp)
2019 mpn_copyd (rp, r->_mp_d, res);
2020 mpz_clear (r);
2021 return res;
2022}
2023\f
2024/* Combinatorics */
2025
2026void
2027mpz_fac_ui (mpz_t x, uint64_t n)
2028{
2029 mpz_set_ui (x, n + (n == 0));
2030 while (n > 2)
2031 mpz_mul_ui (x, x, --n);
2032}
2033
2034void
2035mpz_bin_uiui (mpz_t r, uint64_t n, uint64_t k)
2036{
2037 mpz_t t;
2038
2039 mpz_set_ui (r, k <= n);
2040
2041 if (k > (n >> 1))
2042 k = (k <= n) ? n - k : 0;
2043
2044 mpz_init (t);
2045 mpz_fac_ui (t, k);
2046
2047 for (; k > 0; k--)
2048 mpz_mul_ui (r, r, n--);
2049
2050 mpz_divexact (r, r, t);
2051 mpz_clear (t);
2052}
2053
2054\f
2055/* Primality testing */
2056static int
2057gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y,
2058 const mpz_t q, mp_bitcnt_t k)
2059{
2060 assert (k > 0);
2061
2062 /* Caller must initialize y to the base. */
2063 mpz_powm (y, y, q, n);
2064
2065 if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0)
2066 return 1;
2067
2068 while (--k > 0)
2069 {
2070 mpz_powm_ui (y, y, 2, n);
2071 if (mpz_cmp (y, nm1) == 0)
2072 return 1;
2073 /* y == 1 means that the previous y was a non-trivial square root
2074 of 1 (mod n). y == 0 means that n is a power of the base.
2075 In either case, n is not prime. */
2076 if (mpz_cmp_ui (y, 1) <= 0)
2077 return 0;
2078 }
2079 return 0;
2080}
2081
2082/* This product is 0xc0cfd797, and fits in 32 bits. */
2083#define GMP_PRIME_PRODUCT \
2084 (3UL*5UL*7UL*11UL*13UL*17UL*19UL*23UL*29UL)
2085
2086/* Bit (p+1)/2 is set, for each odd prime <= 61 */
2087#define GMP_PRIME_MASK 0xc96996dcUL
2088
2089int
2090mpz_probab_prime_p (const mpz_t n, int reps)
2091{
2092 mpz_t nm1;
2093 mpz_t q;
2094 mpz_t y;
2095 mp_bitcnt_t k;
2096 int is_prime;
2097 int j;
2098
2099 /* Note that we use the absolute value of n only, for compatibility
2100 with the real GMP. */
2101 if (mpz_even_p (n))
2102 return (mpz_cmpabs_ui (n, 2) == 0) ? 2 : 0;
2103
2104 /* Above test excludes n == 0 */
2105 assert (n->_mp_size != 0);
2106
2107 if (mpz_cmpabs_ui (n, 64) < 0)
2108 return (GMP_PRIME_MASK >> (n->_mp_d[0] >> 1)) & 2;
2109
2110 if (mpz_gcd_ui (NULL, n, GMP_PRIME_PRODUCT) != 1)
2111 return 0;
2112
2113 /* All prime factors are >= 31. */
2114 if (mpz_cmpabs_ui (n, 31*31) < 0)
2115 return 2;
2116
2117 /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] =
2118 j^2 + j + 41 using Euler's polynomial. We potentially stop early,
2119 if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps >
2120 30 (a[30] == 971 > 31*31 == 961). */
2121
2122 mpz_init (nm1);
2123 mpz_init (q);
2124 mpz_init (y);
2125
2126 /* Find q and k, where q is odd and n = 1 + 2**k * q. */
2127 nm1->_mp_size = mpz_abs_sub_ui (nm1, n, 1);
2128 k = mpz_scan1 (nm1, 0);
2129 mpz_tdiv_q_2exp (q, nm1, k);
2130
2131 for (j = 0, is_prime = 1; is_prime & (j < reps); j++)
2132 {
2133 mpz_set_ui (y, (uint64_t) j*j+j+41);
2134 if (mpz_cmp (y, nm1) >= 0)
2135 {
2136 /* Don't try any further bases. This "early" break does not affect
2137 the result for any reasonable reps value (<=5000 was tested) */
2138 assert (j >= 30);
2139 break;
2140 }
2141 is_prime = gmp_millerrabin (n, nm1, y, q, k);
2142 }
2143 mpz_clear (nm1);
2144 mpz_clear (q);
2145 mpz_clear (y);
2146
2147 return is_prime;
2148}
2149
2150\f
2151/* Logical operations and bit manipulation. */
2152
2153/* Numbers are treated as if represented in two's complement (and
2154 infinitely sign extended). For a negative values we get the two's
2155 complement from -x = ~x + 1, where ~ is bitwise complement.
2156 Negation transforms
2157
2158 xxxx10...0
2159
2160 into
2161
2162 yyyy10...0
2163
2164 where yyyy is the bitwise complement of xxxx. So least significant
2165 bits, up to and including the first one bit, are unchanged, and
2166 the more significant bits are all complemented.
2167
2168 To change a bit from zero to one in a negative number, subtract the
2169 corresponding power of two from the absolute value. This can never
2170 underflow. To change a bit from one to zero, add the corresponding
2171 power of two, and this might overflow. E.g., if x = -001111, the
2172 two's complement is 110001. Clearing the least significant bit, we
2173 get two's complement 110000, and -010000. */
2174
2175int
2176mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index)
2177{
2178 mp_size_t limb_index;
2179 uint32_t shift;
2180 mp_size_t ds;
2181 mp_size_t dn;
2182 mp_limb_t w;
2183 int bit;
2184
2185 ds = d->_mp_size;
2186 dn = GMP_ABS (ds);
2187 limb_index = bit_index / GMP_LIMB_BITS;
2188 if (limb_index >= dn)
2189 return ds < 0;
2190
2191 shift = bit_index % GMP_LIMB_BITS;
2192 w = d->_mp_d[limb_index];
2193 bit = (w >> shift) & 1;
2194
2195 if (ds < 0)
2196 {
2197 /* d < 0. Check if any of the bits below is set: If so, our bit
2198 must be complemented. */
2199 if (shift > 0 && (w << (GMP_LIMB_BITS - shift)) > 0)
2200 return bit ^ 1;
2201 while (--limb_index >= 0)
2202 if (d->_mp_d[limb_index] > 0)
2203 return bit ^ 1;
2204 }
2205 return bit;
2206}
2207
2208static void
2209mpz_abs_add_bit (mpz_t d, mp_bitcnt_t bit_index)
2210{
2211 mp_size_t dn, limb_index;
2212 mp_limb_t bit;
2213 mp_ptr dp;
2214
2215 dn = GMP_ABS (d->_mp_size);
2216
2217 limb_index = bit_index / GMP_LIMB_BITS;
2218 bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS);
2219
2220 if (limb_index >= dn)
2221 {
2222 mp_size_t i;
2223 /* The bit should be set outside of the end of the number.
2224 We have to increase the size of the number. */
2225 dp = MPZ_REALLOC (d, limb_index + 1);
2226
2227 dp[limb_index] = bit;
2228 for (i = dn; i < limb_index; i++)
2229 dp[i] = 0;
2230 dn = limb_index + 1;
2231 }
2232 else
2233 {
2234 mp_limb_t cy;
2235
2236 dp = d->_mp_d;
2237
2238 cy = mpn_add_1 (dp + limb_index, dp + limb_index, dn - limb_index, bit);
2239 if (cy > 0)
2240 {
2241 dp = MPZ_REALLOC (d, dn + 1);
2242 dp[dn++] = cy;
2243 }
2244 }
2245
2246 d->_mp_size = (d->_mp_size < 0) ? - dn : dn;
2247}
2248
2249static void
2250mpz_abs_sub_bit (mpz_t d, mp_bitcnt_t bit_index)
2251{
2252 mp_size_t dn, limb_index;
2253 mp_ptr dp;
2254 mp_limb_t bit;
2255
2256 dn = GMP_ABS (d->_mp_size);
2257 dp = d->_mp_d;
2258
2259 limb_index = bit_index / GMP_LIMB_BITS;
2260 bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS);
2261
2262 assert (limb_index < dn);
2263
2264 gmp_assert_nocarry (mpn_sub_1 (dp + limb_index, dp + limb_index,
2265 dn - limb_index, bit));
2266 dn = mpn_normalized_size (dp, dn);
2267 d->_mp_size = (d->_mp_size < 0) ? - dn : dn;
2268}
2269
2270void
2271mpz_setbit (mpz_t d, mp_bitcnt_t bit_index)
2272{
2273 if (!mpz_tstbit (d, bit_index))
2274 {
2275 if (d->_mp_size >= 0)
2276 mpz_abs_add_bit (d, bit_index);
2277 else
2278 mpz_abs_sub_bit (d, bit_index);
2279 }
2280}
2281
2282void
2283mpz_clrbit (mpz_t d, mp_bitcnt_t bit_index)
2284{
2285 if (mpz_tstbit (d, bit_index))
2286 {
2287 if (d->_mp_size >= 0)
2288 mpz_abs_sub_bit (d, bit_index);
2289 else
2290 mpz_abs_add_bit (d, bit_index);
2291 }
2292}
2293
2294void
2295mpz_combit (mpz_t d, mp_bitcnt_t bit_index)
2296{
2297 if (mpz_tstbit (d, bit_index) ^ (d->_mp_size < 0))
2298 mpz_abs_sub_bit (d, bit_index);
2299 else
2300 mpz_abs_add_bit (d, bit_index);
2301}
2302
2303void
2304mpz_com (mpz_t r, const mpz_t u)
2305{
2306 mpz_neg (r, u);
2307 mpz_sub_ui (r, r, 1);
2308}
2309
2310void
2311mpz_and (mpz_t r, const mpz_t u, const mpz_t v)
2312{
2313 mp_size_t un, vn, rn, i;
2314 mp_ptr up, vp, rp;
2315
2316 mp_limb_t ux, vx, rx;
2317 mp_limb_t uc, vc, rc;
2318 mp_limb_t ul, vl, rl;
2319
2320 un = GMP_ABS (u->_mp_size);
2321 vn = GMP_ABS (v->_mp_size);
2322 if (un < vn)
2323 {
2324 MPZ_SRCPTR_SWAP (u, v);
2325 MP_SIZE_T_SWAP (un, vn);
2326 }
2327 if (vn == 0)
2328 {
2329 r->_mp_size = 0;
2330 return;
2331 }
2332
2333 uc = u->_mp_size < 0;
2334 vc = v->_mp_size < 0;
2335 rc = uc & vc;
2336
2337 ux = -uc;
2338 vx = -vc;
2339 rx = -rc;
2340
2341 /* If the smaller input is positive, higher limbs don't matter. */
2342 rn = vx ? un : vn;
2343
2344 rp = MPZ_REALLOC (r, rn + rc);
2345
2346 up = u->_mp_d;
2347 vp = v->_mp_d;
2348
2349 i = 0;
2350 do
2351 {
2352 ul = (up[i] ^ ux) + uc;
2353 uc = ul < uc;
2354
2355 vl = (vp[i] ^ vx) + vc;
2356 vc = vl < vc;
2357
2358 rl = ( (ul & vl) ^ rx) + rc;
2359 rc = rl < rc;
2360 rp[i] = rl;
2361 }
2362 while (++i < vn);
2363 assert (vc == 0);
2364
2365 for (; i < rn; i++)
2366 {
2367 ul = (up[i] ^ ux) + uc;
2368 uc = ul < uc;
2369
2370 rl = ( (ul & vx) ^ rx) + rc;
2371 rc = rl < rc;
2372 rp[i] = rl;
2373 }
2374 if (rc)
2375 rp[rn++] = rc;
2376 else
2377 rn = mpn_normalized_size (rp, rn);
2378
2379 r->_mp_size = rx ? -rn : rn;
2380}
2381
2382void
2383mpz_ior (mpz_t r, const mpz_t u, const mpz_t v)
2384{
2385 mp_size_t un, vn, rn, i;
2386 mp_ptr up, vp, rp;
2387
2388 mp_limb_t ux, vx, rx;
2389 mp_limb_t uc, vc, rc;
2390 mp_limb_t ul, vl, rl;
2391
2392 un = GMP_ABS (u->_mp_size);
2393 vn = GMP_ABS (v->_mp_size);
2394 if (un < vn)
2395 {
2396 MPZ_SRCPTR_SWAP (u, v);
2397 MP_SIZE_T_SWAP (un, vn);
2398 }
2399 if (vn == 0)
2400 {
2401 mpz_set (r, u);
2402 return;
2403 }
2404
2405 uc = u->_mp_size < 0;
2406 vc = v->_mp_size < 0;
2407 rc = uc | vc;
2408
2409 ux = -uc;
2410 vx = -vc;
2411 rx = -rc;
2412
2413 /* If the smaller input is negative, by sign extension higher limbs
2414 don't matter. */
2415 rn = vx ? vn : un;
2416
2417 rp = MPZ_REALLOC (r, rn + rc);
2418
2419 up = u->_mp_d;
2420 vp = v->_mp_d;
2421
2422 i = 0;
2423 do
2424 {
2425 ul = (up[i] ^ ux) + uc;
2426 uc = ul < uc;
2427
2428 vl = (vp[i] ^ vx) + vc;
2429 vc = vl < vc;
2430
2431 rl = ( (ul | vl) ^ rx) + rc;
2432 rc = rl < rc;
2433 rp[i] = rl;
2434 }
2435 while (++i < vn);
2436 assert (vc == 0);
2437
2438 for (; i < rn; i++)
2439 {
2440 ul = (up[i] ^ ux) + uc;
2441 uc = ul < uc;
2442
2443 rl = ( (ul | vx) ^ rx) + rc;
2444 rc = rl < rc;
2445 rp[i] = rl;
2446 }
2447 if (rc)
2448 rp[rn++] = rc;
2449 else
2450 rn = mpn_normalized_size (rp, rn);
2451
2452 r->_mp_size = rx ? -rn : rn;
2453}
2454
2455void
2456mpz_xor (mpz_t r, const mpz_t u, const mpz_t v)
2457{
2458 mp_size_t un, vn, i;
2459 mp_ptr up, vp, rp;
2460
2461 mp_limb_t ux, vx, rx;
2462 mp_limb_t uc, vc, rc;
2463 mp_limb_t ul, vl, rl;
2464
2465 un = GMP_ABS (u->_mp_size);
2466 vn = GMP_ABS (v->_mp_size);
2467 if (un < vn)
2468 {
2469 MPZ_SRCPTR_SWAP (u, v);
2470 MP_SIZE_T_SWAP (un, vn);
2471 }
2472 if (vn == 0)
2473 {
2474 mpz_set (r, u);
2475 return;
2476 }
2477
2478 uc = u->_mp_size < 0;
2479 vc = v->_mp_size < 0;
2480 rc = uc ^ vc;
2481
2482 ux = -uc;
2483 vx = -vc;
2484 rx = -rc;
2485
2486 rp = MPZ_REALLOC (r, un + rc);
2487
2488 up = u->_mp_d;
2489 vp = v->_mp_d;
2490
2491 i = 0;
2492 do
2493 {
2494 ul = (up[i] ^ ux) + uc;
2495 uc = ul < uc;
2496
2497 vl = (vp[i] ^ vx) + vc;
2498 vc = vl < vc;
2499
2500 rl = (ul ^ vl ^ rx) + rc;
2501 rc = rl < rc;
2502 rp[i] = rl;
2503 }
2504 while (++i < vn);
2505 assert (vc == 0);
2506
2507 for (; i < un; i++)
2508 {
2509 ul = (up[i] ^ ux) + uc;
2510 uc = ul < uc;
2511
2512 rl = (ul ^ ux) + rc;
2513 rc = rl < rc;
2514 rp[i] = rl;
2515 }
2516 if (rc)
2517 rp[un++] = rc;
2518 else
2519 un = mpn_normalized_size (rp, un);
2520
2521 r->_mp_size = rx ? -un : un;
2522}
2523
2524static uint32_t
2525gmp_popcount_limb (mp_limb_t x)
2526{
2527 uint32_t c;
2528
2529 /* Do 16 bits at a time, to avoid limb-sized constants. */
2530 for (c = 0; x > 0; x >>= 16)
2531 {
2532 uint32_t w = ((x >> 1) & 0x5555) + (x & 0x5555);
2533 w = ((w >> 2) & 0x3333) + (w & 0x3333);
2534 w = ((w >> 4) & 0x0f0f) + (w & 0x0f0f);
2535 w = (w >> 8) + (w & 0x00ff);
2536 c += w;
2537 }
2538 return c;
2539}
2540
2541mp_bitcnt_t
2542mpn_popcount (mp_srcptr p, mp_size_t n)
2543{
2544 mp_size_t i;
2545 mp_bitcnt_t c;
2546
2547 for (c = 0, i = 0; i < n; i++)
2548 c += gmp_popcount_limb (p[i]);
2549
2550 return c;
2551}
2552
2553mp_bitcnt_t
2554mpz_popcount (const mpz_t u)
2555{
2556 mp_size_t un;
2557
2558 un = u->_mp_size;
2559
2560 if (un < 0)
2561 return ~(mp_bitcnt_t) 0;
2562
2563 return mpn_popcount (u->_mp_d, un);
2564}
2565
2566mp_bitcnt_t
2567mpz_hamdist (const mpz_t u, const mpz_t v)
2568{
2569 mp_size_t un, vn, i;
2570 mp_limb_t uc, vc, ul, vl, comp;
2571 mp_srcptr up, vp;
2572 mp_bitcnt_t c;
2573
2574 un = u->_mp_size;
2575 vn = v->_mp_size;
2576
2577 if ( (un ^ vn) < 0)
2578 return ~(mp_bitcnt_t) 0;
2579
2580 comp = - (uc = vc = (un < 0));
2581 if (uc)
2582 {
2583 assert (vn < 0);
2584 un = -un;
2585 vn = -vn;
2586 }
2587
2588 up = u->_mp_d;
2589 vp = v->_mp_d;
2590
2591 if (un < vn)
2592 MPN_SRCPTR_SWAP (up, un, vp, vn);
2593
2594 for (i = 0, c = 0; i < vn; i++)
2595 {
2596 ul = (up[i] ^ comp) + uc;
2597 uc = ul < uc;
2598
2599 vl = (vp[i] ^ comp) + vc;
2600 vc = vl < vc;
2601
2602 c += gmp_popcount_limb (ul ^ vl);
2603 }
2604 assert (vc == 0);
2605
2606 for (; i < un; i++)
2607 {
2608 ul = (up[i] ^ comp) + uc;
2609 uc = ul < uc;
2610
2611 c += gmp_popcount_limb (ul ^ comp);
2612 }
2613
2614 return c;
2615}
2616
2617mp_bitcnt_t
2618mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit)
2619{
2620 mp_ptr up;
2621 mp_size_t us, un, i;
2622 mp_limb_t limb, ux;
2623
2624 us = u->_mp_size;
2625 un = GMP_ABS (us);
2626 i = starting_bit / GMP_LIMB_BITS;
2627
2628 /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit
2629 for u<0. Notice this test picks up any u==0 too. */
2630 if (i >= un)
2631 return (us >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit);
2632
2633 up = u->_mp_d;
2634 ux = 0;
2635 limb = up[i];
2636
2637 if (starting_bit != 0)
2638 {
2639 if (us < 0)
2640 {
2641 ux = mpn_zero_p (up, i);
2642 limb = ~ limb + ux;
2643 ux = - (mp_limb_t) (limb >= ux);
2644 }
2645
2646 /* Mask to 0 all bits before starting_bit, thus ignoring them. */
2647 limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
2648 }
2649
2650 return mpn_common_scan (limb, i, up, un, ux);
2651}
2652
2653mp_bitcnt_t
2654mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit)
2655{
2656 mp_ptr up;
2657 mp_size_t us, un, i;
2658 mp_limb_t limb, ux;
2659
2660 us = u->_mp_size;
2661 ux = - (mp_limb_t) (us >= 0);
2662 un = GMP_ABS (us);
2663 i = starting_bit / GMP_LIMB_BITS;
2664
2665 /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for
2666 u<0. Notice this test picks up all cases of u==0 too. */
2667 if (i >= un)
2668 return (ux ? starting_bit : ~(mp_bitcnt_t) 0);
2669
2670 up = u->_mp_d;
2671 limb = up[i] ^ ux;
2672
2673 if (ux == 0)
2674 limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */
2675
2676 /* Mask all bits before starting_bit, thus ignoring them. */
2677 limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
2678
2679 return mpn_common_scan (limb, i, up, un, ux);
2680}
2681
2682\f
2683/* MPZ base conversion. */
2684
2685size_t
2686mpz_sizeinbase (const mpz_t u, int base)
2687{
2688 mp_size_t un;
2689 mp_srcptr up;
2690 mp_ptr tp;
2691 mp_bitcnt_t bits;
2692 struct gmp_div_inverse bi;
2693 size_t ndigits;
2694
2695 assert (base >= 2);
2696 assert (base <= 36);
2697
2698 un = GMP_ABS (u->_mp_size);
2699 if (un == 0)
2700 return 1;
2701
2702 up = u->_mp_d;
2703
2704 bits = (un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]);
2705 switch (base)
2706 {
2707 case 2:
2708 return bits;
2709 case 4:
2710 return (bits + 1) / 2;
2711 case 8:
2712 return (bits + 2) / 3;
2713 case 16:
2714 return (bits + 3) / 4;
2715 case 32:
2716 return (bits + 4) / 5;
2717 /* FIXME: Do something more clever for the common case of base
2718 10. */
2719 }
2720
2721 tp = gmp_xalloc_limbs (un);
2722 mpn_copyi (tp, up, un);
2723 mpn_div_qr_1_invert (&bi, base);
2724
2725 ndigits = 0;
2726 do
2727 {
2728 ndigits++;
2729 mpn_div_qr_1_preinv (tp, tp, un, &bi);
2730 un -= (tp[un-1] == 0);
2731 }
2732 while (un > 0);
2733
2734 gmp_free (tp);
2735 return ndigits;
2736}
2737
2738char *
2739mpz_get_str (char *sp, int base, const mpz_t u)
2740{
2741 uint32_t bits;
2742 const char *digits;
2743 mp_size_t un;
2744 size_t i, sn;
2745
2746 if (base >= 0)
2747 {
2748 digits = "0123456789abcdefghijklmnopqrstuvwxyz";
2749 }
2750 else
2751 {
2752 base = -base;
2753 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2754 }
2755 if (base <= 1)
2756 base = 10;
2757 if (base > 36)
2758 return NULL;
2759
2760 sn = 1 + mpz_sizeinbase (u, base);
2761 if (!sp)
2762 sp = (char *) gmp_xalloc (1 + sn);
2763
2764 un = GMP_ABS (u->_mp_size);
2765
2766 if (un == 0)
2767 {
2768 sp[0] = '0';
2769 sp[1] = '\0';
2770 return sp;
2771 }
2772
2773 i = 0;
2774
2775 if (u->_mp_size < 0)
2776 sp[i++] = '-';
2777
2778 bits = mpn_base_power_of_two_p (base);
2779
2780 if (bits)
2781 /* Not modified in this case. */
2782 sn = i + mpn_get_str_bits ((uint8_t *) sp + i, bits, u->_mp_d, un);
2783 else
2784 {
2785 struct mpn_base_info info;
2786 mp_ptr tp;
2787
2788 mpn_get_base_info (&info, base);
2789 tp = gmp_xalloc_limbs (un);
2790 mpn_copyi (tp, u->_mp_d, un);
2791
2792 sn = i + mpn_get_str_other ((uint8_t *) sp + i, base, &info, tp, un);
2793 gmp_free (tp);
2794 }
2795
2796 for (; i < sn; i++)
2797 sp[i] = digits[(uint8_t) sp[i]];
2798
2799 sp[sn] = '\0';
2800 return sp;
2801}
2802
2803size_t
2804mpz_out_str (FILE *stream, int base, const mpz_t x)
2805{
2806 char *str;
2807 size_t len;
2808
2809 str = mpz_get_str (NULL, base, x);
2810 len = strlen (str);
2811 len = fwrite (str, 1, len, stream);
2812 gmp_free (str);
2813 return len;
2814}
2815#endif
2816
2817
2818static void gmp_die (const char *msg)
2819{
2820 fprintf (stderr, "%s\n", msg);
2821 abort();
2822}
2823
2824static mp_ptr gmp_xalloc_limbs (mp_size_t size)
2825{
2826 return (mp_ptr) malloc(size * sizeof(mp_limb_t));
2827}
2828
2829static int gmp_detect_endian (void)
2830{
2831 static const int i = 2;
2832 const uint8_t *p = (const uint8_t *) &i;
2833 return 1 - *p;
2834}
2835
2836void *mpz_export (void *r, size_t *countp, int order, size_t size, int endian,size_t nails, const mpz_t u)
2837{
2838 size_t count;
2839 mp_size_t un;
2840
2841 if (nails != 0)
2842 gmp_die ("mpz_import: Nails not supported.");
2843
2844 assert (order == 1 || order == -1);
2845 assert (endian >= -1 && endian <= 1);
2846 assert (size > 0 || u->_mp_size == 0);
2847
2848 un = u->_mp_size;
2849 count = 0;
2850 if (un != 0)
2851 {
2852 size_t k;
2853 uint8_t *p;
2854 ptrdiff_t word_step;
2855 /* The current (partial) limb. */
2856 mp_limb_t limb;
2857 /* The number of bytes left to to in this limb. */
2858 size_t bytes;
2859 /* The index where the limb was read. */
2860 mp_size_t i;
2861
2862 un = GMP_ABS (un);
2863
2864 /* Count bytes in top limb. */
2865 limb = u->_mp_d[un-1];
2866 assert (limb != 0);
2867
2868 k = 0;
2869 do {
2870 k++; limb >>= CHAR_BIT;
2871 } while (limb != 0);
2872
2873 count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
2874
2875 if (!r)
2876 r = malloc (count * size);
2877
2878 if (endian == 0)
2879 endian = gmp_detect_endian ();
2880
2881 p = (uint8_t *) r;
2882
2883 word_step = (order != endian) ? 2 * size : 0;
2884
2885 /* Process bytes from the least significant end, so point p at the
2886 least significant word. */
2887 if (order == 1)
2888 {
2889 p += size * (count - 1);
2890 word_step = - word_step;
2891 }
2892
2893 /* And at least significant byte of that word. */
2894 if (endian == 1)
2895 p += (size - 1);
2896
2897 for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step)
2898 {
2899 size_t j;
2900 for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
2901 {
2902 if (bytes == 0)
2903 {
2904 if (i < un)
2905 limb = u->_mp_d[i++];
2906 bytes = sizeof (mp_limb_t);
2907 }
2908 *p = limb;
2909 limb >>= CHAR_BIT;
2910 bytes--;
2911 }
2912 }
2913 assert (i == un);
2914 assert (k == count);
2915 }
2916
2917 if (countp)
2918 *countp = count;
2919
2920 return r;
2921}
2922
2923/////////////////////////////////
2924
2925
2926static mp_size_t mpn_normalized_size (mp_srcptr xp, mp_size_t n)
2927{
2928 while (n > 0 && xp[n-1] == 0)
2929 --n;
2930 return n;
2931}
2932
2933
2934static mp_ptr gmp_xrealloc_limbs (mp_ptr old, mp_size_t size)
2935{
2936 assert (size > 0);
2937 return (mp_ptr) realloc(old, size * sizeof (mp_limb_t));
2938}
2939
2940
2941static mp_ptr
2942mpz_realloc (mpz_t r, mp_size_t size)
2943{
2944 size = GMP_MAX (size, 1);
2945
2946 r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size);
2947 r->_mp_alloc = (int32_t)size;
2948
2949 if (GMP_ABS (r->_mp_size) > size)
2950 r->_mp_size = 0;
2951
2952 return r->_mp_d;
2953}
2954
2955/* Import and export. Does not support nails. */
2956void
2957mpz_import (mpz_t r, size_t count, int order, size_t size, int endian,size_t nails, const void *src)
2958{
2959 const uint8_t *p;
2960 ptrdiff_t word_step;
2961 mp_ptr rp;
2962 mp_size_t rn;
2963
2964 // The current (partial) limb.
2965 mp_limb_t limb;
2966 // The number of bytes already copied to this limb (starting from the low end).
2967 size_t bytes;
2968 // The index where the limb should be stored, when completed.
2969 mp_size_t i;
2970
2971 if (nails != 0)
2972 gmp_die ("mpz_import: Nails not supported.");
2973
2974 assert (order == 1 || order == -1);
2975 assert (endian >= -1 && endian <= 1);
2976
2977 if (endian == 0)
2978 endian = gmp_detect_endian ();
2979
2980 p = (uint8_t *) src;
2981
2982 word_step = (order != endian) ? 2 * size : 0;
2983
2984 // Process bytes from the least significant end, so point p at the least significant word
2985 if (order == 1)
2986 {
2987 p += size * (count - 1);
2988 word_step = - word_step;
2989 }
2990 // And at least significant byte of that word
2991 if (endian == 1)
2992 p += (size - 1);
2993 rn = (size * count + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t);
2994 rp = MPZ_REALLOC (r, rn);
2995 for (limb = 0, bytes = 0, i = 0; count > 0; count--, p += word_step)
2996 {
2997 size_t j;
2998 for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
2999 {
3000 limb |= (mp_limb_t) *p << (bytes++ * CHAR_BIT);
3001 if (bytes == sizeof(mp_limb_t))
3002 {
3003 rp[i++] = limb;
3004 bytes = 0;
3005 limb = 0;
3006 }
3007 }
3008 }
3009 assert (i + (bytes > 0) == rn);
3010 if (limb != 0)
3011 rp[i++] = limb;
3012 else i = mpn_normalized_size (rp, i);
3013 r->_mp_size = (int32_t)i;
3014}
3015
3016void mpz_init (mpz_t r)
3017{
3018 r->_mp_alloc = 1;
3019 r->_mp_size = 0;
3020 r->_mp_d = gmp_xalloc_limbs (1);
3021}
3022
3023void
3024mpz_clear (mpz_t r)
3025{
3026 free (r->_mp_d);
3027}
3028
3029static void
3030mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b)
3031{
3032 mp_limb_t m;
3033 mp_limb_t p;
3034 uint32_t exp;
3035
3036 m = GMP_LIMB_MAX / b;
3037 for (exp = 1, p = b; p <= m; exp++)
3038 p *= b;
3039
3040 info->exp = exp;
3041 info->bb = p;
3042}
3043
3044static uint32_t mpn_base_power_of_two_p (uint32_t b)
3045{
3046 switch (b)
3047 {
3048 case 2: return 1;
3049 case 4: return 2;
3050 case 8: return 3;
3051 case 16: return 4;
3052 case 32: return 5;
3053 case 64: return 6;
3054 case 128: return 7;
3055 case 256: return 8;
3056 default: return 0;
3057 }
3058}
3059
3060
3061static mp_size_t mpn_set_str_bits (mp_ptr rp, const uint8_t *sp, size_t sn, uint32_t bits)
3062{
3063 mp_size_t rn;
3064 size_t j;
3065 uint32_t shift;
3066
3067 for (j = sn, rn = 0, shift = 0; j-- > 0; )
3068 {
3069 if (shift == 0)
3070 {
3071 rp[rn++] = sp[j];
3072 shift += bits;
3073 }
3074 else
3075 {
3076 rp[rn-1] |= (mp_limb_t) sp[j] << shift;
3077 shift += bits;
3078 if (shift >= GMP_LIMB_BITS)
3079 {
3080 shift -= GMP_LIMB_BITS;
3081 if (shift > 0)
3082 rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift);
3083 }
3084 }
3085 }
3086 rn = mpn_normalized_size (rp, rn);
3087 return rn;
3088}
3089
3090mp_limb_t
3091mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
3092{
3093 mp_size_t i;
3094
3095 assert (n > 0);
3096 i = 0;
3097 do
3098 {
3099 mp_limb_t r = ap[i] + b;
3100 /* Carry out */
3101 b = (r < b);
3102 rp[i] = r;
3103 }
3104 while (++i < n);
3105
3106 return b;
3107}
3108
3109mp_limb_t
3110mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
3111{
3112 mp_limb_t ul, cl, hpl, lpl;
3113
3114 assert (n >= 1);
3115
3116 cl = 0;
3117 do
3118 {
3119 ul = *up++;
3120 gmp_umul_ppmm (hpl, lpl, ul, vl);
3121
3122 lpl += cl;
3123 cl = (lpl < cl) + hpl;
3124
3125 *rp++ = lpl;
3126 }
3127 while (--n != 0);
3128
3129 return cl;
3130}
3131
3132static mp_size_t
3133mpn_set_str_other (mp_ptr rp, const uint8_t *sp, size_t sn,
3134 mp_limb_t b, const struct mpn_base_info *info)
3135{
3136 mp_size_t rn;
3137 mp_limb_t w;
3138 uint32_t k;
3139 size_t j;
3140
3141 k = 1 + (sn - 1) % info->exp;
3142
3143 j = 0;
3144 w = sp[j++];
3145 while (--k != 0)
3146 w = w * b + sp[j++];
3147
3148 rp[0] = w;
3149
3150 for (rn = (w > 0); j < sn;)
3151 {
3152 mp_limb_t cy;
3153
3154 w = sp[j++];
3155 for (k = 1; k < info->exp; k++)
3156 w = w * b + sp[j++];
3157
3158 cy = mpn_mul_1 (rp, rp, rn, info->bb);
3159 cy += mpn_add_1 (rp, rp, rn, w);
3160 if (cy > 0)
3161 rp[rn++] = cy;
3162 }
3163 assert (j == sn);
3164
3165 return rn;
3166}
3167
3168void mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n)
3169{
3170 mp_size_t i;
3171 for (i = 0; i < n; i++)
3172 d[i] = s[i];
3173}
3174
3175void mpz_set (mpz_t r, const mpz_t x)
3176{
3177 /* Allow the NOP r == x */
3178 if (r != x)
3179 {
3180 mp_size_t n;
3181 mp_ptr rp;
3182
3183 n = GMP_ABS (x->_mp_size);
3184 rp = MPZ_REALLOC (r, n);
3185
3186 mpn_copyi (rp, x->_mp_d, n);
3187 r->_mp_size = x->_mp_size;
3188 }
3189}
3190
3191int mpz_set_str (mpz_t r, const char *sp, int base)
3192{
3193 uint32_t bits;
3194 mp_size_t rn, alloc;
3195 mp_ptr rp;
3196 size_t sn;
3197 int sign;
3198 uint8_t *dp;
3199
3200 assert (base == 0 || (base >= 2 && base <= 36));
3201
3202 while (isspace( (uint8_t) *sp))
3203 sp++;
3204
3205 sign = (*sp == '-');
3206 sp += sign;
3207
3208 if (base == 0)
3209 {
3210 if (*sp == '0')
3211 {
3212 sp++;
3213 if (*sp == 'x' || *sp == 'X')
3214 {
3215 base = 16;
3216 sp++;
3217 }
3218 else if (*sp == 'b' || *sp == 'B')
3219 {
3220 base = 2;
3221 sp++;
3222 }
3223 else
3224 base = 8;
3225 }
3226 else
3227 base = 10;
3228 }
3229
3230 sn = strlen (sp);
3231 dp = (uint8_t *) malloc (sn + (sn == 0));
3232
3233 for (sn = 0; *sp; sp++)
3234 {
3235 uint32_t digit;
3236
3237 if (isspace ((uint8_t) *sp))
3238 continue;
3239 if (*sp >= '0' && *sp <= '9')
3240 digit = *sp - '0';
3241 else if (*sp >= 'a' && *sp <= 'z')
3242 digit = *sp - 'a' + 10;
3243 else if (*sp >= 'A' && *sp <= 'Z')
3244 digit = *sp - 'A' + 10;
3245 else
3246 digit = base; /* fail */
3247
3248 if (digit >= base)
3249 {
3250 free (dp);
3251 r->_mp_size = 0;
3252 return -1;
3253 }
3254
3255 dp[sn++] = digit;
3256 }
3257
3258 bits = mpn_base_power_of_two_p (base);
3259
3260 if (bits > 0)
3261 {
3262 alloc = (sn * bits + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
3263 rp = MPZ_REALLOC (r, alloc);
3264 rn = mpn_set_str_bits (rp, dp, sn, bits);
3265 }
3266 else
3267 {
3268 struct mpn_base_info info;
3269 mpn_get_base_info (&info, base);
3270 alloc = (sn + info.exp - 1) / info.exp;
3271 rp = MPZ_REALLOC (r, alloc);
3272 rn = mpn_set_str_other (rp, dp, sn, base, &info);
3273 }
3274 assert (rn <= alloc);
3275 free (dp);
3276
3277 r->_mp_size = (int32_t)(sign ? - rn : rn);
3278
3279 return 0;
3280}
3281
3282void mpz_init_set (mpz_t r, const mpz_t x)
3283{
3284 mpz_init (r);
3285 mpz_set (r, x);
3286}
3287
3288int mpz_init_set_str (mpz_t r, const char *sp, int base)
3289{
3290 mpz_init (r);
3291 return mpz_set_str (r, sp, base);
3292}
3293
3294int mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n)
3295{
3296 while (--n >= 0)
3297 {
3298 if (ap[n] != bp[n])
3299 return ap[n] > bp[n] ? 1 : -1;
3300 }
3301 return 0;
3302}
3303
3304int mpz_cmp (const mpz_t a, const mpz_t b)
3305{
3306 mp_size_t asize = a->_mp_size;
3307 mp_size_t bsize = b->_mp_size;
3308
3309 if (asize != bsize)
3310 return (asize < bsize) ? -1 : 1;
3311 else if (asize >= 0)
3312 return mpn_cmp (a->_mp_d, b->_mp_d, asize);
3313 else
3314 return mpn_cmp (b->_mp_d, a->_mp_d, -asize);
3315}
3316
3317static void mpn_div_qr_1_invert (struct gmp_div_inverse *inv, mp_limb_t d)
3318{
3319 uint32_t shift;
3320
3321 assert (d > 0);
3322 gmp_clz (shift, d);
3323 inv->shift = shift;
3324 inv->d1 = d << shift;
3325 inv->di = mpn_invert_limb (inv->d1);
3326}
3327
3328/* MPN division interface. */
3329mp_limb_t
3330mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
3331{
3332 mp_limb_t r, p, m;
3333 uint32_t ul, uh;
3334 uint32_t ql, qh;
3335
3336 /* First, do a 2/1 inverse. */
3337 /* The inverse m is defined as floor( (B^2 - 1 - u1)/u1 ), so that 0 <
3338 * B^2 - (B + m) u1 <= u1 */
3339 assert (u1 >= GMP_LIMB_HIGHBIT);
3340
3341 ul = u1 & GMP_LLIMB_MASK;
3342 uh = u1 >> (GMP_LIMB_BITS / 2);
3343
3344 qh = (uint32_t)(~u1 / uh);
3345 r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK;
3346
3347 p = (mp_limb_t) qh * ul;
3348 /* Adjustment steps taken from udiv_qrnnd_c */
3349 if (r < p)
3350 {
3351 qh--;
3352 r += u1;
3353 if (r >= u1) /* i.e. we didn't get carry when adding to r */
3354 if (r < p)
3355 {
3356 qh--;
3357 r += u1;
3358 }
3359 }
3360 r -= p;
3361
3362 /* Do a 3/2 division (with half limb size) */
3363 p = (r >> (GMP_LIMB_BITS / 2)) * qh + r;
3364 ql = (p >> (GMP_LIMB_BITS / 2)) + 1;
3365
3366 /* By the 3/2 method, we don't need the high half limb. */
3367 r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1;
3368
3369 if (r >= (p << (GMP_LIMB_BITS / 2)))
3370 {
3371 ql--;
3372 r += u1;
3373 }
3374 m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql;
3375 if (r >= u1)
3376 {
3377 m++;
3378 r -= u1;
3379 }
3380
3381 if (u0 > 0)
3382 {
3383 mp_limb_t th, tl;
3384 r = ~r;
3385 r += u0;
3386 if (r < u0)
3387 {
3388 m--;
3389 if (r >= u1)
3390 {
3391 m--;
3392 r -= u1;
3393 }
3394 r -= u1;
3395 }
3396 gmp_umul_ppmm (th, tl, u0, m);
3397 r += th;
3398 if (r < th)
3399 {
3400 m--;
3401 m -= ((r > u1) | ((r == u1) & (tl > u0)));
3402 }
3403 }
3404
3405 return m;
3406}
3407
3408static void mpn_div_qr_2_invert (struct gmp_div_inverse *inv,mp_limb_t d1, mp_limb_t d0)
3409{
3410 uint32_t shift;
3411
3412 assert (d1 > 0);
3413 gmp_clz (shift, d1);
3414 inv->shift = shift;
3415 if (shift > 0)
3416 {
3417 d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift));
3418 d0 <<= shift;
3419 }
3420 inv->d1 = d1;
3421 inv->d0 = d0;
3422 inv->di = mpn_invert_3by2 (d1, d0);
3423}
3424
3425static void mpn_div_qr_invert (struct gmp_div_inverse *inv, mp_srcptr dp, mp_size_t dn)
3426{
3427 assert (dn > 0);
3428
3429 if (dn == 1)
3430 mpn_div_qr_1_invert (inv, dp[0]);
3431 else if (dn == 2)
3432 mpn_div_qr_2_invert (inv, dp[1], dp[0]);
3433 else
3434 {
3435 uint32_t shift;
3436 mp_limb_t d1, d0;
3437
3438 d1 = dp[dn-1];
3439 d0 = dp[dn-2];
3440 assert (d1 > 0);
3441 gmp_clz (shift, d1);
3442 inv->shift = shift;
3443 if (shift > 0)
3444 {
3445 d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift));
3446 d0 = (d0 << shift) | (dp[dn-3] >> (GMP_LIMB_BITS - shift));
3447 }
3448 inv->d1 = d1;
3449 inv->d0 = d0;
3450 inv->di = mpn_invert_3by2 (d1, d0);
3451 }
3452}
3453
3454mp_limb_t mpn_lshift(mp_ptr rp, mp_srcptr up, mp_size_t n, uint32_t cnt)
3455{
3456 mp_limb_t high_limb, low_limb;
3457 uint32_t tnc;
3458 mp_limb_t retval;
3459
3460 assert (n >= 1);
3461 assert (cnt >= 1);
3462 assert (cnt < GMP_LIMB_BITS);
3463
3464 up += n;
3465 rp += n;
3466
3467 tnc = GMP_LIMB_BITS - cnt;
3468 low_limb = *--up;
3469 retval = low_limb >> tnc;
3470 high_limb = (low_limb << cnt);
3471
3472 while (--n != 0)
3473 {
3474 low_limb = *--up;
3475 *--rp = high_limb | (low_limb >> tnc);
3476 high_limb = (low_limb << cnt);
3477 }
3478 *--rp = high_limb;
3479
3480 return retval;
3481}
3482
3483// Not matching current public gmp interface, rather corresponding to the sbpi1_div_* functions.
3484static mp_limb_t mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,const struct gmp_div_inverse *inv)
3485{
3486 mp_limb_t d, di;
3487 mp_limb_t r;
3488 mp_ptr tp = NULL;
3489
3490 if (inv->shift > 0)
3491 {
3492 tp = gmp_xalloc_limbs (nn);
3493 r = mpn_lshift (tp, np, nn, inv->shift);
3494 np = tp;
3495 }
3496 else
3497 r = 0;
3498
3499 d = inv->d1;
3500 di = inv->di;
3501 while (--nn >= 0)
3502 {
3503 mp_limb_t q;
3504
3505 gmp_udiv_qrnnd_preinv (q, r, r, np[nn], d, di);
3506 if (qp)
3507 qp[nn] = q;
3508 }
3509 if (inv->shift > 0)
3510 free (tp);
3511
3512 return r >> inv->shift;
3513}
3514static void mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn, const struct gmp_div_inverse *inv)
3515{
3516 uint32_t shift;
3517 mp_size_t i;
3518 mp_limb_t d1, d0, di, r1, r0;
3519 mp_ptr tp=0;
3520
3521 assert (nn >= 2);
3522 shift = inv->shift;
3523 d1 = inv->d1;
3524 d0 = inv->d0;
3525 di = inv->di;
3526
3527 if (shift > 0)
3528 {
3529 tp = gmp_xalloc_limbs (nn);
3530 r1 = mpn_lshift (tp, np, nn, shift);
3531 np = tp;
3532 }
3533 else
3534 r1 = 0;
3535
3536 r0 = np[nn - 1];
3537
3538 i = nn - 2;
3539 do
3540 {
3541 mp_limb_t n0, q;
3542 n0 = np[i];
3543 gmp_udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di);
3544
3545 if (qp)
3546 qp[i] = q;
3547 }
3548 while (--i >= 0);
3549
3550 if (shift > 0)
3551 {
3552 assert ((r0 << (GMP_LIMB_BITS - shift)) == 0);
3553 r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift));
3554 r1 >>= shift;
3555 if ( tp != 0 )
3556 free (tp);
3557 }
3558
3559 rp[1] = r1;
3560 rp[0] = r0;
3561}
3562
3563mp_limb_t mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
3564{
3565 mp_size_t i;
3566 mp_limb_t cy;
3567
3568 for (i = 0, cy = 0; i < n; i++)
3569 {
3570 mp_limb_t a, b;
3571 a = ap[i]; b = bp[i];
3572 b += cy;
3573 cy = (b < cy);
3574 cy += (a < b);
3575 rp[i] = a - b;
3576 }
3577 return cy;
3578}
3579
3580mp_limb_t mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
3581{
3582 mp_limb_t cy;
3583
3584 assert (an >= bn);
3585
3586 cy = mpn_sub_n (rp, ap, bp, bn);
3587 if (an > bn)
3588 cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy);
3589 return cy;
3590}
3591
3592mp_limb_t mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
3593{
3594 mp_limb_t ul, cl, hpl, lpl, rl;
3595
3596 assert (n >= 1);
3597
3598 cl = 0;
3599 do
3600 {
3601 ul = *up++;
3602 gmp_umul_ppmm (hpl, lpl, ul, vl);
3603
3604 lpl += cl;
3605 cl = (lpl < cl) + hpl;
3606
3607 rl = *rp;
3608 lpl = rl - lpl;
3609 cl += lpl > rl;
3610 *rp++ = lpl;
3611 }
3612 while (--n != 0);
3613
3614 return cl;
3615}
3616
3617static void mpn_div_qr_pi1 (mp_ptr qp,mp_ptr np, mp_size_t nn, mp_limb_t n1,mp_srcptr dp, mp_size_t dn,mp_limb_t dinv)
3618{
3619 mp_size_t i;
3620
3621 mp_limb_t d1, d0;
3622 mp_limb_t cy, cy1;
3623 mp_limb_t q;
3624
3625 assert (dn > 2);
3626 assert (nn >= dn);
3627
3628 d1 = dp[dn - 1];
3629 d0 = dp[dn - 2];
3630
3631 assert ((d1 & GMP_LIMB_HIGHBIT) != 0);
3632 /* Iteration variable is the index of the q limb.
3633 *
3634 * We divide <n1, np[dn-1+i], np[dn-2+i], np[dn-3+i],..., np[i]>
3635 * by <d1, d0, dp[dn-3], ..., dp[0] >
3636 */
3637
3638 i = nn - dn;
3639 do
3640 {
3641 mp_limb_t n0 = np[dn-1+i];
3642
3643 if (n1 == d1 && n0 == d0)
3644 {
3645 q = GMP_LIMB_MAX;
3646 mpn_submul_1 (np+i, dp, dn, q);
3647 n1 = np[dn-1+i]; /* update n1, last loop's value will now be invalid */
3648 }
3649 else
3650 {
3651 gmp_udiv_qr_3by2 (q, n1, n0, n1, n0, np[dn-2+i], d1, d0, dinv);
3652
3653 cy = mpn_submul_1 (np + i, dp, dn-2, q);
3654
3655 cy1 = n0 < cy;
3656 n0 = n0 - cy;
3657 cy = n1 < cy1;
3658 n1 = n1 - cy1;
3659 np[dn-2+i] = n0;
3660
3661 if (cy != 0)
3662 {
3663 n1 += d1 + mpn_add_n (np + i, np + i, dp, dn - 1);
3664 q--;
3665 }
3666 }
3667
3668 if (qp)
3669 qp[i] = q;
3670 }
3671 while (--i >= 0);
3672
3673 np[dn - 1] = n1;
3674}
3675
3676mp_limb_t mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, uint32_t cnt)
3677{
3678 mp_limb_t high_limb, low_limb;
3679 uint32_t tnc;
3680 mp_limb_t retval;
3681
3682 assert (n >= 1);
3683 assert (cnt >= 1);
3684 assert (cnt < GMP_LIMB_BITS);
3685
3686 tnc = GMP_LIMB_BITS - cnt;
3687 high_limb = *up++;
3688 retval = (high_limb << tnc);
3689 low_limb = high_limb >> cnt;
3690
3691 while (--n != 0)
3692 {
3693 high_limb = *up++;
3694 *rp++ = low_limb | (high_limb << tnc);
3695 low_limb = high_limb >> cnt;
3696 }
3697 *rp = low_limb;
3698
3699 return retval;
3700}
3701
3702static void mpn_div_qr_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn,mp_srcptr dp, mp_size_t dn,const struct gmp_div_inverse *inv)
3703{
3704 assert (dn > 0);
3705 assert (nn >= dn);
3706
3707 if (dn == 1)
3708 np[0] = mpn_div_qr_1_preinv (qp, np, nn, inv);
3709 else if (dn == 2)
3710 mpn_div_qr_2_preinv (qp, np, np, nn, inv);
3711 else
3712 {
3713 mp_limb_t nh;
3714 uint32_t shift;
3715
3716 assert (inv->d1 == dp[dn-1]);
3717 assert (inv->d0 == dp[dn-2]);
3718 assert ((inv->d1 & GMP_LIMB_HIGHBIT) != 0);
3719
3720 shift = inv->shift;
3721 if (shift > 0)
3722 nh = mpn_lshift (np, np, nn, shift);
3723 else
3724 nh = 0;
3725
3726 mpn_div_qr_pi1 (qp, np, nn, nh, dp, dn, inv->di);
3727
3728 if (shift > 0)
3729 gmp_assert_nocarry (mpn_rshift (np, np, dn, shift));
3730 }
3731}
3732
3733static void mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn)
3734{
3735 struct gmp_div_inverse inv;
3736 mp_ptr tp = NULL;
3737
3738 assert (dn > 0);
3739 assert (nn >= dn);
3740
3741 mpn_div_qr_invert (&inv, dp, dn);
3742 if (dn > 2 && inv.shift > 0)
3743 {
3744 tp = gmp_xalloc_limbs (dn);
3745 gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift));
3746 dp = tp;
3747 }
3748 mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv);
3749 if (tp)
3750 free (tp);
3751}
3752
3753static int
3754mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
3755{
3756 if (an != bn)
3757 return an < bn ? -1 : 1;
3758 else
3759 return mpn_cmp (ap, bp, an);
3760}
3761
3762static mp_size_t mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b)
3763{
3764 mp_size_t an = GMP_ABS (a->_mp_size);
3765 mp_size_t bn = GMP_ABS (b->_mp_size);
3766 int cmp;
3767 mp_ptr rp;
3768
3769 cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn);
3770 if (cmp > 0)
3771 {
3772 rp = MPZ_REALLOC (r, an);
3773 gmp_assert_nocarry (mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn));
3774 return mpn_normalized_size (rp, an);
3775 }
3776 else if (cmp < 0)
3777 {
3778 rp = MPZ_REALLOC (r, bn);
3779 gmp_assert_nocarry (mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an));
3780 return -mpn_normalized_size (rp, bn);
3781 }
3782 else
3783 return 0;
3784}
3785
3786mp_limb_t mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
3787{
3788 mp_size_t i;
3789 mp_limb_t cy;
3790
3791 for (i = 0, cy = 0; i < n; i++)
3792 {
3793 mp_limb_t a, b, r;
3794 a = ap[i]; b = bp[i];
3795 r = a + cy;
3796 cy = (r < cy);
3797 r += b;
3798 cy += (r < b);
3799 rp[i] = r;
3800 }
3801 return cy;
3802}
3803
3804mp_limb_t
3805mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
3806{
3807 mp_limb_t cy;
3808
3809 assert (an >= bn);
3810
3811 cy = mpn_add_n (rp, ap, bp, bn);
3812 if (an > bn)
3813 cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy);
3814 return cy;
3815}
3816
3817static mp_size_t mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b)
3818{
3819 mp_size_t an = GMP_ABS (a->_mp_size);
3820 mp_size_t bn = GMP_ABS (b->_mp_size);
3821 mp_ptr rp;
3822 mp_limb_t cy;
3823
3824 if (an < bn)
3825 {
3826 MPZ_SRCPTR_SWAP (a, b);
3827 MP_SIZE_T_SWAP (an, bn);
3828 }
3829
3830 rp = MPZ_REALLOC (r, an + 1);
3831 cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn);
3832
3833 rp[an] = cy;
3834
3835 return an + cy;
3836}
3837
3838
3839void mpz_sub (mpz_t r, const mpz_t a, const mpz_t b)
3840{
3841 mp_size_t rn;
3842
3843 if ( (a->_mp_size ^ b->_mp_size) >= 0)
3844 rn = mpz_abs_sub (r, a, b);
3845 else
3846 rn = mpz_abs_add (r, a, b);
3847
3848 r->_mp_size = (int)(a->_mp_size >= 0 ? rn : - rn);
3849}
3850
3851/* Adds to the absolute value. Returns new size, but doesn't store it. */
3852static mp_size_t mpz_abs_add_ui (mpz_t r, const mpz_t a, uint64_t b)
3853{
3854 mp_size_t an;
3855 mp_ptr rp;
3856 mp_limb_t cy;
3857
3858 an = GMP_ABS (a->_mp_size);
3859 if (an == 0)
3860 {
3861 r->_mp_d[0] = b;
3862 return b > 0;
3863 }
3864
3865 rp = MPZ_REALLOC (r, an + 1);
3866
3867 cy = mpn_add_1 (rp, a->_mp_d, an, b);
3868 rp[an] = cy;
3869 an += cy;
3870
3871 return an;
3872}
3873
3874mp_limb_t mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
3875{
3876 mp_size_t i;
3877
3878 assert (n > 0);
3879
3880 i = 0;
3881 do
3882 {
3883 mp_limb_t a = ap[i];
3884 /* Carry out */
3885 mp_limb_t cy = a < b;;
3886 rp[i] = a - b;
3887 b = cy;
3888 }
3889 while (++i < n);
3890
3891 return b;
3892}
3893
3894// Subtract from the absolute value. Returns new size, (or -1 on underflow), but doesn't store it.
3895static mp_size_t mpz_abs_sub_ui (mpz_t r, const mpz_t a, uint64_t b)
3896{
3897 mp_size_t an = GMP_ABS (a->_mp_size);
3898 mp_ptr rp = MPZ_REALLOC (r, an);
3899
3900 if (an == 0)
3901 {
3902 rp[0] = b;
3903 return -(b > 0);
3904 }
3905 else if (an == 1 && a->_mp_d[0] < b)
3906 {
3907 rp[0] = b - a->_mp_d[0];
3908 return -1;
3909 }
3910 else
3911 {
3912 gmp_assert_nocarry (mpn_sub_1 (rp, a->_mp_d, an, b));
3913 return mpn_normalized_size (rp, an);
3914 }
3915}
3916
3917void mpz_sub_ui (mpz_t r, const mpz_t a, uint64_t b)
3918{
3919 if (a->_mp_size < 0)
3920 r->_mp_size = (int)-mpz_abs_add_ui (r, a, b);
3921 else
3922 r->_mp_size = (int)mpz_abs_sub_ui (r, a, b);
3923}
3924
3925void mpz_add (mpz_t r, const mpz_t a, const mpz_t b)
3926{
3927 mp_size_t rn;
3928
3929 if ( (a->_mp_size ^ b->_mp_size) >= 0)
3930 rn = mpz_abs_add (r, a, b);
3931 else
3932 rn = mpz_abs_sub (r, a, b);
3933
3934 r->_mp_size = (int32_t)(a->_mp_size >= 0 ? rn : - rn);
3935}
3936
3937void mpz_add_ui (mpz_t r, const mpz_t a, uint64_t b)
3938{
3939 if (a->_mp_size >= 0)
3940 r->_mp_size = (int32_t)mpz_abs_add_ui (r, a, b);
3941 else
3942 r->_mp_size = (int32_t)-mpz_abs_sub_ui (r, a, b);
3943}
3944
3945/* The utility of this function is a bit limited, since many functions
3946 assigns the result variable using mpz_swap. */
3947void mpz_init2 (mpz_t r, mp_bitcnt_t bits)
3948{
3949 mp_size_t rn;
3950
3951 bits -= (bits != 0); /* Round down, except if 0 */
3952 rn = 1 + bits / GMP_LIMB_BITS;
3953
3954 r->_mp_alloc = (int32_t)rn;
3955 r->_mp_size = 0;
3956 r->_mp_d = gmp_xalloc_limbs (rn);
3957}
3958
3959void mpz_set_ui (mpz_t r, uint64_t x)
3960{
3961 if (x > 0)
3962 {
3963 r->_mp_size = 1;
3964 r->_mp_d[0] = x;
3965 }
3966 else
3967 r->_mp_size = 0;
3968}
3969
3970void mpz_set_si (mpz_t r, int64_t x)
3971{
3972 if (x >= 0)
3973 mpz_set_ui (r, x);
3974 else /* (x < 0) */
3975 {
3976 r->_mp_size = -1;
3977 r->_mp_d[0] = GMP_NEG_CAST (uint64_t, x);
3978 }
3979}
3980
3981void mpz_swap (mpz_t u, mpz_t v)
3982{
3983 MP_SIZE_sT_SWAP (u->_mp_size, v->_mp_size);
3984 MP_SIZE_sT_SWAP (u->_mp_alloc, v->_mp_alloc);
3985 MP_PTR_SWAP (u->_mp_d, v->_mp_d);
3986}
3987
3988// Allows q or r to be zero. Returns 1 iff remainder is non-zero.
3989static int mpz_div_qr (mpz_t q, mpz_t r,const mpz_t n, const mpz_t d, enum mpz_div_round_mode mode)
3990{
3991 mp_size_t ns, ds, nn, dn, qs;
3992 ns = n->_mp_size;
3993 ds = d->_mp_size;
3994
3995 if (ds == 0)
3996 gmp_die("mpz_div_qr: Divide by zero.");
3997
3998 if (ns == 0)
3999 {
4000 if (q)
4001 q->_mp_size = 0;
4002 if (r)
4003 r->_mp_size = 0;
4004 return 0;
4005 }
4006
4007 nn = GMP_ABS (ns);
4008 dn = GMP_ABS (ds);
4009
4010 qs = ds ^ ns;
4011
4012 if (nn < dn)
4013 {
4014 if (mode == GMP_DIV_CEIL && qs >= 0)
4015 {
4016 /* q = 1, r = n - d */
4017 if (r)
4018 mpz_sub (r, n, d);
4019 if (q)
4020 mpz_set_ui (q, 1);
4021 }
4022 else if (mode == GMP_DIV_FLOOR && qs < 0)
4023 {
4024 /* q = -1, r = n + d */
4025 if (r)
4026 mpz_add (r, n, d);
4027 if (q)
4028 mpz_set_si (q, -1);
4029 }
4030 else
4031 {
4032 /* q = 0, r = d */
4033 if (r)
4034 mpz_set (r, n);
4035 if (q)
4036 q->_mp_size = 0;
4037 }
4038 return 1;
4039 }
4040 else
4041 {
4042 mp_ptr np, qp;
4043 mp_size_t qn, rn;
4044 mpz_t tq, tr;
4045
4046 mpz_init_set (tr, n);
4047 np = tr->_mp_d;
4048
4049 qn = nn - dn + 1;
4050
4051 if (q)
4052 {
4053 mpz_init2 (tq, qn * GMP_LIMB_BITS);
4054 qp = tq->_mp_d;
4055 }
4056 else
4057 qp = NULL;
4058
4059 mpn_div_qr (qp, np, nn, d->_mp_d, dn);
4060
4061 if (qp)
4062 {
4063 qn -= (qp[qn-1] == 0);
4064
4065 tq->_mp_size = (uint32_t)(qs < 0 ? -qn : qn);
4066 }
4067 rn = mpn_normalized_size (np, dn);
4068 tr->_mp_size = (uint32_t)(ns < 0 ? - rn : rn);
4069
4070 if (mode == GMP_DIV_FLOOR && qs < 0 && rn != 0)
4071 {
4072 if (q)
4073 mpz_sub_ui (tq, tq, 1);
4074 if (r)
4075 mpz_add (tr, tr, d);
4076 }
4077 else if (mode == GMP_DIV_CEIL && qs >= 0 && rn != 0)
4078 {
4079 if (q)
4080 mpz_add_ui (tq, tq, 1);
4081 if (r)
4082 mpz_sub (tr, tr, d);
4083 }
4084
4085 if (q)
4086 {
4087 mpz_swap (tq, q);
4088 mpz_clear (tq);
4089 }
4090 if (r)
4091 mpz_swap (tr, r);
4092
4093 mpz_clear (tr);
4094
4095 return rn != 0;
4096 }
4097}
4098
4099void mpz_cdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
4100{
4101 mpz_div_qr (q, r, n, d, GMP_DIV_CEIL);
4102}
4103
4104uint64_t mpz_get_ui (const mpz_t u)
4105{
4106 return u->_mp_size == 0 ? 0 : u->_mp_d[0];
4107}
4108
4109void mpz_tdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
4110{
4111 mpz_div_qr (q, r, n, d, GMP_DIV_TRUNC);
4112}
4113
4114void mpz_init_set_ui (mpz_t r, uint64_t x)
4115{
4116 mpz_init (r);
4117 mpz_set_ui (r, x);
4118}
4119
4120mp_limb_t mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
4121{
4122 mp_limb_t ul, cl, hpl, lpl, rl;
4123
4124 assert (n >= 1);
4125
4126 cl = 0;
4127 do
4128 {
4129 ul = *up++;
4130 gmp_umul_ppmm (hpl, lpl, ul, vl);
4131
4132 lpl += cl;
4133 cl = (lpl < cl) + hpl;
4134
4135 rl = *rp;
4136 lpl = rl + lpl;
4137 cl += lpl < rl;
4138 *rp++ = lpl;
4139 }
4140 while (--n != 0);
4141
4142 return cl;
4143}
4144
4145mp_limb_t mpn_mul (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
4146{
4147 assert (un >= vn);
4148 assert (vn >= 1);
4149
4150 /* We first multiply by the low order limb. This result can be
4151 stored, not added, to rp. We also avoid a loop for zeroing this
4152 way. */
4153
4154 rp[un] = mpn_mul_1 (rp, up, un, vp[0]);
4155
4156 /* Now accumulate the product of up[] and the next higher limb from
4157 vp[]. */
4158
4159 while (--vn >= 1)
4160 {
4161 rp += 1, vp += 1;
4162 rp[un] = mpn_addmul_1 (rp, up, un, vp[0]);
4163 }
4164 return rp[un];
4165}
4166
4167void mpz_mul (mpz_t r, const mpz_t u, const mpz_t v)
4168{
4169 int sign;
4170 mp_size_t un, vn, rn;
4171 mpz_t t;
4172 mp_ptr tp;
4173
4174 un = u->_mp_size;
4175 vn = v->_mp_size;
4176
4177 if (un == 0 || vn == 0)
4178 {
4179 r->_mp_size = 0;
4180 return;
4181 }
4182
4183 sign = (un ^ vn) < 0;
4184
4185 un = GMP_ABS (un);
4186 vn = GMP_ABS (vn);
4187
4188 mpz_init2 (t, (un + vn) * GMP_LIMB_BITS);
4189
4190 tp = t->_mp_d;
4191 if (un >= vn)
4192 mpn_mul (tp, u->_mp_d, un, v->_mp_d, vn);
4193 else
4194 mpn_mul (tp, v->_mp_d, vn, u->_mp_d, un);
4195
4196 rn = un + vn;
4197 rn -= tp[rn-1] == 0;
4198
4199 t->_mp_size = (int32_t)(sign ? - rn : rn);
4200 mpz_swap (r, t);
4201 mpz_clear (t);
4202}
4203void mpz_mul_ui (mpz_t r, const mpz_t u, uint64_t v)
4204{
4205 mp_size_t un, us; mp_ptr tp; mp_limb_t cy;
4206
4207 us = u->_mp_size;
4208 if (us == 0 || v == 0)
4209 {
4210 r->_mp_size = 0;
4211 return;
4212 }
4213 un = GMP_ABS (us);
4214 tp = MPZ_REALLOC (r, un + 1);
4215 cy = mpn_mul_1 (tp, u->_mp_d, un, v);
4216 tp[un] = cy;
4217 un += (cy > 0);
4218 r->_mp_size = (int32_t)((us < 0) ? -un : un);
4219}
4220
4221static mp_limb_t mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d)
4222{
4223 assert (d > 0);
4224 // Special case for powers of two.
4225 if ((d & (d-1)) == 0)
4226 {
4227 mp_limb_t r = np[0] & (d-1);
4228 if (qp)
4229 {
4230 if (d <= 1)
4231 mpn_copyi (qp, np, nn);
4232 else
4233 {
4234 uint64_t shift;
4235 gmp_ctz (shift, d);
4236 mpn_rshift (qp, np, nn, (uint32_t)shift);
4237 }
4238 }
4239 return r;
4240 }
4241 else
4242 {
4243 struct gmp_div_inverse inv;
4244 mpn_div_qr_1_invert (&inv, d);
4245 return mpn_div_qr_1_preinv (qp, np, nn, &inv);
4246 }
4247}
4248
4249static uint64_t mpz_div_qr_ui (mpz_t q, mpz_t r,const mpz_t n, uint64_t d, enum mpz_div_round_mode mode)
4250{
4251 mp_size_t ns,qn; mp_ptr qp; mp_limb_t rl; mp_size_t rs;
4252 ns = n->_mp_size;
4253 if (ns == 0)
4254 {
4255 if (q)
4256 q->_mp_size = 0;
4257 if (r)
4258 r->_mp_size = 0;
4259 return 0;
4260 }
4261 qn = GMP_ABS (ns);
4262 if (q)
4263 qp = MPZ_REALLOC (q, qn);
4264 else qp = NULL;
4265 rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d);
4266 assert (rl < d);
4267 rs = rl > 0;
4268 rs = (ns < 0) ? -rs : rs;
4269 if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0) || (mode == GMP_DIV_CEIL && ns >= 0)))
4270 {
4271 if (q)
4272 gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1));
4273 rl = d - rl;
4274 rs = -rs;
4275 }
4276 if (r)
4277 {
4278 r->_mp_d[0] = rl;
4279 r->_mp_size = (int32_t)rs;
4280 }
4281 if (q)
4282 {
4283 qn -= (qp[qn-1] == 0);
4284 assert (qn == 0 || qp[qn-1] > 0);
4285 q->_mp_size = (int32_t)((ns < 0) ? -qn : qn);
4286 }
4287 return rl;
4288}
4289
4290uint64_t mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d)
4291{
4292 return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC);
4293}
4294
4295void mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n)
4296{
4297 while (--n >= 0)
4298 d[n] = s[n];
4299}
4300
4301void mpn_zero(mp_ptr rp, mp_size_t n)
4302{
4303 while (--n >= 0)
4304 rp[n] = 0;
4305}
4306
4307void mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits)
4308{
4309 mp_size_t un,rn,limbs; uint32_t shift; mp_ptr rp;
4310 un = GMP_ABS (u->_mp_size);
4311 if (un == 0)
4312 {
4313 r->_mp_size = 0;
4314 return;
4315 }
4316 limbs = bits / GMP_LIMB_BITS;
4317 shift = bits % GMP_LIMB_BITS;
4318 rn = un + limbs + (shift > 0);
4319 rp = MPZ_REALLOC (r, rn);
4320 if (shift > 0)
4321 {
4322 mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift);
4323 rp[rn-1] = cy;
4324 rn -= (cy == 0);
4325 }
4326 else mpn_copyd (rp + limbs, u->_mp_d, un);
4327 mpn_zero (rp, limbs);
4328 r->_mp_size = (int32_t)((u->_mp_size < 0) ? - rn : rn);
4329}
4330
4331#include <stdint.h>
4332
4333static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
4334
4335char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen)
4336{
4337 mpz_t bn0,bn58,dv,rem,bn; char rs[128]; int32_t i,n=0;
4338 //mpz_init_set_str(bn58,"58",10);
4339 //mpz_init_set_str(bn0,"0",10);
4340 mpz_init_set_ui(bn58,58);
4341 mpz_init_set_ui(bn0,0);
4342 mpz_init(dv), mpz_init(rem), mpz_init(bn);
4343 mpz_import(bn,datalen,1,sizeof(data[0]),0,0,data);
4344 while ( mpz_cmp(bn,bn0) > 0 )
4345 {
4346 mpz_tdiv_qr(bn,rem,bn,bn58);
4347 rs[n++] = base58_chars[mpz_get_ui(rem)];
4348 }
4349 for (i=0; i<datalen; i++)
4350 {
4351 if ( data[i] == 0 )
4352 rs[n++] = base58_chars[0];
4353 else break;
4354 }
4355 for (i=0; i<n; i++)
4356 coinaddr[n - i - 1] = rs[i];
4357 coinaddr[n] = 0;
4358 mpz_clear(bn0), mpz_clear(bn58), mpz_clear(dv), mpz_clear(rem), mpz_clear(bn);
4359 return(coinaddr);
4360}
4361
4362int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr)
4363{
4364 uint32_t zeroes,be_sz=0; size_t count; const char *p,*p1; mpz_t bn58,bn;
4365 mpz_init_set_ui(bn58,58);
4366 mpz_init_set_ui(bn,0);
4367 while ( isspace((uint32_t)(*coinaddr & 0xff)) )
4368 coinaddr++;
4369 for (p=coinaddr; *p; p++)
4370 {
4371 p1 = strchr(base58_chars,*p);
4372 if ( p1 == 0 )
4373 {
4374 while (isspace((uint32_t)*p))
4375 p++;
4376 if ( *p != '\0' )
4377 {
4378 mpz_clear(bn), mpz_clear(bn58);
4379 return(-1);
4380 }
4381 break;
4382 }
4383 mpz_mul(bn,bn,bn58);
4384 mpz_add_ui(bn,bn,(int32_t)(p1 - base58_chars));
4385 }
4386 zeroes = 0;
4387 for (p=coinaddr; *p==base58_chars[0]; p++)
4388 data[zeroes++] = 0;
4389 mpz_export(data+zeroes,&count,1,sizeof(data[0]),-1,0,bn);
4390 if ( count >= 2 && data[count - 1] == 0 && data[count - 2] >= 0x80 )
4391 count--;
4392 be_sz = (uint32_t)count + (uint32_t)zeroes;
4393 //memset(data,0,be_sz);
4394 //for (i=0; i<count; i++)
4395 // data[i+zeroes] = revdata[count - 1 - i];
4396 //printf("len.%d be_sz.%d zeroes.%d data[0] %02x %02x\n",be_sz+zeroes,be_sz,zeroes,data[0],data[1]);
4397 mpz_clear(bn), mpz_clear(bn58);
4398 return(be_sz);
4399}
4400
e826da69 4401//#include "../includes/curve25519.h"
d019c447 4402
4403void mpz_from_bits256(mpz_t bn,bits256 x)
4404{
4405 int32_t i;
4406 mpz_init_set_ui(bn,x.ulongs[3]);
4407 for (i=2; i>=0; i--)
4408 {
4409 mpz_mul_2exp(bn,bn,64);
4410 if ( x.ulongs[i] != 0 )
4411 mpz_add_ui(bn,bn,x.ulongs[i]);
4412 }
4413}
4414
4415bits256 mpz_to_bits256(mpz_t bn)
4416{
4417 bits256 x,rev; size_t count; int32_t i;
4418 mpz_export(rev.bytes,&count,1,sizeof(uint64_t),1,0,bn);
4419 for (i=0; i<32; i++)
4420 x.bytes[i] = rev.bytes[31-i];
4421 return(x);
4422}
4423
4424bits256 mpz_muldivcmp(bits256 oldval,int32_t mulval,int32_t divval,bits256 targetval)
4425{
4426 mpz_t bn,target; bits256 newval;
4427 //printf("mulval.%d divval.%d]\n",mulval,divval);
4428 mpz_init(bn), mpz_init(target);
4429 mpz_from_bits256(bn,oldval);
4430 mpz_mul_ui(bn,bn,mulval);
4431 mpz_tdiv_qr_ui(bn,NULL,bn,divval);
4432 if ( bn->_mp_size <= 0 || mpz_cmp(bn,target) > 0 )
4433 newval = targetval;
4434 newval = mpz_to_bits256(bn);
4435 //char *bits256_str(char *,bits256);
4436 //char str[65],str2[65]; printf("%s mul.%d div.%d -> %s size.%d\n",bits256_str(str,oldval),mulval,divval,bits256_str(str2,newval),bn->_mp_size);
4437 mpz_clear(bn), mpz_clear(target);
4438 return(newval);
4439}
4440
4441bits256 mpz_div64(bits256 hash,uint64_t divval)
4442{
4443 mpz_t bn; bits256 newval;
4444 mpz_init(bn);
4445 mpz_from_bits256(bn,hash);
4446 mpz_tdiv_qr_ui(bn,NULL,bn,divval);
4447 newval = mpz_to_bits256(bn);
4448 //char *bits256_str(char *,bits256);
4449 //char str[65],str2[65]; printf("%s div.%lld -> %s size.%d\n",bits256_str(str,hash),(long long)divval,bits256_str(str2,newval),bn->_mp_size);
4450 mpz_clear(bn);
4451 return(newval);
4452}
This page took 0.53433 seconds and 4 git commands to generate.