mini-gmp: mpz_congruent_p and mpz_probab_prime_p
bodrato at mail.dm.unipi.it
bodrato at mail.dm.unipi.it
Tue Mar 4 19:35:02 UTC 2014
Ciao,
Il Lun, 3 Marzo 2014 9:16 pm, Niels M�ller ha scritto:
> Below is an attempt at implementing it (compile-tested only). Per
> Kurlberg suggested using bases k^2 + k + 41 instead of the sequence I
The good old Euler's prime-generating polynomial... http://oeis.org/A007634
> /* Primality testing */
>
> static int
> gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y,
> const mpz_t q, mp_bitcnt_t k)
...
> for (i = 1; i < k; i++)
> {
> mpz_powm_ui (y, y, 2, n);
> if (mpz_cmp (y, nm1) == 0)
> return 1;
> if (mpz_cmp_ui (y, 1) == 0)
> return 0;
May I suggest to change the second comparison to mpz_cmp_ui (y, 1) <= 0?
> /* This product is 0xc0cfd797, and fits in 32 bits. */
> #define GMP_PRIME_PRODUCT \
> (3UL*5UL*7UL*11UL*13UL*17UL*19UL*23UL*29UL)
Then I suggest to simplify the first few lines of prob_prime with:
/* Bit (p-1)/2 is set, for each odd prime below 67 */
#define GMP_PRIME_MASK 0x64b4cb6eUL
int
mpz_probab_prime_p (const mpz_t n, int reps)
{
unsigned x;
mpz_t nm1;
mpz_t q;
mpz_t y;
mp_bitcnt_t k;
if (mpz_even_p (n))
return mpz_cmpabs_ui (n, 2) ? 0 : 2;
if (mpz_cmpabs_ui (n, 66) < 0)
return 2 * (GMP_PRIME_MASK >> (n->_mp_d[0] >> 1) & 1);
if (mpz_gcd_ui (NULL, n, GMP_PRIME_PRODUCT) != 1)
return 0;
/* Ok, now n is odd, and all factors are >= 31. */
if (mpz_cmpabs_ui (n, 31*31) < 0)
return 2;
> /* Use Miller-Rabin, with a deterministic sequence of bases, based
> on 2^k (mod 509), where conveniently 512 = 3 (mod 509). Adding 3
etc...
I "kind of" tested it by substituting the isprime function in bootstrap.c
with the following:
int
isprime (unsigned long int t)
{
mpz_t z;
return mpz_probab_prime_p (mpz_roinit_n (z, &t, 1), 25);
}
and it worked...
Regards,
m
--
http://bodrato.it/
More information about the gmp-devel
mailing list