]> pd.if.org Git - zpackage/blob - libtomcrypt/src/math/gmp_desc.c
remove pmac and pelican
[zpackage] / libtomcrypt / src / math / gmp_desc.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9
10 #define DESC_DEF_ONLY
11 #include "tomcrypt.h"
12
13 #ifdef GMP_DESC
14
15 #include <stdio.h>
16 #include <gmp.h>
17
18 static int init(void **a)
19 {
20    LTC_ARGCHK(a != NULL);
21
22    *a = XCALLOC(1, sizeof(__mpz_struct));
23    if (*a == NULL) {
24       return CRYPT_MEM;
25    }
26    mpz_init(((__mpz_struct *)*a));
27    return CRYPT_OK;
28 }
29
30 static void deinit(void *a)
31 {
32    LTC_ARGCHKVD(a != NULL);
33    mpz_clear(a);
34    XFREE(a);
35 }
36
37 static int neg(void *a, void *b)
38 {
39    LTC_ARGCHK(a != NULL);
40    LTC_ARGCHK(b != NULL);
41    mpz_neg(b, a);
42    return CRYPT_OK;
43 }
44
45 static int copy(void *a, void *b)
46 {
47    LTC_ARGCHK(a != NULL);
48    LTC_ARGCHK(b != NULL);
49    mpz_set(b, a);
50    return CRYPT_OK;
51 }
52
53 static int init_copy(void **a, void *b)
54 {
55    if (init(a) != CRYPT_OK) {
56       return CRYPT_MEM;
57    }
58    return copy(b, *a);
59 }
60
61 /* ---- trivial ---- */
62 static int set_int(void *a, ltc_mp_digit b)
63 {
64    LTC_ARGCHK(a != NULL);
65    mpz_set_ui(((__mpz_struct *)a), b);
66    return CRYPT_OK;
67 }
68
69 static unsigned long get_int(void *a)
70 {
71    LTC_ARGCHK(a != NULL);
72    return mpz_get_ui(a);
73 }
74
75 static ltc_mp_digit get_digit(void *a, int n)
76 {
77    LTC_ARGCHK(a != NULL);
78    return mpz_getlimbn(a, n);
79 }
80
81 static int get_digit_count(void *a)
82 {
83    LTC_ARGCHK(a != NULL);
84    return mpz_size(a);
85 }
86
87 static int compare(void *a, void *b)
88 {
89    int ret;
90    LTC_ARGCHK(a != NULL);
91    LTC_ARGCHK(b != NULL);
92    ret = mpz_cmp(a, b);
93    if (ret < 0) {
94       return LTC_MP_LT;
95    } else if (ret > 0) {
96       return LTC_MP_GT;
97    } else {
98       return LTC_MP_EQ;
99    }
100 }
101
102 static int compare_d(void *a, ltc_mp_digit b)
103 {
104    int ret;
105    LTC_ARGCHK(a != NULL);
106    ret = mpz_cmp_ui(((__mpz_struct *)a), b);
107    if (ret < 0) {
108       return LTC_MP_LT;
109    } else if (ret > 0) {
110       return LTC_MP_GT;
111    } else {
112       return LTC_MP_EQ;
113    }
114 }
115
116 static int count_bits(void *a)
117 {
118    LTC_ARGCHK(a != NULL);
119    return mpz_sizeinbase(a, 2);
120 }
121
122 static int count_lsb_bits(void *a)
123 {
124    LTC_ARGCHK(a != NULL);
125    return mpz_scan1(a, 0);
126 }
127
128
129 static int twoexpt(void *a, int n)
130 {
131    LTC_ARGCHK(a != NULL);
132    mpz_set_ui(a, 0);
133    mpz_setbit(a, n);
134    return CRYPT_OK;
135 }
136
137 /* ---- conversions ---- */
138
139 static const char rmap[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
140
141 /* read ascii string */
142 static int read_radix(void *a, const char *b, int radix)
143 {
144    int ret;
145    LTC_ARGCHK(a != NULL);
146    LTC_ARGCHK(b != NULL);
147    if (radix == 64) {
148       /* Sadly, GMP only supports radixes up to 62, but we need 64.
149        * So, although this is not the most elegant or efficient way,
150        * let's just convert the base 64 string (6 bits per digit) to
151        * an octal string (3 bits per digit) that's twice as long. */
152       char c, *tmp, *q;
153       const char *p;
154       int i;
155       tmp = XMALLOC (1 + 2 * strlen (b));
156       if (tmp == NULL) {
157          return CRYPT_MEM;
158       }
159       p = b;
160       q = tmp;
161       while ((c = *p++) != 0) {
162          for (i = 0; i < 64; i++) {
163             if (c == rmap[i])
164                break;
165          }
166          if (i == 64) {
167             XFREE (tmp);
168             /* printf ("c = '%c'\n", c); */
169             return CRYPT_ERROR;
170          }
171          *q++ = '0' + (i / 8);
172          *q++ = '0' + (i % 8);
173       }
174       *q = 0;
175       ret = mpz_set_str(a, tmp, 8);
176       /* printf ("ret = %d for '%s'\n", ret, tmp); */
177       XFREE (tmp);
178    } else {
179       ret = mpz_set_str(a, b, radix);
180    }
181    return (ret == 0 ? CRYPT_OK : CRYPT_ERROR);
182 }
183
184 /* write one */
185 static int write_radix(void *a, char *b, int radix)
186 {
187    LTC_ARGCHK(a != NULL);
188    LTC_ARGCHK(b != NULL);
189    if (radix >= 11 && radix <= 36)
190       /* If radix is positive, GMP uses lowercase, and if negative, uppercase.
191        * We want it to use uppercase, to match the test vectors (presumably
192        * generated with LibTomMath). */
193       radix = -radix;
194    mpz_get_str(b, radix, a);
195    return CRYPT_OK;
196 }
197
198 /* get size as unsigned char string */
199 static unsigned long unsigned_size(void *a)
200 {
201    unsigned long t;
202    LTC_ARGCHK(a != NULL);
203    t = mpz_sizeinbase(a, 2);
204    if (mpz_cmp_ui(((__mpz_struct *)a), 0) == 0) return 0;
205    return (t>>3) + ((t&7)?1:0);
206 }
207
208 /* store */
209 static int unsigned_write(void *a, unsigned char *b)
210 {
211    LTC_ARGCHK(a != NULL);
212    LTC_ARGCHK(b != NULL);
213    mpz_export(b, NULL, 1, 1, 1, 0, ((__mpz_struct*)a));
214    return CRYPT_OK;
215 }
216
217 /* read */
218 static int unsigned_read(void *a, unsigned char *b, unsigned long len)
219 {
220    LTC_ARGCHK(a != NULL);
221    LTC_ARGCHK(b != NULL);
222    mpz_import(a, len, 1, 1, 1, 0, b);
223    return CRYPT_OK;
224 }
225
226 /* add */
227 static int add(void *a, void *b, void *c)
228 {
229    LTC_ARGCHK(a != NULL);
230    LTC_ARGCHK(b != NULL);
231    LTC_ARGCHK(c != NULL);
232    mpz_add(c, a, b);
233    return CRYPT_OK;
234 }
235
236 static int addi(void *a, ltc_mp_digit b, void *c)
237 {
238    LTC_ARGCHK(a != NULL);
239    LTC_ARGCHK(c != NULL);
240    mpz_add_ui(c, a, b);
241    return CRYPT_OK;
242 }
243
244 /* sub */
245 static int sub(void *a, void *b, void *c)
246 {
247    LTC_ARGCHK(a != NULL);
248    LTC_ARGCHK(b != NULL);
249    LTC_ARGCHK(c != NULL);
250    mpz_sub(c, a, b);
251    return CRYPT_OK;
252 }
253
254 static int subi(void *a, ltc_mp_digit b, void *c)
255 {
256    LTC_ARGCHK(a != NULL);
257    LTC_ARGCHK(c != NULL);
258    mpz_sub_ui(c, a, b);
259    return CRYPT_OK;
260 }
261
262 /* mul */
263 static int mul(void *a, void *b, void *c)
264 {
265    LTC_ARGCHK(a != NULL);
266    LTC_ARGCHK(b != NULL);
267    LTC_ARGCHK(c != NULL);
268    mpz_mul(c, a, b);
269    return CRYPT_OK;
270 }
271
272 static int muli(void *a, ltc_mp_digit b, void *c)
273 {
274    LTC_ARGCHK(a != NULL);
275    LTC_ARGCHK(c != NULL);
276    mpz_mul_ui(c, a, b);
277    return CRYPT_OK;
278 }
279
280 /* sqr */
281 static int sqr(void *a, void *b)
282 {
283    LTC_ARGCHK(a != NULL);
284    LTC_ARGCHK(b != NULL);
285    mpz_mul(b, a, a);
286    return CRYPT_OK;
287 }
288
289 /* div */
290 static int divide(void *a, void *b, void *c, void *d)
291 {
292    mpz_t tmp;
293    LTC_ARGCHK(a != NULL);
294    LTC_ARGCHK(b != NULL);
295    if (c != NULL) {
296       mpz_init(tmp);
297       mpz_divexact(tmp, a, b);
298    }
299    if (d != NULL) {
300       mpz_mod(d, a, b);
301    }
302    if (c != NULL) {
303       mpz_set(c, tmp);
304       mpz_clear(tmp);
305    }
306    return CRYPT_OK;
307 }
308
309 static int div_2(void *a, void *b)
310 {
311    LTC_ARGCHK(a != NULL);
312    LTC_ARGCHK(b != NULL);
313    mpz_divexact_ui(b, a, 2);
314    return CRYPT_OK;
315 }
316
317 /* modi */
318 static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
319 {
320    LTC_ARGCHK(a != NULL);
321    LTC_ARGCHK(c != NULL);
322
323    *c = mpz_fdiv_ui(a, b);
324    return CRYPT_OK;
325 }
326
327 /* gcd */
328 static int gcd(void *a, void *b, void *c)
329 {
330    LTC_ARGCHK(a != NULL);
331    LTC_ARGCHK(b != NULL);
332    LTC_ARGCHK(c != NULL);
333    mpz_gcd(c, a, b);
334    return CRYPT_OK;
335 }
336
337 /* lcm */
338 static int lcm(void *a, void *b, void *c)
339 {
340    LTC_ARGCHK(a != NULL);
341    LTC_ARGCHK(b != NULL);
342    LTC_ARGCHK(c != NULL);
343    mpz_lcm(c, a, b);
344    return CRYPT_OK;
345 }
346
347 static int addmod(void *a, void *b, void *c, void *d)
348 {
349    LTC_ARGCHK(a != NULL);
350    LTC_ARGCHK(b != NULL);
351    LTC_ARGCHK(c != NULL);
352    LTC_ARGCHK(d != NULL);
353    mpz_add(d, a, b);
354    mpz_mod(d, d, c);
355    return CRYPT_OK;
356 }
357
358 static int submod(void *a, void *b, void *c, void *d)
359 {
360    LTC_ARGCHK(a != NULL);
361    LTC_ARGCHK(b != NULL);
362    LTC_ARGCHK(c != NULL);
363    LTC_ARGCHK(d != NULL);
364    mpz_sub(d, a, b);
365    mpz_mod(d, d, c);
366    return CRYPT_OK;
367 }
368
369 static int mulmod(void *a, void *b, void *c, void *d)
370 {
371    LTC_ARGCHK(a != NULL);
372    LTC_ARGCHK(b != NULL);
373    LTC_ARGCHK(c != NULL);
374    LTC_ARGCHK(d != NULL);
375    mpz_mul(d, a, b);
376    mpz_mod(d, d, c);
377    return CRYPT_OK;
378 }
379
380 static int sqrmod(void *a, void *b, void *c)
381 {
382    LTC_ARGCHK(a != NULL);
383    LTC_ARGCHK(b != NULL);
384    LTC_ARGCHK(c != NULL);
385    mpz_mul(c, a, a);
386    mpz_mod(c, c, b);
387    return CRYPT_OK;
388 }
389
390 /* invmod */
391 static int invmod(void *a, void *b, void *c)
392 {
393    LTC_ARGCHK(a != NULL);
394    LTC_ARGCHK(b != NULL);
395    LTC_ARGCHK(c != NULL);
396    mpz_invert(c, a, b);
397    return CRYPT_OK;
398 }
399
400 /* setup */
401 static int montgomery_setup(void *a, void **b)
402 {
403    LTC_ARGCHK(a != NULL);
404    LTC_ARGCHK(b != NULL);
405    *b = (void *)1;
406    return CRYPT_OK;
407 }
408
409 /* get normalization value */
410 static int montgomery_normalization(void *a, void *b)
411 {
412    LTC_ARGCHK(a != NULL);
413    LTC_ARGCHK(b != NULL);
414    mpz_set_ui(a, 1);
415    return CRYPT_OK;
416 }
417
418 /* reduce */
419 static int montgomery_reduce(void *a, void *b, void *c)
420 {
421    LTC_ARGCHK(a != NULL);
422    LTC_ARGCHK(b != NULL);
423    LTC_ARGCHK(c != NULL);
424    mpz_mod(a, a, b);
425    return CRYPT_OK;
426 }
427
428 /* clean up */
429 static void montgomery_deinit(void *a)
430 {
431   LTC_UNUSED_PARAM(a);
432 }
433
434 static int exptmod(void *a, void *b, void *c, void *d)
435 {
436    LTC_ARGCHK(a != NULL);
437    LTC_ARGCHK(b != NULL);
438    LTC_ARGCHK(c != NULL);
439    LTC_ARGCHK(d != NULL);
440    mpz_powm(d, a, b, c);
441    return CRYPT_OK;
442 }
443
444 static int isprime(void *a, int b, int *c)
445 {
446    LTC_ARGCHK(a != NULL);
447    LTC_ARGCHK(c != NULL);
448    if (b == 0) {
449        b = LTC_MILLER_RABIN_REPS;
450    } /* if */
451    *c = mpz_probab_prime_p(a, b) > 0 ? LTC_MP_YES : LTC_MP_NO;
452    return CRYPT_OK;
453 }
454
455 static int set_rand(void *a, int size)
456 {
457    LTC_ARGCHK(a != NULL);
458    mpz_random(a, size);
459    return CRYPT_OK;
460 }
461
462 const ltc_math_descriptor gmp_desc = {
463    "GNU MP",
464    sizeof(mp_limb_t) * CHAR_BIT - GMP_NAIL_BITS,
465
466    &init,
467    &init_copy,
468    &deinit,
469
470    &neg,
471    &copy,
472
473    &set_int,
474    &get_int,
475    &get_digit,
476    &get_digit_count,
477    &compare,
478    &compare_d,
479    &count_bits,
480    &count_lsb_bits,
481    &twoexpt,
482
483    &read_radix,
484    &write_radix,
485    &unsigned_size,
486    &unsigned_write,
487    &unsigned_read,
488
489    &add,
490    &addi,
491    &sub,
492    &subi,
493    &mul,
494    &muli,
495    &sqr,
496    &divide,
497    &div_2,
498    &modi,
499    &gcd,
500    &lcm,
501
502    &mulmod,
503    &sqrmod,
504    &invmod,
505
506    &montgomery_setup,
507    &montgomery_normalization,
508    &montgomery_reduce,
509    &montgomery_deinit,
510
511    &exptmod,
512    &isprime,
513
514 #ifdef LTC_MECC
515 #ifdef LTC_MECC_FP
516    &ltc_ecc_fp_mulmod,
517 #else
518    &ltc_ecc_mulmod,
519 #endif /* LTC_MECC_FP */
520    &ltc_ecc_projective_add_point,
521    &ltc_ecc_projective_dbl_point,
522    &ltc_ecc_map,
523 #ifdef LTC_ECC_SHAMIR
524 #ifdef LTC_MECC_FP
525    &ltc_ecc_fp_mul2add,
526 #else
527    &ltc_ecc_mul2add,
528 #endif /* LTC_MECC_FP */
529 #else
530    NULL,
531 #endif /* LTC_ECC_SHAMIR */
532 #else
533    NULL, NULL, NULL, NULL, NULL,
534 #endif /* LTC_MECC */
535
536 #ifdef LTC_MRSA
537    &rsa_make_key,
538    &rsa_exptmod,
539 #else
540    NULL, NULL,
541 #endif
542    &addmod,
543    &submod,
544
545    &set_rand,
546
547 };
548
549
550 #endif
551
552 /* ref:         $Format:%D$ */
553 /* git commit:  $Format:%H$ */
554 /* commit time: $Format:%ai$ */