示例#1
0
文件: montfp.cpp 项目: mahdiz/mpclib
static void fp_sub(element_ptr c, element_ptr a, element_ptr b) {
	eptr ad = (eptr)a->data, bd = (eptr)b->data;

	if (!ad->flag) {
		fp_neg(c, b);
	}
	else if (!bd->flag) {
		fp_set(c, a);
	}
	else {
		fptr p = (fptr)c->field->data;
		size_t t = p->limbs;
		eptr cd = (eptr)c->data;
		int i = mpn_cmp(ad->d, bd->d, t);

		if (i == 0) {
			cd->flag = 0;
		}
		else {
			cd->flag = 2;
			mpn_sub_n(cd->d, ad->d, bd->d, t);
			if (i < 0) {
				mpn_add_n(cd->d, cd->d, p->primelimbs, t);
			}
		}
	}
}
示例#2
0
int fp_isprime(fp_int *a)
{
   fp_int   b;
   fp_digit d;
   int      r, res;

   /* do trial division */
   for (r = 0; r < 256; r++) {
       fp_mod_d(a, primes[r], &d);
       if (d == 0) {
          return FP_NO;
       }
   }

   /* now do 8 miller rabins */
   fp_init(&b);
   for (r = 0; r < 8; r++) {
       fp_set(&b, primes[r]);
       fp_prime_miller_rabin(a, &b, &res);
       if (res == FP_NO) {
          return FP_NO;
       }
   }
   return FP_YES;
}
示例#3
0
static void fp_halve(element_ptr r, element_ptr a) {
  fp_field_data_ptr p = r->field->data;
  const size_t t = p->limbs;
  int carry = 0;
  mp_limb_t *alimb = a->data;
  mp_limb_t *rlimb = r->data;
  if (alimb[0] & 1) carry = mpn_add_n(rlimb, alimb, p->primelimbs, t);
  else fp_set(r, a);

  mpn_rshift(rlimb, rlimb, t, 1);
  if (carry) rlimb[t - 1] |= ((mp_limb_t) 1) << (sizeof(mp_limb_t) * 8 - 1);
}
示例#4
0
文件: montfp.cpp 项目: mahdiz/mpclib
static void fp_add(element_ptr c, element_ptr a, element_ptr b) {
	eptr ad = (eptr)a->data, bd = (eptr)b->data;

	if (!ad->flag) {
		fp_set(c, b);
	}
	else if (!bd->flag) {
		fp_set(c, a);
	}
	else {
		eptr cd = (eptr)c->data;
		fptr p = (fptr)a->field->data;
		const size_t t = p->limbs;
		mp_limb_t carry;
		carry = mpn_add_n(cd->d, ad->d, bd->d, t);

		if (carry) {
			// Assumes result of following sub is not zero,
			// i.e. modulus cannot be 2^(n * bits_per_limb).
			mpn_sub_n(cd->d, cd->d, p->primelimbs, t);
			cd->flag = 2;
		}
		else {
			int i = mpn_cmp(cd->d, p->primelimbs, t);
			if (!i) {
				cd->flag = 0;
			}
			else {
				cd->flag = 2;
				if (i > 0) {
					mpn_sub_n(cd->d, cd->d, p->primelimbs, t);
				}
			}
		}
	}
}
示例#5
0
文件: montfp.cpp 项目: mahdiz/mpclib
static void fp_halve(element_ptr c, element_ptr a) {
	eptr ad = (eptr)a->data, cd = (eptr)c->data;
	if (!ad->flag) {
		cd->flag = 0;
	}
	else {
		fptr p = (fptr)c->field->data;
		const size_t t = p->limbs;
		int carry = 0;
		mp_limb_t *alimb = ad->d;
		mp_limb_t *climb = cd->d;
		if (alimb[0] & 1) {
			carry = mpn_add_n(climb, alimb, p->primelimbs, t);
		}
		else fp_set(c, a);

		mpn_rshift(climb, climb, t, 1);
		if (carry) climb[t - 1] |= ((mp_limb_t)1) << (sizeof(mp_limb_t)* 8 - 1);
	}
}
/* computes a = B**n mod b without division or multiplication useful for
 * normalizing numbers in a Montgomery system.
 */
void fp_montgomery_calc_normalization(fp_int *a, fp_int *b)
{
  int     x, bits;

  /* how many bits of last digit does b use */
  bits = fp_count_bits (b) % DIGIT_BIT;
  if (!bits) bits = DIGIT_BIT;

  /* compute A = B^(n-1) * 2^(bits-1) */
  if (b->used > 1) {
     fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1);
  } else {
     fp_set(a, 1);
     bits = 1;
  }

  /* now compute C = A * B mod b */
  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
    fp_mul_2 (a, a);
    if (fp_cmp_mag (a, b) != FP_LT) {
      s_fp_sub (a, b, a);
    }
  }
}
示例#7
0
/* ---- trivial ---- */
static int set_int(void *a, unsigned long b)
{
   LTC_ARGCHK(a != NULL);
   fp_set(a, b);
   return CRYPT_OK;
}
示例#8
0
/* ---- trivial ---- */
static int set_int(void *a, ltc_mp_digit b)
{
   LTC_ARGCHK(a != NULL);
   fp_set(a, b);
   return CRYPT_OK;
}
示例#9
0
/* c = 1/a (mod b) for odd b only */
int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
{
  fp_int  x, y, u, v, B, D;
  int     neg;

  /* 2. [modified] b must be odd   */
  if (fp_iseven (b) == FP_YES) {
    return fp_invmod_slow(a,b,c);
  }

  /* init all our temps */
  fp_init(&x);  fp_init(&y);
  fp_init(&u);  fp_init(&v);
  fp_init(&B);  fp_init(&D);

  /* x == modulus, y == value to invert */
  fp_copy(b, &x);

  /* we need y = |a| */
  fp_abs(a, &y);

  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
  fp_copy(&x, &u);
  fp_copy(&y, &v);
  fp_set (&D, 1);

top:
  /* 4.  while u is even do */
  while (fp_iseven (&u) == FP_YES) {
    /* 4.1 u = u/2 */
    fp_div_2 (&u, &u);

    /* 4.2 if B is odd then */
    if (fp_isodd (&B) == FP_YES) {
      fp_sub (&B, &x, &B);
    }
    /* B = B/2 */
    fp_div_2 (&B, &B);
  }

  /* 5.  while v is even do */
  while (fp_iseven (&v) == FP_YES) {
    /* 5.1 v = v/2 */
    fp_div_2 (&v, &v);

    /* 5.2 if D is odd then */
    if (fp_isodd (&D) == FP_YES) {
      /* D = (D-x)/2 */
      fp_sub (&D, &x, &D);
    }
    /* D = D/2 */
    fp_div_2 (&D, &D);
  }

  /* 6.  if u >= v then */
  if (fp_cmp (&u, &v) != FP_LT) {
    /* u = u - v, B = B - D */
    fp_sub (&u, &v, &u);
    fp_sub (&B, &D, &B);
  } else {
    /* v - v - u, D = D - B */
    fp_sub (&v, &u, &v);
    fp_sub (&D, &B, &D);
  }

  /* if not zero goto step 4 */
  if (fp_iszero (&u) == FP_NO) {
    goto top;
  }

  /* now a = C, b = D, gcd == g*v */

  /* if v != 1 then there is no inverse */
  if (fp_cmp_d (&v, 1) != FP_EQ) {
    return FP_VAL;
  }

  /* b is now the inverse */
  neg = a->sign;
  while (D.sign == FP_NEG) {
    fp_add (&D, b, &D);
  }
  fp_copy (&D, c);
  c->sign = neg;
  return FP_OKAY;
}
示例#10
0
static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)
{
  fp_int  x, y, u, v, A, B, C, D;
  int     res;

  /* b cannot be negative */
  if (b->sign == FP_NEG || fp_iszero(b) == 1) {
    return FP_VAL;
  }

  /* init temps */
  fp_init(&x);    fp_init(&y);
  fp_init(&u);    fp_init(&v);
  fp_init(&A);    fp_init(&B);
  fp_init(&C);    fp_init(&D);

  /* x = a, y = b */
  if ((res = fp_mod(a, b, &x)) != FP_OKAY) {
      return res;
  }
  fp_copy(b, &y);

  /* 2. [modified] if x,y are both even then return an error! */
  if (fp_iseven (&x) == 1 && fp_iseven (&y) == 1) {
    return FP_VAL;
  }

  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
  fp_copy (&x, &u);
  fp_copy (&y, &v);
  fp_set (&A, 1);
  fp_set (&D, 1);

top:
  /* 4.  while u is even do */
  while (fp_iseven (&u) == 1) {
    /* 4.1 u = u/2 */
    fp_div_2 (&u, &u);

    /* 4.2 if A or B is odd then */
    if (fp_isodd (&A) == 1 || fp_isodd (&B) == 1) {
      /* A = (A+y)/2, B = (B-x)/2 */
      fp_add (&A, &y, &A);
      fp_sub (&B, &x, &B);
    }
    /* A = A/2, B = B/2 */
    fp_div_2 (&A, &A);
    fp_div_2 (&B, &B);
  }

  /* 5.  while v is even do */
  while (fp_iseven (&v) == 1) {
    /* 5.1 v = v/2 */
    fp_div_2 (&v, &v);

    /* 5.2 if C or D is odd then */
    if (fp_isodd (&C) == 1 || fp_isodd (&D) == 1) {
      /* C = (C+y)/2, D = (D-x)/2 */
      fp_add (&C, &y, &C);
      fp_sub (&D, &x, &D);
    }
    /* C = C/2, D = D/2 */
    fp_div_2 (&C, &C);
    fp_div_2 (&D, &D);
  }

  /* 6.  if u >= v then */
  if (fp_cmp (&u, &v) != FP_LT) {
    /* u = u - v, A = A - C, B = B - D */
    fp_sub (&u, &v, &u);
    fp_sub (&A, &C, &A);
    fp_sub (&B, &D, &B);
  } else {
    /* v - v - u, C = C - A, D = D - B */
    fp_sub (&v, &u, &v);
    fp_sub (&C, &A, &C);
    fp_sub (&D, &B, &D);
  }

  /* if not zero goto step 4 */
  if (fp_iszero (&u) == 0)
    goto top;

  /* now a = C, b = D, gcd == g*v */

  /* if v != 1 then there is no inverse */
  if (fp_cmp_d (&v, 1) != FP_EQ) {
    return FP_VAL;
  }

  /* if its too low */
  while (fp_cmp_d(&C, 0) == FP_LT) {
      fp_add(&C, b, &C);
  }
  
  /* too big */
  while (fp_cmp_mag(&C, b) != FP_LT) {
      fp_sub(&C, b, &C);
  }
  
  /* C is now the inverse */
  fp_copy(&C, c);
  return FP_OKAY;
}