libgmp.h - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
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… | |
62 #define zsub_unsigned(r, a, b) (zabs(_a, a), zabs(_b, b), mpz_sub(r, _a… | |
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 wi… | |
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 } |