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

📄 libtommath.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 4 页
字号:
   */  while (a->used > 0 && a->dp[a->used - 1] == 0) {    --(a->used);  }  /* reset the sign flag if used == 0 */  if (a->used == 0) {    a->sign = MP_ZPOS;  }}/* grow as required */static int mp_grow (mp_int * a, int size){  int     i;  mp_digit *tmp;  /* if the alloc size is smaller alloc more ram */  if (a->alloc < size) {    /* ensure there are always at least MP_PREC digits extra on top */    size += (MP_PREC * 2) - (size % MP_PREC);    /* reallocate the array a->dp     *     * We store the return in a temporary variable     * in case the operation failed we don't want     * to overwrite the dp member of a.     */    tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);    if (tmp == NULL) {      /* reallocation failed but "a" is still valid [can be freed] */      return MP_MEM;    }    /* reallocation succeeded so set a->dp */    a->dp = tmp;    /* zero excess digits */    i        = a->alloc;    a->alloc = size;    for (; i < a->alloc; i++) {      a->dp[i] = 0;    }  }  return MP_OKAY;}/* b = |a|  * * Simple function copies the input and fixes the sign to positive */static int mp_abs (mp_int * a, mp_int * b){  int     res;  /* copy a to b */  if (a != b) {     if ((res = mp_copy (a, b)) != MP_OKAY) {       return res;     }  }  /* force the sign of b to positive */  b->sign = MP_ZPOS;  return MP_OKAY;}/* set to a digit */static void mp_set (mp_int * a, mp_digit b){  mp_zero (a);  a->dp[0] = b & MP_MASK;  a->used  = (a->dp[0] != 0) ? 1 : 0;}/* b = a/2 */static int mp_div_2(mp_int * a, mp_int * b){  int     x, res, oldused;  /* copy */  if (b->alloc < a->used) {    if ((res = mp_grow (b, a->used)) != MP_OKAY) {      return res;    }  }  oldused = b->used;  b->used = a->used;  {    register mp_digit r, rr, *tmpa, *tmpb;    /* source alias */    tmpa = a->dp + b->used - 1;    /* dest alias */    tmpb = b->dp + b->used - 1;    /* carry */    r = 0;    for (x = b->used - 1; x >= 0; x--) {      /* get the carry for the next iteration */      rr = *tmpa & 1;      /* shift the current digit, add in carry and store */      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));      /* forward carry to next iteration */      r = rr;    }    /* zero excess digits */    tmpb = b->dp + b->used;    for (x = b->used; x < oldused; x++) {      *tmpb++ = 0;    }  }  b->sign = a->sign;  mp_clamp (b);  return MP_OKAY;}/* shift left by a certain bit count */static int mp_mul_2d (mp_int * a, int b, mp_int * c){  mp_digit d;  int      res;  /* copy */  if (a != c) {     if ((res = mp_copy (a, c)) != MP_OKAY) {       return res;     }  }  if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {     if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {       return res;     }  }  /* shift by as many digits in the bit count */  if (b >= (int)DIGIT_BIT) {    if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {      return res;    }  }  /* shift any bit count < DIGIT_BIT */  d = (mp_digit) (b % DIGIT_BIT);  if (d != 0) {    register mp_digit *tmpc, shift, mask, r, rr;    register int x;    /* bitmask for carries */    mask = (((mp_digit)1) << d) - 1;    /* shift for msbs */    shift = DIGIT_BIT - d;    /* alias */    tmpc = c->dp;    /* carry */    r    = 0;    for (x = 0; x < c->used; x++) {      /* get the higher bits of the current word */      rr = (*tmpc >> shift) & mask;      /* shift the current word and OR in the carry */      *tmpc = ((*tmpc << d) | r) & MP_MASK;      ++tmpc;      /* set the carry to the carry bits of the current word */      r = rr;    }        /* set final carry */    if (r != 0) {       c->dp[(c->used)++] = r;    }  }  mp_clamp (c);  return MP_OKAY;}static int mp_init_multi(mp_int *mp, ...) {    mp_err res = MP_OKAY;      /* Assume ok until proven otherwise */    int n = 0;                 /* Number of ok inits */    mp_int* cur_arg = mp;    va_list args;    va_start(args, mp);        /* init args to next argument from caller */    while (cur_arg != NULL) {        if (mp_init(cur_arg) != MP_OKAY) {            /* Oops - error! Back-track and mp_clear what we already               succeeded in init-ing, then return error.            */            va_list clean_args;                        /* end the current list */            va_end(args);                        /* now start cleaning up */                        cur_arg = mp;            va_start(clean_args, mp);            while (n--) {                mp_clear(cur_arg);                cur_arg = va_arg(clean_args, mp_int*);            }            va_end(clean_args);            res = MP_MEM;            break;        }        n++;        cur_arg = va_arg(args, mp_int*);    }    va_end(args);    return res;                /* Assumed ok, if error flagged above. */}static void mp_clear_multi(mp_int *mp, ...) {    mp_int* next_mp = mp;    va_list args;    va_start(args, mp);    while (next_mp != NULL) {        mp_clear(next_mp);        next_mp = va_arg(args, mp_int*);    }    va_end(args);}/* shift left a certain amount of digits */static int mp_lshd (mp_int * a, int b){  int     x, res;  /* if its less than zero return */  if (b <= 0) {    return MP_OKAY;  }  /* grow to fit the new digits */  if (a->alloc < a->used + b) {     if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {       return res;     }  }  {    register mp_digit *top, *bottom;    /* increment the used by the shift amount then copy upwards */    a->used += b;    /* top */    top = a->dp + a->used - 1;    /* base */    bottom = a->dp + a->used - 1 - b;    /* much like mp_rshd this is implemented using a sliding window     * except the window goes the otherway around.  Copying from     * the bottom to the top.  see bn_mp_rshd.c for more info.     */    for (x = a->used - 1; x >= b; x--) {      *top-- = *bottom--;    }    /* zero the lower digits */    top = a->dp;    for (x = 0; x < b; x++) {      *top++ = 0;    }  }  return MP_OKAY;}/* returns the number of bits in an int */static int mp_count_bits (mp_int * a){  int     r;  mp_digit q;  /* shortcut */  if (a->used == 0) {    return 0;  }  /* get number of digits and add that */  r = (a->used - 1) * DIGIT_BIT;    /* take the last digit and count the bits in it */  q = a->dp[a->used - 1];  while (q > ((mp_digit) 0)) {    ++r;    q >>= ((mp_digit) 1);  }  return r;}/* calc a value mod 2**b */static int mp_mod_2d (mp_int * a, int b, mp_int * c){  int     x, res;  /* if b is <= 0 then zero the int */  if (b <= 0) {    mp_zero (c);    return MP_OKAY;  }  /* if the modulus is larger than the value than return */  if (b >= (int) (a->used * DIGIT_BIT)) {    res = mp_copy (a, c);    return res;  }  /* copy */  if ((res = mp_copy (a, c)) != MP_OKAY) {    return res;  }  /* zero digits above the last digit of the modulus */  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {    c->dp[x] = 0;  }  /* clear the digit that is not completely outside/inside the modulus */  c->dp[b / DIGIT_BIT] &=    (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));  mp_clamp (c);  return MP_OKAY;}/* slower bit-bang division... also smaller */static int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d){   mp_int ta, tb, tq, q;   int    res, n, n2;  /* is divisor zero ? */  if (mp_iszero (b) == 1) {    return MP_VAL;  }  /* if a < b then q=0, r = a */  if (mp_cmp_mag (a, b) == MP_LT) {    if (d != NULL) {      res = mp_copy (a, d);    } else {      res = MP_OKAY;    }    if (c != NULL) {      mp_zero (c);    }    return res;  }	  /* init our temps */  if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {     return res;  }  mp_set(&tq, 1);  n = mp_count_bits(a) - mp_count_bits(b);  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||      ((res = mp_abs(b, &tb)) != MP_OKAY) ||       ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {      goto LBL_ERR;  }  while (n-- >= 0) {     if (mp_cmp(&tb, &ta) != MP_GT) {        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {           goto LBL_ERR;        }     }     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {           goto LBL_ERR;     }  }  /* now q == quotient and ta == remainder */  n  = a->sign;  n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);  if (c != NULL) {     mp_exch(c, &q);     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;  }  if (d != NULL) {     mp_exch(d, &ta);     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;  }LBL_ERR:   mp_clear_multi(&ta, &tb, &tq, &q, NULL);   return res;}#ifdef MP_LOW_MEM   #define TAB_SIZE 32#else   #define TAB_SIZE 256#endifstatic int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode){  mp_int  M[TAB_SIZE], res, mu;  mp_digit buf;  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;  int (*redux)(mp_int*,mp_int*,mp_int*);  /* 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;    }  }  /* create mu, used for Barrett reduction */  if ((err = mp_init (&mu)) != MP_OKAY) {    goto LBL_M;  }    if (redmode == 0) {     if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {        goto LBL_MU;     }     redux = mp_reduce;  } else {     if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {        goto LBL_MU;     }     redux = mp_reduce_2k_l;  }      /* create M table   *   * The M table contains powers of the base,    * e.g. M[x] = G**x mod P   *   * The first half of the table is not    * computed though accept for M[0] and M[1]   */  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {    goto LBL_MU;  }  /* 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_MU;  }  for (x = 0; x < (winsize - 1); x++) {    /* square it */    if ((err = mp_sqr (&M[1 << (winsize - 1)],                        &M[1 << (winsize - 1)])) != MP_OKAY) {      goto LBL_MU;    }    /* reduce modulo P */    if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {      goto LBL_MU;    }  }  /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)   * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)   */  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_MU;    }    if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {      goto LBL_MU;    }  }  /* setup result */  if ((err = mp_init (&res)) != MP_OKAY) {    goto LBL_MU;  }  mp_set (&res, 1);  /* 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 */      if (digidx == -1) {        break;      }      /* read next digit and reset the bitcnt */      buf    = X->dp[digidx--];      bitcnt = (int) DIGIT_BIT;    }    /* grab the next msb from the exponent */    y     = (buf >> (mp_digit)(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 == 1 && y == 0) {      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {        goto LBL_RES;      }      if ((err = redux (&res, P, &mu)) != MP_OKAY) {        goto LBL_RES;      }      continue;    }    /* else we add it to the window */    bitbuf |= (y << (winsize - ++bitcpy));    mode    = 2;    if (bitcpy == winsize) {      /* ok window is filled so square as required and multiply  */      /* square first */      for (x = 0; x < winsize; x++) {        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {          goto LBL_RES;        }

⌨️ 快捷键说明

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