Hi,

I saw code posted earlier today that did LL testing with the GMP
library. It used the mpz_powm_ui function for exponentiating modulo x.
For x=2**p-1 this function can be sped up considerably, since
a mod (2^p-1) = a % 2^p + a / 2^p (integer operations) and these can
be done by bit shifting/masking.

I use this function below for my P-1 factorer (not released (yet?)).
It gave me a factor 3 speedup. It�s a pretty straigtforward
exponentiation algo 
exp(b,e) = if (e & 1) b*exp(b**2,e >>1) else exp(b**2,e >>1)
with the modulo by bit shifting.
It�s still worlds slower than the FFT code of George, of course. One day
I�ll have to deal with this FFT business.

To Will Edington: I think I saw in the P-1 factorer of the mers package
that it used mpz_powm_ui, too, perhaps you may want to replace it.

Ciao,
  Alex.


void mpz_powmmers_ui(mpz_t r,mpz_t b,unsigned long int e,unsigned long
int n) 
// thats (result, base, exponent, exponent of mersenne to modulo by
(2^n-1))
{
  mpz_t t,u;

  mpz_init(u);
  mpz_init_set(t,b);
  while (mpz_sizeinbase(t,2) > n)
  {
    mpz_tdiv_q_2exp(u,t,n);
    mpz_fdiv_r_2exp(t,t,n);
    mpz_add(t,t,u);
  }  


  if (e & 1)
    { mpz_set(r,t); }
  else
    { mpz_set_ui(r,1); }
  e = e >> 1;
  
  while (e)
  {
    mpz_mul(t,t,t);
    while (mpz_sizeinbase(t,2) > n)
    {
      mpz_tdiv_q_2exp(u,t,n);
      mpz_fdiv_r_2exp(t,t,n);
      mpz_add(t,t,u);
    }
    
    if (e & 1)
    {
      mpz_mul(r,r,t);
      while (mpz_sizeinbase(r,2) > n)
      {
        mpz_tdiv_q_2exp(u,r,n);
        mpz_fdiv_r_2exp(r,r,n);
        mpz_add(r,r,u);
      }
    }    
    e = e >> 1;
  }
}

Reply via email to