Miller–Rabin primality test: Difference between revisions

Content added Content deleted
m (→‎{{header|Fortran}}: works with)
(C)
Line 21: Line 21:
* Deterministic variants of the test exists and can be implemented as extra (not mandatory to complete the task)
* Deterministic variants of the test exists and can be implemented as extra (not mandatory to complete the task)


=={{header|C}}==
{{libheader|GMP}}
'''miller-rabin.h'''

<lang c>#ifndef _MILLER_RABIN_H_
#define _MILLER_RABIN_H
#include <gmp.h>
bool miller_rabin_test(mpz_t n, int j);
#endif</lang>

'''miller-rabin.c'''

{{trans|Fortran}}

For <code>decompose</code> (and header <tt>primedecompose.h</tt>), see [[Prime decomposition#C|Prime decomposition]].

<lang c>#include <stdbool.h>
#include <gmp.h>
#include "primedecompose.h"

#define MAX_DECOMPOSE 100

bool miller_rabin_test(mpz_t n, int j)
{
bool res;
mpz_t f[MAX_DECOMPOSE];
mpz_t s, d, a, x, r;
mpz_t n_1, n_3;
gmp_randstate_t rs;
int l=0, k;

res = false;
gmp_randinit_default(rs);

mpz_init(s); mpz_init(d);
mpz_init(a); mpz_init(x); mpz_init(r);
mpz_init(n_1); mpz_init(n_3);

if ( mpz_cmp_si(n, 3) <= 0 ) { // let us consider 1, 2, 3 as prime
gmp_randclear(rs);
return true;
}
if ( mpz_odd_p(n) != 0 ) {
mpz_sub_ui(n_1, n, 1); // n-1
mpz_sub_ui(n_3, n, 3); // n-3
l = decompose(n_1, f);
mpz_set_ui(s, 0);
mpz_set_ui(d, 1);
for(k=0; k < l; k++) {
if ( mpz_cmp_ui(f[k], 2) == 0 )
mpz_add_ui(s, s, 1);
else
mpz_mul(d, d, f[k]);
} // 2^s * d = n-1
while(j-- > 0) {
mpz_urandomm(a, rs, n_3); // random from 0 to n-4
mpz_add_ui(a, a, 2); // random from 2 to n-2
mpz_powm(x, a, d, n);
if ( mpz_cmp_ui(x, 1) == 0 ) continue;
mpz_set_ui(r, 0);
while( mpz_cmp(r, s) < 0 ) {
if ( mpz_cmp(x, n_1) == 0 ) break;
mpz_powm_ui(x, x, 2, n);
mpz_add_ui(r, r, 1);
}
if ( mpz_cmp(x, n_1) == 0 ) continue;
goto flush; // woops
}
res = true;
}

flush:
for(k=0; k < l; k++) mpz_clear(f[k]);
mpz_clear(s); mpz_clear(d);
mpz_clear(a); mpz_clear(x); mpz_clear(r);
mpz_clear(n_1); mpz_clear(n_3);
gmp_randclear(rs);
return res;
}</lang>

'''Testing'''

<lang c>#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <gmp.h>
#include "miller-rabin.h"

#define PREC 10
#define TOP 4000

int main()
{
mpz_t num;

mpz_init(num);
mpz_set_ui(num, 1);
while ( mpz_cmp_ui(num, TOP) < 0 ) {
if ( miller_rabin_test(num, PREC) ) {
gmp_printf("%Zd maybe prime\n", num);
} /*else {
gmp_printf("%Zd not prime\n", num);
}*/ // remove the comment iff you're interested in
// sure non-prime.
mpz_add_ui(num, num, 1);
}

mpz_clear(num);
return EXIT_SUCCESS;
}</lang>


=={{header|Fortran}}==
=={{header|Fortran}}==