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 LTM_DESC 16 17 #include <tommath.h> 18 19 static const struct { 20 int mpi_code, ltc_code; 21 } mpi_to_ltc_codes[] = { 22 { MP_OKAY , CRYPT_OK}, 23 { MP_MEM , CRYPT_MEM}, 24 { MP_VAL , CRYPT_INVALID_ARG}, 25 }; 26 27 /** 28 Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) 29 @param err The error to convert 30 @return The equivalent LTC error code or CRYPT_ERROR if none found 31 */ 32 static int mpi_to_ltc_error(int err) 33 { 34 int x; 35 36 for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { 37 if (err == mpi_to_ltc_codes[x].mpi_code) { 38 return mpi_to_ltc_codes[x].ltc_code; 39 } 40 } 41 return CRYPT_ERROR; 42 } 43 44 static int init(void **a) 45 { 46 int err; 47 48 LTC_ARGCHK(a != NULL); 49 50 *a = XCALLOC(1, sizeof(mp_int)); 51 if (*a == NULL) { 52 return CRYPT_MEM; 53 } 54 55 if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) { 56 XFREE(*a); 57 } 58 return err; 59 } 60 61 static void deinit(void *a) 62 { 63 LTC_ARGCHKVD(a != NULL); 64 mp_clear(a); 65 XFREE(a); 66 } 67 68 static int neg(void *a, void *b) 69 { 70 LTC_ARGCHK(a != NULL); 71 LTC_ARGCHK(b != NULL); 72 return mpi_to_ltc_error(mp_neg(a, b)); 73 } 74 75 static int copy(void *a, void *b) 76 { 77 LTC_ARGCHK(a != NULL); 78 LTC_ARGCHK(b != NULL); 79 return mpi_to_ltc_error(mp_copy(a, b)); 80 } 81 82 static int init_copy(void **a, void *b) 83 { 84 if (init(a) != CRYPT_OK) { 85 return CRYPT_MEM; 86 } 87 return copy(b, *a); 88 } 89 90 /* ---- trivial ---- */ 91 static int set_int(void *a, unsigned long b) 92 { 93 LTC_ARGCHK(a != NULL); 94 return mpi_to_ltc_error(mp_set_int(a, b)); 95 } 96 97 static unsigned long get_int(void *a) 98 { 99 LTC_ARGCHK(a != NULL); 100 return mp_get_int(a); 101 } 102 103 static unsigned long get_digit(void *a, int n) 104 { 105 mp_int *A; 106 LTC_ARGCHK(a != NULL); 107 A = a; 108 return (n >= A->used || n < 0) ? 0 : A->dp[n]; 109 } 110 111 static int get_digit_count(void *a) 112 { 113 mp_int *A; 114 LTC_ARGCHK(a != NULL); 115 A = a; 116 return A->used; 117 } 118 119 static int compare(void *a, void *b) 120 { 121 int ret; 122 LTC_ARGCHK(a != NULL); 123 LTC_ARGCHK(b != NULL); 124 ret = mp_cmp(a, b); 125 switch (ret) { 126 case MP_LT: return LTC_MP_LT; 127 case MP_EQ: return LTC_MP_EQ; 128 case MP_GT: return LTC_MP_GT; 129 } 130 return 0; 131 } 132 133 static int compare_d(void *a, unsigned long b) 134 { 135 int ret; 136 LTC_ARGCHK(a != NULL); 137 ret = mp_cmp_d(a, b); 138 switch (ret) { 139 case MP_LT: return LTC_MP_LT; 140 case MP_EQ: return LTC_MP_EQ; 141 case MP_GT: return LTC_MP_GT; 142 } 143 return 0; 144 } 145 146 static int count_bits(void *a) 147 { 148 LTC_ARGCHK(a != NULL); 149 return mp_count_bits(a); 150 } 151 152 static int count_lsb_bits(void *a) 153 { 154 LTC_ARGCHK(a != NULL); 155 return mp_cnt_lsb(a); 156 } 157 158 159 static int twoexpt(void *a, int n) 160 { 161 LTC_ARGCHK(a != NULL); 162 return mpi_to_ltc_error(mp_2expt(a, n)); 163 } 164 165 /* ---- conversions ---- */ 166 167 /* read ascii string */ 168 static int read_radix(void *a, const char *b, int radix) 169 { 170 LTC_ARGCHK(a != NULL); 171 LTC_ARGCHK(b != NULL); 172 return mpi_to_ltc_error(mp_read_radix(a, b, radix)); 173 } 174 175 /* write one */ 176 static int write_radix(void *a, char *b, int radix) 177 { 178 LTC_ARGCHK(a != NULL); 179 LTC_ARGCHK(b != NULL); 180 return mpi_to_ltc_error(mp_toradix(a, b, radix)); 181 } 182 183 /* get size as unsigned char string */ 184 static unsigned long unsigned_size(void *a) 185 { 186 LTC_ARGCHK(a != NULL); 187 return mp_unsigned_bin_size(a); 188 } 189 190 /* store */ 191 static int unsigned_write(void *a, unsigned char *b) 192 { 193 LTC_ARGCHK(a != NULL); 194 LTC_ARGCHK(b != NULL); 195 return mpi_to_ltc_error(mp_to_unsigned_bin(a, b)); 196 } 197 198 /* read */ 199 static int unsigned_read(void *a, unsigned char *b, unsigned long len) 200 { 201 LTC_ARGCHK(a != NULL); 202 LTC_ARGCHK(b != NULL); 203 return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len)); 204 } 205 206 /* add */ 207 static int add(void *a, void *b, void *c) 208 { 209 LTC_ARGCHK(a != NULL); 210 LTC_ARGCHK(b != NULL); 211 LTC_ARGCHK(c != NULL); 212 return mpi_to_ltc_error(mp_add(a, b, c)); 213 } 214 215 static int addi(void *a, unsigned long b, void *c) 216 { 217 LTC_ARGCHK(a != NULL); 218 LTC_ARGCHK(c != NULL); 219 return mpi_to_ltc_error(mp_add_d(a, b, c)); 220 } 221 222 /* sub */ 223 static int sub(void *a, void *b, void *c) 224 { 225 LTC_ARGCHK(a != NULL); 226 LTC_ARGCHK(b != NULL); 227 LTC_ARGCHK(c != NULL); 228 return mpi_to_ltc_error(mp_sub(a, b, c)); 229 } 230 231 static int subi(void *a, unsigned long b, void *c) 232 { 233 LTC_ARGCHK(a != NULL); 234 LTC_ARGCHK(c != NULL); 235 return mpi_to_ltc_error(mp_sub_d(a, b, c)); 236 } 237 238 /* mul */ 239 static int mul(void *a, void *b, void *c) 240 { 241 LTC_ARGCHK(a != NULL); 242 LTC_ARGCHK(b != NULL); 243 LTC_ARGCHK(c != NULL); 244 return mpi_to_ltc_error(mp_mul(a, b, c)); 245 } 246 247 static int muli(void *a, unsigned long b, void *c) 248 { 249 LTC_ARGCHK(a != NULL); 250 LTC_ARGCHK(c != NULL); 251 return mpi_to_ltc_error(mp_mul_d(a, b, c)); 252 } 253 254 /* sqr */ 255 static int sqr(void *a, void *b) 256 { 257 LTC_ARGCHK(a != NULL); 258 LTC_ARGCHK(b != NULL); 259 return mpi_to_ltc_error(mp_sqr(a, b)); 260 } 261 262 /* div */ 263 static int divide(void *a, void *b, void *c, void *d) 264 { 265 LTC_ARGCHK(a != NULL); 266 LTC_ARGCHK(b != NULL); 267 return mpi_to_ltc_error(mp_div(a, b, c, d)); 268 } 269 270 static int div_2(void *a, void *b) 271 { 272 LTC_ARGCHK(a != NULL); 273 LTC_ARGCHK(b != NULL); 274 return mpi_to_ltc_error(mp_div_2(a, b)); 275 } 276 277 /* modi */ 278 static int modi(void *a, unsigned long b, unsigned long *c) 279 { 280 mp_digit tmp; 281 int err; 282 283 LTC_ARGCHK(a != NULL); 284 LTC_ARGCHK(c != NULL); 285 286 if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) { 287 return err; 288 } 289 *c = tmp; 290 return CRYPT_OK; 291 } 292 293 /* gcd */ 294 static int gcd(void *a, void *b, void *c) 295 { 296 LTC_ARGCHK(a != NULL); 297 LTC_ARGCHK(b != NULL); 298 LTC_ARGCHK(c != NULL); 299 return mpi_to_ltc_error(mp_gcd(a, b, c)); 300 } 301 302 /* lcm */ 303 static int lcm(void *a, void *b, void *c) 304 { 305 LTC_ARGCHK(a != NULL); 306 LTC_ARGCHK(b != NULL); 307 LTC_ARGCHK(c != NULL); 308 return mpi_to_ltc_error(mp_lcm(a, b, c)); 309 } 310 311 static int mulmod(void *a, void *b, void *c, void *d) 312 { 313 LTC_ARGCHK(a != NULL); 314 LTC_ARGCHK(b != NULL); 315 LTC_ARGCHK(c != NULL); 316 LTC_ARGCHK(d != NULL); 317 return mpi_to_ltc_error(mp_mulmod(a,b,c,d)); 318 } 319 320 static int sqrmod(void *a, void *b, void *c) 321 { 322 LTC_ARGCHK(a != NULL); 323 LTC_ARGCHK(b != NULL); 324 LTC_ARGCHK(c != NULL); 325 return mpi_to_ltc_error(mp_sqrmod(a,b,c)); 326 } 327 328 /* invmod */ 329 static int invmod(void *a, void *b, void *c) 330 { 331 LTC_ARGCHK(a != NULL); 332 LTC_ARGCHK(b != NULL); 333 LTC_ARGCHK(c != NULL); 334 return mpi_to_ltc_error(mp_invmod(a, b, c)); 335 } 336 337 /* setup */ 338 static int montgomery_setup(void *a, void **b) 339 { 340 int err; 341 LTC_ARGCHK(a != NULL); 342 LTC_ARGCHK(b != NULL); 343 *b = XCALLOC(1, sizeof(mp_digit)); 344 if (*b == NULL) { 345 return CRYPT_MEM; 346 } 347 if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) { 348 XFREE(*b); 349 } 350 return err; 351 } 352 353 /* get normalization value */ 354 static int montgomery_normalization(void *a, void *b) 355 { 356 LTC_ARGCHK(a != NULL); 357 LTC_ARGCHK(b != NULL); 358 return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b)); 359 } 360 361 /* reduce */ 362 static int montgomery_reduce(void *a, void *b, void *c) 363 { 364 LTC_ARGCHK(a != NULL); 365 LTC_ARGCHK(b != NULL); 366 LTC_ARGCHK(c != NULL); 367 return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c))); 368 } 369 370 /* clean up */ 371 static void montgomery_deinit(void *a) 372 { 373 XFREE(a); 374 } 375 376 static int exptmod(void *a, void *b, void *c, void *d) 377 { 378 LTC_ARGCHK(a != NULL); 379 LTC_ARGCHK(b != NULL); 380 LTC_ARGCHK(c != NULL); 381 LTC_ARGCHK(d != NULL); 382 return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); 383 } 384 385 static int isprime(void *a, int *b) 386 { 387 int err; 388 LTC_ARGCHK(a != NULL); 389 LTC_ARGCHK(b != NULL); 390 err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b)); 391 *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO; 392 return err; 393 } 394 395 const ltc_math_descriptor ltm_desc = { 396 397 "LibTomMath", 398 (int)DIGIT_BIT, 399 400 &init, 401 &init_copy, 402 &deinit, 403 404 &neg, 405 ©, 406 407 &set_int, 408 &get_int, 409 &get_digit, 410 &get_digit_count, 411 &compare, 412 &compare_d, 413 &count_bits, 414 &count_lsb_bits, 415 &twoexpt, 416 417 &read_radix, 418 &write_radix, 419 &unsigned_size, 420 &unsigned_write, 421 &unsigned_read, 422 423 &add, 424 &addi, 425 &sub, 426 &subi, 427 &mul, 428 &muli, 429 &sqr, 430 ÷, 431 &div_2, 432 &modi, 433 &gcd, 434 &lcm, 435 436 &mulmod, 437 &sqrmod, 438 &invmod, 439 440 &montgomery_setup, 441 &montgomery_normalization, 442 &montgomery_reduce, 443 &montgomery_deinit, 444 445 &exptmod, 446 &isprime, 447 448 #ifdef MECC 449 #ifdef MECC_FP 450 <c_ecc_fp_mulmod, 451 #else 452 <c_ecc_mulmod, 453 #endif 454 <c_ecc_projective_add_point, 455 <c_ecc_projective_dbl_point, 456 <c_ecc_map, 457 #ifdef LTC_ECC_SHAMIR 458 #ifdef MECC_FP 459 <c_ecc_fp_mul2add, 460 #else 461 <c_ecc_mul2add, 462 #endif /* MECC_FP */ 463 #else 464 NULL, 465 #endif /* LTC_ECC_SHAMIR */ 466 #else 467 NULL, NULL, NULL, NULL, NULL, 468 #endif /* MECC */ 469 470 #ifdef MRSA 471 &rsa_make_key, 472 &rsa_exptmod, 473 #else 474 NULL, NULL 475 #endif 476 }; 477 478 479 #endif 480 481 /* $Source: /cvs/libtom/libtomcrypt/src/math/ltm_desc.c,v $ */ 482 /* $Revision: 1.29 $ */ 483 /* $Date: 2006/12/03 00:39:56 $ */ 484