Home | History | Annotate | Download | only in math
      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    &copy,
    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    &divide,
    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    &ltc_ecc_fp_mulmod,
    451 #else
    452    &ltc_ecc_mulmod,
    453 #endif
    454    &ltc_ecc_projective_add_point,
    455    &ltc_ecc_projective_dbl_point,
    456    &ltc_ecc_map,
    457 #ifdef LTC_ECC_SHAMIR
    458 #ifdef MECC_FP
    459    &ltc_ecc_fp_mul2add,
    460 #else
    461    &ltc_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