⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpi.c

📁 该压缩包中包括 tom的加密函数库及pdf说明 ,以及Rinick s ECC:椭圆曲线非对称加密密钥生成器
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org *//* reduce "x" in place modulo "n" using the Diminished Radix algorithm. * * Based on algorithm from the paper * * "Generating Efficient Primes for Discrete Log Cryptosystems" *                 Chae Hoon Lim, Pil Joong Lee, *          POSTECH Information Research Laboratories * * The modulus must be of a special format [see manual] * * Has been modified to use algorithm 7.10 from the LTM book instead * * Input x must be in the range 0 <= x <= (n-1)**2 */intmp_dr_reduce (mp_int * x, mp_int * n, mp_digit k){  int      err, i, m;  mp_word  r;  mp_digit mu, *tmpx1, *tmpx2;  /* m = digits in modulus */  m = n->used;  /* ensure that "x" has at least 2m digits */  if (x->alloc < m + m) {    if ((err = mp_grow (x, m + m)) != MP_OKAY) {      return err;    }  }/* top of loop, this is where the code resumes if * another reduction pass is required. */top:  /* aliases for digits */  /* alias for lower half of x */  tmpx1 = x->dp;  /* alias for upper half of x, or x/B**m */  tmpx2 = x->dp + m;  /* set carry to zero */  mu = 0;  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */  for (i = 0; i < m; i++) {      r         = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;      *tmpx1++  = (mp_digit)(r & MP_MASK);      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));  }  /* set final carry */  *tmpx1++ = mu;  /* zero words above m */  for (i = m + 1; i < x->used; i++) {      *tmpx1++ = 0;  }  /* clamp, sub and return */  mp_clamp (x);  /* if x >= n then subtract and reduce again   * Each successive "recursion" makes the input smaller and smaller.   */  if (mp_cmp_mag (x, n) != MP_LT) {    s_mp_sub(x, n, x);    goto top;  }  return MP_OKAY;}#endif/* End: bn_mp_dr_reduce.c *//* Start: bn_mp_dr_setup.c */#include <ltc_tommath.h>#ifdef BN_MP_DR_SETUP_C/* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org *//* determines the setup value */void mp_dr_setup(mp_int *a, mp_digit *d){   /* the casts are required if DIGIT_BIT is one less than    * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]    */   *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -         ((mp_word)a->dp[0]));}#endif/* End: bn_mp_dr_setup.c *//* Start: bn_mp_exch.c */#include <ltc_tommath.h>#ifdef BN_MP_EXCH_C/* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org *//* swap the elements of two integers, for cases where you can't simply swap the  * mp_int pointers around */voidmp_exch (mp_int * a, mp_int * b){  mp_int  t;  t  = *a;  *a = *b;  *b = t;}#endif/* End: bn_mp_exch.c *//* Start: bn_mp_expt_d.c */#include <ltc_tommath.h>#ifdef BN_MP_EXPT_D_C/* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org *//* calculate c = a**b  using a square-multiply algorithm */int mp_expt_d (mp_int * a, mp_digit b, mp_int * c){  int     res, x;  mp_int  g;  if ((res = mp_init_copy (&g, a)) != MP_OKAY) {    return res;  }  /* set initial result */  mp_set (c, 1);  for (x = 0; x < (int) DIGIT_BIT; x++) {    /* square */    if ((res = mp_sqr (c, c)) != MP_OKAY) {      mp_clear (&g);      return res;    }    /* if the bit is set multiply */    if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {      if ((res = mp_mul (c, &g, c)) != MP_OKAY) {         mp_clear (&g);         return res;      }    }    /* shift to next bit */    b <<= 1;  }  mp_clear (&g);  return MP_OKAY;}#endif/* End: bn_mp_expt_d.c *//* Start: bn_mp_exptmod.c */#include <ltc_tommath.h>#ifdef BN_MP_EXPTMOD_C/* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org *//* this is a shell function that calls either the normal or Montgomery * exptmod functions.  Originally the call to the montgomery code was * embedded in the normal function but that wasted alot of stack space * for nothing (since 99% of the time the Montgomery code would be called) */int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y){  int dr;  /* modulus P must be positive */  if (P->sign == MP_NEG) {     return MP_VAL;  }  /* if exponent X is negative we have to recurse */  if (X->sign == MP_NEG) {#ifdef BN_MP_INVMOD_C     mp_int tmpG, tmpX;     int err;     /* first compute 1/G mod P */     if ((err = mp_init(&tmpG)) != MP_OKAY) {        return err;     }     if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {        mp_clear(&tmpG);        return err;     }     /* now get |X| */     if ((err = mp_init(&tmpX)) != MP_OKAY) {        mp_clear(&tmpG);        return err;     }     if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {        mp_clear_multi(&tmpG, &tmpX, NULL);        return err;     }     /* and now compute (1/G)**|X| instead of G**X [X < 0] */     err = mp_exptmod(&tmpG, &tmpX, P, Y);     mp_clear_multi(&tmpG, &tmpX, NULL);     return err;#else      /* no invmod */     return MP_VAL;#endif  }/* modified diminished radix reduction */#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C)  if (mp_reduce_is_2k_l(P) == MP_YES) {     return s_mp_exptmod(G, X, P, Y, 1);  }#endif#ifdef BN_MP_DR_IS_MODULUS_C  /* is it a DR modulus? */  dr = mp_dr_is_modulus(P);#else  /* default to no */  dr = 0;#endif#ifdef BN_MP_REDUCE_IS_2K_C  /* if not, is it a unrestricted DR modulus? */  if (dr == 0) {     dr = mp_reduce_is_2k(P) << 1;  }#endif      /* if the modulus is odd or dr != 0 use the montgomery method */#ifdef BN_MP_EXPTMOD_FAST_C  if (mp_isodd (P) == 1 || dr !=  0) {    return mp_exptmod_fast (G, X, P, Y, dr);  } else {#endif#ifdef BN_S_MP_EXPTMOD_C    /* otherwise use the generic Barrett reduction technique */    return s_mp_exptmod (G, X, P, Y, 0);#else    /* no exptmod for evens */    return MP_VAL;#endif#ifdef BN_MP_EXPTMOD_FAST_C  }#endif}#endif/* End: bn_mp_exptmod.c *//* Start: bn_mp_exptmod_fast.c */#include <ltc_tommath.h>#ifdef BN_MP_EXPTMOD_FAST_C/* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org *//* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 * * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. * The value of k changes based on the size of the exponent. * * Uses Montgomery or Diminished Radix reduction [whichever appropriate] */#ifdef MP_LOW_MEM   #define TAB_SIZE 32#else   #define TAB_SIZE 256#endifint mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode){  mp_int  M[TAB_SIZE], res;  mp_digit buf, mp;  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;  /* use a pointer to the reduction algorithm.  This allows us to use   * one of many reduction algorithms without modding the guts of   * the code with if statements everywhere.   */  int     (*redux)(mp_int*,mp_int*,mp_digit);  /* find window size */  x = mp_count_bits (X);  if (x <= 7) {    winsize = 2;  } else if (x <= 36) {    winsize = 3;  } else if (x <= 140) {    winsize = 4;  } else if (x <= 450) {    winsize = 5;  } else if (x <= 1303) {    winsize = 6;  } else if (x <= 3529) {    winsize = 7;  } else {    winsize = 8;  }#ifdef MP_LOW_MEM  if (winsize > 5) {     winsize = 5;  }#endif  /* init M array */  /* init first cell */  if ((err = mp_init(&M[1])) != MP_OKAY) {     return err;  }  /* now init the second half of the array */  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {    if ((err = mp_init(&M[x])) != MP_OKAY) {      for (y = 1<<(winsize-1); y < x; y++) {        mp_clear (&M[y]);      }      mp_clear(&M[1]);      return err;    }  }  /* determine and setup reduction code */  if (redmode == 0) {#ifdef BN_MP_MONTGOMERY_SETUP_C          /* now setup montgomery  */     if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {        goto LBL_M;     }#else     err = MP_VAL;     goto LBL_M;#endif     /* automatically pick the comba one if available (saves quite a few calls/ifs) */#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C     if (((P->used * 2 + 1) < MP_WARRAY) &&          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {        redux = fast_mp_montgomery_reduce;     } else #endif     {#ifdef BN_MP_MONTGOMERY_REDUCE_C        /* use slower baseline Montgomery method */        redux = mp_montgomery_reduce;#else        err = MP_VAL;        goto LBL_M;#endif     }  } else if (redmode == 1) {#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)     /* setup DR reduction for moduli of the form B**k - b */     mp_dr_setup(P, &mp);     redux = mp_dr_reduce;#else     err = MP_VAL;     goto LBL_M;#endif  } else {#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)     /* setup DR reduction for moduli of the form 2**k - b */     if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {        goto LBL_M;     }     redux = mp_reduce_2k;#else     err = MP_VAL;     goto LBL_M;#endif  }  /* setup result */  if ((err = mp_init (&res)) != MP_OKAY) {    goto LBL_M;  }  /* create M table   *   *   * The first half of the table is not computed though accept for M[0] and M[1]   */  if (redmode == 0) {#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C     /* now we need R mod m */     if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {       goto LBL_RES;     }#else      err = MP_VAL;     goto LBL_RES;#endif     /* now set M[1] to G * R mod m */     if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {       goto LBL_RES;     }  } else {     mp_set(&res, 1);     if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {        goto LBL_RES;     }  }  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {    goto LBL_RES;  }  for (x = 0; x < (winsize - 1); x++) {    if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {      goto LBL_RES;    }    if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {      goto LBL_RES;    }  }  /* create upper table */  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {      goto LBL_RES;    }    if ((err = redux (&M[x], P, mp)) != MP_OKAY) {      goto LBL_RES;    }  }  /* set initial mode and bit cnt */  mode   = 0;  bitcnt = 1;  buf    = 0;  digidx = X->used - 1;  bitcpy = 0;  bitbuf = 0;  for (;;) {    /* grab next digit as required */    if (--bitcnt == 0) {      /* if digidx == -1 we are out of digits so break */      if (digidx == -1) {        break;      }      /* read next digit and reset bitcnt */      buf    = X->dp[digidx--];      bitcnt = (int)DIGIT_BIT;    }    /* grab the next msb from the exponent */    y     = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;    buf <<= (mp_digit)1;    /* if the bit is zero and mode == 0 then we ignore it     * These represent the leading zero bits before the first 1 bit     * in the exponent.  Technically this opt is not required but it     * does lower the # of trivial squaring/reductions used     */    if (mode == 0 && y == 0) {      continue;    }    /* if the bit is zero and mode == 1 then we square */    if (mode =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -