libgmp.h - libzahl - big integer library
(HTM) git clone git://git.suckless.org/libzahl
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
libgmp.h (5179B)
---
1 #define __GMP_NO_ATTRIBUTE_CONST_PURE
2
3 #include <gmp.h>
4
5 #include <setjmp.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #define BIGINT_LIBRARY "GMP"
12
13 typedef mpz_t z_t;
14
15 static z_t _0, _1, _a, _b;
16 static FILE *_fbuf;
17 static gmp_randstate_t _randstate;
18
19 static inline void
20 zsetup(jmp_buf env)
21 {
22 static char buf[1000];
23 (void) env;
24 mpz_init_set_ui(_0, 0);
25 mpz_init_set_ui(_1, 1);
26 mpz_init(_a);
27 mpz_init(_b);
28 _fbuf = fmemopen(buf, sizeof(buf), "r+");
29 gmp_randinit_mt(_randstate);
30 }
31
32 static inline void
33 zunsetup(void)
34 {
35 mpz_clear(_0);
36 mpz_clear(_1);
37 mpz_clear(_a);
38 mpz_clear(_b);
39 fclose(_fbuf);
40 gmp_randclear(_randstate);
41 }
42
43 #define FAST_RANDOM 0
44 #define SECURE_RANDOM 0
45 #define DEFAULT_RANDOM 0
46 #define FASTEST_RANDOM 0
47 #define LIBC_RAND_RANDOM 0
48 #define LIBC_RANDOM_RANDOM 0
49 #define LIBC_RAND48_RANDOM 0
50 #define QUASIUNIFORM 0
51 #define UNIFORM 1
52 #define MODUNIFORM 2
53
54 #define zperror(x) ((void)0)
55 #define zinit mpz_init
56 #define zfree mpz_clear
57
58 #define zset mpz_set
59 #define zneg mpz_neg
60 #define zabs mpz_abs
61 #define zadd_unsigned(r, a, b) (zabs(_a, a), zabs(_b, b), mpz_add(r, _a, _b))
62 #define zsub_unsigned(r, a, b) (zabs(_a, a), zabs(_b, b), mpz_sub(r, _a, _b))
63 #define zadd mpz_add
64 #define zsub mpz_sub
65 #define zand mpz_and
66 #define zor mpz_ior
67 #define zxor mpz_xor
68 #define zbtest mpz_tstbit
69 #define zeven_nonzero zeven
70 #define zodd_nonzero zodd
71 #define zzero(a) (!mpz_sgn(a))
72 #define zsignum mpz_sgn
73 #define zbits(a) mpz_sizeinbase(a, 2)
74 #define zlsb(a) mpz_scan1(a, 0)
75 #define zswap mpz_swap
76 #define zlsh mpz_mul_2exp
77 #define zrsh mpz_tdiv_q_2exp
78 #define ztrunc mpz_tdiv_r_2exp
79 #define zcmpmag mpz_cmpabs
80 #define zcmp mpz_cmp
81 #define zcmpi(a, b) (zseti(_b, b), zcmp(a, _b))
82 #define zcmpu(a, b) (zsetu(_b, b), zcmp(a, _b))
83 #define zgcd mpz_gcd
84 #define zmul mpz_mul
85 #define zsqr(r, a) mpz_mul(r, a, a)
86 #define zmodmul(r, a, b, m) (zmul(r, a, b), zmod(r, r, m))
87 #define zmodsqr(r, a, m) (zsqr(r, a), zmod(r, r, m))
88 #define zpow(r, a, b) mpz_pow_ui(r, a, mpz_get_ui(b))
89 #define zpowu mpz_pow_ui
90 #define zmodpow mpz_powm
91 #define zmodpowu mpz_powm_ui
92 #define zsets(a, s) mpz_set_str(a, s, 10)
93 #define zstr_length(a, b) (mpz_sizeinbase(a, 10) + (zsignum(a) < 0))
94 #define zstr(a, s, n) (mpz_get_str(s, 10, a))
95 #define zptest(w, a, t) mpz_probab_prime_p(a, t) /* Note, the witness is not returned. */
96 #define zdiv mpz_tdiv_q
97 #define zmod mpz_tdiv_r
98 #define zdivmod mpz_tdiv_qr
99
100 static inline int
101 zeven(z_t a)
102 {
103 return mpz_even_p(a);
104 }
105
106 static inline int
107 zodd(z_t a)
108 {
109 return mpz_odd_p(a);
110 }
111
112 static inline void
113 zsetu(z_t r, unsigned long long int val)
114 {
115 uint32_t high = (uint32_t)(val >> 32);
116 uint32_t low = (uint32_t)val;
117
118 if (high) {
119 mpz_set_ui(r, high);
120 mpz_set_ui(_a, low);
121 zlsh(r, r, 32);
122 zadd(r, r, _a);
123 } else {
124 mpz_set_ui(r, low);
125 }
126
127 }
128
129 static inline void
130 zseti(z_t r, long long int val)
131 {
132 if (val >= 0) {
133 zsetu(r, (unsigned long long int)val);
134 } else {
135 zsetu(r, (unsigned long long int)-val);
136 zneg(r, r);
137 }
138 }
139
140 static inline void
141 znot(z_t r, z_t a)
142 {
143 size_t bits = zbits(a);
144 mpz_set_ui(_b, 0);
145 mpz_setbit(_b, bits);
146 zsub(_b, _b, _1);
147 zxor(r, a, _b);
148 zneg(r, r);
149 }
150
151 static inline void
152 zsplit(z_t high, z_t low, z_t a, size_t brk)
153 {
154 if (low == a) {
155 zrsh(high, a, brk);
156 ztrunc(low, a, brk);
157 } else {
158 ztrunc(low, a, brk);
159 zrsh(high, a, brk);
160 }
161 }
162
163 static inline void
164 zbset(z_t r, z_t a, size_t bit, int mode)
165 {
166 if (r != a)
167 zset(r, a);
168 if (mode > 0)
169 mpz_setbit(r, bit);
170 else if (mode == 0)
171 mpz_clrbit(r, bit);
172 else
173 mpz_combit(r, bit);
174 }
175
176 static inline size_t
177 zsave(z_t a, void *buffer)
178 {
179 size_t n = mpz_out_raw(_fbuf, a);
180 (void)buffer;
181 fseek(_fbuf, -(long)n, SEEK_CUR);
182 return n;
183 }
184
185 static inline size_t
186 zload(z_t a, const void *buffer)
187 {
188 size_t n = mpz_inp_raw(a, _fbuf);
189 (void)buffer;
190 fseek(_fbuf, -(long)n, SEEK_CUR);
191 return n;
192 }
193
194 static inline void
195 zrand(z_t r, int dev, int dist, z_t n)
196 {
197 size_t bits;
198 (void) dev;
199
200 if (zzero(n)) {
201 mpz_set_ui(r, 0);
202 return;
203 }
204 if (zsignum(n) < 0) {
205 return;
206 }
207
208 switch (dist) {
209 case QUASIUNIFORM:
210 bits = zbits(n);
211 mpz_urandomb(r, _randstate, bits);
212 zadd(r, r, _1);
213 zmul(r, r, n);
214 zrsh(r, r, bits);
215 break;
216
217 case UNIFORM: /* Note, n is exclusive in this implementation. */
218 mpz_urandomm(r, _randstate, n);
219 break;
220
221 case MODUNIFORM:
222 bits = zbits(n);
223 mpz_urandomb(r, _randstate, bits);
224 if (zcmp(r, n) > 0)
225 zsub(r, r, n);
226 break;
227
228 default:
229 abort();
230 }
231 }