This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,21 @@
{{Wikipedia|MillerRabin primality test}}
The [[wp:MillerRabin primality test|MillerRabin primality test]] or RabinMiller primality test is a primality test: an algorithm which determines whether a given number is prime or not. The algorithm, as modified by [[wp:Michael O. Rabin|Michael O. Rabin]] to avoid the [[wp:generalized Riemann hypothesis|generalized Riemann hypothesis]], is a probabilistic algorithm.
The pseudocode, from [[wp:Miller-Rabin primality test#Algorithm_and_running_time|Wikipedia]] is:
'''Input''': ''n'' > 2, an odd integer to be tested for primality;
''k'', a parameter that determines the accuracy of the test
'''Output''': ''composite'' if ''n'' is composite, otherwise ''probably prime''
write ''n'' 1 as 2<sup>''s''</sup>·''d'' with ''d'' odd by factoring powers of 2 from ''n'' 1
LOOP: '''repeat''' ''k'' times:
pick ''a'' randomly in the range [2, ''n'' 1]
''x'' ← ''a''<sup>''d''</sup> mod ''n''
'''if''' ''x'' = 1 or ''x'' = ''n'' 1 '''then''' '''do''' '''next''' LOOP
'''for''' ''r'' = 1 .. ''s'' 1
''x'' ← ''x''<sup>2</sup> mod ''n''
'''if''' ''x'' = 1 '''then''' '''return''' ''composite''
'''if''' ''x'' = ''n'' 1 '''then''' '''do''' '''next''' LOOP
'''return''' ''composite''
'''return''' ''probably prime''
* The nature of the test involves big numbers, so the use of "big numbers" libraries (or similar features of the language of your choice) are suggested, but '''not''' mandatory.
* Deterministic variants of the test exist and can be implemented as extra (not mandatory to complete the task)

View file

@ -0,0 +1,2 @@
---
note: Prime Numbers

View file

@ -0,0 +1,38 @@
MODE LINT=LONG INT;
MODE LOOPINT = INT;
MODE POWMODSTRUCT = LINT;
PR READ "prelude/pow_mod.a68" PR;
PROC miller rabin = (LINT n, LOOPINT k)BOOL: (
IF n<=3 THEN TRUE
ELIF NOT ODD n THEN FALSE
ELSE
LINT d := n - 1;
INT s := 0;
WHILE NOT ODD d DO
d := d OVER 2;
s +:= 1
OD;
TO k DO
LINT a := 2 + ENTIER (random*(n-3));
LINT x := pow mod(a, d, n);
IF x /= 1 THEN
TO s DO
IF x = n-1 THEN done FI;
x := x*x %* n
OD;
else: IF x /= n-1 THEN return false FI;
done: EMPTY
FI
OD;
TRUE EXIT
return false: FALSE
FI
);
FOR i FROM 937 TO 1000 DO
IF miller rabin(i, 10) THEN
print((" ",whole(i,0)))
FI
OD

View file

@ -0,0 +1,9 @@
generic
type Number is range <>;
package Miller_Rabin is
type Result_Type is (Composite, Probably_Prime);
function Is_Prime (N : Number; K : Positive := 10) return Result_Type;
end Miller_Rabin;

View file

@ -0,0 +1,55 @@
with Ada.Numerics.Discrete_Random;
package body Miller_Rabin is
function Is_Prime (N : Number; K : Positive := 10)
return Result_Type
is
subtype Number_Range is Number range 2 .. N - 1;
package Random is new Ada.Numerics.Discrete_Random (Number_Range);
function Mod_Exp (Base, Exponent, Modulus : Number) return Number is
Result : Number := 1;
begin
for E in 1 .. Exponent loop
Result := Result * Base mod Modulus;
end loop;
return Result;
end Mod_Exp;
Generator : Random.Generator;
D : Number := N - 1;
S : Natural := 0;
X : Number;
begin
-- exclude 2 and even numbers
if N = 2 then
return Probably_Prime;
elsif N mod 2 = 0 then
return Composite;
end if;
-- write N-1 as 2**S * D, with D mod 2 /= 0
while D mod 2 = 0 loop
D := D / 2;
S := S + 1;
end loop;
-- initialize RNG
Random.Reset (Generator);
for Loops in 1 .. K loop
X := Mod_Exp(Random.Random (Generator), D, N);
if X /= 1 and X /= N - 1 then
Inner : for R in 1 .. S - 1 loop
X := Mod_Exp (X, 2, N);
if X = 1 then return Composite; end if;
exit Inner when X = N - 1;
end loop Inner;
if X /= N - 1 then return Composite; end if;
end if;
end loop;
return Probably_Prime;
end Is_Prime;
end Miller_Rabin;

View file

@ -0,0 +1,25 @@
with Ada.Text_IO, Miller_Rabin;
procedure Mr_Tst is
type Number is range 0 .. (2**48)-1;
package Num_IO is new Ada.Text_IO.Integer_IO (Number);
package Pos_IO is new Ada.Text_IO.Integer_IO (Positive);
package MR is new Miller_Rabin(Number); use MR;
N : Number;
K : Positive;
begin
for I in Number(2) .. 1000 loop
if Is_Prime (I) = Probably_Prime then
Ada.Text_IO.Put (Number'Image (I));
end if;
end loop;
Ada.Text_IO.Put_Line (".");
Ada.Text_IO.Put ("Enter a Number: "); Num_IO.Get (N);
Ada.Text_IO.Put ("Enter the count of loops: "); Pos_IO.Get (K);
Ada.Text_IO.Put_Line ("What is it? " & Result_Type'Image (Is_Prime(N, K)));
end MR_Tst;

View file

@ -0,0 +1,86 @@
with Ada.Text_IO, Crypto.Types.Big_Numbers, Ada.Numerics.Discrete_Random;
procedure Miller_Rabin is
Bound: constant Positive := 256; -- can be any multiple of 32
package LN is new Crypto.Types.Big_Numbers (Bound);
use type LN.Big_Unsigned; -- all computations "mod 2**Bound"
function "+"(S: String) return LN.Big_Unsigned
renames LN.Utils.To_Big_Unsigned;
function Is_Prime (N : LN.Big_Unsigned; K : Positive := 10) return Boolean is
subtype Mod_32 is Crypto.Types.Mod_Type;
use type Mod_32;
package R_32 is new Ada.Numerics.Discrete_Random (Mod_32);
Generator : R_32.Generator;
function Random return LN.Big_Unsigned is
X: LN.Big_Unsigned := LN.Big_Unsigned_Zero;
begin
for I in 1 .. Bound/32 loop
X := (X * 2**16) * 2**16;
X := X + R_32.Random(Generator);
end loop;
return X;
end Random;
D: LN.Big_Unsigned := N - LN.Big_Unsigned_One;
S: Natural := 0;
A, X: LN.Big_Unsigned;
begin
-- exclude 2 and even numbers
if N = 2 then
return True;
elsif N mod 2 = LN.Big_Unsigned_Zero then
return False;
else
-- write N-1 as 2**S * D, with odd D
while D mod 2 = LN.Big_Unsigned_Zero loop
D := D / 2;
S := S + 1;
end loop;
-- initialize RNG
R_32.Reset (Generator);
-- run the real test
for Loops in 1 .. K loop
loop
A := Random;
exit when (A > 1) and (A < (N - 1));
end loop;
X := LN.Mod_Utils.Pow(A, D, N); -- X := (Random**D) mod N
if X /= 1 and X /= N - 1 then
Inner:
for R in 1 .. S - 1 loop
X := LN.Mod_Utils.Pow(X, LN.Big_Unsigned_Two, N);
if X = 1 then
return False;
end if;
exit Inner when X = N - 1;
end loop Inner;
if X /= N - 1 then
return False;
end if;
end if;
end loop;
end if;
return True;
end Is_Prime;
S: constant String :=
"4547337172376300111955330758342147474062293202868155909489";
T: constant String :=
"4547337172376300111955330758342147474062293202868155909393";
K: constant Positive := 10;
begin
Ada.Text_IO.Put_Line("Prime(" & S & ")=" & Boolean'Image(Is_Prime(+S, K)));
Ada.Text_IO.Put_Line("Prime(" & T & ")=" & Boolean'Image(Is_Prime(+T, K)));
end Miller_Rabin;

View file

@ -0,0 +1,26 @@
with Ada.Text_IO, Crypto.Types.Big_Numbers, Ada.Numerics.Discrete_Random;
procedure Miller_Rabin is
Bound: constant Positive := 256; -- can be any multiple of 32
package LN is new Crypto.Types.Big_Numbers (Bound);
use type LN.Big_Unsigned; -- all computations "mod 2**Bound"
function "+"(S: String) return LN.Big_Unsigned
renames LN.Utils.To_Big_Unsigned;
S: constant String :=
"4547337172376300111955330758342147474062293202868155909489";
T: constant String :=
"4547337172376300111955330758342147474062293202868155909393";
K: constant Positive := 10;
begin
Ada.Text_IO.Put_Line("Prime(" & S & ")="
& Boolean'Image (LN.Mod_Utils.Passed_Miller_Rabin_Test(+S, K)));
Ada.Text_IO.Put_Line("Prime(" & T & ")="
& Boolean'Image (LN.Mod_Utils.Passed_Miller_Rabin_Test(+T, K)));
end Miller_Rabin;

View file

@ -0,0 +1,41 @@
MsgBox % MillerRabin(999983,10) ; 1
MsgBox % MillerRabin(999809,10) ; 1
MsgBox % MillerRabin(999727,10) ; 1
MsgBox % MillerRabin(52633,10) ; 0
MsgBox % MillerRabin(60787,10) ; 0
MsgBox % MillerRabin(999999,10) ; 0
MsgBox % MillerRabin(999995,10) ; 0
MsgBox % MillerRabin(999991,10) ; 0
MillerRabin(n,k) { ; 0: composite, 1: probable prime (n < 2**31)
d := n-1, s := 0
While !(d&1)
d>>=1, s++
Loop %k% {
Random a, 2, n-2 ; if n < 4,759,123,141, it is enough to test a = 2, 7, and 61.
x := PowMod(a,d,n)
If (x=1 || x=n-1)
Continue
Cont := 0
Loop % s-1 {
x := PowMod(x,2,n)
If (x = 1)
Return 0
If (x = n-1) {
Cont = 1
Break
}
}
IfEqual Cont,1, Continue
Return 0
}
Return 1
}
PowMod(x,n,m) { ; x**n mod m
y := 1, i := n, z := x
While i>0
y := i&1 ? mod(y*z,m) : y, z := mod(z*z,m), i >>= 1
Return y
}

View file

@ -0,0 +1,70 @@
( 1:?seed
& ( rand
=
. mod$(!seed*1103515245+12345.4294967296):?seed
& mod$(div$(!seed.65536).32768)
)
& ( rangerand
= from to b h i m n r length
. !arg:(?from,?to)
& !to+-1*!from+1:?m
& @(!m:? [?length)
& div$(!length+1.2)+1:?h
& 100^mod$(!h.!m):?b
& whl
' ( 0:?n
& !h+1:?i
& whl
' ( !i+-1:>0:?i
& rand$:?r
& whl'(!r:<68&rand$:?r)
& !n*100+mod$(!r.100):?n
)
& !n:>!b
)
& !from+mod$(!n.!m)
)
& ( miller-rabin-test
= n k d r a x s return
. !arg:(?n,?k)
& ( !n:~>3&1
| mod$(!n.2):0
| !n+-1:?d
& 0:?s
& whl
' ( mod$(!d.2):0
& !d*1/2:?d
& 1+!s:?s
)
& 1:?return
& whl
' ( !k+-1:?k:~<0
& rangerand$(2,!n+-2):?a
& mod$(!a^!d.!n):?x
& ( !x:1
| 0:?r
& whl
' ( !r+1:~>!s:?r
& !n+-1:~!x
& mod$(!x*!x.!n):?x
)
& ( !n+-1:!x
| 0:?return&~
)
)
)
& !return
)
)
& 0:?i
& :?primes
& whl
' ( 1+!i:<1000:?i
& ( miller-rabin-test$(!i,10):1
& !primes !i:?primes
|
)
)
& !primes:? [-11 ?last
& out$!last
);

View file

@ -0,0 +1,5 @@
#ifndef _MILLER_RABIN_H_
#define _MILLER_RABIN_H
#include <gmp.h>
bool miller_rabin_test(mpz_t n, int j);
#endif

View file

@ -0,0 +1,63 @@
#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;
}

View file

@ -0,0 +1,29 @@
#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;
}

View file

@ -0,0 +1,43 @@
(defun factor-out (number divisor)
"Return two values R and E such that NUMBER = DIVISOR^E * R,
and R is not divisible by DIVISOR."
(do ((e 0 (1+ e))
(r number (/ r divisor)))
((/= (mod r divisor) 0) (values r e))))
(defun mult-mod (x y modulus) (mod (* x y) modulus))
(defun expt-mod (base exponent modulus)
"Fast modular exponentiation by repeated squaring."
(labels ((expt-mod-iter (b e p)
(cond ((= e 0) p)
((evenp e)
(expt-mod-iter (mult-mod b b modulus)
(/ e 2)
p))
(t
(expt-mod-iter b
(1- e)
(mult-mod b p modulus))))))
(expt-mod-iter base exponent 1)))
(defun random-in-range (lower upper)
"Return a random integer from the range [lower..upper]."
(+ lower (random (+ (- upper lower) 1))))
(defun miller-rabin-test (n k)
"Test N for primality by performing the Miller-Rabin test K times.
Return NIL if N is composite, and T if N is probably prime."
(cond ((= n 1) nil)
((< n 4) t)
((evenp n) nil)
(t
(multiple-value-bind (d s) (factor-out (- n 1) 2)
(labels ((strong-liar? (a)
(let ((x (expt-mod a d n)))
(or (= x 1)
(loop repeat s
for y = x then (mult-mod y y n)
thereis (= y (- n 1)))))))
(loop repeat k
always (strong-liar? (random-in-range 2 (- n 2)))))))))

View file

@ -0,0 +1,48 @@
import std.random;
bool isProbablePrime(in ulong n, in int k) {
static long modPow(long b, long e, in long m)
pure nothrow {
long result = 1;
while (e > 0) {
if ((e & 1) == 1) {
result = (result * b) % m;
}
b = (b * b) % m;
e >>= 1;
}
return result;
}
if (n < 2 || n % 2 == 0)
return n == 2;
ulong d = n - 1;
ulong s = 0;
while (d % 2 == 0) {
d /= 2;
s++;
}
assert(2 ^^ s * d == n - 1);
outer:
foreach (_; 0 .. k) {
ulong a = uniform(2, n);
ulong x = modPow(a, d, n);
if (x == 1 || x == n - 1)
continue;
foreach (__; 1 .. s) {
x = modPow(x, 2, n);
if (x == 1) return false;
if (x == n - 1) continue outer;
}
return false;
}
return true;
}
void main() { // demo code
import std.stdio, std.range, std.algorithm;
writeln(filter!(n => isProbablePrime(n, 10))(iota(2, 30)));
}

View file

@ -0,0 +1,23 @@
def millerRabinPrimalityTest(n :(int > 0), k :int, random) :boolean {
if (n <=> 2 || n <=> 3) { return true }
if (n <=> 1 || n %% 2 <=> 0) { return false }
var d := n - 1
var s := 0
while (d %% 2 <=> 0) {
d //= 2
s += 1
}
for _ in 1..k {
def nextTrial := __continue
def a := random.nextInt(n - 3) + 2 # [2, n - 2] = [0, n - 4] + 2 = [0, n - 3) + 2
var x := a**d %% n # Note: Will do optimized modular exponentiation
if (x <=> 1 || x <=> n - 1) { nextTrial() }
for _ in 1 .. (s - 1) {
x := x**2 %% n
if (x <=> 1) { return false }
if (x <=> n - 1) { nextTrial() }
}
return false
}
return true
}

View file

@ -0,0 +1,4 @@
for i ? (millerRabinPrimalityTest(i, 1, entropy)) in 4..1000 {
print(i, " ")
}
println()

View file

@ -0,0 +1,78 @@
-module(miller_rabin).
-compile([export_all]).
basis(N) when N>2 ->
1 + random:uniform(N-2).
find_ds(D, S) ->
case D rem 2 == 0 of
true ->
find_ds(trunc(D/2), S+1);
false ->
{D, S}
end.
find_ds(N) ->
find_ds(N-1, 0).
pow_mod(B, E, M) ->
case E of
0 -> 1;
_ -> case trunc(E) rem 2 == 0 of
true -> trunc(math:pow(pow_mod(B, trunc(E/2), M), 2)) rem M;
false -> trunc(B*pow_mod(B, E-1, M)) rem M
end
end.
mr_series(N, A, D, S) when N rem 2 == 1 ->
Js = lists:seq(0, S),
lists:map(fun(J) -> pow_mod(A, math:pow(2, J)*D, N) end, Js).
is_mr_prime(N, As) when N>2, N rem 2 == 1 ->
{D, S} = find_ds(N),
not lists:any(fun(A) ->
case mr_series(N, A, D, S) of
[1|_] -> false;
L -> not lists:member(N-1, L)
end
end,
As).
proving_bases(N) when N < 1373653 ->
[2, 3];
proving_bases(N) when N < 25326001 ->
[2, 3, 5];
proving_bases(N) when N < 25000000000 ->
[2, 3, 5, 7];
proving_bases(N) when N < 2152302898747->
[2, 3, 5, 7, 11];
proving_bases(N) when N < 341550071728321 ->
[2, 3, 5, 7, 11, 13];
proving_bases(N) when N < 341550071728321 ->
[2, 3, 5, 7, 11, 13, 17].
random_bases(N, K) ->
[basis(N) || _ <- lists:seq(1, K)].
is_prime(1) -> false;
is_prime(2) -> true;
is_prime(N) when N rem 2 == 0 -> false;
is_prime(N) when N < 341550071728321 ->
is_mr_prime(N, proving_bases(N)).
is_probable_prime(N) ->
is_mr_prime(N, random_bases(N, 20)).
first_1000() ->
L = lists:seq(1,1000),
lists:map(fun(X) ->
case is_prime(X) of
true ->
io:format("~w~n", [X]);
false ->
false
end
end,
L),
ok.

View file

@ -0,0 +1,56 @@
module Miller_Rabin
use PrimeDecompose
implicit none
integer, parameter :: max_decompose = 100
private :: int_rrand, max_decompose
contains
function int_rrand(from, to)
integer(huge) :: int_rrand
integer(huge), intent(in) :: from, to
real :: o
call random_number(o)
int_rrand = floor(from + o * real(max(from,to) - min(from, to)))
end function int_rrand
function miller_rabin_test(n, k) result(res)
logical :: res
integer(huge), intent(in) :: n
integer, intent(in) :: k
integer(huge), dimension(max_decompose) :: f
integer(huge) :: s, d, i, a, x, r
res = .true.
f = 0
if ( (n <= 2) .and. (n > 0) ) return
if ( mod(n, 2) == 0 ) then
res = .false.
return
end if
call find_factors(n-1, f)
s = count(f == 2)
d = (n-1) / (2 ** s)
loop: do i = 1, k
a = int_rrand(2_huge, n-2)
x = mod(a ** d, n)
if ( x == 1 ) cycle
do r = 0, s-1
if ( x == ( n - 1 ) ) cycle loop
x = mod(x*x, n)
end do
if ( x == (n-1) ) cycle
res = .false.
return
end do loop
res = .true.
end function miller_rabin_test
end module Miller_Rabin

View file

@ -0,0 +1,24 @@
program TestMiller
use Miller_Rabin
implicit none
integer, parameter :: prec = 30
integer(huge) :: i
! this is limited since we're not using a bignum lib
call do_test( (/ (i, i=1, 29) /) )
contains
subroutine do_test(a)
integer(huge), dimension(:), intent(in) :: a
integer :: i
do i = 1, size(a,1)
print *, a(i), miller_rabin_test(a(i), prec)
end do
end subroutine do_test
end program TestMiller

View file

@ -0,0 +1,66 @@
package main
import "log"
func main() {
// max uint32 is not prime
c := uint32(1<<32 - 1)
// a few primes near the top of the range. source: prime pages.
for _, p := range []uint32{1<<32 - 5, 1<<32 - 17, 1<<32 - 65, 1<<32 - 99} {
for ; c > p; c-- {
if prime(c) {
log.Fatalf("prime(%d) returned true", c)
}
}
if !prime(p) {
log.Fatalf("prime(%d) returned false", p)
}
c--
}
}
func prime(n uint32) bool {
// bases of 2, 7, 61 are sufficient to cover 2^32
switch n {
case 0, 1:
return false
case 2, 7, 61:
return true
}
// compute s, d where 2^s * d = n-1
nm1 := n - 1
d := nm1
s := 0
for d&1 == 0 {
d >>= 1
s++
}
n64 := uint64(n)
for _, a := range []uint32{2, 7, 61} {
// compute x := a^d % n
x := uint64(1)
p := uint64(a)
for dr := d; dr > 0; dr >>= 1 {
if dr&1 != 0 {
x = x * p % n64
}
p = p * p % n64
}
if x == 1 || uint32(x) == nm1 {
continue
}
for r := 1; ; r++ {
if r >= s {
return false
}
x = x * x % n64
if x == 1 {
return false
}
if uint32(x) == nm1 {
break
}
}
}
return true
}

View file

@ -0,0 +1,32 @@
import System.Random
import Data.List
import Control.Monad
import Control.Arrow
primesTo100 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
powerMod :: (Integral a, Integral b) => a -> a -> b -> a
powerMod m _ 0 = 1
powerMod m x n | n > 0 = join (flip f (n - 1)) x `rem` m where
f _ 0 y = y
f a d y = g a d where
g b i | even i = g (b*b `rem` m) (i `quot` 2)
| otherwise = f b (i-1) (b*y `rem` m)
witns :: (Num a, Ord a, Random a) => Int -> a -> IO [a]
witns x y = do
g <- newStdGen
let r = [9080191, 4759123141, 2152302898747, 3474749600383, 341550071728321]
fs = [[31,73],[2,7,61],[2,3,5,7,11],[2,3,5,7,11,13],[2,3,5,7,11,13,17]]
if y >= 341550071728321
then return $ take x $ randomRs (2,y-1) g
else return $ snd.head.dropWhile ((<= y).fst) $ zip r fs
isMillerRabinPrime :: Integer -> IO Bool
isMillerRabinPrime n | n `elem` primesTo100 = return True
| otherwise = do
let pn = pred n
e = uncurry (++) . second(take 1) . span even . iterate (`div` 2) $ pn
try = return . all (\a -> let c = map (powerMod n a) e in
pn `elem` c || last c == 1)
witns 100 n >>= try

View file

@ -0,0 +1,22 @@
procedure main()
every writes(primeTest(901 to 1000, 10)," ")
write()
end
procedure primeTest(n, k)
if n = 2 then return n
if n%2 = 0 then fail
s := 0
d := n-1
while (d%2 ~= 0, s+:=1, d/:=2)
every (1 to k, x := ((1+?(n-2))^d)%n) do {
if x = (1 | (n-1)) then next
every (1 to s-1, x := (x^2)%n) do {
if x = 1 then fail
if x = n-1 then break next
}
fail
}
return n
end

View file

@ -0,0 +1,9 @@
import java.math.BigInteger;
public class MillerRabinPrimalityTest {
public static void main(String[] args) {
BigInteger n = new BigInteger(args[0]);
int certainty = Integer.parseInt(args[1]);
System.out.println(n.toString() + " is " + (n.isProbablePrime(certainty) ? "probably prime" : "composite"));
}
}

View file

@ -0,0 +1,31 @@
function modProd(a,b,n){
if(b==0) return 0;
if(b==1) return a%n;
return (modProd(a,(b-b%10)/10,n)*10+(b%10)*a)%n;
}
function modPow(a,b,n){
if(b==0) return 1;
if(b==1) return a%n;
if(b%2==0){
var c=modPow(a,b/2,n);
return modProd(c,c,n);
}
return modProd(a,modPow(a,b-1,n),n);
}
function isPrime(n){
if(n==2||n==3||n==5) return true;
if(n%2==0||n%3==0||n%5==0) return false;
if(n<25) return true;
for(var a=[2,3,5,7,11,13,17,19],b=n-1,d,t,i,x;b%2==0;b/=2);
for(i=0;i<a.length;i++){
x=modPow(a[i],b,n);
if(x==1||x==n-1) continue;
for(t=true,d=b;t&&d<n-1;d*=2){
x=modProd(x,x,n); if(x==n-1) t=false;
}
if(t) return false;
}
return true;
}
for(var i=1;i<=1000;i++) if(isPrime(i)) console.log(i);

View file

@ -0,0 +1,9 @@
MillerRabin[n_,k_]:=Module[{d=n-1,s=0,test=True},While[Mod[d,2]==0 ,d/=2 ;s++]
Do[
a=RandomInteger[{2,n-1}]; x=PowerMod[a,d,n];
If[x!=1,
For[ r = 0, r < s, r++, If[x==n-1, Continue[]]; x = Mod[x*x, n]; ];
If[ x != n-1, test=False ];
];
,{k}];
Print[test] ]

View file

@ -0,0 +1,2 @@
MillerRabin[17388,10]
->False

View file

@ -0,0 +1,47 @@
/* Miller-Rabin algorithm is builtin, see function primep. Here is another implementation */
/* find highest power of p, p^s, that divide n, and return s and n / p^s */
facpow(n, p) := block(
[s: 0],
while mod(n, p) = 0 do (s: s + 1, n: quotient(n, p)),
[s, n]
)$
/* check whether n is a strong pseudoprime to base a; s and d are given by facpow(n - 1, 2) */
sppp(n, a, s, d) := block(
[x: power_mod(a, d, n), q: false],
if x = 1 or x = n - 1 then true else (
from 2 thru s do (
x: mod(x * x, n),
if x = 1 then return(q: false) elseif x = n - 1 then return(q: true)
),
q
)
)$
/* Miller-Rabin primality test. For n < 341550071728321, the test is deterministic;
for larger n, the number of bases tested is given by the option variable
primep_number_of_tests, which is used by Maxima in primep. The bound for deterministic
test is also the same as in primep. */
miller_rabin(n) := block(
[v: [2, 3, 5, 7, 11, 13, 17], s, d, q: true, a],
if n < 19 then member(n, v) else (
[s, d]: facpow(n - 1, 2),
if n < 341550071728321 then ( /* see http://oeis.org/A014233 */
for a in v do (
if not sppp(n, a, s, d) then return(q: false)
),
q
) else (
thru primep_number_of_tests do (
a: 2 + random(n - 3),
if not sppp(n, a, s, d) then return(q: false)
),
q
)
)
)$

View file

@ -0,0 +1,39 @@
<?php
function is_prime($n, $k) {
if ($n == 2)
return true;
if ($n < 2 || $n % 2 == 0)
return false;
$d = $n - 1;
$s = 0;
while ($d % 2 == 0) {
$d /= 2;
$s++;
}
for ($i = 0; $i < $k; $i++) {
$a = rand(2, $n-1);
$x = bcpowmod($a, $d, $n);
if ($x == 1 || $x == $n-1)
continue;
for ($j = 1; $j < $s; $j++) {
$x = bcmod(bcmul($x, $x), $n);
if ($x == 1)
return false;
if ($x == $n-1)
continue 2;
}
return false;
}
return true;
}
for ($i = 1; $i <= 1000; $i++)
if (is_prime($i, 10))
echo "$i, ";
echo "\n";
?>

View file

@ -0,0 +1,35 @@
use bigint;
sub is_prime
{
my ($n,$k) = @_;
return 1 if $n == 2;
return 0 if $n < 2 or $n % 2 == 0;
$d = $n - 1;
$s = 0;
while(!($d % 2))
{
$d /= 2;
$s++;
}
LOOP: for(1..$k)
{
$a = 2 + int(rand($n-2));
$x = $a->bmodpow($d, $n);
next if $x == 1 or $x == $n-1;
for(1..$s-1)
{
$x = ($x*$x) % $n;
return 0 if $x == 1;
next LOOP if $x == $n-1;
}
return 0;
}
return 1;
}
print join ", ", grep { is_prime $_,10 }(1..1000);

View file

@ -0,0 +1,47 @@
(de longRand (N)
(use (R D)
(while (=0 (setq R (abs (rand)))))
(until (> R N)
(unless (=0 (setq D (abs (rand))))
(setq R (* R D)) ) )
(% R N) ) )
(de **Mod (X Y N)
(let M 1
(loop
(when (bit? 1 Y)
(setq M (% (* M X) N)) )
(T (=0 (setq Y (>> 1 Y)))
M )
(setq X (% (* X X) N)) ) ) )
(de _prim? (N D S)
(use (A X R)
(while (> 2 (setq A (longRand N))))
(setq R 0 X (**Mod A D N))
(loop
(T
(or
(and (=0 R) (= 1 X))
(= X (dec N)) )
T )
(T
(or
(and (> R 0) (= 1 X))
(>= (inc 'R) S) )
NIL )
(setq X (% (* X X) N)) ) ) )
(de prime? (N K)
(default K 50)
(and
(> N 1)
(bit? 1 N)
(let (D (dec N) S 0)
(until (bit? 1 D)
(setq
D (>> 1 D)
S (inc S) ) )
(do K
(NIL (_prim? N D S))
T ) ) ) )

View file

@ -0,0 +1,78 @@
import random
_mrpt_num_trials = 5 # number of bases to test
def is_probable_prime(n):
"""
Miller-Rabin primality test.
A return value of False means n is certainly not prime. A return value of
True means n is very likely a prime.
>>> is_probable_prime(1)
Traceback (most recent call last):
...
AssertionError
>>> is_probable_prime(2)
True
>>> is_probable_prime(3)
True
>>> is_probable_prime(4)
False
>>> is_probable_prime(5)
True
>>> is_probable_prime(123456789)
False
>>> primes_under_1000 = [i for i in range(2, 1000) if is_probable_prime(i)]
>>> len(primes_under_1000)
168
>>> primes_under_1000[-10:]
[937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
>>> is_probable_prime(6438080068035544392301298549614926991513861075340134\
3291807343952413826484237063006136971539473913409092293733259038472039\
7133335969549256322620979036686633213903952966175107096769180017646161\
851573147596390153)
True
>>> is_probable_prime(7438080068035544392301298549614926991513861075340134\
3291807343952413826484237063006136971539473913409092293733259038472039\
7133335969549256322620979036686633213903952966175107096769180017646161\
851573147596390153)
False
"""
assert n >= 2
# special case 2
if n == 2:
return True
# ensure n is odd
if n % 2 == 0:
return False
# write n-1 as 2**s * d
# repeatedly try to divide n-1 by 2
s = 0
d = n-1
while True:
quotient, remainder = divmod(d, 2)
if remainder == 1:
break
s += 1
d = quotient
assert(2**s * d == n-1)
# test the base a to see whether it is a witness for the compositeness of n
def try_composite(a):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2**i * d, n) == n-1:
return False
return True # n is definitely composite
for i in range(_mrpt_num_trials):
a = random.randrange(2, n)
if try_composite(a):
return False
return True # no base tested showed n as composite

View file

@ -0,0 +1,72 @@
/*REXX program puts Miller-Rabin primality test through its paces. */
arg limit accur . /*get some arguments (if any). */
if limit=='' | limit==',' then limit=1000 /*maybe assume LIMIT default*/
if accur=='' | accur==',' then accur=10 /* " " ACCUR " */
numeric digits max(200,2*limit) /*we're dealing with some biggies*/
tell=accur<0 /*show primes if K is negative.*/
accur=abs(accur) /*now, make K postive. */
call suspenders /*suspenders now, belt later... */
primePi=# /*save the count of (real) primes*/
say "They're" primePi 'primes ' limit /*might as well crow a wee bit. */
say /*nothing wrong with whitespace. */
do a=2 to accur /*(skipping 1) do range of K's.*/
say copies('',79) /*show separator for the eyeballs*/
mrp=0 /*prime counter for this pass. */
do z=1 for limit /*now, let's get busy and crank. */
p=Miller_Rabin(z,a) /*invoke and pray... */
if p==0 then iterate /*Not prime? Then try another. */
mrp=mrp+1 /*well, found another one, by gum*/
if tell then say z, /*maybe should do a show & tell ?*/
'is prime according to Miller-Rabin primality test with K='a
if !.z\==0 then iterate
say '[K='a"] " z "isn't prime !" /*oopsy-doopsy & whoopsy-daisy!*/
end /*z*/
say 'for 1'limit", K="a', Miller-Rabin primality test found' mrp,
'primes {out of' primePi"}"
end /*a*/
exit /*stick a fork in it, we're done.*/
/*─────────────────────────────────────Miller─Rabin primality test.─────*/
/*─────────────────────────────────────Rabin─Miller (also known as)─────*/
Miller_Rabin: procedure; parse arg n,k
if n==2 then return 1 /*special case of an even prime. */
if n<2 | n//2==0 then return 0 /*check for low, or even number.*/
d=n-1
nL=n-1 /*saves a bit of time, down below*/
s=0
do while d//2==0; d=d%2; s=s+1; end /*while d//2==0 */
do k
a=random(2,nL)
x=(a**d) // n /*this number can get big fast. */
if x==1 | x==nL then iterate
do r=1 for s-1
x=(x*x) // n
if x==1 then return 0 /*it's definately not prime. */
if x==nL then leave
end /*r*/
if x\==nL then return 0 /*nope, it ain't prime nohows. */
end /*k*/
/*maybe it is, maybe it ain't ...*/
return 1 /*coulda/woulda/shoulda be prime.*/
/*──────────────────────────────────SUSPENDERS subroutine───────────────*/
suspenders: @.=0; !.=0 /*crank up the ole prime factory.*/
@.1=2; @.2=3; @.3=5; #=3 /*prime the pump with low primes.*/
!.2=1; !.3=1; !.5=1 /*and don't forget the water jar.*/
do j =@.#+2 by 2 to limit /*just process the odd integers. */
do k=2 while @.k**2<=j /*let's do the ole primality test*/
if j//@.k==0 then iterate j /*the Greek way, in days of yore.*/
end /*k*/ /*a useless comment, but hey!! */
#=#+1 /*bump the prime counter. */
@.#=j /*keep priming the prime pump. */
!.j=1 /*and keep filling the water jar.*/
end /*j*/ /*this comment not left blank. */
return /*whew! All done with the primes*/

View file

@ -0,0 +1,23 @@
require 'openssl'
def miller_rabin_prime?(n,g)
d = n - 1
s = 0
while d % 2 == 0
d /= 2
s += 1
end
g.times do
a = 2 + rand(n-4)
x = OpenSSL::BN::new(a.to_s).mod_exp(d,n) #x = (a**d) % n
next if x == 1 or x == n-1
for r in (1 .. s-1)
x = x.mod_exp(2,n) #x = (x**2) % n
return false if x == 1
break if x == n-1
end
return false if x != n-1
end
true # probably
end
p primes = (3..1000).step(2).find_all {|i| miller_rabin_prime?(i,10)}

View file

@ -0,0 +1,7 @@
puts miller_rabin_prime?(94366396730334173383107353049414959521528815310548187030165936229578960209523421808912459795329035203510284576187160076386643700441216547732914250578934261891510827140267043592007225160798348913639472564715055445201512461359359488795427875530231001298552452230535485049737222714000227878890892901228389026881,1000)
puts miller_rabin_prime?(138028649176899647846076023812164793645371887571371559091892986639999096471811910222267538577825033963552683101137782650479906670021895135954212738694784814783986671046107023185842481502719762055887490765764329237651328922972514308635045190654896041748716218441926626988737664133219271115413563418353821396401,1000)
puts miller_rabin_prime?(123301261697053560451930527879636974557474268923771832437126939266601921428796348203611050423256894847735769138870460373141723679005090549101566289920247264982095246187318303659027201708559916949810035265951104246512008259674244307851578647894027803356820480862664695522389066327012330793517771435385653616841,1000)
puts miller_rabin_prime?(119432521682023078841121052226157857003721669633106050345198988740042219728400958282159638484144822421840470442893056822510584029066504295892189315912923804894933736660559950053226576719285711831138657839435060908151231090715952576998400120335346005544083959311246562842277496260598128781581003807229557518839,1000)
puts miller_rabin_prime?(132082885240291678440073580124226578272473600569147812319294626601995619845059779715619475871419551319029519794232989255381829366374647864619189704922722431776563860747714706040922215308646535910589305924065089149684429555813953571007126408164577035854428632242206880193165045777949624510896312005014225526731,1000)
puts miller_rabin_prime?(153410708946188157980279532372610756837706984448408515364579602515073276538040155990230789600191915021209039203172105094957316552912585741177975853552299222501069267567888742458519569317286299134843250075228359900070009684517875782331709619287588451883575354340318132216817231993558066067063143257425853927599,1000)
puts miller_rabin_prime?(103130593592068072608023213244858971741946977638988649427937324034014356815504971087381663169829571046157738503075005527471064224791270584831779395959349442093395294980019731027051356344056416276026592333932610954020105156667883269888206386119513058400355612571198438511950152690467372712488391425876725831041,1000)

View file

@ -0,0 +1,34 @@
Integer extend [
millerRabinTest: kl [ |k| k := kl.
self <= 3
ifTrue: [ ^true ]
ifFalse: [
(self even)
ifTrue: [ ^false ]
ifFalse: [ |d s|
d := self - 1.
s := 0.
[ (d rem: 2) == 0 ]
whileTrue: [
d := d / 2.
s := s + 1.
].
[ k:=k-1. k >= 0 ]
whileTrue: [ |a x r|
a := Random between: 2 and: (self - 2).
x := (a raisedTo: d) rem: self.
( x = 1 )
ifFalse: [ |r|
r := -1.
[ r := r + 1. (r < s) & (x ~= (self - 1)) ]
whileTrue: [
x := (x raisedTo: 2) rem: self
].
( x ~= (self - 1) ) ifTrue: [ ^false ]
]
].
^true
]
]
]
].

View file

@ -0,0 +1,3 @@
1 to: 1000 do: [ :n |
(n millerRabinTest: 10) ifTrue: [ n printNl ]
].

View file

@ -0,0 +1,34 @@
package require Tcl 8.5
proc miller_rabin {n k} {
if {$n <= 3} {return true}
if {$n % 2 == 0} {return false}
# write n - 1 as 2^s·d with d odd by factoring powers of 2 from n 1
set d [expr {$n - 1}]
set s 0
while {$d % 2 == 0} {
set d [expr {$d / 2}]
incr s
}
while {$k > 0} {
incr k -1
set a [expr {2 + int(rand()*($n - 4))}]
set x [expr {($a ** $d) % $n}]
if {$x == 1 || $x == $n - 1} continue
for {set r 1} {$r < $s} {incr r} {
set x [expr {($x ** 2) % $n}]
if {$x == 1} {return false}
if {$x == $n - 1} break
}
if {$x != $n-1} {return false}
}
return true
}
for {set i 1} {$i < 1000} {incr i} {
if {[miller_rabin $i 10]} {
puts $i
}
}