예제 #1
0
static PyObject *
GMPy_MPZ_Function_GCDext(PyObject *self, PyObject *args)
{
    PyObject *arg0, *arg1, *result = NULL;
    MPZ_Object *g = NULL, *s = NULL, *t = NULL, *tempa = NULL, *tempb = NULL;

    if(PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments");
        return NULL;
    }

    if (!(result = PyTuple_New(3)) ||
        !(g = GMPy_MPZ_New(NULL)) ||
        !(s = GMPy_MPZ_New(NULL)) ||
        !(t = GMPy_MPZ_New(NULL))) {

        /* LCOV_EXCL_START */
        Py_XDECREF((PyObject*)g);
        Py_XDECREF((PyObject*)s);
        Py_XDECREF((PyObject*)t);
        Py_XDECREF(result);
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    arg0 = PyTuple_GET_ITEM(args, 0);
    arg1 = PyTuple_GET_ITEM(args, 1);

    if (MPZ_Check(arg0) && MPZ_Check(arg1)) {
        mpz_gcdext(g->z, s->z, t->z, MPZ(arg0), MPZ(arg1));
    }
    else {
        if(!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) ||
           !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) {

            TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments");
            Py_XDECREF((PyObject*)tempa);
            Py_XDECREF((PyObject*)tempb);
            Py_DECREF((PyObject*)g);
            Py_DECREF((PyObject*)s);
            Py_DECREF((PyObject*)t);
            Py_DECREF(result);
            return NULL;
        }
        mpz_gcdext(g->z, s->z, t->z, tempa->z, tempb->z);
        Py_DECREF((PyObject*)tempa);
        Py_DECREF((PyObject*)tempb);
    }
    PyTuple_SET_ITEM(result, 0, (PyObject*)g);
    PyTuple_SET_ITEM(result, 1, (PyObject*)s);
    PyTuple_SET_ITEM(result, 2, (PyObject*)t);
    return result;
}
예제 #2
0
파일: wrappers.c 프로젝트: jaspervdj/ghc
/* wraps mpz_gcdext()
 *
 * Set g to the greatest common divisor of x and y, and in addition
 * set s and t to coefficients satisfying x*s + y*t = g.
 *
 * The {gp,gn} array is zero-padded (as otherwise 'gn' can't be
 * reconstructed).
 *
 * g must have space for exactly gn=min(xn,yn) limbs.
 * s must have space for at least xn limbs.
 *
 * return value: signed 'sn' of {sp,sn}
 */
mp_size_t
integer_gmp_gcdext(mp_limb_t s0[], mp_limb_t g0[],
                   const mp_limb_t x0[], const mp_size_t xn,
                   const mp_limb_t y0[], const mp_size_t yn)
{
  const mp_size_t gn0 = mp_size_minabs(xn, yn);
  const mpz_t x = CONST_MPZ_INIT(x0, mp_limb_zero_p(x0,xn) ? 0 : xn);
  const mpz_t y = CONST_MPZ_INIT(y0, mp_limb_zero_p(y0,yn) ? 0 : yn);

  mpz_t g, s;
  mpz_init (g);
  mpz_init (s);

  mpz_gcdext (g, s, NULL, x, y);

  const mp_size_t gn = g[0]._mp_size;
  assert(0 <= gn && gn <= gn0);
  memset(g0, 0, gn0*sizeof(mp_limb_t));
  memcpy(g0, g[0]._mp_d, gn*sizeof(mp_limb_t));
  mpz_clear (g);

  const mp_size_t ssn = s[0]._mp_size;
  const mp_size_t sn  = mp_size_abs(ssn);
  assert(sn <= xn);
  memcpy(s0, s[0]._mp_d, sn*sizeof(mp_limb_t));
  mpz_clear (s);

  if (!sn) {
    s0[0] = 0;
    return 1;
  }

  return ssn;
}
예제 #3
0
static Variant HHVM_FUNCTION(gmp_gcdext,
                             const Variant& dataA,
                             const Variant& dataB) {
  mpz_t gmpDataA, gmpDataB, gmpReturnG, gmpReturnS, gmpReturnT;

  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_GCDEXCT, gmpDataA, dataA)) {
    return false;
  }
  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_GCDEXCT, gmpDataB, dataB)) {
    mpz_clear(gmpDataA);
    return false;
  }

  mpz_init(gmpReturnG);
  mpz_init(gmpReturnS);
  mpz_init(gmpReturnT);

  mpz_gcdext(gmpReturnG, gmpReturnS, gmpReturnT, gmpDataA, gmpDataB);

  ArrayInit returnArray(3, ArrayInit::Map{});
  returnArray.set(s_gmp_g, NEWOBJ(GMPResource)(gmpReturnG));
  returnArray.set(s_gmp_s, NEWOBJ(GMPResource)(gmpReturnS));
  returnArray.set(s_gmp_t, NEWOBJ(GMPResource)(gmpReturnT));

  mpz_clear(gmpDataA);
  mpz_clear(gmpDataB);
  mpz_clear(gmpReturnG);
  mpz_clear(gmpReturnS);
  mpz_clear(gmpReturnT);

  return returnArray.toVariant();
}
예제 #4
0
/* Puts in inv[0..l-1] the inverses of a[0..l-1] (mod n), using 3*(l-1) 
   multiplies and one gcdext.
   Returns 1 if a factor was found (stored in t), 0 otherwise.
*/
int
list_invert (listz_t inv, listz_t a, unsigned long l, mpz_t t, mpmod_t modulus)
{
  unsigned long i;
  
  if (l == 0)
    return 0;
  
  mpz_set (inv[0], a[0]);
  
  for (i = 1; i < l; i++)
    {
      mpz_mul (t, inv[i-1], a[i]);
      mpz_mod (inv[i], t, modulus->orig_modulus); /* inv[i] = a[0]*...*a[i] */
    }
  
  mpz_gcdext (t, inv[l-1], NULL, inv[l-1], modulus->orig_modulus);
  
  if (mpz_cmp_ui (t, 1) != 0)
    return 1;
  
  for (i = l-1; i > 0; i--)
    {
      mpz_mul (t, inv[i], inv[i-1]); /* t = (a[0]*...*a[i])^(-1) * (a[0]*...*a[i-1]) = a[i]^(-1) */
      mpz_mul (inv[i-1], inv[i], a[i]); /* inv[i-1] = (a[0]*...*a[i])^(-1) * a[i] = (a[0]*...*a[i-1])^(-1) */
      mpz_mod (inv[i-1], inv[i-1], modulus->orig_modulus);
      mpz_mod (inv[i], t, modulus->orig_modulus);
    }
  
  return 0;
}
예제 #5
0
void xgcd_mpz_s128(s128_t* out_g, s128_t* out_s, s128_t* out_t,
		   const s128_t* in_u, const s128_t* in_v) {
  if (s128_is_s64(in_u) && s128_is_s64(in_v)) {
    int64_t s;
    int64_t t;
    int64_t g = xgcd_mpz_s64(&s, &t, in_u->v0, in_v->v0);
    set_s128_s64(out_g, g);
    set_s128_s64(out_s, s);
    set_s128_s64(out_t, t);
    return;
  }

  // NOTE: We hack the structure of an mpz_t so that
  // it uses stack memory. We use 256-bits instead of 128-bits
  // since it seems that some intermediate numbers use more than
  // 128-bits.  We hope that 256-bits is enough.
  mpz_t g;
  mpz_t s;
  mpz_t t;
  mpz_t u;
  mpz_t v;
  uint64_t g_[4];
  uint64_t s_[4];
  uint64_t t_[4];
  uint64_t u_[4];
  uint64_t v_[4];
  
  g->_mp_alloc = 256 / GMP_LIMB_BITS;
  g->_mp_size  = 0;
  g->_mp_d = (mp_limb_t*)g_;
  
  s->_mp_alloc = 256 / GMP_LIMB_BITS;
  s->_mp_size  = 0;
  s->_mp_d = (mp_limb_t*)s_;
  
  t->_mp_alloc = 256 / GMP_LIMB_BITS;
  t->_mp_size  = 0;
  t->_mp_d = (mp_limb_t*)t_;

  u->_mp_alloc = 256 / GMP_LIMB_BITS;
  u->_mp_size  = 0;
  u->_mp_d = (mp_limb_t*)u_;

  v->_mp_alloc = 256 / GMP_LIMB_BITS;
  v->_mp_size  = 0;
  v->_mp_d = (mp_limb_t*)v_;

  mpz_set_ui(g, 0);
  mpz_set_ui(s, 0);
  mpz_set_ui(t, 0);
  s128_to_mpz(in_u, u);
  s128_to_mpz(in_v, v);

  mpz_gcdext(g, s, t, u, v);

  s128_from_mpz(out_g, g);
  s128_from_mpz(out_s, s);
  s128_from_mpz(out_t, t);
}
예제 #6
0
 void Bezout<>(boost::multiprecision::mpz_int a, 
               boost::multiprecision::mpz_int b, 
               boost::multiprecision::mpz_int& x, 
               boost::multiprecision::mpz_int& y)
 {
     boost::multiprecision::mpz_int g = 1;    
     mpz_gcdext (g.backend().data(), x.backend().data(), y.backend().data(), a.backend().data(), b.backend().data());   
 }
예제 #7
0
ring_elem RingZZ::gcd_extended(const ring_elem f, const ring_elem g,
                            ring_elem &u, ring_elem &v) const
{
  mpz_ptr result = new_elem();
  mpz_ptr u1 = new_elem();
  mpz_ptr v1 = new_elem();
  mpz_gcdext(result, u1, v1, f.get_mpz(), g.get_mpz());
  u = ring_elem(u1);
  v = ring_elem(v1);
  return ring_elem(result);
}
예제 #8
0
void mpz_sqrtmn
	(mpz_ptr root, mpz_srcptr a, 
	mpz_srcptr p, mpz_srcptr q, mpz_srcptr n)
{
	mpz_t g, u, v;
	mpz_init(g), mpz_init(u), mpz_init(v);
	mpz_gcdext(g, u, v, p, q);
	if (mpz_cmp_ui(g, 1L) == 0)
	{
		mpz_t root_p, root_q, root1, root2, root3, root4;
		/* single square roots */
		mpz_init(root_p), mpz_init(root_q);
		mpz_sqrtmp(root_p, a, p);
		mpz_sqrtmp(root_q, a, q);
		/* construct common square root */
		mpz_init_set(root1, root_q);
		mpz_init_set(root2, root_p);
		mpz_init_set(root3, root_q);
		mpz_init_set(root4, root_p);
		mpz_mul(root1, root1, u);
		mpz_mul(root1, root1, p);
		mpz_mul(root2, root2, v);
		mpz_mul(root2, root2, q);
		mpz_add(root1, root1, root2);
		mpz_mod(root1, root1, n);
		mpz_sqrtmn_2(root2, root1, n);
		mpz_neg(root3, root3);
		mpz_mul(root3, root3, u);
		mpz_mul(root3, root3, p);
		mpz_mul(root4, root4, v);
		mpz_mul(root4, root4, q);
		mpz_add(root3, root3, root4);
		mpz_mod(root3, root3, n);
		mpz_sqrtmn_2 (root4, root3, n);
		/* choose smallest root */
		mpz_set(root, root1);
		if (mpz_cmpabs(root2, root) < 0)
			mpz_set(root, root2);
		if (mpz_cmpabs(root3, root) < 0)
			mpz_set(root, root3);
		if (mpz_cmpabs(root4, root) < 0)
			mpz_set(root, root4);
		mpz_clear(root_p), mpz_clear(root_q);
		mpz_clear(root1), mpz_clear(root2);
		mpz_clear(root3), mpz_clear(root4);
		mpz_clear(g), mpz_clear(u), mpz_clear(v);
		return;
	}
	mpz_clear(g), mpz_clear(u), mpz_clear(v);
	/* error, return zero root */
	mpz_set_ui(root, 0L);
}
예제 #9
0
mpz_class invertMultiplicative(const mpz_class& x, const mpz_class& p)
{
    if (x == p - 1 || x == 1)
        return x;
    mpz_t gcd, s, t;
    mpz_init(gcd);
    mpz_init(s);
    mpz_init(t);
    mpz_gcdext(gcd, s, t, x.get_mpz_t(), p.get_mpz_t());
    mpz_class inverse(s);
    if (inverse < 0)
        inverse += p;
    return inverse;
}
예제 #10
0
int64_t xgcd_mpz_s64(int64_t* out_s, int64_t* out_t,
		   const int64_t in_u, const int64_t in_v) {
  // NOTE: We hack the structure of an mpz_t so that
  // it uses stack memory. We use 128-bits instead of 64-bits
  // since it seems that some intermediate numbers use more than
  // 64-bits.  We hope that 128-bits is enough.
  mpz_t g;
  mpz_t s;
  mpz_t t;
  mpz_t u;
  mpz_t v;
  uint64_t g_[2];
  uint64_t s_[2];
  uint64_t t_[2];
  uint64_t u_[2];
  uint64_t v_[2];
  
  g->_mp_alloc = 128 / GMP_LIMB_BITS;
  g->_mp_size  = 0;
  g->_mp_d = (mp_limb_t*)g_;
  
  s->_mp_alloc = 128 / GMP_LIMB_BITS;
  s->_mp_size  = 0;
  s->_mp_d = (mp_limb_t*)s_;
  
  t->_mp_alloc = 128 / GMP_LIMB_BITS;
  t->_mp_size  = 0;
  t->_mp_d = (mp_limb_t*)t_;

  u->_mp_alloc = 128 / GMP_LIMB_BITS;
  u->_mp_size  = 0;
  u->_mp_d = (mp_limb_t*)u_;

  v->_mp_alloc = 128 / GMP_LIMB_BITS;
  v->_mp_size  = 0;
  v->_mp_d = (mp_limb_t*)v_;

  mpz_set_ui(g, 0);
  mpz_set_ui(s, 0);
  mpz_set_ui(t, 0);
  mpz_set_si(u, in_u);
  mpz_set_si(v, in_v);

  mpz_gcdext(g, s, t, u, v);

  *out_s = mpz_get_si(s);
  *out_t = mpz_get_si(t);
  return mpz_get_si(g);
}
예제 #11
0
파일: ec.c 프로젝트: leivaburto/ecc-gmp
void ecc_jcb_to_afn(ecc_afn_t *ROP, ecc_jcb_t *P, ecc_curve *curve)
{
	mpz_t g, s, inv, tmp;	
	mpz_inits(g, s, inv, tmp, NULL);

	mpz_gcdext(g, s, inv, curve->p, P->z); // inv = Z^1

	fp_mul_mpz(tmp, inv, inv, curve->p); // (Z^1)^2
	fp_mul_mpz(ROP->x, P->x, tmp, curve->p); // X*((Z^1)^2)

	fp_mul_mpz(tmp, tmp, inv, curve->p); // (Z^1)^3
	fp_mul_mpz(ROP->y, P->y, tmp, curve->p); // Y*((Z^1)^3)

	mpz_clears(g, s, inv, tmp, NULL);
}
예제 #12
0
파일: invert.c 프로젝트: mahdiz/mpclib
int
mpz_invert (mpz_ptr inverse, mpz_srcptr x, mpz_srcptr n)
{
  mpz_t gcd, tmp;
  mp_size_t xsize, nsize, size;
  TMP_DECL (marker);

  xsize = SIZ (x);
  nsize = SIZ (n);
  xsize = ABS (xsize);
  nsize = ABS (nsize);
  size = MAX (xsize, nsize) + 1;

  /* No inverse exists if the leftside operand is 0.  Likewise, no
     inverse exists if the mod operand is 1.  */
  if (xsize == 0 || (nsize == 1 && (PTR (n))[0] == 1))
    return 0;

  TMP_MARK (marker);

  MPZ_TMP_INIT (gcd, size);
  MPZ_TMP_INIT (tmp, size);
  mpz_gcdext (gcd, tmp, (mpz_ptr) 0, x, n);

  /* If no inverse existed, return with an indication of that.  */
  if (SIZ (gcd) != 1 || PTR(gcd)[0] != 1)
    {
      TMP_FREE (marker);
      return 0;
    }

  /* Make sure we return a positive inverse.  */
  if (SIZ (tmp) < 0)
    {
      if (SIZ (n) < 0)
	mpz_sub (inverse, tmp, n);
      else
	mpz_add (inverse, tmp, n);
    }
  else
    mpz_set (inverse, tmp);

  TMP_FREE (marker);
  return 1;
}
예제 #13
0
void gcd_ext(const Ptr<RCP<const Integer>> &g, const Ptr<RCP<const Integer>> &s,
             const Ptr<RCP<const Integer>> &t, const Integer &a, const Integer &b)
{
    mpz_t g_t;
    mpz_t s_t;
    mpz_t t_t;

    mpz_init(g_t);
    mpz_init(s_t);
    mpz_init(t_t);

    mpz_gcdext(g_t, s_t, t_t, a.as_mpz().get_mpz_t(), b.as_mpz().get_mpz_t());
    *g = integer(mpz_class(g_t));
    *s = integer(mpz_class(s_t));
    *t = integer(mpz_class(t_t));

    mpz_clear(g_t);
    mpz_clear(s_t);
    mpz_clear(t_t);
}
예제 #14
0
int qsieve_extgcd(mpz_t x, mpz_t y, mpz_t xd, mpz_t yd, mpz_t z)
{
    mpz_gcdext(TD, TB, TC, x, y);
    while(qsieve_getsize(TB) < 0)
    {
        mpz_add(TB, TB, y);
        mpz_sub(TC, TC, x);
    }
    if(z != xd && z != yd) if(TD!=z) mpz_set(z, TD);
    if(xd != yd)
    {
        if(TB!=xd) mpz_set(xd, TB);
        if(TC!=yd) mpz_set(yd, TC);
    }
    else
    {
        if(TB!=xd) mpz_set(xd, TB);
    }
    return qsieve_getsize(TD);
}
예제 #15
0
파일: prime.c 프로젝트: zoresvit/sandbox
void inverse(mpz_t inv, mpz_t n, mpz_t mod)
{
    mpz_t d, y;
    mpz_init(d);
    mpz_init(y);
    mpz_init(inv);

    mpz_gcdext(d, inv, y, n, mod);

    if(mpz_cmp_ui(d, 1) > 0)
    {
        /* inverse element doesn't exist */
        mpz_set_ui(inv, 0);
    }

    /* keep inverse value positive */
    mpz_mod(inv, inv, mod);

    mpz_clear(d);
    mpz_clear(y);
    return;
}
예제 #16
0
/*
*   It is a function that generates the keys for RSA algorithm
*   input: mpz_t e, mpz_t, d, mpz_t n and int bitUsed;
*   output: mpz_t e, mpz_t d, mpz_t n
*/
void findRSAKeys(mpz_t e, mpz_t d, mpz_t n, int bitUsed){
    mpz_t p;
    mpz_init(p);
    mpz_t q;
    mpz_init(q);
    //mpz_t n;
    //mpz_init(n);
    mpz_t p1;
    mpz_init(p1);
    mpz_t q1;
    mpz_init(q1);
    mpz_t eulerN;
    mpz_init(eulerN);
    //steps according to wikipedia
    //step 1
    generatePrime(p, bitUsed);
    while(mpz_cmp_ui(q, 0) == 0 || mpz_cmp(p, q) == 0){
        generatePrime(q, bitUsed);
    }
    //step 2
    mpz_mul(n,p,q);
    //step 3
    mpz_sub_ui(p1, p, 1);
    mpz_sub_ui(q1, q, 1);
    mpz_mul(eulerN, p1, q1);
    //step 4
    //mpz_t e;
    //mpz_init(e);
    findESimple(e, eulerN);
    //gmp_printf("e is %Zd\n", e);
    //step 5
    mpz_t g, s;
    mpz_init(g);
    mpz_init(s);
    mpz_gcdext(g, s, d, eulerN, e);
}
예제 #17
0
extern void _jl_mpz_gcdext(mpz_t *g, mpz_t *s, mpz_t *t, mpz_t *a, mpz_t *b) {
    mpz_gcdext(*g, *s, *t, *a, *b);
}
예제 #18
0
/* p-adic logarithm */
void padiclog(mpz_t ans, const mpz_t a, unsigned long p, unsigned long prec, const mpz_t modulo) {
    /*  Compute the p-adic logarithm of a,
        which is supposed to be congruent to 1 mod p

        Algorithm:
         1. we raise a at the power p^(v-1) (for a suitable v) in order
            to make it closer to 1
         2. we write the new a as a product
              1/a = (1 - a_0*p^v) (1 - a_1*p^(2*v) (1 - a_2*p^(4*v) ...
            with 0 <= a_i < p^(v*2^i).
         3. we compute each log(1 - a_i*p^(v*2^i)) using Taylor expansion
            and a binary spliting strategy.                                */

    unsigned long i, v, e, N, saveN, Np, tmp, trunc, step;
    double den = log(p);
    mpz_t f, arg, trunc_mod, h, hpow, mpz_tmp, mpz_tmp2, d, inv, mod2;
    mpz_t *num, *denom;

    mpz_init(mpz_tmp);
    mpz_init(mpz_tmp2);
    mpz_init(arg);
    mpz_set_ui(ans, 0);

    mpz_fdiv_r_ui(mpz_tmp, a, p);
    mpz_set(arg, a);

    /* First we make the argument closer to 1 by raising it to the p^(v-1) */
    if (prec < p) {
        v = 0; e = 1;
    } else {
        v = (unsigned long)(log(prec)/den);  // v here is v-1
        e = pow(p,v);
        mpz_mul_ui(mpz_tmp, modulo, e);
        mpz_powm_ui(arg, arg, e, mpz_tmp);
        prec += v;
    }

    /* Where do we need to truncate the Taylor expansion */
    N = prec+v; N /= ++v;                 // note the ++v
    Np = N;
    den *= v;
    while(1) {
        tmp = Np + (unsigned long)(log(N)/den);
        if (tmp == N) break;
        N = tmp;
    }

    /* We allocate memory and initialize variables */
    mpz_init(f); mpz_init(mod2);
    mpz_init(h); mpz_init(hpow);
    mpz_init(d); mpz_init(inv);
    sig_block();
    num = (mpz_t*)malloc(N*sizeof(mpz_t));
    denom = (mpz_t*)malloc(N*sizeof(mpz_t));
    sig_unblock();
    for (i = 0; i < N; i++) {
        mpz_init(num[i]);
        mpz_init(denom[i]);
    }

    trunc = v << 1;
    mpz_init(trunc_mod);
    mpz_ui_pow_ui(trunc_mod, p, trunc);
    while(1) {
        /* We compute f = 1 - a_i*p^((v+1)*2^i)
           trunc_mod is p^((v+1)*2^(i+1)) */
        mpz_fdiv_r(f, arg, trunc_mod);

        if (mpz_cmp_ui(f, 1) != 0) {

            mpz_ui_sub(f, 2, f);
            mpz_mul(arg, arg, f);

            /* We compute the Taylor expansion of log(f)
               For now, computations are carried out over the rationals */
            for (i = 0; i < N; i++) {
                mpz_set_ui(num[i], 1);
                mpz_set_ui(denom[i], i+1);
            }
            step = 1;
            mpz_ui_sub(h, 1, f);   // we write f = 1 - h, i.e. h = a_i*p^(2^i)
            mpz_set(hpow, h);
            while(step < N) {
                for (i = 0; i < N - step; i += step << 1) {
                    mpz_mul(mpz_tmp2, hpow, num[i+step]);
                    mpz_mul(mpz_tmp, mpz_tmp2, denom[i]);
                    mpz_mul(num[i], num[i], denom[i+step]);
                    mpz_add(num[i], num[i], mpz_tmp);
                    mpz_mul(denom[i], denom[i], denom[i+step]);
                }
                step <<= 1;
                mpz_mul(hpow, hpow, hpow);
            }

            /* We simplify the fraction */
            Np = N; tmp = 0;
            while(Np > 0) { Np /= p; tmp += Np; }
            mpz_ui_pow_ui(d, p, tmp);
            mpz_divexact(mpz_tmp, num[0], d);
            mpz_divexact(denom[0], denom[0], d);

            mpz_divexact_ui(h, h, e);
            mpz_mul(mpz_tmp, h, mpz_tmp);

            /* We coerce the result from Q to Zp */
            mpz_gcdext(d, inv, NULL, denom[0], modulo);
            mpz_mul(mpz_tmp, mpz_tmp, inv);

            /* We add this contribution to log(f) */
            mpz_add(ans, ans, mpz_tmp);

        }

        if (trunc > prec) break;

        /* We update the variables for the next step */
        mpz_mul(trunc_mod, trunc_mod, trunc_mod);
        trunc <<= 1;
        for (i = N >> 1; i < N; i++) {
            mpz_clear(num[i]);
            mpz_clear(denom[i]);
        }
        N >>= 1;
    }

    mpz_fdiv_r(ans, ans, modulo);

    /* We clear memory */
    mpz_clear(arg);
    mpz_clear(f);
    mpz_clear(trunc_mod);
    mpz_clear(h);
    mpz_clear(hpow);
    mpz_clear(mpz_tmp);
    mpz_clear(d);
    mpz_clear(inv);
    mpz_clear(mod2);
    for (i = 0; i < N; i++) {
        mpz_clear(num[i]);
        mpz_clear(denom[i]);
    }
    sig_block();
    free(num);
    free(denom);
    sig_unblock();
}
예제 #19
0
파일: unigcd.cpp 프로젝트: AnZhg/mU
/** 
\brief 整系数多项式最大公因子.
\param f,g 整系数本原多项式,且\f$\deg f=n\ge\deg g\ge 1\f$.
\param r 最大公因子.
\note 小素数模方法.
\todo 理论文档此处有误.
*/
void UniGcdZ_SmallPrime1(poly_z & r,const poly_z & f,const poly_z & g)
{
	poly_z fp,gp,vp,v1;
	poly_z fstar,gstar;
	mpz_t c,s,t;
	mpz_init(c);mpz_init(s);mpz_init(t);
	mpz_t A,b,B,z_temp,k,p_bound,p,p_low_bound,p1,B2;
	mpf_t float_temp;
	mpz_init(A);mpz_init(b);mpz_init(B);mpz_init(z_temp);mpz_init(k);mpz_init(p_bound);mpz_init(p);mpz_init(p1);mpz_init(p_low_bound);mpf_init(float_temp);mpz_init(B2);
	UniMaxNormZ(A,f);UniMaxNormZ(b,g);
	int n=f.size()-1,m=g.size()-1;
	if(mpz_cmp(A,b)<0)mpz_set(A,b);
	mpz_gcd(b,f[n],g[m]);
	mpz_ui_pow_ui(B,2,n);
	mpz_mul(B,B,A);
	mpz_mul(B,B,b);
	mpf_sqrt_ui(float_temp,n+1);
	mpz_set_f(z_temp,float_temp);
	mpz_mul(B,B,z_temp);
	mpz_mul_ui(B2,B,2);
	mpz_set_si(z_temp,n);
	int tempint;
	tempint=2*n*mpz_sizeinbase(z_temp,2)+2*mpz_sizeinbase(b,2)+4*n*mpz_sizeinbase(A,2);
	//tempint=2*n*Modules::NumberTheory::IntegerLength(Z(n),2)+2*Modules::NumberTheory::IntegerLength(b,2)+4*n*Modules::NumberTheory::IntegerLength(A,2);
	mpz_set_si(k,tempint);
	mpz_mul_ui(p_bound,k,2);
	mpz_mul_ui(p_bound,p_bound,mpz_sizeinbase(k,2));
	mpz_set_ui(p_low_bound,3);
	fstar.resize(n+1);
	for(size_t i=0;i<=n;i++)
	{
		mpz_mul(fstar[i],f[i],b);
	}
	gstar.resize(m+1);
	for(size_t i=0;i<=m;i++)
	{
		mpz_mul(gstar[i],g[i],b);
	}
	while(1)
	{
		while(1)
		{
			random::randominteger(p,p_low_bound,p_bound);
			if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
		}
		UniPolynomialMod(fp,f,p);
		UniPolynomialMod(gp,g,p);
		UniGcdZp(vp,fp,gp,p);
		if(vp.size()==1)
		{
			r.resize(1);
			mpz_set_si(r[0],1);
			fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
			fstar.resize(0);gstar.resize(0);
			mpz_clear(c);mpz_clear(s);mpz_clear(t);
			mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
			return ;
		}
		mpz_set(p1,p);
		copy_poly_z(v1,vp);
		while(mpz_cmp(p1,B2)<0)
		{
			while(1)
			{
				random::randominteger(p,p_low_bound,p_bound);
				if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
			}
			UniPolynomialMod(fp,f,p);
			UniPolynomialMod(gp,g,p);
			UniGcdZp(vp,fp,gp,p);
			if(vp.size()==1)
			{
				r.resize(1);
				mpz_set_si(r[0],1);
				fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
				fstar.resize(0);gstar.resize(0);
				mpz_clear(c);mpz_clear(s);mpz_clear(t);
				mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
				return ;
			}
			if(vp.size()<v1.size())
			{
				mpz_set(p1,p);
				copy_poly_z(v1,vp);
				continue;
			}
			if(vp.size()==v1.size())
			{
				mpz_gcdext(c,s,t,p1,p);
				mpz_mul(t,p,t);
				mpz_mul(s,p1,s);
				mpz_mul(p1,p1,p);
				for(size_t i=0;i<vp.size();i++)
				{
					mpz_mul(c,v1[i],t);
					mpz_addmul(c,vp[i],s);
					mpz_set(v1[i],c);
				}
				UniPolynomialMod(v1,v1,p1);
			}
		}
		for(size_t i=0;i<v1.size();i++)mpz_mul(v1[i],v1[i],b);
		UniPolynomialMod(v1,v1,p1);
		if(poly_z_divisible(fstar,v1)&&poly_z_divisible(gstar,v1))
		{
			UniPPZ(r,v1);break;
		}
	}
	fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
	fstar.resize(0);gstar.resize(0);
	mpz_clear(c);mpz_clear(s);mpz_clear(t);
	mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
	return ;
}
예제 #20
0
int chinese(mpz_t ret, mpz_t lcm, mpz_t *a, mpz_t *m, int items)
{
    mpz_t sum, gcd, u, v, s, t, temp1, temp2;
    int i, rval = 1;

#if 0
    if (items >= 128) {
        int first = items/2;
        mpz_t ca[2], cm[2];

        for (i = 0; i < 2; i++)
        {
            mpz_init(ca[i]);
            mpz_init(cm[i]);
        }
        rval = chinese(ca[0], cm[0], a, m, first);
        if (rval == 1)
            rval = chinese(ca[1], cm[1], a+first, m+first, items-first);
        if (rval == 1)
            rval = chinese(ret, lcm, ca, cm, 2);
        for (i = 0; i < 2; i++)
        {
            mpz_clear(ca[i]);
            mpz_clear(cm[i]);
        }
        return rval;
    }
#else
#define CRTN 8
    if (items >= 64) {
        int start = 0, step = items/CRTN;
        mpz_t ca[CRTN], cm[CRTN];

        for (i = 0; i < CRTN; i++)
        {
            mpz_init(ca[i]);
            mpz_init(cm[i]);
        }
        for (i = 0; rval && i < CRTN; i++) {
            int citems = (i==CRTN-1) ? items-(CRTN-1)*step : step;
            rval = chinese(ca[i], cm[i], a+i*step, m+i*step, citems);
        }
        if (rval) rval = chinese(ret, lcm, ca, cm, CRTN);
        for (i = 0; i < CRTN; i++)
        {
            mpz_clear(ca[i]);
            mpz_clear(cm[i]);
        }
        return rval;
    }
#endif

    mpz_init(temp1);
    mpz_init(temp2);
    mpz_init(sum);
    mpz_init(gcd);
    mpz_init(s);
    mpz_init(t);
    mpz_init(u);
    mpz_init(v);

    mpz_set(lcm, m[0]);
    mpz_mod(sum, a[0], m[0]);
    for (i = 1; i < items; i++) {
        mpz_gcdext(gcd, u, v, lcm, m[i]);
        mpz_divexact(s, m[i], gcd);
        mpz_divexact(t, lcm, gcd);
        if (mpz_cmp_ui(gcd,1) != 0) {
            mpz_mod(temp1, sum, gcd);
            mpz_mod(temp2, a[i], gcd);
            if (mpz_cmp(temp1, temp2) != 0) {
                rval = 0;
                break;
            }
        }
        if (mpz_sgn(s) < 0) mpz_neg(s,s);
        if (mpz_sgn(t) < 0) mpz_neg(t,t);
        mpz_mul(lcm, lcm, s);
        if (mpz_sgn(u) < 0) mpz_add(u, u, lcm);
        if (mpz_sgn(v) < 0) mpz_add(v, v, lcm);
        mpz_mul(temp1, v, s);
        mpz_mul(v, temp1, sum);
        mpz_mul(temp1, u, t);
        mpz_mul(u, temp1, a[i]);
        mpz_add(temp1, v, u);
        mpz_mod(sum, temp1, lcm);
    }
    mpz_set(ret, sum);
    mpz_clear(sum);
    mpz_clear(gcd);
    mpz_clear(s);
    mpz_clear(t);
    mpz_clear(u);
    mpz_clear(v);
    mpz_clear(temp1);
    mpz_clear(temp2);
    return rval;
}
예제 #21
0
파일: ecpp.c 프로젝트: xcvii/gkecpp
static int ec_add(mpz_t xr, mpz_t yr, mpz_t x1, mpz_t y1, int z1,
    mpz_t x2, mpz_t y2, int z2, unsigned long n, mpz_t a)
{
  /* add two points of an elliptic curve by matching an addition rule,
   * in non-trivial cases producing a secant connecting the points (or a
   * tangent in case of overlapping points), finding the third intersection
   * point and mirroring it to the x axis
   */

  if (0 == z1 && 0 == z2) /* 0 + 0 = 0 */
  {
    mpz_set_ui(xr, 0);
    mpz_set_ui(yr, 1);

    return 0;
  }
  else if (0 == z2) /* P + 0 = P */
  {
    mpz_set(xr, x1);
    mpz_set(yr, y1);

    return 1;
  }
  else if (0 == z1) /* 0 + Q = Q */
  {
    mpz_set(xr, x2);
    mpz_set(yr, y2);

    return 1;
  }
  else if (0 != mpz_cmp(x1, x2)) /* P + Q, P != Q */
  {
    /*   m = (y2 - y1) / (x2 - x1)
     *   xr = m^2 - x1 - x2
     *   yr = m * (x1 - x3) - y1
     */
    mpz_t xt, yt, tmp;

    mpz_init(xt);
    mpz_init(yt);
    mpz_init_set_ui(tmp, n);

    mpz_sub(yt, y2, y1);
    mpz_sub(xt, x2, x1);

    {
      /* multiplicative inverse over GF(n) using the Extended Euclidean
       * Algorithm
       *   1 = g = s * (x2 - x1) + t * n = s * (x2 - x1)
       */

      mpz_t s, t, g;

      mpz_init(s);
      mpz_init(t);
      mpz_init(g);

      mpz_gcdext(g, s, t, xt, tmp);
      mpz_mul(xt, s, yt);
      mpz_mod_ui(xt, xt, n);
      mpz_set(yt, xt);

      mpz_clear(s);
      mpz_clear(t);
      mpz_clear(g);
    }

    mpz_mul(xt, xt, xt);
    mpz_sub(xt, xt, x1);
    mpz_sub(xt, xt, x2);
    mpz_mod_ui(xt, xt, n);

    mpz_sub(tmp, x1, xt);
    mpz_mul(yt, yt, tmp);
    mpz_sub(yt, yt, y1);
    mpz_mod_ui(yt, yt, n);

    mpz_set(xr, xt);
    mpz_set(yr, yt);

    mpz_clear(xt);
    mpz_clear(yt);
    mpz_clear(tmp);

    return 1;
  }
  else if (0 != mpz_cmp(y1, y2)) /* P + (-P) = 0 */
  {
    mpz_set_ui(xr, 0);
    mpz_set_ui(yr, 1);

    return 0;
  }
  else /* P + P */
  {
    /*   m = (3 * x1^2 + a) / (2 * y1)
     *   xr = m^2 - 2 * x1
     *   yr = m * (x1 - x3) - y1
     */
    mpz_t xt, yt, tmp;

    mpz_init(xt);
    mpz_init(yt);

    mpz_init_set_ui(tmp, n);

    mpz_mul(xt, x1, x1);
    mpz_mul_ui(xt, xt, 3);
    mpz_add(xt, xt, a);
    mpz_add(yt, y1, y1);

    {
      /* multiplicative inverse over GF(n) using the Extended Euclidean
       * Algorithm
       *   1 = g = s * (2 * y1) + t * n = s * (2 * y1)
       */

      mpz_t s, t, g;

      mpz_init(s);
      mpz_init(t);
      mpz_init(g);

      mpz_gcdext(g, s, t, yt, tmp);
      mpz_mul(xt, s, xt);
      mpz_mod_ui(xt, xt, n);
      mpz_set(yt, xt);

      mpz_clear(s);
      mpz_clear(t);
      mpz_clear(g);
    }

    mpz_mul(xt, xt, xt);
    mpz_sub(xt, xt, x1);
    mpz_sub(xt, xt, x1);
    mpz_mod_ui(xt, xt, n);

    mpz_sub(tmp, x1, xt);
    mpz_mul(yt, yt, tmp);
    mpz_sub(yt, yt, y1);
    mpz_mod_ui(yt, yt, n);

    mpz_set(xr, xt);
    mpz_set(yr, yt);

    mpz_clear(xt);
    mpz_clear(yt);
    mpz_clear(tmp);

    return 1;
  }
}
예제 #22
0
int
main (int argc, char **argv)
{
  int i;
  int pass, reps = 400;
  mpz_t in1, in2, in3;
  unsigned long int in2i;
  mp_size_t size;
  mpz_t res1, res2, res3;
  mpz_t ref1, ref2, ref3;
  mpz_t t;
  unsigned long int r1, r2;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  TESTS_REPS (reps, argv, argc);

  rands = RANDS;

  mpz_init (bs);

  mpz_init (in1);
  mpz_init (in2);
  mpz_init (in3);
  mpz_init (ref1);
  mpz_init (ref2);
  mpz_init (ref3);
  mpz_init (res1);
  mpz_init (res2);
  mpz_init (res3);
  mpz_init (t);

  for (pass = 1; pass <= reps; pass++)
    {
      if (isatty (fileno (stdout)))
	{
	  printf ("\r%d/%d passes", pass, reps);
	  fflush (stdout);
	}

      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 21 + 2;

      if ((pass & 1) == 0)
	{
	  /* Make all input operands have quite different sizes */
	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in1, rands, size);

	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in2, rands, size);

	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in3, rands, size);
	}
      else
	{
	  /* Make all input operands have about the same size */
	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in1, rands, size);

	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in2, rands, size);

	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in3, rands, size);
	}

      mpz_urandomb (bs, rands, 3);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (in1, in1);
      if ((bsi & 2) != 0)
	mpz_neg (in2, in2);
      if ((bsi & 4) != 0)
	mpz_neg (in3, in3);

      for (i = 0; i < numberof (dss); i++)
	{
	  if (dss[i].isdivision && mpz_sgn (in2) == 0)
	    continue;
	  if (dss[i].isslow && size_range > 19)
	    continue;

	  (dss[i].fptr) (ref1, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RSS (dss[i], res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dss, i, in1, in2, NULL);

	  mpz_set (res1, in2);
	  INVOKE_RSS (dss[i], res1, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dss, i, in1, in2, NULL);
	}

      for (i = 0; i < numberof (ddss_div); i++)
	{
	  if (mpz_sgn (in2) == 0)
	    continue;

	  (ddss_div[i].fptr) (ref1, ref2, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res2, in1);
	  INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res1, in2);
	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res2, in2);
	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);
	}

      for (i = 0; i < numberof (ds); i++)
	{
	  if (ds[i].nonneg && mpz_sgn (in1) < 0)
	    continue;

	  (ds[i].fptr) (ref1, in1);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RS (ds[i], res1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (ds, i, in1, in2, NULL);
	}

      in2i = mpz_get_ui (in2);

      for (i = 0; i < numberof (dsi); i++)
	{
	  if (dsi[i].mod != 0)
	    in2i = mpz_get_ui (in2) % dsi[i].mod;

	  (dsi[i].fptr) (ref1, in1, in2i);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RRS (dsi[i], res1, res1, in2i);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dsi, i, in1, in2, NULL);
	}

      if (in2i != 0)	  /* Don't divide by 0.  */
	{
	  for (i = 0; i < numberof (dsi_div); i++)
	    {
	      r1 = (dsi_div[i].fptr) (ref1, in1, in2i);
	      MPZ_CHECK_FORMAT (ref1);

	      mpz_set (res1, in1);
	      r2 = (dsi_div[i].fptr) (res1, res1, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
		FAIL (dsi_div, i, in1, in2, NULL);
	    }

	  for (i = 0; i < numberof (ddsi_div); i++)
	    {
	      r1 = (ddsi_div[i].fptr) (ref1, ref2, in1, in2i);
	      MPZ_CHECK_FORMAT (ref1);

	      mpz_set (res1, in1);
	      r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
		FAIL (ddsi_div, i, in1, in2, NULL);

	      mpz_set (res2, in1);
	      (ddsi_div[i].fptr) (res1, res2, res2, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
		FAIL (ddsi_div, i, in1, in2, NULL);
	    }
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_sqrtrem (ref1, ref2, in1);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  mpz_sqrtrem (res1, res2, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);

	  mpz_set (res2, in1);
	  mpz_sqrtrem (res1, res2, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);

	  mpz_set (res1, in1);
	  mpz_sqrtrem (res1, res1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref2, res1) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_root (ref1, in1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_root (res1, res1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_root, in1, in2, NULL);
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_rootrem (ref1, ref2, in1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  mpz_rootrem (res1, res2, res1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_rootrem, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_rootrem (res1, res2, res2, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_rootrem, in1, in2, NULL);
	}

      if (size_range < 18)	/* run fewer tests since gcdext lots of time */
	{
	  mpz_gcdext (ref1, ref2, ref3, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);
	  MPZ_CHECK_FORMAT (ref3);

	  mpz_set (res1, in1);
	  mpz_gcdext (res1, res2, res3, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_gcdext (res1, res2, res3, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res3, in1);
	  mpz_gcdext (res1, res2, res3, res3, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_gcdext (res1, res2, res3, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in2);
	  mpz_gcdext (res1, res2, res3, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res3, in2);
	  mpz_gcdext (res1, res2, res3, in1, res3);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in1);
	  mpz_gcdext (res1, res2, NULL, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_gcdext (res1, res2, NULL, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_gcdext (res1, res2, NULL, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in2);
	  mpz_gcdext (res1, res2, NULL, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);
	}

      /* Don't run mpz_powm for huge exponents or when undefined.  */
      if (size_range < 17 && mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
	  && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
	{
	  mpz_powm (ref1, in1, in2, in3);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_powm (res1, res1, in2, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);

	  mpz_set (res1, in2);
	  mpz_powm (res1, in1, res1, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);

	  mpz_set (res1, in3);
	  mpz_powm (res1, in1, in2, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);
	}

      /* Don't run mpz_powm_ui when undefined.  */
      if (size_range < 17 && mpz_sgn (in3) != 0)
	{
	  mpz_powm_ui (ref1, in1, in2i, in3);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_powm_ui (res1, res1, in2i, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm_ui, in1, in2, in3);

	  mpz_set (res1, in3);
	  mpz_powm_ui (res1, in1, in2i, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm_ui, in1, in2, in3);
	}

      {
	r1 = mpz_gcd_ui (ref1, in1, in2i);
	MPZ_CHECK_FORMAT (ref1);

	mpz_set (res1, in1);
	r2 = mpz_gcd_ui (res1, res1, in2i);
	MPZ_CHECK_FORMAT (res1);
	if (mpz_cmp (ref1, res1) != 0)
	  FAIL2 (mpz_gcd_ui, in1, in2, NULL);
      }

      if (mpz_sgn (in2) != 0)
	{
	  /* Test mpz_remove */
	  mp_bitcnt_t refretval, retval;
	  refretval = mpz_remove (ref1, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  retval = mpz_remove (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
	    FAIL2 (mpz_remove, in1, in2, NULL);

	  mpz_set (res1, in2);
	  retval = mpz_remove (res1, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
	    FAIL2 (mpz_remove, in1, in2, NULL);
	}

      if (mpz_sgn (in2) != 0)
	{
	  /* Test mpz_divexact */
	  mpz_mul (t, in1, in2);
	  mpz_divexact (ref1, t, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, t);
	  mpz_divexact (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact, t, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_divexact (res1, t, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact, t, in2, NULL);
	}

      if (mpz_sgn (in2) > 0)
	{
	  /* Test mpz_divexact_gcd, same as mpz_divexact */
	  mpz_mul (t, in1, in2);
	  mpz_divexact_gcd (ref1, t, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, t);
	  mpz_divexact_gcd (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_divexact_gcd (res1, t, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);
	}
    }

  if (isatty (fileno (stdout)))
    printf ("\r%20s", "");

  mpz_clear (bs);
  mpz_clear (in1);
  mpz_clear (in2);
  mpz_clear (in3);
  mpz_clear (ref1);
  mpz_clear (ref2);
  mpz_clear (ref3);
  mpz_clear (res1);
  mpz_clear (res2);
  mpz_clear (res3);
  mpz_clear (t);

  if (isatty (fileno (stdout)))
    printf ("\r");

  tests_end ();
  exit (0);
}
예제 #23
0
/* void key_generation(int, RSA_PRIVATE, RSA_PUBLIC)
 * generate keys for encrypting and decrypting messages
 * see more at  http://tools.ietf.org/html/rfc2313
 */
void key_generation(int length, RSA_PRIVATE &priv, RSA_PUBLIC &pub) {
    mpz_t p, q, p1, q1;
    mpz_init2(p, length/2);
    mpz_init2(q, length/2);
    mpz_init2(p1, length/2);
    mpz_init2(q1, length/2);

    // generate a random number of bit, set two highest bits and one lowest
    string p_tab(length/2, '1');
    string q_tab(length/2, '1');

    // generating random bits
    int r;
    for (int i=2; i<(length/2 -1); i++) {
        r = random(2);
        if (r==0) p_tab[i]='0';
        else p_tab[i]='1';

        r = random(2);
        if (r==0) q_tab[i]='0';
        else q_tab[i]='1';
    }

    mpz_set_str(p, p_tab.c_str(), 2);
    mpz_set_str(q, q_tab.c_str(), 2);

    // if p not prime, then +=2 and try again
    while ( mpz_probab_prime_p(p, 100)==0 ) {
        mpz_add_ui(p, p, 2L);
    }
    // if q not prime, then +=2 and try again
    while ( mpz_probab_prime_p(q, 100)==0 ) {
        mpz_add_ui(q, q, 2L);
    }

    // swap values if and only if p < q
    // will be used later (see CRT - Chinese Remainder Theorem)
    if (mpz_cmp(p, q) < 0) {
        mpz_swap(p, q);
    }

    mpz_t n, phi;
    mpz_init2(n, length);
    mpz_init2(phi, length);

    //n:
    mpz_mul(n, p, q);

    // p1 = p-1
    // q1 = q-1
    // will be useful later
    mpz_sub_ui(p1, p, 1);
    mpz_sub_ui(q1, q, 1);
    mpz_mul(phi, p1, q1);

    // e:
    // 1 < e < phi, gcd(e, phi) == 1
    mpz_t e, gcd;
    mpz_inits(e, gcd, NULL);
    unsigned int gcd_tab[] = {3, 17, 65537};
    for (int i=0; i<3; i++) {
        mpz_gcd_ui(gcd, phi, gcd_tab[i]);
        if (mpz_cmp_ui(gcd, 1) == 0) {
            mpz_set_ui(e, gcd_tab[i]);
            break;
        }
    }

    // d:
    // probably redundant
    mpz_t d;
    mpz_init(d);
    mpz_gcdext(gcd, d, NULL, e, phi);
    if (mpz_cmp_ui(d,0) < 0)
        mpz_mod(d, d, phi);

    mpz_t dP, dQ, qInv;
    mpz_inits(dP, dQ, qInv, NULL);

    // dP:
    mpz_gcdext(gcd, dP, NULL, e, p1);
    if (mpz_cmp_ui(dP, 0) < 0)
        mpz_mod(dP, dP, p1);

    // dQ:
    mpz_gcdext(gcd, dQ, NULL, e, q1);
    if (mpz_cmp_ui(dQ, 0) < 0)
        mpz_mod(dQ, dQ, q1);

    // qInv:
    mpz_gcdext(gcd, qInv, NULL, q, p);
    if (mpz_cmp_ui(qInv, 0) < 0)
        mpz_mod(qInv, qInv, p);

    // public key:
    // (n, e)
    mpz_set(pub.n, n);
    mpz_set(pub.e, e);

    // private key:
    // (n, d)  OR  (p, q, dP, dQ, qInv)
    mpz_set(priv.p, p);
    mpz_set(priv.q, q);
    mpz_set(priv.dP, dP);
    mpz_set(priv.dQ, dQ);
    mpz_set(priv.qInv, qInv);

    pub.length = priv.length = length;

    mpz_clears(p, q, p1, q1, n, phi, e, gcd, d, dP, dQ, qInv, NULL);
}
예제 #24
0
파일: rabin.c 프로젝트: abbrev/rabbitsign
/*
 * Compute the Rabin signature and the useful value of f.
 */
int rs_sign_rabin(mpz_t res,	        /* mpz to store signature */
		  int* f,	        /* f value chosen */
		  const mpz_t hash,	/* MD5 hash of app */
		  int rootnum,		/* root number (0, 1, 2, 3) */
		  RSKey* key)		/* key structure */
{
  mpz_t mm;
  int mLp, mLq;
  int pm8, qm8;

  if (!mpz_sgn(key->n)) {
    rs_error(key, NULL, "unable to sign: public key missing");
    return RS_ERR_MISSING_PUBLIC_KEY;
  }

  if (!mpz_sgn(key->p) || !mpz_sgn(key->q)) {
    rs_error(key, NULL, "unable to sign: private key missing");
    return RS_ERR_MISSING_PRIVATE_KEY;
  }

  mpz_init(mm);

  /* Calculate q^-1 if necessary */

  if (!mpz_sgn(key->qinv)) {
#ifndef USE_MPZ_GCDEXT
    mpz_sub_ui(mm, key->p, 2);
    mpz_powm(key->qinv, key->q, mm, key->p);
#else
    mpz_gcdext(mm, key->qinv, NULL, key->q, key->p);
    if (mpz_cmp_ui(mm, 1)) {
      mpz_clear(mm);
      rs_error(key, NULL, "unable to sign: unsuitable key");
      return RS_ERR_UNSUITABLE_RABIN_KEY;
    }
#endif
  }

  applyf(mm, hash, key->n, 2);

  mLp = mpz_legendre(mm, key->p);
  mLq = mpz_legendre(mm, key->q);

  pm8 = mpz_get_ui(key->p) % 8;
  qm8 = mpz_get_ui(key->q) % 8;

  if (pm8 == 1 || qm8 == 1 || (pm8 % 2) == 0 || (qm8 % 2) == 0) {
    mpz_clear(mm);
    rs_error(key, NULL, "unable to sign: unsuitable key");
    return RS_ERR_UNSUITABLE_RABIN_KEY;
  }

  *f = ftab[(mLp == 1 ? 0 : 1) +
	    (mLq == 1 ? 0 : 2) +
	    (((qm8 - 3) / 2) * 4) +
	    (((pm8 - 3) / 2) * 12)];

  if (*f == 99) {
    mpz_clear(mm);
    rs_error(key, NULL, "unable to sign: unsuitable key");
    return RS_ERR_UNSUITABLE_RABIN_KEY;
  }

  rabsigf(res, hash, key->n, key->p, key->q, key->qinv, *f, rootnum);
  mpz_clear(mm);
  return RS_SUCCESS;
}
void
one_test (mpz_t op1, mpz_t op2, mpz_t ref, int i)
{
  /*
  printf ("%ld %ld %ld\n", SIZ (op1), SIZ (op2), SIZ (ref));
  fflush (stdout);
  */

  /*
  fprintf (stderr, "op1=");  debug_mp (op1, -16);
  fprintf (stderr, "op2=");  debug_mp (op2, -16);
  */

  mpz_gcdext (gcd1, s, NULL, op1, op2);

  if (ref && mpz_cmp (ref, gcd1) != 0)
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcdext returned incorrect result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "expected result:\n");   debug_mp (ref, -16);
      fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16);
      abort ();
    }

  if (!gcdext_valid_p(op1, op2, gcd1, s))
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcdext returned invalid result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16);
      abort ();
    }

  mpz_gcd (gcd2, op1, op2);
  if (mpz_cmp (gcd2, gcd1) != 0)
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcd returned incorrect result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "expected result:\n");   debug_mp (gcd1, -16);
      fprintf (stderr, "mpz_gcd returns:\n");   debug_mp (gcd2, -16);
      abort ();
    }

  /* This should probably move to t-gcd_ui.c */
  if (mpz_fits_ulong_p (op1) || mpz_fits_ulong_p (op2))
    {
      if (mpz_fits_ulong_p (op1))
	mpz_gcd_ui (gcd2, op2, mpz_get_ui (op1));
      else
	mpz_gcd_ui (gcd2, op1, mpz_get_ui (op2));
      if (mpz_cmp (gcd2, gcd1))
	{
	  fprintf (stderr, "ERROR in test %d\n", i);
	  fprintf (stderr, "mpz_gcd_ui returned incorrect result\n");
	  fprintf (stderr, "op1=");                 debug_mp (op1, -16);
	  fprintf (stderr, "op2=");                 debug_mp (op2, -16);
	  fprintf (stderr, "expected result:\n");   debug_mp (gcd1, -16);
	  fprintf (stderr, "mpz_gcd_ui returns:\n");   debug_mp (gcd2, -16);
	  abort ();
	}
    }

  mpz_gcdext (gcd2, temp1, temp2, op1, op2);
  mpz_mul (temp1, temp1, op1);
  mpz_mul (temp2, temp2, op2);
  mpz_add (temp1, temp1, temp2);
  
  if (mpz_cmp (gcd1, gcd2) != 0
      || mpz_cmp (gcd2, temp1) != 0)
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcdext returned incorrect result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "expected result:\n");   debug_mp (gcd1, -16);
      fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd2, -16);
      abort ();
    }
}
예제 #26
0
파일: t-gcd.c 프로젝트: mahdiz/mpclib
int
main (int argc, char **argv)
{
  mpz_t op1, op2, x;
  mpz_t gcd, gcd2, s, t;
  mpz_t temp1, temp2;
  mp_size_t op1_size, op2_size, x_size;
  int i;
  int reps = 2000;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

  if (argc == 2)
    reps = atoi (argv[1]);

  mpz_init (op1);
  mpz_init (op2);
  mpz_init (x);
  mpz_init (gcd);
  mpz_init (gcd2);
  mpz_init (temp1);
  mpz_init (temp2);
  mpz_init (s);
  mpz_init (t);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 12 + 2; /* 0..8191 bit operands */

      mpz_urandomb (bs, rands, size_range);
      op1_size = mpz_get_ui (bs);
      mpz_rrandomb (op1, rands, op1_size);

      mpz_urandomb (bs, rands, size_range);
      op2_size = mpz_get_ui (bs);
      mpz_rrandomb (op2, rands, op2_size);

      mpz_urandomb (bs, rands, size_range);
      x_size = mpz_get_ui (bs);
      mpz_rrandomb (x, rands, x_size);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (op1, op1);
      if ((bsi & 2) != 0)
	mpz_neg (op2, op2);

      /* printf ("%ld %ld\n", SIZ (op1), SIZ (op2)); */

      mpz_mul (op1, op1, x);
      mpz_mul (op2, op2, x);

      mpz_gcd (gcd, op1, op2);
      /* We know GCD will be at least X, since we multiplied both operands
	 with it.  */
      if (mpz_cmp (gcd, x) < 0 && mpz_sgn (op1) != 0 && mpz_sgn (op2) != 0)
	dump_abort (i, op1, op2);

      if (mpz_fits_ulong_p (op2))
	{
	  mpz_gcd_ui (gcd2, op1, mpz_get_ui (op2));
	  if (mpz_cmp (gcd, gcd2))
	    dump_abort (i, op1, op2);
	}

      mpz_gcdext (gcd2, s, t, op1, op2);
      if (mpz_cmp (gcd, gcd2))
	dump_abort (i, op1, op2);

      mpz_gcdext (gcd2, s, NULL, op1, op2);
      if (mpz_cmp (gcd, gcd2))
	dump_abort (i, op1, op2);

      mpz_mul (temp1, s, op1);
      mpz_mul (temp2, t, op2);
      mpz_add (gcd2, temp1, temp2);
      if (mpz_cmp (gcd, gcd2))
	dump_abort (i, op1, op2);
    }

  mpz_clear (bs);
  mpz_clear (op1);
  mpz_clear (op2);
  mpz_clear (x);
  mpz_clear (gcd);
  mpz_clear (gcd2);
  mpz_clear (temp1);
  mpz_clear (temp2);
  mpz_clear (s);
  mpz_clear (t);

  tests_end ();
  exit (0);
}