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

📄 imath.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* {{{ mp_int_exptmod_evalue(a, value, m, c) */mp_result mp_int_exptmod_evalue(mp_int a, int value, mp_int m, mp_int c){  mpz_t    vtmp;  mp_digit vbuf[MP_VALUE_DIGITS(value)];  s_fake(&vtmp, value, vbuf);  return mp_int_exptmod(a, &vtmp, m, c);}/* }}} *//* {{{ mp_int_exptmod_bvalue(v, b, m, c) */mp_result mp_int_exptmod_bvalue(int value, mp_int b,				mp_int m, mp_int c){  mpz_t    vtmp;  mp_digit vbuf[MP_VALUE_DIGITS(value)];  s_fake(&vtmp, value, vbuf);  return mp_int_exptmod(&vtmp, b, m, c);}/* }}} *//* {{{ mp_int_exptmod_known(a, b, m, mu, c) */mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c){  mp_result res;  mp_size   um;  mpz_t     temp[2];  mp_int    s;  int       last = 0;  CHECK(a && b && m && c);  /* Zero moduli and negative exponents are not considered. */  if(CMPZ(m) == 0)    return MP_UNDEF;  if(CMPZ(b) < 0)    return MP_RANGE;  um = MP_USED(m);  SETUP(mp_int_init_size(TEMP(0), 2 * um), last);  if(c == b || c == m) {    SETUP(mp_int_init_size(TEMP(1), 2 * um), last);    s = TEMP(1);  }   else {    s = c;  }    if((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP;  if((res = s_embar(TEMP(0), b, m, mu, s)) != MP_OK)    goto CLEANUP;  res = mp_int_copy(s, c); CLEANUP:  while(--last >= 0)    mp_int_clear(TEMP(last));  return res;}/* }}} *//* {{{ mp_int_redux_const(m, c) */mp_result mp_int_redux_const(mp_int m, mp_int c){  CHECK(m != NULL && c != NULL && m != c);  return s_brmu(c, m);}/* }}} *//* {{{ mp_int_invmod(a, m, c) */mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c){  mp_result res;  mp_sign   sa;  int       last = 0;  mpz_t     temp[2];  CHECK(a != NULL && m != NULL && c != NULL);  if(CMPZ(a) == 0 || CMPZ(m) <= 0)    return MP_RANGE;  sa = MP_SIGN(a); /* need this for the result later */  for(last = 0; last < 2; ++last)    mp_int_init(TEMP(last));  if((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK)     goto CLEANUP;  if(mp_int_compare_value(TEMP(0), 1) != 0) {    res = MP_UNDEF;    goto CLEANUP;  }  /* It is first necessary to constrain the value to the proper range */  if((res = mp_int_mod(TEMP(1), m, TEMP(1))) != MP_OK)    goto CLEANUP;  /* Now, if 'a' was originally negative, the value we have is     actually the magnitude of the negative representative; to get the     positive value we have to subtract from the modulus.  Otherwise,     the value is okay as it stands.   */  if(sa == MP_NEG)    res = mp_int_sub(m, TEMP(1), c);  else    res = mp_int_copy(TEMP(1), c); CLEANUP:  while(--last >= 0)    mp_int_clear(TEMP(last));  return res;}/* }}} *//* {{{ mp_int_gcd(a, b, c) *//* Binary GCD algorithm due to Josef Stein, 1961 */mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c){   int       ca, cb, k = 0;  mpz_t     u, v, t;  mp_result res;  CHECK(a != NULL && b != NULL && c != NULL);  ca = CMPZ(a);  cb = CMPZ(b);  if(ca == 0 && cb == 0)    return MP_UNDEF;  else if(ca == 0)     return mp_int_abs(b, c);  else if(cb == 0)     return mp_int_abs(a, c);  mp_int_init(&t);  if((res = mp_int_init_copy(&u, a)) != MP_OK)    goto U;  if((res = mp_int_init_copy(&v, b)) != MP_OK)    goto V;  MP_SIGN(&u) = MP_ZPOS; MP_SIGN(&v) = MP_ZPOS;  { /* Divide out common factors of 2 from u and v */    int div2_u = s_dp2k(&u), div2_v = s_dp2k(&v);       k = MIN(div2_u, div2_v);    s_qdiv(&u, (mp_size) k);    s_qdiv(&v, (mp_size) k);  }    if(mp_int_is_odd(&u)) {    if((res = mp_int_neg(&v, &t)) != MP_OK)      goto CLEANUP;  }   else {    if((res = mp_int_copy(&u, &t)) != MP_OK)      goto CLEANUP;  }  for(;;) {    s_qdiv(&t, s_dp2k(&t));    if(CMPZ(&t) > 0) {      if((res = mp_int_copy(&t, &u)) != MP_OK)	goto CLEANUP;    }     else {      if((res = mp_int_neg(&t, &v)) != MP_OK)	goto CLEANUP;    }    if((res = mp_int_sub(&u, &v, &t)) != MP_OK)      goto CLEANUP;    if(CMPZ(&t) == 0)      break;  }   if((res = mp_int_abs(&u, c)) != MP_OK)    goto CLEANUP;  if(!s_qmul(c, (mp_size) k))    res = MP_MEMORY;   CLEANUP:  mp_int_clear(&v); V: mp_int_clear(&u); U: mp_int_clear(&t);  return res;}/* }}} *//* {{{ mp_int_egcd(a, b, c, x, y) *//* This is the binary GCD algorithm again, but this time we keep track   of the elementary matrix operations as we go, so we can get values   x and y satisfying c = ax + by. */mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, 		      mp_int x, mp_int y){   int       k, last = 0, ca, cb;  mpz_t     temp[8];  mp_result res;    CHECK(a != NULL && b != NULL && c != NULL && 	(x != NULL || y != NULL));  ca = CMPZ(a);  cb = CMPZ(b);  if(ca == 0 && cb == 0)    return MP_UNDEF;  else if(ca == 0) {    if((res = mp_int_abs(b, c)) != MP_OK) return res;    mp_int_zero(x); (void) mp_int_set_value(y, 1); return MP_OK;  }   else if(cb == 0) {    if((res = mp_int_abs(a, c)) != MP_OK) return res;    (void) mp_int_set_value(x, 1); mp_int_zero(y); return MP_OK;  }  /* Initialize temporaries:     A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */  for(last = 0; last < 4; ++last)     mp_int_init(TEMP(last));  TEMP(0)->digits[0] = 1;  TEMP(3)->digits[0] = 1;  SETUP(mp_int_init_copy(TEMP(4), a), last);  SETUP(mp_int_init_copy(TEMP(5), b), last);  /* We will work with absolute values here */  MP_SIGN(TEMP(4)) = MP_ZPOS;  MP_SIGN(TEMP(5)) = MP_ZPOS;  { /* Divide out common factors of 2 from u and v */    int  div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5));        k = MIN(div2_u, div2_v);    s_qdiv(TEMP(4), k);    s_qdiv(TEMP(5), k);  }  SETUP(mp_int_init_copy(TEMP(6), TEMP(4)), last);  SETUP(mp_int_init_copy(TEMP(7), TEMP(5)), last);  for(;;) {    while(mp_int_is_even(TEMP(4))) {      s_qdiv(TEMP(4), 1);            if(mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) {	if((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK) 	  goto CLEANUP;	if((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK) 	  goto CLEANUP;      }      s_qdiv(TEMP(0), 1);      s_qdiv(TEMP(1), 1);    }        while(mp_int_is_even(TEMP(5))) {      s_qdiv(TEMP(5), 1);      if(mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) {	if((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK) 	  goto CLEANUP;	if((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK) 	  goto CLEANUP;      }      s_qdiv(TEMP(2), 1);      s_qdiv(TEMP(3), 1);    }    if(mp_int_compare(TEMP(4), TEMP(5)) >= 0) {      if((res = mp_int_sub(TEMP(4), TEMP(5), TEMP(4))) != MP_OK) goto CLEANUP;      if((res = mp_int_sub(TEMP(0), TEMP(2), TEMP(0))) != MP_OK) goto CLEANUP;      if((res = mp_int_sub(TEMP(1), TEMP(3), TEMP(1))) != MP_OK) goto CLEANUP;    }     else {      if((res = mp_int_sub(TEMP(5), TEMP(4), TEMP(5))) != MP_OK) goto CLEANUP;      if((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP;      if((res = mp_int_sub(TEMP(3), TEMP(1), TEMP(3))) != MP_OK) goto CLEANUP;    }    if(CMPZ(TEMP(4)) == 0) {      if(x && (res = mp_int_copy(TEMP(2), x)) != MP_OK) goto CLEANUP;      if(y && (res = mp_int_copy(TEMP(3), y)) != MP_OK) goto CLEANUP;      if(c) {	if(!s_qmul(TEMP(5), k)) {	  res = MP_MEMORY;	  goto CLEANUP;	}	 	res = mp_int_copy(TEMP(5), c);      }      break;    }  } CLEANUP:  while(--last >= 0)    mp_int_clear(TEMP(last));  return res;}/* }}} *//* {{{ mp_int_divisible_value(a, v) */int       mp_int_divisible_value(mp_int a, int v){  int       rem = 0;  if(mp_int_div_value(a, v, NULL, &rem) != MP_OK)    return 0;  return rem == 0;}/* }}} *//* {{{ mp_int_is_pow2(z) */int       mp_int_is_pow2(mp_int z){  CHECK(z != NULL);  return s_isp2(z);}/* }}} *//* {{{ mp_int_sqrt(a, c) */mp_result mp_int_sqrt(mp_int a, mp_int c){  mp_result  res = MP_OK;  mpz_t      temp[2];  int        last = 0;  CHECK(a != NULL && c != NULL);  /* The square root of a negative value does not exist in the integers. */  if(MP_SIGN(a) == MP_NEG)    return MP_UNDEF;  SETUP(mp_int_init_copy(TEMP(last), a), last);  SETUP(mp_int_init(TEMP(last)), last);  for(;;) {    if((res = mp_int_sqr(TEMP(0), TEMP(1))) != MP_OK)      goto CLEANUP;    if(mp_int_compare_unsigned(a, TEMP(1)) == 0) break;    if((res = mp_int_copy(a, TEMP(1))) != MP_OK)       goto CLEANUP;    if((res = mp_int_div(TEMP(1), TEMP(0), TEMP(1), NULL)) != MP_OK)       goto CLEANUP;    if((res = mp_int_add(TEMP(0), TEMP(1), TEMP(1))) != MP_OK)       goto CLEANUP;    if((res = mp_int_div_pow2(TEMP(1), 1, TEMP(1), NULL)) != MP_OK)      goto CLEANUP;    if(mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) break;    if((res = mp_int_sub_value(TEMP(0), 1, TEMP(0))) != MP_OK) goto CLEANUP;    if(mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) break;    if((res = mp_int_copy(TEMP(1), TEMP(0))) != MP_OK) goto CLEANUP;  }    res = mp_int_copy(TEMP(0), c); CLEANUP:  while(--last >= 0)    mp_int_clear(TEMP(last));    return res;}/* }}} *//* {{{ mp_int_to_int(z, out) */mp_result mp_int_to_int(mp_int z, int *out){  unsigned int uv = 0;  mp_size   uz;  mp_digit *dz;  mp_sign   sz;  CHECK(z != NULL);  /* Make sure the value is representable as an int */  sz = MP_SIGN(z);  if((sz == MP_ZPOS && mp_int_compare_value(z, INT_MAX) > 0) ||     mp_int_compare_value(z, INT_MIN) < 0)    return MP_RANGE;       uz = MP_USED(z);  dz = MP_DIGITS(z) + uz - 1;    while(uz > 0) {    uv <<= MP_DIGIT_BIT/2;    uv = (uv << (MP_DIGIT_BIT/2)) | *dz--;    --uz;  }  if(out)    *out = (sz == MP_NEG) ? -(int)uv : (int)uv;  return MP_OK;}/* }}} *//* {{{ mp_int_to_string(z, radix, str, limit) */mp_result mp_int_to_string(mp_int z, mp_size radix, 			   char *str, int limit){  mp_result res;  int       cmp = 0;  CHECK(z != NULL && str != NULL && limit >= 2);  if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)    return MP_RANGE;  if(CMPZ(z) == 0) {    *str++ = s_val2ch(0, 1);  }   else {    mpz_t tmp;    char  *h, *t;    if((res = mp_int_init_copy(&tmp, z)) != MP_OK)      return res;    if(MP_SIGN(z) == MP_NEG) {      *str++ = '-';      --limit;    }    h = str;    /* Generate digits in reverse order until finished or limit reached */    for(/* */; limit > 0; --limit) {      mp_digit d;      if((cmp = CMPZ(&tmp)) == 0)	break;      d = s_ddiv(&tmp, (mp_digit)radix);      *str++ = s_val2ch(d, 1);    }    t = str - 1;    /* Put digits back in correct output order */    while(h < t) {      char tc = *h;      *h++ = *t;      *t-- = tc;    }    mp_int_clear(&tmp);  }  *str = '\0';  if(cmp == 0)    return MP_OK;  else    return MP_TRUNC;}/* }}} *//* {{{ mp_int_string_len(z, radix) */mp_result mp_int_string_len(mp_int z, mp_size radix){   int  len;  CHECK(z != NULL);  if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)    return MP_RANGE;  len = s_outlen(z, radix) + 1; /* for terminator */  /* Allow for sign marker on negatives */  if(MP_SIGN(z) == MP_NEG)    len += 1;  return len;}/* }}} *//* {{{ mp_int_read_string(z, radix, *str) *//* Read zero-terminated string into z */mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str){  return mp_int_read_cstring(z, radix, str, NULL);}/* }}} *//* {{{ mp_int_read_cstring(z, radix, *str, **end) */mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end){   int       ch;  CHECK(z != NULL && str != NULL);  if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)    return MP_RANGE;  /* Skip leading whitespace */  while(isspace((unsigned char)*str))    ++str;  /* Handle leading sign tag (+/-, positive default) */  switch(*str) {  case '-':    MP_SIGN(z) = MP_NEG;    ++str;    break;  case '+':    ++str; /* fallthrough */  default:    MP_SIGN(z) = MP_ZPOS;    break;  }  /* Skip leading zeroes */  while((ch = s_ch2val(*str, radix)) == 0)     ++str;  /* Make sure there is enough space for the value */  if(!s_pad(z, s_inlen(strlen(str), radix)))    return MP_MEMORY;  MP_USED(z) = 1; z->digits[0] = 0;  while(*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) {    s_dmul(z, (mp_digit)radix);    s_dadd(z, (mp_digit)ch);    ++str;  }    CLAMP(z);  /* Override sign for zero, even if negative specified. */  if(CMPZ(z) == 0)    MP_SIGN(z) = MP_ZPOS;    if(end != NULL)    *end = (char *)str;  /* Return a truncation error if the string has unprocessed     characters remaining, so the caller can tell if the whole string     was done */  if(*str != '\0')     return MP_TRUNC;  else    return MP_OK;}/* }}} *//* {{{ mp_int_count_bits(z) */mp_result mp_int_count_bits(mp_int z){  mp_size  nbits = 0, uz;  mp_digit d;  CHECK(z != NULL);  uz = MP_USED(z);  if(uz == 1 && z->digits[0] == 0)    return 1;

⌨️ 快捷键说明

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