Skip to content
Snippets Groups Projects
Commit ac4ae7ad authored by Martin Mareš's avatar Martin Mareš
Browse files

Teorie čísel: Testování prvočiselnosti

Bezostyšně kopíruji svůj starý numth.tex.
parent 4d1eac78
No related branches found
No related tags found
No related merge requests found
...@@ -24,7 +24,8 @@ Nejprve připomeneme základní značení: ...@@ -24,7 +24,8 @@ Nejprve připomeneme základní značení:
\:$x\perp y$ značí, že $x$ a $y$ jsou \em{nesoudělná,} tedy $\gcd(x,y)=1$. \:$x\perp y$ značí, že $x$ a $y$ jsou \em{nesoudělná,} tedy $\gcd(x,y)=1$.
\:$x\equiv y\pmod n$ je \em{kongruence modulo~$n>0$,} která znamená, že $x$ a~$y$ \:$x\equiv y\pmod n$ je \em{kongruence modulo~$n>0$,} která znamená, že $x$ a~$y$
dávají stejný zbytek modulo~$n$. To je totéž, jako že $n\divs (x-y)$. dávají stejný zbytek modulo~$n$. To je totéž, jako že $n\divs (x-y)$.
Pokud bude z~kontextu jasné, modulo čím počítáme, budeme psát prostě $x\equiv y$. Někdy to budeme zkracovat na $x\equiv_n y$
a~pokud bude z~kontextu jasné, modulo čím počítáme, budeme psát prostě $x\equiv y$.
\endlist \endlist
\section{Základní aritmetické algoritmy} \section{Základní aritmetické algoritmy}
...@@ -458,12 +459,275 @@ Prvočíselnost: ...@@ -458,12 +459,275 @@ Prvočíselnost:
se složitostí $\O(b^6\log^c b)$. V~praxi jsou mnohem pomalejší než ty pravděpodobnostní. se složitostí $\O(b^6\log^c b)$. V~praxi jsou mnohem pomalejší než ty pravděpodobnostní.
\endlist \endlist
\subsection{Triviální testy}
\def\Prime{{\csc prvočíslo}}
\def\Comp{{\csc složené}}
Jak navrhnout pravděpodobnostní test prvočíselnosti? Testujeme-li číslo~$n$, můžeme
vygenerovat rovnoměrně náhodné $a\in\{2,\ldots,n-1\}$ a otestovat, zda $a$ je dělitelem~$n$.
Pokud je, odpovíme, že $n$ je složené. Jinak odpovíme, že $n$ je prvočíslo.
Jak dobrý tento test je? Doběhne vždy v~čase $\O(b^3)$.
Pokud odpoví \Comp, je to vždy pravda.
Pokud odpoví \Prime, může se mýlit.
Pro prvočíslo tedy vždy odpoví \Prime, ale pro složené číslo může odpovědět špatně.
Chtěli bychom tedy dokázat, že test složené číslo \uv{usvědčí}
s~dost velkou pravděpodobností. To bohužel neplatí: je-li $n=pq$ pro dvě různá prvočísla $p$ a~$q$,
test odpoví \Comp{} pouze pro $a=p$ a $a=q$. Pravděpodobnost usvědčení je tedy pouze $2/(n-2)$.
Druhý pokus: opět vygenerujeme náhodné~$a$ a tentokrát spočítáme $\gcd(a,n)$. Pokud je to více
než~1, našli jsme netriviálního dělitele a odpovíme \Comp{} (takovému~$a$ se říká \em{Euklidův
svědek} složenosti). Pokud vyjde~1, odpovíme \Prime. Pro prvočísla tedy vždy odpovídáme správně,
zatímco u~složeného čísla se můžeme mýlit. Jaká je pravděpodobnost, že složené číslo usvědčíme?
Pro $n=pq$ bohužel stále dost malá. Jelikož $\varphi(pq) = (p-1)(q-1)$, Euklidových svědků existuje
jenom $pq - 1 - (p-1)(q-1) = p + q$. Je-li $p\approx q$, je počet svědků řádově $\sqrt{n}$, takže
pravděpodobnost, že se do nějakého strefíme, je pouze $\sqrt{n} / n = 1 / \sqrt{n}$.
\subsection{Fermatův test} \subsection{Fermatův test}
Zajímavější test získáme z~malé Fermatovy věty. Ta říká, že pro prvočíslo~$n$ a libovolné $a\perp n$
platí $a^{n-1}\bmod n = 1$. Pokud tedy pro dané~$n$ najdeme~$a\perp n$, pro které $a^{n-1}\bmod n \ne 1$,
víme, že $n$~není prvočíslo. Takovému~$a$ se říká \em{Fermatův svědek} složenosti. Celý test bude
vypadat následovně:
\algo{FermatůvTest}
\algin číslo $n>1$
\:Zvolíme rovnoměrně náhodně $a\in\{2,\ldots,n-1\}$.
\:[fermeukl]Pokud $\gcd(a,n)\ne 1$, odpovíme \Comp. \cmt{$a$ je Euklidův svědek}
\:[fermwit]Pokud $a^{n-1}\bmod n\ne 1$, odpovíme \Comp. \cmt{$a$ je Fermatův svědek}
\:Odpovíme \Prime.
\endalgo
Test pracuje v~čase $\O(b^3)$. Krok~\itemref{fermeukl} bychom dokonce mohli vynechat, protože
pokud $d=\gcd(a,n) > 1$, je $a^{n-1}$ dělitelné~$d$, a~tím pádem i $a^{n-1}\bmod n$
dělitelné~$d$, a~proto by číslo prohlásil za složené i samotný krok~\itemref{fermwit}. Přítomnost
druhého kroku nám nicméně zjednoduší uvažování o~testu.
Pokud test odpoví \Comp, nemýlí se. Pro prvočísla tedy vždy odpovídá správně.
Potřebujeme ukázat, že složená čísla mají dostatek svědků, takže se
s~nezanedbatelnou pravděpodobností do nějakého strefíme.
To bohužel není pravda: existují \em{Carmichaelova čísla,} což jsou složená čísla
bez Fermatových svědků, takže je lze usvědčit pouze Euklidovými svědky, kterých je
obecně málo. Nejmenší Carmichaelovo číslo je 561 a dnes už se ví, že existuje nekonečně mnoho
dalších, takže nestačí do algoritmu zabudovat tabulku výjimek.
Dobrá zpráva ovšem je, že pro ostatní čísla test funguje dobře.
\lemma{
Je-li $n$ složené číslo, které není Carmichaelovo, Fermatův test ho usvědčí s~pravděpodobností aspoň~$1/2$.
}
\proof
Spusťme algoritmus s~daným~$n$. Pokud narazíme na Euklidova svědka, rovnou odpovíme správně.
Stačí tedy lemma dokazat pro $a$ rovnoměrně náhodně vybrané z~$\Zsn$.
Uvažme podmnožinu $H\subseteq\Zsn$ čísel, která nejsou Fermatovými svědky. Tedy:
$$
H = \{ a\in\Zsn \mid a^{n-1}\bmod n = 1 \}.
$$
Dokážeme, že $H$ je podgroupu~$\Zsn$. Jistě platí $1\in H$. Pokud $a,b\in H$,
máme $(ab)^{n-1} \equiv a^{n-1}b^{n-1} \equiv 1\cdot 1 \equiv 1$, takže $ab\in H$.
Podobně ověříme, že pro $a\in H$ je $a\inv\in H$.
Nyní použijeme Lagrangeovu větu a získáme $|H|\divs |\Zsn|$. Jenže $n$ není Carmichaelovo,
takže $H\ne\Zsn$, a~tím pádem musí být $|H| \le |\Zsn|/2$. Pravděpodobnost, že najdeme
Fermatova svědka, je tedy alespoň $1/2$.
\qed
Může se zdát, že pravděpodobnost usvědčení $1/2$ není nic moc. Ovšem pravděpodobnostní
test můžeme iterovat: spustíme ho $t$-krát s~nezávisle náhodnými~$a$ a odpovíme \Prime{}
pouze tehdy, když se na tom všechna spuštění shodla. Pravděpodobnost chyby je pak nejvýše
$1/2^t$. Časovou složitost jsme přitom zhoršili jen na $\O(tb^3)$.
\subsection{Rabinův-Millerův test} \subsection{Rabinův-Millerův test}
V~praxi se používá důmyslnější test, který se nenechá zmást ani Carmichaelovými čísly.
Funguje následovně:
\algo{RabinůvMillerůvTest}
\algin číslo $n>1$
\:Zvolíme rovnoměrně náhodně $a\in\{2,\ldots,n-1\}$.
\:[rmeukl]Pokud $\gcd(a,n)\ne 1$, odpovíme \Comp. \cmt{$a$ je Euklidův svědek}
\:Najdeme $t$ a liché~$m$ taková, že $n-1=2^t\cdot m$.
\:Spočteme $b_0 \= a^m \bmod n$.
\:Spočteme $b_1,\ldots,b_t$: $b_{i+1} = a_i^2 \bmod n$ (tudíž $b_t\equiv x^{n-1}$).
\:Pokud je $b_t\ne 1$, odpovíme \Comp. \cmt{$a$ je Fermatův svědek}
\:[rmallone]Pokud jsou všechna $b_0,\ldots,b_t = 1$, odpovíme \Prime.
\:Jinak vezmeme nejvyšší~$i$, pro něž $b_i\ne 1$:
\::[rmmone]Pokud je $b_i\equiv -1$, odpovíme \Prime.
\::Jinak odpovíme \Comp{}. \cmt{$a$ je Riemannův svědek}
\endalgo
Krok~\itemref{rmeukl} můžeme stejně jako u Fermatova testu vypustit, ale jeho
přítomnost nám usnadní analýzu algoritmu.
Na algoritmus se můžeme dívat i jinak: nejdříve spočteme $a^{n-1}$ (vše mod~$n$).
Pokud nevyjde jednička, je $n$ složené podle Fermatova testu. Pokud vyjde a $n-1$ je sudé,
musí být $a^{(n-1)/2}$ odmocninou z~jedničky. Tyto odmocniny mohou existovat jenom dvě: 1 a~$-1$
(kvadratický polynom má nejvýš dva kořeny v~každém tělese).
Pokud tedy vyjde něco jiného, $n$ jistě není prvočíslo.
Pokud vyjde opět jednička, pokračujeme v~odmocňování a počítáme $a^{(n-1)/4}$, $a^{(n-1)/8}$, atd.
Zastavíme se, když narazíme na~$-1$ (tehdy odpovíme \Prime), nebo na něco jiného
než $\pm 1$ (\Comp), nebo když exponent přestane být celočíselný (\Prime).
Z~této úvahy plyne, že kdykoliv odpovíme \Comp, je to pravda.
Důležité ovšem je, že pro všechna složená čísla existuje dostatek svědků:
\theorem{
Rabinův-Millerův test testuje prvočíselnost v~polynomiálním čase, na~prvočísla
odpovídá správně a složená čísla prohlašuje za prvočísla s~pravděpodobností nejvýše $1/4$.
}
Důkaz je poměrně náročný, naleznete ho například v~knize Computational Number Theory
od Victora Shoupa. Zjednodušenou verzi (pro konstantu $1/2$ namísto $1/4$) uvádíme níže.
\rem{
Za~zmínku ještě stojí, že původní Millerův test byl deterministický a pan Miller o~něm
dokázal, že pokud platí rozšířená Riemannova hypotéza, má každé složené číslo svědka
(Fermatova či Riemannova), který je jen logaritmicky velký. Zda je to pravda, to se dosud neví,
nicméně pan Rabin později nahlédl, že svědků vždy existuje alespoň $3/4\cdot n$,
a randomizovaný algoritmus byl na~světě.
}
\section{Diskrétní logaritmy} \section{Diskrétní logaritmy}
\section{Diskrétní odmocniny} \section{Diskrétní odmocniny}
\sectionstar{Rozbor Rabinova-Millerova testu}
O~Rabinově-Millerově testu již víme, že prvočíslo vždy prohlásí za~prvočíslo
a že složené číslo, které není Carmichaelovo, usvědčí s~pravděpodobností alespoň $1/2$.
Nyní dokážeme, že je to pravda i pro Carmichaelova čísla. Nejprve si připravíme půdu jedním drobným lemmatem:
\lemma{
Žádné Carmichaelovo číslo není mocninou prvočísla (druhou nebo větší).
}
\proof
Uvažujme libovolné $n=p^e$, kde $p$ je prvočíslo a $e>1$.
Zvolíme $a = 1 + p^{e-1}$ a podle binomické věty spočteme $a^p$ (vše počítáme v~$Z^*_n$, kam~$a$ jistě patří):
$$
a^p \equiv (1+p^{e-1})^p \equiv {p\choose 0}\cdot 1\cdot 1 + {p\choose 1}\cdot 1\cdot p^{e-1} + {p\choose 2}\cdot 1\cdot p^{2(e-1)} + \ldots + {p\choose p}\cdot 1\cdot p^{p(e-1)} \equiv 1
$$
(všechny členy mimo nultého jsou totiž dělitelné~$p^e$ -- prvnímu pomůže kombinační číslo, u~ostatních stačí vyšší mocnina $p^{e-1}$).
Proto také $a^n \equiv (a^p)^e \equiv 1$. Tedy $a^{n-1} \equiv a^{-1} \not\equiv 1$,
takže $n$ není Carmichaelovo.
\qed
Nyní uvažujme, kdy může Rabinův-Millerův test odpovědět, že číslo je prvočíslem. Stane
se tak buď v~kroku~\itemref{rmallone} (všechna $b_0,\ldots,b_t$ jsou jedničky, což nastane, kdykoliv $b_0\equiv 1$)
nebo v~kroku~\itemref{rmmone} (nějaké $b_i\equiv -1$ a $b_{i+1}\equiv\ldots\equiv b_t\equiv 1$). Rozebereme
postupně oba případy.
\lemma{
Buď~$n$ Carmichaelovo a $n-1=2^t\cdot m$ jako v~algoritmu. Poté existuje alespoň $\vert\Z^*_n\vert/2$
čísel $a\in\Z_n^*$, pro něž $b_0:=a^m\not\equiv 1$.
}
\proof Podobnou úvahou založenou na~Lagrangeově větě, jako jsme použili u~Fermatova testu.
Množina $B = \{ b\in \Z^*_n \mid b^m\equiv 1 \}$ tvoří podgrupu $\Z_n^*$, takže
zbývá ukázat, že alespoň jeden prvek~$a\in \Z^*_n$ neleží v~$B$.
Buď~$p$ nějaký prvočíselný dělitel čísla~$n$.
Zvolme~$a\in\Z^*_p$, které není modulo~$p$ odmocnitelné. Už víme, že takových čísel existuje $(p-1)/2$
a že splňují následující vlastnosti:
$$\eqalign{
a^{p-1} &\equiv 1 \pmod{p}, \cr
a^{(p-1)/2} &\equiv -1 \pmod{p}. \cr
}$$
Uvažujme podgrupu $H\subseteq \Z_p$ generovanou prvkem~$a$ (tedy množinu $\{a^0,a^1,a^2,\ldots \}$).
Z~předchozích dvou rovností vyplývá, že řád této podgrupy dělí $p-1$, ale nedělí $(p-1)/2$,
takže řád musí být sudé číslo. Pro liché~$m$ tedy nemůže platit $a^m\equiv_p 1$, takže
ani $a^m\equiv_n\nobreak 1$.
\qed
Nyní se přesuneme ke~kroku~\itemref{rmmone}. Z~přechozího lemmatu víme, že pro některé volby čísla~$a$ v~algoritmu
je $b_0\not\equiv 1$. Můžeme proto zvolit~$i$ ($0\le i<t$) takové, že $b_{i+1}\equiv a^{2^{i+1}m} \equiv 1$
pro všechna možná~$a\in\Z_n$, ale $b_i\equiv a^{2^im} \not\equiv 1$ pro alespoň jedno takové~$a$. Jakmile dokážeme,
že $b_i\not\equiv\pm 1$ pro alespoň polovinu z~možných~$a$, máme vyhráno.
\lemma{
Pro $n$ Carmichaelovo, $n-1=2^t\cdot m$ a~$i$ definované podle předchozího odstavce
existuje alespoň $\vert\Z^*_n\vert/2$ čísel $a\in\Z^*_n$ takových, že $a^{2^im}\not\equiv_n\pm 1$.
}
\proof
Ještě jednou stejný trik s~podgroupou. Tentokrát zvolíme $G = \{ x\in\Z^*_n \mid a^{2^im} \equiv \pm1 \}$,
což je evidentně podgrupa~$\Z^*_n$, a~opět chceme dokázat, že alespoň jeden prvek leží mimo ni.
Z~volby~$i$ víme, že existuje~$c$, pro něž $c^{2^im}\not\equiv 1$. Pokud $c^{2^im}\not\equiv -1$, máme vyhráno,
neboť takové~$c$ neleží v~$G$. V~opačném případě zvolíme nějaký člen~$p^e$ z~prvočíselného
rozkladu čísla~$n$. Jelikož $c^{2^im}\equiv_n -1$, musí tato kongruence platit i modulo~$p^e$. Nyní
pomocí Čínské věty o~zbytcích najdeme~$d$ tak, aby splňovalo současně $d\equiv_{p^e} c$ a $d\equiv_{n/p^e} 1$
(zde jsme potřebovali, že $n$ není mocnina prvočísla).
Spočítáme-li $(2^im)$-tou mocninu čísla~$d$ modulo jak~$p^e$, tak $n/p^e$, dostaneme $d^{2^im} \equiv_{p^e} c^{2^im} \equiv_{p^e} -1$
a $d^{2^im} \equiv_{n/p^e} 1$. Proto $d^{2^im}$ nemůže být modulo~$n$ ani~1, ani~$-1$, takže $d\not\in G$.
\qed
\sectionstar{Ještě jeden test prvočíselnosti}
Nakonec předvedeme ještě jeden algoritmus pro pravděpodobnostní testování prvočísel,
jehož korektost je snadné dokázat. Daní za jednoduchost důkazu ovšem bude to, že
náš test může udělat chybu na~obě strany: jak prohlásit složené číslo za~prvočíslo,
tak prvočíslo za~složené. Bude fungovat následovně:
\algo{OdmocninovýTest}
\algin $n>1$ je testované číslo, $t\ge 1$ počet iterací
\:Pokud je $n$ netriviální mocninou nějakého přirozeného čísla, odpovíme \Comp.
\:Vygenerujeme náhodná $a_1,\ldots,a_t\in \Z_n\setminus\{0\}$.
\:Pokud pro nějaké~$i$ je $\gcd(a_i,n)\ne 1$, odpovíme \Comp.
\:Spočítáme $r_i \= a_i^{(n-1)/2} \bmod n$ pro všechna~$i$.
\:Pokud pro nějaké~$i$ je $r_i\not\equiv\pm1$, odpovíme \Comp.
\:Pokud pro všechna~$i$ je $r_i=1$, odpovíme \Comp.
\:Jinak odpovíme \Prime.
\endlist
Nejprve si všimneme, že algoritmus běží v~polynomiálním čase. Největší společné dělitele
a mocniny modulo~$n$ už polynomiálně umíme počítat, jediný problematický krok je ten první.
V~něm ale stačí zkoušet všechny možné exponenty (těch je $\O(\log n)=\O(b)$, jelikož základ je alespoň~$2$)
a pro každý exponent hledat pomocí půlení intervalu odmocninu (opět $\O(b)$ kroků).
Nyní nahlédněme, jak algoritmus probíhá pro prvočísla. První ani třetí krok prvočíslo neodmítnou,
pátý také ne, jediný problém může nastat v~šestém kroku. Již víme, že $r_i=1$ právě tehdy, má-li $a_i$ druhou odmocninu,
a~to nastane s~pravděpodobností $1/2$. Šestý krok tedy odpoví {\csc složené} jen tehdy,
když jsou všechna $a_i$ odmocnitelná, pravděpodobnost čehož je $1/2^t$.
Složené číslo naopak prohlásíme za~prvočíslo jen tehdy, pokud jsou všechna $a_i\in \Z_n^*$,
nalezneme alespoň jedno $r_i\equiv -1$ a všechna ostatní $r_j$ jsou buďto
1 nebo $-1$. K~odhadu pravděpodobnosti tohoto nám poslouží následující lemma:
\lemma{
Buď $n$ složené číslo, které není mocninou prvočísla. Nechť pro nějaké $a\in \Z_n^*$ je
$a^{(n-1)/2} \equiv_n -1.$ Pak množina $S_n = \{ x\in \Z_n^* \mid x^{(n-1)/2} \equiv_n \pm 1 \}$
obsahuje nejvýše $\vert \Z_n^*\vert/2$ prvků.
}
\proof
Podobně jako u~Fermatova testu:
Všimneme si, že $S_n$ je podgrupa $\Z_n^*$, takže zbývá dokázat, že je to podgrupa netriviální,
a použít Lagrangeovu větu. Najdeme číslo~$b$, které nebude ležet v~$S_n$.
Nechť $n$ má prvočíselný rozklad $p_1^{k_1}\cdot\ldots\cdot p_s^{k_s}$. Již víme, že $s\ge 2$. Označme
$q=p_1^{k_1}$ a $m=n/q$. Jelikož $q\divs n$ i $m\divs n$, musí být pro každý prvek
$x\in S_n$ jak $x^{(n-1)/2}\equiv_q \pm1$, tak $x^{(n-1)/2}\equiv_m \pm1$ a znaménka obou zbytků jsou stejná.
Kýžené číslo~$b$ zvolíme tak, aby pro něj platilo
$b\equiv_q a$ a současně $b\equiv_m 1$ (Čínská věta o~zbytcích nám jeho existenci zaručuje, jelikož $q\perp m$).
Snadno ověříme, že platí:
$$\eqalign{
b^{(n-1)/2} &\equiv_q a^{(n-1)/2} \equiv_q -1, \cr
b^{(n-1)/2} &\equiv_m 1. \cr
}$$
Takové $b$ ovšem neleží v~$S_n$, protože jak už jsme pozorovali, pro každý prvek z~$S_n$
jsou zbytky po~dělení $q$ a $m$ stejné a my jsme si~$b$ zvolili tak, aby byly různé.
\qed
Náš algoritmus tudíž selže jedině tehdy, když $a_2,\ldots,a_t$ padnou všechna do~$S_n$,
a to nastane s~pravděpodobností nejvýše $1/2^{t-1}$. Sečteno a podtrženo, dokázali
jsme následující větu:
\theorem{
Prvočíselný test z~tohoto oddílu má při $t$ iteracích pravděpodobnost chyby nejvýše $1/2^{t-1}$.
}
\endchapter \endchapter
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment