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 * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com 10 */ 11 12 #define DESC_DEF_ONLY 13 #include "tomcrypt.h" 14 15 #ifdef GMP_DESC 16 17 #include <stdio.h> 18 #include <gmp.h> 19 20 static int init(void **a) 21 { 22 LTC_ARGCHK(a != NULL); 23 24 *a = XCALLOC(1, sizeof(__mpz_struct)); 25 if (*a == NULL) { 26 return CRYPT_MEM; 27 } 28 mpz_init(((__mpz_struct *)*a)); 29 return CRYPT_OK; 30 } 31 32 static void deinit(void *a) 33 { 34 LTC_ARGCHKVD(a != NULL); 35 mpz_clear(a); 36 XFREE(a); 37 } 38 39 static int neg(void *a, void *b) 40 { 41 LTC_ARGCHK(a != NULL); 42 LTC_ARGCHK(b != NULL); 43 mpz_neg(b, a); 44 return CRYPT_OK; 45 } 46 47 static int copy(void *a, void *b) 48 { 49 LTC_ARGCHK(a != NULL); 50 LTC_ARGCHK(b != NULL); 51 mpz_set(b, a); 52 return CRYPT_OK; 53 } 54 55 static int init_copy(void **a, void *b) 56 { 57 if (init(a) != CRYPT_OK) { 58 return CRYPT_MEM; 59 } 60 return copy(b, *a); 61 } 62 63 /* ---- trivial ---- */ 64 static int set_int(void *a, unsigned long b) 65 { 66 LTC_ARGCHK(a != NULL); 67 mpz_set_ui(((__mpz_struct *)a), b); 68 return CRYPT_OK; 69 } 70 71 static unsigned long get_int(void *a) 72 { 73 LTC_ARGCHK(a != NULL); 74 return mpz_get_ui(a); 75 } 76 77 static unsigned long get_digit(void *a, int n) 78 { 79 LTC_ARGCHK(a != NULL); 80 return mpz_getlimbn(a, n); 81 } 82 83 static int get_digit_count(void *a) 84 { 85 LTC_ARGCHK(a != NULL); 86 return mpz_size(a); 87 } 88 89 static int compare(void *a, void *b) 90 { 91 int ret; 92 LTC_ARGCHK(a != NULL); 93 LTC_ARGCHK(b != NULL); 94 ret = mpz_cmp(a, b); 95 if (ret < 0) { 96 return LTC_MP_LT; 97 } else if (ret > 0) { 98 return LTC_MP_GT; 99 } else { 100 return LTC_MP_EQ; 101 } 102 } 103 104 static int compare_d(void *a, unsigned long b) 105 { 106 int ret; 107 LTC_ARGCHK(a != NULL); 108 ret = mpz_cmp_ui(((__mpz_struct *)a), b); 109 if (ret < 0) { 110 return LTC_MP_LT; 111 } else if (ret > 0) { 112 return LTC_MP_GT; 113 } else { 114 return LTC_MP_EQ; 115 } 116 } 117 118 static int count_bits(void *a) 119 { 120 LTC_ARGCHK(a != NULL); 121 return mpz_sizeinbase(a, 2); 122 } 123 124 static int count_lsb_bits(void *a) 125 { 126 LTC_ARGCHK(a != NULL); 127 return mpz_scan1(a, 0); 128 } 129 130 131 static int twoexpt(void *a, int n) 132 { 133 LTC_ARGCHK(a != NULL); 134 mpz_set_ui(a, 0); 135 mpz_setbit(a, n); 136 return CRYPT_OK; 137 } 138 139 /* ---- conversions ---- */ 140 141 /* read ascii string */ 142 static int read_radix(void *a, const char *b, int radix) 143 { 144 LTC_ARGCHK(a != NULL); 145 LTC_ARGCHK(b != NULL); 146 mpz_set_str(a, b, radix); 147 return CRYPT_OK; 148 } 149 150 /* write one */ 151 static int write_radix(void *a, char *b, int radix) 152 { 153 LTC_ARGCHK(a != NULL); 154 LTC_ARGCHK(b != NULL); 155 mpz_get_str(b, radix, a); 156 return CRYPT_OK; 157 } 158 159 /* get size as unsigned char string */ 160 static unsigned long unsigned_size(void *a) 161 { 162 unsigned long t; 163 LTC_ARGCHK(a != NULL); 164 t = mpz_sizeinbase(a, 2); 165 if (mpz_cmp_ui(((__mpz_struct *)a), 0) == 0) return 0; 166 return (t>>3) + ((t&7)?1:0); 167 } 168 169 /* store */ 170 static int unsigned_write(void *a, unsigned char *b) 171 { 172 LTC_ARGCHK(a != NULL); 173 LTC_ARGCHK(b != NULL); 174 mpz_export(b, NULL, 1, 1, 1, 0, ((__mpz_struct*)a)); 175 return CRYPT_OK; 176 } 177 178 /* read */ 179 static int unsigned_read(void *a, unsigned char *b, unsigned long len) 180 { 181 LTC_ARGCHK(a != NULL); 182 LTC_ARGCHK(b != NULL); 183 mpz_import(a, len, 1, 1, 1, 0, b); 184 return CRYPT_OK; 185 } 186 187 /* add */ 188 static int add(void *a, void *b, void *c) 189 { 190 LTC_ARGCHK(a != NULL); 191 LTC_ARGCHK(b != NULL); 192 LTC_ARGCHK(c != NULL); 193 mpz_add(c, a, b); 194 return CRYPT_OK; 195 } 196 197 static int addi(void *a, unsigned long b, void *c) 198 { 199 LTC_ARGCHK(a != NULL); 200 LTC_ARGCHK(c != NULL); 201 mpz_add_ui(c, a, b); 202 return CRYPT_OK; 203 } 204 205 /* sub */ 206 static int sub(void *a, void *b, void *c) 207 { 208 LTC_ARGCHK(a != NULL); 209 LTC_ARGCHK(b != NULL); 210 LTC_ARGCHK(c != NULL); 211 mpz_sub(c, a, b); 212 return CRYPT_OK; 213 } 214 215 static int subi(void *a, unsigned long b, void *c) 216 { 217 LTC_ARGCHK(a != NULL); 218 LTC_ARGCHK(c != NULL); 219 mpz_sub_ui(c, a, b); 220 return CRYPT_OK; 221 } 222 223 /* mul */ 224 static int mul(void *a, void *b, void *c) 225 { 226 LTC_ARGCHK(a != NULL); 227 LTC_ARGCHK(b != NULL); 228 LTC_ARGCHK(c != NULL); 229 mpz_mul(c, a, b); 230 return CRYPT_OK; 231 } 232 233 static int muli(void *a, unsigned long b, void *c) 234 { 235 LTC_ARGCHK(a != NULL); 236 LTC_ARGCHK(c != NULL); 237 mpz_mul_ui(c, a, b); 238 return CRYPT_OK; 239 } 240 241 /* sqr */ 242 static int sqr(void *a, void *b) 243 { 244 LTC_ARGCHK(a != NULL); 245 LTC_ARGCHK(b != NULL); 246 mpz_mul(b, a, a); 247 return CRYPT_OK; 248 } 249 250 /* div */ 251 static int divide(void *a, void *b, void *c, void *d) 252 { 253 mpz_t tmp; 254 LTC_ARGCHK(a != NULL); 255 LTC_ARGCHK(b != NULL); 256 if (c != NULL) { 257 mpz_init(tmp); 258 mpz_divexact(tmp, a, b); 259 } 260 if (d != NULL) { 261 mpz_mod(d, a, b); 262 } 263 if (c != NULL) { 264 mpz_set(c, tmp); 265 mpz_clear(tmp); 266 } 267 return CRYPT_OK; 268 } 269 270 static int div_2(void *a, void *b) 271 { 272 LTC_ARGCHK(a != NULL); 273 LTC_ARGCHK(b != NULL); 274 mpz_divexact_ui(b, a, 2); 275 return CRYPT_OK; 276 } 277 278 /* modi */ 279 static int modi(void *a, unsigned long b, unsigned long *c) 280 { 281 LTC_ARGCHK(a != NULL); 282 LTC_ARGCHK(c != NULL); 283 284 *c = mpz_fdiv_ui(a, b); 285 return CRYPT_OK; 286 } 287 288 /* gcd */ 289 static int gcd(void *a, void *b, void *c) 290 { 291 LTC_ARGCHK(a != NULL); 292 LTC_ARGCHK(b != NULL); 293 LTC_ARGCHK(c != NULL); 294 mpz_gcd(c, a, b); 295 return CRYPT_OK; 296 } 297 298 /* lcm */ 299 static int lcm(void *a, void *b, void *c) 300 { 301 LTC_ARGCHK(a != NULL); 302 LTC_ARGCHK(b != NULL); 303 LTC_ARGCHK(c != NULL); 304 mpz_lcm(c, a, b); 305 return CRYPT_OK; 306 } 307 308 static int mulmod(void *a, void *b, void *c, void *d) 309 { 310 LTC_ARGCHK(a != NULL); 311 LTC_ARGCHK(b != NULL); 312 LTC_ARGCHK(c != NULL); 313 LTC_ARGCHK(d != NULL); 314 mpz_mul(d, a, b); 315 mpz_mod(d, d, c); 316 return CRYPT_OK; 317 } 318 319 static int sqrmod(void *a, void *b, void *c) 320 { 321 LTC_ARGCHK(a != NULL); 322 LTC_ARGCHK(b != NULL); 323 LTC_ARGCHK(c != NULL); 324 mpz_mul(c, a, a); 325 mpz_mod(c, c, b); 326 return CRYPT_OK; 327 } 328 329 /* invmod */ 330 static int invmod(void *a, void *b, void *c) 331 { 332 LTC_ARGCHK(a != NULL); 333 LTC_ARGCHK(b != NULL); 334 LTC_ARGCHK(c != NULL); 335 mpz_invert(c, a, b); 336 return CRYPT_OK; 337 } 338 339 /* setup */ 340 static int montgomery_setup(void *a, void **b) 341 { 342 LTC_ARGCHK(a != NULL); 343 LTC_ARGCHK(b != NULL); 344 *b = (void *)1; 345 return CRYPT_OK; 346 } 347 348 /* get normalization value */ 349 static int montgomery_normalization(void *a, void *b) 350 { 351 LTC_ARGCHK(a != NULL); 352 LTC_ARGCHK(b != NULL); 353 mpz_set_ui(a, 1); 354 return CRYPT_OK; 355 } 356 357 /* reduce */ 358 static int montgomery_reduce(void *a, void *b, void *c) 359 { 360 LTC_ARGCHK(a != NULL); 361 LTC_ARGCHK(b != NULL); 362 LTC_ARGCHK(c != NULL); 363 mpz_mod(a, a, b); 364 return CRYPT_OK; 365 } 366 367 /* clean up */ 368 static void montgomery_deinit(void *a) 369 { 370 } 371 372 static int exptmod(void *a, void *b, void *c, void *d) 373 { 374 LTC_ARGCHK(a != NULL); 375 LTC_ARGCHK(b != NULL); 376 LTC_ARGCHK(c != NULL); 377 LTC_ARGCHK(d != NULL); 378 mpz_powm(d, a, b, c); 379 return CRYPT_OK; 380 } 381 382 static int isprime(void *a, int *b) 383 { 384 LTC_ARGCHK(a != NULL); 385 LTC_ARGCHK(b != NULL); 386 *b = mpz_probab_prime_p(a, 8) > 0 ? LTC_MP_YES : LTC_MP_NO; 387 return CRYPT_OK; 388 } 389 390 const ltc_math_descriptor gmp_desc = { 391 "GNU MP", 392 sizeof(mp_limb_t) * CHAR_BIT - GMP_NAIL_BITS, 393 394 &init, 395 &init_copy, 396 &deinit, 397 398 &neg, 399 ©, 400 401 &set_int, 402 &get_int, 403 &get_digit, 404 &get_digit_count, 405 &compare, 406 &compare_d, 407 &count_bits, 408 &count_lsb_bits, 409 &twoexpt, 410 411 &read_radix, 412 &write_radix, 413 &unsigned_size, 414 &unsigned_write, 415 &unsigned_read, 416 417 &add, 418 &addi, 419 &sub, 420 &subi, 421 &mul, 422 &muli, 423 &sqr, 424 ÷, 425 &div_2, 426 &modi, 427 &gcd, 428 &lcm, 429 430 &mulmod, 431 &sqrmod, 432 &invmod, 433 434 &montgomery_setup, 435 &montgomery_normalization, 436 &montgomery_reduce, 437 &montgomery_deinit, 438 439 &exptmod, 440 &isprime, 441 442 #ifdef MECC 443 #ifdef MECC_FP 444 <c_ecc_fp_mulmod, 445 #else 446 <c_ecc_mulmod, 447 #endif /* MECC_FP */ 448 <c_ecc_projective_add_point, 449 <c_ecc_projective_dbl_point, 450 <c_ecc_map, 451 #ifdef LTC_ECC_SHAMIR 452 #ifdef MECC_FP 453 <c_ecc_fp_mul2add, 454 #else 455 <c_ecc_mul2add, 456 #endif /* MECC_FP */ 457 #else 458 NULL, 459 #endif /* LTC_ECC_SHAMIR */ 460 #else 461 NULL, NULL, NULL, NULL, NULL 462 #endif /* MECC */ 463 464 #ifdef MRSA 465 &rsa_make_key, 466 &rsa_exptmod, 467 #else 468 NULL, NULL 469 #endif 470 471 }; 472 473 474 #endif 475 476 /* $Source: /cvs/libtom/libtomcrypt/src/math/gmp_desc.c,v $ */ 477 /* $Revision: 1.14 $ */ 478 /* $Date: 2006/12/03 00:39:56 $ */ 479