A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
21
Task/Miller-Rabin-primality-test/0DESCRIPTION
Normal file
21
Task/Miller-Rabin-primality-test/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{{Wikipedia|Miller–Rabin primality test}}
|
||||
The [[wp:Miller–Rabin primality test|Miller–Rabin primality test]] or Rabin–Miller 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)
|
||||
2
Task/Miller-Rabin-primality-test/1META.yaml
Normal file
2
Task/Miller-Rabin-primality-test/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Prime Numbers
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
);
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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)))))))))
|
||||
|
|
@ -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)));
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
for i ? (millerRabinPrimalityTest(i, 1, entropy)) in 4..1000 {
|
||||
print(i, " ")
|
||||
}
|
||||
println()
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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] ]
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
MillerRabin[17388,10]
|
||||
->False
|
||||
|
|
@ -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
|
||||
)
|
||||
)
|
||||
)$
|
||||
|
|
@ -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";
|
||||
?>
|
||||
|
|
@ -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);
|
||||
|
|
@ -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 ) ) ) )
|
||||
|
|
@ -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
|
||||
|
|
@ -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*/
|
||||
|
|
@ -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)}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
]
|
||||
]
|
||||
]
|
||||
].
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
1 to: 1000 do: [ :n |
|
||||
(n millerRabinTest: 10) ifTrue: [ n printNl ]
|
||||
].
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue