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 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    &copy,
    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    &divide,
    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    &ltc_ecc_fp_mulmod,
    445 #else
    446    &ltc_ecc_mulmod,
    447 #endif /* MECC_FP */
    448    &ltc_ecc_projective_add_point,
    449    &ltc_ecc_projective_dbl_point,
    450    &ltc_ecc_map,
    451 #ifdef LTC_ECC_SHAMIR
    452 #ifdef MECC_FP
    453    &ltc_ecc_fp_mul2add,
    454 #else
    455    &ltc_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