Sz\303\241m\303\255t\303\263g\303\251pes sz\303\241melm\303\251letJ\303\241rai AntalEzek a programok csak szeml\303\251ltet\303\251sre szolg\303\241lnak1. A pr\303\255mek eloszl\303\241sa, szit\303\241l\303\241s2. Egyszer\305\261 faktoriz\303\241l\303\241si m\303\263dszerek3. Egyszer\305\261 pr\303\255mtesztel\303\251si m\303\263dszerekrestart; with(numtheory);3.1. K\303\251rd\303\251s.3.2. Feladat.#
# This procedure do Wilson's test. The return value
# is a pair of lower two digits of (n-1)!+1 in base n.
#
wilsontest:=proc(n::posint) local i,r,m;
r:=1; m:=n^2;
for i from 2 to n-1 do r:=r*i mod m od;
r:=r+1 mod m; [irem(r,n),iquo(r,n)] end;#
# This procedure do Wilson's test and
# look for Wilson numbers until a given
# limit.
#
wilson:=proc(n) local i,r,p,w;
p:=[]; w:=[];
for i from 2 to n do
r:=wilsontest(i);
if r[1]=0 then
p:=[op(p),i];
if r[2]=0 then w:=[op(w),i] fi
fi
od; [w,p] end;wilson(1000);3.3. Probl\303\251ma.3.4. Fermat-teszt.n:=(2^28-9)/7; 3&^(n-1) mod n; 2&^(n-1)mod n;3.5. Feladat.#
# This procedure do Fermat's test for the number n with base a.
# If the result is false, the number is composite, if FAIL,
# then may be prime.
#
fermattest:=proc(n::posint,a::posint)
if type(n,even) then error "first argument must be odd",n fi;
if n<3 then error "first argument is too small",n fi;
if n<=a then error "second argument is too large",a fi;
if modp(a&^(n-1),n)<>1 then RETURN(false) fi; FAIL end;n:=(2^28-9)/7; fermattest(n,3); fermattest(n,2);3.6. Feladat.#
# This procedure look for pseudoprimes until a given limit n
# in bases in the list L.
#
pseudoprime:=proc(n::posint,L::list(posint)) local pp,i,a,t;
pp:=[];
for i from max(3,op(L))+1 to n do
if type(i,even) then next fi;
for a in L do
t:=fermattest(i,a);
if not t then break fi
od;
if t=FAIL then
if not isprime(i) then pp:=[op(pp),i] fi
fi
od; pp end;pseudoprime(10000,[2]);3.7. Feladat.#
# This procedure look for Carmichael
# numbers until a given limit n.
#
carmichael:=proc(n) local L,i,a,t;
L:=[];
for i from 2 to n do
if type(i,even) then next fi;
if isprime(i) then next fi;
for a from 2 to i-1 do
if igcd(i,a)=1 then
t:=fermattest(i,a);
if not t then break fi
fi
od;
if t=FAIL then L:=[op(L),i] fi
od; L end;carmichael(10000);#
# Much larger speed can be obtained using that a number n is
# Carmichael number if and only if it is squre free, has at least
# three prime factors and p-1 divides n-1 for every prime factor
# p of n.
#
3.8. Lemma.3.9. Lemma.3.10. T\303\251tel.3.11. Defin\303\255ci\303\263.3.12. Euler t\303\251tele.3.13. Gauss lemm\303\241ja.3.14. Gauss kvadratikus reciprocit\303\241si t\303\266rv\303\251nye.3.15. Defin\303\255ci\303\263.3.16. T\303\251tel.3.17. P\303\251lda.3.18. A Jacobi-szimb\303\263lum kisz\303\241m\303\255t\303\241sa.#
# This recursive procedure calculates
# the Jacobi symbol (n|m) for integers
# m>2 and n, where m is odd.
#
jacobisymbol:=proc(n::integer,m::posint) local s;
if type(m,even) then error "second argument must be odd" fi;
if n=0 then RETURN(0) fi;
if n=1 then RETURN(1) fi;
if n<0 then
if type((m-1)/2,odd) then
RETURN(-jacobisymbol(-n,m))
else
RETURN(jacobisymbol(-n,m))
fi
fi;
if type(n,even) then
if type((irem(m,16)^2-1)/8,odd) then
RETURN(-jacobisymbol(n/2,m))
else
RETURN(jacobisymbol(n/2,m))
fi
fi;
if n>m then RETURN(jacobisymbol(irem(n,m),m)) fi;
if type(irem((m-1)/2,2)*irem((n-1)/2,2),odd) then
-jacobisymbol(m,n)
else
jacobisymbol(m,n)
fi
end;debug(jacobisymbol); jacobisymbol(76,131);#
# What is this?
#
jacobiproba:=proc(a,b,p,n) local i,j,L;
for i from 0 to n-1 do L:=[];
for j from 0 to p-1 do L:=[op(L),jacobi(a,b+(i*p+j)*a)]; od;
print(L);
od; end;3.19. Feladat.3.20. Feladat.interface(verboseproc=2);print(jacobi);3.21. Feladat.print(legendre);3.22. Soloway-Strassen-teszt.n:=561; 5&^(n-1) mod n; 5&^((n-1)/2) mod n; jacobi(5,n);3.23. Feladat.#
# This procedure do the Soloway-Strassen probabilistic test.
# The first parameter is the integer to test, the second
# the number of rounds. if the result is false, the number
# is composite, if FAIL, then probably prime.
#
solowaystrassen:=proc(n::posint,m::posint) local i,b,rnd;
if type(n,even) then error "first argument must be odd",n fi;
if n<5 then error "first argument is too small",n fi;
rnd:=rand(2..n-2);
for i to m do b:=rnd();
if igcd(b,n)>1 then RETURN(false) fi;
if modp(b&^((n-1)/2),n)<>modp(jacobi(b,n),n) then RETURN(false) fi
od; FAIL end;debug(solowaystrassen); solowaystrassen(5,2);3.24. Miller-Rabin-teszt.millerrabin:=proc(n::posint,b::posint) local j,e,r,bb;
if n<9 then ERROR(`first parameter is too small`,n) fi;
if type(n,even) then ERROR(`first parameter is even`,n) fi;
if b<2 then ERROR(`second parameter is too small`,b) fi;
if n<=b then ERROR(`second parameter is too large`,b) fi;
e:=0; r:=n-1;
while type(r,even) do e:=e+1; r:=r/2 od;
bb:=modp(b&^r,n); if bb=1 then RETURN(FAIL) fi;
for j to e while bb<>n-1 do bb:=modp(bb&^2,n) od;
if j=e+1 then RETURN(false) fi; FAIL; end;rabin:=proc(n::posint,m::posint) local i,j,b,e,r,rnd;
if n<9 then ERROR(`first parameter is too small`,n) fi;
if type(n,even) then ERROR(`first parameter is even`,n) fi;
rnd:=rand(2..n-1); e:=0; r:=n-1;
while type(r,even) do e:=e+1; r:=r/2 od;
for i to m do
b:=rnd();
if 1<gcd(b,n) then RETURN(false) fi;
modp(b&^r,n); if %=1 then next fi;
for j to e while %<>n-1 do modp(%&^2,n) od;
if j=e+1 then RETURN(false) fi;
od; FAIL end;trueisprime:=proc(n::posint) local f;
if n<2 then RETURN(false) fi;
if n=2 or n=3 or n=5 or n=7 or n=11 or n=13 then RETURN(true) fi;
if 1<gcd(n,30030) then RETURN(false) fi;
if n<289 then RETURN(true) fi;
if 1<gcd(n,247110827) then RETURN(false) fi;
f:=millerrabin(n,2); if f=false then RETURN(f) fi;
f:=millerrabin(n,3); if f=false then RETURN(f) fi;
if n<1373653 then RETURN(true) fi;
f:=millerrabin(n,5); if f=false then RETURN(f) fi;
if n< 5326001 then RETURN(true) fi;
f:=millerrabin(n,7); if f=false then RETURN(f) fi;
if n<3215031751 then RETURN(true) fi;
f:=millerrabin(n,11); if f=false then RETURN(f) fi;
if n<2152302898747 then RETURN(true) fi;
f:=millerrabin(n,13); if f=false then RETURN(f) fi;
if n<3474749660383 then RETURN(true) fi;
f:=millerrabin(n,17); if f=false then RETURN(f) fi;
if n<341550071728321 then RETURN(true) fi; FAIL end;3.25. Feladat.3.26. Feladat.3.27. Miller t\303\251tele.3.28. Feladat.#
# This procedure do Miller's deterministic test
# based on GRH. The parameter is the integer to test.
#
millertest:=proc(n::posint) local i,b,t;
if n=1 then RETURN(false) fi;
if n=2 or n=3 or n=5 or n=7 or n=11 or n=13 then RETURN(true) fi;
if type(n,even) then RETURN(false) fi;
if n=9 then RETURN(false) fi;
b:=floor(2.0002*ln(n)^2);
for i from 2 to b do
if not millerrabin(n,i) then RETURN(false) fi;
od; true end;millertest(17);3.29. Lucas-teszt.#
# This procedure do Lucas' test
# for the number n on the naive way
# using base a
#
naivelucastest:=proc(n,a) local m;
if igcd(a,n)>1 then RETURN(false) fi;
if modp(a&^(n-1),n)<>1 then RETURN(false) fi;
for m from 2 to n-2 do
if modp(a&^m,n)=1 then RETURN(false) fi
od; true end;#
# This procedure do Lucas' test
# for the number n using the set S of
# factors of n-1 and base a
#
lucastest:=proc(n,a,S) local p;
if n<=a then ERROR(`second parameter is too large`,a) fi;
if igcd(a,n)>1 then RETURN(false) fi;
if modp(a&^(n-1),n)<>1 then RETURN(false) fi;
for p in S do
if modp(a&^((n-1)/p),n)=1 then RETURN(FAIL) fi
od; true end;#
# This procedure do Lucas' test
# for numbers n*k^m+1 with small
# n,k,m and base a.
#
speclucas:=proc(n,k,m,a) local S,N,p;
S:=factorset(n);
if m>0 then S:=S union factorset(k) fi;
N:=n*k^m+1;
if N<=a then ERROR(`last parameter is too large`,a) fi;
if igcd(a,N)>1 then RETURN(false) fi;
if modp(a&^(N-1),N)<>1 then RETURN(false) fi;
for p in S do
if modp(a&^((N-1)/p),N)=1 then RETURN(FAIL) fi
od; true end;#
# This procedure try to find a large prime using Lucas' test.
# The search goes for n,n+1,n+2,... between numbers n*k^m+1.
#
largewithlucas:=proc(n::posint,k::posint,m::posint) local i,a,aa,f;
if k<2 then ERROR(`second parameter is too small`,k) fi;
for i from n do
f:=FAIL;
for a from 2 while f=FAIL do
f:=speclucas(i,k,m,a); aa:=a;
od;
print(i*k^m+1,aa,f);
od; end;debug(largewithlucas); debug(speclucas); largewithlucas(1,2,16);3.30. Feladat.3.31. P\303\251pin-teszt.#
# This procedure do the Pepin test
# for the Fermat number 2^(2^m)+1.
#
pepin:=proc(m::nonnegint) local N;
if m=0 then RETURN(true) fi;
N:=2^(2^m)+1;
if modp(3&^((N-1)/2),N)=N-1 then RETURN(true) fi;
false end;pepin(4); pepin(5);3.32. Feladat.3.32. Pocklington-Lehmer-teszt.#
# This procedure do the Lehmer-Pocklington test
# for the number n using the subset S of factors of
# n-1 and base a. Returns with the reduced set S.
#
LPtest:=proc(n,S,a) local p,newS;
if n<=a then ERROR(`last parameter is too large`,a) fi;
if igcd(a,n)>1 then RETURN(false) fi;
if modp(a&^(n-1),n)<>1 then RETURN(false) fi;
newS:=S;
for p in S do
if igcd(modp(a&^((n-1)/p),n)-1,n)=1 then newS:=newS minus {p} fi
od; newS; end;#
# This procedure try to find a large prime using
# Lehmer-Pocklington test. The search goes for n,n+1,... between
# numbers n*k^m+1.
#
largewithLP:=proc(n,k,m) local i,a,aa,S,S0;
if k<2 then ERROR(`second parameter is too small`,k) fi;
S0:=factorset(k);
for i from n do
if n<=k^m then S:=S0 else S:=S0 union factorset(i) fi;
for a from 2 while S<>{} and S<>false do
S:=LPtest(i*k^m+1,S,a);
aa:=a;
od;
if S=false then
print(i*k^m+1,aa,false)
else
print(i*k^m+1,aa,true)
fi
od; end;debug(largewithLP); largewithLP(1,2,16);#
# This procedure try to find factors of n having the form
# a*k+b from k=1 until K or the square root of n.
# Note that LPtest capable to prove that factors n have
# the form f*k+1, where f is the factorised part of n-1,
# and a test treated later capable to prove that
# factors have the form f*k+1 or f*k-1, where f is the
# factorised part of n+1.
#
tryfactors:=proc(a::posint,b::integer,n::posint,K::posint)
local nn,i,f;
if a=1 then error "first parameter is too small",a fi;
if b<=1-a then error "second parameter is too small",b fi;
f:=[]; nn:=n;
for i to K while (i*a+b)^2<=nn do
if modp(nn,i*a+b)=0 then
f:=[op(f),i*a+b];
nn:=nn/(i*a+b);
i:=i-1;
fi;
od; f end;3.34. Feladat.3.35. Feladat.3.36. Proth-teszt.3.37. Feladat.#
# This procedure do the Proth test for the number n=h*2^m+1.
#
proth:=proc(h::posint,m::posint) local a,b,n; n:=h*2^m+1;
if h>=2^m then error "first parmeter is too large",h fi;
if not type(h,odd) then error "first parameter must be odd",h fi;
if m=1 or m=2 then return true fi;
if m=3 then if h=5 then return true else return false fi fi;
# 2 is not a quadratic residue mod n, we start with 3
# (2*a|n)=(a|n), hence enough to try odd bases a
for a from 3 by 2 do
b:=2&^m mod a; b:=h*b+1 mod a;
# by quadratic reciprocity, (a|n)=(n|a)=(b|a)
b:=modp(2&^m,a); b:=modp(h*b+1,a);
if jacobi(b,a)=0 then return false fi;
if jacobi(b,a)=-1 then
if modp(a&^((n-1)/2),n)=n-1 then return true else return false fi;
fi;
od end;
proth(11,5);ifactor(11*2^5+1);3.38. T\303\251tel.#
# This test may be used if n-1=FR, where the factors
# of F are known, and there is given a bound B such that
# R has no primedivisor less then B, and FB>sqrt(N). First
# we have to use the Lehmer - Pocklington test with
# the set of divisors of F. After this the second step is
# to find an appropriate base a to R.
#
PLtestsecondstep:=proc(n,F,a) local p,newS;
if n<=a then ERROR(`last parameter is too large`,a) fi;
if igcd(a,n)>1 then RETURN(false) fi;
if modp(a&^(n-1),n)<>1 then RETURN(false) fi;
if igcd(modp(a&^F-1,n),n)=1 then RETURN(true) fi;
FAIL end; 3.39. Feladat.4. Lucas-sorozatok5. Alkalmaz\303\241sok 6. Sz\303\241mok \303\251s polinomok7. Gyors Fourier-transzform\303\241ci\303\2638. Elliptikus f\303\274ggv\303\251nyek9. Sz\303\241mol\303\241s elliptikus g\303\266rb\303\251ken10. Faktoriz\303\241l\303\241s elliptikus g\303\266rb\303\251kkel11. Pr\303\255mteszt elliptikus g\303\266rb\303\251kkel12. Polinomfaktoriz\303\241l\303\241s13. Az AKS-teszt14. A szita m\303\263dszerek alapjai15. Sz\303\241mtest szita16. Vegyes probl\303\251m\303\241kLUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYjLUkjbWlHRiQ2JVEhRicvJSdpdGFsaWNHUSV0cnVlRicvJSxtYXRodmFyaWFudEdRJ2l0YWxpY0Yn