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

📄 libtommath.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Minimal code for RSA support from LibTomMath 0.41 * http://libtom.org/ * http://libtom.org/files/ltm-0.41.tar.bz2 * This library was released in public domain by Tom St Denis. * * The combination in this file may not use all of the optimized algorithms * from LibTomMath and may be considerable slower than the LibTomMath with its * default settings. The main purpose of having this version here is to make it * easier to build bignum.c wrapper without having to install and build an * external library. * * If CONFIG_INTERNAL_LIBTOMMATH is defined, bignum.c includes this * libtommath.c file instead of using the external LibTomMath library. */#ifndef CHAR_BIT#define CHAR_BIT 8#endif#define BN_MP_INVMOD_C#define BN_S_MP_EXPTMOD_C /* Note: #undef in tommath_superclass.h; this would			   * require BN_MP_EXPTMOD_FAST_C instead */#define BN_S_MP_MUL_DIGS_C#define BN_MP_INVMOD_SLOW_C#define BN_S_MP_SQR_C#define BN_S_MP_MUL_HIGH_DIGS_C /* Note: #undef in tommath_superclass.h; this				 * would require other than mp_reduce */#ifdef LTM_FAST/* Use faster div at the cost of about 1 kB */#define BN_MP_MUL_D_C/* Include faster exptmod (Montgomery) at the cost of about 2.5 kB in code */#define BN_MP_EXPTMOD_FAST_C#define BN_MP_MONTGOMERY_SETUP_C#define BN_FAST_MP_MONTGOMERY_REDUCE_C#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C#define BN_MP_MUL_2_C/* Include faster sqr at the cost of about 0.5 kB in code */#define BN_FAST_S_MP_SQR_C#else /* LTM_FAST */#define BN_MP_DIV_SMALL#define BN_MP_INIT_MULTI_C#define BN_MP_CLEAR_MULTI_C#define BN_MP_ABS_C#endif /* LTM_FAST *//* Current uses do not require support for negative exponent in exptmod, so we * can save about 1.5 kB in leaving out invmod. */#define LTM_NO_NEG_EXP/* from tommath.h */#ifndef MIN   #define MIN(x,y) ((x)<(y)?(x):(y))#endif#ifndef MAX   #define MAX(x,y) ((x)>(y)?(x):(y))#endif#define  OPT_CAST(x)typedef unsigned long mp_digit;typedef u64 mp_word;#define DIGIT_BIT          28#define MP_28BIT#define XMALLOC  os_malloc#define XFREE    os_free#define XREALLOC os_realloc#define MP_MASK          ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))#define MP_LT        -1   /* less than */#define MP_EQ         0   /* equal to */#define MP_GT         1   /* greater than */#define MP_ZPOS       0   /* positive integer */#define MP_NEG        1   /* negative */#define MP_OKAY       0   /* ok result */#define MP_MEM        -2  /* out of mem */#define MP_VAL        -3  /* invalid input */#define MP_YES        1   /* yes response */#define MP_NO         0   /* no response */typedef int           mp_err;/* define this to use lower memory usage routines (exptmods mostly) */#define MP_LOW_MEM/* default precision */#ifndef MP_PREC   #ifndef MP_LOW_MEM      #define MP_PREC                 32     /* default digits of precision */   #else      #define MP_PREC                 8      /* default digits of precision */   #endif   #endif/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */#define MP_WARRAY               (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))/* the infamous mp_int structure */typedef struct  {    int used, alloc, sign;    mp_digit *dp;} mp_int;/* ---> Basic Manipulations <--- */#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)#define mp_isodd(a)  (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)/* prototypes for copied functions */#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)static int s_mp_exptmod(mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);static int s_mp_sqr(mp_int * a, mp_int * b);static int s_mp_mul_high_digs(mp_int * a, mp_int * b, mp_int * c, int digs);static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);#ifdef BN_MP_INIT_MULTI_Cstatic int mp_init_multi(mp_int *mp, ...);#endif#ifdef BN_MP_CLEAR_MULTI_Cstatic void mp_clear_multi(mp_int *mp, ...);#endifstatic int mp_lshd(mp_int * a, int b);static void mp_set(mp_int * a, mp_digit b);static void mp_clamp(mp_int * a);static void mp_exch(mp_int * a, mp_int * b);static void mp_rshd(mp_int * a, int b);static void mp_zero(mp_int * a);static int mp_mod_2d(mp_int * a, int b, mp_int * c);static int mp_div_2d(mp_int * a, int b, mp_int * c, mp_int * d);static int mp_init_copy(mp_int * a, mp_int * b);static int mp_mul_2d(mp_int * a, int b, mp_int * c);#ifndef LTM_NO_NEG_EXPstatic int mp_div_2(mp_int * a, mp_int * b);static int mp_invmod(mp_int * a, mp_int * b, mp_int * c);static int mp_invmod_slow(mp_int * a, mp_int * b, mp_int * c);#endif /* LTM_NO_NEG_EXP */static int mp_copy(mp_int * a, mp_int * b);static int mp_count_bits(mp_int * a);static int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);static int mp_mod(mp_int * a, mp_int * b, mp_int * c);static int mp_grow(mp_int * a, int size);static int mp_cmp_mag(mp_int * a, mp_int * b);#ifdef BN_MP_ABS_Cstatic int mp_abs(mp_int * a, mp_int * b);#endifstatic int mp_sqr(mp_int * a, mp_int * b);static int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);static int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);static int mp_2expt(mp_int * a, int b);static int mp_reduce_setup(mp_int * a, mp_int * b);static int mp_reduce(mp_int * x, mp_int * m, mp_int * mu);static int mp_init_size(mp_int * a, int size);#ifdef BN_MP_EXPTMOD_FAST_Cstatic int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);#endif /* BN_MP_EXPTMOD_FAST_C */#ifdef BN_FAST_S_MP_SQR_Cstatic int fast_s_mp_sqr (mp_int * a, mp_int * b);#endif /* BN_FAST_S_MP_SQR_C */#ifdef BN_MP_MUL_D_Cstatic int mp_mul_d (mp_int * a, mp_digit b, mp_int * c);#endif /* BN_MP_MUL_D_C *//* functions from bn_<func name>.c *//* reverse an array, used for radix code */static void bn_reverse (unsigned char *s, int len){  int     ix, iy;  unsigned char t;  ix = 0;  iy = len - 1;  while (ix < iy) {    t     = s[ix];    s[ix] = s[iy];    s[iy] = t;    ++ix;    --iy;  }}/* low level addition, based on HAC pp.594, Algorithm 14.7 */static int s_mp_add (mp_int * a, mp_int * b, mp_int * c){  mp_int *x;  int     olduse, res, min, max;  /* find sizes, we let |a| <= |b| which means we have to sort   * them.  "x" will point to the input with the most digits   */  if (a->used > b->used) {    min = b->used;    max = a->used;    x = a;  } else {    min = a->used;    max = b->used;    x = b;  }  /* init result */  if (c->alloc < max + 1) {    if ((res = mp_grow (c, max + 1)) != MP_OKAY) {      return res;    }  }  /* get old used digit count and set new one */  olduse = c->used;  c->used = max + 1;  {    register mp_digit u, *tmpa, *tmpb, *tmpc;    register int i;    /* alias for digit pointers */    /* first input */    tmpa = a->dp;    /* second input */    tmpb = b->dp;    /* destination */    tmpc = c->dp;    /* zero the carry */    u = 0;    for (i = 0; i < min; i++) {      /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */      *tmpc = *tmpa++ + *tmpb++ + u;      /* U = carry bit of T[i] */      u = *tmpc >> ((mp_digit)DIGIT_BIT);      /* take away carry bit from T[i] */      *tmpc++ &= MP_MASK;    }    /* now copy higher words if any, that is in A+B      * if A or B has more digits add those in      */    if (min != max) {      for (; i < max; i++) {        /* T[i] = X[i] + U */        *tmpc = x->dp[i] + u;        /* U = carry bit of T[i] */        u = *tmpc >> ((mp_digit)DIGIT_BIT);        /* take away carry bit from T[i] */        *tmpc++ &= MP_MASK;      }    }    /* add carry */    *tmpc++ = u;    /* clear digits above oldused */    for (i = c->used; i < olduse; i++) {      *tmpc++ = 0;    }  }  mp_clamp (c);  return MP_OKAY;}/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */static int s_mp_sub (mp_int * a, mp_int * b, mp_int * c){  int     olduse, res, min, max;  /* find sizes */  min = b->used;  max = a->used;  /* init result */  if (c->alloc < max) {    if ((res = mp_grow (c, max)) != MP_OKAY) {      return res;    }  }  olduse = c->used;  c->used = max;  {    register mp_digit u, *tmpa, *tmpb, *tmpc;    register int i;    /* alias for digit pointers */    tmpa = a->dp;    tmpb = b->dp;    tmpc = c->dp;    /* set carry to zero */    u = 0;    for (i = 0; i < min; i++) {      /* T[i] = A[i] - B[i] - U */      *tmpc = *tmpa++ - *tmpb++ - u;      /* U = carry bit of T[i]       * Note this saves performing an AND operation since       * if a carry does occur it will propagate all the way to the       * MSB.  As a result a single shift is enough to get the carry       */      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));      /* Clear carry from T[i] */      *tmpc++ &= MP_MASK;    }    /* now copy higher words if any, e.g. if A has more digits than B  */    for (; i < max; i++) {      /* T[i] = A[i] - U */      *tmpc = *tmpa++ - u;      /* U = carry bit of T[i] */      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));      /* Clear carry from T[i] */      *tmpc++ &= MP_MASK;    }    /* clear digits above used (since we may not have grown result above) */    for (i = c->used; i < olduse; i++) {      *tmpc++ = 0;    }  }  mp_clamp (c);  return MP_OKAY;}/* init a new mp_int */static int mp_init (mp_int * a){  int i;  /* allocate memory required and clear it */  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);  if (a->dp == NULL) {    return MP_MEM;  }  /* set the digits to zero */  for (i = 0; i < MP_PREC; i++) {      a->dp[i] = 0;  }  /* set the used to zero, allocated digits to the default precision   * and sign to positive */  a->used  = 0;  a->alloc = MP_PREC;  a->sign  = MP_ZPOS;  return MP_OKAY;}/* clear one (frees)  */static void mp_clear (mp_int * a){  int i;  /* only do anything if a hasn't been freed previously */  if (a->dp != NULL) {    /* first zero the digits */    for (i = 0; i < a->used; i++) {        a->dp[i] = 0;    }    /* free ram */    XFREE(a->dp);    /* reset members to make debugging easier */    a->dp    = NULL;    a->alloc = a->used = 0;    a->sign  = MP_ZPOS;  }}/* high level addition (handles signs) */static int mp_add (mp_int * a, mp_int * b, mp_int * c){  int     sa, sb, res;  /* get sign of both inputs */  sa = a->sign;  sb = b->sign;  /* handle two cases, not four */  if (sa == sb) {    /* both positive or both negative */    /* add their magnitudes, copy the sign */    c->sign = sa;    res = s_mp_add (a, b, c);  } else {    /* one positive, the other negative */    /* subtract the one with the greater magnitude from */    /* the one of the lesser magnitude.  The result gets */    /* the sign of the one with the greater magnitude. */    if (mp_cmp_mag (a, b) == MP_LT) {      c->sign = sb;      res = s_mp_sub (b, a, c);    } else {      c->sign = sa;      res = s_mp_sub (a, b, c);    }  }  return res;}/* high level subtraction (handles signs) */static int mp_sub (mp_int * a, mp_int * b, mp_int * c){  int     sa, sb, res;  sa = a->sign;  sb = b->sign;  if (sa != sb) {    /* subtract a negative from a positive, OR */    /* subtract a positive from a negative. */    /* In either case, ADD their magnitudes, */    /* and use the sign of the first number. */    c->sign = sa;    res = s_mp_add (a, b, c);  } else {    /* subtract a positive from a positive, OR */    /* subtract a negative from a negative. */    /* First, take the difference between their */    /* magnitudes, then... */    if (mp_cmp_mag (a, b) != MP_LT) {      /* Copy the sign from the first */      c->sign = sa;      /* The first has a larger or equal magnitude */      res = s_mp_sub (a, b, c);    } else {      /* The result has the *opposite* sign from */      /* the first number. */      c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;      /* The second has a larger magnitude */      res = s_mp_sub (b, a, c);    }  }  return res;}/* high level multiplication (handles sign) */static int mp_mul (mp_int * a, mp_int * b, mp_int * c){  int     res, neg;  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;  /* use Toom-Cook? */#ifdef BN_MP_TOOM_MUL_C  if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {    res = mp_toom_mul(a, b, c);  } else #endif#ifdef BN_MP_KARATSUBA_MUL_C  /* use Karatsuba? */  if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {    res = mp_karatsuba_mul (a, b, c);  } else #endif  {    /* can we use the fast multiplier?     *     * The fast multiplier can be used if the output will      * have less than MP_WARRAY digits and the number of      * digits won't affect carry propagation     */#ifdef BN_FAST_S_MP_MUL_DIGS_C    int     digs = a->used + b->used + 1;    if ((digs < MP_WARRAY) &&        MIN(a->used, b->used) <=         (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {      res = fast_s_mp_mul_digs (a, b, c, digs);    } else #endif#ifdef BN_S_MP_MUL_DIGS_C      res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */#else#error mp_mul could fail      res = MP_VAL;#endif  }  c->sign = (c->used > 0) ? neg : MP_ZPOS;  return res;}/* d = a * b (mod c) */static int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d){  int     res;  mp_int  t;  if ((res = mp_init (&t)) != MP_OKAY) {    return res;  }  if ((res = mp_mul (a, b, &t)) != MP_OKAY) {    mp_clear (&t);    return res;  }  res = mp_mod (&t, c, d);  mp_clear (&t);  return res;}/* c = a mod b, 0 <= c < b */static int mp_mod (mp_int * a, mp_int * b, mp_int * c){  mp_int  t;  int     res;  if ((res = mp_init (&t)) != MP_OKAY) {    return res;  }  if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {    mp_clear (&t);    return res;  }  if (t.sign != b->sign) {    res = mp_add (b, &t, c);  } else {    res = MP_OKAY;    mp_exch (&t, c);  }  mp_clear (&t);  return res;}/* this is a shell function that calls either the normal or Montgomery * exptmod functions.  Originally the call to the montgomery code was

⌨️ 快捷键说明

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