Różnica pomiędzy stronami "Największy wspólny dzielnik, element odwrotny modulo, funkcja Eulera" i "Protokół Diffiego-Hellmana. Szyfrowanie RSA. Podpis cyfrowy"

Z Henryk Dąbrowski
(Różnica między stronami)
Przejdź do nawigacji Przejdź do wyszukiwania
 
 
Linia 1: Linia 1:
<div style="text-align:right; font-size: 130%; font-style: italic; font-weight: bold;">22.12.2023</div>
+
<div style="text-align:right; font-size: 130%; font-style: italic; font-weight: bold;">22.11.2023</div>
  
 
__FORCETOC__
 
__FORCETOC__
Linia 5: Linia 5:
  
  
== Największy wspólny dzielnik ==
+
== Protokół Diffiego-Hellmana ==
  
<span id="H1" style="font-size: 110%; font-weight: bold;">Definicja H1</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q1</span><br/>
Niech będą dane dwie liczby całkowite <math>a</math> i <math>b</math> niebędące jednocześnie zerami. Największym wspólnym dzielnikiem<ref name="GCD1"/> liczb <math>a</math> i <math>b</math> będziemy nazywali liczbę całkowitą <math>D</math> taką, że
+
Metoda ta została opracowana przez W. Diffiego i&nbsp;M. Hellmana<ref name="DiffieHellman1"/><ref name="DiffieHellman2"/> w 1976 roku. Opisana niżej procedura nie jest metodą szyfrowania i&nbsp;z&nbsp;założenia jej cel jest zupełnie inny. Umożliwia ona osobom mogącym kontaktować się ze sobą jedynie przez niezabezpieczone przed podsłuchem środki łączności ustalenie (tajnej) liczby, zwanej kluczem. Dysponując wspólną liczbą-kluczem osoby te mogą kodować i&nbsp;odczytywać wiadomości wybraną metodą szyfrowania. Przedstawimy w&nbsp;punktach procedurę postępowania wraz z&nbsp;przykładowymi danymi.
  
:#&nbsp;&nbsp;<math> D \mid a \quad \text{i} \quad D \mid b</math>
+
::1. Agencja i&nbsp;Bolek wybierają (jawną) liczbę pierwszą <math>p = 541</math> i (jawną) liczbę <math>g = 2</math><ref name="generator1"/>
:#&nbsp;&nbsp;<math>\,\, d \mid a \quad \text{i} \quad \; d \mid b \qquad \Longrightarrow \qquad d \leqslant D</math>
 
  
gdzie <math>d</math> jest dowolną liczbą całkowitą.
+
::2. Agencja ustala (tajny, znany tylko sobie) wykładnik <math>a = 2718</math>
  
 +
::3. Bolek ustala (tajny, znany tylko sobie) wykładnik <math>b = 3141</math>
  
 +
::4. Agencja oblicza (jawną) liczbę <math>X = R_p (g^a) = 300</math> i&nbsp;wysyła ją do Bolka
  
<span id="H2" style="font-size: 110%; font-weight: bold;">Uwaga H2</span><br/>
+
::5. Bolek oblicza (jawną) liczbę <math>Y = R_p (g^b) = 191</math> i&nbsp;wysyła ją do Agencji
Tak zdefiniowaną liczbę <math>D</math> będziemy oznaczali przez <math>\gcd (a, b)</math>. Ponieważ <math>1 \mid a \;</math> i <math>\; 1 \mid b</math>, to z&nbsp;definicji wynika natychmiast, że <math>\gcd (a, b) \geqslant 1</math>.
 
  
 +
::6. Agencja oblicza (tajną) liczbę <math>k_A = R_p (Y^a) = 493</math>
  
 +
::7. Bolek oblicza (tajną) liczbę <math>k_B = R_p (X^b) = 493</math>
  
<span id="H3" style="font-size: 110%; font-weight: bold;">Zadanie H3</span><br/>
+
::8. Modulo <math>p</math> mamy
Pokazać, że
 
  
::<math>d \mid \gcd (a, b) \qquad \Longleftrightarrow \qquad d \mid a \quad \text{i} \quad d \mid b</math>
+
::::<math>k_A = R_p (Y^a) \equiv Y^a = [R_p (g^b)]^a \equiv (g^b)^a \equiv g^{a b} \equiv (g^a)^b \equiv [R_p (g^a)]^b = X^b \equiv R_p (X^b) = k_B \!\! \pmod{p}</math>
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
::9. Z&nbsp;definicji liczby <math>k_A, k_B \in [0, p - 1]</math>, zatem <math>0 \leqslant | k_A - k_B | \leqslant p - 1</math>. Ponieważ liczby <math>k_A, k_B</math> przystają do siebie modulo <math>p</math>, to muszą być sobie równe, czyli liczba <math>k = k_A = k_B</math> jest poszukiwanym kluczem.
  
<math>\Large{\Longrightarrow}</math>
 
  
Z założenia <math>d \mid \gcd (a, b)</math>. Z&nbsp;definicji największego wspólnego dzielnika <math>\gcd (a, b) \mid a</math>, zatem <math>d \mid a</math>. Analogicznie pokazujemy, że <math>d \mid b</math>.
 
  
<math>\Large{\Longleftarrow}</math>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q2</span><br/>
 +
Liczby <math>a</math> i <math>b</math> mogą być losowo wybranymi liczbami dodatnimi nie większymi od <math>p</math>. Istotnie, jeżeli <math>a = k \cdot (p - 1) + r</math>, to
  
Z założenia <math>a = r d</math>, <math>b = s d</math>. Z&nbsp;lematu Bézouta (zobacz C73) istnieją takie liczby całkowite <math>x, y</math>, że
+
::<math>g^a \equiv (g^{p - 1})^k \cdot g^r \equiv g^r \!\! \pmod{p}</math>
  
::<math>\gcd (a, b) = a x + b y = r d x + s d y = d (r x + s y)</math>
+
W naszym przykładzie możemy użyć liczb <math>a = 18</math> oraz <math>b = 441</math> otrzymując te same rezultaty. W&nbsp;praktyce ten problem nie występuje, bo gdy liczba pierwsza <math>p</math> ma co najmniej sto cyfr, to trudno wybrać jeszcze większy wykładnik.
 
 
Zatem <math>d \mid \gcd (a, b)</math>.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H4" style="font-size: 110%; font-weight: bold;">Twierdzenie H4</span><br/>
 
Jeżeli liczby całkowite <math>a, b</math> nie są jednocześnie równe zero i <math>\gcd (a, b) = a x + b y</math>, to <math>\gcd (x, y) = 1</math>.
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Z lematu Bézouta (zobacz C73) wiemy, że liczby całkowite <math>x, y</math> zawsze istnieją. Niech <math>\gcd (a, b) = d > 0</math>, zatem <math>a = d k</math> i <math>b = d m</math>, czyli
 
 
 
::<math>(d k) x + (d m) y = d</math>
 
 
 
Co oznacza, że <math>k x + m y = 1</math>, ale <math>\gcd (x, y)</math> jest dzielnikiem <math>k x + m y</math> (bo jest dzielnikiem <math>x</math> i <math>y</math>), zatem <math>\gcd (x, y) \mid 1</math>, czyli <math>\gcd (x, y) = 1</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H5" style="font-size: 110%; font-weight: bold;">Twierdzenie H5</span><br/>
 
Niech <math>a, b, k \in \mathbb{Z}</math>. Prawdziwy jest wzór
 
 
 
::<math>\gcd (a + k b, b) = \gcd (a, b)</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Niech <math>d_1 = \gcd (a + k b, b) \;</math> i <math>\; d_2 = \gcd (a, b)</math>.
 
 
 
Z definicji <math>d_1 \mid (a + k b) \;</math> i <math>\; d_1 \mid b</math>, zatem <math>a + k b = x d_1 \;</math> i <math>\; b = y d_1</math>, czyli <math>a + k x d_1 = x d_1</math>, skąd natychmiast wynika, że <math>d_1 \mid a</math>. Ponieważ <math>d_1 \mid b</math>, to <math>d_1 \mid d_2</math> (zobacz&nbsp;[[#H2|H2]]).
 
 
 
Z definicji <math>d_2 \mid a \;</math> i <math>\; d_2 \mid b</math>, zatem <math>d_2 \mid (a + k b) \;</math> i <math>\; d_2 \mid b</math>, czyli <math>d_2 \mid d_1</math>.
 
 
 
Ponieważ <math>d_1 \mid d_2 \;</math> i <math>\; d_2 \mid d_1</math>, to <math>| d_1 | = | d_2 |</math>. Co kończy dowód.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H6" style="font-size: 110%; font-weight: bold;">Twierdzenie H6</span><br/>
 
Niech <math>a, b, m \in \mathbb{Z}</math>. Prawdziwa jest następująca równoważność
 
 
 
::<math>\gcd (a, m) = 1 \quad  \text{i} \quad \gcd (b, m) = 1 \quad \qquad \Longleftrightarrow \quad \qquad \gcd (a b, m) = 1</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
 
 
<math>\Large{\Longrightarrow}</math>
 
 
 
Niech <math>\gcd (a b, m) = d</math>. Z&nbsp;definicji <math>d \mid a b</math> i <math>d \mid m</math>. Gdyby było <math>d > 1</math>, to istniałaby liczba pierwsza <math>p</math> taka, że <math>p \mid d</math> i&nbsp;mielibyśmy <math>p \mid a b</math> i <math>p \mid m</math>. Jeżeli <math>p \mid a b</math>, to <math>p \mid a</math> lub <math>p \mid b</math> (zobacz C74). W&nbsp;przypadku, gdy <math>p \mid a</math> dostajemy <math>\gcd (a, m) \geqslant p > 1</math>, wbrew założeniu, że <math>\gcd (a, m) = 1</math>. Analogicznie pokazujemy sprzeczność, gdy <math>p \mid b</math>.
 
 
 
<math>\Large{\Longleftarrow}</math>
 
 
 
Niech <math>\gcd (a, m) = d</math>. Z&nbsp;definicji <math>d \mid a</math> i <math>d \mid m</math>, zatem również <math>d \mid a b</math> i <math>d \mid m</math>. Mamy stąd
 
 
 
::<math>1 = \gcd (a b, m) \geqslant d \geqslant 1</math>
 
 
 
Czyli musi być <math>d = 1</math>. Analogicznie pokazujemy, że <math>\gcd (b, m) = 1</math>.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H7" style="font-size: 110%; font-weight: bold;">Twierdzenie H7</span><br/>
 
Dla <math>a, b, m \in \mathbb{Z}</math> jest
 
 
 
::<math>\gcd (a b, m) \mid \gcd (a, m) \cdot \gcd (b, m)</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Wprowadźmy oznaczenia
 
 
 
::<math>r = \gcd (a b, m)</math>
 
 
 
::<math>s = \gcd (a, m)</math>
 
 
 
::<math>t = \gcd (b, m)</math>
 
 
 
Z lematu Bézouta (zobacz C73) istnieją takie liczby <math>x, y, X, Y</math>, że
 
 
 
::<math>s = a x + m y</math>
 
 
 
::<math>t = b X + m Y</math>
 
 
 
Zatem
 
 
 
::<math>s t = (a x + m y) (b X + m Y) = a b x X + a m x Y + m b y X + m^2 y Y</math>
 
 
 
ale <math>r \mid a b</math> i <math>r \mid m</math>, skąd otrzymujemy, że <math>r \mid s t</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H8" style="font-size: 110%; font-weight: bold;">Twierdzenie H8</span><br/>
 
Jeżeli liczby <math>a, b</math> są względnie pierwsze, to
 
 
 
::<math>\gcd (a b, m) = \gcd (a, m) \cdot \gcd (b, m)</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Wprowadźmy oznaczenia
 
 
 
::<math>r = \gcd (a b, m)</math>
 
 
 
::<math>s = \gcd (a, m)</math>
 
 
 
::<math>t = \gcd (b, m)</math>
 
 
 
Z założenia <math>\gcd (a, b) = 1</math>. Ponieważ <math>s \mid a</math> oraz <math>t \mid b</math>, to <math>\gcd (s, t) = 1</math>, zatem (zobacz C75)
 
 
 
::<math>s \mid a \qquad \,\, \text{i} \qquad t \mid b \qquad \qquad \;\, \Longrightarrow \qquad \qquad s t \mid a b</math>
 
 
 
::<math>s \mid m \qquad \text{i} \qquad t \mid m \qquad \qquad \Longrightarrow \qquad \qquad s t \mid m</math>
 
 
 
Wynika stąd, że <math>s t \mid \gcd (a b, m)</math>, czyli <math>s t \mid r</math>. Z&nbsp;poprzedniego twierdzenia wiemy, że <math>r \mid s t</math>, zatem <math>|r| = |s t|</math>. Co kończy dowód.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H9" style="font-size: 110%; font-weight: bold;">Twierdzenie H9</span><br/>
 
Jeżeli liczby <math>b, m</math> są względnie pierwsze, to
 
 
 
::<math>\gcd (a b, m) = \gcd (a, m)</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Wprowadźmy oznaczenia
 
 
 
::<math>r = \gcd (a b, m)</math>
 
 
 
::<math>s = \gcd (a, m)</math>
 
 
 
Z lematu Bézouta istnieją takie liczby <math>x, y</math>, że
 
 
 
::<math>r = a b x + m y</math>
 
 
 
Ale <math>s \mid a \;</math> i <math>\; s \mid m</math>, zatem <math>s \mid r</math>.
 
 
 
Z założenia <math>\gcd (b, m) = 1</math>, zatem z twierdzenia [[#H7|H7]] wynika natychmiast, że <math>r \mid s</math>. Ponieważ <math>s \mid r \;</math> i <math>\; r \mid s</math>, to <math>| r | = | s |</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H10" style="font-size: 110%; font-weight: bold;">Twierdzenie H10</span><br/>
 
Jeżeli liczby <math>a, b</math> nie są jednocześnie równe zero i <math>m \neq 0</math>, to
 
 
 
::<math>\gcd (a m, b m) = | m | \cdot \gcd (a, b)</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Oznaczmy <math>d = \gcd (a, b) \;</math> i <math>\; D = \gcd (a m, b m)</math>. Pokażemy, że <math>d m \mid D</math>.
 
 
 
<div style="margin-top: 1.5em; margin-bottom: 1em;">
 
::<math>
 
\begin{array}{llll}
 
  d = \gcd (a, b) & \qquad \Longrightarrow \qquad & d \mid a \quad \text{i} \quad d \mid b & \text{(zobacz H3)} \\
 
  &  &  & \\
 
  & \qquad \Longrightarrow \qquad & d m \mid a m \quad \text{i} \quad d m \mid b m & \\
 
  &  &  & \\
 
  & \qquad \Longrightarrow \qquad & d m \mid \gcd (a m, b m) & \text{(zobacz H3)} \\
 
  &  &  & \\
 
  & \qquad \Longrightarrow \qquad & d m \mid D & \\
 
\end{array}
 
</math>
 
</div>
 
 
 
Pokażemy, że <math>D \mid d m</math>.
 
 
 
<div style="margin-top: 1.5em; margin-bottom: 1em;">
 
::<math>
 
\begin{array}{llll}
 
  d = \gcd (a, b) & \qquad \Longrightarrow \qquad & d = a x + b y & \text{(lemat Bézouta C73)} \\
 
  &  &  & \\
 
  & \qquad \Longrightarrow \qquad & d m = a m x + b m y & \\
 
  &  &  & \\
 
  & \qquad \Longrightarrow \qquad & D \mid d m & \\
 
\end{array}
 
</math>
 
</div>
 
 
 
Ostatnia implikacja korzysta z tego, że <math>D \mid a m \;</math> i <math>\; D \mid b m</math> (zobacz [[#H3|H3]]). Ponieważ <math>d m \mid D \;</math> i <math>\; D \mid d m</math>, to <math>| D | = | d m |</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H11" style="font-size: 110%; font-weight: bold;">Zadanie H11</span><br/>
 
Pokazać, że <math>a \mid b</math> wtedy i tylko wtedy, gdy <math>a \mid \gcd (a, b)</math>.
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
 
 
 
<math>\Large{\Longrightarrow}</math>
 
 
 
Zakładając, że <math>a \mid b</math>, dostajemy
 
 
 
<div style="margin-top: 1.5em; margin-bottom: 1em;">
 
::<math>
 
\begin{array}{llll}
 
  a \mid b & \qquad \Longrightarrow \qquad & b = k a & \\
 
  &  &  & \\
 
  & \qquad \Longrightarrow \qquad & \gcd (a, b) = \gcd (a, k a) = | a | \cdot \gcd (1, k) = | a | & \qquad \text{(zobacz H10)} \\
 
  &  &  & \\
 
  & \qquad \Longrightarrow \qquad & a \mid \gcd (a, b) & \\
 
\end{array}
 
</math>
 
</div>
 
 
 
<math>\Large{\Longleftarrow}</math>
 
 
 
Jeżeli <math>a \mid \gcd (a, b)</math>, to <math>a \mid b</math> (zobacz [[#H3|H3]]). Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H12" style="font-size: 110%; font-weight: bold;">Zadanie H12</span><br/>
 
Niech <math>\gcd (a, d) = 1</math>. Pokazać, że <math>d \nmid a b</math> wtedy i tylko wtedy, gdy <math>d \nmid b</math>.
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
 
Korzystając z rezultatu pokazanego w zadaniu [[#H11|H11]], dostajemy
 
 
 
<div style="margin-top: 1.5em; margin-bottom: 1em;">
 
::<math>
 
\begin{array}{llll}
 
  d \nmid a b & \qquad \Longleftrightarrow \qquad & d \nmid \gcd (d, a b) & \\
 
  &  &  & \\
 
  & \qquad \Longleftrightarrow \qquad & d \nmid \gcd (d, b) & \text{(zobacz H9)} \\
 
  &  &  & \\
 
  & \qquad \Longleftrightarrow \qquad & d \nmid b & \\
 
\end{array}
 
</math>
 
</div>
 
 
 
Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H13" style="font-size: 110%; font-weight: bold;">Twierdzenie H13</span><br/>
 
Jeżeli dodatnie liczby <math>a, b</math> są względnie pierwsze, to każdy dzielnik <math>d</math> iloczynu <math>a b</math> można przedstawić jednoznacznie w&nbsp;postaci <math>d = d_1 d_2</math>, gdzie <math>d_1 \mid a ,</math> <math>\; d_2 \mid b \;</math> <math>\text{i} \; \gcd (d_1, d_2) = 1</math>.
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Niech <math>d_1 = \gcd (d, a) \;</math> i <math>\; d_2 = \gcd (d, b)</math>. Z&nbsp;twierdzenia [[#H8|H8]] mamy
 
 
 
::<math>d_1 d_2 = \gcd (d, a) \cdot \gcd (d, b) = \gcd (d, a b) = d</math>
 
 
 
Bo z&nbsp;założenia <math>d \mid a b</math>. Z&nbsp;definicji największego wspólnego dzielnika i&nbsp;zadania [[#H3|H3]] dostajemy
 
 
 
::<math>\gcd (d_1, d_2) = e \qquad \Longrightarrow \qquad e \mid d_1 \quad \text{i} \quad e \mid d_2</math>
 
 
 
::::::::<math>\, \Longrightarrow \qquad e \mid \gcd (d, a) \quad \text{i} \quad e \mid \gcd (d, b)</math>
 
 
 
::::::::<math>\, \Longrightarrow \qquad e \mid a \quad \text{i} \quad e \mid b</math>
 
 
 
::::::::<math>\, \Longrightarrow \qquad e \mid \gcd (a, b)</math>
 
 
 
::::::::<math>\, \Longrightarrow \qquad \gcd (a, b) \geqslant e</math>
 
 
 
Gdyby było <math>\gcd (d_1, d_2) = e > 1</math>, to mielibyśmy <math>\gcd (a, b) \geqslant e > 1</math>. Wbrew założeniu, że <math>\gcd (a, b) = 1</math>. Co kończy dowód.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H14" style="font-size: 110%; font-weight: bold;">Twierdzenie H14</span><br/>
 
Jeżeli <math>a, m, n \in \mathbb{Z}_+</math>, to
 
 
 
::<math>\gcd (a^m - 1, a^n - 1) = a^{\gcd (m, n)} - 1</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Pokażemy najpierw, że jeżeli <math>d</math> jest dzielnikiem lewej strony dowodzonej równości, to jest również dzielnikiem prawej strony i&nbsp;odwrotnie.
 
 
 
<math>\Large{\Longrightarrow}</math>
 
 
 
Z założenia <math>d</math> jest dzielnikiem <math>\gcd (a^m - 1, a^n - 1)</math>, czyli <math>d \mid (a^m - 1) \;</math> i <math>\; d \mid (a^n - 1)</math>, co możemy zapisać w&nbsp;postaci
 
 
 
::<math>a^m \equiv 1 \!\! \pmod{d} \quad \qquad \text{oraz} \quad \qquad a^n \equiv 1 \!\! \pmod{d}</math>
 
 
 
Z lematu Bézouta (zobacz C73) wiemy, że istnieją takie liczby <math>x, y</math>, że <math>\gcd (m, n) = m x + n y</math>. Łatwo znajdujemy, że
 
 
 
::<math>a^{\gcd (m, n)} \equiv a^{m x + n y} \equiv (a^m)^x \cdot (a^n)^y \equiv 1^x \cdot 1^y \equiv 1 \!\! \pmod{d}</math>
 
 
 
Czyli <math>d \, \biggr\rvert \left( a^{\gcd (m, n)} - 1 \right)</math>.
 
 
 
<math>\Large{\Longleftarrow}</math>
 
 
 
Z założenia <math>d \, \biggr\rvert \left( a^{\gcd (m, n)} - 1 \right)</math>, czyli
 
 
 
::<math>a^{\gcd (m, n)} \equiv 1 \!\! \pmod{d}</math>
 
 
 
Zatem
 
 
 
::<math>a^m \equiv \left[ a^{\gcd (m, n)} \right]^{\tfrac{m}{\gcd (m, n)}} \equiv 1 \!\! \pmod{d}</math>
 
 
 
Podobnie otrzymujemy
 
 
 
::<math>a^n \equiv 1 \!\! \pmod{d}</math>
 
 
 
Zatem <math>d</math> dzieli <math>a^m - 1 \;</math> i <math>\; a^n - 1</math>, czyli
 
 
 
::<math>d \mid \gcd (a^m - 1, a^n - 1)</math>
 
 
 
 
 
W szczególności wynika stąd, że
 
 
 
:*&nbsp;&nbsp;&nbsp;<math>\gcd (a^m - 1, a^n - 1) \, \biggr\rvert \left( a^{\gcd (m, n)} - 1 \right)</math>
 
 
 
:*&nbsp;&nbsp;&nbsp;<math>\left( a^{\gcd (m, n)} - 1 \right) \, \biggr\rvert \, \gcd (a^m - 1, a^n - 1)</math>
 
 
 
Czyli <math>\left| \gcd (a^m - 1, a^n - 1) \right| = \left| a^{\gcd (m, n)} - 1 \right|</math>. Co kończy dowód.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H15" style="font-size: 110%; font-weight: bold;">Uwaga H15</span><br/>
 
W dowodzie twierdzenia [[#H14|H14]] pominęliśmy milczeniem fakt, że jedna z&nbsp;liczb <math>x, y</math> może być (i często jest) ujemna. Choć rezultat jest prawidłowy, to nie wiemy, co oznacza zapis
 
 
 
::<math>a^{- 1000} \equiv 1^{- 10} \equiv 1 \!\! \pmod{d}</math>
 
 
 
Omówimy ten problem w&nbsp;następnej sekcji. Zauważmy, wyprzedzając materiał, że z&nbsp;kongruencji
 
 
 
::<math>a^m \equiv 1 \!\! \pmod{d} \quad \qquad \text{oraz} \quad \qquad a^n \equiv 1 \!\! \pmod{d}</math>
 
 
 
wynika, że <math>\gcd (a, d) = 1</math> i&nbsp;liczba <math>a</math> ma element odwrotny modulo <math>d</math>.
 
  
  
  
 
+
<span style="font-size: 110%; font-weight: bold;">Przykład Q3</span><br/>
 
+
Zobaczmy, jak wpłynie na protokół zmiana liczby <math>g</math>. Niech <math>p = 541</math> i <math>g = 15</math>.
== Element odwrotny modulo <math>m</math> ==
 
 
 
<span id="H16" style="font-size: 110%; font-weight: bold;">Twierdzenie H16</span><br/>
 
Niech <math>m \in \mathbb{Z}_+</math>. Dla liczby <math>a \in \mathbb{Z}</math> istnieje taka liczba <math>x</math>, że
 
 
 
::<math>a x \equiv 1 \!\! \pmod{m}</math>
 
 
 
wtedy i&nbsp;tylko wtedy, gdy <math>\gcd (a, m) = 1</math>.
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
 
 
<math>\Large{\Longrightarrow}</math>
 
 
 
Z założenia istnieje taka liczba <math>x</math>, że
 
 
 
::<math>a x \equiv 1 \!\! \pmod{m}</math>
 
 
 
Zatem dla pewnego <math>k \in \mathbb{Z}</math> jest
 
 
 
::<math>a x = 1 + k m</math>
 
 
 
Czyli <math>a x - k m = 1</math>. Wynika stąd, że <math>\gcd (a, m)</math> dzieli <math>1</math>, co oznacza, że <math>\gcd (a, m) = 1</math>.
 
 
 
<math>\Large{\Longleftarrow}</math>
 
 
 
Z założenia <math>\gcd (a, m) = 1</math>. Z&nbsp;lematu Bézouta (zobacz C73) wynika, że istnieją takie liczby całkowite <math>x, y</math>, że
 
 
 
::<math>a x + m y = 1</math>
 
 
 
Zatem modulo <math>m</math> dostajemy
 
 
 
::<math>a x \equiv 1 \!\! \pmod{m}</math>
 
 
 
Co kończy dowód.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H17" style="font-size: 110%; font-weight: bold;">Definicja H17</span><br/>
 
Niech <math>m \in \mathbb{Z}_+</math>. Liczbę <math>x</math> taką, że
 
 
 
::<math>a \cdot x \equiv 1 \!\! \pmod{m}</math>
 
 
 
będziemy nazywali elementem odwrotnym liczby <math>a</math> modulo <math>m</math> i&nbsp;oznaczali jako <math>a^{- 1}</math>.
 
 
 
 
 
 
 
<span id="H18" style="font-size: 110%; font-weight: bold;">Uwaga H18</span><br/>
 
Oznaczenie elementu odwrotnego ma naturalne uzasadnienie. Zauważmy, że jeżeli <math>b \mid a</math> oraz <math>b</math> ma element odwrotny modulo <math>m</math>, to prawdziwa jest kongruencja
 
 
 
::<math>{\small\frac{a}{b}} \equiv a b^{- 1} \!\! \pmod{m}</math>
 
 
 
Istotnie
 
 
 
::<math>{\small\frac{a}{b}} = {\small\frac{a}{b}} \cdot 1 \equiv {\small\frac{a}{b}} \cdot b b^{- 1} \equiv a b^{- 1} \!\! \pmod{m}</math>
 
 
 
W PARI/GP odwrotność liczby <math>a</math> modulo <math>m</math> znajdujemy, wpisując <code>Mod(a, m)^(-1)</code>.
 
 
 
 
 
 
 
<span id="H19" style="font-size: 110%; font-weight: bold;">Twierdzenie H19</span><br/>
 
Niech <math>a, k \in \mathbb{Z}</math>, <math>m \in \mathbb{Z}_+</math>. Poniższa tabelka przedstawia elementy odwrotne do elementu <math>a</math> w&nbsp;przypadku niektórych modułów <math>m</math>. W&nbsp;szczególności, jeżeli moduł <math>m</math> jest liczbą nieparzystą, to <math>2^{- 1} \equiv {\small\frac{m + 1}{2}} \!\! \pmod{m}</math>.
 
  
 
::{| class="wikitable plainlinks"  style="font-size: 90%; text-align: center; margin-right: auto;"
 
::{| class="wikitable plainlinks"  style="font-size: 90%; text-align: center; margin-right: auto;"
 
|-
 
|-
! || postać <br/> modułu <math>\boldsymbol{m}</math> || odwrotność <br/> elementu <math>\boldsymbol{a}</math> || uwagi
+
! <math>\boldsymbol{a}</math> || <math>\boldsymbol{b}</math> || <math>\boldsymbol{R_p(g^a)}</math> || <math>\boldsymbol{R_p(g^b)}</math> || <math>\boldsymbol{R_p(g^{a b})}</math>
 
|-
 
|-
| <math>1.</math> || <math>m = 2</math> || <math>1</math> || rowspan = 3 | liczba <math>a</math> <br/> jest liczbą <br/> nieparzystą
+
| <math>2985</math> || <math>4683</math> || <math>411</math> || <math>129</math> || <math>1</math>
 
|-
 
|-
| <math>2.</math> || <math>m = 4</math> || <math>R_4(a)</math>
+
| <math>4270</math> || <math>8998</math> || <math>312</math> || <math>214</math> || <math>15</math>
 
|-
 
|-
| <math>3.</math> || <math>m = 8</math> || <math>R_8(a)</math>
+
| <math>9749</math> || <math>3921</math> || <math>225</math> || <math>411</math> || <math>129</math>
 
|-
 
|-
| <math>4.</math> || <math>m = a k - 1</math> || <math>{\small\frac{m + 1}{a}}</math> || <math></math>
+
| <math>8993</math> || <math>6479</math> || <math>225</math> || <math>505</math> || <math>214</math>
 
|-
 
|-
| <math>5.</math> || <math>m = a k + 1</math> || <math>- {\small\frac{m - 1}{a}}</math> || <math></math>
+
| <math>2146</math> || <math>8663</math> || <math>312</math> || <math>352</math> || <math>225</math>
 
|-
 
|-
| <math>6.</math> || <math>m = a k - 2</math> || <math>{\small\frac{m + 1}{2}} \cdot {\small\frac{m + 2}{a}}</math> || rowspan = 2 | liczby <math>a , m</math> <br/> są liczbami <br/> nieparzystymi
+
| <math>9941</math> || <math>6182</math> || <math>352</math> || <math>505</math> || <math>312</math>
 
|-
 
|-
| <math>7.</math> || <math>m = a k + 2</math> || <math>{\small\frac{m - 1}{2}} \cdot {\small\frac{m - 2}{2}}</math>  
+
| <math>8944</math> || <math>8120</math> || <math>214</math> || <math>225</math> || <math>352</math>
 +
|-
 +
| <math>2928</math> || <math>9314</math> || <math>129</math> || <math>505</math> || <math>411</math>
 +
|-
 +
| <math>7436</math> || <math>3172</math> || <math>225</math> || <math>312</math> || <math>505</math>
 
|}
 
|}
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
Czytelnik może wybierać dowolne inne wykładniki <math>a</math> i <math>b</math>, ale innych wartości <math>R_p (g^{a b})</math> już nie uzyska. Wybór liczby <math>g = 2</math> w&nbsp;zamieszczonym powyżej opisie metody, nie był przypadkowy. Liczba <math>2</math> jest generatorem modulo <math>541</math>. Generator modulo liczba pierwsza <math>p</math>, to taka liczba <math>g</math>, że zbiór potęg
 
 
'''Punkty 1. - 3.'''
 
 
 
Ponieważ dla liczb nieparzystych jest
 
 
 
::<math>a^2 \equiv 1 \!\! \pmod{2}</math>
 
 
 
::<math>a^2 \equiv 1 \!\! \pmod{4}</math>
 
 
 
::<math>a^2 \equiv 1 \!\! \pmod{8}</math>
 
 
 
to liczba nieparzysta <math>a</math> jest swoją odwrotnością modulo <math>2</math>, <math>4</math> i <math>8</math>. Ponieważ element odwrotny jest definiowany modulo, zatem możemy napisać
 
 
 
::<math>a^{- 1} \equiv R_2 (a) \!\! \pmod{2}</math>
 
 
 
::<math>a^{- 1} \equiv R_4 (a) \!\! \pmod{4}</math>
 
 
 
::<math>a^{- 1} \equiv R_8 (a) \!\! \pmod{8}</math>
 
 
 
W pierwszym przypadku wynik jest oczywisty, bo <math>R_2 (a) = 1</math>.
 
 
 
'''Punkt 4.'''
 
 
 
Zauważmy, że
 
 
 
::<math>\gcd (a, m) = \gcd (a, a k - 1) = \gcd (a, - 1) = 1</math>
 
 
 
oraz <math>a \mid (m + 1)</math>. Zatem
 
 
 
::<math>a \cdot a^{- 1} = a \cdot {\small\frac{m + 1}{a}} = m + 1 \equiv 1 \!\! \pmod{m}</math>
 
 
 
'''Punkt 5.'''
 
 
 
Zauważmy, że
 
 
 
::<math>\gcd (a, m) = \gcd (a, a k + 1) = \gcd (a, 1) = 1</math>
 
 
 
oraz <math>a \mid (m - 1)</math>. Zatem
 
 
 
::<math>a \cdot a^{- 1} = a \cdot \left[ - \left( {\small\frac{m - 1}{a}} \right) \right] = - m + 1 \equiv 1 \!\! \pmod{m}</math>
 
 
 
'''Punkt 6.'''
 
 
 
Ponieważ zakładamy, że <math>2 \mid (m + 1)</math>, to <math>m</math> musi być liczbą nieparzystą, czyli <math>a</math> też musi być liczbą nieparzystą. Zauważmy, że
 
 
 
::<math>\gcd (a, m) = \gcd (a, a k - 2) = \gcd (a, - 2) = 1</math>
 
 
 
oraz <math>a \mid (m + 2)</math>. Zatem
 
 
 
::<math>a \cdot a^{- 1} = a \cdot \left( {\small\frac{m + 1}{2}} \cdot {\small\frac{m + 2}{a}} \right) = {\small\frac{m + 1}{2}} \cdot (m + 2) \equiv {\small\frac{m + 1}{2}} \cdot 2 \equiv m + 1 \equiv 1 \!\! \pmod{m}</math>
 
 
 
Podobnie pokazujemy punkt 7. Co kończy dowód.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H20" style="font-size: 110%; font-weight: bold;">Twierdzenie H20</span><br/>
 
Niech <math>a, b \in \mathbb{Z}</math>, <math>m \in \mathbb{Z}_+</math> i&nbsp;liczba <math>a</math> ma element odwrotny modulo <math>m</math>. Jeżeli liczby <math>u_1, u_2, \ldots, u_r</math> są liczbami różnymi modulo <math>m</math>, to liczby
 
 
 
::1.&nbsp;&nbsp;&nbsp;<math>a u_1, a u_2, \ldots, a u_r</math>
 
 
 
::2.&nbsp;&nbsp;&nbsp;<math>a u_1 + b, a u_2 + b, \ldots, a u_r + b</math>
 
 
 
są liczbami różnymi modulo <math>m</math>. Jeżeli ponadto liczby <math>u_1, u_2, \ldots, u_r</math> są względnie pierwsze z <math>m</math>, to również liczby
 
 
 
::3.&nbsp;&nbsp;&nbsp;<math>u^{- 1}_1, u^{- 1}_2, \ldots, u^{- 1}_r</math>
 
 
 
są liczbami różnymi modulo <math>m</math>.
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
 
 
'''Punkt 1.'''
 
 
 
Przypuśćmy dla uzyskania sprzeczności, że istnieją takie różne wskaźniki <math>i, j</math>, że
 
 
 
::<math>a u_i \equiv a u_j \!\! \pmod{m}</math>
 
 
 
Z założenia liczba <math>a</math> ma element odwrotny modulo <math>m</math>, zatem mnożąc obie strony kongruencji przez <math>a^{- 1}</math>, otrzymujemy
 
 
 
::<math>u_i \equiv u_j \!\! \pmod{m}</math>
 
 
 
dla <math>i \neq j</math>, wbrew założeniu, że liczby <math>u_1, u_2, \ldots, u_r</math> są różne modulo <math>m</math>. Dowód punktu 2. jest analogiczny.
 
 
 
'''Punkt 3.'''
 
 
 
Przypuśćmy dla uzyskania sprzeczności, że istnieją takie różne wskaźniki <math>i, j</math>, że
 
 
 
::<math>u^{- 1}_i \equiv u^{- 1}_j \!\! \pmod{m}</math>
 
 
 
::<math>u_j u^{- 1}_i \equiv 1 \!\! \pmod{m}</math>
 
 
 
::<math>u_j u^{- 1}_i u_i \equiv u_i \!\! \pmod{m}</math>
 
 
 
::<math>u_j \equiv u_i \!\! \pmod{m}</math>
 
 
 
Ponownie otrzymujemy <math>u_i \equiv u_j \!\! \pmod{m}</math> dla <math>i \neq j</math>, wbrew założeniu, że liczby <math>u_1, u_2, \ldots, u_r</math> są różne modulo <math>m</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H21" style="font-size: 110%; font-weight: bold;">Zadanie H21</span><br/>
 
Niech <math>p</math> będzie liczbą pierwszą. Pokazać, że dla <math>k \in [0, p - 1]</math> prawdziwa jest kongruencja
 
 
 
::<math>\binom{p - 1}{k} \equiv (- 1)^k \pmod{p}</math>
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
 
Zauważmy, że modulo <math>p</math> mamy
 
  
::<math>\binom{p - 1}{k} = {\small\frac{(p - 1) !}{k! \cdot (p - 1 - k) !}}</math>
+
::<math>\{ g^1, g^2, g^3, \ldots, g^{p - 1} \}</math>
  
::::<math>\;\;\;\; = {\small\frac{(p - 1) (p - 2) \cdot \ldots \cdot (p - k)}{k!}}</math>
+
rozpatrywany modulo <math>p</math> jest identyczny ze zbiorem
  
::::<math>\;\;\;\; \equiv (p - 1) (p - 2) \cdot \ldots \cdot (p - k) \cdot (k!)^{- 1}</math>
+
::<math>\{ 1, 2, 3, \ldots, p - 1 \}</math>
  
::::<math>\;\;\;\; \equiv (- 1)^k \cdot k! \cdot (k!)^{- 1}</math>
+
Wybierając liczbę <math>g</math> tak, aby była generatorem modulo <math>p</math>, zapewniamy sobie, że w&nbsp;ostatniej kolumnie mogą pojawić się wszystkie liczby od <math>1</math> do <math>p - 1</math>. Taki wybór <math>g</math> zwiększa ilość możliwych wartości dla ustalanego klucza <math>k = R_p (g^{a b})</math>, a&nbsp;tym samym zwiększa bezpieczeństwo procedury. Zauważmy, że liczby <math>p</math> i <math>g</math> są jawne. Osoba próbująca poznać ustalony klucz <math>k</math> z&nbsp;pewnością ucieszy się, gdy sprawdzi, że niewłaściwy wybór liczby <math>g</math> zredukował ilość możliwych kluczy i&nbsp;ułatwił jej pracę.
  
::::<math>\;\;\;\; \equiv (- 1)^k \pmod{p}</math>
+
Każda liczba pierwsza ma generator modulo, ale znalezienie go dla dużych liczb pierwszych nie jest proste i&nbsp;może trwać bardzo długo. Pomocne w&nbsp;tej sytuacji jest następujące twierdzenie.
  
Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
  
  
 
+
<span style="font-size: 110%; font-weight: bold;">Twierdzenie Q4</span><br/>
<span id="H22" style="font-size: 110%; font-weight: bold;">Zadanie H22</span><br/>
+
Niech <math>p = 2 q + 1</math> będzie liczbą pierwszą, gdzie <math>q \geqslant 3</math> jest również liczbą pierwszą. Jeżeli <math>g</math> jest liczbą niekwadratową modulo <math>p</math> i <math>g \not\equiv - 1 \!\! \pmod{p}</math>, to <math>g</math> jest generatorem modulo <math>p</math>.
Niech <math>A</math> i <math>B</math> będą zbiorami skończonymi. Pokazać, że jeżeli <math>A \subseteq B \;\; \text{i} \;\; | A | = | B |</math>, to <math>\; A = B</math>.
 
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
 
<span style="border-bottom-style: double;">Pierwszy sposób</span><br/><br/>
 
Z definicji zbiory <math>A</math> i <math>B</math> są równe wtedy i&nbsp;tylko wtedy, gdy jednocześnie spełnione są warunki
 
 
 
:#&nbsp;&nbsp;<math>x \in A \qquad \Longrightarrow \qquad x \in B</math>
 
:#&nbsp;&nbsp;<math>x \in B \qquad \Longrightarrow \qquad x \in A</math>
 
 
 
Z założenia <math>A \subseteq B</math>, zatem warunek 1. jest spełniony. Przypuśćmy, że istnieje taki element <math>x</math>, że <math>x \in B</math>, ale <math>x \notin A</math>. Jeśli tak, to
 
 
 
::<math>| B | = | A | + 1</math>
 
 
 
Co jest sprzeczne z&nbsp;założeniem, że <math>| A | = | B |</math>.
 
 
 
'''Uwaga'''<br/>
 
Łatwo zauważyć, że wybierając z&nbsp;trzech warunków <math>A \subseteq B</math>, <math>B \subseteq A</math> i <math>| A | = | B |</math> dowolne dwa, zawsze otrzymamy z&nbsp;nich trzeci. Oczywiście nie dotyczy to zbiorów nieskończonych. Przykładowo liczby parzyste stanowią podzbiór liczb całkowitych, liczb parzystych jest tyle samo, co liczb całkowitych<ref name="cardinality1"/>, ale zbiór liczb całkowitych nie jest podzbiorem zbioru liczb parzystych.
 
 
 
 
 
<span style="border-bottom-style: double;">Drugi sposób</span><br/><br/>
 
Ponieważ zbiór <math>A</math> jest z&nbsp;założenia podzbiorem zbioru <math>B</math>, to zbiór <math>B</math> można przedstawić w&nbsp;postaci sumy zbioru <math>A</math> i&nbsp;pewnego zbioru <math>C</math> takiego, że żaden element zbioru <math>C</math> nie jest elementem zbioru <math>A</math>. Zatem
 
 
 
::<math>B = A \cup C \qquad \text{i} \qquad A \cap C = \varnothing</math>
 
 
 
Ponieważ zbiory <math>A</math> i <math>C</math> są rozłączne, to wiemy, że
 
 
 
::<math>| A \cup C | = | A | + | C |</math>
 
 
 
Czyli
 
 
 
::<math>| B | = | A \cup C | = | A | + | C |</math>
 
 
 
Skąd wynika, że <math>| C | = 0</math>, zatem zbiór <math>C</math> jest zbiorem pustym i&nbsp;otrzymujemy natychmiast <math>B = A</math>. Co należało pokazać.
 
 
 
'''Uwaga (przypadek zbiorów skończonych)'''<br/>
 
Najczęściej prawdziwe jest jedynie oszacowanie <math>| A \cup C | \leqslant | A | + | C |</math>, bo niektóre elementy mogą zostać policzone dwa razy. Elementy liczone dwukrotnie to te, które należą do iloczynu zbiorów <math>| A |</math> i <math>| C |</math>, zatem od sumy <math>| A | + | C |</math> musimy odjąć liczbę elementów iloczynu zbiorów <math>| A |</math> i <math>| C |</math>. Co daje ogólny wzór<ref name="sumazbiorow"/>
 
 
 
::<math>| A \cup C | = | A | + | C | - | A \cap C |</math><br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H23" style="font-size: 110%; font-weight: bold;">Definicja H23</span><br/>
 
Niech elementy każdego ze zbiorów <math>A = \{ a_1, a_2, \ldots, a_r \}</math> oraz <math>B = \{ b_1, b_2, \ldots, b_r \}</math> będą różne modulo <math>m</math>. Powiemy, że zbiory <math>A, B</math> są równe modulo <math>m</math>, jeżeli dla każdego <math>k = 1, \ldots, r</math> istnieje takie <math>j = 1, \ldots, r</math>, że prawdziwa jest kongruencja <math>a_k \equiv b_j \!\! \pmod{m}</math>.
 
 
 
 
 
 
 
<span id="H24" style="font-size: 110%; font-weight: bold;">Twierdzenie H24</span><br/>
 
Niech elementy każdego ze zbiorów <math>A = \{ a_1, a_2, \ldots, a_r \}</math> oraz <math>B = \{ b_1, b_2, \ldots, b_r \}</math> będą różne modulo <math>m</math>. Zbiory <math>A, B</math> są równe modulo <math>m</math> wtedy i&nbsp;tylko wtedy, gdy zbiory <math>A' = \{ R_m (a_1), R_m (a_2), \ldots, R_m (a_r) \}</math> i <math>B' = \{ R_m (b_1), R_m (b_2), \ldots, R_m (b_r) \}</math> są równe.
 
  
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 +
Dowód jest na tyle prosty i&nbsp;elegancki, że postanowiliśmy go zamieścić, choć wykracza on poza omówiony wcześniej materiał. Czytelnik może ten dowód pominąć. Dowód poprzedzamy kilkoma prostymi, ale istotnymi komentarzami.
  
<math>\Large{\Longrightarrow}</math>
+
'''Komentarz 1.'''
 
 
Ponieważ elementy każdego ze zbiorów <math>A, B</math> są różne modulo <math>m</math>, to elementy zbiorów <math>A'</math> i <math>B'</math> są wszystkie różne. Czyli <math>| A' | = | B' | = r</math>. Ponieważ warunek
 
 
 
::<math>a_k \equiv b_j \!\! \pmod{m}</math>
 
 
 
oznacza, że reszty z&nbsp;dzielenia liczb <math>a_k</math> i <math>b_j</math> przez <math>m</math> są równe, to z&nbsp;założenia dla każdego <math>k = 1, \ldots, r</math> istnieje takie <math>j = 1, \ldots, r</math>, że
 
 
 
::<math>R_m (a_k) = R_m (b_j)</math>
 
 
 
A to oznacza, że każdy element zbioru <math>A'</math> należy do zbioru <math>B'</math>, czyli <math>A' \subseteq B'</math>. Wynika stąd, że <math>A' = B'</math> (zobacz [[#H22|H22]]). Co należało pokazać.
 
  
<math>\Large{\Longleftarrow}</math>
+
'''Bez dowodu''' przyjmujemy fakt, że istnieje dokładnie <math>\varphi (p - 1)</math> różnych generatorów modulo <math>p</math>, gdzie <math>\varphi</math> jest funkcją Eulera<ref name="funkcjaphi1"/>. Funkcja Eulera <math>\varphi (n)</math> jest równa ilości liczb całkowitych dodatnich nie większych od <math>n</math> i&nbsp;względnie pierwszych z <math>n</math>.
  
Ponieważ zbiory <math>A', B'</math> są równe, to zbiór <math>A'</math> jest podzbiorem zbioru <math>B'</math>, czyli dla każdego elementu <math>R_m (a_k) \in A'</math> istnieje taki element <math>R_m (b_j) \in B'</math>, że
+
'''Komentarz 2.'''
  
::<math>R_m (a_k) = R_m (b_j)</math>
+
Udowodnimy, że jeżeli <math>g</math> jest generatorem modulo <math>p</math>, to <math>g</math> jest liczbą niekwadratową modulo <math>p</math>.
  
Ponieważ równość reszt oznacza równość modulo, zatem
+
Przypuśćmy, że <math>g</math> jest liczbą kwadratową modulo <math>p</math>, zatem (zobacz J30)
  
::<math>a_k \equiv b_j \!\! \pmod{m}</math>
+
::<math>g^{(p - 1) / 2} \equiv 1 \!\! \pmod{p}</math>
  
Wynika stąd, że dla każdego <math>k = 1, \ldots, r</math> istnieje takie <math>j = 1, \ldots, r</math>, że prawdziwa jest kongruencja
+
Wynika stąd, że zbiór
  
::<math>a_k \equiv b_j \!\! \pmod{m}</math>
+
::<math>S = \{ g^1, g^2, g^3, \ldots, g^{p - 1} \}</math>
  
czyli zbiory <math>A, B</math> są równe modulo <math>m</math>. Co kończy dowód.<br/>
+
::<math>\;\;\,\, = \left\{ g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1}, g^{\tfrac{p - 1}{2}}, g^{\tfrac{p - 1}{2} + 1}, g^{\tfrac{p - 1}{2} + 2}, g^{\tfrac{p - 1}{2} + 3}, \ldots, g^{p - 3}, g^{p - 2}, g^{p - 1} \right\}</math>
&#9633;
 
{{\Spoiler}}
 
  
 +
jest identyczny modulo <math>p</math> ze zbiorem
  
 +
::<math>S' = \left\{ g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1}, 1, g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1} \right\}</math>
  
<span id="H25" style="font-size: 110%; font-weight: bold;">Twierdzenie H25</span><br/>
+
::<math>\quad \, = \left\{ 1, g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1} \right\}</math>
Niech będą dane zbiory <math>A = \{ 1, 2, \ldots, p - 1 \}</math>, <math>B = \{ b_1, b_2, \ldots, b_{p - 1} \}</math>, gdzie <math>p</math> jest liczbą pierwszą. Jeżeli wszystkie elementy zbioru <math>B</math> są różne modulo <math>p</math> i&nbsp;żadna z&nbsp;liczb <math>b_k \in B</math> nie jest podzielna przez <math>p</math>, to zbiory <math>A, B, C = \{ b^{- 1}_1, b^{- 1}_2, \ldots, b^{- 1}_{p - 1} \}</math> są równe modulo <math>p</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
i nie może być identyczny modulo <math>p</math> ze zbiorem <math>T = \{ 1, 2, 3, \ldots, p - 1 \}</math>, bo <math>S'</math> zawiera co najwyżej połowę elementów zbioru <math>T</math>. Uzyskana sprzeczność dowodzi, że generator musi być liczbą niekwadratową modulo <math>p</math>.
Z definicji zbioru <math>A</math> wszystkie elementy tego zbioru są różne modulo <math>p</math>. Łatwo zauważamy, że
 
  
::<math>A = \{ 1, 2, \ldots, p - 1 \} = \{ R_p (1), R_p (2), \ldots, R_p (p - 1) \} = A'</math>
+
'''Komentarz 3.'''
  
Ponieważ wszystkie liczby <math>b_k \in B</math>, gdzie <math>k = 1, \ldots, p - 1</math> są różne modulo <math>p</math> i&nbsp;nie są podzielne przez <math>p</math>, to reszty <math>R_p (b_1), R_p (b_2), \ldots, R_p (b_{p - 1})</math> są wszystkie dodatnie i&nbsp;różne, a&nbsp;ponieważ jest ich <math>p - 1</math>, czyli dokładnie tyle, ile jest różnych i&nbsp;dodatnich reszt z&nbsp;dzielenia przez liczbę <math>p</math>, to zbiór tych reszt jest identyczny ze zbiorem dodatnich reszt z&nbsp;dzielenia przez <math>p</math>, czyli ze zbiorem <math>A</math>. Zatem mamy
+
Ponieważ funkcja Eulera <math>\varphi (n)</math> jest równa ilości liczb całkowitych dodatnich nie większych od <math>n</math> i&nbsp;względnie pierwszych z <math>n</math>, to dla liczby pierwszej <math>p</math> mamy <math>\varphi (p) = p - 1</math>, bo wszystkie liczby <math>1, 2, 3, \ldots, p - 1</math> są względnie pierwsze z&nbsp;liczbą pierwszą <math>p</math>.
  
::<math>A = A' = \{ R_p (b_1), R_p (b_2), \ldots, R_p (b_{p - 1}) \} = B'</math>
+
'''Komentarz 4.'''
  
Na mocy twierdzenia [[#H24|H24]] zbiory <math>A</math> i <math>B</math> są równe modulo <math>p</math>.
+
Ponieważ funkcja Eulera <math>\varphi (n)</math> jest równa ilości liczb całkowitych dodatnich nie większych od <math>n</math> i&nbsp;względnie pierwszych z
 +
<math>n</math>, to dla liczby pierwszej nieparzystej <math>p</math> mamy <math>\varphi (2 p) = p - 1</math>, bo
  
Z twierdzenia [[#H20|H20]] wiemy, że wszystkie liczby <math>b^{- 1}_k \in C</math> są różne modulo <math>p</math>. Zauważmy, że każda z&nbsp;tych liczb jest względnie pierwsza z <math>p</math>, zatem nie może być podzielna przez <math>p</math>. Wynika stąd, że reszty <math>R_p (b^{- 1}_1), R_p (b^{- 1}_2), \ldots, R_p (b^{- 1}_{p - 1})</math> są wszystkie dodatnie i&nbsp;różne, a&nbsp;ponieważ jest ich <math>p - 1</math>, czyli dokładnie tyle, ile jest różnych i&nbsp;dodatnich reszt z&nbsp;dzielenia przez liczbę <math>p</math>, to zbiór tych reszt jest identyczny ze zbiorem dodatnich reszt z&nbsp;dzielenia przez <math>p</math>, czyli ze zbiorem <math>A</math>. Zatem mamy
+
:* wszystkie liczby parzyste <math>2, 4, 6, \ldots, 2 p - 2</math> mają z&nbsp;liczbą <math>2 p</math> wspólny dzielnik równy <math>2</math> i&nbsp;nie mogą być względnie pierwsze z&nbsp;liczbą <math>2 p</math>  
 +
:* wszystkie liczby nieparzyste <math>1, 3, 5, \ldots, 2 p - 1</math> (których jest <math>p</math>) są względnie pierwsze z&nbsp;liczbą <math>2 p</math>, poza liczbą nieparzystą <math>p</math>, która nie jest względnie pierwsza z&nbsp;liczbą <math>2 p</math>
  
::<math>A = A' = \{ R_p (b^{- 1}_1), R_p (b^{- 1}_2), \ldots, R_p (b^{- 1}_{p - 1}) \} = C'</math>
 
  
Na mocy twierdzenia [[#H24|H24]] zbiory <math>A</math> i <math>C</math> są równe modulo <math>p</math>. Ponieważ <math>A' = B'</math> i <math>A' = C'</math>, to <math>B' = C'</math> i&nbsp;ponownie na mocy twierdzenia [[#H24|H24]] zbiory <math>B</math> i <math>C</math> są równe modulo <math>p</math>. Co należało pokazać.<br/>
+
Wracając do dowodu twierdzenia Q4, zauważmy, że liczba <math>- 1</math> jest liczbą niekwadratową modulo <math>p = 2 q + 1</math>. Istotnie, obliczając symbol Jacobiego, otrzymujemy
&#9633;
 
{{\Spoiler}}
 
  
 +
::<math>\left( {\small\frac{- 1}{p}} \right)_{\small{\!\! J}} = (- 1)^{\tfrac{p - 1}{2}} = (- 1)^q = - 1</math>
  
 +
Zauważmy też, że dla liczb pierwszych <math>p \geqslant 5</math> liczba <math>- 1</math> nie jest generatorem modulo <math>p</math>. Ponieważ <math>(- 1)^n = \pm 1</math>, to zbiór potęg
  
<span id="H26" style="font-size: 110%; font-weight: bold;">Zadanie H26</span><br/>
+
::<math>\{ g^1, g^2, g^3, \ldots, g^{p - 1} \}</math>
Niech <math>p</math> będzie liczbą pierwszą nieparzystą. Pokazać, że suma <math>\sum_{k = 1}^{p - 1} {\small\frac{(p - 1) !}{k}}</math> jest podzielna przez <math>p</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
składa się tylko z&nbsp;dwóch elementów <math>\{ - 1, 1 \}</math> i&nbsp;dla liczb pierwszych <math>p \geqslant 5</math> nie może być identyczny modulo <math>p</math> ze zbiorem <math>\{ 1, 2, 3, \ldots, p - 1 \}</math>.
Zauważmy najpierw, że modulo <math>p</math> następujące sumy są równe
 
  
::<math>\sum_{k = 1}^{p - 1} k \equiv \sum_{k = 1}^{p - 1} k^{- 1} \!\! \pmod{p}</math>
 
  
Istotnie, jeśli przyjmiemy w&nbsp;twierdzeniu [[#H25|H25]], że zbiór <math>B = \{ 1, 2, \ldots, p - 1 \}</math>, to zbiór <math>C</math> będzie zbiorem liczb, które są odwrotnościami liczb <math>1, 2, \ldots, p - 1</math> modulo <math>p</math> i&nbsp;możemy napisać
+
Ilość generatorów modulo <math>p</math> dla liczby pierwszej <math>p = 2 q + 1</math> jest równa
  
::<math>\sum_{x \in B} x \equiv \sum_{y \in C} y \!\! \pmod{p}</math>
+
::<math>\varphi (p - 1) = \varphi (2 q) = q - 1 = {\small\frac{p - 1}{2}} - 1</math>
  
bo
+
Ponieważ istnieje <math>{\small\frac{p - 1}{2}}</math> liczb niekwadratowych modulo <math>p</math> (zobacz J29), to liczb niekwadratowych modulo <math>p</math>, różnych od <math>- 1</math>, jest <math>{\small\frac{p - 1}{2}} - 1</math>, czyli tyle samo, co generatorów modulo <math>p</math>, a&nbsp;żadna z&nbsp;pozostałych liczb (kwadratowych modulo <math>p</math>) nie może być generatorem modulo <math>p</math>. Co kończy dowód.<br/>
 
 
:* gdy <math>x</math> przebiega kolejne wartości <math>b_k</math>, to <math>x</math> przyjmuje kolejno wartości <math>1, 2, \ldots, p - 1</math>
 
 
 
:* gdy <math>y</math> przebiega kolejne wartości <math>b_k^{- 1}</math>, to <math>y</math> (modulo <math>p</math>) przyjmuje wszystkie wartości ze zbioru <math>A = \{ 1, 2, \ldots, p - 1 \}</math>, czyli liczba <math>y</math> (modulo <math>p</math>) przyjmuje wszystkie wartości <math>1, 2, \ldots, p - 1</math>, ale w&nbsp;innej kolejności
 
 
 
Ponieważ kolejność sumowania tych samych składników nie wpływa na wartość sumy, to prawdziwa jest wyżej wypisana równość sum modulo <math>p</math>.
 
 
 
Zatem modulo <math>p</math> otrzymujemy
 
 
 
::<math>\sum_{k = 1}^{p - 1} {\small\frac{(p - 1) !}{k}} \equiv \sum_{k = 1}^{p - 1} (p - 1)! \cdot k^{- 1}</math>
 
 
 
:::::<math>\;\;\: \equiv (p - 1) ! \cdot \sum_{k = 1}^{p - 1} k^{- 1}</math>
 
 
 
:::::<math>\;\;\: \equiv (p - 1) ! \cdot \sum_{k = 1}^{p - 1} k</math>
 
 
 
:::::<math>\;\;\: \equiv (p - 1) ! \cdot {\small\frac{(p - 1) p}{2}}</math>
 
 
 
:::::<math>\;\;\: \equiv (p - 1) ! \cdot {\small\frac{p - 1}{2}} \cdot p</math>
 
 
 
:::::<math>\;\;\: \equiv 0 \!\! \pmod{p}</math>
 
 
 
Należy zauważyć, że dla liczby pierwszej nieparzystej <math>p</math> liczba <math>{\small\frac{p - 1}{2}}</math> jest liczbą całkowitą.<br/>
 
 
&#9633;
 
&#9633;
 
{{\Spoiler}}
 
{{\Spoiler}}
Linia 727: Linia 147:
  
  
 +
<span style="font-size: 110%; font-weight: bold;">Uwaga Q5</span><br/>
 +
Jeśli nie potrzebujemy wyliczyć najmniejszego generatora modulo <math>p = 2 q + 1</math>, to z&nbsp;twierdzenia Q4 można łatwo pokazać, że liczba <math>- 4</math> jest generatorem dla wszystkich liczb pierwszych <math>p = 2 q + 1 \geqslant 7</math>, a&nbsp;liczba <math>- 3</math> dla wszystkich liczb pierwszych <math>p = 2 q + 1 \geqslant 11</math>. Ponieważ <math>q = 2 k + 1</math>, to <math>p = 4 k + 3</math>.
  
 +
1. Pokażemy, że <math>- 4</math> jest liczbą niekwadratową modulo <math>p</math>. Liczba <math>k</math> może być postaci <math>2 j</math> lub <math>2 j + 1</math>, co daje odpowiednio <math>p = 8 j + 3</math> lub <math>p = 8 j + 7</math>. Zatem
  
== Funkcje multiplikatywne ==
+
::<math>\left( {\small\frac{- 4}{p}} \right)_{\small{\!\! J}} = \left( {\small\frac{- 1}{p}} \right)_{\small{\!\! J}} \cdot \left( {\small\frac{2}{p}} \right)_{\small{\!\! J}}^{\! 2} = (- 1) \cdot (\pm 1)^2 = - 1</math>
  
<span id="H27" style="font-size: 110%; font-weight: bold;">Definicja H27</span><br/>
+
Zobacz twierdzenie J41 p.6.
Powiemy, że funkcja <math>f(n)</math> określona w&nbsp;zbiorze liczb całkowitych dodatnich jest funkcją multiplikatywną, jeżeli <math>f(1) = 1</math> i&nbsp;dla względnie pierwszych liczb <math>a, b</math> spełniony jest warunek <math>f(a b) = f (a) f (b)</math>.
 
  
  
 +
2. Pokażemy, że <math>- 3</math> jest liczbą niekwadratową modulo <math>p</math>. Liczba <math>k</math> może być postaci <math>3 j, 3 j + 1, 3 j + 2</math>, co daje odpowiednio
  
<span id="H28" style="font-size: 110%; font-weight: bold;">Uwaga H28</span><br/>
+
::<math>k = 3 j \qquad \qquad \;\!\!\! p = 12 j + 3 \qquad \;\; q = 6 j + 1</math>
Założenie <math>f(1) = 1</math> możemy równoważnie zastąpić założeniem, że funkcja <math>f(n)</math> nie jest tożsamościowo równa zero.
 
Gdyby <math>f(n)</math> spełniała jedynie warunek <math>f(a b) = f (a) f (b)</math> dla względnie pierwszych liczb <math>a, b</math>, to mielibyśmy
 
  
::a)&nbsp;&nbsp;&nbsp;<math>f(n)</math> jest tożsamościowo równa zeru wtedy i&nbsp;tylko wtedy, gdy <math>f(1) = 0</math>
+
::<math>k = 3 j + 1 \qquad p = 12 j + 7 \qquad \;\; q = 6 j + 3</math>
  
::b)&nbsp;&nbsp;&nbsp;<math>f(n)</math> nie jest tożsamościowo równa zeru wtedy i&nbsp;tylko wtedy, gdy <math>f(1) = 1</math>
+
::<math>k = 3 j + 2 \qquad p = 12 j + 11 \qquad q = 6 j + 5</math>
  
Ponieważ <math>f(1) = f (1 \cdot 1) = f (1) f (1)</math>, zatem <math>f(1) = 0</math> lub <math>f (1) = 1</math>.
+
Pierwsza i&nbsp;druga postać liczby <math>k</math> nie jest możliwa, bo albo liczba <math>p</math>, albo liczba <math>q</math> byłyby liczbami złożonymi. Zatem
  
Jeżeli <math>f(1) = 0</math>, to dla dowolnego <math>n</math> mamy
+
::<math>\left( {\small\frac{- 3}{p}} \right)_{\small{\!\! J}} = \left( {\small\frac{- 1}{p}} \right)_{\small{\!\! J}} \cdot \left( {\small\frac{3}{p}} \right)_{\small{\!\! J}} = (- 1) \cdot (+ 1) = - 1</math>
  
::<math>f(n) = f (n \cdot 1) = f (n) f (1) = 0</math>
+
Zobacz twierdzenie J41 p.6 i&nbsp;zadanie J46.
  
Czyli <math>f(n)</math> jest funkcją tożsamościowo równą zero.
 
  
Jeżeli <math>f(n)</math> nie jest funkcją tożsamościowo równą zero, to istnieje taka liczba <math>a \in \mathbb{Z}_+</math>, że <math>f(a) \neq 0</math>. Zatem
 
  
::<math>f(a) = f (a \cdot 1) = f (a) f (1)</math>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q6</span><br/>
 +
O ile w&nbsp;ogólnym przypadku liczb pierwszych <math>p</math> liczących setki cyfr znalezienie najmniejszego generatora modulo <math>p</math> może trwać godzinami, to w&nbsp;przypadku liczb pierwszych <math>p = 2 q + 1</math>, gdzie <math>q</math> jest również liczbą pierwszą, wystarczy znaleźć liczbę niekwadratową modulo <math>p</math>, a&nbsp;obliczenie symbolu Jacobiego trwa bardzo krótko, zaś wyszukanie liczb pierwszych postaci <math>p = 2 q + 1</math> też jest zaskakująco szybkie. Dlatego napisaliśmy w&nbsp;PARI/GP prosty program, który wyszukuje w&nbsp;zadanym przedziale <math>[m, n]</math> liczbę pierwszą <math>p</math> taką, że <math>p = 2 q + 1</math> i&nbsp;zwraca <math>p</math> oraz najmniejszy generator modulo <math>p</math>.
  
I dzieląc obie strony przez <math>f(a) \neq 0</math>, dostajemy <math>f(1) = 1</math>.
+
Należy zwrócić uwagę, że funkcje <code>ispseudoprime()</code> i <code>randomprime()</code> sprawdzają pierwszość liczby na tym samym poziomie – wykonywany jest test Millera-Rabina. Dlatego używamy ich łącznie, co przyspiesza wyszukanie odpowiedniej liczby pierwszej. Następnie, już silniejszym testem, potwierdzamy pierwszość obydwu liczb: <math>p</math> i <math>(p - 1) / 2</math>.
  
 
+
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Pokaż kod|Hide=Ukryj kod}}
 
+
<span style="font-size: 90%; color:black;">SafePrime(m, n) =  
<span id="H29" style="font-size: 110%; font-weight: bold;">Przykład H29</span><br/>
+
\\ zwraca wektor [p, g], gdzie p i (p-1)/2 są liczbami pierwszymi, a g jest generatorem modulo p
Ponieważ <math>\gcd (1, c) = 1</math>, to <math>\gcd (n, c)</math> rozpatrywana jako funkcja <math>n</math>, gdzie <math>c</math> jest ustaloną liczbą całkowitą, jest funkcją multiplikatywną (zobacz [[#H8|H8]]).
+
{
 
+
'''local'''(g, p);
 
+
'''setrand'''('''getwalltime'''()); \\ ustawiamy ziarno (ang. seed) generatora liczb losowych
 
+
'''while'''( 1,
<span id="H30" style="font-size: 110%; font-weight: bold;">Twierdzenie H30</span><br/>
+
        p = 9;
Jeżeli funkcja <math>f(n)</math> jest funkcją multiplikatywną, to funkcja
+
        '''while'''( !'''ispseudoprime'''( (p - 1)/2 ), p = '''randomprime'''([m, n]) );
 
+
        '''if'''( '''isprime'''(p) && '''isprime'''( (p-1)/2 ), '''break'''() );
::<math>F(n) = \sum_{d \mid n} f (d)</math>
+
      );
 
+
g = 2;
gdzie sumowanie przebiega po wszystkich dzielnikach dodatnich liczby <math>n</math>, jest również funkcją multiplikatywną.
+
'''while'''( jacobi(g, p) > -1, g++ );
 
+
'''return'''([p, g]);
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
}</span>
Ponieważ
+
<br/>
 
 
::<math>F(1) = \sum_{d \mid 1} f (d) = f (1) = 1</math>
 
 
 
to funkcja <math>F(n)</math> spełnia pierwszy warunek definicji [[#H27|H27]].
 
 
 
Niech <math>a, b</math> będą względnie pierwszymi liczbami dodatnimi. Każdy dzielnik dodatni iloczynu <math>a b</math> można zapisać w&nbsp;postaci <math>d = d_1 d_2</math>, gdzie <math>d_1 \mid a</math>, <math>\; d_2 \mid b \,</math> oraz <math>\, \gcd (d_1, d_2) = 1</math> (zobacz [[#H13|H13]]). Niech zbiory
 
 
 
::<math>S_a = \{ d \in \mathbb{Z}_+ : d \mid a \}</math>
 
 
 
::<math>S_b = \{ d \in \mathbb{Z}_+ : d \mid b \}</math>
 
 
 
::<math>S_{a b} = \{ d \in \mathbb{Z}_+ : d \mid a b \}</math>
 
 
 
będą zbiorami dzielników dodatnich liczb <math>a, b</math> i <math>a b</math>. Dla przykładu
 
 
 
::<math>S_5 = \{ 1, 5 \}</math>
 
 
 
::<math>S_7 = \{ 1, 7 \}</math>
 
 
 
::<math>S_{35} = \{ 1, 5, 7, 35 \}</math>
 
 
 
Dla dowolnego <math>d_1 \in S_a \,</math> i <math>\, d_2 \in S_b</math> musi być <math>\gcd (d_1, d_2) = 1</math>, bo gdyby było <math>\gcd (d_1, d_2) = g > 1</math>, to
 
 
 
::<math>g \mid d_1 \quad \; \text{i} \quad \; d_1 \mid a \qquad \quad \Longrightarrow \qquad \quad g \mid a</math>
 
 
 
::<math>g \mid d_2 \quad \; \text{i} \quad \; d_2 \mid b \qquad \quad \Longrightarrow \qquad \quad g \mid b</math>
 
 
 
Zatem <math>g \mid \gcd (a, b)</math> i&nbsp;mielibyśmy <math>\gcd (a, b) \geqslant g > 1</math>, wbrew założeniu.
 
 
 
Przekształcając, otrzymujemy
 
 
 
::<math>F(a b) = \sum_{d \mid a b} f (d)</math>
 
 
 
:::<math>\;\;\;\;\: = \sum_{d \in S_{a b}} f (d)</math>
 
 
 
:::<math>\;\;\;\;\: = \underset{d_2 \in S_{b}}{\sum_{d_1 \in S_{a}}} f (d_1 d_2)</math>
 
 
 
:::<math>\;\;\;\;\: = \underset{d_2 \in S_{b}}{\sum_{d_1 \in S_{a}}} f (d_1) f (d_2)</math>
 
 
 
:::<math>\;\;\;\;\: = \sum_{d_1 \in S_{a}} f (d_1) \sum_{d_2 \in S_{b}} f (d_2)</math>
 
 
 
:::<math>\;\;\;\;\: = \sum_{d_1 \mid a} f (d_1) \sum_{d_2 \mid b} f (d_2)</math>
 
 
 
:::<math>\;\;\;\;\: = F (a) F (b)</math>
 
 
 
Co należało pokazać.<br/>
 
&#9633;
 
 
{{\Spoiler}}
 
{{\Spoiler}}
  
  
  
 +
<span style="font-size: 110%; font-weight: bold;">Uwaga Q7</span><br/>
 +
Jak dalece bezpieczna jest opisana wyżej metoda? Aby znaleźć klucz trzeba oprócz (jawnych) liczb <math>p, g, X, Y</math> znać jedną z&nbsp;liczb <math>a</math> lub <math>b</math>. Liczba <math>a</math> spełnia kongruencję
  
 +
::<math>g^a \equiv X \!\! \pmod{p}</math>
  
== Funkcja Eulera <math>\varphi (n)</math> ==
+
ale nie istnieje żadna metoda szybkiego znalezienia wykładnika <math>a</math>. Oczywiście zawsze pozostaje możliwość kolejnego wyliczania <math>g^n</math> modulo <math>p</math> z&nbsp;nadzieją trafienia na <math>X</math> lub <math>Y</math>. Dla naszych danych mielibyśmy modulo <math>541</math>
  
<span id="H31" style="font-size: 110%; font-weight: bold;">Definicja H31</span><br/>
+
::<math>2^1 \equiv 2, \quad 2^2 \equiv 4, \; \ldots , \; 2^{17} \equiv 150, \quad 2^{18} \equiv 300</math>
Funkcja Eulera <math>\varphi (n)</math><ref name="Euler1"/> jest równa ilości liczb całkowitych dodatnich nie większych od <math>n</math> i&nbsp;względnie pierwszych z <math>n</math>.
 
  
 +
czyli wystarczyło jedynie 18 prób! Ale dla dwustucyfrowej liczby pierwszej <math>p</math> i&nbsp;trochę lepiej wybranych liczb <math>a</math> i <math>b</math> ilość prób będzie liczbą rzędu <math>10^{50}</math>. Nawet dla najszybszych komputerów stanowi to barierę nie do pokonania.
  
  
<span id="H32" style="font-size: 110%; font-weight: bold;">Twierdzenie H32</span><br/>
 
Funkcja Eulera <math>\varphi (n)</math> jest multiplikatywna, czyli dla względnie pierwszych liczb <math>m, n</math> jest <math>\varphi (m n) = \varphi (m) \varphi (n)</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q8</span><br/>
Niech <math>m, n</math> będą dodatnimi liczbami całkowitymi takimi, że <math>\gcd (m, n) = 1</math>. Twierdzenie jest prawdziwe dla <math>n = 1</math>, zatem nie zmniejszając ogólności, możemy założyć, że <math>n > 1</math>. Wypiszmy w&nbsp;tabeli wszystkie liczby od <math>1</math> do <math>m n</math>.
+
Realne zagrożenie pojawia się jedynie wtedy, gdy Agencja i&nbsp;Bolek nie sprawdzą autentyczności liczb <math>X</math> i <math>Y</math>. Przykładowo Agencja może zapytać o <math>7</math>, <math>23</math>, <math>101</math> itd. cyfrę liczby <math>X</math>, którą otrzymał Bolek. Dlaczego jest to ważne? Jeżeli korespondencja (maile, listy) Agencji i&nbsp;Bolka jest kontrolowana przez Wywiad, to Wywiad może przechwycić liczby <math>X = R_p (g^a)</math> oraz <math>Y = R_p (g^b)</math> i&nbsp;wysłać im swoją liczbę <math>Z = R_p (g^c)</math>. Od tej pory korespondencja Agencji będzie przechwytywana, odszyfrowywana przez Wywiad kluczem <math>k_1 = R_p (g^{a c})</math>, czytana, ewentualnie zmieniana, ponownie szyfrowana kluczem <math>k_2 = R_p (g^{b c})</math> i&nbsp;wysyłana do Bolka.
 
 
::{| class="wikitable plainlinks"  style="font-size: 90%; text-align: right; margin-right: auto;"
 
|-
 
| <math>1</math> || <math>2</math> || <math></math> || <math>k</math> || <math>…</math> || <math>m</math>
 
|-
 
| <math>m + 1</math> || <math>m + 2</math> || <math>…</math> || <math>m + k</math> || <math>…</math> || <math>2 m</math>
 
|-
 
| <math>2 m + 1</math> || <math>2 m + 2</math> || <math>…</math> || <math>2 m + k</math> || <math>…</math> || <math>3 m</math>
 
|-
 
| <math>…</math> || <math>…</math> || <math>…</math> || <math>…</math> || <math></math> || <math></math>
 
|-
 
| <math>(n - 1) m + 1</math> || <math>(n - 1) m + 2</math> || <math>…</math> || <math>(n - 1) m + k</math> || <math>…</math> || <math>n m</math>
 
|}
 
 
 
'''1.''' Natychmiast widzimy, że w&nbsp;pierwszym wierszu mamy <math>\varphi (m)</math> liczb względnie pierwszych z <math>m</math>. Tak samo jest w&nbsp;każdym kolejnym wierszu, bo (zobacz [[#H5|H5]])
 
 
 
::<math>\gcd (r m + k, m) = \gcd (k, m)</math>
 
 
 
Zatem mamy dokładnie <math>\varphi (m)</math> kolumn liczb względnie pierwszych z <math>m</math>.
 
 
 
 
 
'''2.''' Załóżmy, że liczba <math>k</math> jest jedną z&nbsp;liczb względnie pierwszych z <math>m</math>, czyli <math>\gcd (k, m) = 1</math>. Przy tym założeniu <math>k</math>-ta kolumna (pokazana w&nbsp;tabeli) jest kolumną liczb względnie pierwszych z <math>m</math>.
 
 
 
 
 
'''3.''' Zauważmy, że reszty z&nbsp;dzielenia liczb wypisanych w <math>k</math>-tej kolumnie przez <math>n</math> są wszystkie różne. Gdyby tak nie było, to dla pewnych <math>i, j</math>, gdzie <math>0 \leqslant i, j \leqslant n - 1</math>, różnica liczb <math>i m + k</math> oraz <math>j m + k</math> byłaby podzielna przez <math>n</math>. Mielibyśmy
 
  
::<math>n \mid ((i m + k) - (j m + k))</math>
+
Analogicznie będzie kontrolowana korespondencja Bolka wysyłana do Agencji.
  
Skąd wynika natychmiast
 
  
::<math>n \mid (i - j) m</math>
 
  
Ponieważ założyliśmy, że <math>\gcd (n, m) = 1</math>, to musi być <math>n \mid (i - j)</math> (zobacz C74), ale
 
  
::<math>0 \leqslant | i - j | \leqslant n - 1</math>
 
  
Czyli <math>n</math> może dzielić <math>i - j</math> tylko w&nbsp;przypadku, gdy <math>i = j</math>. Wbrew naszemu przypuszczeniu, że istnieją różne liczby dające takie same reszty przy dzieleniu przez <math>n</math>.
+
== Szyfrowanie RSA ==
  
 +
<span style="font-size: 110%; font-weight: bold;">Uwaga Q9</span><br/>
 +
Rozpoczniemy od dowodu kilku prostych twierdzeń. Łatwość ich sformułowania i&nbsp;dowodu zaskakuje, jeśli weźmiemy pod uwagę fakt, że stanowią one podstawę niezwykle ważnej metody szyfrowania.
  
'''4.''' Ponieważ w <math>k</math>-tej kolumnie znajduje się dokładnie <math>n</math> liczb i&nbsp;reszty z&nbsp;dzielenia tych liczb przez <math>n</math> są wszystkie różne, to reszty te tworzą zbiór <math>S = \{ 0, 1, \ldots, n - 1 \}</math>. Wynika stąd, że liczby wypisane w <math>k</math>-tej kolumnie mogą być zapisane w&nbsp;postaci
 
  
::<math>a_r = b_r \cdot n + r</math>
 
  
gdzie <math>r = 0, 1, \ldots, n - 1</math> i <math>b_r \in \mathbb{Z}</math>.
+
<span style="font-size: 110%; font-weight: bold;">Twierdzenie Q10</span><br/>
 +
Jeżeli <math>p</math> jest liczbą pierwszą, to dla dowolnego <math>a \in \mathbb{Z}</math> i&nbsp;każdego <math>k \geqslant 0</math> jest
  
Zauważmy, że następujące ilości liczb są sobie równe
+
::<math>a^{(p - 1) k + 1} \equiv a \!\! \pmod{p}</math>
 
 
:*&nbsp;&nbsp;&nbsp;ilość liczb w <math>k</math>-tej kolumnie względnie pierwszych z <math>n</math>
 
 
 
:*&nbsp;&nbsp;&nbsp;ilość liczb <math>r</math> względnie pierwszych z <math>n</math>, gdzie <math>r = 0, \ldots, n - 1</math>, bo <math>\gcd (b_r \cdot n + r, n) = \gcd (r, n)</math>
 
 
 
:*&nbsp;&nbsp;&nbsp;ilość liczb <math>r</math> względnie pierwszych z <math>n</math>, gdzie <math>r = 1, \ldots, n</math>, bo <math>\gcd (n, n) = \gcd (0, n) = | n | > 1</math>
 
 
 
Ostatnia ilość liczb jest równa <math>\varphi (n)</math>, co wynika wprost z&nbsp;definicji funkcji <math>\varphi (n)</math>.
 
 
 
 
 
'''5.''' Zbierając: mamy w&nbsp;wypisanej tabeli dokładnie <math>\varphi (m) \varphi (n)</math> liczb <math>u \in [1, m n]</math>, dla których jednocześnie jest
 
 
 
::<math>\gcd (u, m) = 1 \quad  \text{i} \quad \gcd (u, n) = 1</math>
 
 
 
Z twierdzenia [[#H6|H6]] wynika, że w&nbsp;tabeli jest dokładnie <math>\varphi (m) \varphi (n)</math> liczb <math>u \in [1, m n]</math>, dla których jest
 
 
 
::<math>\gcd (u, m n) = 1</math>
 
 
 
Zatem <math>\varphi (m n) = \varphi (m) \varphi (n)</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
<span id="H33" style="font-size: 110%; font-weight: bold;">Twierdzenie H33</span><br/>
 
Dla dowolnej liczby całkowitej dodatniej <math>n</math> jest
 
 
 
::<math>\varphi (n) = n \cdot \prod_{p|n} \left( 1 - {\small\frac{1}{p}} \right)</math>
 
 
 
gdzie iloczyn obliczamy po wszystkich liczbach pierwszych <math>p</math>, będących dzielnikami liczby <math>n</math>.
 
  
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
Ponieważ wszystkie liczby naturalne mniejsze od liczby pierwszej <math>p</math> są jednocześnie pierwsze względem <math>p</math>, to <math>\varphi (p) = p - 1</math>.
+
Jeżeli <math>p \mid a</math>, to dowodzona kongruencja jest prawdziwa. Jeżeli <math>p \nmid a</math>, to modulo <math>p</math> mamy
 
 
Równie łatwo znajdujemy wartość funkcji <math>\varphi (n)</math> w&nbsp;przypadku gdy <math>n</math> jest potęgą liczby pierwszej <math>n = p^k</math>. Wystarczy zauważyć, że w&nbsp;ciągu kolejnych liczb
 
 
 
::<math>1, 2, 3, 4, \ldots, p^k - 1, p^k</math>
 
 
 
jedynymi liczbami, które nie są pierwsze względem <math>p^k</math>, są te, które dzielą się przez <math>p</math> i&nbsp;jest ich <math>p^{k - 1}</math>, co widać natychmiast po ich bezpośrednim wypisaniu
 
 
 
::<math>1 \cdot p, 2 \cdot p, 3 \cdot p, \ldots, (p^{k - 1} - 1) \cdot p, p^{k - 1} \cdot p</math>
 
 
 
Zatem
 
 
 
::<math>\varphi (p^k) = p^k - p^{k - 1} = p^k \left( 1 - {\small\frac{1}{p}} \right)</math>
 
 
 
Ponieważ <math>\varphi (n)</math> jest funkcją multiplikatywną, to dla <math>n = p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s</math> otrzymujemy
 
 
 
::<math>\varphi (n) = \prod^s_{k = 1} \varphi (p^{\alpha_k}_k)</math>
 
 
 
:::<math>\;\;\; = \prod^s_{k = 1} p^{\alpha_k}_k \left( 1 - {\small\frac{1}{p_k}} \right)</math>
 
 
 
:::<math>\;\;\; = \left[ \prod^s_{k = 1} p^{\alpha_k}_k \right] \cdot \left[ \prod^s_{k = 1} \left( 1 - {\small\frac{1}{p_k}} \right) \right]</math>
 
 
 
:::<math>\;\;\; = n \cdot \prod^s_{k = 1} \left( 1 - {\small\frac{1}{p_k}} \right)</math>
 
  
:::<math>\;\;\; = n \cdot \prod_{p|n} \left( 1 - {\small\frac{1}{p}} \right)</math>
+
::<math>a^{(p - 1) k + 1} = a \cdot (a^{p - 1})^k \equiv a \!\! \pmod{p}</math>
  
Co należało pokazać.<br/>
+
gdzie skorzystaliśmy z&nbsp;twierdzenia Fermata (J21).<br/>
 
&#9633;
 
&#9633;
 
{{\Spoiler}}
 
{{\Spoiler}}
Linia 949: Linia 243:
  
  
<span id="H34" style="font-size: 110%; font-weight: bold;">Twierdzenie H34</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Twierdzenie Q11</span><br/>
Niech <math>n \in \mathbb{Z}_+</math>. Jeżeli <math>q</math> jest liczbą pierwszą, to
+
Jeżeli <math>p</math> i <math>q</math> są różnymi liczbami pierwszymi, to dla dowolnego <math>a \in \mathbb{Z}</math> i&nbsp;każdego <math>k \geqslant 0</math> jest
  
::<math>\varphi (q n) = \left\{ \begin{array}{rl}
+
::<math>a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{p q}</math>
  (q - 1) \varphi (n) & \quad \text{gdy} \quad q \nmid n \\
 
  q \varphi (n) & \quad \text{gdy} \quad q \mid n \\
 
\end{array} \right.</math>
 
  
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
Jeżeli <math>q \nmid m</math>, to <math>\gcd (q, m) = 1</math>, zatem <math>\varphi (q m) = \varphi (q) \varphi (m) = (q - 1) \varphi (m)</math>. Jeżeli <math>q \mid m</math>, to liczby <math>m</math> oraz <math>q m</math> mają taki sam zbiór dzielników pierwszych, zatem
+
Z twierdzenia Q10 wiemy, że dla dowolnych liczb <math>i, j \geqslant 0</math> prawdziwe są kongruencje
 
 
::<math>\varphi (q m) = q m \prod_{p \mid q m} \left( 1 - {\small\frac{1}{p}} \right) = q \cdot \left[ m \prod_{p \mid m} \left( 1 - {\small\frac{1}{p}} \right) \right] = q \varphi (m)</math>
 
 
 
Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
  
 +
::<math>a^{(p - 1) i + 1} \equiv a \!\! \pmod{p}</math>
  
 +
::<math>a^{(q - 1) j + 1} \equiv a \!\! \pmod{q}</math>
  
<span id="H35" style="font-size: 110%; font-weight: bold;">Zadanie H35</span><br/>
+
Dla dowolnego, ale ustalonego <math>k \geqslant 0</math> wybierzmy liczby <math>i, j</math> następująco: <math>i = k (q - 1)</math> oraz <math>j = k (p - 1)</math>. Otrzymujemy
Niech <math>q \in \mathbb{P}</math> i <math>a, b, m, n \in \mathbb{Z}_+</math>. Pokazać, że
 
  
:*&nbsp;&nbsp;&nbsp;<math>\varphi (q^{a + b}) = q^a \varphi (q^b)</math>
+
::<math>a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{p}</math>
  
:*&nbsp;&nbsp;&nbsp;<math>\varphi (n^m) = n^{m - 1} \varphi (n)</math>
+
::<math>a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{q}</math>
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
Z twierdzenia J1 wiemy, że powyższy układ kongruencji może być zapisany w&nbsp;sposób równoważny
'''Punkt 1.'''
 
  
::<math>\varphi (q^{a + b}) = (q - 1) q^{a + b - 1} = q^a \cdot (q - 1) q^{b - 1} = q^a \varphi (q^b)</math>
+
::<math>a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{p q}</math>
 
 
'''Punkt 2.'''
 
 
 
Niech <math>n = p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s</math>
 
 
 
::<math>\varphi (n^m) = \varphi (p^{m \alpha_1}_1 \cdot \ldots \cdot p^{m \alpha_s}_s)</math>
 
 
 
::::<math>\, = \varphi (p^{m \alpha_1}_1) \cdot \ldots \cdot \varphi (p^{m \alpha_s}_s)</math>
 
 
 
::::<math>\, = \varphi (p^{(m - 1) \alpha_1 + \alpha_1}_1) \cdot \ldots \cdot \varphi (p^{(m - 1) \alpha_s + \alpha_s}_s)</math>
 
 
 
::::<math>\, = p^{(m - 1) \alpha_1}_1 \varphi (p^{\alpha_1}_1) \cdot \ldots \cdot p^{(m - 1) \alpha_s}_s \varphi (p^{\alpha_s}_s)</math>
 
 
 
::::<math>\, = p^{(m - 1) \alpha_1}_1 \cdot \ldots \cdot p^{(m - 1) \alpha_s}_s \cdot \varphi (p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s)</math>
 
 
 
::::<math>\, = n^{m - 1} \varphi (n)</math>
 
  
 
Co należało pokazać.<br/>
 
Co należało pokazać.<br/>
Linia 1002: Linia 271:
  
  
<span id="H36" style="font-size: 110%; font-weight: bold;">Twierdzenie H36</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q12 (metoda szyfrowania RSA)</span><br/>
Niech <math>m, n \in \mathbb{Z}_+</math>. Jeżeli <math>m \mid n</math>, to <math>\varphi (m) \mid \varphi (n)</math>.
+
RSA<ref name="RSA1"/><ref name="RSA2"/> to akronim od nazwisk twórców tej metody: Rona Rivesta, Adiego Shamira i&nbsp;Leonarda Adlemana. Rozpoczniemy od wypisania używanych oznaczeń, co znakomicie ułatwi zrozumienie opisu metody.
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
:# <math>p, q</math> – dwie duże liczby pierwsze o&nbsp;zbliżonych wartościach
Niech <math>n = p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s</math>. Ponieważ założyliśmy, że <math>m \mid n</math>, to <math>m</math> musi być postaci <math>m = p^{\beta_1}_1 \cdot \ldots \cdot p^{\beta_s}_s</math>, gdzie <math>0 \leqslant \beta_i \leqslant \alpha_i</math>, dla <math>i = 1, \ldots, s</math>. Łatwo zauważamy, że
+
:#* często przyjmuje się, że <math>p < q < 2 p</math>; można też przyjąć, że <math>q \sim 2 p</math>
 
+
:# <math>m = p q</math>
:*&nbsp;&nbsp;&nbsp;jeżeli <math>\beta_i = 0</math>, to <math>\varphi (p^{\beta_i}_i) = 1</math> i&nbsp;dzieli <math>\varphi (p^{\alpha_i}_i)</math>
+
:# <math>\Phi = (p - 1) (q - 1)</math>
 
+
:#* oznaczenie nawiązuje do funkcji Eulera <math>\varphi</math>, bo <math>\varphi (m) = \varphi (p q) = (p - 1) (q - 1)</math>
:*&nbsp;&nbsp;&nbsp;jeżeli <math>1 \leqslant \beta_i \leqslant \alpha_i</math>, to <math>(p_i - 1) p_i^{\beta_i - 1} \mid (p_i - 1) p_i^{\alpha_i - 1}</math>, zatem <math>\varphi (p^{\beta_i}_i) \mid \varphi (p^{\alpha_i}_i)</math>
+
:# <math>e</math> (ang. ''encryption'') – wykładnik służący do szyfrowania (publiczny)
 +
:# <math>d</math> (ang. ''decryption'') – wykładnik służący do odszyfrowania (tajny)
 +
:# <math>B</math> (ang. ''block of digits'') – wiadomość w&nbsp;postaci liczby (ciągu cyfr) przeznaczona do zaszyfrowania
 +
:# <math>C</math> (ang. ''coded block of digits'') – zaszyfrowana wiadomość, czyli liczba powstała w&nbsp;wyniku szyfrowania liczby <math>B</math>
  
Skąd natychmiast wynika, że <math>\varphi (p^{\beta_1}_1) \cdot \ldots \cdot \varphi (p^{\beta_s}_s)</math> dzieli <math>\varphi (p^{\alpha_1}_1) \cdot \ldots \cdot \varphi (p^{\alpha_s}_s)</math>, czyli <math>\varphi (m) \mid \varphi (n)</math>.
 
  
Zauważmy, że twierdzenie odwrotne nie jest prawdziwe, bo <math>\varphi (7) \mid \varphi (19)</math>, ale <math>7 \nmid 19</math>.<br/>
+
'''Opis metody'''
&#9633;
+
:# Wybierzmy liczbę <math>e</math> tak, aby spełniała warunki <math>\gcd (e, \Phi) = 1</math> i <math>2 < e < \Phi</math>
{{\Spoiler}}
+
:#* zaleca się, aby <math>e \geqslant 65537</math>
 +
:# Z&nbsp;lematu Bézouta (zobacz C73) istnieją takie liczby całkowite <math>d</math> i <math>k</math>, że <math>d e + k \Phi = 1</math>. Liczbę <math>d</math> wyliczamy ze wzoru <math>d = d_0 + \Phi t</math>, gdzie <math>d_0</math> (oraz <math>k_0</math>) otrzymujemy, wykorzystując w&nbsp;PARI/GP funkcję <code>gcdext(e, Φ)</code> (zobacz C78)
 +
:#* <math>d</math> wybieramy tak, aby była liczbą dodatnią, wtedy <math>k</math> musi być liczbą ujemną
 +
:#* <math>d</math> nie może być zbyt małą liczbą; pokazano<ref name="BonehDurfee1"/>, że powinno być <math>d > m^{0.292}</math>
 +
:# Metoda szyfrowania RSA wymaga trzech liczb: <math>m</math>, <math>e</math>, <math>d</math>. Liczba <math>d</math> jest tajna. Podobnie tajne są liczby <math>p</math>, <math>q</math>, <math>\Phi</math>, ale te liczby można po prostu skasować po wyliczeniu <math>d</math>
 +
:# Szyfrowaną wiadomość przekształcamy w&nbsp;ciąg cyfr. W&nbsp;przypadku długich wiadomości może być konieczny podział ciągu cyfr na bloki. Tworzymy w&nbsp;ten sposób liczbę <math>B</math>. Zakładamy, że <math>B < m</math>
 +
:# Szyfrowanie. Zakodowany tekst jest wynikiem operacji: <math>C = R_m (B^e)</math>, gdzie <math>R_m (B^e)</math> oznacza resztę z&nbsp;dzielenia liczby <math>B^e</math> przez <math>m</math>
 +
:#* zauważmy, że: <math>C \equiv B^e \!\! \pmod{m}</math>
 +
:# Odszyfrowanie. Odkodowany tekst otrzymujemy, obliczając: <math>B = R_m (C^d)</math>
 +
:# Dowód poprawności metody wynika z&nbsp;twierdzenia Q12
 +
:#* <math>R_m (C^d) \equiv C^d \equiv (B^e)^d \equiv B^{e d} \equiv B^{- k \Phi + 1} \equiv B^{- k (p - 1) (q - 1) + 1} \equiv B \!\! \pmod{m}</math>
 +
:#* ponieważ <math>k < 0</math>, to <math>- k</math> jest liczbą dodatnią i&nbsp;możemy zastosować twierdzenie Q12
 +
:#* ponieważ <math>B < m</math>, to <math>R_m (C^d) = B</math>
 +
:# Para liczb <math>(m, e)</math> jest nazywana kluczem publicznym – służy do szyfrowania i&nbsp;może być dostępna dla każdego.
 +
:# Para liczb <math>(m, d)</math> jest nazywana kluczem prywatnym – służy do odszyfrowania. Liczba <math>d</math> jest tajna – osoba, która ją wykradnie, będzie mogła odczytywać wysyłane do nas wiadomości
  
  
  
<span id="H37" style="font-size: 110%; font-weight: bold;">Zadanie H37</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Przykład Q13</span><br/>
Dla <math>n \geqslant 3</math> wartości <math>\varphi (n)</math> są liczbami parzystymi.
+
Prosty przykład: niech wysyłaną wiadomością będzie słowo <math>\text{YES}</math>. Zamianę liter na ciąg cyfr dokonamy, przypisując każdej literze jej numer w&nbsp;alfabecie np.: <math>A \longrightarrow 01</math>, <math>B \longrightarrow 02</math>, ... , <math>Z \longrightarrow 26</math>, czyli <math>\text{YES}\longrightarrow 250519</math>, zatem musimy zaszyfrować liczbę <math>250519</math>.
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
Niech <math>p = 1009</math>, <math>q = 1013</math>, <math>e = 1019</math>. Znajdujemy <math>m = p q = 1022117</math>, <math>\Phi = (p - 1) (q - 1) = 1020096</math>, <math>d = 397427</math>. Klucz publiczny <math>(m, e)</math>, klucz prywatny <math>(m, d)</math>. Zaszyfrowana wiadomość to <math>R_m (250519^e) = 560222</math>. Odszyfrowując, otrzymujemy <math>R_m (560222^d) = 250519</math>. Tak, jak być powinno.
Jeżeli liczba <math>n \geqslant 3</math> jest podzielna przez liczbę pierwszą nieparzystą <math>p</math>, zaś <math>k</math> jest wykładnikiem, z&nbsp;jakim <math>p</math> wchodzi do rozwinięcia <math>n</math> na czynniki pierwsze, to
 
  
::<math>\varphi (n) = \varphi \left( p^k \cdot {\small\frac{n}{p^k}} \right) = (p - 1) p^{k  - 1} \cdot \varphi \left( {\small\frac{n}{p^k}} \right)</math>
 
  
zatem <math>\varphi (n)</math> jest liczbą parzystą, ponieważ <math>p - 1</math> jest liczbą parzystą.
 
  
Jeżeli żadna liczba nieparzysta nie dzieli <math>n</math>, to liczba <math>n</math> jest postaci <math>n = 2^a</math> i <math>\varphi (n) = 2^{a - 1}</math>, ale z&nbsp;założenia <math>n \geqslant 3</math>, zatem <math>a \geqslant 2</math> i <math>\varphi (n)</math> jest liczbą parzystą.<br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q14</span><br/>
&#9633;
+
Bezpieczeństwo metody polega na wyborze tak dużych liczb pierwszych <math>p</math> i <math>q</math>, aby faktoryzacja ich iloczynu <math>m</math> leżała poza możliwościami współczesnych komputerów i&nbsp;stosowanych algorytmów. Choć klucz publiczny <math>(m, e)</math> służący do szyfrowania nie jest tajny i&nbsp;może być udostępniany wszystkim, to poznanie klucza prywatnego, czyli liczby <math>d</math>, jest praktycznie niemożliwe.
{{\Spoiler}}
 
  
 +
Liczba <math>d</math> wynika z&nbsp;rozwiązania równania <math>d e + k \Phi = 1</math>, ale aby obliczyć <math>\Phi = (p - 1) (q - 1)</math> musimy znać rozkład liczby <math>m</math> na czynniki pierwsze. Obecnie nie istnieją dostatecznie szybkie sposoby znajdowania rozkładu dużych liczb na czynniki pierwsze. Możemy łatwo sprawdzić, czy liczba <math>m = p q</math> jest liczbą złożoną, ale jeśli tak jest, to poznanie jej czynników jest dla dostatecznie dużych <math>m</math> niemożliwe.
  
  
<span id="H38" style="font-size: 110%; font-weight: bold;">Twierdzenie H38</span><br/>
 
Jeżeli <math>n</math> jest liczbą złożoną, to <math>\varphi (n) \leqslant n - \sqrt{n}</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q15 (generowanie liczb <math>m, e, d</math>)</span><br/>
<span style="border-bottom-style: double;">Pierwszy sposób</span><br/>
+
Przyjmując proste założenia co do liczb pierwszych <math>p, q</math> (przyjęliśmy, że <math>1.8 p < q < 2.2 p</math>) oraz zakładając, że <math>d > m^{2 / 3}</math> napisaliśmy prosty program do generowania klucza publicznego i&nbsp;prywatnego. Parametr <code>w</code> określa, ile cyfr w&nbsp;układzie dziesiętnym będą miały liczby <math>p, q</math>. Wybór <code>w > 500</code> gwarantuje wygenerowanie liczby <math>m</math>, której rozkład na czynniki pierwsze nie powinien być możliwy przez wiele lat. Ostatnie (znane) osiągnięcie faktoryzacji, to rozkład 250-cyfrowej liczby <math>m = p q</math> na czynniki pierwsze<ref name="RSA250"/>.
Niech <math>n = a b</math>, gdzie <math>1 < a \leqslant b < n</math>. Liczby <math>1 \cdot a, 2 \cdot a, 3 \cdot a, \ldots, b \cdot a</math> są nie większe od <math>n</math> i&nbsp;nie są względnie pierwsze z <math>n</math>, zatem
 
  
::<math>\varphi (n) \leqslant n - b</math>
+
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Pokaż kod|Hide=Ukryj kod}}
 +
<span style="font-size: 90%; color:black;">RSAkeys(w) =
 +
\\ parametr w > 1 określa, ile cyfr w&nbsp;układzie dziesiętnym będą miały liczby p, q
 +
{
 +
'''local'''(d, e, m, p, Phi, q);
 +
'''setrand'''('''getwalltime'''());  \\ ustawiamy ziarno (ang. seed) generatora liczb losowych
 +
p = 1;
 +
q = 0;
 +
'''while'''( !'''isprime'''(p)  ||  !'''isprime'''(q),
 +
        '''while'''( q < 1.8 * p  ||  q > 2.2 * p,
 +
              p = '''randomprime'''( [10^(w - 1), 10^w] );
 +
              q = '''randomprime'''( [10^(w - 1), 10^w] );
 +
            );
 +
      );
 +
m = p * q;
 +
Phi = (p - 1) * (q - 1);
 +
d = -1;
 +
'''while'''( d < m^(2/3),
 +
        e = '''randomprime'''( [10^10, 10^15] );
 +
        if( '''gcd'''(e, Phi) > 1, '''next'''() );
 +
        d = '''gcdext'''(e, Phi)[1];
 +
      );
 +
'''return'''([m, e, d]);
 +
}</span>
  
Ponieważ <math>b \geqslant a</math>, to <math>b^2 \geqslant a b = n</math> i <math>b \geqslant \sqrt{n}</math>. Wynika stąd, że
+
<span style="font-size: 90%; color:black;">PrintRSAkeys(w) =
 
+
{
::<math>\varphi (n) \leqslant n - b \leqslant n - \sqrt{n}</math>
+
'''local'''(V);
 
+
V = RSAkeys(w);
<br/><span style="border-bottom-style: double;">Drugi sposób</span><br/>
+
'''print'''("m = ", V[1]);
Niech <math>q</math> oznacza najmniejszy dzielnik pierwszy liczby złożonej <math>n</math>, zatem <math>q^2 \leqslant n</math>, czyli <math>q \leqslant \sqrt{n}</math>, a&nbsp;stąd <math>{\small\frac{n}{q}} \geqslant \sqrt{n}</math> i
+
'''print'''("e = ", V[2]);
 
+
'''print'''("d = ", V[3]);
::<math>\varphi (n) = n \cdot \prod_{p|n} \left( 1 - {\small\frac{1}{p}} \right) \leqslant n \left( 1 - {\small\frac{1}{q}} \right) = n - {\small\frac{n}{q}} \leqslant n - \sqrt{n}</math>
+
}</span>
 
 
Co należało pokazać.<br/>
 
&#9633;
 
 
{{\Spoiler}}
 
{{\Spoiler}}
  
  
  
<span id="H39" style="font-size: 110%; font-weight: bold;">Twierdzenie H39</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q16 (zamiana tekstu na liczbę i&nbsp;odwrotnie)</span><br/>
Dla <math>n \geqslant 1</math> prawdziwe jest oszacowanie <math>\varphi (n) > {\small\frac{\sqrt{n}}{2}}</math>.
+
W przypadku profesjonalnych programów szyfrujących wykorzystujących metodę RSA szyfrowany jest cały plik, który jest przecież ciągiem zer i&nbsp;jedynek. Oprogramowanie dzieli taki plik na odpowiednich rozmiarów bloki <math>B_j</math> i&nbsp;każdy jest szyfrowany kluczem publicznym <math>(m, e)</math>. Możemy w&nbsp;ten sposób szyfrować zdjęcia, filmy, tekst w&nbsp;dowolnym języku itd.
 
 
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Dla <math>k \geqslant 3</math> jest
 
 
 
::<math>\left( 1 - {\small\frac{1}{k}} \right)^2 > {\small\frac{1}{k}}</math>
 
 
 
Wynika stąd, że jeżeli <math>m \geqslant 3</math> jest liczbą nieparzystą, to
 
 
 
::<math>\varphi (m)^2 = m^2 \prod_{p|m} \left( 1 - {\small\frac{1}{p}} \right)^2 > m^2 \prod_{p|m} {\small\frac{1}{p}} \geqslant m</math>
 
 
 
bo
 
 
 
::<math>\prod_{p|m} p \leqslant m</math>
 
 
 
Czyli dla nieparzystych liczb <math>m \geqslant 3</math> mamy
 
 
 
::<math>\varphi (m) > \sqrt{m} > {\small\frac{\sqrt{m}}{2}}</math>
 
 
 
 
 
Jeżeli <math>d = 2^a</math>, gdzie <math>a \geqslant 1</math>, to
 
  
::<math>\varphi (d) = \varphi (2^a) = 2^{a - 1} > {\small\frac{\sqrt{2^a}}{2}} = {\small\frac{\sqrt{d}}{2}}</math>
+
Ponieważ napisanie takiego oprogramowania wykraczałoby poza potrzeby tego omówienia, ale z&nbsp;drugiej strony chcemy udostępnić Czytelnikowi przykłady bardziej skomplikowane niż szyfrowanie słowa <math>\text{YES}</math>, to postanowiliśmy ograniczyć się do szyfrowania tekstu, który zawiera jedynie znaki ASCII<ref name="ASCII"/>.
  
 +
Aby efektywnie korzystać z&nbsp;szyfrowania RSA potrzebne będą nam programy, które przetworzą taki tekst na liczbę i&nbsp;odwrotnie. Poniżej przedstawiamy dwie bardzo proste funkcje: pierwsza funkcja zamienia znaki ASCII od 32 do 126 na liczbę (każdemu znakowi przypisywane są dwie cyfry), a&nbsp;druga funkcja zamienia wygenerowaną przez pierwszą funkcję liczbę na odpowiadający tej liczbie tekst.
  
W przypadku ogólnym, gdy <math>n</math> jest iloczynem liczby nieparzystej <math>m \geqslant 3</math> i&nbsp;potęgi liczby <math>2</math>, dostajemy
+
Założenie, że nasza wiadomość zawiera tylko znaki ASCII od 32 do 126, jest bardzo ważne. Oznacza to, że taki tekst przetworzony przez funkcję <code>TextToNumber()</code> na liczbę, zostanie odtworzony przez funkcję <code>NumberToText()</code> w&nbsp;niezmienionej postaci. Nie będzie tak, jeśli wystąpią inne znaki: każdy z&nbsp;takich znaków zostanie zamieniony na spacje (np. każda polska litera zostanie zamieniona na dwie spacje). Nie oznacza to, że nie można korzystać z&nbsp;tych funkcji, ale jeśli szyfrujemy '''podpisaną''' wiadomość, to zgodność tekstów ma zasadnicze znaczenie.
  
::<math>\varphi (n) = \varphi (2^a m) = \varphi (2^a) \varphi (m) > {\small\frac{\sqrt{2^a}}{2}} \cdot \sqrt{m} = {\small\frac{\sqrt{2^a m}}{2}} = {\small\frac{\sqrt{n}}{2}}</math>
+
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Pokaż kod|Hide=Ukryj kod}}
 +
<span style="font-size: 90%; color:black;">TextToNumber( s ) =  
 +
\\ zamienia znaki ASCII od 32 do 126 na liczbę
 +
{
 +
'''local'''(a, b, k, len, txt, V);
 +
V = '''Vecsmall'''(s);
 +
len = '''length'''(V);
 +
txt = "";
 +
k = 0;
 +
'''while'''( k++ <= len,
 +
        a = V[k];
 +
        b = "01";  \\ spacja – wstawiamy jeżeli a jest poza zakresem
 +
        '''if'''( a >= 32  &&  a <= 40, b = '''Str'''("0", a - 31) );
 +
        '''if'''( a >= 41  &&  a <= 126, b = '''Str'''(a - 31) );
 +
        txt = '''Str'''(txt, b);
 +
      );
 +
'''return'''( '''eval'''(txt) );
 +
}</span>
  
Oczywiście nierówność <math>\varphi (n) > {\small\frac{\sqrt{n}}{2}}</math> jest również prawdziwa dla <math>n = 1</math>. Co należało pokazać.<br/>
+
<span style="font-size: 90%; color:black;">NumberToText( n ) =
&#9633;
+
{
 +
'''local'''(a, k, len, txt, V);
 +
len = '''length'''('''Str'''(n));
 +
'''if'''( len % 2 == 1, len++ ); \\ "zgubione" zero na początku
 +
len = len / 2;
 +
V = '''vector'''(len);
 +
k = len + 1;
 +
'''while'''( k-- >= 1,
 +
        a = n % 100;
 +
        n = '''floor'''(n / 100);
 +
        V[k] = a + 31;
 +
      );
 +
txt = '''strchr'''(V);
 +
'''return'''(txt);
 +
}</span>
 +
<br/>
 
{{\Spoiler}}
 
{{\Spoiler}}
  
  
  
<span id="H40" style="font-size: 110%; font-weight: bold;">Zadanie H40</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q17</span><br/>
Pokazać, że dla <math>n \geqslant 7</math> prawdziwe jest oszacowanie <math>\varphi (n) > \sqrt{n}</math>.
+
Jeżeli mamy już funkcje zamieniające tekst na liczbę i&nbsp;odwrotnie, to napisanie w&nbsp;PARI/GP programów do szyfrowania i&nbsp;deszyfrowania metodą RSA jest bardzo proste.
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Pokaż kod|Hide=Ukryj kod}}
Zauważmy, że
+
<span style="font-size: 90%; color:black;">RSAencode(m, e, s) =
 +
\\ szyfrujemy string s
 +
{
 +
'''local'''(B, C);
 +
B = TextToNumber(s);
 +
C = '''lift'''( '''Mod'''(B, m)^e );
 +
'''print'''(C);
 +
}</span>
  
::<math>n - 1 > \sqrt{n} \qquad \qquad \;\, \text{dla} \; n \geqslant 3</math>
+
<span style="font-size: 90%; color:black;">RSAdecode(m, d, C) =  
 
+
\\ deszyfrujemy liczbę C
::<math>n - 1 > \sqrt{2 n} \qquad \qquad \text{dla} \; n \geqslant 4</math>
+
{
 
+
'''local'''(B, s);
 
+
B = '''lift'''( '''Mod'''(C, m)^d );
Zatem dla liczby pierwszej <math>p</math> i <math>k \geqslant 1</math> jest
+
s = NumberToText(B);
 
+
'''print'''(s);
::<math>\varphi (p^k) = (p - 1) p^{k - 1} > \sqrt{p} \cdot p^{k - 1} = p^{k - \tfrac{1}{2}} \geqslant p^{\tfrac{k}{2}} = \sqrt{p^k} \qquad \qquad \qquad \qquad \quad \; \text{dla} \;\: p \geqslant 3</math>
+
}</span>
 
+
<br/>
::<math>\varphi (p^k) = (p - 1) p^{k - 1} > \sqrt{2 p} \cdot p^{k - 1} = \sqrt{2} \cdot p^{k - \tfrac{1}{2}} \geqslant \sqrt{2} \cdot p^{\tfrac{k}{2}} = \sqrt{2 p^k} \qquad \qquad \text{dla} \;\, p \geqslant 5</math>
 
 
 
 
 
'''1. Przypadek, gdy <math>\boldsymbol{n \geqslant 3}</math> jest liczbą nieparzystą'''
 
 
 
Liczba <math>n</math> jest iloczynem czynników pierwszych nieparzystych, zatem
 
 
 
::<math>\varphi (n) = \varphi (p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s) = \varphi (p^{\alpha_1}_1) \cdot \ldots \cdot \varphi (p^{\alpha_s}_s) > \sqrt{p^{\alpha_1}_1} \cdot \ldots \cdot \sqrt{p^{\alpha_s}_s} = \sqrt{n}</math>
 
 
 
 
 
'''2. Przypadek, gdy <math>\boldsymbol{n = 2^a m} \;</math> i <math>\; \boldsymbol{q \mid m ,} \;</math> gdzie <math>\; \boldsymbol{q \geqslant 5}</math>'''
 
 
 
Z założenia <math>n = 2^a m = 2^a q^b r</math>, gdzie <math>r \geqslant 1</math> jest liczbą nieparzystą. Zauważmy, że <math>\varphi (r) \geqslant \sqrt{r}</math>, bo może być <math>r = 1</math>.
 
 
 
::<math>\varphi (n) = \varphi (2^a q^b r)</math>
 
 
 
:::<math>\;\;\,\, = \varphi (2^a) \varphi (q^b) \varphi (r)</math>
 
 
 
:::<math>\;\;\,\, > 2^{a - 1} \sqrt{2 q^b} \sqrt{r}</math>
 
 
 
:::<math>\;\;\,\, = 2^{a - \tfrac{1}{2}} \sqrt{q^b} \sqrt{r}</math>
 
 
 
:::<math>\;\;\,\, \geqslant 2^{\tfrac{a}{2}} \sqrt{q^b r}</math>
 
 
 
:::<math>\;\;\,\, = \sqrt{2^a q^b r}</math>
 
 
 
:::<math>\;\;\,\, = \sqrt{n}</math>
 
 
 
 
 
'''3. Przypadek, gdy <math>\boldsymbol{n = 2^a m} \;</math> i <math>\; \boldsymbol{q \nmid m ,} \;</math> gdzie <math>\; \boldsymbol{q \geqslant 5}</math>'''
 
 
 
Jeżeli żadna liczba pierwsza <math>q \geqslant 5</math> nie dzieli <math>m</math>, to możliwe są tylko dwie sytuacje: <math>n = 2^a \,</math> i <math>\, n = 2^a 3^b</math>.
 
 
 
'''3a. Przypadek, gdy <math>\boldsymbol{n = 2^a}</math>'''
 
 
 
::<math>\varphi (n) = \varphi (2^a) = 2^{a - 1} > \sqrt{2^a} = \sqrt{n} \qquad \qquad \;\, \text{dla} \; a \geqslant 3</math>
 
 
 
Twierdzenie nie jest prawdziwe dla <math>n = 2 \,</math> i <math>\, n = 4 \,\,</math> (gdy <math>a = 1 \,</math> lub <math>\, a = 2</math>).
 
 
 
'''3b. Przypadek, gdy <math>\boldsymbol{n = 2^a 3^b}</math>'''
 
 
 
::<math>\varphi (n) = \varphi (2^a 3^b) = \varphi (2^a) \varphi (3^b) = 2^{a - 1} \cdot 2 \cdot 3^{b - 1} = 2^a 3^{b - 1} = \sqrt{2^a 3^b} \cdot {\small\frac{\sqrt{2^a 3^b}}{3}} > \sqrt{2^a 3^b}</math>
 
 
 
Ostatnia nierówność jest prawdziwa, o&nbsp;ile <math>\sqrt{2^a 3^b} > 3</math>, czyli gdy <math>2^a 3^b > 9</math>, co ma miejsce, gdy <math>a \geqslant 2</math> lub <math>b \geqslant 2</math>.
 
 
 
Twierdzenie nie jest prawdziwe dla <math>n = 6 \;</math> (gdy <math>a = 1 \,</math> i <math>\, b = 1</math>).
 
 
 
 
 
Zbierając uzyskane wyniki, otrzymujemy: oszacowanie <math>\varphi (n) > \sqrt{n}</math> nie jest prawdziwe dla <math>n = 1, 2, 4, 6</math>. Co należało pokazać.<br/>
 
&#9633;
 
 
{{\Spoiler}}
 
{{\Spoiler}}
  
  
  
<span id="H41" style="font-size: 110%; font-weight: bold;">Zadanie H41</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Przykład Q18</span><br/>
Pokazać, że dla <math>n \geqslant 2</math> prawdziwe jest oszacowanie <math>\varphi (n) > {\small\frac{n}{3 \log n}}</math>. Korzystając z&nbsp;tego wyniku, pokazać, że <math>\varphi (n) > n^{2 / 3}</math> dla <math>n \geqslant 43</math> oraz że <math>\varphi (n) > n^{3 / 4}</math> dla <math>n \geqslant 211</math>.
+
Kładąc <code>w = 50</code> w&nbsp;funkcji <code>RSAkeys(w)</code> otrzymaliśmy
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
m = 2173471545652309346779542101680852446325835148920429701148920590128959176663355134192839060494750117<br/>
Niech <math>n = q^{\alpha_1}_1 \cdot \ldots \cdot q^{\alpha_s}_s</math>, a <math>n' = q_1 \cdot \ldots \cdot q_s</math> oznacza liczbę, będącą iloczynem dokładnie '''tych samych''' czynników pierwszych, jakie występują w&nbsp;liczbie <math>n</math>, natomiast <math>n^{\!\ast} = p_1 \cdot \ldots \cdot p_s</math> oznacza liczbę, będącą iloczynem dokładnie '''tej samej ilości''' czynników pierwszych, przy czym <math>p_i</math> oznacza teraz <math>i</math>-tą liczbę pierwszą.
+
e = 3675359337253<br/>
 +
d = 308186586218659991253427464678921309369969889382350078327142348395702895999753492453847408362677933<br/>
  
Ponieważ
+
Liczba m&nbsp;ma 100 cyfr. Podamy teraz prosty przykład z&nbsp;polskimi literami. Zakodujemy i&nbsp;odkodujemy tekst (35 znaków)
  
::<math>{\small\frac{\varphi (n)}{n}} = \prod_{p \mid n} \left( 1 - {\small\frac{1}{p}} \right)</math>
+
''Lepszy na wolności kęsek lada jaki.''
  
to
+
Zamieniając tekst na liczbę – funkcją <code>TextToNumber(s)</code> – otrzymujemy liczbę 74-cyfrową
  
::<math>{\small\frac{\varphi (n)}{n}} = {\small\frac{\varphi (n')}{n'}} \geqslant {\small\frac{\varphi (n^{\!\ast})}{n^{\!\ast}}} = \prod^s_{i = 1} \left( 1 - {\small\frac{1}{p_i}} \right) \geqslant \prod^{p_s}_{k = 2} \left( 1 - {\small\frac{1}{k}} \right) = {\small\frac{1}{p_s}}</math>
+
B = 45708184919001796601888077798001016874017601018470760177666966017566767415
  
Ostatnia równość wynika z&nbsp;prostego wzoru
+
Jest tak, bo każdy znak tekstu został zamieniony na dwie cyfry, ale każda z&nbsp;polskich liter "ś" i "ę" została zamieniona na dwie spacje i&nbsp;każdej z&nbsp;tych liter odpowiadają cztery cyfry "0101". Zauważmy, że B&nbsp;<&nbsp;m tak, jak być powinno.
  
::<math>\prod^m_{k = 2} \left( 1 - {\small\frac{1}{k}} \right) = {\small\frac{1}{2}} \cdot {\small\frac{2}{3}} \cdot {\small\frac{3}{4}} \cdot \ldots \cdot {\small\frac{m - 2}{m - 1}} \cdot {\small\frac{m - 1}{m}} = {\small\frac{1}{m}}</math>
+
Korzystając z&nbsp;funkcji <code>RSAencode(m, e, s)</code>, dostajemy od razu zakodowany tekst
  
 +
C = 1883258467778511884133977054466089742750188942420326552221154007622797635139655819975338109849673552
  
Musimy oszacować wartość liczby <math>p_s</math>. Z&nbsp;twierdzenia B31 wynika, że dla <math>m \geqslant 2</math> jest <math>P(m) \geqslant 2^{m / 2}</math>, gdzie funkcja <math>P(m)</math> jest równa iloczynowi wszystkich liczb pierwszych nie większych od <math>m</math>. Zatem dla <math>p_s \geqslant 2</math> jest
+
Po odkodowaniu funkcją <code>RSAdecode(m, d, C)</code>, otrzymujemy
  
::<math>n^{\!\ast} = p_1 \cdot \ldots \cdot p_s = P (p_s) \geqslant 2^{p_s / 2}</math>
+
''Lepszy na wolno&nbsp;&nbsp;ci k&nbsp;&nbsp;sek lada jaki.''
  
Logarytmując, otrzymujemy
+
Polskie litery zostały zastąpione przez dwie spacje.
  
::<math>p_s \leqslant {\small\frac{2 \log n^{\!\ast}}{\log 2}}</math>
 
  
Ponieważ <math>n \geqslant n' \geqslant n^{\!\ast}</math>, to
+
Czytelnikowi pozostawiamy odszyfrowanie podanej niżej zakodowanej wiadomości. Ze względu na rozmiar musieliśmy podzielić tekst i&nbsp;otrzymaliśmy trzy zakodowane bloki.
  
::<math>{\small\frac{\varphi (n)}{n}} \geqslant {\small\frac{1}{p_s}} \geqslant {\small\frac{\log 2}{2 \log n^{\!\ast}}} \geqslant {\small\frac{\log 2}{2 \log n}} > {\small\frac{1}{3 \log n}}</math>
+
C<sub>1</sub> = 1228411078235780067165277802337600665865387220034514894292654793454492777859429937501850347835450261<br/>
 +
C<sub>2</sub> = 1212270919532485597119464911345613794658433495925582794819870422454753698249874400827689168074862675<br/>
 +
C<sub>3</sub> = 1407997868763350498310642273976637553443290951270357250985396471705600151258961305510222246198960667<br/>
  
Ostatecznie otrzymujemy
 
  
::<math>\varphi (n) > {\small\frac{n}{3 \log n}}</math>
 
  
Co należało pokazać.
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q19</span><br/>
 +
Omówiliśmy dokładnie metodę szyfrowania RSA i&nbsp;Czytelnik powinien mieć już jasność, że metodą tą możemy szyfrować tylko liczby. Jeśli chcemy zaszyfrować tekst, to musi najpierw zostać zapisany w&nbsp;postaci liczby (ciągu cyfr). Podaliśmy też dwie proste metody takiej zamiany (zobacz Q13 i&nbsp;Q16).
  
 +
W dalszej części artykułu pisząc o&nbsp;szyfrowaniu metodą RSA, będziemy mieli najczęściej na myśli dwie czynności wykonywanie łącznie: zamianę tekstu na liczbę (ustaloną wcześniej metodą) i&nbsp;właściwą operację szyfrowania. Podobnie pisząc o&nbsp;odszyfrowaniu, też zazwyczaj będziemy mieli myśli dwie czynności: właściwą operację odszyfrowywania i&nbsp;zamianę otrzymanej liczby na tekst.
  
Rozwiązując drugą część zadania, wystarczy znaleźć, dla jakich <math>n</math> prawdziwa jest nierówność
 
  
::<math>{\small\frac{n}{3 \log n}} > n^{2 / 3}</math>
 
  
Przebieg funkcji <math>{\small\frac{n}{3 \log n}} \,</math> i <math>\, n^{2 / 3}</math> przedstawiliśmy na wykresie
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q20</span><br/>
 +
Zwróćmy uwagę na to, że w&nbsp;przypadku pomyłki i&nbsp;zaszyfrowania wiadomości naszym kluczem prywatnym <math>(m, d)</math> możliwe będzie jej odczytanie przez każdą osobę, która zna nasz klucz publiczny <math>(m, e)</math>. Istotnie, niech <math>C = R_m (B^d)</math>. Łatwo pokażemy, że <math>B = R_m (C^e)</math>.
  
::[[File: Euler1.png|1100px|none]]
+
::<math>R_m (C^e) \equiv C^e \equiv (B^d)^e \equiv B^{e d} \equiv B^{- k \Phi + 1} \equiv B^{- k (p - 1) (q - 1) + 1} \equiv B \!\! \pmod{m}</math>
  
Punkt przecięcia tych funkcji znajdujemy, wpisując w&nbsp;PARI/GP polecenie
+
Fakt ten wykorzystamy do stworzenia podpisu wiadomości.
  
<span style="font-size: 90%; color:black;">'''solve'''(n = 10, 10^5, n/(3*'''log'''(n)) - n^(2/3))</span>
 
  
Otrzymujemy
 
  
::<math>n = 29409.965</math>
 
  
Zatem <math>{\small\frac{n}{3 \log n}} > n^{2 / 3}</math> dla <math>n > 2.95 \cdot 10^4</math>.
 
  
Poleceniem
+
== Kryptograficzne funkcje haszujące ==
  
<span style="font-size: 90%; color:black;">'''for'''(n = 1, 3*10^4, '''if'''( '''eulerphi'''(n) <= n^(2/3), '''print'''(n) ))</span>
+
<span style="font-size: 110%; font-weight: bold;">Definicja Q21</span><br/>
 +
Funkcja haszująca<ref name="hashfunction1"/> przypisuje każdemu ciągowi bitów o&nbsp;dowolnej (ale skończonej) długości ciąg bitów o&nbsp;stałej długości.
  
sprawdzamy, że oszacowanie <math>\varphi (n) > n^{2 / 3}</math> jest prawdziwe dla <math>n \geqslant 43</math>.
 
  
  
Postępując analogicznie jak wyżej, znajdujemy, dla jakich <math>n</math> prawdziwa jest nierówność
+
<span style="font-size: 110%; font-weight: bold;">Przykład Q22</span><br/>
 +
Bardzo prosta funkcja haszująca przypisuje każdemu ciągowi osiem pierwszych bitów tego ciągu (w przypadku, gdy ciąg jest za krótki, wystarczy powtórzyć go odpowiednią liczbę razy). Tak określona funkcja nie jest dobrą funkcją haszującą i&nbsp;ze wszystkich wymagań (które wymienimy niżej) spełnia tylko jeden: możemy szybko obliczyć wynik.
  
::<math>{\small\frac{n}{3 \log n}} > n^{3 / 4}</math>
+
Innym przykładem funkcji haszującej może być funkcja, która oblicza sumę kodów ASCII kolejnych znaków modulo <math>256</math>. Ta funkcja, podobnie jak poprzednia, jedynie szybko oblicza wynik.
  
Wpisując w&nbsp;PARI/GP polecenie
+
Druga funkcja jest lepsza od pierwszej, bo każdy znak tekstu wpływa na uzyskany wynik. Co prawda ciągi znaków, których suma kodów ASCII wynosi 256 (np. "8dd") możemy dodawać bezkarnie, jednak uwzględniając, że wiadomość nie jest ciągiem przypadkowych znaków, modyfikacja wiadomości tak, aby hasz pozostał niezmieniony, będzie wymagała pewnego wysiłku.
  
<span style="font-size: 90%; color:black;">'''solve'''(n = 10, 10^7, n/(3*'''log'''(n)) - n^(3/4))</span>
 
  
otrzymujemy
 
  
::<math>n = 4447862.680</math>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q23</span><br/>
 +
Od dobrej funkcji haszującej oczekujemy, że będzie spełniała następujące warunki
  
Zatem <math>{\small\frac{n}{3 \log n}} > n^{3 / 4}</math> dla <math>n > 4.45 \cdot 10^6</math>
+
:* będzie szybko obliczać wynik
 +
:* (jednokierunkowość) dla zadanej wartości hasza <math>h</math> znalezienie jakiegokolwiek ciągu bitów <math>m</math> takiego, że <math>h = \mathop{\text{hash}}(m)</math> powinno być bardzo trudne
 +
:* (słaba odporność na kolizje) dla zadanego ciągu bitów <math>m_1</math> znalezienie jakiegokolwiek ciągu bitów <math>m_2 \neq m_1</math> takiego, że <math>\mathop{\text{hash}}(m_2) = \mathop{\text{hash}}(m_1)</math> powinno być bardzo trudne
 +
:* (silna odporność na kolizje) znalezienie jakichkolwiek dwóch ciągów bitów <math>m_1</math> i <math>m_2</math> takich, że <math>\mathop{\text{hash}}(m_1) = \mathop{\text{hash}}(m_2)</math> powinno być bardzo trudne
  
Poleceniem
+
W praktyce oznacza to, że jeżeli dwa łańcuchy mają taki sam hasz, to są one identyczne. To właśnie ta własność decyduje o&nbsp;przydatności funkcji haszującej dla podpisu elektronicznego i&nbsp;innych zastosowań.
  
<span style="font-size: 90%; color:black;">'''for'''(n = 1, 5*10^6, '''if'''( '''eulerphi'''(n) <= n^(3/4), '''print'''(n) ))</span>
 
  
sprawdzamy, że oszacowanie <math>\varphi (n) > n^{3 / 4}</math> jest prawdziwe dla <math>n \geqslant 211</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
  
 +
<span style="font-size: 110%; font-weight: bold;">Przykład Q24 (zastosowanie funkcji haszujących)</span><br/>
 +
Jeśli chcemy upewnić się, czy przesłana mailem wiadomość nie zastała zmieniona, to wystarczy, że telefonicznie podamy odbiorcy hasz wiadomości.
  
 +
Hasło podawane przy logowaniu powinno być haszowane, a&nbsp;system powinien przechowywać jedynie hasz hasła tak, aby samo hasło pozostawało nikomu nieznane.
  
<span id="H42" style="font-size: 110%; font-weight: bold;">Twierdzenie H42</span><br/>
+
Udostępniając do pobrania plik, możemy udostępnić również jego hasz. Umożliwi to łatwe sprawdzenie użytkownikowi, czy pobrany plik nie został uszkodzony.
Niech <math>n \in \mathbb{Z}_+</math>. Liczba <math>n</math> jest liczbą pierwszą wtedy i&nbsp;tylko wtedy, gdy <math>\varphi (n) = n - 1</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
 
Dla liczb złożonych <math>n \geqslant 4</math> nigdy nie będzie <math>\varphi (n) = n - 1</math>, bo
 
  
::<math>\varphi (n) \leqslant n - \sqrt{n} \leqslant n - 2</math>
 
  
Dla <math>n = 1, 2, 3</math> sprawdzamy bezpośrednio: <math>\varphi (1) = 1 \neq 1 - 1</math>, <math>\varphi (2) = 1 = 2 - 1</math>, <math>\varphi (3) = 2 = 3 - 1</math>. Co kończy dowód.<br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q25 (przykłady funkcji haszujących)</span><br/>
&#9633;
+
Istnieje wiele wykorzystywanych w&nbsp;praktyce funkcji haszujących. Najbardziej znane to: CRC<ref name="CRC"/>, MD5<ref name="MD5"/>, SHA-1<ref name="SHA1"/> oraz funkcje ze standardu SHA-2<ref name="SHA2"/>: SHA-224, SHA-256, SHA-384, SHA-512
{{\Spoiler}}
 
  
 +
Linux udostępnia wypisane wyżej funkcje jako cksum (CRC), md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum.
  
 +
Na stronie [https://emn178.github.io/online-tools/ GitHub – Online Tools] znajdziemy wiele funkcji haszujących. Możemy policzyć wartości wybranej funkcji dla dowolnego tekstu i&nbsp;dla plików. Zauważmy, że wiele edytorów tekstu automatycznie dodaje znak końca linii<ref name="konieclinii"/> (LF) o&nbsp;kodzie ASCII równym 10 (szesnastkowo 0a) na końcu pliku. Może to powodować różnice przy obliczaniu hasza dla tekstu i&nbsp;dla pliku tekstowego zawierającego ten sam tekst.
  
<span id="H43" style="font-size: 110%; font-weight: bold;">Twierdzenie H43</span><br/>
 
Dla dowolnej liczby całkowitej dodatniej <math>n</math> jest
 
  
::<math>n = \sum_{d \mid n} \varphi (d) = \sum_{d \mid n} \varphi \left( \frac{n}{d} \right)</math>
 
  
gdzie sumowanie przebiega po wszystkich dzielnikach dodatnich liczby <math>n</math>.
+
<span style="font-size: 110%; font-weight: bold;">Przykład Q26</span><br/>
 +
Dla przykładu rozważmy, często używaną, funkcję haszującą SHA-256. Generuje ona 256-bitowy hasz, który zapisujemy, podając 64 cyfry w&nbsp;zapisie szesnastkowym. Każdą cyfrę w&nbsp;układzie szesnastkowym można zapisać w&nbsp;postaci 4 zer i&nbsp;jedynek w&nbsp;układzie dwójkowym (czterech bitów).
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
::<math>0 = 0000, \ldots, 9 = 1001, a = 1010, \ldots, f = 1111</math>
Ponieważ <math>\varphi (n)</math> jest funkcją multiplikatywną, to funkcja
 
  
::<math>F(n) = \sum_{d \mid n} \varphi (d)</math>
+
Dla tekstu
  
też jest funkcją multiplikatywną (zobacz [[#H30|H30]]). Łatwo sprawdzamy, że twierdzenie jest prawdziwe dla <math>n = 1</math>. Niech <math>n > 1</math>. Jeżeli <math>n =
+
''Polskie litery i cyfry: ąćęłńóśźżĄĆĘŁŃÓŚŹŻ 0123456789''
p^{\alpha}</math> jest potęgą liczby pierwszej, to otrzymujemy
 
  
::<math>F (p^{\alpha}) = \sum_{d \mid p^{\alpha}} \varphi (d)</math>
+
otrzymujemy hasz
  
::::<math>= \varphi (1) + \varphi (p) + \varphi (p^2) + \ldots + \varphi (p^{\alpha}) =</math>
+
5a86397d5e16611466e82376cc9f4d367ecbcd4af6d4418a5d3a130e8ad9d98d
  
::::<math>= 1 + (p - 1) + p (p - 1) + \ldots + p^{\alpha - 1} (p - 1) =</math>
+
Czytelnik powinien zwrócić uwagę, że nawet niewielka zmiana tekstu (np. zmiana lub dodanie jednego znaku) spowoduje wygenerowanie zupełnie innego hasza.
  
::::<math>= 1 + (p - 1) + (p^2 - p) + \ldots + (p^{\alpha} - p^{\alpha - 1})</math>
 
  
::::<math>= p^{\alpha}</math>
 
  
Jeżeli <math>n</math> jest postaci <math>n = p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s</math>, to
 
  
::<math>F(n) = F (p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s) =</math>
 
  
:::<math>\;\;\;\, = F (p^{\alpha_1}_1) \cdot \ldots \cdot F (p^{\alpha_s}_s) =</math>
+
== Podpisywanie dokumentów jawnych ==
  
:::<math>\;\;\;\, = p^{\alpha_1}_1 \cdot \ldots \cdot p^{\alpha_s}_s</math>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q27</span><br/>
 +
Zauważmy, że przekazywanie wiadomości (jawnych lub nie) wymaga wcześniejszego ustalenia sposobu komunikowania się. Może to być konto mailowe (jawne lub używane tylko do kontaktów tajnych), umówiona skrytka itd. Wynika stąd, że odbiorca zawsze zna nadawcę (wie, od kogo otrzymał przesyłkę).
  
:::<math>\;\;\;\, = n</math>
+
Ponieważ musimy liczyć się z&nbsp;tym, że ustalony kanał łączności może zostać przejęty, a&nbsp;przekaz zmieniony, to stosujemy różnego rodzaju zabezpieczenia, których celem jest ochrona integralności przekazu.
  
Niech <math>1 < d_1 < d_2 < \ldots < n</math> będą dzielnikami liczby <math>n</math>. Zauważmy, że kiedy <math>d</math> przebiega zbiór dzielników <math>\{ 1, d_1, d_2, \ldots, n \}</math>, to <math>e = \frac{n}{d}</math> przebiega wszystkie te liczby tylko w&nbsp;odwrotnej kolejności. Zatem
 
  
::<math>\sum_{d \mid n} \varphi (d) = \sum_{d \mid n} \varphi \left( \frac{n}{d} \right)</math>
 
  
Co należało pokazać.<br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q28</span><br/>
&#9633;
+
Powiedzmy, że Bolek chce przekazać ważny dokument do Urzędu. Jednak Urząd chce mieć pewność, że tak ważny dokument rzeczywiście sporządził Bolek, a&nbsp;nie ktoś inny, kto tylko pod Bolka się podszywa. Oczywiście można taki dokument przekazać osobiście, ale co zrobić w&nbsp;sytuacji, gdy jest to niemożliwe, a&nbsp;dostępny jest internet?
{{\Spoiler}}
 
  
 +
Jeśli Bolek potrafi szyfrować wiadomości metodą RSA i&nbsp;udostępnił swój klucz publiczny <math>(m, e)</math> Urzędowi, to może postąpić następująco
  
 +
:# sporządzić ów ważny dokument (powiedzmy DokB) w&nbsp;postaci pliku (ewentualnie papierowy dokument zeskanować)
 +
:# obliczyć hasz pliku DokB: <math>\; h_B = \mathop{\text{SHA256}}( \text{DokB} )</math>
 +
:# zaszyfrować hasz <math>h_B</math> swoim '''kluczem prywatnym''' <math>(m, d)</math> (zobacz Q20)
 +
:#* zaszyfrowany hasz <math>h_B</math> jest podpisem Bolka (co za chwilę stanie się jasne)
 +
:# tak zaszyfrowany hasz wpisać w&nbsp;treści maila i&nbsp;załączyć plik DokB
  
<span id="H44" style="font-size: 110%; font-weight: bold;">Zadanie H44</span><br/>
 
Niech <math>n \geqslant 2</math>. Pokazać, że suma liczb całkowitych dodatnich nie większych od <math>n</math> i&nbsp;względnie pierwszych z <math>n</math> jest równa <math>{\small\frac{1}{2}} n \varphi (n)</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
Jak przebiega weryfikacja odebranej wiadomości?
Łatwo sprawdzamy, że wzór jest prawdziwy dla <math>n = 2</math> i&nbsp;odtąd będziemy przyjmowali, że <math>n \geqslant 3</math>. Zatem wartości <math>\varphi (n)</math> są liczbami parzystymi i&nbsp;niech <math>c = {\small\frac{1}{2}} \varphi (n)</math>. Zauważmy, że jeżeli liczba <math>a</math> jest względnie pierwsza z <math>n</math>, to liczba <math>n - a</math> jest również względnie pierwsza z <math>n</math>, bo <math>\gcd (a, n) = \gcd (n - a, n)</math>. Wypiszmy wszystkie liczby całkowite dodatnie nie większe od <math>n</math> i&nbsp;względnie pierwsze z <math>n</math> w&nbsp;kolejności rosnącej, a&nbsp;pod spodem w&nbsp;kolejności malejącej
 
  
::{| class="wikitable plainlinks"  style="font-size: 90%; text-align: center; margin-right: auto;"
+
:# Urząd odbiera mail od Bolka i&nbsp;pobiera załącznik (nazwijmy go DokU, bo nie wiemy, czy nie został zmieniony)
|-
+
:# Urząd oblicza hasz załączonego pliku DokU: <math>\; h_U = \mathop{\text{SHA256}}( \text{DokU} )</math>
| <math>1</math> || <math>a_2</math> || <math>…</math> || <math>a_c</math> || <math>n - a_c</math> || <math>…</math> || <math>n - a_2</math> || <math>n - 1</math>
+
:# '''kluczem publicznym''' Bolka Urząd odszyfrowuje otrzymany w&nbsp;mailu zaszyfrowany hasz <math>h_B</math> (zobacz Q20)
|-
+
:# z&nbsp;równości <math>h_B = h_U</math> wynika, że dokumenty DokB i&nbsp;DokU są identyczne (zobacz Q23)
| <math>n - 1</math> || <math>n - a_2</math> || <math>…</math> || <math>n - a_c</math> || <math>a_c</math> || <math>…</math> || <math>a_2</math> || <math>1</math>
 
|}
 
  
Suma liczb w&nbsp;każdej kolumnie jest równa <math>n</math>. Ponieważ ilość liczb względnie pierwszych z <math>n</math> jest równa <math>\varphi (n)</math>, to podwojona suma liczb całkowitych nie większych od <math>n</math> i&nbsp;pierwszych względem <math>n</math> wynosi <math>n \varphi (n)</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
  
 +
Jest tak, ponieważ z&nbsp;równości <math>h_B = h_U</math> wynika, że zaszyfrowany hasz <math>h_B</math> musiał pochodzić od Bolka, bo został zaszyfrowany jego kluczem '''prywatnym''', do którego nikt, poza nim, nie ma dostępu. Dlatego zaszyfrowany kluczem prywatnym Bolka hasz <math>h_B</math> jest tym samym, co jego podpis i&nbsp;potwierdza to, że plik DokB (którego hasz jest równy <math>h_B</math>) został sporządzony przez Bolka.
  
 +
Ujmując inaczej, każdy może przedstawić się w&nbsp;mailu jako Bolek, dołączyć spreparowany plik, policzyć hasz tego pliku, ale nie będzie w&nbsp;stanie zaszyfrować tego hasza kluczem '''prywatnym''' Bolka, bo klucz ten jest tajny i&nbsp;niedostępny dla nikogo poza Bolkiem.
  
<span id="H45" style="font-size: 110%; font-weight: bold;">Zadanie H45</span><br/>
 
Pokazać, że dla liczb naturalnych nieparzystych <math>n \geqslant 5</math> prawdziwe jest oszacowanie <math>\varphi (n) > \pi (n)</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
 
'''1.''' Jeżeli <math>n \geqslant 5</math> jest liczbą pierwszą, to liczbami pierwszymi względem <math>n</math> są wszystkie liczby pierwsze mniejsze od <math>n</math> oraz liczby <math>1, 4</math>. Zatem
 
  
::<math>\varphi (n) \geqslant \pi (n) - 1 + 2 > \pi (n)</math>.
 
  
'''2.''' Jeżeli <math>n = p^a</math>, gdzie <math>a \geqslant 2</math>, jest potęgą liczby pierwszej nieparzystej, to <math>n \geqslant 9</math> i&nbsp;liczbami pierwszymi względem <math>n</math> są wszystkie liczby pierwsze nie większe od <math>n</math> (oprócz liczby <math>p</math>) oraz liczby <math>1, 4, 8</math>. Zatem
 
  
::<math>\varphi (n) \geqslant \pi (n) - 1 + 3 > \pi (n)</math>.
+
== Podpisywanie dokumentów tajnych ==
  
'''3.''' Jeżeli <math>n</math> ma więcej niż jeden dzielnik pierwszy nieparzysty, to <math>n = q^{\alpha_1}_1 \cdot \ldots \cdot q^{\alpha_s}_s</math>, gdzie <math>s \geqslant 2</math>. Zauważmy, że
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q29</span><br/>
 +
Powiedzmy, że Bolek ma ważną informację i&nbsp;chce ją przekazać do Agencji. Oczywiście informacji nie może przeczytać nikt inny, a&nbsp;Agencja musi mieć pewność, że źródłem tej ważnej informacji jest rzeczywiście Bolek, a&nbsp;nie ktoś inny, kto tylko pod Bolka się podszywa. Tym razem Bolek na pewno potrafi szyfrować wiadomości metodą RSA, a&nbsp;jego klucz publiczny <math>(m, e)</math> jest z&nbsp;pewnością znany Agencji. Co więcej, Bolek zna klucz publiczny Agencji <math>(M, E)</math>, którego ma używać do komunikowania się z&nbsp;Agencją. W&nbsp;tym przypadku Bolek postępuje następująco
  
::<math>n = q^{\alpha_1}_1 \cdot \ldots \cdot q^{\alpha_s}_s \geqslant q_1 \cdot \ldots \cdot q_s \geqslant 3 \cdot 5^{s - 1} > 2^{2 s - 1}</math>
+
:# oblicza hasz wiadomości <math>h_B = \mathop{\text{SHA256}}( \text{tekst} )</math>
 +
:# szyfruje hasz <math>h_B</math> swoim '''kluczem prywatnym''' <math>(m, d)</math>
 +
:# umieszcza zaszyfrowany hasz <math>h_B</math> jako ostatnią linię tekstu wiadomości
 +
:# szyfruje całość (tekst wiadomości + zaszyfrowany hasz <math>h_B</math>) kluczem publicznym Agencji <math>(M, E)</math>
 +
:# umieszcza cały zaszyfrowany tekst w&nbsp;pliku i&nbsp;wysyła jako załącznik maila do Agencji
  
Liczbami pierwszymi względem <math>n</math> są wszystkie liczby pierwsze nie większe od <math>n</math> (oprócz liczb <math>q_1, \ldots, q_s</math>) oraz liczby <math>1, 2^2, 2^3, \ldots, 2^{2 s - 1}</math>. Zatem
+
Agencja
  
::<math>\varphi (n) \geqslant \pi (n) - s + 2 s - 1 = \pi (n) + s - 1 > \pi (n)</math>
+
:# pobiera załącznik
 +
:# tekst z&nbsp;załącznika odszyfrowuje kluczem prywatnym Agencji <math>(M, D)</math>
 +
:# z&nbsp;ostatniej linii pliku odczytuje zaszyfrowany hasz <math>h_A</math> tekstu otrzymanej wiadomości
 +
:# deszyfruje hasz <math>h_A</math> wiadomości '''kluczem publicznym''' Bolka <math>(m, e)</math>
 +
:# oblicza hasz <math>h_B</math> wiadomości od Bolka
 +
:# równość <math>h_B = h_A</math> potwierdza, że wiadomość nie została zmieniona i&nbsp;przekazał ją do Agencji Bolek
  
Co należało pokazać.<br/>
+
Zauważmy, że '''klucz publiczny''' Agencji może być wiedzą poufną, ale z&nbsp;pewnością nie jest tak dobrze strzeżony, jak '''klucze prywatne'''. Agencja nie może zakładać, że zaszyfrowany jej kluczem publicznym plik nie został spreparowany. Dopiero po odszyfrowaniu pliku, obliczeniu hasza wiadomości i&nbsp;potwierdzenia zgodności tego hasza z&nbsp;haszem zapisanym w&nbsp;ostatniej linii pliku (który został zaszyfrowany '''kluczem prywatnym''' Bolka) Agencja ma pewność, że plik stworzył i&nbsp;wysłał Bolek.
&#9633;
 
{{\Spoiler}}
 
  
  
  
<span id="H46" style="font-size: 110%; font-weight: bold;">Zadanie H46</span><br/>
+
<span style="font-size: 110%; font-weight: bold;">Uwaga Q30</span><br/>
Pokazać, że dla liczb naturalnych <math>n \geqslant 91</math> prawdziwe jest oszacowanie <math>\varphi (n) > \pi (n)</math>.
+
Zwróćmy uwagę, że '''jeżeli korzystamy''' z&nbsp;funkcji <code>TextToNumber()</code> i <code>NumberToText()</code> (zobacz Q16), a&nbsp;jednocześnie chcemy podpisywać szyfrowane wiadomości, to wiadomości '''nie mogą''' zawierać znaków innych niż znaki ASCII od&nbsp;32 do&nbsp;126.
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
Jest tak dlatego, że funkcja <code>TextToNumber()</code> zgubi informację o&nbsp;innych znakach w&nbsp;wiadomości, a&nbsp;funkcja <code>NumberToText()</code> już tej informacji nie odtworzy. Zatem hasz wysyłanej wiadomości i&nbsp;hasz otrzymanej wiadomości (po odszyfrowaniu) nigdy nie będą identyczne w&nbsp;przypadku użycia znaków innych niż znaki ASCII od&nbsp;32 do&nbsp;126.
Ponieważ <math>p_{2 s} > 1</math> i <math>p_{2 s} \geqslant p_{s + 1}</math>, to z&nbsp;zadania A40 natychmiast wynika nierówność
 
  
::<math>p_1 p_2 \cdot \ldots \cdot p_s > p_{s + 1} p_{2 s}</math>
 
  
która jest prawdziwa dla <math>n \geqslant 4</math>.
 
  
Pokażemy najpierw, że dla każdej liczby naturalnej mającej nie mniej niż cztery dzielniki pierwsze nierówność <math>\varphi (n) > \pi (n)</math> jest zawsze prawdziwa.
 
  
Przez <math>p_1, p_2, \ldots, p_k, \ldots</math> oznaczymy kolejne liczby pierwsze. Niech <math>n \geqslant 2</math> będzie liczbą naturalną i <math>n = q^{\alpha_1}_1 \cdot \ldots \cdot q^{\alpha_s}_s</math>, gdzie <math>q_i</math> oznaczają dowolne (nie muszą być kolejne) liczby pierwsze.
 
  
Wśród kolejnych <math>2 s</math> liczb pierwszych znajduje się przynajmniej <math>s</math> liczb pierwszych '''różnych''' od każdej z&nbsp;liczb <math>q_1, \ldots, q_s</math>. Jeśli oznaczymy te liczby (w rosnącej kolejności) przez <math>r_1, \ldots, r_s</math>, to łatwo zauważymy, że prawdziwe są dla nich następujące oszacowania
 
  
:*&nbsp;&nbsp;&nbsp;dla najmniejszej liczby <math>r_1 \leqslant p_{s + 1}</math>
 
  
:*&nbsp;&nbsp;&nbsp;dla wszystkich liczb <math>r_j \leqslant p_{2 s}</math> dla <math>j = 1, \ldots, s</math>.
 
  
Korzystając z&nbsp;wypisanej na początku dowodu nierówności, dla <math>s \geqslant 4</math> mamy
 
  
::<math>n = q^{\alpha_1}_1 \cdot \ldots \cdot q^{\alpha_s}_s \geqslant q_1 \cdot \ldots \cdot q_s \geqslant p_1 \cdot \ldots \cdot p_s > p_{s + 1} p_{2 s} \geqslant r_1 \cdot r_j</math>
 
  
gdzie <math>j = 1, \ldots, s</math>.
 
  
Wynika stąd, że jeśli <math>s \geqslant 4</math>, to liczbami pierwszymi względem <math>n</math> są wszystkie liczby pierwsze nie większe od <math>n</math> (oprócz liczb pierwszych <math>q_1, \ldots, q_s</math>) oraz liczby <math>1</math> i <math>r_1 r_j</math>, gdzie <math>j = 1, \ldots, s</math>. Zatem
 
  
::<math>\varphi (n) \geqslant \pi (n) - s + s + 1> \pi (n)</math>
 
  
Co mieliśmy pokazać.
 
  
 +
== Przypisy ==
  
Uwzględniając rezultat pokazany w&nbsp;zadaniu [[#H45|H45]], pozostaje sprawdzić przypadki gdy <math>n = 2^a</math>, <math>n = 2^a p^b</math>, <math>n = 2^a p^b q^c</math>, gdzie <math>a, b, c \in \mathbb{Z}_+</math>.
+
<references>
 
 
'''1.''' Niech <math>n = 2^a</math>. Jeśli <math>n \geqslant 16</math>, to liczbami pierwszymi względem <math>n</math> są wszystkie liczby pierwsze nie większe od <math>n</math> (oprócz liczby <math>2</math>) oraz liczby <math>1, 9, 15</math>. Zatem
 
 
 
::<math>\varphi (n) \geqslant \pi (n) - 1 + 3 > \pi (n)</math>
 
 
 
'''2.''' Niech <math>n = 2^a p^b</math>, zaś <math>r</math> będzie najmniejszą liczbą pierwszą nieparzystą różną od <math>p</math>. Oczywiście <math>r \in \{ 3, 5 \}</math> i&nbsp;jeśli tylko <math>n > 5^3 = 125</math>, to liczbami pierwszymi względem <math>n</math> są wszystkie liczby pierwsze nie większe od <math>n</math> (oprócz liczb pierwszych <math>2</math> i <math>p</math>) oraz liczby <math>1, r^2, r^3</math>. Zatem
 
 
 
::<math>\varphi (n) \geqslant \pi (n) - 2 + 3 > \pi (n)</math>
 
 
 
'''3.''' Niech <math>n = 2^a p^b q^c</math>, zaś <math>r</math> będzie najmniejszą liczbą pierwszą nieparzystą różną od <math>p</math> oraz różną od <math>q</math>. Oczywiście <math>r \in \{ 3, 5, 7 \}</math> i&nbsp;jeśli <math>n > 7^4 = 2401</math>, to liczbami pierwszymi względem <math>n</math> są wszystkie liczby pierwsze nie większe od <math>n</math> (oprócz liczb pierwszych <math>2</math>, <math>p</math> i <math>q</math>) oraz liczby <math>1, r^2, r^3, r^4</math>. Zatem
 
 
 
::<math>\varphi (n) \geqslant \pi (n) - 3 + 4 > \pi (n)</math>
 
 
 
Zbierając: pozostaje sprawdzić bezpośrednio przypadki, gdy <math>n</math> jest liczbą parzystą i <math>n \leqslant 2401</math>. W&nbsp;GP/PARI wystarczy napisać polecenie
 
  
<span style="font-size: 90%; color:black;">for(n = 1, 2500, if( eulerphi(n) <= primepi(n), print(n) ))</span>
+
<ref name="DiffieHellman1">Whitfield Diffie and Martin E. Hellman, ''New Directions in Cryptography'', IEEE Transactions on Information Theory, Vol.&nbsp;22, No.&nbsp;6, 1976 ([https://ee.stanford.edu/~hellman/publications/24.pdf LINK])</ref>
  
Nierówność <math>\varphi (n) > \pi (n)</math> nie jest prawdziwa dla <math>n \in \{ 2, 3, 4, 6, 8, 10, 12, 14, 18, 20, 24, 30, 42, 60, 90 \}</math>. Co kończy dowód.<br/>
+
<ref name="DiffieHellman2">Wikipedia, ''Protokół Diffiego-Hellmana'', ([https://pl.wikipedia.org/wiki/Protok%C3%B3%C5%82_Diffiego-Hellmana Wiki-pl]), ([https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange Wiki-en])</ref>
&#9633;
 
{{\Spoiler}}
 
  
 +
<ref name="generator1">Liczba <math>g</math> powinna (ale nie musi) być generatorem modulo <math>p</math>. Dlaczego tak jest, wyjaśnimy w&nbsp;dalszej części tekstu.</ref>
  
 +
<ref name="funkcjaphi1">Wikipedia, ''Funkcja φ'', ([https://pl.wikipedia.org/wiki/Funkcja_%CF%86 Wiki-pl]), ([https://en.wikipedia.org/wiki/Euler%27s_totient_function Wiki-en])</ref>
  
<span id="H47" style="font-size: 110%; font-weight: bold;">Zadanie H47</span><br/>
+
<ref name="RSA1">R. Rivest, A. Shamir and L. Adleman, ''A Method for Obtaining Digital Signatures and Public-Key Cryptosystems'', Communications of the ACM, Volume 21, Issue 2, Feb. 1978, pp. 120-126</ref>
Pokazać, że <math>\varphi (n) = 2^a</math> wtedy i&nbsp;tylko wtedy, gdy <math>n = 2^b q_1 \cdot \ldots \cdot q_s</math>, gdzie <math>q_1, \ldots, q_s</math> są liczbami pierwszymi Fermata: <math>3, 5, 17, 257, 65537</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Rozwiązanie|Hide=Ukryj rozwiązanie}}
+
<ref name="RSA2">Wikipedia, ''RSA (kryptografia)'', ([https://pl.wikipedia.org/wiki/RSA_(kryptografia) Wiki-pl]), ([https://en.wikipedia.org/wiki/RSA_(cryptosystem) Wiki-en])</ref>
W przypadku, gdy <math>2 \mid n</math>, łatwo zauważamy, że liczba <math>2</math> może występować w&nbsp;dowolnej potędze, bo <math>\varphi (2^b) = 2^{b - 1}</math>.
 
  
W przypadku, gdy <math>p \mid n</math>, gdzie <math>p</math> jest liczbą pierwszą nieparzystą, mamy <math>\varphi (p^k) = (p - 1) p^{k - 1}</math> i&nbsp;równie łatwo zauważmy, że musi być <math>k = 1</math>, a&nbsp;liczba <math>p - 1</math> musi być potęgą liczby <math>2</math>. Zatem liczba pierwsza <math>p</math> musi być postaci <math>p = 2^t + 1</math>, co jest możliwe tylko wtedy, gdy <math>t</math> jest potęgą liczby <math>2</math> (zobacz [[#H48|H48]]), czyli <math>p</math> musi być liczbą pierwszą Fermata. Co należało pokazać.<br/>
+
<ref name="BonehDurfee1">Dan Boneh and Glenn Durfee, ''Cryptanalysis of RSA with Private Key d Less Than N<sup>0.292</sup>'', IEEE Transactions on Information Theory, Vol.&nbsp;46, No.&nbsp;4, 2000</ref>
&#9633;
 
{{\Spoiler}}
 
  
 +
<ref name="RSA250">Wikipedia, ''RSA numbers'', ([https://en.wikipedia.org/wiki/RSA_numbers#RSA-250 Wiki-en])</ref>
  
 +
<ref name="ASCII">Wikipedia, ''ASCII'', ([https://pl.wikipedia.org/wiki/ASCII Wiki-pl]), ([https://en.wikipedia.org/wiki/ASCII Wiki-en])</ref>
  
 +
<ref name="hashfunction1">Wikipedia, ''Cryptographic hash function'', ([https://en.wikipedia.org/wiki/Cryptographic_hash_function Wiki-en]), ([https://pl.wikipedia.org/wiki/Funkcja_skr%C3%B3tu#Kryptograficzne_funkcje_skr%C3%B3tu Wiki-pl])</ref>
  
 +
<ref name="CRC">Wikipedia, ''Cykliczny kod nadmiarowy'', ([https://pl.wikipedia.org/wiki/Cykliczny_kod_nadmiarowy Wiki-pl]), ([https://en.wikipedia.org/wiki/Cyclic_redundancy_check Wiki-en])</ref>
  
== Uzupełnienie ==
+
<ref name="MD5">Wikipedia, ''MD5'', ([https://pl.wikipedia.org/wiki/MD5 Wiki-pl]), ([https://en.wikipedia.org/wiki/MD5 Wiki-en])</ref>
  
<span id="H48" style="font-size: 110%; font-weight: bold;">Twierdzenie H48</span><br/>
+
<ref name="SHA1">Wikipedia, ''SHA-1'', ([https://pl.wikipedia.org/wiki/SHA-1 Wiki-pl]), ([https://en.wikipedia.org/wiki/SHA-1 Wiki-en])</ref>
Niech <math>a, n \in \mathbb{Z}_+</math> i <math>a \geqslant 2</math>. Jeżeli liczba <math>a^n + 1</math> jest liczbą pierwszą, to <math>a</math> jest liczbą parzystą i <math>n = 2^m</math>.
 
  
{{Spoiler|Style = font-style: italic; font-weight: bold; color: olive; text-decoration: underline;|Show=Dowód|Hide=Ukryj dowód}}
+
<ref name="SHA2">Wikipedia, ''SHA-2'', ([https://pl.wikipedia.org/wiki/SHA-2 Wiki-pl]), ([https://en.wikipedia.org/wiki/SHA-2 Wiki-en])</ref>
Gdyby liczba <math>a</math> była nieparzysta, to liczba <math>a^n + 1 \geqslant 4</math> byłaby parzysta i&nbsp;nie mogłaby być liczbą pierwszą.
 
  
Niech wykładnik <math>n = x y</math> będzie liczbą złożoną, a <math>x</math> będzie liczbą nieparzystą. Wtedy
+
<ref name="konieclinii">Wikipedia, ''Koniec linii'', ([https://pl.wikipedia.org/wiki/Koniec_linii Wiki-pl]), ([https://en.wikipedia.org/wiki/Newline Wiki-en])</ref>
 
 
::<math>a^n + 1 = (a^y)^x + 1</math>
 
 
 
Oznaczając <math>b = a^y</math> oraz <math>x = 2 k + 1</math>, otrzymujemy
 
 
 
::<math>a^n + 1 = (a^y)^x + 1 = b^x + 1 = b^{2 k + 1} + 1 = (b + 1) \cdot (1 - b + b^2 - b^3 + \ldots + b^{2 k - 2} - b^{2 k - 1} + b^{2 k})</math>
 
 
 
Zatem w&nbsp;takim przypadku <math>a^n + 1</math> jest liczbą złożoną. Wynika stąd, że wykładnik <math>n</math> nie może zawierać czynników nieparzystych, czyli musi być <math>n = 2^m</math>. Co należało pokazać.<br/>
 
&#9633;
 
{{\Spoiler}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
== Przypisy ==
 
 
 
<references>
 
 
 
<ref name="GCD1">Wikipedia, ''Największy wspólny dzielnik'', ([https://pl.wikipedia.org/wiki/Najwi%C4%99kszy_wsp%C3%B3lny_dzielnik Wiki-pl]), ([https://en.wikipedia.org/wiki/Greatest_common_divisor Wiki-en])</ref>
 
 
 
<ref name="cardinality1">Wikipedia, ''Moc zbioru'', ([https://pl.wikipedia.org/wiki/Moc_zbioru Wiki-pl]), ([https://en.wikipedia.org/wiki/Cardinality Wiki-en])</ref>
 
 
 
<ref name="sumazbiorow">Wikipedia, ''Zasada włączeń i&nbsp;wyłączeń'', ([https://pl.wikipedia.org/wiki/Zasada_w%C5%82%C4%85cze%C5%84_i_wy%C5%82%C4%85cze%C5%84 Wiki-pl]), ([https://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_principle Wiki-en])</ref>
 
 
 
<ref name="Euler1">Wikipedia, ''Funkcja φ'', ([https://pl.wikipedia.org/wiki/Funkcja_%CF%86 Wiki-pl]), ([https://en.wikipedia.org/wiki/Euler%27s_totient_function Wiki-en])</ref>
 
  
 
</references>
 
</references>
 
 
 
 
 
  
  

Wersja z 13:19, 17 lut 2024

22.11.2023



Protokół Diffiego-Hellmana

Uwaga Q1
Metoda ta została opracowana przez W. Diffiego i M. Hellmana[1][2] w 1976 roku. Opisana niżej procedura nie jest metodą szyfrowania i z założenia jej cel jest zupełnie inny. Umożliwia ona osobom mogącym kontaktować się ze sobą jedynie przez niezabezpieczone przed podsłuchem środki łączności ustalenie (tajnej) liczby, zwanej kluczem. Dysponując wspólną liczbą-kluczem osoby te mogą kodować i odczytywać wiadomości wybraną metodą szyfrowania. Przedstawimy w punktach procedurę postępowania wraz z przykładowymi danymi.

1. Agencja i Bolek wybierają (jawną) liczbę pierwszą [math]\displaystyle{ p = 541 }[/math] i (jawną) liczbę [math]\displaystyle{ g = 2 }[/math][3]
2. Agencja ustala (tajny, znany tylko sobie) wykładnik [math]\displaystyle{ a = 2718 }[/math]
3. Bolek ustala (tajny, znany tylko sobie) wykładnik [math]\displaystyle{ b = 3141 }[/math]
4. Agencja oblicza (jawną) liczbę [math]\displaystyle{ X = R_p (g^a) = 300 }[/math] i wysyła ją do Bolka
5. Bolek oblicza (jawną) liczbę [math]\displaystyle{ Y = R_p (g^b) = 191 }[/math] i wysyła ją do Agencji
6. Agencja oblicza (tajną) liczbę [math]\displaystyle{ k_A = R_p (Y^a) = 493 }[/math]
7. Bolek oblicza (tajną) liczbę [math]\displaystyle{ k_B = R_p (X^b) = 493 }[/math]
8. Modulo [math]\displaystyle{ p }[/math] mamy
[math]\displaystyle{ k_A = R_p (Y^a) \equiv Y^a = [R_p (g^b)]^a \equiv (g^b)^a \equiv g^{a b} \equiv (g^a)^b \equiv [R_p (g^a)]^b = X^b \equiv R_p (X^b) = k_B \!\! \pmod{p} }[/math]
9. Z definicji liczby [math]\displaystyle{ k_A, k_B \in [0, p - 1] }[/math], zatem [math]\displaystyle{ 0 \leqslant | k_A - k_B | \leqslant p - 1 }[/math]. Ponieważ liczby [math]\displaystyle{ k_A, k_B }[/math] przystają do siebie modulo [math]\displaystyle{ p }[/math], to muszą być sobie równe, czyli liczba [math]\displaystyle{ k = k_A = k_B }[/math] jest poszukiwanym kluczem.


Uwaga Q2
Liczby [math]\displaystyle{ a }[/math] i [math]\displaystyle{ b }[/math] mogą być losowo wybranymi liczbami dodatnimi nie większymi od [math]\displaystyle{ p }[/math]. Istotnie, jeżeli [math]\displaystyle{ a = k \cdot (p - 1) + r }[/math], to

[math]\displaystyle{ g^a \equiv (g^{p - 1})^k \cdot g^r \equiv g^r \!\! \pmod{p} }[/math]

W naszym przykładzie możemy użyć liczb [math]\displaystyle{ a = 18 }[/math] oraz [math]\displaystyle{ b = 441 }[/math] otrzymując te same rezultaty. W praktyce ten problem nie występuje, bo gdy liczba pierwsza [math]\displaystyle{ p }[/math] ma co najmniej sto cyfr, to trudno wybrać jeszcze większy wykładnik.


Przykład Q3
Zobaczmy, jak wpłynie na protokół zmiana liczby [math]\displaystyle{ g }[/math]. Niech [math]\displaystyle{ p = 541 }[/math] i [math]\displaystyle{ g = 15 }[/math].

Czytelnik może wybierać dowolne inne wykładniki [math]\displaystyle{ a }[/math] i [math]\displaystyle{ b }[/math], ale innych wartości [math]\displaystyle{ R_p (g^{a b}) }[/math] już nie uzyska. Wybór liczby [math]\displaystyle{ g = 2 }[/math] w zamieszczonym powyżej opisie metody, nie był przypadkowy. Liczba [math]\displaystyle{ 2 }[/math] jest generatorem modulo [math]\displaystyle{ 541 }[/math]. Generator modulo liczba pierwsza [math]\displaystyle{ p }[/math], to taka liczba [math]\displaystyle{ g }[/math], że zbiór potęg

[math]\displaystyle{ \{ g^1, g^2, g^3, \ldots, g^{p - 1} \} }[/math]

rozpatrywany modulo [math]\displaystyle{ p }[/math] jest identyczny ze zbiorem

[math]\displaystyle{ \{ 1, 2, 3, \ldots, p - 1 \} }[/math]

Wybierając liczbę [math]\displaystyle{ g }[/math] tak, aby była generatorem modulo [math]\displaystyle{ p }[/math], zapewniamy sobie, że w ostatniej kolumnie mogą pojawić się wszystkie liczby od [math]\displaystyle{ 1 }[/math] do [math]\displaystyle{ p - 1 }[/math]. Taki wybór [math]\displaystyle{ g }[/math] zwiększa ilość możliwych wartości dla ustalanego klucza [math]\displaystyle{ k = R_p (g^{a b}) }[/math], a tym samym zwiększa bezpieczeństwo procedury. Zauważmy, że liczby [math]\displaystyle{ p }[/math] i [math]\displaystyle{ g }[/math] są jawne. Osoba próbująca poznać ustalony klucz [math]\displaystyle{ k }[/math] z pewnością ucieszy się, gdy sprawdzi, że niewłaściwy wybór liczby [math]\displaystyle{ g }[/math] zredukował ilość możliwych kluczy i ułatwił jej pracę.

Każda liczba pierwsza ma generator modulo, ale znalezienie go dla dużych liczb pierwszych nie jest proste i może trwać bardzo długo. Pomocne w tej sytuacji jest następujące twierdzenie.


Twierdzenie Q4
Niech [math]\displaystyle{ p = 2 q + 1 }[/math] będzie liczbą pierwszą, gdzie [math]\displaystyle{ q \geqslant 3 }[/math] jest również liczbą pierwszą. Jeżeli [math]\displaystyle{ g }[/math] jest liczbą niekwadratową modulo [math]\displaystyle{ p }[/math] i [math]\displaystyle{ g \not\equiv - 1 \!\! \pmod{p} }[/math], to [math]\displaystyle{ g }[/math] jest generatorem modulo [math]\displaystyle{ p }[/math].

Dowód

Dowód jest na tyle prosty i elegancki, że postanowiliśmy go zamieścić, choć wykracza on poza omówiony wcześniej materiał. Czytelnik może ten dowód pominąć. Dowód poprzedzamy kilkoma prostymi, ale istotnymi komentarzami.

Komentarz 1.

Bez dowodu przyjmujemy fakt, że istnieje dokładnie [math]\displaystyle{ \varphi (p - 1) }[/math] różnych generatorów modulo [math]\displaystyle{ p }[/math], gdzie [math]\displaystyle{ \varphi }[/math] jest funkcją Eulera[4]. Funkcja Eulera [math]\displaystyle{ \varphi (n) }[/math] jest równa ilości liczb całkowitych dodatnich nie większych od [math]\displaystyle{ n }[/math] i względnie pierwszych z [math]\displaystyle{ n }[/math].

Komentarz 2.

Udowodnimy, że jeżeli [math]\displaystyle{ g }[/math] jest generatorem modulo [math]\displaystyle{ p }[/math], to [math]\displaystyle{ g }[/math] jest liczbą niekwadratową modulo [math]\displaystyle{ p }[/math].

Przypuśćmy, że [math]\displaystyle{ g }[/math] jest liczbą kwadratową modulo [math]\displaystyle{ p }[/math], zatem (zobacz J30)

[math]\displaystyle{ g^{(p - 1) / 2} \equiv 1 \!\! \pmod{p} }[/math]

Wynika stąd, że zbiór

[math]\displaystyle{ S = \{ g^1, g^2, g^3, \ldots, g^{p - 1} \} }[/math]
[math]\displaystyle{ \;\;\,\, = \left\{ g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1}, g^{\tfrac{p - 1}{2}}, g^{\tfrac{p - 1}{2} + 1}, g^{\tfrac{p - 1}{2} + 2}, g^{\tfrac{p - 1}{2} + 3}, \ldots, g^{p - 3}, g^{p - 2}, g^{p - 1} \right\} }[/math]

jest identyczny modulo [math]\displaystyle{ p }[/math] ze zbiorem

[math]\displaystyle{ S' = \left\{ g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1}, 1, g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1} \right\} }[/math]
[math]\displaystyle{ \quad \, = \left\{ 1, g^1, g^2, g^3, \ldots, g^{\tfrac{p - 1}{2} - 3}, g^{\tfrac{p - 1}{2} - 2}, g^{\tfrac{p - 1}{2} - 1} \right\} }[/math]

i nie może być identyczny modulo [math]\displaystyle{ p }[/math] ze zbiorem [math]\displaystyle{ T = \{ 1, 2, 3, \ldots, p - 1 \} }[/math], bo [math]\displaystyle{ S' }[/math] zawiera co najwyżej połowę elementów zbioru [math]\displaystyle{ T }[/math]. Uzyskana sprzeczność dowodzi, że generator musi być liczbą niekwadratową modulo [math]\displaystyle{ p }[/math].

Komentarz 3.

Ponieważ funkcja Eulera [math]\displaystyle{ \varphi (n) }[/math] jest równa ilości liczb całkowitych dodatnich nie większych od [math]\displaystyle{ n }[/math] i względnie pierwszych z [math]\displaystyle{ n }[/math], to dla liczby pierwszej [math]\displaystyle{ p }[/math] mamy [math]\displaystyle{ \varphi (p) = p - 1 }[/math], bo wszystkie liczby [math]\displaystyle{ 1, 2, 3, \ldots, p - 1 }[/math] są względnie pierwsze z liczbą pierwszą [math]\displaystyle{ p }[/math].

Komentarz 4.

Ponieważ funkcja Eulera [math]\displaystyle{ \varphi (n) }[/math] jest równa ilości liczb całkowitych dodatnich nie większych od [math]\displaystyle{ n }[/math] i względnie pierwszych z [math]\displaystyle{ n }[/math], to dla liczby pierwszej nieparzystej [math]\displaystyle{ p }[/math] mamy [math]\displaystyle{ \varphi (2 p) = p - 1 }[/math], bo

  • wszystkie liczby parzyste [math]\displaystyle{ 2, 4, 6, \ldots, 2 p - 2 }[/math] mają z liczbą [math]\displaystyle{ 2 p }[/math] wspólny dzielnik równy [math]\displaystyle{ 2 }[/math] i nie mogą być względnie pierwsze z liczbą [math]\displaystyle{ 2 p }[/math]
  • wszystkie liczby nieparzyste [math]\displaystyle{ 1, 3, 5, \ldots, 2 p - 1 }[/math] (których jest [math]\displaystyle{ p }[/math]) są względnie pierwsze z liczbą [math]\displaystyle{ 2 p }[/math], poza liczbą nieparzystą [math]\displaystyle{ p }[/math], która nie jest względnie pierwsza z liczbą [math]\displaystyle{ 2 p }[/math]


Wracając do dowodu twierdzenia Q4, zauważmy, że liczba [math]\displaystyle{ - 1 }[/math] jest liczbą niekwadratową modulo [math]\displaystyle{ p = 2 q + 1 }[/math]. Istotnie, obliczając symbol Jacobiego, otrzymujemy

[math]\displaystyle{ \left( {\small\frac{- 1}{p}} \right)_{\small{\!\! J}} = (- 1)^{\tfrac{p - 1}{2}} = (- 1)^q = - 1 }[/math]

Zauważmy też, że dla liczb pierwszych [math]\displaystyle{ p \geqslant 5 }[/math] liczba [math]\displaystyle{ - 1 }[/math] nie jest generatorem modulo [math]\displaystyle{ p }[/math]. Ponieważ [math]\displaystyle{ (- 1)^n = \pm 1 }[/math], to zbiór potęg

[math]\displaystyle{ \{ g^1, g^2, g^3, \ldots, g^{p - 1} \} }[/math]

składa się tylko z dwóch elementów [math]\displaystyle{ \{ - 1, 1 \} }[/math] i dla liczb pierwszych [math]\displaystyle{ p \geqslant 5 }[/math] nie może być identyczny modulo [math]\displaystyle{ p }[/math] ze zbiorem [math]\displaystyle{ \{ 1, 2, 3, \ldots, p - 1 \} }[/math].


Ilość generatorów modulo [math]\displaystyle{ p }[/math] dla liczby pierwszej [math]\displaystyle{ p = 2 q + 1 }[/math] jest równa

[math]\displaystyle{ \varphi (p - 1) = \varphi (2 q) = q - 1 = {\small\frac{p - 1}{2}} - 1 }[/math]

Ponieważ istnieje [math]\displaystyle{ {\small\frac{p - 1}{2}} }[/math] liczb niekwadratowych modulo [math]\displaystyle{ p }[/math] (zobacz J29), to liczb niekwadratowych modulo [math]\displaystyle{ p }[/math], różnych od [math]\displaystyle{ - 1 }[/math], jest [math]\displaystyle{ {\small\frac{p - 1}{2}} - 1 }[/math], czyli tyle samo, co generatorów modulo [math]\displaystyle{ p }[/math], a żadna z pozostałych liczb (kwadratowych modulo [math]\displaystyle{ p }[/math]) nie może być generatorem modulo [math]\displaystyle{ p }[/math]. Co kończy dowód.


Uwaga Q5
Jeśli nie potrzebujemy wyliczyć najmniejszego generatora modulo [math]\displaystyle{ p = 2 q + 1 }[/math], to z twierdzenia Q4 można łatwo pokazać, że liczba [math]\displaystyle{ - 4 }[/math] jest generatorem dla wszystkich liczb pierwszych [math]\displaystyle{ p = 2 q + 1 \geqslant 7 }[/math], a liczba [math]\displaystyle{ - 3 }[/math] dla wszystkich liczb pierwszych [math]\displaystyle{ p = 2 q + 1 \geqslant 11 }[/math]. Ponieważ [math]\displaystyle{ q = 2 k + 1 }[/math], to [math]\displaystyle{ p = 4 k + 3 }[/math].

1. Pokażemy, że [math]\displaystyle{ - 4 }[/math] jest liczbą niekwadratową modulo [math]\displaystyle{ p }[/math]. Liczba [math]\displaystyle{ k }[/math] może być postaci [math]\displaystyle{ 2 j }[/math] lub [math]\displaystyle{ 2 j + 1 }[/math], co daje odpowiednio [math]\displaystyle{ p = 8 j + 3 }[/math] lub [math]\displaystyle{ p = 8 j + 7 }[/math]. Zatem

[math]\displaystyle{ \left( {\small\frac{- 4}{p}} \right)_{\small{\!\! J}} = \left( {\small\frac{- 1}{p}} \right)_{\small{\!\! J}} \cdot \left( {\small\frac{2}{p}} \right)_{\small{\!\! J}}^{\! 2} = (- 1) \cdot (\pm 1)^2 = - 1 }[/math]

Zobacz twierdzenie J41 p.6.


2. Pokażemy, że [math]\displaystyle{ - 3 }[/math] jest liczbą niekwadratową modulo [math]\displaystyle{ p }[/math]. Liczba [math]\displaystyle{ k }[/math] może być postaci [math]\displaystyle{ 3 j, 3 j + 1, 3 j + 2 }[/math], co daje odpowiednio

[math]\displaystyle{ k = 3 j \qquad \qquad \;\!\!\! p = 12 j + 3 \qquad \;\; q = 6 j + 1 }[/math]
[math]\displaystyle{ k = 3 j + 1 \qquad p = 12 j + 7 \qquad \;\; q = 6 j + 3 }[/math]
[math]\displaystyle{ k = 3 j + 2 \qquad p = 12 j + 11 \qquad q = 6 j + 5 }[/math]

Pierwsza i druga postać liczby [math]\displaystyle{ k }[/math] nie jest możliwa, bo albo liczba [math]\displaystyle{ p }[/math], albo liczba [math]\displaystyle{ q }[/math] byłyby liczbami złożonymi. Zatem

[math]\displaystyle{ \left( {\small\frac{- 3}{p}} \right)_{\small{\!\! J}} = \left( {\small\frac{- 1}{p}} \right)_{\small{\!\! J}} \cdot \left( {\small\frac{3}{p}} \right)_{\small{\!\! J}} = (- 1) \cdot (+ 1) = - 1 }[/math]

Zobacz twierdzenie J41 p.6 i zadanie J46.


Uwaga Q6
O ile w ogólnym przypadku liczb pierwszych [math]\displaystyle{ p }[/math] liczących setki cyfr znalezienie najmniejszego generatora modulo [math]\displaystyle{ p }[/math] może trwać godzinami, to w przypadku liczb pierwszych [math]\displaystyle{ p = 2 q + 1 }[/math], gdzie [math]\displaystyle{ q }[/math] jest również liczbą pierwszą, wystarczy znaleźć liczbę niekwadratową modulo [math]\displaystyle{ p }[/math], a obliczenie symbolu Jacobiego trwa bardzo krótko, zaś wyszukanie liczb pierwszych postaci [math]\displaystyle{ p = 2 q + 1 }[/math] też jest zaskakująco szybkie. Dlatego napisaliśmy w PARI/GP prosty program, który wyszukuje w zadanym przedziale [math]\displaystyle{ [m, n] }[/math] liczbę pierwszą [math]\displaystyle{ p }[/math] taką, że [math]\displaystyle{ p = 2 q + 1 }[/math] i zwraca [math]\displaystyle{ p }[/math] oraz najmniejszy generator modulo [math]\displaystyle{ p }[/math].

Należy zwrócić uwagę, że funkcje ispseudoprime() i randomprime() sprawdzają pierwszość liczby na tym samym poziomie – wykonywany jest test Millera-Rabina. Dlatego używamy ich łącznie, co przyspiesza wyszukanie odpowiedniej liczby pierwszej. Następnie, już silniejszym testem, potwierdzamy pierwszość obydwu liczb: [math]\displaystyle{ p }[/math] i [math]\displaystyle{ (p - 1) / 2 }[/math].

Pokaż kod
SafePrime(m, n) = 
\\ zwraca wektor [p, g], gdzie p i (p-1)/2 są liczbami pierwszymi, a g jest generatorem modulo p
{
local(g, p);
setrand(getwalltime());  \\ ustawiamy ziarno (ang. seed) generatora liczb losowych
while( 1,
       p = 9;
       while( !ispseudoprime( (p - 1)/2 ), p = randomprime([m, n]) );
       if( isprime(p) && isprime( (p-1)/2 ), break() );
     );
g = 2;
while( jacobi(g, p) > -1, g++ );
return([p, g]);
}



Uwaga Q7
Jak dalece bezpieczna jest opisana wyżej metoda? Aby znaleźć klucz trzeba oprócz (jawnych) liczb [math]\displaystyle{ p, g, X, Y }[/math] znać jedną z liczb [math]\displaystyle{ a }[/math] lub [math]\displaystyle{ b }[/math]. Liczba [math]\displaystyle{ a }[/math] spełnia kongruencję

[math]\displaystyle{ g^a \equiv X \!\! \pmod{p} }[/math]

ale nie istnieje żadna metoda szybkiego znalezienia wykładnika [math]\displaystyle{ a }[/math]. Oczywiście zawsze pozostaje możliwość kolejnego wyliczania [math]\displaystyle{ g^n }[/math] modulo [math]\displaystyle{ p }[/math] z nadzieją trafienia na [math]\displaystyle{ X }[/math] lub [math]\displaystyle{ Y }[/math]. Dla naszych danych mielibyśmy modulo [math]\displaystyle{ 541 }[/math]

[math]\displaystyle{ 2^1 \equiv 2, \quad 2^2 \equiv 4, \; \ldots , \; 2^{17} \equiv 150, \quad 2^{18} \equiv 300 }[/math]

czyli wystarczyło jedynie 18 prób! Ale dla dwustucyfrowej liczby pierwszej [math]\displaystyle{ p }[/math] i trochę lepiej wybranych liczb [math]\displaystyle{ a }[/math] i [math]\displaystyle{ b }[/math] ilość prób będzie liczbą rzędu [math]\displaystyle{ 10^{50} }[/math]. Nawet dla najszybszych komputerów stanowi to barierę nie do pokonania.


Uwaga Q8
Realne zagrożenie pojawia się jedynie wtedy, gdy Agencja i Bolek nie sprawdzą autentyczności liczb [math]\displaystyle{ X }[/math] i [math]\displaystyle{ Y }[/math]. Przykładowo Agencja może zapytać o [math]\displaystyle{ 7 }[/math], [math]\displaystyle{ 23 }[/math], [math]\displaystyle{ 101 }[/math] itd. cyfrę liczby [math]\displaystyle{ X }[/math], którą otrzymał Bolek. Dlaczego jest to ważne? Jeżeli korespondencja (maile, listy) Agencji i Bolka jest kontrolowana przez Wywiad, to Wywiad może przechwycić liczby [math]\displaystyle{ X = R_p (g^a) }[/math] oraz [math]\displaystyle{ Y = R_p (g^b) }[/math] i wysłać im swoją liczbę [math]\displaystyle{ Z = R_p (g^c) }[/math]. Od tej pory korespondencja Agencji będzie przechwytywana, odszyfrowywana przez Wywiad kluczem [math]\displaystyle{ k_1 = R_p (g^{a c}) }[/math], czytana, ewentualnie zmieniana, ponownie szyfrowana kluczem [math]\displaystyle{ k_2 = R_p (g^{b c}) }[/math] i wysyłana do Bolka.

Analogicznie będzie kontrolowana korespondencja Bolka wysyłana do Agencji.



Szyfrowanie RSA

Uwaga Q9
Rozpoczniemy od dowodu kilku prostych twierdzeń. Łatwość ich sformułowania i dowodu zaskakuje, jeśli weźmiemy pod uwagę fakt, że stanowią one podstawę niezwykle ważnej metody szyfrowania.


Twierdzenie Q10
Jeżeli [math]\displaystyle{ p }[/math] jest liczbą pierwszą, to dla dowolnego [math]\displaystyle{ a \in \mathbb{Z} }[/math] i każdego [math]\displaystyle{ k \geqslant 0 }[/math] jest

[math]\displaystyle{ a^{(p - 1) k + 1} \equiv a \!\! \pmod{p} }[/math]
Dowód

Jeżeli [math]\displaystyle{ p \mid a }[/math], to dowodzona kongruencja jest prawdziwa. Jeżeli [math]\displaystyle{ p \nmid a }[/math], to modulo [math]\displaystyle{ p }[/math] mamy

[math]\displaystyle{ a^{(p - 1) k + 1} = a \cdot (a^{p - 1})^k \equiv a \!\! \pmod{p} }[/math]

gdzie skorzystaliśmy z twierdzenia Fermata (J21).


Twierdzenie Q11
Jeżeli [math]\displaystyle{ p }[/math] i [math]\displaystyle{ q }[/math] są różnymi liczbami pierwszymi, to dla dowolnego [math]\displaystyle{ a \in \mathbb{Z} }[/math] i każdego [math]\displaystyle{ k \geqslant 0 }[/math] jest

[math]\displaystyle{ a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{p q} }[/math]
Dowód

Z twierdzenia Q10 wiemy, że dla dowolnych liczb [math]\displaystyle{ i, j \geqslant 0 }[/math] prawdziwe są kongruencje

[math]\displaystyle{ a^{(p - 1) i + 1} \equiv a \!\! \pmod{p} }[/math]
[math]\displaystyle{ a^{(q - 1) j + 1} \equiv a \!\! \pmod{q} }[/math]

Dla dowolnego, ale ustalonego [math]\displaystyle{ k \geqslant 0 }[/math] wybierzmy liczby [math]\displaystyle{ i, j }[/math] następująco: [math]\displaystyle{ i = k (q - 1) }[/math] oraz [math]\displaystyle{ j = k (p - 1) }[/math]. Otrzymujemy

[math]\displaystyle{ a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{p} }[/math]
[math]\displaystyle{ a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{q} }[/math]

Z twierdzenia J1 wiemy, że powyższy układ kongruencji może być zapisany w sposób równoważny

[math]\displaystyle{ a^{k (p - 1) (q - 1) + 1} \equiv a \!\! \pmod{p q} }[/math]

Co należało pokazać.


Uwaga Q12 (metoda szyfrowania RSA)
RSA[5][6] to akronim od nazwisk twórców tej metody: Rona Rivesta, Adiego Shamira i Leonarda Adlemana. Rozpoczniemy od wypisania używanych oznaczeń, co znakomicie ułatwi zrozumienie opisu metody.

  1. [math]\displaystyle{ p, q }[/math] – dwie duże liczby pierwsze o zbliżonych wartościach
    • często przyjmuje się, że [math]\displaystyle{ p \lt q \lt 2 p }[/math]; można też przyjąć, że [math]\displaystyle{ q \sim 2 p }[/math]
  2. [math]\displaystyle{ m = p q }[/math]
  3. [math]\displaystyle{ \Phi = (p - 1) (q - 1) }[/math]
    • oznaczenie nawiązuje do funkcji Eulera [math]\displaystyle{ \varphi }[/math], bo [math]\displaystyle{ \varphi (m) = \varphi (p q) = (p - 1) (q - 1) }[/math]
  4. [math]\displaystyle{ e }[/math] (ang. encryption) – wykładnik służący do szyfrowania (publiczny)
  5. [math]\displaystyle{ d }[/math] (ang. decryption) – wykładnik służący do odszyfrowania (tajny)
  6. [math]\displaystyle{ B }[/math] (ang. block of digits) – wiadomość w postaci liczby (ciągu cyfr) przeznaczona do zaszyfrowania
  7. [math]\displaystyle{ C }[/math] (ang. coded block of digits) – zaszyfrowana wiadomość, czyli liczba powstała w wyniku szyfrowania liczby [math]\displaystyle{ B }[/math]


Opis metody

  1. Wybierzmy liczbę [math]\displaystyle{ e }[/math] tak, aby spełniała warunki [math]\displaystyle{ \gcd (e, \Phi) = 1 }[/math] i [math]\displaystyle{ 2 \lt e \lt \Phi }[/math]
    • zaleca się, aby [math]\displaystyle{ e \geqslant 65537 }[/math]
  2. Z lematu Bézouta (zobacz C73) istnieją takie liczby całkowite [math]\displaystyle{ d }[/math] i [math]\displaystyle{ k }[/math], że [math]\displaystyle{ d e + k \Phi = 1 }[/math]. Liczbę [math]\displaystyle{ d }[/math] wyliczamy ze wzoru [math]\displaystyle{ d = d_0 + \Phi t }[/math], gdzie [math]\displaystyle{ d_0 }[/math] (oraz [math]\displaystyle{ k_0 }[/math]) otrzymujemy, wykorzystując w PARI/GP funkcję gcdext(e, Φ) (zobacz C78)
    • [math]\displaystyle{ d }[/math] wybieramy tak, aby była liczbą dodatnią, wtedy [math]\displaystyle{ k }[/math] musi być liczbą ujemną
    • [math]\displaystyle{ d }[/math] nie może być zbyt małą liczbą; pokazano[7], że powinno być [math]\displaystyle{ d \gt m^{0.292} }[/math]
  3. Metoda szyfrowania RSA wymaga trzech liczb: [math]\displaystyle{ m }[/math], [math]\displaystyle{ e }[/math], [math]\displaystyle{ d }[/math]. Liczba [math]\displaystyle{ d }[/math] jest tajna. Podobnie tajne są liczby [math]\displaystyle{ p }[/math], [math]\displaystyle{ q }[/math], [math]\displaystyle{ \Phi }[/math], ale te liczby można po prostu skasować po wyliczeniu [math]\displaystyle{ d }[/math]
  4. Szyfrowaną wiadomość przekształcamy w ciąg cyfr. W przypadku długich wiadomości może być konieczny podział ciągu cyfr na bloki. Tworzymy w ten sposób liczbę [math]\displaystyle{ B }[/math]. Zakładamy, że [math]\displaystyle{ B \lt m }[/math]
  5. Szyfrowanie. Zakodowany tekst jest wynikiem operacji: [math]\displaystyle{ C = R_m (B^e) }[/math], gdzie [math]\displaystyle{ R_m (B^e) }[/math] oznacza resztę z dzielenia liczby [math]\displaystyle{ B^e }[/math] przez [math]\displaystyle{ m }[/math]
    • zauważmy, że: [math]\displaystyle{ C \equiv B^e \!\! \pmod{m} }[/math]
  6. Odszyfrowanie. Odkodowany tekst otrzymujemy, obliczając: [math]\displaystyle{ B = R_m (C^d) }[/math]
  7. Dowód poprawności metody wynika z twierdzenia Q12
    • [math]\displaystyle{ R_m (C^d) \equiv C^d \equiv (B^e)^d \equiv B^{e d} \equiv B^{- k \Phi + 1} \equiv B^{- k (p - 1) (q - 1) + 1} \equiv B \!\! \pmod{m} }[/math]
    • ponieważ [math]\displaystyle{ k \lt 0 }[/math], to [math]\displaystyle{ - k }[/math] jest liczbą dodatnią i możemy zastosować twierdzenie Q12
    • ponieważ [math]\displaystyle{ B \lt m }[/math], to [math]\displaystyle{ R_m (C^d) = B }[/math]
  8. Para liczb [math]\displaystyle{ (m, e) }[/math] jest nazywana kluczem publicznym – służy do szyfrowania i może być dostępna dla każdego.
  9. Para liczb [math]\displaystyle{ (m, d) }[/math] jest nazywana kluczem prywatnym – służy do odszyfrowania. Liczba [math]\displaystyle{ d }[/math] jest tajna – osoba, która ją wykradnie, będzie mogła odczytywać wysyłane do nas wiadomości


Przykład Q13
Prosty przykład: niech wysyłaną wiadomością będzie słowo [math]\displaystyle{ \text{YES} }[/math]. Zamianę liter na ciąg cyfr dokonamy, przypisując każdej literze jej numer w alfabecie np.: [math]\displaystyle{ A \longrightarrow 01 }[/math], [math]\displaystyle{ B \longrightarrow 02 }[/math], ... , [math]\displaystyle{ Z \longrightarrow 26 }[/math], czyli [math]\displaystyle{ \text{YES}\longrightarrow 250519 }[/math], zatem musimy zaszyfrować liczbę [math]\displaystyle{ 250519 }[/math].

Niech [math]\displaystyle{ p = 1009 }[/math], [math]\displaystyle{ q = 1013 }[/math], [math]\displaystyle{ e = 1019 }[/math]. Znajdujemy [math]\displaystyle{ m = p q = 1022117 }[/math], [math]\displaystyle{ \Phi = (p - 1) (q - 1) = 1020096 }[/math], [math]\displaystyle{ d = 397427 }[/math]. Klucz publiczny [math]\displaystyle{ (m, e) }[/math], klucz prywatny [math]\displaystyle{ (m, d) }[/math]. Zaszyfrowana wiadomość to [math]\displaystyle{ R_m (250519^e) = 560222 }[/math]. Odszyfrowując, otrzymujemy [math]\displaystyle{ R_m (560222^d) = 250519 }[/math]. Tak, jak być powinno.


Uwaga Q14
Bezpieczeństwo metody polega na wyborze tak dużych liczb pierwszych [math]\displaystyle{ p }[/math] i [math]\displaystyle{ q }[/math], aby faktoryzacja ich iloczynu [math]\displaystyle{ m }[/math] leżała poza możliwościami współczesnych komputerów i stosowanych algorytmów. Choć klucz publiczny [math]\displaystyle{ (m, e) }[/math] służący do szyfrowania nie jest tajny i może być udostępniany wszystkim, to poznanie klucza prywatnego, czyli liczby [math]\displaystyle{ d }[/math], jest praktycznie niemożliwe.

Liczba [math]\displaystyle{ d }[/math] wynika z rozwiązania równania [math]\displaystyle{ d e + k \Phi = 1 }[/math], ale aby obliczyć [math]\displaystyle{ \Phi = (p - 1) (q - 1) }[/math] musimy znać rozkład liczby [math]\displaystyle{ m }[/math] na czynniki pierwsze. Obecnie nie istnieją dostatecznie szybkie sposoby znajdowania rozkładu dużych liczb na czynniki pierwsze. Możemy łatwo sprawdzić, czy liczba [math]\displaystyle{ m = p q }[/math] jest liczbą złożoną, ale jeśli tak jest, to poznanie jej czynników jest dla dostatecznie dużych [math]\displaystyle{ m }[/math] niemożliwe.


Uwaga Q15 (generowanie liczb [math]\displaystyle{ m, e, d }[/math])
Przyjmując proste założenia co do liczb pierwszych [math]\displaystyle{ p, q }[/math] (przyjęliśmy, że [math]\displaystyle{ 1.8 p \lt q \lt 2.2 p }[/math]) oraz zakładając, że [math]\displaystyle{ d \gt m^{2 / 3} }[/math] napisaliśmy prosty program do generowania klucza publicznego i prywatnego. Parametr w określa, ile cyfr w układzie dziesiętnym będą miały liczby [math]\displaystyle{ p, q }[/math]. Wybór w > 500 gwarantuje wygenerowanie liczby [math]\displaystyle{ m }[/math], której rozkład na czynniki pierwsze nie powinien być możliwy przez wiele lat. Ostatnie (znane) osiągnięcie faktoryzacji, to rozkład 250-cyfrowej liczby [math]\displaystyle{ m = p q }[/math] na czynniki pierwsze[8].

Pokaż kod
RSAkeys(w) = 
\\ parametr w > 1 określa, ile cyfr w układzie dziesiętnym będą miały liczby p, q
{
local(d, e, m, p, Phi, q);
setrand(getwalltime());  \\ ustawiamy ziarno (ang. seed) generatora liczb losowych
p = 1;
q = 0;
while( !isprime(p)  ||  !isprime(q),
       while( q < 1.8 * p  ||  q > 2.2 * p, 
              p = randomprime( [10^(w - 1), 10^w] ); 
              q = randomprime( [10^(w - 1), 10^w] );
            );
     );
m = p * q;
Phi = (p - 1) * (q - 1);
d = -1;
while( d < m^(2/3), 
       e = randomprime( [10^10, 10^15] );
       if( gcd(e, Phi) > 1, next() );
       d = gcdext(e, Phi)[1];
     );
return([m, e, d]);
}
PrintRSAkeys(w) = 
{
local(V);
V = RSAkeys(w);
print("m = ", V[1]);
print("e = ", V[2]);
print("d = ", V[3]);
}


Uwaga Q16 (zamiana tekstu na liczbę i odwrotnie)
W przypadku profesjonalnych programów szyfrujących wykorzystujących metodę RSA szyfrowany jest cały plik, który jest przecież ciągiem zer i jedynek. Oprogramowanie dzieli taki plik na odpowiednich rozmiarów bloki [math]\displaystyle{ B_j }[/math] i każdy jest szyfrowany kluczem publicznym [math]\displaystyle{ (m, e) }[/math]. Możemy w ten sposób szyfrować zdjęcia, filmy, tekst w dowolnym języku itd.

Ponieważ napisanie takiego oprogramowania wykraczałoby poza potrzeby tego omówienia, ale z drugiej strony chcemy udostępnić Czytelnikowi przykłady bardziej skomplikowane niż szyfrowanie słowa [math]\displaystyle{ \text{YES} }[/math], to postanowiliśmy ograniczyć się do szyfrowania tekstu, który zawiera jedynie znaki ASCII[9].

Aby efektywnie korzystać z szyfrowania RSA potrzebne będą nam programy, które przetworzą taki tekst na liczbę i odwrotnie. Poniżej przedstawiamy dwie bardzo proste funkcje: pierwsza funkcja zamienia znaki ASCII od 32 do 126 na liczbę (każdemu znakowi przypisywane są dwie cyfry), a druga funkcja zamienia wygenerowaną przez pierwszą funkcję liczbę na odpowiadający tej liczbie tekst.

Założenie, że nasza wiadomość zawiera tylko znaki ASCII od 32 do 126, jest bardzo ważne. Oznacza to, że taki tekst przetworzony przez funkcję TextToNumber() na liczbę, zostanie odtworzony przez funkcję NumberToText() w niezmienionej postaci. Nie będzie tak, jeśli wystąpią inne znaki: każdy z takich znaków zostanie zamieniony na spacje (np. każda polska litera zostanie zamieniona na dwie spacje). Nie oznacza to, że nie można korzystać z tych funkcji, ale jeśli szyfrujemy podpisaną wiadomość, to zgodność tekstów ma zasadnicze znaczenie.

Pokaż kod
TextToNumber( s ) = 
\\ zamienia znaki ASCII od 32 do 126 na liczbę
{
local(a, b, k, len, txt, V);
V = Vecsmall(s);
len = length(V);
txt = "";
k = 0;
while( k++ <= len,
       a = V[k];
       b = "01";  \\ spacja – wstawiamy jeżeli a jest poza zakresem
       if( a >= 32  &&  a <= 40, b = Str("0", a - 31) );
       if( a >= 41  &&  a <= 126, b = Str(a - 31) );
       txt = Str(txt, b);
     );
return( eval(txt) );
}
NumberToText( n ) = 
{
local(a, k, len, txt, V);
len = length(Str(n));
if( len % 2 == 1, len++ ); \\ "zgubione" zero na początku
len = len / 2;
V = vector(len);
k = len + 1;
while( k-- >= 1,
       a = n % 100;
       n = floor(n / 100);
       V[k] = a + 31;
     );
txt = strchr(V);
return(txt);
}



Uwaga Q17
Jeżeli mamy już funkcje zamieniające tekst na liczbę i odwrotnie, to napisanie w PARI/GP programów do szyfrowania i deszyfrowania metodą RSA jest bardzo proste.

Pokaż kod
RSAencode(m, e, s) = 
\\ szyfrujemy string s
{
local(B, C);
B = TextToNumber(s);
C = lift( Mod(B, m)^e );
print(C);
}
RSAdecode(m, d, C) = 
\\ deszyfrujemy liczbę C
{
local(B, s);
B = lift( Mod(C, m)^d );
s = NumberToText(B);
print(s);
}



Przykład Q18
Kładąc w = 50 w funkcji RSAkeys(w) otrzymaliśmy

m = 2173471545652309346779542101680852446325835148920429701148920590128959176663355134192839060494750117
e = 3675359337253
d = 308186586218659991253427464678921309369969889382350078327142348395702895999753492453847408362677933

Liczba m ma 100 cyfr. Podamy teraz prosty przykład z polskimi literami. Zakodujemy i odkodujemy tekst (35 znaków)

Lepszy na wolności kęsek lada jaki.

Zamieniając tekst na liczbę – funkcją TextToNumber(s) – otrzymujemy liczbę 74-cyfrową

B = 45708184919001796601888077798001016874017601018470760177666966017566767415

Jest tak, bo każdy znak tekstu został zamieniony na dwie cyfry, ale każda z polskich liter "ś" i "ę" została zamieniona na dwie spacje i każdej z tych liter odpowiadają cztery cyfry "0101". Zauważmy, że B < m tak, jak być powinno.

Korzystając z funkcji RSAencode(m, e, s), dostajemy od razu zakodowany tekst

C = 1883258467778511884133977054466089742750188942420326552221154007622797635139655819975338109849673552

Po odkodowaniu funkcją RSAdecode(m, d, C), otrzymujemy

Lepszy na wolno  ci k  sek lada jaki.

Polskie litery zostały zastąpione przez dwie spacje.


Czytelnikowi pozostawiamy odszyfrowanie podanej niżej zakodowanej wiadomości. Ze względu na rozmiar musieliśmy podzielić tekst i otrzymaliśmy trzy zakodowane bloki.

C1 = 1228411078235780067165277802337600665865387220034514894292654793454492777859429937501850347835450261
C2 = 1212270919532485597119464911345613794658433495925582794819870422454753698249874400827689168074862675
C3 = 1407997868763350498310642273976637553443290951270357250985396471705600151258961305510222246198960667


Uwaga Q19
Omówiliśmy dokładnie metodę szyfrowania RSA i Czytelnik powinien mieć już jasność, że metodą tą możemy szyfrować tylko liczby. Jeśli chcemy zaszyfrować tekst, to musi najpierw zostać zapisany w postaci liczby (ciągu cyfr). Podaliśmy też dwie proste metody takiej zamiany (zobacz Q13 i Q16).

W dalszej części artykułu pisząc o szyfrowaniu metodą RSA, będziemy mieli najczęściej na myśli dwie czynności wykonywanie łącznie: zamianę tekstu na liczbę (ustaloną wcześniej metodą) i właściwą operację szyfrowania. Podobnie pisząc o odszyfrowaniu, też zazwyczaj będziemy mieli myśli dwie czynności: właściwą operację odszyfrowywania i zamianę otrzymanej liczby na tekst.


Uwaga Q20
Zwróćmy uwagę na to, że w przypadku pomyłki i zaszyfrowania wiadomości naszym kluczem prywatnym [math]\displaystyle{ (m, d) }[/math] możliwe będzie jej odczytanie przez każdą osobę, która zna nasz klucz publiczny [math]\displaystyle{ (m, e) }[/math]. Istotnie, niech [math]\displaystyle{ C = R_m (B^d) }[/math]. Łatwo pokażemy, że [math]\displaystyle{ B = R_m (C^e) }[/math].

[math]\displaystyle{ R_m (C^e) \equiv C^e \equiv (B^d)^e \equiv B^{e d} \equiv B^{- k \Phi + 1} \equiv B^{- k (p - 1) (q - 1) + 1} \equiv B \!\! \pmod{m} }[/math]

Fakt ten wykorzystamy do stworzenia podpisu wiadomości.



Kryptograficzne funkcje haszujące

Definicja Q21
Funkcja haszująca[10] przypisuje każdemu ciągowi bitów o dowolnej (ale skończonej) długości ciąg bitów o stałej długości.


Przykład Q22
Bardzo prosta funkcja haszująca przypisuje każdemu ciągowi osiem pierwszych bitów tego ciągu (w przypadku, gdy ciąg jest za krótki, wystarczy powtórzyć go odpowiednią liczbę razy). Tak określona funkcja nie jest dobrą funkcją haszującą i ze wszystkich wymagań (które wymienimy niżej) spełnia tylko jeden: możemy szybko obliczyć wynik.

Innym przykładem funkcji haszującej może być funkcja, która oblicza sumę kodów ASCII kolejnych znaków modulo [math]\displaystyle{ 256 }[/math]. Ta funkcja, podobnie jak poprzednia, jedynie szybko oblicza wynik.

Druga funkcja jest lepsza od pierwszej, bo każdy znak tekstu wpływa na uzyskany wynik. Co prawda ciągi znaków, których suma kodów ASCII wynosi 256 (np. "8dd") możemy dodawać bezkarnie, jednak uwzględniając, że wiadomość nie jest ciągiem przypadkowych znaków, modyfikacja wiadomości tak, aby hasz pozostał niezmieniony, będzie wymagała pewnego wysiłku.


Uwaga Q23
Od dobrej funkcji haszującej oczekujemy, że będzie spełniała następujące warunki

  • będzie szybko obliczać wynik
  • (jednokierunkowość) dla zadanej wartości hasza [math]\displaystyle{ h }[/math] znalezienie jakiegokolwiek ciągu bitów [math]\displaystyle{ m }[/math] takiego, że [math]\displaystyle{ h = \mathop{\text{hash}}(m) }[/math] powinno być bardzo trudne
  • (słaba odporność na kolizje) dla zadanego ciągu bitów [math]\displaystyle{ m_1 }[/math] znalezienie jakiegokolwiek ciągu bitów [math]\displaystyle{ m_2 \neq m_1 }[/math] takiego, że [math]\displaystyle{ \mathop{\text{hash}}(m_2) = \mathop{\text{hash}}(m_1) }[/math] powinno być bardzo trudne
  • (silna odporność na kolizje) znalezienie jakichkolwiek dwóch ciągów bitów [math]\displaystyle{ m_1 }[/math] i [math]\displaystyle{ m_2 }[/math] takich, że [math]\displaystyle{ \mathop{\text{hash}}(m_1) = \mathop{\text{hash}}(m_2) }[/math] powinno być bardzo trudne

W praktyce oznacza to, że jeżeli dwa łańcuchy mają taki sam hasz, to są one identyczne. To właśnie ta własność decyduje o przydatności funkcji haszującej dla podpisu elektronicznego i innych zastosowań.


Przykład Q24 (zastosowanie funkcji haszujących)
Jeśli chcemy upewnić się, czy przesłana mailem wiadomość nie zastała zmieniona, to wystarczy, że telefonicznie podamy odbiorcy hasz wiadomości.

Hasło podawane przy logowaniu powinno być haszowane, a system powinien przechowywać jedynie hasz hasła tak, aby samo hasło pozostawało nikomu nieznane.

Udostępniając do pobrania plik, możemy udostępnić również jego hasz. Umożliwi to łatwe sprawdzenie użytkownikowi, czy pobrany plik nie został uszkodzony.


Uwaga Q25 (przykłady funkcji haszujących)
Istnieje wiele wykorzystywanych w praktyce funkcji haszujących. Najbardziej znane to: CRC[11], MD5[12], SHA-1[13] oraz funkcje ze standardu SHA-2[14]: SHA-224, SHA-256, SHA-384, SHA-512

Linux udostępnia wypisane wyżej funkcje jako cksum (CRC), md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum.

Na stronie GitHub – Online Tools znajdziemy wiele funkcji haszujących. Możemy policzyć wartości wybranej funkcji dla dowolnego tekstu i dla plików. Zauważmy, że wiele edytorów tekstu automatycznie dodaje znak końca linii[15] (LF) o kodzie ASCII równym 10 (szesnastkowo 0a) na końcu pliku. Może to powodować różnice przy obliczaniu hasza dla tekstu i dla pliku tekstowego zawierającego ten sam tekst.


Przykład Q26
Dla przykładu rozważmy, często używaną, funkcję haszującą SHA-256. Generuje ona 256-bitowy hasz, który zapisujemy, podając 64 cyfry w zapisie szesnastkowym. Każdą cyfrę w układzie szesnastkowym można zapisać w postaci 4 zer i jedynek w układzie dwójkowym (czterech bitów).

[math]\displaystyle{ 0 = 0000, \ldots, 9 = 1001, a = 1010, \ldots, f = 1111 }[/math]

Dla tekstu

Polskie litery i cyfry: ąćęłńóśźżĄĆĘŁŃÓŚŹŻ 0123456789

otrzymujemy hasz

5a86397d5e16611466e82376cc9f4d367ecbcd4af6d4418a5d3a130e8ad9d98d

Czytelnik powinien zwrócić uwagę, że nawet niewielka zmiana tekstu (np. zmiana lub dodanie jednego znaku) spowoduje wygenerowanie zupełnie innego hasza.



Podpisywanie dokumentów jawnych

Uwaga Q27
Zauważmy, że przekazywanie wiadomości (jawnych lub nie) wymaga wcześniejszego ustalenia sposobu komunikowania się. Może to być konto mailowe (jawne lub używane tylko do kontaktów tajnych), umówiona skrytka itd. Wynika stąd, że odbiorca zawsze zna nadawcę (wie, od kogo otrzymał przesyłkę).

Ponieważ musimy liczyć się z tym, że ustalony kanał łączności może zostać przejęty, a przekaz zmieniony, to stosujemy różnego rodzaju zabezpieczenia, których celem jest ochrona integralności przekazu.


Uwaga Q28
Powiedzmy, że Bolek chce przekazać ważny dokument do Urzędu. Jednak Urząd chce mieć pewność, że tak ważny dokument rzeczywiście sporządził Bolek, a nie ktoś inny, kto tylko pod Bolka się podszywa. Oczywiście można taki dokument przekazać osobiście, ale co zrobić w sytuacji, gdy jest to niemożliwe, a dostępny jest internet?

Jeśli Bolek potrafi szyfrować wiadomości metodą RSA i udostępnił swój klucz publiczny [math]\displaystyle{ (m, e) }[/math] Urzędowi, to może postąpić następująco

  1. sporządzić ów ważny dokument (powiedzmy DokB) w postaci pliku (ewentualnie papierowy dokument zeskanować)
  2. obliczyć hasz pliku DokB: [math]\displaystyle{ \; h_B = \mathop{\text{SHA256}}( \text{DokB} ) }[/math]
  3. zaszyfrować hasz [math]\displaystyle{ h_B }[/math] swoim kluczem prywatnym [math]\displaystyle{ (m, d) }[/math] (zobacz Q20)
    • zaszyfrowany hasz [math]\displaystyle{ h_B }[/math] jest podpisem Bolka (co za chwilę stanie się jasne)
  4. tak zaszyfrowany hasz wpisać w treści maila i załączyć plik DokB


Jak przebiega weryfikacja odebranej wiadomości?

  1. Urząd odbiera mail od Bolka i pobiera załącznik (nazwijmy go DokU, bo nie wiemy, czy nie został zmieniony)
  2. Urząd oblicza hasz załączonego pliku DokU: [math]\displaystyle{ \; h_U = \mathop{\text{SHA256}}( \text{DokU} ) }[/math]
  3. kluczem publicznym Bolka Urząd odszyfrowuje otrzymany w mailu zaszyfrowany hasz [math]\displaystyle{ h_B }[/math] (zobacz Q20)
  4. z równości [math]\displaystyle{ h_B = h_U }[/math] wynika, że dokumenty DokB i DokU są identyczne (zobacz Q23)


Jest tak, ponieważ z równości [math]\displaystyle{ h_B = h_U }[/math] wynika, że zaszyfrowany hasz [math]\displaystyle{ h_B }[/math] musiał pochodzić od Bolka, bo został zaszyfrowany jego kluczem prywatnym, do którego nikt, poza nim, nie ma dostępu. Dlatego zaszyfrowany kluczem prywatnym Bolka hasz [math]\displaystyle{ h_B }[/math] jest tym samym, co jego podpis i potwierdza to, że plik DokB (którego hasz jest równy [math]\displaystyle{ h_B }[/math]) został sporządzony przez Bolka.

Ujmując inaczej, każdy może przedstawić się w mailu jako Bolek, dołączyć spreparowany plik, policzyć hasz tego pliku, ale nie będzie w stanie zaszyfrować tego hasza kluczem prywatnym Bolka, bo klucz ten jest tajny i niedostępny dla nikogo poza Bolkiem.



Podpisywanie dokumentów tajnych

Uwaga Q29
Powiedzmy, że Bolek ma ważną informację i chce ją przekazać do Agencji. Oczywiście informacji nie może przeczytać nikt inny, a Agencja musi mieć pewność, że źródłem tej ważnej informacji jest rzeczywiście Bolek, a nie ktoś inny, kto tylko pod Bolka się podszywa. Tym razem Bolek na pewno potrafi szyfrować wiadomości metodą RSA, a jego klucz publiczny [math]\displaystyle{ (m, e) }[/math] jest z pewnością znany Agencji. Co więcej, Bolek zna klucz publiczny Agencji [math]\displaystyle{ (M, E) }[/math], którego ma używać do komunikowania się z Agencją. W tym przypadku Bolek postępuje następująco

  1. oblicza hasz wiadomości [math]\displaystyle{ h_B = \mathop{\text{SHA256}}( \text{tekst} ) }[/math]
  2. szyfruje hasz [math]\displaystyle{ h_B }[/math] swoim kluczem prywatnym [math]\displaystyle{ (m, d) }[/math]
  3. umieszcza zaszyfrowany hasz [math]\displaystyle{ h_B }[/math] jako ostatnią linię tekstu wiadomości
  4. szyfruje całość (tekst wiadomości + zaszyfrowany hasz [math]\displaystyle{ h_B }[/math]) kluczem publicznym Agencji [math]\displaystyle{ (M, E) }[/math]
  5. umieszcza cały zaszyfrowany tekst w pliku i wysyła jako załącznik maila do Agencji

Agencja

  1. pobiera załącznik
  2. tekst z załącznika odszyfrowuje kluczem prywatnym Agencji [math]\displaystyle{ (M, D) }[/math]
  3. z ostatniej linii pliku odczytuje zaszyfrowany hasz [math]\displaystyle{ h_A }[/math] tekstu otrzymanej wiadomości
  4. deszyfruje hasz [math]\displaystyle{ h_A }[/math] wiadomości kluczem publicznym Bolka [math]\displaystyle{ (m, e) }[/math]
  5. oblicza hasz [math]\displaystyle{ h_B }[/math] wiadomości od Bolka
  6. równość [math]\displaystyle{ h_B = h_A }[/math] potwierdza, że wiadomość nie została zmieniona i przekazał ją do Agencji Bolek

Zauważmy, że klucz publiczny Agencji może być wiedzą poufną, ale z pewnością nie jest tak dobrze strzeżony, jak klucze prywatne. Agencja nie może zakładać, że zaszyfrowany jej kluczem publicznym plik nie został spreparowany. Dopiero po odszyfrowaniu pliku, obliczeniu hasza wiadomości i potwierdzenia zgodności tego hasza z haszem zapisanym w ostatniej linii pliku (który został zaszyfrowany kluczem prywatnym Bolka) Agencja ma pewność, że plik stworzył i wysłał Bolek.


Uwaga Q30
Zwróćmy uwagę, że jeżeli korzystamy z funkcji TextToNumber() i NumberToText() (zobacz Q16), a jednocześnie chcemy podpisywać szyfrowane wiadomości, to wiadomości nie mogą zawierać znaków innych niż znaki ASCII od 32 do 126.

Jest tak dlatego, że funkcja TextToNumber() zgubi informację o innych znakach w wiadomości, a funkcja NumberToText() już tej informacji nie odtworzy. Zatem hasz wysyłanej wiadomości i hasz otrzymanej wiadomości (po odszyfrowaniu) nigdy nie będą identyczne w przypadku użycia znaków innych niż znaki ASCII od 32 do 126.








Przypisy

  1. Whitfield Diffie and Martin E. Hellman, New Directions in Cryptography, IEEE Transactions on Information Theory, Vol. 22, No. 6, 1976 (LINK)
  2. Wikipedia, Protokół Diffiego-Hellmana, (Wiki-pl), (Wiki-en)
  3. Liczba [math]\displaystyle{ g }[/math] powinna (ale nie musi) być generatorem modulo [math]\displaystyle{ p }[/math]. Dlaczego tak jest, wyjaśnimy w dalszej części tekstu.
  4. Wikipedia, Funkcja φ, (Wiki-pl), (Wiki-en)
  5. R. Rivest, A. Shamir and L. Adleman, A Method for Obtaining Digital Signatures and Public-Key Cryptosystems, Communications of the ACM, Volume 21, Issue 2, Feb. 1978, pp. 120-126
  6. Wikipedia, RSA (kryptografia), (Wiki-pl), (Wiki-en)
  7. Dan Boneh and Glenn Durfee, Cryptanalysis of RSA with Private Key d Less Than N0.292, IEEE Transactions on Information Theory, Vol. 46, No. 4, 2000
  8. Wikipedia, RSA numbers, (Wiki-en)
  9. Wikipedia, ASCII, (Wiki-pl), (Wiki-en)
  10. Wikipedia, Cryptographic hash function, (Wiki-en), (Wiki-pl)
  11. Wikipedia, Cykliczny kod nadmiarowy, (Wiki-pl), (Wiki-en)
  12. Wikipedia, MD5, (Wiki-pl), (Wiki-en)
  13. Wikipedia, SHA-1, (Wiki-pl), (Wiki-en)
  14. Wikipedia, SHA-2, (Wiki-pl), (Wiki-en)
  15. Wikipedia, Koniec linii, (Wiki-pl), (Wiki-en)