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

📄 mpi.c

📁 椭圆曲线Elliptic Curve)加密算法(
💻 C
📖 第 1 页 / 共 5 页
字号:
    mp_clear(&qp);  }  if(r)    *r = rem;  return res;} /* end mp_div_d() *//* }}} *//* {{{ mp_div_2(a, c) *//*  mp_div_2(a, c)  Compute c = a / 2, disregarding the remainder. */mp_err mp_div_2(mp_int *a, mp_int *c){  mp_err  res;  ARGCHK(a != NULL && c != NULL, MP_BADARG);  if((res = mp_copy(a, c)) != MP_OKAY)    return res;  s_mp_div_2(c);  return MP_OKAY;} /* end mp_div_2() *//* }}} *//* {{{ mp_expt_d(a, d, b) */mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c){  mp_int   s, x;  mp_err   res;  ARGCHK(a != NULL && c != NULL, MP_BADARG);  if((res = mp_init(&s)) != MP_OKAY)    return res;  if((res = mp_init_copy(&x, a)) != MP_OKAY)    goto X;  DIGIT(&s, 0) = 1;  while(d != 0) {    if(d & 1) {      if((res = s_mp_mul(&s, &x)) != MP_OKAY)	goto CLEANUP;    }    d >>= 1;    if((res = s_mp_sqr(&x)) != MP_OKAY)      goto CLEANUP;  }  s_mp_exch(&s, c);CLEANUP:  mp_clear(&x);X:  mp_clear(&s);  return res;} /* end mp_expt_d() *//* }}} *//* }}} *//*------------------------------------------------------------------------*//* {{{ Full arithmetic *//* {{{ mp_abs(a, b) *//*  mp_abs(a, b)  Compute b = |a|.  'a' and 'b' may be identical. */mp_err mp_abs(mp_int *a, mp_int *b){  mp_err   res;  ARGCHK(a != NULL && b != NULL, MP_BADARG);  if((res = mp_copy(a, b)) != MP_OKAY)    return res;  SIGN(b) = MP_ZPOS;  return MP_OKAY;} /* end mp_abs() *//* }}} *//* {{{ mp_neg(a, b) *//*  mp_neg(a, b)  Compute b = -a.  'a' and 'b' may be identical. */mp_err mp_neg(mp_int *a, mp_int *b){  mp_err   res;  ARGCHK(a != NULL && b != NULL, MP_BADARG);  if((res = mp_copy(a, b)) != MP_OKAY)    return res;  if(s_mp_cmp_d(b, 0) == MP_EQ)     SIGN(b) = MP_ZPOS;  else     SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG;  return MP_OKAY;} /* end mp_neg() *//* }}} *//* {{{ mp_add(a, b, c) *//*  mp_add(a, b, c)  Compute c = a + b.  All parameters may be identical. */mp_err mp_add(mp_int *a, mp_int *b, mp_int *c){  mp_err  res;  int     cmp;  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);  if(SIGN(a) == SIGN(b)) { /* same sign:  add values, keep sign */    /* Commutativity of addition lets us do this in either order,       so we avoid having to use a temporary even if the result        is supposed to replace the output     */    if(c == b) {      if((res = s_mp_add(c, a)) != MP_OKAY)	return res;    } else {      if(c != a && (res = mp_copy(a, c)) != MP_OKAY)	return res;      if((res = s_mp_add(c, b)) != MP_OKAY) 	return res;    }  } else if((cmp = s_mp_cmp(a, b)) > 0) {  /* different sign: a > b   */    /* If the output is going to be clobbered, we will use a temporary       variable; otherwise, we'll do it without touching the memory        allocator at all, if possible     */    if(c == b) {      mp_int  tmp;      if((res = mp_init_copy(&tmp, a)) != MP_OKAY)	return res;      if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {	mp_clear(&tmp);	return res;      }      s_mp_exch(&tmp, c);      mp_clear(&tmp);    } else {      if(c != a && (res = mp_copy(a, c)) != MP_OKAY)	return res;      if((res = s_mp_sub(c, b)) != MP_OKAY)	return res;    }  } else if(cmp == 0) {             /* different sign, a == b   */    mp_zero(c);    return MP_OKAY;  } else {                          /* different sign: a < b    */    /* See above... */    if(c == a) {      mp_int  tmp;      if((res = mp_init_copy(&tmp, b)) != MP_OKAY)	return res;      if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {	mp_clear(&tmp);	return res;      }      s_mp_exch(&tmp, c);      mp_clear(&tmp);    } else {      if(c != b && (res = mp_copy(b, c)) != MP_OKAY)	return res;      if((res = s_mp_sub(c, a)) != MP_OKAY)	return res;    }  }  if(USED(c) == 1 && DIGIT(c, 0) == 0)    SIGN(c) = MP_ZPOS;  return MP_OKAY;} /* end mp_add() *//* }}} *//* {{{ mp_sub(a, b, c) *//*  mp_sub(a, b, c)  Compute c = a - b.  All parameters may be identical. */mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c){  mp_err  res;  int     cmp;  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);  if(SIGN(a) != SIGN(b)) {    if(c == a) {      if((res = s_mp_add(c, b)) != MP_OKAY)	return res;    } else {      if(c != b && ((res = mp_copy(b, c)) != MP_OKAY))	return res;      if((res = s_mp_add(c, a)) != MP_OKAY)	return res;      SIGN(c) = SIGN(a);    }  } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */    if(c == b) {      mp_int  tmp;      if((res = mp_init_copy(&tmp, a)) != MP_OKAY)	return res;      if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {	mp_clear(&tmp);	return res;      }      s_mp_exch(&tmp, c);      mp_clear(&tmp);    } else {      if(c != a && ((res = mp_copy(a, c)) != MP_OKAY))	return res;      if((res = s_mp_sub(c, b)) != MP_OKAY)	return res;    }  } else if(cmp == 0) {  /* Same sign, equal magnitude */    mp_zero(c);    return MP_OKAY;  } else {               /* Same sign, b > a */    if(c == a) {      mp_int  tmp;      if((res = mp_init_copy(&tmp, b)) != MP_OKAY)	return res;      if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {	mp_clear(&tmp);	return res;      }      s_mp_exch(&tmp, c);      mp_clear(&tmp);    } else {      if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) 	return res;      if((res = s_mp_sub(c, a)) != MP_OKAY)	return res;    }    SIGN(c) = !SIGN(b);  }  if(USED(c) == 1 && DIGIT(c, 0) == 0)    SIGN(c) = MP_ZPOS;  return MP_OKAY;} /* end mp_sub() *//* }}} *//* {{{ mp_mul(a, b, c) *//*  mp_mul(a, b, c)  Compute c = a * b.  All parameters may be identical. */mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c){  mp_err   res;  mp_sign  sgn;  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);  sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG;  if((res = mp_copy(a, c)) != MP_OKAY)    return res;  if((res = s_mp_mul(c, b)) != MP_OKAY)    return res;    if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ)    SIGN(c) = MP_ZPOS;  else    SIGN(c) = sgn;    return MP_OKAY;} /* end mp_mul() *//* }}} *//* {{{ mp_sqr(a, b) */#if MP_SQUAREmp_err mp_sqr(mp_int *a, mp_int *b){  mp_err   res;  ARGCHK(a != NULL && b != NULL, MP_BADARG);  if((res = mp_copy(a, b)) != MP_OKAY)    return res;  if((res = s_mp_sqr(b)) != MP_OKAY)    return res;  SIGN(b) = MP_ZPOS;  return MP_OKAY;} /* end mp_sqr() */#endif/* }}} *//* {{{ mp_div(a, b, q, r) *//*  mp_div(a, b, q, r)  Compute q = a / b and r = a mod b.  Input parameters may be re-used  as output parameters.  If q or r is NULL, that portion of the  computation will be discarded (although it will still be computed)  Pay no attention to the hacker behind the curtain. */mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r){  mp_err   res;  mp_int   qtmp, rtmp;  int      cmp;  ARGCHK(a != NULL && b != NULL, MP_BADARG);  if(mp_cmp_z(b) == MP_EQ)    return MP_RANGE;  /* If a <= b, we can compute the solution without division, and     avoid any memory allocation   */  if((cmp = s_mp_cmp(a, b)) < 0) {    if(r) {      if((res = mp_copy(a, r)) != MP_OKAY)	return res;    }    if(q)       mp_zero(q);    return MP_OKAY;  } else if(cmp == 0) {    /* Set quotient to 1, with appropriate sign */    if(q) {      int qneg = (SIGN(a) != SIGN(b));      mp_set(q, 1);      if(qneg)	SIGN(q) = MP_NEG;    }    if(r)      mp_zero(r);    return MP_OKAY;  }  /* If we get here, it means we actually have to do some division */  /* Set up some temporaries... */  if((res = mp_init_copy(&qtmp, a)) != MP_OKAY)    return res;  if((res = mp_init_copy(&rtmp, b)) != MP_OKAY)    goto CLEANUP;  if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY)    goto CLEANUP;  /* Compute the signs for the output  */  SIGN(&rtmp) = SIGN(a); /* Sr = Sa              */  if(SIGN(a) == SIGN(b))    SIGN(&qtmp) = MP_ZPOS;  /* Sq = MP_ZPOS if Sa = Sb */  else    SIGN(&qtmp) = MP_NEG;   /* Sq = MP_NEG if Sa != Sb */  if(s_mp_cmp_d(&qtmp, 0) == MP_EQ)    SIGN(&qtmp) = MP_ZPOS;  if(s_mp_cmp_d(&rtmp, 0) == MP_EQ)    SIGN(&rtmp) = MP_ZPOS;  /* Copy output, if it is needed      */  if(q)     s_mp_exch(&qtmp, q);  if(r)     s_mp_exch(&rtmp, r);CLEANUP:  mp_clear(&rtmp);  mp_clear(&qtmp);  return res;} /* end mp_div() *//* }}} *//* {{{ mp_div_2d(a, d, q, r) */mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r){  mp_err  res;  ARGCHK(a != NULL, MP_BADARG);  if(q) {    if((res = mp_copy(a, q)) != MP_OKAY)      return res;    s_mp_div_2d(q, d);  }  if(r) {    if((res = mp_copy(a, r)) != MP_OKAY)      return res;    s_mp_mod_2d(r, d);  }  return MP_OKAY;} /* end mp_div_2d() *//* }}} *//* {{{ mp_expt(a, b, c) *//*  mp_expt(a, b, c)  Compute c = a ** b, that is, raise a to the b power.  Uses a  standard iterative square-and-multiply technique. */mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c){  mp_int   s, x;  mp_err   res;  mp_digit d;  mp_size  dig;  int      bit;  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);  if(mp_cmp_z(b) < 0)    return MP_RANGE;  if((res = mp_init(&s)) != MP_OKAY)    return res;  mp_set(&s, 1);  if((res = mp_init_copy(&x, a)) != MP_OKAY)    goto X;  /* Loop over low-order digits in ascending order */  for(dig = 0; dig < (USED(b) - 1); dig++) {    d = DIGIT(b, dig);    /* Loop over bits of each non-maximal digit */    for(bit = 0; bit < DIGIT_BIT; bit++) {      if(d & 1) {	if((res = s_mp_mul(&s, &x)) != MP_OKAY) 	  goto CLEANUP;      }      d >>= 1;            if((res = s_mp_sqr(&x)) != MP_OKAY)	goto CLEANUP;    }  }  /* Consider now the last digit... */  d = DIGIT(b, dig);  while(d) {    if(d & 1) {      if((res = s_mp_mul(&s, &x)) != MP_OKAY)	goto CLEANUP;    }    d >>= 1;    if((res = s_mp_sqr(&x)) != MP_OKAY)      goto CLEANUP;  }    if(mp_iseven(b))    SIGN(&s) = SIGN(a);  res = mp_copy(&s, c);CLEANUP:  mp_clear(&x);X:  mp_clear(&s);  return res;} /* end mp_expt() *//* }}} *//* {{{ mp_2expt(a, k) *//* Compute a = 2^k */mp_err mp_2expt(mp_int *a, mp_digit k){  ARGCHK(a != NULL, MP_BADARG);  return s_mp_2expt(a, k);} /* end mp_2expt() *//* }}} *//* {{{ mp_mod(a, m, c) *//*  mp_mod(a, m, c)  Compute c = a (mod m).  Result will always be 0 <= c < m. */mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c){  mp_err  res;  int     mag;  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);  if(SIGN(m) == MP_NEG)    return MP_RANGE;  /*     If |a| > m, we need to divide to get the remainder and take the     absolute value.       If |a| < m, we don't need to do any division, just copy and adjust     the sign (if a is negative).     If |a| == m, we can simply set the result to zero.     This order is intended to minimize the average path length of the     comparison chain on common workloads -- the most frequent cases are     that |a| != m, so we do those first.   */  if((mag = s_mp_cmp(a, m)) > 0) {    if((res = mp_div(a, m, NULL, c)) != MP_OKAY)      return res;        if(SIGN(c) == MP_NEG) {      if((res = mp_add(c, m, c)) != MP_OKAY)	return res;    }  } else if(mag < 0) {    if((res = mp_copy(a, c)) != MP_OKAY)      return res;    if(mp_cmp_z(a) < 0) {      if((res = mp_add(c, m, c)) != MP_OKAY)	return res;    }      } else {    mp_zero(c);

⌨️ 快捷键说明

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