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@gmail.com, http://libtomcrypt.com 10 */ 11 12#define DESC_DEF_ONLY 13#include "tomcrypt.h" 14 15#ifdef TFM_DESC 16 17#include <tfm.h> 18 19static const struct { 20 int tfm_code, ltc_code; 21} tfm_to_ltc_codes[] = { 22 { FP_OKAY , CRYPT_OK}, 23 { FP_MEM , CRYPT_MEM}, 24 { FP_VAL , CRYPT_INVALID_ARG}, 25}; 26 27/** 28 Convert a tfm 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*/ 32static int tfm_to_ltc_error(int err) 33{ 34 int x; 35 36 for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) { 37 if (err == tfm_to_ltc_codes[x].tfm_code) { 38 return tfm_to_ltc_codes[x].ltc_code; 39 } 40 } 41 return CRYPT_ERROR; 42} 43 44static int init(void **a) 45{ 46 LTC_ARGCHK(a != NULL); 47 48 *a = XCALLOC(1, sizeof(fp_int)); 49 if (*a == NULL) { 50 return CRYPT_MEM; 51 } 52 fp_init(*a); 53 return CRYPT_OK; 54} 55 56static void deinit(void *a) 57{ 58 LTC_ARGCHKVD(a != NULL); 59 XFREE(a); 60} 61 62static int neg(void *a, void *b) 63{ 64 LTC_ARGCHK(a != NULL); 65 LTC_ARGCHK(b != NULL); 66 fp_neg(((fp_int*)a), ((fp_int*)b)); 67 return CRYPT_OK; 68} 69 70static int copy(void *a, void *b) 71{ 72 LTC_ARGCHK(a != NULL); 73 LTC_ARGCHK(b != NULL); 74 fp_copy(a, b); 75 return CRYPT_OK; 76} 77 78static int init_copy(void **a, void *b) 79{ 80 if (init(a) != CRYPT_OK) { 81 return CRYPT_MEM; 82 } 83 return copy(b, *a); 84} 85 86/* ---- trivial ---- */ 87static int set_int(void *a, unsigned long b) 88{ 89 LTC_ARGCHK(a != NULL); 90 fp_set(a, b); 91 return CRYPT_OK; 92} 93 94static unsigned long get_int(void *a) 95{ 96 fp_int *A; 97 LTC_ARGCHK(a != NULL); 98 A = a; 99 return A->used > 0 ? A->dp[0] : 0; 100} 101 102static unsigned long get_digit(void *a, int n) 103{ 104 fp_int *A; 105 LTC_ARGCHK(a != NULL); 106 A = a; 107 return (n >= A->used || n < 0) ? 0 : A->dp[n]; 108} 109 110static int get_digit_count(void *a) 111{ 112 fp_int *A; 113 LTC_ARGCHK(a != NULL); 114 A = a; 115 return A->used; 116} 117 118static int compare(void *a, void *b) 119{ 120 int ret; 121 LTC_ARGCHK(a != NULL); 122 LTC_ARGCHK(b != NULL); 123 ret = fp_cmp(a, b); 124 switch (ret) { 125 case FP_LT: return LTC_MP_LT; 126 case FP_EQ: return LTC_MP_EQ; 127 case FP_GT: return LTC_MP_GT; 128 } 129 return 0; 130} 131 132static int compare_d(void *a, unsigned long b) 133{ 134 int ret; 135 LTC_ARGCHK(a != NULL); 136 ret = fp_cmp_d(a, b); 137 switch (ret) { 138 case FP_LT: return LTC_MP_LT; 139 case FP_EQ: return LTC_MP_EQ; 140 case FP_GT: return LTC_MP_GT; 141 } 142 return 0; 143} 144 145static int count_bits(void *a) 146{ 147 LTC_ARGCHK(a != NULL); 148 return fp_count_bits(a); 149} 150 151static int count_lsb_bits(void *a) 152{ 153 LTC_ARGCHK(a != NULL); 154 return fp_cnt_lsb(a); 155} 156 157static int twoexpt(void *a, int n) 158{ 159 LTC_ARGCHK(a != NULL); 160 fp_2expt(a, n); 161 return CRYPT_OK; 162} 163 164/* ---- conversions ---- */ 165 166/* read ascii string */ 167static int read_radix(void *a, const char *b, int radix) 168{ 169 LTC_ARGCHK(a != NULL); 170 LTC_ARGCHK(b != NULL); 171 return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix)); 172} 173 174/* write one */ 175static int write_radix(void *a, char *b, int radix) 176{ 177 LTC_ARGCHK(a != NULL); 178 LTC_ARGCHK(b != NULL); 179 return tfm_to_ltc_error(fp_toradix(a, b, radix)); 180} 181 182/* get size as unsigned char string */ 183static unsigned long unsigned_size(void *a) 184{ 185 LTC_ARGCHK(a != NULL); 186 return fp_unsigned_bin_size(a); 187} 188 189/* store */ 190static int unsigned_write(void *a, unsigned char *b) 191{ 192 LTC_ARGCHK(a != NULL); 193 LTC_ARGCHK(b != NULL); 194 fp_to_unsigned_bin(a, b); 195 return CRYPT_OK; 196} 197 198/* read */ 199static int unsigned_read(void *a, unsigned char *b, unsigned long len) 200{ 201 LTC_ARGCHK(a != NULL); 202 LTC_ARGCHK(b != NULL); 203 fp_read_unsigned_bin(a, b, len); 204 return CRYPT_OK; 205} 206 207/* add */ 208static int add(void *a, void *b, void *c) 209{ 210 LTC_ARGCHK(a != NULL); 211 LTC_ARGCHK(b != NULL); 212 LTC_ARGCHK(c != NULL); 213 fp_add(a, b, c); 214 return CRYPT_OK; 215} 216 217static int addi(void *a, unsigned long b, void *c) 218{ 219 LTC_ARGCHK(a != NULL); 220 LTC_ARGCHK(c != NULL); 221 fp_add_d(a, b, c); 222 return CRYPT_OK; 223} 224 225/* sub */ 226static int sub(void *a, void *b, void *c) 227{ 228 LTC_ARGCHK(a != NULL); 229 LTC_ARGCHK(b != NULL); 230 LTC_ARGCHK(c != NULL); 231 fp_sub(a, b, c); 232 return CRYPT_OK; 233} 234 235static int subi(void *a, unsigned long b, void *c) 236{ 237 LTC_ARGCHK(a != NULL); 238 LTC_ARGCHK(c != NULL); 239 fp_sub_d(a, b, c); 240 return CRYPT_OK; 241} 242 243/* mul */ 244static int mul(void *a, void *b, void *c) 245{ 246 LTC_ARGCHK(a != NULL); 247 LTC_ARGCHK(b != NULL); 248 LTC_ARGCHK(c != NULL); 249 fp_mul(a, b, c); 250 return CRYPT_OK; 251} 252 253static int muli(void *a, unsigned long b, void *c) 254{ 255 LTC_ARGCHK(a != NULL); 256 LTC_ARGCHK(c != NULL); 257 fp_mul_d(a, b, c); 258 return CRYPT_OK; 259} 260 261/* sqr */ 262static int sqr(void *a, void *b) 263{ 264 LTC_ARGCHK(a != NULL); 265 LTC_ARGCHK(b != NULL); 266 fp_sqr(a, b); 267 return CRYPT_OK; 268} 269 270/* div */ 271static int divide(void *a, void *b, void *c, void *d) 272{ 273 LTC_ARGCHK(a != NULL); 274 LTC_ARGCHK(b != NULL); 275 return tfm_to_ltc_error(fp_div(a, b, c, d)); 276} 277 278static int div_2(void *a, void *b) 279{ 280 LTC_ARGCHK(a != NULL); 281 LTC_ARGCHK(b != NULL); 282 fp_div_2(a, b); 283 return CRYPT_OK; 284} 285 286/* modi */ 287static int modi(void *a, unsigned long b, unsigned long *c) 288{ 289 fp_digit tmp; 290 int err; 291 292 LTC_ARGCHK(a != NULL); 293 LTC_ARGCHK(c != NULL); 294 295 if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) { 296 return err; 297 } 298 *c = tmp; 299 return CRYPT_OK; 300} 301 302/* gcd */ 303static int gcd(void *a, void *b, void *c) 304{ 305 LTC_ARGCHK(a != NULL); 306 LTC_ARGCHK(b != NULL); 307 LTC_ARGCHK(c != NULL); 308 fp_gcd(a, b, c); 309 return CRYPT_OK; 310} 311 312/* lcm */ 313static int lcm(void *a, void *b, void *c) 314{ 315 LTC_ARGCHK(a != NULL); 316 LTC_ARGCHK(b != NULL); 317 LTC_ARGCHK(c != NULL); 318 fp_lcm(a, b, c); 319 return CRYPT_OK; 320} 321 322static int mulmod(void *a, void *b, void *c, void *d) 323{ 324 LTC_ARGCHK(a != NULL); 325 LTC_ARGCHK(b != NULL); 326 LTC_ARGCHK(c != NULL); 327 LTC_ARGCHK(d != NULL); 328 return tfm_to_ltc_error(fp_mulmod(a,b,c,d)); 329} 330 331static int sqrmod(void *a, void *b, void *c) 332{ 333 LTC_ARGCHK(a != NULL); 334 LTC_ARGCHK(b != NULL); 335 LTC_ARGCHK(c != NULL); 336 return tfm_to_ltc_error(fp_sqrmod(a,b,c)); 337} 338 339/* invmod */ 340static int invmod(void *a, void *b, void *c) 341{ 342 LTC_ARGCHK(a != NULL); 343 LTC_ARGCHK(b != NULL); 344 LTC_ARGCHK(c != NULL); 345 return tfm_to_ltc_error(fp_invmod(a, b, c)); 346} 347 348/* setup */ 349static int montgomery_setup(void *a, void **b) 350{ 351 int err; 352 LTC_ARGCHK(a != NULL); 353 LTC_ARGCHK(b != NULL); 354 *b = XCALLOC(1, sizeof(fp_digit)); 355 if (*b == NULL) { 356 return CRYPT_MEM; 357 } 358 if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) { 359 XFREE(*b); 360 } 361 return err; 362} 363 364/* get normalization value */ 365static int montgomery_normalization(void *a, void *b) 366{ 367 LTC_ARGCHK(a != NULL); 368 LTC_ARGCHK(b != NULL); 369 fp_montgomery_calc_normalization(a, b); 370 return CRYPT_OK; 371} 372 373/* reduce */ 374static int montgomery_reduce(void *a, void *b, void *c) 375{ 376 LTC_ARGCHK(a != NULL); 377 LTC_ARGCHK(b != NULL); 378 LTC_ARGCHK(c != NULL); 379 fp_montgomery_reduce(a, b, *((fp_digit *)c)); 380 return CRYPT_OK; 381} 382 383/* clean up */ 384static void montgomery_deinit(void *a) 385{ 386 XFREE(a); 387} 388 389static int exptmod(void *a, void *b, void *c, void *d) 390{ 391 LTC_ARGCHK(a != NULL); 392 LTC_ARGCHK(b != NULL); 393 LTC_ARGCHK(c != NULL); 394 LTC_ARGCHK(d != NULL); 395 return tfm_to_ltc_error(fp_exptmod(a,b,c,d)); 396} 397 398static int isprime(void *a, int *b) 399{ 400 LTC_ARGCHK(a != NULL); 401 LTC_ARGCHK(b != NULL); 402 *b = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO; 403 return CRYPT_OK; 404} 405 406#if defined(MECC) && defined(MECC_ACCEL) 407 408static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp) 409{ 410 fp_int t1, t2; 411 fp_digit mp; 412 413 LTC_ARGCHK(P != NULL); 414 LTC_ARGCHK(R != NULL); 415 LTC_ARGCHK(modulus != NULL); 416 LTC_ARGCHK(Mp != NULL); 417 418 mp = *((fp_digit*)Mp); 419 420 fp_init(&t1); 421 fp_init(&t2); 422 423 if (P != R) { 424 fp_copy(P->x, R->x); 425 fp_copy(P->y, R->y); 426 fp_copy(P->z, R->z); 427 } 428 429 /* t1 = Z * Z */ 430 fp_sqr(R->z, &t1); 431 fp_montgomery_reduce(&t1, modulus, mp); 432 /* Z = Y * Z */ 433 fp_mul(R->z, R->y, R->z); 434 fp_montgomery_reduce(R->z, modulus, mp); 435 /* Z = 2Z */ 436 fp_add(R->z, R->z, R->z); 437 if (fp_cmp(R->z, modulus) != FP_LT) { 438 fp_sub(R->z, modulus, R->z); 439 } 440 441 /* &t2 = X - T1 */ 442 fp_sub(R->x, &t1, &t2); 443 if (fp_cmp_d(&t2, 0) == FP_LT) { 444 fp_add(&t2, modulus, &t2); 445 } 446 /* T1 = X + T1 */ 447 fp_add(&t1, R->x, &t1); 448 if (fp_cmp(&t1, modulus) != FP_LT) { 449 fp_sub(&t1, modulus, &t1); 450 } 451 /* T2 = T1 * T2 */ 452 fp_mul(&t1, &t2, &t2); 453 fp_montgomery_reduce(&t2, modulus, mp); 454 /* T1 = 2T2 */ 455 fp_add(&t2, &t2, &t1); 456 if (fp_cmp(&t1, modulus) != FP_LT) { 457 fp_sub(&t1, modulus, &t1); 458 } 459 /* T1 = T1 + T2 */ 460 fp_add(&t1, &t2, &t1); 461 if (fp_cmp(&t1, modulus) != FP_LT) { 462 fp_sub(&t1, modulus, &t1); 463 } 464 465 /* Y = 2Y */ 466 fp_add(R->y, R->y, R->y); 467 if (fp_cmp(R->y, modulus) != FP_LT) { 468 fp_sub(R->y, modulus, R->y); 469 } 470 /* Y = Y * Y */ 471 fp_sqr(R->y, R->y); 472 fp_montgomery_reduce(R->y, modulus, mp); 473 /* T2 = Y * Y */ 474 fp_sqr(R->y, &t2); 475 fp_montgomery_reduce(&t2, modulus, mp); 476 /* T2 = T2/2 */ 477 if (fp_isodd(&t2)) { 478 fp_add(&t2, modulus, &t2); 479 } 480 fp_div_2(&t2, &t2); 481 /* Y = Y * X */ 482 fp_mul(R->y, R->x, R->y); 483 fp_montgomery_reduce(R->y, modulus, mp); 484 485 /* X = T1 * T1 */ 486 fp_sqr(&t1, R->x); 487 fp_montgomery_reduce(R->x, modulus, mp); 488 /* X = X - Y */ 489 fp_sub(R->x, R->y, R->x); 490 if (fp_cmp_d(R->x, 0) == FP_LT) { 491 fp_add(R->x, modulus, R->x); 492 } 493 /* X = X - Y */ 494 fp_sub(R->x, R->y, R->x); 495 if (fp_cmp_d(R->x, 0) == FP_LT) { 496 fp_add(R->x, modulus, R->x); 497 } 498 499 /* Y = Y - X */ 500 fp_sub(R->y, R->x, R->y); 501 if (fp_cmp_d(R->y, 0) == FP_LT) { 502 fp_add(R->y, modulus, R->y); 503 } 504 /* Y = Y * T1 */ 505 fp_mul(R->y, &t1, R->y); 506 fp_montgomery_reduce(R->y, modulus, mp); 507 /* Y = Y - T2 */ 508 fp_sub(R->y, &t2, R->y); 509 if (fp_cmp_d(R->y, 0) == FP_LT) { 510 fp_add(R->y, modulus, R->y); 511 } 512 513 return CRYPT_OK; 514} 515 516/** 517 Add two ECC points 518 @param P The point to add 519 @param Q The point to add 520 @param R [out] The destination of the double 521 @param modulus The modulus of the field the ECC curve is in 522 @param mp The "b" value from montgomery_setup() 523 @return CRYPT_OK on success 524*/ 525static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp) 526{ 527 fp_int t1, t2, x, y, z; 528 fp_digit mp; 529 530 LTC_ARGCHK(P != NULL); 531 LTC_ARGCHK(Q != NULL); 532 LTC_ARGCHK(R != NULL); 533 LTC_ARGCHK(modulus != NULL); 534 LTC_ARGCHK(Mp != NULL); 535 536 mp = *((fp_digit*)Mp); 537 538 fp_init(&t1); 539 fp_init(&t2); 540 fp_init(&x); 541 fp_init(&y); 542 fp_init(&z); 543 544 /* should we dbl instead? */ 545 fp_sub(modulus, Q->y, &t1); 546 if ( (fp_cmp(P->x, Q->x) == FP_EQ) && 547 (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) && 548 (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { 549 return tfm_ecc_projective_dbl_point(P, R, modulus, Mp); 550 } 551 552 fp_copy(P->x, &x); 553 fp_copy(P->y, &y); 554 fp_copy(P->z, &z); 555 556 /* if Z is one then these are no-operations */ 557 if (Q->z != NULL) { 558 /* T1 = Z' * Z' */ 559 fp_sqr(Q->z, &t1); 560 fp_montgomery_reduce(&t1, modulus, mp); 561 /* X = X * T1 */ 562 fp_mul(&t1, &x, &x); 563 fp_montgomery_reduce(&x, modulus, mp); 564 /* T1 = Z' * T1 */ 565 fp_mul(Q->z, &t1, &t1); 566 fp_montgomery_reduce(&t1, modulus, mp); 567 /* Y = Y * T1 */ 568 fp_mul(&t1, &y, &y); 569 fp_montgomery_reduce(&y, modulus, mp); 570 } 571 572 /* T1 = Z*Z */ 573 fp_sqr(&z, &t1); 574 fp_montgomery_reduce(&t1, modulus, mp); 575 /* T2 = X' * T1 */ 576 fp_mul(Q->x, &t1, &t2); 577 fp_montgomery_reduce(&t2, modulus, mp); 578 /* T1 = Z * T1 */ 579 fp_mul(&z, &t1, &t1); 580 fp_montgomery_reduce(&t1, modulus, mp); 581 /* T1 = Y' * T1 */ 582 fp_mul(Q->y, &t1, &t1); 583 fp_montgomery_reduce(&t1, modulus, mp); 584 585 /* Y = Y - T1 */ 586 fp_sub(&y, &t1, &y); 587 if (fp_cmp_d(&y, 0) == FP_LT) { 588 fp_add(&y, modulus, &y); 589 } 590 /* T1 = 2T1 */ 591 fp_add(&t1, &t1, &t1); 592 if (fp_cmp(&t1, modulus) != FP_LT) { 593 fp_sub(&t1, modulus, &t1); 594 } 595 /* T1 = Y + T1 */ 596 fp_add(&t1, &y, &t1); 597 if (fp_cmp(&t1, modulus) != FP_LT) { 598 fp_sub(&t1, modulus, &t1); 599 } 600 /* X = X - T2 */ 601 fp_sub(&x, &t2, &x); 602 if (fp_cmp_d(&x, 0) == FP_LT) { 603 fp_add(&x, modulus, &x); 604 } 605 /* T2 = 2T2 */ 606 fp_add(&t2, &t2, &t2); 607 if (fp_cmp(&t2, modulus) != FP_LT) { 608 fp_sub(&t2, modulus, &t2); 609 } 610 /* T2 = X + T2 */ 611 fp_add(&t2, &x, &t2); 612 if (fp_cmp(&t2, modulus) != FP_LT) { 613 fp_sub(&t2, modulus, &t2); 614 } 615 616 /* if Z' != 1 */ 617 if (Q->z != NULL) { 618 /* Z = Z * Z' */ 619 fp_mul(&z, Q->z, &z); 620 fp_montgomery_reduce(&z, modulus, mp); 621 } 622 623 /* Z = Z * X */ 624 fp_mul(&z, &x, &z); 625 fp_montgomery_reduce(&z, modulus, mp); 626 627 /* T1 = T1 * X */ 628 fp_mul(&t1, &x, &t1); 629 fp_montgomery_reduce(&t1, modulus, mp); 630 /* X = X * X */ 631 fp_sqr(&x, &x); 632 fp_montgomery_reduce(&x, modulus, mp); 633 /* T2 = T2 * x */ 634 fp_mul(&t2, &x, &t2); 635 fp_montgomery_reduce(&t2, modulus, mp); 636 /* T1 = T1 * X */ 637 fp_mul(&t1, &x, &t1); 638 fp_montgomery_reduce(&t1, modulus, mp); 639 640 /* X = Y*Y */ 641 fp_sqr(&y, &x); 642 fp_montgomery_reduce(&x, modulus, mp); 643 /* X = X - T2 */ 644 fp_sub(&x, &t2, &x); 645 if (fp_cmp_d(&x, 0) == FP_LT) { 646 fp_add(&x, modulus, &x); 647 } 648 649 /* T2 = T2 - X */ 650 fp_sub(&t2, &x, &t2); 651 if (fp_cmp_d(&t2, 0) == FP_LT) { 652 fp_add(&t2, modulus, &t2); 653 } 654 /* T2 = T2 - X */ 655 fp_sub(&t2, &x, &t2); 656 if (fp_cmp_d(&t2, 0) == FP_LT) { 657 fp_add(&t2, modulus, &t2); 658 } 659 /* T2 = T2 * Y */ 660 fp_mul(&t2, &y, &t2); 661 fp_montgomery_reduce(&t2, modulus, mp); 662 /* Y = T2 - T1 */ 663 fp_sub(&t2, &t1, &y); 664 if (fp_cmp_d(&y, 0) == FP_LT) { 665 fp_add(&y, modulus, &y); 666 } 667 /* Y = Y/2 */ 668 if (fp_isodd(&y)) { 669 fp_add(&y, modulus, &y); 670 } 671 fp_div_2(&y, &y); 672 673 fp_copy(&x, R->x); 674 fp_copy(&y, R->y); 675 fp_copy(&z, R->z); 676 677 return CRYPT_OK; 678} 679 680 681#endif 682 683const ltc_math_descriptor tfm_desc = { 684 685 "TomsFastMath", 686 (int)DIGIT_BIT, 687 688 &init, 689 &init_copy, 690 &deinit, 691 692 &neg, 693 ©, 694 695 &set_int, 696 &get_int, 697 &get_digit, 698 &get_digit_count, 699 &compare, 700 &compare_d, 701 &count_bits, 702 &count_lsb_bits, 703 &twoexpt, 704 705 &read_radix, 706 &write_radix, 707 &unsigned_size, 708 &unsigned_write, 709 &unsigned_read, 710 711 &add, 712 &addi, 713 &sub, 714 &subi, 715 &mul, 716 &muli, 717 &sqr, 718 ÷, 719 &div_2, 720 &modi, 721 &gcd, 722 &lcm, 723 724 &mulmod, 725 &sqrmod, 726 &invmod, 727 728 &montgomery_setup, 729 &montgomery_normalization, 730 &montgomery_reduce, 731 &montgomery_deinit, 732 733 &exptmod, 734 &isprime, 735 736#ifdef MECC 737#ifdef MECC_FP 738 <c_ecc_fp_mulmod, 739#else 740 <c_ecc_mulmod, 741#endif /* MECC_FP */ 742#ifdef MECC_ACCEL 743 &tfm_ecc_projective_add_point, 744 &tfm_ecc_projective_dbl_point, 745#else 746 <c_ecc_projective_add_point, 747 <c_ecc_projective_dbl_point, 748#endif /* MECC_ACCEL */ 749 <c_ecc_map, 750#ifdef LTC_ECC_SHAMIR 751#ifdef MECC_FP 752 <c_ecc_fp_mul2add, 753#else 754 <c_ecc_mul2add, 755#endif /* MECC_FP */ 756#else 757 NULL, 758#endif /* LTC_ECC_SHAMIR */ 759#else 760 NULL, NULL, NULL, NULL, NULL, 761#endif /* MECC */ 762 763#ifdef MRSA 764 &rsa_make_key, 765 &rsa_exptmod, 766#else 767 NULL, NULL 768#endif 769 770}; 771 772 773#endif 774 775/* $Source: /cvs/libtom/libtomcrypt/src/math/tfm_desc.c,v $ */ 776/* $Revision: 1.26 $ */ 777/* $Date: 2006/12/03 00:39:56 $ */ 778