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

📄 libtommath.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * 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) */static 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 LTM_NO_NEG_EXP        return MP_VAL;#else /* LTM_NO_NEG_EXP */#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 #error mp_exptmod would always fail     /* no invmod */     return MP_VAL;#endif#endif /* LTM_NO_NEG_EXP */  }/* modified diminished radix reduction */#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_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#error mp_exptmod could fail    /* no exptmod for evens */    return MP_VAL;#endif#ifdef BN_MP_EXPTMOD_FAST_C  }#endif}/* compare two ints (signed)*/static int mp_cmp (mp_int * a, mp_int * b){  /* compare based on sign */  if (a->sign != b->sign) {     if (a->sign == MP_NEG) {        return MP_LT;     } else {        return MP_GT;     }  }    /* compare digits */  if (a->sign == MP_NEG) {     /* if negative compare opposite direction */     return mp_cmp_mag(b, a);  } else {     return mp_cmp_mag(a, b);  }}/* compare a digit */static int mp_cmp_d(mp_int * a, mp_digit b){  /* compare based on sign */  if (a->sign == MP_NEG) {    return MP_LT;  }  /* compare based on magnitude */  if (a->used > 1) {    return MP_GT;  }  /* compare the only digit of a to b */  if (a->dp[0] > b) {    return MP_GT;  } else if (a->dp[0] < b) {    return MP_LT;  } else {    return MP_EQ;  }}#ifndef LTM_NO_NEG_EXP/* hac 14.61, pp608 */static int mp_invmod (mp_int * a, mp_int * b, mp_int * c){  /* b cannot be negative */  if (b->sign == MP_NEG || mp_iszero(b) == 1) {    return MP_VAL;  }#ifdef BN_FAST_MP_INVMOD_C  /* if the modulus is odd we can use a faster routine instead */  if (mp_isodd (b) == 1) {    return fast_mp_invmod (a, b, c);  }#endif#ifdef BN_MP_INVMOD_SLOW_C  return mp_invmod_slow(a, b, c);#endif#ifndef BN_FAST_MP_INVMOD_C#ifndef BN_MP_INVMOD_SLOW_C#error mp_invmod would always fail#endif#endif  return MP_VAL;}#endif /* LTM_NO_NEG_EXP *//* get the size for an unsigned equivalent */static int mp_unsigned_bin_size (mp_int * a){  int     size = mp_count_bits (a);  return (size / 8 + ((size & 7) != 0 ? 1 : 0));}#ifndef LTM_NO_NEG_EXP/* hac 14.61, pp608 */static int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c){  mp_int  x, y, u, v, A, B, C, D;  int     res;  /* b cannot be negative */  if (b->sign == MP_NEG || mp_iszero(b) == 1) {    return MP_VAL;  }  /* init temps */  if ((res = mp_init_multi(&x, &y, &u, &v,                            &A, &B, &C, &D, NULL)) != MP_OKAY) {     return res;  }  /* x = a, y = b */  if ((res = mp_mod(a, b, &x)) != MP_OKAY) {      goto LBL_ERR;  }  if ((res = mp_copy (b, &y)) != MP_OKAY) {    goto LBL_ERR;  }  /* 2. [modified] if x,y are both even then return an error! */  if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {    res = MP_VAL;    goto LBL_ERR;  }  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */  if ((res = mp_copy (&x, &u)) != MP_OKAY) {    goto LBL_ERR;  }  if ((res = mp_copy (&y, &v)) != MP_OKAY) {    goto LBL_ERR;  }  mp_set (&A, 1);  mp_set (&D, 1);top:  /* 4.  while u is even do */  while (mp_iseven (&u) == 1) {    /* 4.1 u = u/2 */    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {      goto LBL_ERR;    }    /* 4.2 if A or B is odd then */    if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {      /* A = (A+y)/2, B = (B-x)/2 */      if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {         goto LBL_ERR;      }      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {         goto LBL_ERR;      }    }    /* A = A/2, B = B/2 */    if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {      goto LBL_ERR;    }    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {      goto LBL_ERR;    }  }  /* 5.  while v is even do */  while (mp_iseven (&v) == 1) {    /* 5.1 v = v/2 */    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {      goto LBL_ERR;    }    /* 5.2 if C or D is odd then */    if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {      /* C = (C+y)/2, D = (D-x)/2 */      if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {         goto LBL_ERR;      }      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {         goto LBL_ERR;      }    }    /* C = C/2, D = D/2 */    if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {      goto LBL_ERR;    }    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {      goto LBL_ERR;    }  }  /* 6.  if u >= v then */  if (mp_cmp (&u, &v) != MP_LT) {    /* u = u - v, A = A - C, B = B - D */    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {      goto LBL_ERR;    }    if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {      goto LBL_ERR;    }    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {      goto LBL_ERR;    }  } else {    /* v - v - u, C = C - A, D = D - B */    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {      goto LBL_ERR;    }    if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {      goto LBL_ERR;    }    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {      goto LBL_ERR;    }  }  /* if not zero goto step 4 */  if (mp_iszero (&u) == 0)    goto top;  /* now a = C, b = D, gcd == g*v */  /* if v != 1 then there is no inverse */  if (mp_cmp_d (&v, 1) != MP_EQ) {    res = MP_VAL;    goto LBL_ERR;  }  /* if its too low */  while (mp_cmp_d(&C, 0) == MP_LT) {      if ((res = mp_add(&C, b, &C)) != MP_OKAY) {         goto LBL_ERR;      }  }    /* too big */  while (mp_cmp_mag(&C, b) != MP_LT) {      if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {         goto LBL_ERR;      }  }    /* C is now the inverse */  mp_exch (&C, c);  res = MP_OKAY;LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);  return res;}#endif /* LTM_NO_NEG_EXP *//* compare maginitude of two ints (unsigned) */static int mp_cmp_mag (mp_int * a, mp_int * b){  int     n;  mp_digit *tmpa, *tmpb;  /* compare based on # of non-zero digits */  if (a->used > b->used) {    return MP_GT;  }    if (a->used < b->used) {    return MP_LT;  }  /* alias for a */  tmpa = a->dp + (a->used - 1);  /* alias for b */  tmpb = b->dp + (a->used - 1);  /* compare based on digits  */  for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {    if (*tmpa > *tmpb) {      return MP_GT;    }    if (*tmpa < *tmpb) {      return MP_LT;    }  }  return MP_EQ;}/* reads a unsigned char array, assumes the msb is stored first [big endian] */static int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c){  int     res;  /* make sure there are at least two digits */  if (a->alloc < 2) {     if ((res = mp_grow(a, 2)) != MP_OKAY) {        return res;     }  }  /* zero the int */  mp_zero (a);  /* read the bytes in */  while (c-- > 0) {    if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {      return res;    }#ifndef MP_8BIT      a->dp[0] |= *b++;      a->used += 1;#else      a->dp[0] = (*b & MP_MASK);      a->dp[1] |= ((*b++ >> 7U) & 1);      a->used += 2;#endif  }  mp_clamp (a);  return MP_OKAY;}/* store in unsigned [big endian] format */static int mp_to_unsigned_bin (mp_int * a, unsigned char *b){  int     x, res;  mp_int  t;  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {    return res;  }  x = 0;  while (mp_iszero (&t) == 0) {#ifndef MP_8BIT      b[x++] = (unsigned char) (t.dp[0] & 255);#else      b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));#endif    if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {      mp_clear (&t);      return res;    }  }  bn_reverse (b, x);  mp_clear (&t);  return MP_OKAY;}/* shift right by a certain bit count (store quotient in c, optional remainder in d) */static int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d){  mp_digit D, r, rr;  int     x, res;  mp_int  t;  /* if the shift count is <= 0 then we do no work */  if (b <= 0) {    res = mp_copy (a, c);    if (d != NULL) {      mp_zero (d);    }    return res;  }  if ((res = mp_init (&t)) != MP_OKAY) {    return res;  }  /* get the remainder */  if (d != NULL) {    if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {      mp_clear (&t);      return res;    }  }  /* copy */  if ((res = mp_copy (a, c)) != MP_OKAY) {    mp_clear (&t);    return res;  }  /* shift by as many digits in the bit count */  if (b >= (int)DIGIT_BIT) {    mp_rshd (c, b / DIGIT_BIT);  }  /* shift any bit count < DIGIT_BIT */  D = (mp_digit) (b % DIGIT_BIT);  if (D != 0) {    register mp_digit *tmpc, mask, shift;    /* mask */    mask = (((mp_digit)1) << D) - 1;    /* shift for lsb */    shift = DIGIT_BIT - D;    /* alias */    tmpc = c->dp + (c->used - 1);    /* carry */    r = 0;    for (x = c->used - 1; x >= 0; x--) {      /* get the lower  bits of this word in a temp */      rr = *tmpc & mask;      /* shift the current word and mix in the carry bits from the previous word */      *tmpc = (*tmpc >> D) | (r << shift);      --tmpc;      /* set the carry to the carry bits of the current word found above */      r = rr;    }  }  mp_clamp (c);  if (d != NULL) {    mp_exch (&t, d);  }  mp_clear (&t);  return MP_OKAY;}static int mp_init_copy (mp_int * a, mp_int * b){  int     res;  if ((res = mp_init (a)) != MP_OKAY) {    return res;  }  return mp_copy (b, a);}/* set to zero */static void mp_zero (mp_int * a){  int       n;  mp_digit *tmp;  a->sign = MP_ZPOS;  a->used = 0;  tmp = a->dp;  for (n = 0; n < a->alloc; n++) {     *tmp++ = 0;  }}/* copy, b = a */static int mp_copy (mp_int * a, mp_int * b){  int     res, n;  /* if dst == src do nothing */  if (a == b) {    return MP_OKAY;  }  /* grow dest */  if (b->alloc < a->used) {     if ((res = mp_grow (b, a->used)) != MP_OKAY) {        return res;     }  }  /* zero b and copy the parameters over */  {    register mp_digit *tmpa, *tmpb;    /* pointer aliases */    /* source */    tmpa = a->dp;    /* destination */    tmpb = b->dp;    /* copy all the digits */    for (n = 0; n < a->used; n++) {      *tmpb++ = *tmpa++;    }    /* clear high digits */    for (; n < b->used; n++) {      *tmpb++ = 0;

⌨️ 快捷键说明

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