Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

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,77 @@
MODULE MRTEST !Try the Miller-Rabin primality test.
CONTAINS !Working only with in-built integers.
LOGICAL FUNCTION MRPRIME(N,TRIALS) !Could N be a prime number?
USE DFPORT !To get RAND.
INTEGER N !The number.
INTEGER TRIALS !The count of trials to make.
INTEGER D,S !Represents a number in a special form.
INTEGER TRIAL
INTEGER A,X,R
Catch some annoying cases.
IF (N .LE. 4) THEN !A single-digit number?
MRPRIME = N.GT.1 .AND. N.LE.3 !Yes. Some special values.
RETURN !Thus allow 2 to be reported as prime.
END IF !Yet, test for 2 as a possible factor for larger numbers.
MRPRIME = .FALSE. !Pessimism prevails.
IF (MOD(N,2).EQ.0 .OR. MOD(N,3).EQ.0) RETURN !Thus.
Construct D such that N - 1 = D*2**S. By here, N is odd, and greater than three.
D = N - 1 !Thus, D becomes an even number.
S = 1 !So, it has at least one power of two.
10 D = D/2 !Divide it out.
IF (MOD(D,2).EQ.0) THEN !If there is another,
S = S + 1 !Count it,
GO TO 10 !And divide it out also.
END IF !So, D is no longer even. N = 1 + D*2**S
WRITE (6,11) N,D,S
11 FORMAT("For ",I0,", D=",I0,",S=",I0)
Convince through repetition..
T:DO TRIAL = 1,TRIALS !Some trials yield a definite result.
A = RAND(0)*(N - 2) + 2 !For small N, the birthday problem.
X = MODEXP(N,A,D) !A**D mod N.
WRITE (6,22) TRIAL,A,X,INT8(A)**D,N,MOD(INT8(A)**D,N)
22 FORMAT(6X,"Trial ",I0,",A=",I4,",X=",I4,
1 "=MOD(",I0,",",I0,")=",I0)
IF (X.EQ.1 .OR. X.EQ.N - 1) CYCLE T !Pox. A prime yields these.
DO R = 1,S - 1 !Step through the powers of two in N - 1.
X = MODEXP(N,X,2) !X**2 mod N.
WRITE (6,23) R,X
23 FORMAT (14X,"R=",I4,",X=",I0)
IF (X.EQ.1) RETURN !Definitely composite. No prime does this.
IF (X.EQ.N - 1) CYCLE T !Pox. Try something else.
END DO !Another power of two?
RETURN !Definitely composite.
END DO T !Have another go.
MRPRIME = .TRUE. !Would further trials yield greater assurance?
END FUNCTION MRPRIME !Are some numbers resistant to this scheme?
INTEGER FUNCTION MODEXP(N,X,P) !Calculate X**P mod N without overflowing...
C Relies on a.b mod n = (a mod n)(b mod n) mod n
INTEGER N,X,P !All presumed positive, and X < N.
INTEGER I !A stepper.
INTEGER*8 V,W !Broad scratchpads, otherwise N > 46340 may incur overflow in 32-bit.
V = 1 !=X**0
IF (P.GT.0) THEN !Something to do?
I = P !Yes. Get a copy I can mess with.
W = X !=X**1, X**2, X**4, X**8, ... except, all are mod N.
1 IF (MOD(I,2).EQ.1) V = MOD(V*W,N) !Incorporate W if the low-end calls for it.
I = I/2 !Used. Shift the next one down.
IF (I.GT.0) THEN !Still something to do?
W = MOD(W**2,N) !Yes. Square W ready for the next bit up.
GO TO 1 !Consider it.
END IF !Don't square W if nothing remains. It might overflow.
END IF !Negative powers are ignored.
MODEXP = V !Done, in lb(P) iterations!
END FUNCTION MODEXP !"Bit" presence by arithmetic: works for non-binary arithmetic too.
PROGRAM POKEMR
USE MRTEST
INTEGER I
LOGICAL HIC
DO I = 3,36,2
HIC = MRPRIME(I,6)
WRITE (6,11) I,HIC
11 FORMAT (I6,1X,L)
END DO
END