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 LTM_DESC 16 17#include <tommath.h> 18 19static 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*/ 32static 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 44static 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 61static void deinit(void *a) 62{ 63 LTC_ARGCHKVD(a != NULL); 64 mp_clear(a); 65 XFREE(a); 66} 67 68static 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 75static 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 82static 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 ---- */ 91static 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 97static unsigned long get_int(void *a) 98{ 99 LTC_ARGCHK(a != NULL); 100 return mp_get_int(a); 101} 102 103static 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 111static 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 119static 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 133static 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 146static int count_bits(void *a) 147{ 148 LTC_ARGCHK(a != NULL); 149 return mp_count_bits(a); 150} 151 152static int count_lsb_bits(void *a) 153{ 154 LTC_ARGCHK(a != NULL); 155 return mp_cnt_lsb(a); 156} 157 158 159static 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 */ 168static 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 */ 176static 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 */ 184static unsigned long unsigned_size(void *a) 185{ 186 LTC_ARGCHK(a != NULL); 187 return mp_unsigned_bin_size(a); 188} 189 190/* store */ 191static 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 */ 199static 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 */ 207static 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 215static 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 */ 223static 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 231static 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 */ 239static 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 247static 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 */ 255static 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 */ 263static 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 270static 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 */ 278static 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 */ 294static 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 */ 303static 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 311static 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 320static 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 */ 329static 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 */ 338static 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 */ 354static 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 */ 362static 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 */ 371static void montgomery_deinit(void *a) 372{ 373 XFREE(a); 374} 375 376static 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 385static 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 395const 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