libtommath.h - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
libtommath.h (6423B) | |
--- | |
1 #include <tommath.h> | |
2 | |
3 #include <setjmp.h> | |
4 #include <stddef.h> | |
5 #include <stdint.h> | |
6 #include <stdio.h> | |
7 | |
8 #define BIGINT_LIBRARY "libtommath" | |
9 | |
10 #define FAST_RANDOM 0 | |
11 #define SECURE_RANDOM 0 | |
12 #define DEFAULT_RANDOM 0 | |
13 #define FASTEST_RANDOM 0 | |
14 #define LIBC_RAND_RANDOM 0 | |
15 #define LIBC_RANDOM_RANDOM 0 | |
16 #define LIBC_RAND48_RANDOM 0 | |
17 #define QUASIUNIFORM 0 | |
18 #define UNIFORM 1 | |
19 #define MODUNIFORM 2 | |
20 | |
21 typedef mp_int z_t[1]; | |
22 | |
23 static z_t _0, _1, _a, _b; | |
24 static int _tmp, error; | |
25 static jmp_buf jbuf; | |
26 | |
27 #ifdef ZAHL_UNSAFE | |
28 # define try(expr) (expr) | |
29 #else | |
30 # define try(expr) do if ((error = (expr))) longjmp(jbuf, 1); while (0) | |
31 #endif | |
32 | |
33 static inline void | |
34 zsetup(jmp_buf env) | |
35 { | |
36 *jbuf = *env; | |
37 try(mp_init_set_int(_0, 0)); | |
38 try(mp_init_set_int(_1, 1)); | |
39 try(mp_init(_a)); | |
40 try(mp_init(_b)); | |
41 } | |
42 | |
43 static inline void | |
44 zunsetup(void) | |
45 { | |
46 mp_clear(_0); | |
47 mp_clear(_1); | |
48 mp_clear(_a); | |
49 mp_clear(_b); | |
50 } | |
51 | |
52 static inline void | |
53 zperror(const char *str) | |
54 { | |
55 if (str && *str) | |
56 fprintf(stderr, "%s: %s\n", str, mp_error_to_string(erro… | |
57 else | |
58 fprintf(stderr, "%s\n", mp_error_to_string(error)); | |
59 } | |
60 | |
61 static inline void | |
62 zinit(z_t a) | |
63 { | |
64 try(mp_init(a)); | |
65 } | |
66 | |
67 static inline void | |
68 zfree(z_t a) | |
69 { | |
70 mp_clear(a); | |
71 } | |
72 | |
73 static inline void | |
74 zset(z_t r, z_t a) | |
75 { | |
76 try(mp_copy(a, r)); | |
77 } | |
78 | |
79 static inline void | |
80 zneg(z_t r, z_t a) | |
81 { | |
82 try(mp_neg(a, r)); | |
83 } | |
84 | |
85 static inline void | |
86 zabs(z_t r, z_t a) | |
87 { | |
88 try(mp_abs(a, r)); | |
89 } | |
90 | |
91 static inline void | |
92 zadd(z_t r, z_t a, z_t b) | |
93 { | |
94 try(mp_add(a, b, r)); | |
95 } | |
96 | |
97 static inline void | |
98 zsub(z_t r, z_t a, z_t b) | |
99 { | |
100 try(mp_sub(a, b, r)); | |
101 } | |
102 | |
103 static inline void | |
104 zadd_unsigned(z_t r, z_t a, z_t b) | |
105 { | |
106 zabs(_a, a); | |
107 zabs(_b, b); | |
108 zadd(r, _a, _b); | |
109 } | |
110 | |
111 static inline void | |
112 zsub_unsigned(z_t r, z_t a, z_t b) | |
113 { | |
114 zabs(_a, a); | |
115 zabs(_b, b); | |
116 zsub(r, _a, _b); | |
117 } | |
118 | |
119 static inline size_t | |
120 zbits(z_t a) | |
121 { | |
122 return mp_count_bits(a); | |
123 } | |
124 | |
125 static inline size_t | |
126 zlsb(z_t a) | |
127 { | |
128 return mp_cnt_lsb(a); | |
129 } | |
130 | |
131 static inline int | |
132 zeven(z_t a) | |
133 { | |
134 return mp_iseven(a); | |
135 } | |
136 | |
137 static inline int | |
138 zodd(z_t a) | |
139 { | |
140 return mp_isodd(a); | |
141 } | |
142 | |
143 static inline int | |
144 zeven_nonzero(z_t a) | |
145 { | |
146 return zeven(a); | |
147 } | |
148 | |
149 static inline int | |
150 zodd_nonzero(z_t a) | |
151 { | |
152 return zodd(a); | |
153 } | |
154 | |
155 static inline int | |
156 zzero(z_t a) | |
157 { | |
158 return mp_iszero(a); | |
159 } | |
160 | |
161 static inline void | |
162 zand(z_t r, z_t a, z_t b) | |
163 { | |
164 try(mp_and(a, b, r)); | |
165 } | |
166 | |
167 static inline void | |
168 zor(z_t r, z_t a, z_t b) | |
169 { | |
170 try(mp_or(a, b, r)); | |
171 } | |
172 | |
173 static inline void | |
174 zxor(z_t r, z_t a, z_t b) | |
175 { | |
176 try(mp_xor(a, b, r)); | |
177 } | |
178 | |
179 static inline void | |
180 znot(z_t r, z_t a) | |
181 { | |
182 try(mp_2expt(_a, (int)zbits(a))); | |
183 try(mp_sub_d(_a, 1, _a)); | |
184 zand(r, a, _a); | |
185 zneg(r, r); | |
186 } | |
187 | |
188 static inline int | |
189 zbtest(z_t a, size_t bit) | |
190 { | |
191 try(mp_2expt(_b, (int)bit)); | |
192 zand(_b, a, _b); | |
193 return !zzero(_b); | |
194 } | |
195 | |
196 static inline void | |
197 zbset(z_t r, z_t a, size_t bit, int mode) | |
198 { | |
199 if (mode > 0) { | |
200 try(mp_2expt(_b, (int)bit)); | |
201 zor(r, a, _b); | |
202 } else if (mode < 0 || zbtest(a, bit)) { | |
203 try(mp_2expt(_b, (int)bit)); | |
204 zxor(r, a, _b); | |
205 } | |
206 } | |
207 | |
208 static inline void | |
209 zswap(z_t a, z_t b) | |
210 { | |
211 mp_exch(a, b); | |
212 } | |
213 | |
214 static inline void | |
215 zlsh(z_t r, z_t a, size_t b) | |
216 { | |
217 try(mp_mul_2d(a, (int)b, r)); | |
218 } | |
219 | |
220 static inline void | |
221 zrsh(z_t r, z_t a, size_t b) | |
222 { | |
223 try(mp_div_2d(a, (int)b, r, 0)); | |
224 } | |
225 | |
226 static inline void | |
227 ztrunc(z_t r, z_t a, size_t b) | |
228 { | |
229 try(mp_mod_2d(a, (int)b, r)); | |
230 } | |
231 | |
232 static inline void | |
233 zsplit(z_t high, z_t low, z_t a, size_t brk) | |
234 { | |
235 if (low == a) { | |
236 zrsh(high, a, brk); | |
237 ztrunc(low, a, brk); | |
238 } else { | |
239 ztrunc(low, a, brk); | |
240 zrsh(high, a, brk); | |
241 } | |
242 } | |
243 | |
244 static inline void | |
245 zsetu(z_t r, unsigned long long int val) | |
246 { | |
247 try(mp_set_long_long(r, val)); | |
248 } | |
249 | |
250 static inline void | |
251 zseti(z_t r, long long int val) | |
252 { | |
253 if (val >= 0) { | |
254 zsetu(r, (unsigned long long int)val); | |
255 } else { | |
256 zsetu(r, (unsigned long long int)-val); | |
257 zneg(r, r); | |
258 } | |
259 } | |
260 | |
261 static inline int | |
262 zcmpmag(z_t a, z_t b) | |
263 { | |
264 return mp_cmp_mag(a, b); | |
265 } | |
266 | |
267 static inline int | |
268 zcmp(z_t a, z_t b) | |
269 { | |
270 return mp_cmp(a, b); | |
271 } | |
272 | |
273 static inline int | |
274 zcmpi(z_t a, long long int b) | |
275 { | |
276 zseti(_b, b); | |
277 return zcmp(a, _b); | |
278 } | |
279 | |
280 static inline int | |
281 zcmpu(z_t a, unsigned long long int b) | |
282 { | |
283 zsetu(_b, b); | |
284 return zcmp(a, _b); | |
285 } | |
286 | |
287 static inline int | |
288 zsignum(z_t a) | |
289 { | |
290 return zcmp(a, _0); | |
291 } | |
292 | |
293 static inline void | |
294 zgcd(z_t r, z_t a, z_t b) | |
295 { | |
296 try(mp_gcd(a, b, r)); | |
297 } | |
298 | |
299 static inline void | |
300 zmul(z_t r, z_t a, z_t b) | |
301 { | |
302 try(mp_mul(a, b, r)); | |
303 } | |
304 | |
305 static inline void | |
306 zsqr(z_t r, z_t a) | |
307 { | |
308 try(mp_sqr(a, r)); | |
309 } | |
310 | |
311 static inline void | |
312 zmodmul(z_t r, z_t a, z_t b, z_t m) | |
313 { | |
314 try(mp_mulmod(a, b, m, r)); | |
315 } | |
316 | |
317 static inline void | |
318 zmodsqr(z_t r, z_t a, z_t m) | |
319 { | |
320 try(mp_sqrmod(a, m, r)); | |
321 } | |
322 | |
323 static inline void | |
324 zpow(z_t r, z_t a, z_t b) | |
325 { | |
326 try(mp_expt_d(a, (mp_digit)mp_get_int(b), r)); | |
327 } | |
328 | |
329 static inline void | |
330 zpowu(z_t r, z_t a, unsigned long long int b) | |
331 { | |
332 try(mp_expt_d(a, (mp_digit)b, r)); | |
333 } | |
334 | |
335 static inline void | |
336 zmodpow(z_t r, z_t a, z_t b, z_t m) | |
337 { | |
338 try(mp_exptmod(a, b, m, r)); | |
339 } | |
340 | |
341 static inline void | |
342 zmodpowu(z_t r, z_t a, unsigned long long int b, z_t m) | |
343 { | |
344 try(mp_set_int(_b, b)); | |
345 try(mp_exptmod(a, _b, m, r)); | |
346 } | |
347 | |
348 static inline void | |
349 zsets(z_t a, const char *s) | |
350 { | |
351 try(mp_read_radix(a, s, 10)); | |
352 } | |
353 | |
354 static inline size_t | |
355 zstr_length(z_t a, size_t b) | |
356 { | |
357 try(mp_radix_size(a, b, &_tmp)); | |
358 return _tmp; | |
359 } | |
360 | |
361 static inline char * | |
362 zstr(z_t a, char *s, size_t n) | |
363 { | |
364 try(mp_toradix(a, s, 10)); | |
365 return s; | |
366 (void) n; | |
367 } | |
368 | |
369 static inline int | |
370 zptest(z_t w, z_t a, int t) | |
371 { | |
372 try(mp_prime_is_prime(a, t, &_tmp)); | |
373 return _tmp; | |
374 (void) w; /* Note, the witness is not returned. */ | |
375 } | |
376 | |
377 static inline size_t | |
378 zsave(z_t a, char *b) | |
379 { | |
380 _tmp = !b ? mp_signed_bin_size(a) : mp_to_signed_bin(a, (unsigne… | |
381 return _tmp; | |
382 } | |
383 | |
384 static inline size_t | |
385 zload(z_t a, const char *b) /* Note, requires that zsave was called dire… | |
386 { | |
387 return mp_read_signed_bin(a, (const unsigned char *)b, _tmp); | |
388 } | |
389 | |
390 static inline void | |
391 zdiv(z_t r, z_t a, z_t b) | |
392 { | |
393 try(mp_div(a, b, r, 0)); | |
394 } | |
395 | |
396 static inline void | |
397 zmod(z_t r, z_t a, z_t b) | |
398 { | |
399 try(mp_mod(a, b, r)); | |
400 } | |
401 | |
402 static inline void | |
403 zdivmod(z_t q, z_t r, z_t a, z_t b) | |
404 { | |
405 try(mp_div(a, b, q, r)); | |
406 } | |
407 | |
408 static inline void | |
409 zrand(z_t r, int dev, int dist, z_t n) | |
410 { | |
411 static int gave_up = 0; | |
412 int bits; | |
413 (void) dev; | |
414 | |
415 if (zzero(n)) { | |
416 mp_zero(r); | |
417 return; | |
418 } | |
419 if (zsignum(n) < 0) { | |
420 return; | |
421 } | |
422 | |
423 bits = zbits(n); | |
424 | |
425 switch (dist) { | |
426 case QUASIUNIFORM: | |
427 try(mp_rand(r, bits)); | |
428 zadd(r, r, _1); | |
429 zmul(r, r, n); | |
430 zrsh(r, r, bits); | |
431 break; | |
432 | |
433 case UNIFORM: | |
434 if (!gave_up) { | |
435 gave_up = 1; | |
436 printf("I'm sorry, this is too difficult, I give… | |
437 } | |
438 break; | |
439 | |
440 case MODUNIFORM: | |
441 try(mp_rand(r, bits)); | |
442 if (zcmp(r, n) > 0) | |
443 zsub(r, r, n); | |
444 break; | |
445 | |
446 default: | |
447 abort(); | |
448 } | |
449 } |