Exemple #1
0
void encrypt(int msg/*To be extended to other types !*/){
	// generate r between 0 and n-1 inclusive 
	unsigned long int m = msg;
	gmp_randstate_t state;
	gmp_randinit_mt (state); // initiallize state with Mersenne Twister which is basically fast one !
	mpz_urandomm(r, state, n);
//66666666666666666666666666666666666
	//mpz_init_set_str(r,"23",10);
//6666666666666666666666666666666666	
	gmp_printf ("\nr = %Zd\n", r);
	mpz_powm_ui(tmpI, g/*base*/, m/*exp*/, nn/*mod*/); // tmp = base^exp modulo mod
	gmp_printf ("\ng^m = %Zd\n", tmpI);
	mpz_powm(tmpII, r/*base*/, n/*exp*/, nn/*mod*/); // tmp = base^exp modulo mod
	gmp_printf ("\nr^n = %Zd\n", tmpII);
	// Remember : a.b mod n = ((a mod n).(b mod n)) mod n
	mpz_mul(c, tmpI, tmpII);
	mpz_mod(c, c, nn);

	gmp_printf ("\nc = %Zd\n", c);
}
Exemple #2
0
static void zp_square(element_ptr c, element_ptr a) {
  /*
     mpz_mul(c->data, a->data, a->data);
     mpz_mod(c->data, c->data, c->field->order);
   */
	mpz_powm_ui((mpz_ptr)c->data, (mpz_ptr)a->data, 2, c->field->order);

  /*
     const mpz_ptr prime = c->field->order;
     const size_t t = prime->_mp_size;
     const mpz_ptr p = a->data;
     const mpz_ptr r = c->data;
     mp_limb_t tmp[2 * t];
     mp_limb_t qp[t + 1];

     mpn_mul_n(tmp, p->_mp_d, p->_mp_d, t);

     mpn_tdiv_qr(qp, r->_mp_d, 0, tmp, 2 * t, prime->_mp_d, t);
   */
}
Exemple #3
0
static int
millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
             mpz_srcptr q, unsigned long int k)
{
  unsigned long int i;

  mpz_powm (y, x, q, n);

  if (mpz_cmp_ui (y, 1L) == 0 || mpz_cmp (y, nm1) == 0)
    return 1;

  for (i = 1; i < k; i++)
    {
      mpz_powm_ui (y, y, 2L, n);
      if (mpz_cmp (y, nm1) == 0)
	return 1;
      if (mpz_cmp_ui (y, 1L) == 0)
	return 0;
    }
  return 0;
}
Exemple #4
0
void SRPCalcS(LPNLS nls, char *result) {
	mpz_t temp, s, v, a;

	mpz_init2(a, 256);
	mpz_init2(v, 256);
	mpz_init(temp);
	mpz_init(s);

	mpz_import(a, 32, -1, 1, 0, 0, nls->A);
	mpz_import(v, 32, -1, 1, 0, 0, nls->V);

	mpz_powm_ui(temp, v, SRPCalcU(nls->B), N);
	mpz_mul(temp, a, temp);
	mpz_powm(s, temp, nls->b_src, N);

	mpz_export(result, (size_t *)0, -1, 1, 0, 0, s);

	mpz_clear(temp);
	mpz_clear(s);
	mpz_clear(v);
	mpz_clear(a);
}
Exemple #5
0
string bbs(int N) {
    mpz_t A, B, r, n, tmp;
    mpz_init(tmp);
    mpz_init(n);
    mpz_init(r);
    mpz_init(A);
    mpz_init(B);

    mpz_set_str(A, "32372334488362947019304797379371153325410700999", 10);
    mpz_set_str(B, "541528607341564832259551", 10);
    mpz_mul(n, A, B);


    mpz_set_ui(r, rand() % 100000 + 1);
    string res;
    while (N) {
        mpz_powm_ui(r, r, 2, n);
        mpz_mod_ui(tmp, r, 2);
        res += to_string(mpz_get_ui(tmp));
        N--;
    }
    return res;
}
int miller_rabin_pass(mpz_t a, mpz_t n) {
    int i, s, result;
    mpz_t a_to_power, d, n_minus_one;

    mpz_init(n_minus_one);
    mpz_sub_ui(n_minus_one, n, 1);

    s = 0;
    mpz_init_set(d, n_minus_one);
    while (mpz_even_p(d)) {
        mpz_fdiv_q_2exp(d, d, 1);
        s++;
    }

    mpz_init(a_to_power);
    mpz_powm(a_to_power, a, d, n);
    if (mpz_cmp_ui(a_to_power, 1) == 0)  {
        result=PROBABLE_PRIME; goto exit;
    }
    for(i=0; i < s-1; i++) {
        if (mpz_cmp(a_to_power, n_minus_one) == 0) {
            result=PROBABLE_PRIME; goto exit;
        }
        mpz_powm_ui (a_to_power, a_to_power, 2, n);
    }
    if (mpz_cmp(a_to_power, n_minus_one) == 0) {
        result=PROBABLE_PRIME; goto exit;
    }
    result = COMPOSITE;

exit:
    mpz_clear(a_to_power);
    mpz_clear(d);
    mpz_clear(n_minus_one);
    return result;
}
/*
 * isprime : is this number prime ?
 * this use the Miller-Rabin method. The algorithm can be found at Wikipedia
 * return 1 (yes) and 0 (no)
 */
int
isprime(mpz_t p)
{
    gmp_randstate_t st;         /* random init stat */
    mpz_t           a,
                    d,
                    tmp,
                    x;
    int             i,
                    ret,
                    j;
    unsigned long   s;

    ret = 1;

    /*
     * ensure that p is odd and greater than 3 
     */
    if (mpz_cmp_ui(p, 3) <= 0 || !mpz_tstbit(p, 0))
        return 0;

    /*
     * put p in the 2^s.d form
     */
    mpz_init(d);
    mpz_sub_ui(d, p, 1);        /* d = p-1 */
    s = 0;

    do {
        s++;
        mpz_divexact_ui(d, d, 2);
    } while (mpz_divisible_ui_p(d, 2));
    /*
     * now we have p as 2^s.d
     */

    gmp_randinit_default(st);
    gmp_randseed_ui(st, time(NULL));
    mpz_init(a);
    mpz_init(x);
    mpz_init(tmp);
    mpz_sub_ui(tmp, p, 1);      /* tmp = p - 1 */

    for (i = 0; i < ACCURACY; i++) {
        /*
         * generate a as 2 <= a <= n-2 
         */
        do {
            mpz_urandomm(a, st, tmp);   /* a will be between 0 and * tmp-1 
                                         * inclusive */
        } while (mpz_cmp_ui(a, 2) < 0);

        mpz_powm(x, a, d, p);   /* do x = a^d mod p */

        /*
         * if x == 1 or x == p-1 
         */
        if (!mpz_cmp_ui(x, 1) || !mpz_cmp(x, tmp))
            continue;

        for (j = 1; j < s; j++) {
            mpz_powm_ui(x, x, 2, p);    /* do x = x^2 mod p */
            if (!mpz_cmp_ui(x, 1)
                || !mpz_cmp(x, tmp))    /* x == 1 */
                break;
        }

        if (mpz_cmp(x, tmp) || !mpz_cmp_ui(x, 1)) {     /* x != p-1 */
            ret = 0;
            break;
        }
    }

    /*
     * Free Ressources
     */
    gmp_randclear(st);
    mpz_clear(a);
    mpz_clear(d);
    mpz_clear(tmp);

    return ret;
}
Exemple #8
0
// get some bytes (taken from gmpbbs.c)
void rndbbs_randbytes(PGM_CTX *pgm_ctx, char *retbuf, size_t nbytes)
#define FUNC_NAME "rndbbs_randbytes"
{
  char *urandom_buffer = NULL;
  RNDBBS *bbs;

  // pick up handy ptr
  bbs = &pgm_ctx->rndbbs;

  if ( bbs->xor_urandom )
    {
      if ( (urandom_buffer = (char *) malloc(nbytes)) == NULL)
	{
	  perror(FUNC_NAME ": malloc");
	  return;
	}

      {
	int i;
	int j;
	unsigned int r;

	r = nrand48(pgm_ctx->xsubi);
	for ( j = 0, i = 0 ; i < nbytes ; i++ ) {
	  if ( j > 3 ) {
	    j = 0;
	    r = nrand48(pgm_ctx->xsubi);
	  }
	  urandom_buffer [ i ] = (unsigned char)r;
	  r >>= 8;
	  j += 1;
	}
      }

#if 0
      if ( _urandread(urandom_buffer, nbytes) != nbytes )
	{
	  perror(FUNC_NAME ": _urandread: continuting...");
	  bbs->xor_urandom = 0;
	}
#endif
    }

  memset(retbuf, 0, nbytes);

  if (!bbs->improved)
    {
      /* basic implementation without improvements (only keep parity) */
      {
	int i;
	for (i=0;i<nbytes;i++)
	  {
	    int j;

	    /* we keep the parity (least significant bit) of each x_n */
	    for (j=7;j>=0;j--)
	      {
		/* x[n+1] = x[n]^2 (mod blumint) */
		mpz_powm_ui(bbs->x, bbs->x, 2, bbs->blumint);

		/* mpz_fdiv_ui(bbs->x, 2) == mpz_tstbit(bbs->x, 0) */
		retbuf[i] |= (mpz_tstbit(bbs->x, 0) << j);
	      }
	    if (bbs->xor_urandom)
	      retbuf[i] ^= urandom_buffer[i];
	  }
	if ( urandom_buffer != NULL )
	  free(urandom_buffer);
	return;
      }
    }
  else
    {
      /* improved implementation (keep log2(log2(blumint)) bits of x[i]) */
      unsigned int loglogblum = log(1.0*bbs->key_bitlen)/log(2.0);

      unsigned int byte=0, bit=0, i;

      for (;;)
	{
	  //printf("%s: calculating x[n+1], loglogblum = %d\n",
	  //__FUNCTION__,loglogblum);
	  
	  /* x[n+1] = x[n]^2 (mod blumint) */
	  mpz_powm_ui(bbs->x, bbs->x, 2, bbs->blumint);

	  for (i=0;i<loglogblum;i++)
	    {
	      if (byte == nbytes)
		{
		  if ( urandom_buffer != NULL )
		    free(urandom_buffer);
		  return;
		}

	      /* get the ith bit of x */
	      retbuf[byte] |= (mpz_tstbit(bbs->x, i) << (7-bit) );

	      if (bit == 7)
		{
		  if (bbs->xor_urandom)
		    retbuf[byte] ^= urandom_buffer[byte];
		  byte++;
		  bit=0;
		}
	      else
		{
		  bit++;
		}
	    }
	}
    }
}
Exemple #9
0
/* See:
 *   (1) Kaltofen, Valente, Yui 1989
 *   (2) Valente 1992 (Thesis)
 *   (3) Konstantinou, Stamatiou, and Zaroliagis (CHES 2002)
 * This code is performing table 1 of reference 3.
 */
static void weber_root_to_hilbert_root(mpz_t r, mpz_t N, long D)
{
  mpz_t A, t;

  if (D < 0) D = -D;
  D = ((D % 4) == 0)  ?  D/4  :  D;
  if ( (D % 8) == 0 )
    return;

  mpz_init(A);  mpz_init(t);

  switch (D % 8) {
    case 1:  if ((D % 3) != 0)  mpz_powm_ui(t, r, 12, N);
             else               mpz_powm_ui(t, r,  4, N);
             mpz_mul_ui(A, t, 64);
             mpz_sub_ui(t, A, 16);
             break;
    case 2:
    case 6:  if ((D % 3) != 0)  mpz_powm_ui(t, r, 12, N);
             else               mpz_powm_ui(t, r,  4, N);
             mpz_mul_ui(A, t, 64);
             mpz_add_ui(t, A, 16);
             break;
    case 5:  if ((D % 3) != 0)  mpz_powm_ui(t, r, 6, N);
             else               mpz_powm_ui(t, r, 2, N);
             mpz_mul_ui(A, t, 64);
             mpz_sub_ui(t, A, 16);
             break;
    case 7:  if (!mpz_invert(t, r, N)) mpz_set_ui(t, 0);
             if ((D % 3) != 0)  mpz_powm_ui(A, t, 24, N);
             else               mpz_powm_ui(A, t,  8, N);
             mpz_sub_ui(t, A, 16);
             break;
    /* Results in degree 3x Hilbert, so typically not used */
    case 3:  if (!mpz_invert(t, r, N)) mpz_set_ui(t, 0);
             if ((D % 3) != 0) {
               mpz_powm_ui(t, t, 24, N);
               mpz_mul_2exp(A, t, 12);
             } else {
               mpz_powm_ui(t, t, 8, N);
               mpz_mul_2exp(A, t, 4);
             }
             mpz_sub_ui(t, A, 16);
             break;
    default: break;
  }
  /* r = t^3 / A */
  mpz_powm_ui(t, t, 3, N);
  if ( ! mpz_divmod(r, t, A, N, r) )
    mpz_set_ui(r, 0);
  mpz_clear(A);  mpz_clear(t);
}
Exemple #10
0
void
paillier_keygen( int modulusbits, int decryptServers, int thresholdServers,
                                 paillier_pubkey_t** pub,
                                 paillier_partialkey_t*** partKeys,
                                 paillier_get_rand_t get_rand )
{
    mpz_t p1;
    mpz_t q1;
    mpz_t p;
    mpz_t q;
    mpz_t m;
    mpz_t nm;
    mpz_t nSquare;
    mpz_t mInversToN;
    mpz_t d;
    mpz_t r;
    mpz_t gcdRN;
    mpz_t vExp;
    mpz_t * a;
    mpz_t * shares;
    mpz_t * viarray;
    gmp_randstate_t rand;

    /* allocate the new key structures */

    *pub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t));
    *partKeys = (paillier_partialkey_t**) malloc(sizeof(paillier_partialkey_t*) * decryptServers);

    /* initialize our integers */

    mpz_init((*pub)->n);
    mpz_init((*pub)->n_squared);
    mpz_init((*pub)->n_plusone);
    mpz_init((*pub)->delta);
    mpz_init((*pub)->combineSharesConstant);
    mpz_init((*pub)->v);
    mpz_init(m);
    mpz_init(nm);
    mpz_init(nSquare);
    mpz_init(mInversToN);
    mpz_init(d);
    mpz_init(r);
    mpz_init(gcdRN);
    mpz_init(vExp);


    /* pick random (modulusbits/2)-bit primes p and q */

    init_rand(rand, get_rand, modulusbits / 8 + 1);
    do
    {
        genSafePrimes(&p1,&p,modulusbits,rand);

        do
            genSafePrimes(&q1,&q,modulusbits,rand);
        while( mpz_cmp(p,q)==0 || mpz_cmp(p,q1)==0 || mpz_cmp(q,p1)==0 || mpz_cmp(q1,p1)==0 );

        /* compute the public modulus n = p q */

        mpz_mul((*pub)->n, p, q);
        mpz_mul(m, p1, q1);
    } while( !mpz_tstbit((*pub)->n, modulusbits - 1) );
    (*pub)->bits = modulusbits;
    (*pub)->decryptServers = decryptServers;
    (*pub)->threshold = thresholdServers;
    (*pub)->complete();


    // We decide on some s>0, thus the plaintext space will be Zn^s
    // for now we set s=1
    mpz_mul(nm, (*pub)->n, m);
    mpz_mul(nSquare, (*pub)->n, (*pub)->n);

    // next d need to be chosen such that
    // d=0 mod m and d=1 mod n, using Chinese remainder thm
    // we can find d using Chinese remainder thm
    // note that $d=(m. (m^-1 mod n))$
    int errorCode = mpz_invert(mInversToN,m,(*pub)->n);
    if (errorCode == 0)
    {
        throw std::runtime_error("Inverse of m mod n not found!");
    }
    mpz_mul(d,m,mInversToN);


    //a[0] is equal to d
    //a[i] is the random number used for generating the polynomial
    //between 0... n^s*m-1, for 0 < i < thresholdServers
    a = (mpz_t*) malloc(sizeof(mpz_t) * thresholdServers);
    mpz_init(a[0]);
    mpz_set(a[0], d);
    for (int i = 1; i < thresholdServers; ++i) {
        mpz_init(a[i]);
        mpz_urandomm(a[i], rand, nm);
    }


    //We need to generate v
    //Although v needs to be the generator of the squares in Z^*_{n^2}
    //I will use a heuristic which gives a generator with high prob.
    //get a random element r such that gcd(r,nSquare) is one
    //set v=r*r mod nSquare. This heuristic is used in the Victor Shoup
    //threshold signature paper.
    do
    {
        mpz_urandomb(r, rand, 4*modulusbits);
        mpz_gcd(gcdRN, r, (*pub)->n);
    } while( !mpz_cmp_ui(gcdRN, 1)==0 );
    // we can now set v to r*r mod nSquare
    mpz_powm_ui((*pub)->v, r, 2, nSquare);

    //This array holds the resulting keys
    shares = (mpz_t*) malloc(sizeof(mpz_t) * decryptServers);
    viarray = (mpz_t*) malloc(sizeof(mpz_t) * decryptServers);


    for (int i = 0; i < decryptServers; ++i) {
        mpz_init(shares[i]);
        mpz_init(viarray[i]);

        // The secret share of the i'th authority will be s_i=f(i) for 1<=i<=l
        paillier_polynomial_point_t *polynPoint = evaluatePolynomial(a, thresholdServers, i+1, nm);
        mpz_set(shares[i], polynPoint->p);
        paillier_freepolynomialpoint(polynPoint);
        //for each decryption server a verication key v_i=v^(delta*s_i) mod n^(s+1)
        mpz_mul(vExp, (*pub)->delta, shares[i]);
        mpz_powm(viarray[i], (*pub)->v, vExp, nSquare);
    }


    /* Set key structures */

    (*pub)->verificationKeys = (paillier_verificationkey_t**) malloc(sizeof(paillier_verificationkey_t) * decryptServers);
    for (int i = 0; i < decryptServers; ++i) {
        int id = i+1;

        paillier_verificationkey_t* verKey = (paillier_verificationkey_t*) malloc(sizeof(paillier_verificationkey_t));
        mpz_init(verKey->v);
        verKey->id=id;
        mpz_set(verKey->v, viarray[i]);
        (*pub)->verificationKeys[i]=verKey;

        paillier_partialkey_t* share = (paillier_partialkey_t*) malloc(sizeof(paillier_partialkey_t));
        mpz_init(share->s);
        share->id=id;
        mpz_set(share->s, shares[i]);
        (*partKeys)[i]=share;
    }


    /* clear temporary integers and randstate */

    mpz_clear(p);
    mpz_clear(q);
    mpz_clear(p1);
    mpz_clear(q1);
    mpz_clear(m);
    mpz_clear(nm);
    mpz_clear(nSquare);
    mpz_clear(mInversToN);
    mpz_clear(d);
    mpz_clear(r);
    mpz_clear(gcdRN);
    mpz_clear(vExp);
    gmp_randclear(rand);
    for (int i = 0; i < thresholdServers; ++i) {
        mpz_clear(a[i]);
    }
    free(a);
    for (int i = 0; i < decryptServers; ++i) {
        mpz_clear(shares[i]);
        mpz_clear(viarray[i]);
    }
    free(shares);
    free(viarray);
}
Exemple #11
0
static int
mpfr_rem1 (mpfr_ptr rem, long *quo, mpfr_rnd_t rnd_q,
           mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
{
  mpfr_exp_t ex, ey;
  int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x);
  mpz_t mx, my, r;
  int tiny = 0;

  MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ);

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y)))
    {
      if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x)
          || MPFR_IS_ZERO (y))
        {
          /* for remquo, quo is undefined */
          MPFR_SET_NAN (rem);
          MPFR_RET_NAN;
        }
      else                      /* either y is Inf and x is 0 or non-special,
                                   or x is 0 and y is non-special,
                                   in both cases the quotient is zero. */
        {
          if (quo)
            *quo = 0;
          return mpfr_set (rem, x, rnd);
        }
    }

  /* now neither x nor y is NaN, Inf or zero */

  mpz_init (mx);
  mpz_init (my);
  mpz_init (r);

  ex = mpfr_get_z_2exp (mx, x);  /* x = mx*2^ex */
  ey = mpfr_get_z_2exp (my, y);  /* y = my*2^ey */

  /* to get rid of sign problems, we compute it separately:
     quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y)
     quo(-x,y) = -quo(x,y), rem(-x,y)  = -rem(x,y)
     thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */
  sign = (signx == MPFR_SIGN (y)) ? 1 : -1;
  mpz_abs (mx, mx);
  mpz_abs (my, my);
  q_is_odd = 0;

  /* divide my by 2^k if possible to make operations mod my easier */
  {
    unsigned long k = mpz_scan1 (my, 0);
    ey += k;
    mpz_fdiv_q_2exp (my, my, k);
  }

  if (ex <= ey)
    {
      /* q = x/y = mx/(my*2^(ey-ex)) */

      /* First detect cases where q=0, to avoid creating a huge number
         my*2^(ey-ex): if sx = mpz_sizeinbase (mx, 2) and sy =
         mpz_sizeinbase (my, 2), we have x < 2^(ex + sx) and
         y >= 2^(ey + sy - 1), thus if ex + sx <= ey + sy - 1
         the quotient is 0 */
      if (ex + (mpfr_exp_t) mpz_sizeinbase (mx, 2) <
          ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
        {
          tiny = 1;
          mpz_set (r, mx);
          mpz_set_ui (mx, 0);
        }
      else
        {
          mpz_mul_2exp (my, my, ey - ex);   /* divide mx by my*2^(ey-ex) */

          /* since mx > 0 and my > 0, we can use mpz_tdiv_qr in all cases */
          mpz_tdiv_qr (mx, r, mx, my);
          /* 0 <= |r| <= |my|, r has the same sign as mx */
        }

      if (rnd_q == MPFR_RNDN)
        q_is_odd = mpz_tstbit (mx, 0);
      if (quo)                  /* mx is the quotient */
        {
          mpz_tdiv_r_2exp (mx, mx, WANTED_BITS);
          *quo = mpz_get_si (mx);
        }
    }
  else                          /* ex > ey */
    {
      if (quo) /* remquo case */
        /* for remquo, to get the low WANTED_BITS more bits of the quotient,
           we first compute R =  X mod Y*2^WANTED_BITS, where X and Y are
           defined below. Then the low WANTED_BITS of the quotient are
           floor(R/Y). */
        mpz_mul_2exp (my, my, WANTED_BITS);     /* 2^WANTED_BITS*Y */

      else if (rnd_q == MPFR_RNDN) /* remainder case */
        /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers.
           Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y).
           To be able to perform the rounding, we need the least significant
           bit of the quotient, i.e., one more bit in the remainder,
           which is obtained by dividing by 2Y. */
        mpz_mul_2exp (my, my, 1);       /* 2Y */

      mpz_set_ui (r, 2);
      mpz_powm_ui (r, r, ex - ey, my);  /* 2^(ex-ey) mod my */
      mpz_mul (r, r, mx);
      mpz_mod (r, r, my);

      if (quo)                  /* now 0 <= r < 2^WANTED_BITS*Y */
        {
          mpz_fdiv_q_2exp (my, my, WANTED_BITS);   /* back to Y */
          mpz_tdiv_qr (mx, r, r, my);
          /* oldr = mx*my + newr */
          *quo = mpz_get_si (mx);
          q_is_odd = *quo & 1;
        }
      else if (rnd_q == MPFR_RNDN) /* now 0 <= r < 2Y in the remainder case */
        {
          mpz_fdiv_q_2exp (my, my, 1);     /* back to Y */
          /* least significant bit of q */
          q_is_odd = mpz_cmpabs (r, my) >= 0;
          if (q_is_odd)
            mpz_sub (r, r, my);
        }
      /* now 0 <= |r| < |my|, and if needed,
         q_is_odd is the least significant bit of q */
    }

  if (mpz_cmp_ui (r, 0) == 0)
    {
      inex = mpfr_set_ui (rem, 0, MPFR_RNDN);
      /* take into account sign of x */
      if (signx < 0)
        mpfr_neg (rem, rem, MPFR_RNDN);
    }
  else
    {
      if (rnd_q == MPFR_RNDN)
        {
          /* FIXME: the comparison 2*r < my could be done more efficiently
             at the mpn level */
          mpz_mul_2exp (r, r, 1);
          /* if tiny=1, we should compare r with my*2^(ey-ex) */
          if (tiny)
            {
              if (ex + (mpfr_exp_t) mpz_sizeinbase (r, 2) <
                  ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
                compare = 0; /* r*2^ex < my*2^ey */
              else
                {
                  mpz_mul_2exp (my, my, ey - ex);
                  compare = mpz_cmpabs (r, my);
                }
            }
          else
            compare = mpz_cmpabs (r, my);
          mpz_fdiv_q_2exp (r, r, 1);
          compare = ((compare > 0) ||
                     ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd));
          /* if compare != 0, we need to subtract my to r, and add 1 to quo */
          if (compare)
            {
              mpz_sub (r, r, my);
              if (quo && (rnd_q == MPFR_RNDN))
                *quo += 1;
            }
        }
      /* take into account sign of x */
      if (signx < 0)
        mpz_neg (r, r);
      inex = mpfr_set_z_2exp (rem, r, ex > ey ? ey : ex, rnd);
    }

  if (quo)
    *quo *= sign;

  mpz_clear (mx);
  mpz_clear (my);
  mpz_clear (r);

  return inex;
}
Exemple #12
0
void fmpz_powm_ui(fmpz_t f, const fmpz_t g, ulong e, const fmpz_t m)
{
    if (fmpz_sgn(m) <= 0)
    {
        printf("Exception (fmpz_powm_ui).  Modulus is less than 1.\n");
        abort();
    }

    if (fmpz_is_one(m))
    {
        fmpz_zero(f);
    }
    else if (e == 0)
    {
        fmpz_one(f);
    }
    else  /* e != 0, m > 0 */
    {
        fmpz g2 = *g;
        fmpz m2 = *m;

        if (!COEFF_IS_MPZ(m2))  /* m is small */
        {
            if (!COEFF_IS_MPZ(g2))  /* g is small */
            {
                mp_limb_t minv = n_preinvert_limb(m2);

                _fmpz_demote(f);

                if (g2 >= 0)
                {
                    g2 = n_mod2_preinv(g2, m2, minv);
                    *f = n_powmod2_preinv(g2, e, m2, minv);
                }
                else
                {
                    g2 = n_mod2_preinv(-g2, m2, minv);
                    *f = n_powmod2_preinv(g2, e, m2, minv);
                    if ((e & 1UL))
                        *f = n_negmod(*f, m2);
                }
            }
            else  /* g is large */
            {
                __mpz_struct *ptr = _fmpz_promote(f);
                mpz_t m3;

                mpz_init_set_ui(m3, m2);
                mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, m3);
                mpz_clear(m3);

                _fmpz_demote_val(f);
            }
        }
        else  /* m is large */
        {
            if (!COEFF_IS_MPZ(g2))  /* g is small */
            {
                __mpz_struct *ptr = _fmpz_promote(f);
                mpz_t g3;

                mpz_init_set_si(g3, g2);
                mpz_powm_ui(ptr, g3, e, COEFF_TO_PTR(m2));
                mpz_clear(g3);

                _fmpz_demote_val(f);
            }
            else  /* g is large */
            {
               __mpz_struct *ptr = _fmpz_promote(f);

                mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, COEFF_TO_PTR(m2));

                _fmpz_demote_val(f);
            }
        }
    }
}
Exemple #13
0
/* See Cohen section 1.5.
 * See http://www.math.vt.edu/people/brown/doc/sqrts.pdf
 */
int sqrtmod(mpz_t x, mpz_t a, mpz_t p,
            mpz_t t, mpz_t q, mpz_t b, mpz_t z) /* 4 temp variables */
{
    int r, e, m;

    /* Easy cases from page 31 (or Menezes 3.36, 3.37) */
    if (mpz_congruent_ui_p(p, 3, 4)) {
        mpz_add_ui(t, p, 1);
        mpz_tdiv_q_2exp(t, t, 2);
        mpz_powm(x, a, t, p);
        return verify_sqrt(x, a, p, t, q);
    }

    if (mpz_congruent_ui_p(p, 5, 8)) {
        mpz_sub_ui(t, p, 1);
        mpz_tdiv_q_2exp(t, t, 2);
        mpz_powm(q, a, t, p);
        if (mpz_cmp_si(q, 1) == 0) { /* s = a^((p+3)/8) mod p */
            mpz_add_ui(t, p, 3);
            mpz_tdiv_q_2exp(t, t, 3);
            mpz_powm(x, a, t, p);
        } else {                      /* s = 2a * (4a)^((p-5)/8) mod p */
            mpz_sub_ui(t, p, 5);
            mpz_tdiv_q_2exp(t, t, 3);
            mpz_mul_ui(q, a, 4);
            mpz_powm(x, q, t, p);
            mpz_mul_ui(x, x, 2);
            mpz_mulmod(x, x, a, p, x);
        }
        return verify_sqrt(x, a, p, t, q);
    }

    if (mpz_kronecker(a, p) != 1) {
        /* Possible no solution exists.  Check Euler criterion. */
        mpz_sub_ui(t, p, 1);
        mpz_tdiv_q_2exp(t, t, 1);
        mpz_powm(x, a, t, p);
        if (mpz_cmp_si(x, 1) != 0) {
            mpz_set_ui(x, 0);
            return 0;
        }
    }

    mpz_sub_ui(q, p, 1);
    e = mpz_scan1(q, 0);              /* Remove 2^e from q */
    mpz_tdiv_q_2exp(q, q, e);
    mpz_set_ui(t, 2);
    while (mpz_legendre(t, p) != -1)  /* choose t "at random" */
        mpz_add_ui(t, t, 1);
    mpz_powm(z, t, q, p);                     /* Step 1 complete */
    r = e;

    mpz_powm(b, a, q, p);
    mpz_add_ui(q, q, 1);
    mpz_divexact_ui(q, q, 2);
    mpz_powm(x, a, q, p);   /* Done with q, will use it for y now */

    while (mpz_cmp_ui(b, 1)) {
        /* calculate how many times b^2 mod p == 1 */
        mpz_set(t, b);
        m = 0;
        do {
            mpz_powm_ui(t, t, 2, p);
            m++;
        } while (m < r && mpz_cmp_ui(t, 1));
        if (m >= r) break;
        mpz_ui_pow_ui(t, 2, r-m-1);
        mpz_powm(t, z, t, p);
        mpz_mulmod(x, x, t, p, x);
        mpz_powm_ui(z, t, 2, p);
        mpz_mulmod(b, b, z, p, b);
        r = m;
    }
    return verify_sqrt(x, a, p, t, q);
}
Exemple #14
0
int quadratic_residue(mpz_t x,mpz_t q,mpz_t n)
{
    int                        leg;
    mpz_t                        tmp,ofac,nr,t,r,c,b;
    unsigned int            mod4;
    mp_bitcnt_t                twofac=0,m,i,ix;

    mod4=mpz_tstbit(n,0);
    if(!mod4) // must be odd
        return 0;

    mod4+=2*mpz_tstbit(n,1);

    leg=mpz_legendre(q,n);
    if(leg!=1)
        return leg;

    mpz_init_set(tmp,n);
	
    if(mod4==3) // directly, x = q^(n+1)/4 mod n
        {
	printf("diretamente\n\n");
        mpz_add_ui(tmp,tmp,1UL);
        mpz_tdiv_q_2exp(tmp,tmp,2);
        mpz_powm(x,q,tmp,n);
	gmp_printf("NUMERO X %Zd \n\n",x);
        mpz_clear(tmp);
        }
    else // Tonelli-Shanks
        {
	printf("Tonelli shanks!!!\n");
        mpz_inits(ofac,t,r,c,b,NULL);

        // split n - 1 into odd number times power of 2 ofac*2^twofac
        mpz_sub_ui(tmp,tmp,1UL);
        twofac=mpz_scan1(tmp,twofac); // largest power of 2 divisor
        if(twofac)
            mpz_tdiv_q_2exp(ofac,tmp,twofac); // shift right

        // look for non-residue
        mpz_init_set_ui(nr,2UL);
        while(mpz_legendre(nr,n)!=-1)
            mpz_add_ui(nr,nr,1UL);

        mpz_powm(c,nr,ofac,n); // c = nr^ofac mod n

        mpz_add_ui(tmp,ofac,1UL);
        mpz_tdiv_q_2exp(tmp,tmp,1);
        mpz_powm(r,q,tmp,n); // r = q^(ofac+1)/2 mod n

        mpz_powm(t,q,ofac,n);
        mpz_mod(t,t,n); // t = q^ofac mod n

        if(mpz_cmp_ui(t,1UL)!=0) // if t = 1 mod n we're done
            {
            m=twofac;
            do
                {
                i=2;
                ix=1;
                while(ix<m)
                    {
                    // find lowest 0 < ix < m | t^2^ix = 1 mod n
                    mpz_powm_ui(tmp,t,i,n); // repeatedly square t
                    if(mpz_cmp_ui(tmp,1UL)==0)
                        break;
                    i<<=1; // i = 2, 4, 8, ...
                    ix++; // ix is log2 i
                    }
                mpz_powm_ui(b,c,1<<(m-ix-1),n); // b = c^2^(m-ix-1) mod n
                mpz_mul(r,r,b);
                mpz_mod(r,r,n); // r = r*b mod n
                mpz_mul(c,b,b);
                mpz_mod(c,c,n); // c = b^2 mod n
                mpz_mul(t,t,c);
                mpz_mod(t,t,n); // t = t b^2 mod n
                m=ix;
                }while(mpz_cmp_ui(t,1UL)!=0); // while t mod n != 1
            }
        mpz_set(x,r);
        mpz_clears(tmp,ofac,nr,t,r,c,b,NULL);
        }

    return 1;
}
Exemple #15
0
int main(void)
{
   int i, result;
   flint_rand_t state;
   
   printf("powmod_precomp....");
   fflush(stdout);

   flint_randinit(state);

   for (i = 0; i < 100000; i++)
   {
      mp_limb_t a, d, r1, r2, bits;
      mpz_t a_m, d_m, r2_m;
      mp_limb_signed_t exp;
      double dpre;

      mpz_init(a_m);
      mpz_init(d_m);
      mpz_init(r2_m);
      
      bits = n_randint(state, FLINT_D_BITS) + 1;
      d = n_randbits(state, bits);
      do
      {
         a = n_randint(state, d);
      } while (n_gcd(d, a) != 1UL);
      exp = n_randtest(state);
      
      dpre = n_precompute_inverse(d);
      r1 = n_powmod_precomp(a, exp, d, dpre);

      mpz_set_ui(a_m, a);
      mpz_set_ui(d_m, d);
      if (exp < 0L)
      {
         mpz_powm_ui(r2_m, a_m, -exp, d_m);
         mpz_invert(r2_m, r2_m, d_m);
      } else
         mpz_powm_ui(r2_m, a_m, exp, d_m);      
      r2 = mpz_get_ui(r2_m);
      
      result = (r1 == r2);
      if (!result)
      {
         printf("FAIL:\n");
         printf("a = %lu, exp = %ld, d = %lu\n", a, exp, d); 
         printf("r1 = %lu, r2 = %lu\n", r1, r2);
         abort();
      }

      mpz_clear(a_m);
      mpz_clear(d_m);
      mpz_clear(r2_m);
   }

   flint_randclear(state);

   printf("PASS\n");
   return 0;
}
Exemple #16
0
bool Algorithms::MillerRabin(mpz_t number, unsigned int numBits, unsigned int numTest)
{
    unsigned int i, j, k;
    char *a_str;

    mpz_t buf, t, gcd, a, c;
    mpz_init(buf);
    mpz_init(t);
    mpz_init(gcd);
    mpz_init(a);
    mpz_init(c);

    if(mpz_cmp_ui(number,(unsigned long)2) == 0)
         return true;

    mpz_mod_ui(buf, number, (unsigned long)2);
    if(mpz_cmp_ui(buf,(unsigned long)0) == 0)
        return false;

    unsigned long s = 0;
    mpz_sub_ui(t,number,(unsigned long)1);

    mpz_mod_ui(buf, t, (unsigned long)2);
    while(mpz_cmp_ui(buf,(unsigned long)0) == 0)
    {
         mpz_tdiv_qr_ui(t, buf, t, (unsigned long)2);
         mpz_mod_ui(buf, t, (unsigned long)2);
         s++;
    }

    a_str = new char[numBits];

    for(i = 0; i < numTest; i++)
    {
        for(k = 0; k < numBits - 1; k++)
            a_str[k] = (int)(2.0 * rand() / (RAND_MAX + 1.0)) + '0';
        a_str[k] = '\0';

        mpz_set_str(a,a_str,2);

        mpz_gcd(gcd,a,number);
        if(mpz_cmp_ui(gcd,(unsigned long)1) != 0)
            return false;

        mpz_powm(c, a, t, number);

        if(mpz_cmp_ui(c,(unsigned long)1) == 0)
            continue;

        mpz_sub_ui(buf,number,(unsigned long)1);
        if(mpz_cmp(c,buf) == 0)
            continue;

        bool f = true;
        for(j = 0; j < s - 1; j++)
        {
            mpz_powm_ui(c, c,(unsigned long)2, number);

            if(mpz_cmp(c,buf) == 0)
                f = false;
        }

        if(f)
            return false;
    }
    mpz_clear(buf);
    mpz_clear(t);
    mpz_clear(gcd);
    mpz_clear(a);
    mpz_clear(c);

    free(a_str);

    return true;
}
Exemple #17
0
// init
void bbs_pseudo_init ( PGM_CTX *pgm_ctx )
{
  RNDBBS *bbs;
  mpz_t p,q;
  KEYBUF_128 *kb_128;

  // pick up handy ptr
  bbs = &pgm_ctx->rndbbs;

  // init pgm_ctx
  mpz_init(bbs->blumint);
  mpz_init(bbs->x);
  bbs->key_bitlen  = 0;
  bbs->improved    = 1;
  bbs->xor_urandom = 0;

  // init local vars
  mpz_init(p);
  mpz_init(q);

  // get p, use key_four as starting point
  kb_128 = &pgm_ctx->dibit_kb3_i.kb->key_four;
  bbs_pseudo_cvt_bytes_to_mpz ( kb_128->k, KEYBUF_128_SIZE, p);
  bbs_pseudo_next_prime ( p );

  // encrypt key_four as we've used it up
  {
    unsigned char *kc;
    int i;

    // pick up ptr to buffer
    kc = kb_128->k;
    // make big
    *kc |= 0xc0;
    // make odd
    kc [ KEYBUF_128_SIZE -1 ] |= 0x1;

    for ( i = 0 ; i < KEYBUF_128_SIZE/AES_BLOCK_SIZE ; i++, kc += AES_BLOCK_SIZE ) {
      aes_encrypt( &pgm_ctx->pgm_ctx_aes_b.crypto_aes_ctx,
		   pgm_ctx->pgm_ctx_aes_b.crypto_aes_register_a,
		   kc);
      memcpy(kc,pgm_ctx->pgm_ctx_aes_b.crypto_aes_register_a,AES_BLOCK_SIZE);
    }
  }

  // get q
  mpz_set(q,p);
  bbs_pseudo_next_prime ( q );

  // calculate blumint
  mpz_mul(bbs->blumint,p,q);
  bbs->key_bitlen = mpz_sizeinbase(bbs->blumint, 2);

  // get bbs->x
  {
    mpz_t tmpgcd;
    unsigned char m[4];

    mpz_init(tmpgcd);

    m[0] = getNKeyBits_3_iterator ( pgm_ctx, 8, &pgm_ctx->dibit_kb3_i );
    m[1] = getNKeyBits_3_iterator ( pgm_ctx, 8, &pgm_ctx->dibit_kb3_i );
    m[2] = getNKeyBits_3_iterator ( pgm_ctx, 8, &pgm_ctx->dibit_kb3_i );
    m[3] = getNKeyBits_3_iterator ( pgm_ctx, 8, &pgm_ctx->dibit_kb3_i );

    // get trial x
    bbs_pseudo_cvt_bytes_to_mpz ( m, 4, bbs->x );

    // make sure 'x' is good

    while ( 1 ) {
      mpz_gcd(tmpgcd, bbs->blumint, bbs->x);
      if (mpz_cmp_ui(tmpgcd, 1) != 0)
	{
	  // here, not so good, try again
	  mpz_add_ui(bbs->x,bbs->x,1);
	  continue;
	}
      break;
    }

    // finally, calculate x[0]

    /* x[0] = x^2 (mod n) */
    mpz_powm_ui(bbs->x, bbs->x, 2, bbs->blumint);

    // tidy up
    mpz_clear(tmpgcd);
  }

  // display if necessary
  if ( trace_flag > 1 ) {
    printf("\n%s: bbs->key_bitlen = %d\n",
	   __FUNCTION__,
	   bbs->key_bitlen);
    gmp_printf ("p      : %Zx\n", p);
    gmp_printf ("q      : %Zx\n", q);
    gmp_printf ("x[0]   : %Zx\n", bbs->x);
    gmp_printf ("blumint: %Zx\n", bbs->blumint);
    printf("\n");
  }

  // cleanup
  mpz_clear(p);
  mpz_clear(q);

  // done
}
Exemple #18
0
int is_aks_prime(mpz_t n)
{
  mpz_t *px, *py;
  int retval;
  UV i, s, r, a;
  UV starta = 1;
  int _verbose = get_verbose_level();

  if (mpz_cmp_ui(n, 4) < 0)
    return (mpz_cmp_ui(n, 1) <= 0) ? 0 : 1;

  /* Just for performance: check small divisors: 2*3*5*7*11*13*17*19*23 */
  if (mpz_gcd_ui(0, n, 223092870UL) != 1 && mpz_cmp_ui(n, 23) > 0)
    return 0;

  if (mpz_perfect_power_p(n))
    return 0;

#if AKS_VARIANT == AKS_VARIANT_V6    /* From the V6 AKS paper */
  {
    mpz_t sqrtn, t;
    double log2n;
    UV limit, startr;
    PRIME_ITERATOR(iter);

    mpz_init(sqrtn);
    mpz_sqrt(sqrtn, n);

    log2n = mpz_log2(n);
    limit = (UV) floor( log2n * log2n );

    if (_verbose>1) gmp_printf("# AKS checking order_r(%Zd) to %"UVuf"\n", n, (unsigned long) limit);

    /* Using a native r limits us to ~2000 digits in the worst case (r ~ log^5n)
     * but would typically work for 100,000+ digits (r ~ log^3n).  This code is
     * far too slow to matter either way.  Composite r is ok here, but it will
     * always end up prime, so save time and just check primes. */
    retval = 0;
    /* Start order search at a good spot.  Idea from Nemana and Venkaiah. */
    startr = (mpz_sizeinbase(n,2)-1) * (mpz_sizeinbase(n,2)-1);
    startr = (startr < 1002) ? 2 : startr - 100;
    for (r = 2; /* */; r = prime_iterator_next(&iter)) {
      if (mpz_divisible_ui_p(n, r) ) /* r divides n.  composite. */
        { retval = 0; break; }
      if (mpz_cmp_ui(sqrtn, r) <= 0) /* no r <= sqrtn divides n.  prime. */
        { retval = 1; break; }
      if (r < startr) continue;
      if (mpz_order_ui(r, n, limit) > limit)
        { retval = 2; break; }
    }
    prime_iterator_destroy(&iter);
    mpz_clear(sqrtn);
    if (retval != 2) return retval;

    /* Since r is prime, phi(r) = r-1. */
    s = (UV) floor( sqrt(r-1) * log2n );
  }
#elif AKS_VARIANT == AKS_VARIANT_BORNEMANN /* Bernstein + Voloch */
  {
    UV slim;
    double c2, x;
    /* small t = few iters of big poly.  big t = many iters of small poly */
    double const t = (mpz_sizeinbase(n, 2) <= 64) ? 32 : 40;
    double const t1 = (1.0/((t+1)*log(t+1)-t*log(t)));
    double const dlogn = mpz_logn(n);
    mpz_t tmp;
    PRIME_ITERATOR(iter);

    mpz_init(tmp);
    prime_iterator_setprime(&iter, (UV) (t1*t1 * dlogn*dlogn) );
    r = prime_iterator_next(&iter);
    while (!is_primitive_root_uiprime(n,r))
      r = prime_iterator_next(&iter);
    prime_iterator_destroy(&iter);

    slim = (UV) (2*t*(r-1));
    c2 = dlogn * floor(sqrt(r));
    { /* Binary search for first s in [1,slim] where x >= 0 */
      UV bi = 1;
      UV bj = slim;
      while (bi < bj) {
        s = bi + (bj-bi)/2;
        mpz_bin_uiui(tmp, r+s-1, s);
        x = mpz_logn(tmp) / c2 - 1.0;
        if (x < 0)  bi = s+1;
        else        bj = s;
      }
      s = bi-1;
    }
    s = (s+3) >> 1;
    /* Bornemann checks factors up to (s-1)^2, we check to max(r,s) */
    /* slim = (s-1)*(s-1); */
    slim = (r > s) ? r : s;
    if (_verbose > 1) printf("# aks trial to %"UVuf"\n", slim);
    if (_GMP_trial_factor(n, 2, slim) > 1)
      { mpz_clear(tmp); return 0; }
    mpz_sqrt(tmp, n);
    if (mpz_cmp_ui(tmp, slim) <= 0)
      { mpz_clear(tmp); return 1; }
    mpz_clear(tmp);
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN21
  { /* Bernstein 2003, theorem 2.1 (simplified) */
    UV q;
    double slim, scmp, x;
    mpz_t t, t2;
    PRIME_ITERATOR(iter);
    mpz_init(t);  mpz_init(t2);
    r = s = 0;
    while (1) {
      /* todo: Check r|n and r >= sqrt(n) here instead of waiting */
      if (mpz_cmp_ui(n, r) <= 0) break;
      r = prime_iterator_next(&iter);
      q = largest_factor(r-1);
      mpz_set_ui(t, r);
      mpz_powm_ui(t, n, (r-1)/q, t);
      if (mpz_cmp_ui(t, 1) <= 0) continue;
      scmp = 2 * floor(sqrt(r)) * mpz_log2(n);

      slim = 20 * (r-1);

      /* Check viability */
      mpz_bin_uiui(t, q+slim-1, slim); if (mpz_log2(t) < scmp) continue;

      for (s = 2; s < slim; s++) {
        mpz_bin_uiui(t, q+s-1, s);
        if (mpz_log2(t) > scmp) break;
      }
      if (s < slim) break;
    }
    mpz_clear(t);  mpz_clear(t2);
    prime_iterator_destroy(&iter);
    if (_GMP_trial_factor(n, 2, s) > 1)
      return 0;
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN22
  { /* Bernstein 2003, theorem 2.2 (simplified) */
    UV q;
    double slim, scmp, x;
    mpz_t t, t2;
    PRIME_ITERATOR(iter);
    mpz_init(t);  mpz_init(t2);
    r = s = 0;
    while (1) {
      /* todo: Check r|n and r >= sqrt(n) here instead of waiting */
      if (mpz_cmp_ui(n, r) <= 0) break;
      r = prime_iterator_next(&iter);
      if (!is_primitive_root_uiprime(n,r)) continue;
      q = r-1;   /* Since r is prime, phi(r) = r-1 */
      scmp = 2 * floor(sqrt(r-1)) * mpz_log2(n);

      slim = 20 * (r-1);

      /* Check viability */
      mpz_bin_uiui(t, q+slim-1, slim); if (mpz_log2(t) < scmp) continue;

      for (s = 2; s < slim; s++) {
        mpz_bin_uiui(t, q+s-1, s);
        if (mpz_log2(t) > scmp) break;
      }
      if (s < slim) break;
    }
    mpz_clear(t);  mpz_clear(t2);
    prime_iterator_destroy(&iter);
    if (_GMP_trial_factor(n, 2, s) > 1)
      return 0;
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN23
  { /* Bernstein 2003, theorem 2.3 (simplified) */
    UV q, d, limit;
    double slim, scmp, sbin, x, log2n;
    mpz_t t, t2;
    PRIME_ITERATOR(iter);
    mpz_init(t);  mpz_init(t2);
    log2n = mpz_log2(n);
    limit = (UV) floor( log2n * log2n );
    r = 2;
    s = 0;
    while (1) {
      /* todo: Check r|n and r >= sqrt(n) here instead of waiting */
      if (mpz_cmp_ui(n, r) <= 0) break;
      r++;
      UV gcd = mpz_gcd_ui(NULL, n, r);
      if (gcd != 1) { mpz_clear(t); mpz_clear(t2); return 0; }
      UV v = mpz_order_ui(r, n, limit);
      if (v >= limit) continue;

      mpz_set_ui(t2, r);
      totient(t, t2);
      q = mpz_get_ui(t);
      UV phiv = q/v;
      /* printf("phi(%lu)/v = %lu/%lu = %lu\n", r, q, v, phiv); */

      /* This is extremely inefficient. */

      /* Choose an s value we'd be happy with */
      slim = 20 * (r-1);

      /* Quick check to see if it could work with s=slim, d=1 */
      mpz_bin_uiui(t, q+slim-1, slim);
      sbin = mpz_log2(t);
      if (sbin < 2*floor(sqrt(q))*log2n)
        continue;

      for (s = 2; s < slim; s++) {
        mpz_bin_uiui(t, q+s-1, s);
        sbin = mpz_log2(t);
        if (sbin < 2*floor(sqrt(q))*log2n) continue;   /* d=1 */
        /* Check each number dividing phi(r)/v */
        for (d = 2; d < phiv; d++) {
          if ((phiv % d) != 0) continue;
          scmp = 2 * d * floor(sqrt(q/d)) * log2n;
          if (sbin < scmp) break;
        }
        /* if we did not exit early, this s worked for each d.  This s wins. */
        if (d >= phiv) break;
      }
      if (s < slim) break;
    }
    mpz_clear(t);  mpz_clear(t2);
    prime_iterator_destroy(&iter);
    if (_GMP_trial_factor(n, 2, s) > 1)
      return 0;
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN41
  {
    double const log2n = mpz_log2(n);
    /* Tuning: Initial 'r' selection */
    double const r0 = 0.008 * log2n * log2n;
    /* Tuning: Try a larger 'r' if 's' looks very large */
    UV const rmult = 8;
    UV slim;
    mpz_t tmp, tmp2;
    PRIME_ITERATOR(iter);

    mpz_init(tmp);  mpz_init(tmp2);
    /* r has to be at least 3. */
    prime_iterator_setprime(&iter, (r0 < 2) ? 2 : (UV) r0);
    r = prime_iterator_next(&iter);

    /* r must be a primitive root.  For performance, skip if s looks too big. */
    while ( !is_primitive_root_uiprime(n, r) ||
            !bern41_acceptable(n, r, rmult*(r-1), tmp, tmp2) )
      r = prime_iterator_next(&iter);
    prime_iterator_destroy(&iter);

    { /* Binary search for first s in [1,lim] where conditions met */
      UV bi = 1;
      UV bj = rmult * (r-1);
      while (bi < bj) {
        s = bi + (bj-bi)/2;
        if (!bern41_acceptable(n,r,s,tmp,tmp2))  bi = s+1;
        else                                     bj = s;
      }
      s = bj;
      /* Our S goes from 2 to s+1. */
      starta = 2;
      s = s+1;
    }
    /* printf("chose r=%lu s=%lu d = %lu i = %lu j = %lu\n", r, s, d, i, j); */

    /* Check divisibility to s(s-1) to cover both gcd conditions */
    slim = s * (s-1);
    if (_verbose > 1) printf("# aks trial to %"UVuf"\n", slim);
    if (_GMP_trial_factor(n, 2, slim) > 1)
      { mpz_clear(tmp); mpz_clear(tmp2); return 0; }
    /* If we checked divisibility to sqrt(n), then it is prime. */
    mpz_sqrt(tmp, n);
    if (mpz_cmp_ui(tmp, slim) <= 0)
      { mpz_clear(tmp); mpz_clear(tmp2); return 1; }

    /* Check b^(n-1) = 1 mod n for b in [2..s] */
    if (_verbose > 1) printf("# aks checking fermat to %"UVuf"\n", s);
    mpz_sub_ui(tmp2, n, 1);
    for (i = 2; i <= s; i++) {
      mpz_set_ui(tmp, i);
      mpz_powm(tmp, tmp, tmp2, n);
      if (mpz_cmp_ui(tmp, 1) != 0)
        { mpz_clear(tmp); mpz_clear(tmp2); return 0; }
    }

    mpz_clear(tmp);  mpz_clear(tmp2);
  }

#endif

  if (_verbose) gmp_printf("# AKS %Zd.  r = %"UVuf" s = %"UVuf"\n", n, (unsigned long) r, (unsigned long) s);

  /* Create the three polynomials we will use */
  New(0, px, r, mpz_t);
  New(0, py, r, mpz_t);
  if ( !px || !py )
    croak("allocation failure\n");
  for (i = 0; i < r; i++) {
    mpz_init(px[i]);
    mpz_init(py[i]);
  }

  retval = 1;
  for (a = starta; a <= s; a++) {
    retval = test_anr(a, n, r, px, py);
    if (!retval) break;
    if (_verbose>1) { printf("."); fflush(stdout); }
  }
  if (_verbose>1) { printf("\n"); fflush(stdout); };

  /* Free the polynomials */
  for (i = 0; i < r; i++) {
    mpz_clear(px[i]);
    mpz_clear(py[i]);
  }
  Safefree(px);
  Safefree(py);

  return retval;
}
Exemple #19
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);
}
Exemple #20
0
unsigned int tonelli_shanks(mpz_t num, unsigned int prime)
{
	fprintf(stderr, "shanks for %d\n", prime);
	mpz_t tmp, mpz_prime, r, c, t, b;
	mpz_init(tmp); mpz_init(mpz_prime);
	mpz_init(r); mpz_init(c); mpz_init(t); mpz_init(b);
	mpz_set_ui(mpz_prime, prime);
	unsigned int q = prime-1;
	unsigned int s = 0;
	while(!(q & 1))
	{
		s += 1;
		q >>= 1;
	}

	unsigned int z;
	for(z = 2;; ++z)
	{
		mpz_set_ui(tmp, z);
		mpz_powm_ui(tmp, tmp, (prime-1)/2, mpz_prime);
		if(mpz_cmp_ui(tmp, 1))
			break; // found non-quadratic residue
	}
	printf("c=%d^%d\n", z, q);
	// c = z^q
	mpz_set_ui(tmp, z);
	mpz_powm_ui(c, tmp, q, mpz_prime);
	// r = n^(q+1)/2
	mpz_powm_ui(r, num, (q+1)/2, mpz_prime);
	// t = n^q
	mpz_powm_ui(t, num, q, mpz_prime);
	// m = s
	unsigned int m = s; //mpz_set_ui(m, s);
	// while t != 1 mod p
	while(mpz_cmp_ui(t, 1))
	{
		mpz_out_str(stderr, 10, t);
		fputs(", durr\n", stderr);
		// find smallest i so that t^2^i = 1 mod p
		mpz_set(tmp, t);
		unsigned int i;
		for(i = 1; ;++i)
		{
			mpz_powm_ui(tmp, tmp, 2, mpz_prime);
			mpz_out_str(stderr, 10, tmp);
			fputs("!\n", stderr);
			if(!mpz_cmp_ui(tmp, 1))
				break;
		}
		// TODO: For some reason i >= m here
		// set b to c^2^(m-i-1) as well, by repeated squaring
		mpz_set(b, c);
		printf("m = %d, i = %d\n", m, i);
		for(size_t foo = 0; foo < m-i-1; ++foo)
		{
			mpz_powm_ui(b, b, 2, mpz_prime);
		}
		// r = r*b
		mpz_mul(r, r, b);
		mpz_mod_ui(r, r, prime);
		// t = t*b²
		mpz_mul(t, t, b);
		mpz_mul(t, t, b);
		mpz_mod_ui(t, t, prime);
		// c = b²
		mpz_mul(c, b, b);
		mpz_mod_ui(c, c, prime);
		// m = i
		m = i;
	}
	unsigned int out = mpz_get_ui(r);
	mpz_clear(r); mpz_clear(c); mpz_clear(t); mpz_clear(b);
	mpz_clear(tmp); mpz_init(mpz_prime);
	return out;
}
Exemple #21
0
void find_candidates(mpz_t num, mpz_t gmp_root)
{
	num_cands = 0;
	mpz_add_ui(gmp_root, gmp_root, 1);

	size_t sieve_size = primes[B-1]*100;

	double *table = malloc(sizeof(double)*sieve_size);
	uint64_t root = mpz_get_ui(gmp_root);
	double approx = mpz_get_d(num);

	mpz_t tmp, tmp2;
	mpz_init(tmp); mpz_init(tmp2);

	mpz_set_ui(tmp, root);

	mpz_pow_ui(tmp, tmp, 2);
	mpz_sub(tmp, tmp, num);
	mpz_set(first_cands[0], tmp);

	unsigned int used_primes[B];
	double used_log[B];
	used_primes[0] = 2;
	used_log[0] = log_primes[0];
	size_t next_prime = 1;
	size_t offsets[B][2];
	uint64_t cand_offsets[B+1];
	size_t next_cand = 1;

	// Find prime numbers that appear in the candidate series
	for(size_t p = 1; p < B; ++p)
	{
		unsigned int prime = primes[p];
		mpz_set_ui(tmp2, prime);
		mpz_powm_ui(tmp, num, (prime-1)/2, tmp2);

		if(mpz_cmp_ui(tmp, 1)) // Skip non-quadratic residues
			continue;

		used_primes[next_prime] = prime;
		used_log[next_prime] = log_primes[p];

		// Generate more exact candidates
		for(int i = next_cand; i < prime; ++i)
		{
			mpz_set_ui(tmp, root + i);
			mpz_pow_ui(tmp, tmp, 2);
			mpz_sub(tmp, tmp, num);
			mpz_set(first_cands[i], tmp);
		}
		next_cand = prime;

		// find offsets for them
		// TODO Shanks-tonelli
		unsigned int foo = tonelli_shanks(num, prime);
		printf("root for %u is %u and %u\n", prime, foo, prime-foo);
		size_t idx = 0;
		for(int i = 0; i < prime; ++i)
		{
			if(mpz_divisible_ui_p(first_cands[i], prime))
			{
				offsets[next_prime][idx++] = i;

				if(idx == 2)
					break;
			}
		}
		assert(idx == 2);
		++next_prime;
	}

	// sieve until we find more than B candidates, guarantees linear dependence
	size_t sieve_offset = 0;
	while(num_cands <= B)
	{
		for(size_t i = 0; i < sieve_size; ++i)
		{
			double d = root + i;
			d += sieve_offset;
			table[i] = log(d*d-approx);
		}
		// cross out even ones
		for(size_t i = mpz_tstbit(tmp, 1)^(sieve_offset & 1); i < sieve_size; i+=2)
			table[i] -= log_primes[0];

		for(int p = 1; p < next_prime && num_cands <= B; ++p)
		{
			unsigned int prime = used_primes[p];
			double log_prime = used_log[p];
//			fprintf(stderr, "offsets[%d] are %d and %d\n", used_primes[p], offsets[p][0], offsets[p][1]);

			for(int x = 0; x < 2; ++x)
			{
				size_t off = (offsets[p][x] + sieve_offset + prime-1) % prime;
				for(int a = off; a < sieve_size; a += prime)
				{
					table[a] -= log_prime;
	
					if(table[a] > LIMIT)
						continue;
	
					cand_offsets[num_cands++] = root + a + sieve_offset;
					if(num_cands > B)
						break;
				}
			}
		}
		sieve_offset += sieve_size;
	}

	for(size_t i = 0; i < num_cands; ++i)
	{
		//fprintf(stderr, "%llu\n", cand_offsets[i]);
		// TODO REMOVE VERY SLOW STUFF
		mpz_set_ui(tmp, root + i);
		mpz_pow_ui(tmp, tmp, 2);
		mpz_sub(tmp, tmp, num);
//		mpz_out_str(stderr, 10, tmp);
//		fputc('\n', stderr);
	}

	fprintf(stderr, "%d used candidates\n", num_cands);

	free(table);
	mpz_clear(tmp); mpz_clear(tmp2);
}
Exemple #22
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();
}
Exemple #23
0
int 
rsa_createkey_ex(PPUBKEY_EX ppubkey,PPRIVKEY_EX pprivkey){
    int retval;
    gmp_randstate_t hrandstate;
    mpz_t n;
    mpz_t pminus;
    mpz_t qminus;
    mpz_t z;
    mpz_t gcd;
    mpz_t dua; // untuk menghitung R2P,R2Q dan R2N
    //mpz_t d;
    unsigned long int k_int = 65537;
    /* inisialisasi semuanya */
    gmp_randinit_default(hrandstate);
    mpz_init(n);
    mpz_init(pminus);
    mpz_init(qminus);
    mpz_init(z);
    mpz_init(gcd);
    mpz_init(dua);
    mpz_init(ppubkey->p);
    mpz_init(ppubkey->q);
    mpz_init(ppubkey->e);
    mpz_init(pprivkey->p);
    mpz_init(pprivkey->q);
    mpz_init(pprivkey->d);
    mpz_init(pprivkey->dp);
    mpz_init(pprivkey->dq);
    mpz_init(pprivkey->zp);
    mpz_init(pprivkey->zq);
    mpz_init(pprivkey->r2p);
    mpz_init(pprivkey->r2q);
    mpz_init(pprivkey->r2n);
    mpz_init(pprivkey->r2modp);
    mpz_init(pprivkey->r2modq);

    /* inisialisasi randomizer */
    gmp_randseed_ui(hrandstate,GetTickCount());
    /* pick two random prime number (p and q ) */
    mpz_urandomb(pprivkey->p,hrandstate,PRIMESIZE);
    mpz_nextprime(pprivkey->p,pprivkey->p);
    mpz_urandomb(pprivkey->q,hrandstate,PRIMESIZE);
    mpz_nextprime(pprivkey->q,pprivkey->q);
    /* set public key p and q */
    mpz_set(ppubkey->p,pprivkey->p);
    mpz_set(ppubkey->q,pprivkey->q);
    /* calculate n = (p * q) */
    mpz_mul(n,pprivkey->q,pprivkey->p);
    /* calculate z = (p-1) * ( q - 1) */
    mpz_sub_ui(pminus,pprivkey->p,(unsigned int)1);
    mpz_sub_ui(qminus,pprivkey->q,(unsigned int)1);
    mpz_mul(z,pminus,qminus);
    /* choose k, such that k is co-prime to z, i.e z is not divisible by k 
       or in other word gcd(k,z) = 1 */
    while(1){
        mpz_gcd_ui(gcd,z,k_int);
        if(mpz_cmp_ui(gcd,(unsigned long)1) == 0)
            break;
        k_int +=1;
    }
    mpz_set_ui(ppubkey->e,k_int);

    /* calculate d for  e * d  = 1 mod z 
       which result d = e^(-1) mod z;
    */
    if(mpz_invert(pprivkey->d,ppubkey->e,z) == 0){
        /* cannot find d (multiplicative inverse) */
        rsa_cleanup_key(ppubkey,pprivkey);
        retval = -1;
        goto closure;
    }
    /* dp = d mod (p-1), dq = d mod (q-1) */
    mpz_mod(pprivkey->dp,pprivkey->d,pminus);
    mpz_mod(pprivkey->dq,pprivkey->d,qminus);

    /* zp = q^(p-1) mod n, zq = p^(q-1) mod n */
    mpz_powm(pprivkey->zp,pprivkey->q,pminus,n);
    mpz_powm(pprivkey->zq,pprivkey->p,qminus,n);

    /*  R2P = 2^(Jml bit P + 2 ) mod q */
    mpz_set_ui(dua,2);
    mpz_powm_ui(pprivkey->r2p,dua,(PRIMESIZE+2),pprivkey->p);
    /*  R2Q = 2^(Jml bit Q + 2 ) mod q */
    mpz_powm_ui(pprivkey->r2q,dua,(PRIMESIZE+2),pprivkey->q);
    /*  R2N = 2^(Jml bit N + 2 ) mod n */
    mpz_powm_ui(pprivkey->r2n,dua,(BITSTRENGTH+2),n);
    /* R2MODP = 2^(jml key size + 2) mod P */
    mpz_powm_ui(pprivkey->r2modp,dua,(BITSTRENGTH+2),pprivkey->p);
    /* R2MODQ = 2^(jml key size + 2) mod Q */
    mpz_powm_ui(pprivkey->r2modq,dua,(BITSTRENGTH+2),pprivkey->q);
    retval = 0;
    goto closure;



closure:
    mpz_clear(n);
    mpz_clear(pminus);
    mpz_clear(qminus);
    mpz_clear(z);
    mpz_clear(gcd);
    mpz_clear(dua);
    return retval;


}
Exemple #24
0
void mexp(int k, mpz_t b[k], mpz_t e[k], mpz_t *m, mpz_t *r) {

  // Main multiexp alg from paper
  int i, j, jnew, J, l, precompindex, offset,km;
  unsigned det;
  int msb_set;
  unsigned bitlen, maxbitlen = 0;

  // Setup and precomputation
  bases = b;
  modulus = m;
  numberOfFactors = k;

  // Compute window size
  for (i = 0; i < k; i++) {
    bitlen = mpz_sizeinbase(e[i], 2);
    if (bitlen > maxbitlen) maxbitlen = bitlen;
  }
  // TODO: Make this more elegant
  double lmb = log(maxbitlen)/log(2);
  winSize = (int) ceil((lmb - 2*(log(lmb)/log(2))) / k);
  if(winSize <= 0) winSize =1;


  // Build up precomputation table
  precomputation();

  km = k -1;
  mpz_set_ui(*r, 1);

  // Find maximal bit length of all exponents

  // Type conversion from unsigned to int. Only a problem for exponents
  // that have more binary digits than max(int). This is unlikely to occur in practice.
  // Maybe add check on arg to m_exp() to test for this possible problem?
  j = maxbitlen - 1;
  // A-while
  while (j >= 0) {
    // check if bit #maxbitlen is zero for all exponents
    // TODO: in the first iteraration this is the case by def of maxbitlen
    // -> can we skip first iteration to improve efficiency?
    msb_set = 0;

    for(i=0; i< k && msb_set == 0; i++) msb_set = mpz_tstbit(e[i], j);
    // B-if
    if (msb_set == 0) {
      mpz_powm_ui(*r, *r, 2, *m);
      j--;
    }
    // C-else
    else {
      if ( (j-winSize) > -1) jnew = j-winSize; else jnew = -1;
      J = jnew + 1;
      // D-while (is implemented as do-while)
      for(;;) {
	i = km;
	msb_set = 0;
	for(i=0; i< k && msb_set == 0; i++) msb_set = mpz_tstbit(e[i], j);
	if (msb_set == 0)
	  J++;
	else
	  break;
      }
      // E-for
      precompindex = 0;
      offset = winSize - (j - J) -1;
      for (i = km; i  >= 0; i--) {
	// Compute access index into pre-computation table
	precompindex <<= offset;
	for (l = j; l >= J; l--) {
	  precompindex <<= 1;
	  precompindex = precompindex | mpz_tstbit(e[i], l);
	}
      }
      // F-while
      det = 1;
      det <<= ((j-J)+1);
      mpz_powm_ui(*r, *r,det, *m);
      j = J-1;
      mpz_mul(*r, *r, preCompTable[precompindex]);
      mpz_mod(*r, *r, *m);

      // G-while
      if (j > jnew) {
	det =1;
	det <<= (j-jnew);
	mpz_powm_ui(*r, *r,det, *m);
	j = jnew + 1;
      }
    }
  }
  freeMemory();
}
Exemple #25
0
int
main (int argc, char **argv)
{
  mpz_t base, exp, mod;
  mpz_t r1, r2, base2;
  mp_size_t base_size, exp_size, mod_size;
  unsigned long int exp2;
  int i;
  int reps = 100;
  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 (base);
  mpz_init (exp);
  mpz_init (mod);
  mpz_init (r1);
  mpz_init (r2);
  mpz_init (base2);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 18 + 2;

      do  /* Loop until mathematically well-defined.  */
	{
	  mpz_urandomb (bs, rands, size_range);
	  base_size = mpz_get_ui (bs);
	  mpz_rrandomb (base, rands, base_size);

	  mpz_urandomb (bs, rands, 6L);
	  exp_size = mpz_get_ui (bs);
	  mpz_rrandomb (exp, rands, exp_size);
	  exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
	}
      while (mpz_cmp_ui (base, 0) == 0 && exp2 == 0);

      do
        {
	  mpz_urandomb (bs, rands, size_range);
	  mod_size = mpz_get_ui (bs);
	  mpz_rrandomb (mod, rands, mod_size);
	}
      while (mpz_cmp_ui (mod, 0) == 0);

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

      /* printf ("%ld %ld\n", SIZ (base), SIZ (mod)); */

#if 0
      putc ('\n', stderr);
      debug_mp (base, -16);
      debug_mp (mod, -16);
#endif

      mpz_powm_ui (r1, base, exp2, mod);
      MPZ_CHECK_FORMAT (r1);

      mpz_set_ui (r2, 1);
      mpz_set (base2, base);

      mpz_mod (r2, r2, mod);	/* needed when exp==0 and mod==1 */
      while (exp2 != 0)
	{
	  if (exp2 % 2 != 0)
	    {
	      mpz_mul (r2, r2, base2);
	      mpz_mod (r2, r2, mod);
	    }
	  mpz_mul (base2, base2, base2);
	  mpz_mod (base2, base2, mod);
	  exp2 = exp2 / 2;
	}

#if 0
      debug_mp (r1, -16);
      debug_mp (r2, -16);
#endif

      if (mpz_cmp (r1, r2) != 0)
	{
	  fprintf (stderr, "\ntest %d: Incorrect results for operands:\n", i);
	  debug_mp (base, -16);
	  debug_mp (exp, -16);
	  debug_mp (mod, -16);
	  fprintf (stderr, "mpz_powm_ui result:\n");
	  debug_mp (r1, -16);
	  fprintf (stderr, "reference result:\n");
	  debug_mp (r2, -16);
	  abort ();
	}
    }

  mpz_clear (bs);
  mpz_clear (base);
  mpz_clear (exp);
  mpz_clear (mod);
  mpz_clear (r1);
  mpz_clear (r2);
  mpz_clear (base2);

  tests_end ();
  exit (0);
}
Exemple #26
0
void field_init_mont_fp(field_ptr f, mpz_t prime) {
	PBC_ASSERT(!mpz_fits_ulong_p(prime), "modulus too small");
	fptr p;
	field_init(f);
	f->init = fp_init;
	f->clear = fp_clear;
	f->set_si = fp_set_si;
	f->set_mpz = fp_set_mpz;
	f->out_str = fp_out_str;
	f->snprint = fp_snprint;
	f->set_str = fp_set_str;
	f->add = fp_add;
	f->sub = fp_sub;
	f->set = fp_set;
	f->mul = fp_mul;
	f->doub = fp_double;
	f->halve = fp_halve;
	f->pow_mpz = fp_pow_mpz;
	f->neg = fp_neg;
	f->sign = fp_sgn_odd;
	f->cmp = fp_cmp;
	f->invert = fp_invert;
	f->random = fp_random;
	f->from_hash = fp_from_hash;
	f->is1 = fp_is1;
	f->is0 = fp_is0;
	f->set0 = fp_set0;
	f->set1 = fp_set1;
	f->is_sqr = fp_is_sqr;
	f->sqrt = element_tonelli;
	f->field_clear = fp_field_clear;
	f->to_bytes = fp_to_bytes;
	f->from_bytes = fp_from_bytes;
	f->to_mpz = fp_to_mpz;
	f->out_info = fp_out_info;

	// Initialize per-field data specific to this implementation.
	f->data = pbc_malloc(sizeof(*p));
	p = (fptr)f->data;
	p->limbs = mpz_size(prime);
	p->bytes = p->limbs * sizeof(mp_limb_t);
	p->primelimbs = (mp_limb_t*)pbc_malloc(p->bytes);
	mpz_export(p->primelimbs, &p->limbs, -1, sizeof(mp_limb_t), 0, 0, prime);
	mpz_set(f->order, prime);
	f->fixed_length_in_bytes = (mpz_sizeinbase(prime, 2) + 7) / 8;

	// Compute R, R3 and negpinv.
	mpz_t z;
	mpz_init(z);

	p->R = (mp_limb_t*)pbc_malloc(p->bytes);
	p->R3 = (mp_limb_t*)pbc_malloc(p->bytes);
	mpz_setbit(z, p->bytes * 8);
	mpz_mod(z, z, prime);
	set_limbs(p->R, z, p->limbs);

	mpz_powm_ui(z, z, 3, prime);
	set_limbs(p->R3, z, p->limbs);

	mpz_set_ui(z, 0);

	// Algorithm II.5 in Blake, Seroussi and Smart is better but this suffices
	// since we're only doing it once.
	mpz_setbit(z, p->bytes * 8);
	mpz_invert(z, prime, z);

#ifdef _MSC_VER		// for VC++ compatibility
	int tmp = mpz_get_ui(z);
	p->negpinv = -tmp;
#else
	p->negpinv = -mpz_get_ui(z);
#endif

	mpz_clear(z);
}
/*
 * This function reads the encrypted query sent by client, computes the intermediate cosine tfidf product and cosine co-ordination factor,
 * randomizes these two values and writes them along with respective randomizing values into the output_file_name.
 * */
int read_encrypt_vec_from_file_comp_inter_sec_prod( int vsizelocal, const char * input_encr_tfidf_file_name, const char * input_encr_bin_file_name, const char * input_tfidf_vec_file_name, const char * input_bin_vec_file_name, const char * output_file_name, const char * key_file_name)
{
	int input_size = 0, i, temp, *p_tfidf_vec, *p_bin_vec;
	mpz_t *vec1;	//holds input encrypted tfidf q values
	mpz_t *vec2;	//holds input encrypted binary q values
	mpz_t cosine_result;
	mpz_t co_ord_factor;
	mpz_t random_no;
	FILE *input_encr_tfidf_file, *input_tfidf_vec_file, *input_bin_vec_file, *output_file, *input_encr_bin_file;


	vsize = vsizelocal;
	input_encr_tfidf_file = fopen(input_encr_tfidf_file_name, "r");
	input_encr_bin_file = fopen(input_encr_bin_file_name, "r");
	input_tfidf_vec_file = fopen(input_tfidf_vec_file_name, "r");
	input_bin_vec_file = fopen(input_bin_vec_file_name, "r");
	output_file = fopen(output_file_name, "w");

	strncpy(g_key_file_name, key_file_name, sizeof(g_key_file_name));

	printf("Number of vector dimensions = %d\n", vsizelocal);
	//printf("p_tfidf_vec:%p, ENOMEM:%d\n", p_tfidf_vec, (errno == ENOMEM)?1:0);



	//initialize vectors and big number variables
	//Dynamically creating the array
	vec1 = (mpz_t *)malloc(vsizelocal*sizeof(mpz_t));
	vec2 = (mpz_t *)malloc(vsizelocal*sizeof(mpz_t));
	p_tfidf_vec = (int*)malloc(vsize*sizeof(int));
	p_bin_vec = (int*)malloc(vsize*sizeof(int));
	printf("p_tfidf_vec:%p, ENOMEM:%d\n", p_tfidf_vec, (errno == ENOMEM)?1:0);

	//initialize vectors and big number variables
	for (i = 0; i < vsizelocal; i++)
		mpz_init(*(vec1+i));
	for (i = 0; i < vsizelocal; i++)
		mpz_init(*(vec2+i));

	//variables are set to 0
	mpz_init(cosine_result);
	mpz_init(co_ord_factor);
	mpz_init(random_no);

	init();

	//variables are set to 0

	//init();



	//check if files are opened properly
	if (input_encr_tfidf_file == NULL) {
		printf("\n%s", "Error: open input_encr_tfidf_file!");
		return -2;
	}

	if (input_encr_bin_file == NULL) {
		printf("\n%s", "Error: open input_encr_bin_file!");
		return -2;
	}

	if (input_tfidf_vec_file == NULL) {
		printf("\n%s", "Error: open input_tfidf_vec_file!");
		return -3;
	}

	if (input_bin_vec_file == NULL) {
		printf("\n%s", "Error: open input_bin_vec_file!");
		return -4;
	}

	if (output_file == NULL) {
		printf("\n%s", "Error: open output_file!");
		exit(1);
	}


	//fill in the first vector
	input_size = 0;
	while ( (input_size < vsizelocal) )
	{
		if ( input_size == vsizelocal - 1 )
		{
			gmp_fscanf(input_encr_tfidf_file,"%Zd", (vec1+input_size));
		}
		else
		{
			gmp_fscanf(input_encr_tfidf_file,"%Zd\n", (vec1+input_size));
		}
		gmp_printf("%d>> READ %Zd\n", input_size+1, *(vec1+input_size));

		input_size++;
	}
	if ( !( input_size == vsizelocal ) )
	{
		fprintf(stderr, "%s:%d::ERROR! TFIDF: Nothing to read OR parsing error! input_size:%d, vsizelocal:%d\n", 
				__func__, __LINE__, input_size, vsizelocal);
		return -4;
	}

	input_size = 0;
	while ( (input_size < vsizelocal) )
	{
		if ( input_size == vsizelocal - 1 )
		{
			gmp_fscanf(input_encr_bin_file,"%Zd", (vec2+input_size));
		}
		else
		{
			gmp_fscanf(input_encr_bin_file,"%Zd\n", (vec2+input_size));
		}
		gmp_printf("%d>> READ %Zd\n", input_size+1, *(vec2+input_size));

		input_size++;
	}
	if ( !( input_size == vsizelocal ) )
	{
		fprintf(stderr, "%s:%d::ERROR! Binary: Nothing to read OR parsing error! input_size:%d, vsizelocal:%d\n", 
				__func__, __LINE__, input_size, vsizelocal);
		return -4;
	}


	printf("\n");
	input_size = 0;

	//fill in the second vector
	for( fscanf(input_tfidf_vec_file,"%d", &temp); temp != EOF && input_size < vsize; 
			fscanf(input_tfidf_vec_file, "%d", &temp) ){

		printf("Non encrypted TFIDF Input::Wt.:%d\n", temp);
		*(p_tfidf_vec + input_size) = temp;
		input_size ++;
	} 

	input_size = 0;
	for( fscanf(input_bin_vec_file,"%d", &temp); temp != EOF && input_size < vsize; 
			fscanf(input_bin_vec_file, "%d", &temp) ){

		printf("Non encrypted Binary Input::Wt.:%d\n", temp);
		*(p_bin_vec + input_size) = temp;
		input_size ++;
	} 

	encrypt(cosine_result, 0);
	//compute encrypted the vec1 * p_tfidf_vec (dot product)
	for (i = 0; i < input_size; i++) {
		//compute m1 * m2
		mpz_powm_ui(big_temp, *(vec1+i), *(p_tfidf_vec+i), n_square);
		//compute m1 + m2
		mpz_mul(cosine_result, cosine_result, big_temp);
		mpz_mod(cosine_result, cosine_result, n_square);
	}

	encrypt(co_ord_factor, 0);
	//compute encrypted the vec2 * co_ord_factor (dot product)
	for (i = 0; i < input_size; i++) {
		//compute m1 * m2
		mpz_powm_ui(big_temp, *(vec2+i), *(p_bin_vec+i), n_square);
		//compute m1 + m2
		mpz_mul(co_ord_factor, co_ord_factor, big_temp);
		mpz_mod(co_ord_factor, co_ord_factor, n_square);
	}


	/*
	 * Donot decrypt here as we would not be having the CORRESPONDING private key
	 * */
	//decrypt the encrypted dot product
	//decrypt(cosine_result);

	//TODO: Remove this debug decryption. - START
	mpz_t dot_prod;
	mpz_init(dot_prod);
	mpz_set(dot_prod, cosine_result);
	decrypt(dot_prod);
	gmp_fprintf(stderr, "\n%s:%d:: Query*%s TFIDF cosine product: %Zd\n", __func__, __LINE__, input_encr_tfidf_file_name, dot_prod);

	mpz_set(dot_prod, co_ord_factor);
	decrypt(dot_prod);
	gmp_fprintf(stderr, "%s:%d:: Query*%s CO-ORD. cosine product: %Zd\n\n", __func__, __LINE__, input_encr_bin_file_name, dot_prod);
	fflush(stderr);

	mpz_clear(dot_prod);
	//TODO: Remove this debug decryption. - END

	//decrypt the encrypted co ordination factor
	//decrypt(co_ord_factor);

	/*
	 * Generate two random numbers of the modulo n_square and the add these two
	 * to the two results - cosine product and co_ord_factor. 
	 * Write these two random values one after the other
	 * and then the randomized values after them in the output file
	 * given for performing the secure multiplication
	 * protocol. All should be seperated by a newline except maybe the last one
	 * written to the file. FORMAT - output file
	 * ===START===
	 * r_1
	 * randomized cosine tfidf product
	 * r_2
	 * randomized cosine co-ord. product
	 *  ===END===
	 * */

	//Generate random number, say r_1
	get_random_r_given_modulo(random_no, n_square);
	//Write r_1 to outputfile
	mpz_out_str(output_file, 10, random_no);
	fprintf(output_file, "\n");
	//Calculate randomized cosine tfidf product, MULTIPLYING to add
	mpz_mul(cosine_result, cosine_result, random_no);
	//Compute modulus
	mpz_mod(cosine_result, cosine_result, n_square);
	//Write randomized cosine tfidf product to output file
	mpz_out_str(output_file, 10, cosine_result);
	fprintf(output_file, "\n");

	//Generate random number, say r_2
	get_random_r_given_modulo(random_no, n_square);
	//Write r_2 to outputfile
	mpz_out_str(output_file, 10, random_no);
	fprintf(output_file, "\n");
	//Calculate randomized cosine tfidf product, MULTIPLYING to add
	mpz_mul(co_ord_factor, co_ord_factor, random_no);
	//Compute modulus
	mpz_mod(co_ord_factor, co_ord_factor, n_square);
	//Write randomized cosine co_ord product to output file
	mpz_out_str(output_file, 10, co_ord_factor);

	gmp_printf("\nThus similarity of %s and %s score = %Zd written in %s\n", input_encr_tfidf_file_name, input_tfidf_vec_file_name, cosine_result, output_file_name);
#if 0
	//print the cosine_result
	if (mpz_out_str(output_file, 10, cosine_result) == 0)
		printf("ERROR: Not able to write the cosine_result!\n");

	fprintf(output_file, "\n");
#endif
	gmp_printf("\nThus co-ord. factor of %s and %s score = %Zd written in %s\n", input_encr_bin_file_name, input_bin_vec_file_name, co_ord_factor, output_file_name);
#if 0
	//print the co_ord_factor
	if (mpz_out_str(output_file, 10, co_ord_factor) == 0)
		printf("ERROR: Not able to write the co_ord_factor!\n");
#endif


	fclose(input_encr_tfidf_file);  
	fclose(input_encr_bin_file);  
	//fflush(input_tfidf_vec_file);
	fclose(input_tfidf_vec_file);
	//fflush(input_bin_vec_file);
	fclose(input_bin_vec_file);
	fflush(output_file);
	fclose(output_file);

	//release space used by big number variables
	for (i = 0; i < vsizelocal; i++)
		mpz_clear(*(vec1+i));
	for (i = 0; i < vsizelocal; i++)
		mpz_clear(*(vec2+i));


	mpz_clear(cosine_result);
	mpz_clear(co_ord_factor);
	mpz_clear(random_no);
	clear();
	free(vec1);
	free(vec2);
	free(p_tfidf_vec);
	free(p_bin_vec);

	return 0;
}