1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
6 * The library is free for all purposes without any express
18 static int init(void **a)
20 LTC_ARGCHK(a != NULL);
22 *a = XCALLOC(1, sizeof(__mpz_struct));
26 mpz_init(((__mpz_struct *)*a));
30 static void deinit(void *a)
32 LTC_ARGCHKVD(a != NULL);
37 static int neg(void *a, void *b)
39 LTC_ARGCHK(a != NULL);
40 LTC_ARGCHK(b != NULL);
45 static int copy(void *a, void *b)
47 LTC_ARGCHK(a != NULL);
48 LTC_ARGCHK(b != NULL);
53 static int init_copy(void **a, void *b)
55 if (init(a) != CRYPT_OK) {
61 /* ---- trivial ---- */
62 static int set_int(void *a, ltc_mp_digit b)
64 LTC_ARGCHK(a != NULL);
65 mpz_set_ui(((__mpz_struct *)a), b);
69 static unsigned long get_int(void *a)
71 LTC_ARGCHK(a != NULL);
75 static ltc_mp_digit get_digit(void *a, int n)
77 LTC_ARGCHK(a != NULL);
78 return mpz_getlimbn(a, n);
81 static int get_digit_count(void *a)
83 LTC_ARGCHK(a != NULL);
87 static int compare(void *a, void *b)
90 LTC_ARGCHK(a != NULL);
91 LTC_ARGCHK(b != NULL);
102 static int compare_d(void *a, ltc_mp_digit b)
105 LTC_ARGCHK(a != NULL);
106 ret = mpz_cmp_ui(((__mpz_struct *)a), b);
109 } else if (ret > 0) {
116 static int count_bits(void *a)
118 LTC_ARGCHK(a != NULL);
119 return mpz_sizeinbase(a, 2);
122 static int count_lsb_bits(void *a)
124 LTC_ARGCHK(a != NULL);
125 return mpz_scan1(a, 0);
129 static int twoexpt(void *a, int n)
131 LTC_ARGCHK(a != NULL);
137 /* ---- conversions ---- */
139 static const char rmap[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
141 /* read ascii string */
142 static int read_radix(void *a, const char *b, int radix)
145 LTC_ARGCHK(a != NULL);
146 LTC_ARGCHK(b != NULL);
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. */
155 tmp = XMALLOC (1 + 2 * strlen (b));
161 while ((c = *p++) != 0) {
162 for (i = 0; i < 64; i++) {
168 /* printf ("c = '%c'\n", c); */
171 *q++ = '0' + (i / 8);
172 *q++ = '0' + (i % 8);
175 ret = mpz_set_str(a, tmp, 8);
176 /* printf ("ret = %d for '%s'\n", ret, tmp); */
179 ret = mpz_set_str(a, b, radix);
181 return (ret == 0 ? CRYPT_OK : CRYPT_ERROR);
185 static int write_radix(void *a, char *b, int radix)
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). */
194 mpz_get_str(b, radix, a);
198 /* get size as unsigned char string */
199 static unsigned long unsigned_size(void *a)
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);
209 static int unsigned_write(void *a, unsigned char *b)
211 LTC_ARGCHK(a != NULL);
212 LTC_ARGCHK(b != NULL);
213 mpz_export(b, NULL, 1, 1, 1, 0, ((__mpz_struct*)a));
218 static int unsigned_read(void *a, unsigned char *b, unsigned long len)
220 LTC_ARGCHK(a != NULL);
221 LTC_ARGCHK(b != NULL);
222 mpz_import(a, len, 1, 1, 1, 0, b);
227 static int add(void *a, void *b, void *c)
229 LTC_ARGCHK(a != NULL);
230 LTC_ARGCHK(b != NULL);
231 LTC_ARGCHK(c != NULL);
236 static int addi(void *a, ltc_mp_digit b, void *c)
238 LTC_ARGCHK(a != NULL);
239 LTC_ARGCHK(c != NULL);
245 static int sub(void *a, void *b, void *c)
247 LTC_ARGCHK(a != NULL);
248 LTC_ARGCHK(b != NULL);
249 LTC_ARGCHK(c != NULL);
254 static int subi(void *a, ltc_mp_digit b, void *c)
256 LTC_ARGCHK(a != NULL);
257 LTC_ARGCHK(c != NULL);
263 static int mul(void *a, void *b, void *c)
265 LTC_ARGCHK(a != NULL);
266 LTC_ARGCHK(b != NULL);
267 LTC_ARGCHK(c != NULL);
272 static int muli(void *a, ltc_mp_digit b, void *c)
274 LTC_ARGCHK(a != NULL);
275 LTC_ARGCHK(c != NULL);
281 static int sqr(void *a, void *b)
283 LTC_ARGCHK(a != NULL);
284 LTC_ARGCHK(b != NULL);
290 static int divide(void *a, void *b, void *c, void *d)
293 LTC_ARGCHK(a != NULL);
294 LTC_ARGCHK(b != NULL);
297 mpz_divexact(tmp, a, b);
309 static int div_2(void *a, void *b)
311 LTC_ARGCHK(a != NULL);
312 LTC_ARGCHK(b != NULL);
313 mpz_divexact_ui(b, a, 2);
318 static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
320 LTC_ARGCHK(a != NULL);
321 LTC_ARGCHK(c != NULL);
323 *c = mpz_fdiv_ui(a, b);
328 static int gcd(void *a, void *b, void *c)
330 LTC_ARGCHK(a != NULL);
331 LTC_ARGCHK(b != NULL);
332 LTC_ARGCHK(c != NULL);
338 static int lcm(void *a, void *b, void *c)
340 LTC_ARGCHK(a != NULL);
341 LTC_ARGCHK(b != NULL);
342 LTC_ARGCHK(c != NULL);
347 static int addmod(void *a, void *b, void *c, void *d)
349 LTC_ARGCHK(a != NULL);
350 LTC_ARGCHK(b != NULL);
351 LTC_ARGCHK(c != NULL);
352 LTC_ARGCHK(d != NULL);
358 static int submod(void *a, void *b, void *c, void *d)
360 LTC_ARGCHK(a != NULL);
361 LTC_ARGCHK(b != NULL);
362 LTC_ARGCHK(c != NULL);
363 LTC_ARGCHK(d != NULL);
369 static int mulmod(void *a, void *b, void *c, void *d)
371 LTC_ARGCHK(a != NULL);
372 LTC_ARGCHK(b != NULL);
373 LTC_ARGCHK(c != NULL);
374 LTC_ARGCHK(d != NULL);
380 static int sqrmod(void *a, void *b, void *c)
382 LTC_ARGCHK(a != NULL);
383 LTC_ARGCHK(b != NULL);
384 LTC_ARGCHK(c != NULL);
391 static int invmod(void *a, void *b, void *c)
393 LTC_ARGCHK(a != NULL);
394 LTC_ARGCHK(b != NULL);
395 LTC_ARGCHK(c != NULL);
401 static int montgomery_setup(void *a, void **b)
403 LTC_ARGCHK(a != NULL);
404 LTC_ARGCHK(b != NULL);
409 /* get normalization value */
410 static int montgomery_normalization(void *a, void *b)
412 LTC_ARGCHK(a != NULL);
413 LTC_ARGCHK(b != NULL);
419 static int montgomery_reduce(void *a, void *b, void *c)
421 LTC_ARGCHK(a != NULL);
422 LTC_ARGCHK(b != NULL);
423 LTC_ARGCHK(c != NULL);
429 static void montgomery_deinit(void *a)
434 static int exptmod(void *a, void *b, void *c, void *d)
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);
444 static int isprime(void *a, int b, int *c)
446 LTC_ARGCHK(a != NULL);
447 LTC_ARGCHK(c != NULL);
449 b = LTC_MILLER_RABIN_REPS;
451 *c = mpz_probab_prime_p(a, b) > 0 ? LTC_MP_YES : LTC_MP_NO;
455 static int set_rand(void *a, int size)
457 LTC_ARGCHK(a != NULL);
462 const ltc_math_descriptor gmp_desc = {
464 sizeof(mp_limb_t) * CHAR_BIT - GMP_NAIL_BITS,
507 &montgomery_normalization,
519 #endif /* LTC_MECC_FP */
520 <c_ecc_projective_add_point,
521 <c_ecc_projective_dbl_point,
523 #ifdef LTC_ECC_SHAMIR
528 #endif /* LTC_MECC_FP */
531 #endif /* LTC_ECC_SHAMIR */
533 NULL, NULL, NULL, NULL, NULL,
534 #endif /* LTC_MECC */
552 /* ref: $Format:%D$ */
553 /* git commit: $Format:%H$ */
554 /* commit time: $Format:%ai$ */