<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Math on kenji.blog</title><link>http://kenji.blog/fr/tags/math/</link><description>Recent content in Math on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 22:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/fr/tags/math/index.xml" rel="self" type="application/rss+xml"/><item><title>Fondements et implémentation de la cryptographie à l'aide du petit théorème de Fermat</title><link>http://kenji.blog/fr/p/fermats-little-theorem-cryptography-implementation/</link><pubDate>Fri, 11 Sep 2026 22:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/fermats-little-theorem-cryptography-implementation/</guid><description>&lt;img src="http://kenji.blog/p/fermats-little-theorem-cryptography-implementation/img/eyecatch.jpg" alt="Featured image of post Fondements et implémentation de la cryptographie à l'aide du petit théorème de Fermat" />&lt;h2 id="1-introduction--le-mystère-mathématique-qui-sous-tend-la-cryptographie-moderne">1. Introduction : Le mystère mathématique qui sous-tend la cryptographie moderne
&lt;/h2>&lt;p>Dans la société numérique d&amp;rsquo;aujourd&amp;rsquo;hui, et particulièrement dans les communications sur Internet, le &amp;ldquo;chiffrement&amp;rdquo; est devenu une technologie fondamentale indispensable. Le fait que nous puissions naviguer en toute sécurité sur des sites web via HTTPS dans nos navigateurs, effectuer des transactions financières par le biais des services bancaires en ligne, et avoir des échanges privés sur des applications de messagerie est dû aux protocoles cryptographiques basés sur des théories mathématiques avancées fonctionnant en arrière-plan. Parmi ceux-ci, la &amp;ldquo;cryptographie à clé publique&amp;rdquo; joue un rôle particulièrement important, dont le représentant le plus célèbre est le &lt;strong>chiffrement RSA&lt;/strong>.&lt;/p>
&lt;p>La sécurité et la validité de nombreux algorithmes cryptographiques, y compris RSA, dépendent fortement d&amp;rsquo;un théorème extrêmement beau et puissant découvert par le mathématicien français du 17e siècle, Pierre de Fermat. Il s&amp;rsquo;agit du &lt;strong>petit théorème de Fermat (Fermat&amp;rsquo;s Little Theorem)&lt;/strong>. De plus, le théorème de Leonhard Euler, qui généralise ce théorème, joue également un rôle décisif dans la théorie cryptographique.&lt;/p>
&lt;p>Cet article explique en détail, depuis les bases, comment la découverte mathématique pure qu&amp;rsquo;est le petit théorème de Fermat s&amp;rsquo;applique aux technologies cryptographiques pratiques modernes, en particulier aux &amp;ldquo;tests de primalité&amp;rdquo; et au &amp;ldquo;chiffrement RSA&amp;rdquo;. Il s&amp;rsquo;agit d&amp;rsquo;un guide technique très détaillé couvrant tout, des preuves mathématiques, aux mécanismes de chiffrement et de déchiffrement, jusqu&amp;rsquo;à l&amp;rsquo;implémentation concrète des algorithmes en C++ et Python.&lt;/p>
&lt;hr>
&lt;h2 id="2-bases-des-congruences-et-de-larithmétique-modulaire">2. Bases des congruences et de l&amp;rsquo;arithmétique modulaire
&lt;/h2>&lt;p>Pour comprendre le petit théorème de Fermat, vous devez d&amp;rsquo;abord vous familiariser avec le concept mathématique d&amp;rsquo;&amp;ldquo;arithmétique modulaire (congruences)&amp;rdquo;. L&amp;rsquo;arithmétique modulaire est un système de calcul qui se concentre sur le &amp;ldquo;reste&amp;rdquo; lorsqu&amp;rsquo;un nombre est divisé par un nombre fixe (appelé module). Comme il s&amp;rsquo;agit d&amp;rsquo;un calcul similaire à celui du cadran d&amp;rsquo;une horloge (qui fait un tour en 12 heures), on l&amp;rsquo;appelle aussi parfois &amp;ldquo;mathématiques de l&amp;rsquo;horloge&amp;rdquo;.&lt;/p>
&lt;p>Lorsque le reste de la division de deux entiers $a$ et $b$ par un entier positif $n$ est égal, on l&amp;rsquo;écrit mathématiquement comme suit :&lt;/p>
$$
a \equiv b \pmod n
$$
&lt;p>Cela se lit &amp;ldquo;$a$ et $b$ sont congrus modulo $n$&amp;rdquo;. Par exemple, le reste de 17 divisé par 5 est 2, et le reste de 12 divisé par 5 est également 2. Par conséquent, on peut écrire ce qui suit :&lt;/p>
$$
17 \equiv 12 \pmod 5 \equiv 2 \pmod 5
$$
&lt;p>En arithmétique modulaire, les quatre opérations arithmétiques habituelles (addition, soustraction, multiplication) s&amp;rsquo;appliquent telles quelles.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Addition&lt;/strong> : Si $a \equiv b \pmod n$ et $c \equiv d \pmod n$, alors $a + c \equiv b + d \pmod n$&lt;/li>
&lt;li>&lt;strong>Soustraction&lt;/strong> : Si $a \equiv b \pmod n$ et $c \equiv d \pmod n$, alors $a - c \equiv b - d \pmod n$&lt;/li>
&lt;li>&lt;strong>Multiplication&lt;/strong> : Si $a \equiv b \pmod n$ et $c \equiv d \pmod n$, alors $a \times c \equiv b \times d \pmod n$&lt;/li>
&lt;li>&lt;strong>Exponentiation&lt;/strong> : Si $a \equiv b \pmod n$, alors pour tout entier naturel $k$, $a^k \equiv b^k \pmod n$&lt;/li>
&lt;/ol>
&lt;p>Cependant, il faut faire attention à la &lt;strong>division&lt;/strong>. En général, même si $a \times c \equiv b \times c \pmod n$, vous ne pouvez pas diviser les deux côtés par $c$ pour obtenir $a \equiv b \pmod n$. Cela n&amp;rsquo;est vrai que si $c$ et $n$ sont premiers entre eux (leur plus grand commun diviseur est 1). Ce concept d&amp;rsquo;&amp;ldquo;inverse modulaire&amp;rdquo; devient extrêmement important dans la génération de clés pour le chiffrement RSA, que nous aborderons plus tard.&lt;/p>
&lt;hr>
&lt;h2 id="3-contexte-mathématique-et-preuve-du-petit-théorème-de-fermat">3. Contexte mathématique et preuve du petit théorème de Fermat
&lt;/h2>&lt;p>Maintenant que nous avons couvert les bases de l&amp;rsquo;arithmétique modulaire, examinons le sujet principal, le petit théorème de Fermat.&lt;/p>
&lt;h3 id="31-définition-du-théorème">3.1 Définition du théorème
&lt;/h3>&lt;p>Le petit théorème de Fermat est formulé comme suit :&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Petit théorème de Fermat (Fermat&amp;rsquo;s Little Theorem)&lt;/strong>
Soit $p$ un nombre premier et $a$ un entier quelconque qui n&amp;rsquo;est pas un multiple de $p$ (c&amp;rsquo;est-à-dire que $a$ et $p$ sont premiers entre eux). Alors, la congruence suivante est vraie :
&lt;/p>
$$ a^{p-1} \equiv 1 \pmod p $$
&lt;/blockquote>
&lt;p>Il est également courant d&amp;rsquo;exprimer ce théorème sous une forme valable pour tout entier $a$, en supprimant la condition &amp;ldquo;$a$ n&amp;rsquo;est pas un multiple de $p$&amp;rdquo;. Dans ce cas, on multiplie les deux côtés par $a$, ce qui donne :&lt;/p>
$$
a^p \equiv a \pmod p
$$
&lt;h3 id="32-vérification-par-des-exemples-concrets">3.2 Vérification par des exemples concrets
&lt;/h3>&lt;p>Vérifions si le théorème se vérifie vraiment en utilisant des nombres concrets.
Soit le nombre premier $p = 5$. Alors $p-1 = 4$. Nous choisissons un entier pour $a$ qui n&amp;rsquo;est pas un multiple de $p$.&lt;/p>
&lt;ul>
&lt;li>Pour $a = 2$ : $2^{5-1} = 2^4 = 16$. $16 \div 5 = 3$ avec un reste de $1$. Donc $16 \equiv 1 \pmod 5$. (Vérifié)&lt;/li>
&lt;li>Pour $a = 3$ : $3^{5-1} = 3^4 = 81$. $81 \div 5 = 16$ avec un reste de $1$. Donc $81 \equiv 1 \pmod 5$. (Vérifié)&lt;/li>
&lt;li>Pour $a = 4$ : $4^{5-1} = 4^4 = 256$. $256 \div 5 = 51$ avec un reste de $1$. Donc $256 \equiv 1 \pmod 5$. (Vérifié)&lt;/li>
&lt;/ul>
&lt;p>Ainsi, quel que soit le $a$ que vous choisissez (à condition qu&amp;rsquo;il ne soit pas un multiple de 5), le reste de sa 4ème puissance divisée par 5 sera toujours 1. Cela ressemble à de la magie, mais cela découle des magnifiques propriétés des nombres premiers.&lt;/p>
&lt;h3 id="33-preuve-mathématique-du-théorème">3.3 Preuve mathématique du théorème
&lt;/h3>&lt;p>Pourquoi cela est-il vrai ? Nous présentons ici une preuve élégante utilisant l&amp;rsquo;ensemble des classes de restes.&lt;/p>
&lt;p>Considérons l&amp;rsquo;ensemble $S = \{1, 2, 3, \dots, p-1\}$. Ce sont les représentants des entiers dont les restes de la division par $p$ vont de $1$ à $p-1$.
Considérons maintenant un nouvel ensemble $T$ obtenu en multipliant chaque élément par un entier $a$ qui est premier avec $p$.
&lt;/p>
$$ T = \{1a, 2a, 3a, \dots, (p-1)a\} $$
&lt;p>Considérons les restes de chaque élément de cet ensemble $T$ divisé par $p$. Étonnamment, ces restes, bien que leur ordre puisse changer, correspondent exactement à l&amp;rsquo;ensemble des éléments de l&amp;rsquo;ensemble d&amp;rsquo;origine $S$.
Pourquoi ?&lt;/p>
&lt;ol>
&lt;li>Les éléments de $T$ ne peuvent jamais être des multiples de $p$ (car ni $a$ ni les éléments d&amp;rsquo;origine ne sont des multiples de $p$).&lt;/li>
&lt;li>Il n&amp;rsquo;y a pas deux éléments distincts dans $T$ qui sont congrus modulo $p$. Si $ia \equiv ja \pmod p$ ($i \neq j$), puisque $a$ et $p$ sont premiers entre eux, nous pouvons diviser par $a$ pour obtenir $i \equiv j \pmod p$, ce qui est une contradiction.&lt;/li>
&lt;/ol>
&lt;p>Par conséquent, le produit de tous les éléments de $S$ et le produit de tous les éléments de $T$ sont congrus modulo $p$.&lt;/p>
$$
(1a) \times (2a) \times \dots \times ((p-1)a) \equiv 1 \times 2 \times \dots \times (p-1) \pmod p
$$
&lt;p>En réorganisant le côté gauche, puisqu&amp;rsquo;il y a $p-1$ termes de $a$,&lt;/p>
$$
a^{p-1} \cdot (p-1)! \equiv (p-1)! \pmod p
$$
&lt;p>Comme $(p-1)!$ est premier avec $p$, nous pouvons diviser les deux côtés par $(p-1)!$, ce qui conduit finalement au théorème suivant :&lt;/p>
$$
a^{p-1} \equiv 1 \pmod p
$$
&lt;p>Ceci est la preuve du petit théorème de Fermat.&lt;/p>
&lt;hr>
&lt;h2 id="4-la-fonction-indicatrice-deuler-et-le-théorème-deuler">4. La fonction indicatrice d&amp;rsquo;Euler et le théorème d&amp;rsquo;Euler
&lt;/h2>&lt;p>Le petit théorème de Fermat est un théorème concernant &amp;ldquo;un nombre premier $p$&amp;rdquo;, mais il a été généralisé à &amp;ldquo;tout entier positif $n$&amp;rdquo; par Leonhard Euler. Cette extension est essentielle pour comprendre le chiffrement RSA.&lt;/p>
&lt;h3 id="41-la-fonction-indicatrice-deuler-phin">4.1 La fonction indicatrice d&amp;rsquo;Euler $\phi(n)$
&lt;/h3>&lt;p>La fonction indicatrice d&amp;rsquo;Euler (ou fonction $\phi$ d&amp;rsquo;Euler) $\phi(n)$ est une fonction qui représente &amp;ldquo;le nombre d&amp;rsquo;entiers de $1$ à $n$ qui sont premiers avec $n$&amp;rdquo;.&lt;/p>
&lt;ul>
&lt;li>Dans le cas d&amp;rsquo;un nombre premier $p$, puisque tous les entiers de $1$ à $p-1$ sont premiers avec $p$, $\phi(p) = p - 1$.&lt;/li>
&lt;li>Pour le produit de deux nombres premiers distincts $p$ et $q$, c&amp;rsquo;est-à-dire $n = p \times q$, $\phi(n)$ peut être calculé avec une formule très simple :
$$ \phi(p \times q) = \phi(p) \times \phi(q) = (p - 1)(q - 1) $$&lt;/li>
&lt;/ul>
&lt;p>Cette propriété est la logique fondamentale derrière la génération de clés dans le chiffrement RSA.&lt;/p>
&lt;h3 id="42-le-théorème-deuler">4.2 Le théorème d&amp;rsquo;Euler
&lt;/h3>&lt;p>Euler a généralisé le petit théorème de Fermat comme suit :&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Théorème d&amp;rsquo;Euler (Euler&amp;rsquo;s Theorem)&lt;/strong>
Pour tout entier positif $n$ et tout entier $a$ qui lui est premier entre eux, ce qui suit est vrai :
&lt;/p>
$$ a^{\phi(n)} \equiv 1 \pmod n $$
&lt;/blockquote>
&lt;p>Si $n$ est un nombre premier $p$, alors $\phi(p) = p - 1$, donc cela devient exactement le petit théorème de Fermat ($a^{p-1} \equiv 1 \pmod p$). En d&amp;rsquo;autres termes, le petit théorème de Fermat n&amp;rsquo;est qu&amp;rsquo;un cas particulier du théorème d&amp;rsquo;Euler.&lt;/p>
&lt;hr>
&lt;h2 id="5-trouver-dénormes-nombres-premiers--le-test-de-primalité-de-fermat">5. Trouver d&amp;rsquo;énormes nombres premiers : Le test de primalité de Fermat
&lt;/h2>&lt;p>Dans les technologies cryptographiques (comme le chiffrement RSA et l&amp;rsquo;échange de clés Diffie-Hellman), il est nécessaire de trouver rapidement &amp;ldquo;d&amp;rsquo;énormes nombres premiers&amp;rdquo; s&amp;rsquo;étendant sur des centaines de chiffres. Cependant, utiliser la méthode de la &amp;ldquo;division par essais&amp;rdquo;, qui consiste à essayer de diviser par tous les nombres de $2$ à $\sqrt{N}$ pour déterminer si un grand nombre $N$ est premier, prendrait un temps équivalent à l&amp;rsquo;âge de l&amp;rsquo;univers.&lt;/p>
&lt;p>C&amp;rsquo;est là qu&amp;rsquo;intervient le &lt;strong>test de primalité de Fermat (Fermat Primality Test)&lt;/strong>, un &amp;ldquo;test de primalité probabiliste&amp;rdquo; qui utilise le petit théorème de Fermat à l&amp;rsquo;envers.&lt;/p>
&lt;h3 id="51-quest-ce-quun-test-de-primalité-probabiliste-">5.1 Qu&amp;rsquo;est-ce qu&amp;rsquo;un test de primalité probabiliste ?
&lt;/h3>&lt;p>Selon le petit théorème de Fermat, si $p$ est premier, alors $a^{p-1} \equiv 1 \pmod p$ est toujours vrai pour tout $a$ ($1 &lt; a &lt; p$).
La contraposée de cette affirmation est : &amp;ldquo;S&amp;rsquo;il existe un $a$ pour lequel $a^{p-1} \not\equiv 1 \pmod p$, alors $p$ &lt;strong>n&amp;rsquo;est absolument pas un nombre premier (c&amp;rsquo;est un nombre composé)&lt;/strong>&amp;rdquo;.&lt;/p>
&lt;p>Par conséquent, si vous voulez déterminer si $N$ est premier, vous choisissez quelques valeurs aléatoires de $a$, calculez $a^{N-1} \pmod N$ et vérifiez si le résultat est $1$. Si vous obtenez une réponse autre que $1$ ne serait-ce qu&amp;rsquo;une seule fois, il est certain que $N$ est un nombre composé. S&amp;rsquo;il vaut $1$ peu importe le nombre de fois que vous essayez, vous pouvez juger avec une forte probabilité que $N$ est &amp;ldquo;probablement premier&amp;rdquo;.&lt;/p>
&lt;h3 id="52-explication-de-lalgorithme-et-organigramme">5.2 Explication de l&amp;rsquo;algorithme et organigramme
&lt;/h3>&lt;p>L&amp;rsquo;algorithme du test de Fermat est le suivant :&lt;/p>
&lt;div class="mermaid">flowchart TD
Start["Début"] --> Input["Entrer le nombre à tester p et le nombre de tests k"]
Input --> LoopStart["Boucle de i = 0 à k-1"]
LoopStart --> Condition{"i &lt; k ?"}
Condition -- "Oui" --> RandomA["Choisir un entier aléatoire a dans la plage 1 &lt; a &lt; p-1"]
RandomA --> Calc["Calculer l'exponentiation modulaire a^(p-1) mod p"]
Calc --> CheckPrime{"Le résultat est-il 1 ?"}
CheckPrime -- "Non" --> ReturnComposite["p est un nombre composé (certain)"]
CheckPrime -- "Oui" --> Increment["Incrémenter i"]
Increment --> Condition
Condition -- "Non" --> ReturnPrime["p est probablement premier (probabiliste)"]
ReturnComposite --> End["Fin"]
ReturnPrime --> End&lt;/div>
&lt;h3 id="53-le-piège-des-nombres-de-carmichael-pseudo-premiers">5.3 Le piège des nombres de Carmichael (pseudo-premiers)
&lt;/h3>&lt;p>Bien que le test de Fermat soit extrêmement rapide, il présente un défaut majeur. Il existe des nombres diaboliques qui, bien qu&amp;rsquo;ils soient composés, satisfont $a^{N-1} \equiv 1 \pmod N$ pour tous les $a$. Ceux-ci sont appelés &lt;strong>nombres de Carmichael (Carmichael numbers)&lt;/strong>. Le plus petit nombre de Carmichael est $561$ ($3 \times 11 \times 17$).&lt;/p>
&lt;p>En raison de l&amp;rsquo;existence des nombres de Carmichael, un test de Fermat pur seul ne peut pas déterminer la primalité de manière absolue. C&amp;rsquo;est pourquoi, dans les systèmes cryptographiques réels (comme OpenSSL), le &lt;strong>test de primalité de Miller-Rabin (Miller-Rabin primality test)&lt;/strong>, qui est une version améliorée du test de Fermat, est utilisé en standard. Le test de Miller-Rabin peut détecter les nombres de Carmichael, réduisant ainsi la probabilité de fausse détection à presque zéro.&lt;/p>
&lt;h3 id="54-exponentiation-modulaire-rapide-méthode-dexponentiation-par-carrés">5.4 Exponentiation modulaire rapide (Méthode d&amp;rsquo;exponentiation par carrés)
&lt;/h3>&lt;p>Dans l&amp;rsquo;algorithme de test de primalité, il est nécessaire de calculer $a^{N-1} \pmod N$. Si $N$ est énorme, $a^{N-1}$ aura un nombre de chiffres astronomique et ne tiendra pas dans la mémoire d&amp;rsquo;un ordinateur.
La solution à ce problème est la &lt;strong>méthode d&amp;rsquo;exponentiation par carrés (Exponentiation by Squaring)&lt;/strong> ou exponentiation modulaire. En prenant le modulo (mod N) à chaque étape du calcul, la valeur est toujours maintenue plus petite que $N$, ce qui permet un calcul très rapide (complexité temporelle $O(\log N)$).&lt;/p>
&lt;hr>
&lt;h2 id="6-implémentation-du-test-de-primalité-et-de-lexponentiation-modulaire">6. Implémentation du test de primalité et de l&amp;rsquo;exponentiation modulaire
&lt;/h2>&lt;p>Maintenant, implémentons le test de primalité de Fermat et la méthode d&amp;rsquo;exponentiation par carrés en C++ et Python.&lt;/p>
&lt;h3 id="61-implémentation-en-c">6.1 Implémentation en C++
&lt;/h3>&lt;p>En C++, les types d&amp;rsquo;entiers standard ont tendance à déborder facilement, donc une bibliothèque d&amp;rsquo;entiers à précision multiple (comme GMP) est nécessaire pour manipuler des nombres géants. Cependant, pour comprendre l&amp;rsquo;algorithme, nous montrons ici une implémentation dans la limite des entiers 64 bits (&lt;code>unsigned long long&lt;/code>).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;random&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Exponentiation modulaire rapide (a^b mod m) - Exponentiation par carrés
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="nf">power_mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Si le bit de poids faible de b est 1, multiplier le résultat par a
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">__int128&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">result&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Extension en 128 bits pour éviter le débordement
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Élever a au carré
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">__int128&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Décaler b vers la droite (diviser par la moitié)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">/=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Test de primalité de Fermat
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">bool&lt;/span> &lt;span class="nf">fermat_is_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">iterations&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">5&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">random_device&lt;/span> &lt;span class="n">rd&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">mt19937_64&lt;/span> &lt;span class="n">gen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">rd&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">uniform_int_distribution&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">dis&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">iterations&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dis&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">gen&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Si a^(p-1) mod p n&amp;#39;est pas 1, alors c&amp;#39;est un nombre composé
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">power_mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Probablement premier
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">num&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1000000007&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Nombre premier connu
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">fermat_is_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">num&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">num&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; is probably prime.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">num&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; is composite.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-implémentation-en-python">6.2 Implémentation en Python
&lt;/h3>&lt;p>En Python, le type entier standard prend en charge les entiers à précision multiple, il n&amp;rsquo;y a donc pas besoin de s&amp;rsquo;inquiéter du débordement. De plus, la fonction intégrée &lt;code>pow(a, b, m)&lt;/code> de Python utilise l&amp;rsquo;exponentiation par carrés en interne et est très rapide.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">random&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">fermat_is_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">iterations&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Test de primalité probabiliste utilisant le test de Fermat
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">False&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">False&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">_&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">iterations&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Choisir un nombre aléatoire a entre 2 et p-2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randint&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calculer a^(p-1) mod p. La fonction intégrée pow est rapide.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">False&lt;/span> &lt;span class="c1"># Certitude que c&amp;#39;est un nombre composé&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">True&lt;/span> &lt;span class="c1"># Probablement premier&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Test&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">number_to_test&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">104729&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">fermat_is_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">number_to_test&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">number_to_test&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> est probablement premier.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">number_to_test&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> est un nombre composé.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-application-au-chiffrement-rsa--où-fermat-et-euler-se-rencontrent">7. Application au chiffrement RSA : Où Fermat et Euler se rencontrent
&lt;/h2>&lt;p>La plus grande application du petit théorème de Fermat (et du théorème d&amp;rsquo;Euler) est le &lt;strong>chiffrement RSA&lt;/strong>, développé en 1977 par Rivest, Shamir et Adleman.
Le chiffrement RSA est un système révolutionnaire de &amp;ldquo;cryptographie à clé publique&amp;rdquo;, qui réalise un mécanisme où la clé de chiffrement (clé publique) est rendue publique au monde entier, tandis que la clé de déchiffrement (clé privée) n&amp;rsquo;est connue que du destinataire.&lt;/p>
&lt;p>Cette asymétrie repose sur la sécurité computationnelle selon laquelle &amp;ldquo;la factorisation en nombres premiers de nombres composés géants est extrêmement difficile&amp;rdquo;.&lt;/p>
&lt;h3 id="71-fonctionnement-du-chiffrement-rsa-génération-de-clés-chiffrement-déchiffrement">7.1 Fonctionnement du chiffrement RSA (Génération de clés, Chiffrement, Déchiffrement)
&lt;/h3>&lt;p>Vérifions le flux de communication global du chiffrement RSA avec un diagramme de séquence Mermaid.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant Alice["Alice (Destinataire)"]
participant Bob["Bob (Expéditeur)"]
Alice->>Alice: "Générer d'énormes nombres premiers p, q"
Alice->>Alice: "Calculer N = p * q, φ(N) = (p-1)(q-1)"
Alice->>Alice: "Calculer la clé publique e et la clé privée d (e*d ≡ 1 mod φ(N))"
Alice->>Bob: "Envoyer la clé publique (N, e)"
Note over Bob: "Préparer le texte clair M (M &lt; N)"
Bob->>Bob: "Calculer le texte chiffré C = M^e mod N"
Bob->>Alice: "Envoyer le texte chiffré C"
Alice->>Alice: "Calculer le texte clair M = C^d mod N pour déchiffrer"&lt;/div>
&lt;p>Voici une explication des étapes mathématiques détaillées.&lt;/p>
&lt;h4 id="étape-1--génération-de-clés-travail-du-destinataire-alice">Étape 1 : Génération de clés (Travail du destinataire Alice)
&lt;/h4>&lt;ol>
&lt;li>Générer aléatoirement deux énormes nombres premiers $p$ et $q$ (c&amp;rsquo;est là que la méthode de test de primalité mentionnée ci-dessus est utilisée).&lt;/li>
&lt;li>Calculer leur produit $N = p \times q$. Ce $N$ est rendu public.&lt;/li>
&lt;li>En utilisant la fonction indicatrice d&amp;rsquo;Euler, calculer $\phi(N) = (p-1)(q-1)$.&lt;/li>
&lt;li>Choisir un entier $e$ (exposant public) qui est premier avec $\phi(N)$ (souvent $e = 65537$ est utilisé).&lt;/li>
&lt;li>Calculer l&amp;rsquo;inverse modulaire $d$ (exposant privé) de $e$. C&amp;rsquo;est-à-dire, trouver $d$ qui satisfait ce qui suit :
$$ e \cdot d \equiv 1 \pmod{\phi(N)} $$
&lt;strong>L&amp;rsquo;algorithme d&amp;rsquo;Euclide étendu&lt;/strong> est utilisé pour ce calcul.&lt;/li>
&lt;/ol>
&lt;p>La &lt;strong>clé publique est maintenant $(N, e)$&lt;/strong> et la &lt;strong>clé privée est $(N, d)$&lt;/strong>. ($p$, $q$, et $\phi(N)$ doivent être immédiatement détruits ou strictement dissimulés).&lt;/p>
&lt;h4 id="étape-2--chiffrement-travail-de-lexpéditeur-bob">Étape 2 : Chiffrement (Travail de l&amp;rsquo;expéditeur Bob)
&lt;/h4>&lt;p>Supposons que Bob veuille envoyer un message $M$ à Alice ($M$ est la version numérisée des caractères, avec $0 \le M &lt; N$).
Bob utilise la clé publique d&amp;rsquo;Alice $(N, e)$ pour effectuer le calcul suivant et créer le texte chiffré $C$.&lt;/p>
$$
C \equiv M^e \pmod N
$$
&lt;p>Ce $C$ est envoyé à Alice via le réseau.&lt;/p>
&lt;h4 id="étape-3--déchiffrement-travail-du-destinataire-alice">Étape 3 : Déchiffrement (Travail du destinataire Alice)
&lt;/h4>&lt;p>Alice, après avoir reçu le texte chiffré $C$, effectue le calcul suivant en utilisant sa clé privée $d$, qu&amp;rsquo;elle seule connaît.&lt;/p>
$$
M' \equiv C^d \pmod N
$$
&lt;p>Étonnamment, ce résultat de calcul $M'$ correspond parfaitement au message original $M$.&lt;/p>
&lt;h3 id="72-pourquoi-cela-peut-il-être-déchiffré--preuve-mathématique">7.2 Pourquoi cela peut-il être déchiffré ? (Preuve mathématique)
&lt;/h3>&lt;p>C&amp;rsquo;est ici que le petit théorème de Fermat (le théorème d&amp;rsquo;Euler) montre sa véritable valeur. Pourquoi $C^d \pmod N$ revient-il à $M$ ?&lt;/p>
&lt;p>Développons la formule de déchiffrement.
Puisque $C \equiv M^e \pmod N$,
&lt;/p>
$$ C^d \equiv (M^e)^d \equiv M^{ed} \pmod N $$
&lt;p>Lors de l&amp;rsquo;étape de génération de clés, nous avons choisi $d$ de sorte que $e \cdot d \equiv 1 \pmod{\phi(N)}$. Cela signifie qu&amp;rsquo;il existe un entier $k$ tel qu&amp;rsquo;il peut s&amp;rsquo;écrire comme suit :
&lt;/p>
$$ e \cdot d = 1 + k \cdot \phi(N) $$
&lt;p>En substituant cela dans la formule ci-dessus :
&lt;/p>
$$ M^{ed} = M^{1 + k \cdot \phi(N)} = M \cdot M^{k \cdot \phi(N)} = M \cdot (M^{\phi(N)})^k \pmod N $$
&lt;p>Ici, le &lt;strong>théorème d&amp;rsquo;Euler&lt;/strong> ($M^{\phi(N)} \equiv 1 \pmod N$) entre en jeu. (&lt;em>Strictement parlant, $M$ et $N$ doivent être premiers entre eux, mais dans RSA, la probabilité que $M$ et $N$ ne soient pas premiers entre eux est astronomiquement faible, et en utilisant le théorème des restes chinois, il peut être prouvé que cela est vrai même s&amp;rsquo;ils ne sont pas premiers entre eux&lt;/em>).&lt;/p>
&lt;p>En appliquant le théorème d&amp;rsquo;Euler, puisque $M^{\phi(N)} \equiv 1$,
&lt;/p>
$$ M \cdot (1)^k \equiv M \pmod N $$
&lt;p>$M$ est magnifiquement restauré ! Les propriétés des nombres que Fermat et Euler ont découvertes il y a des centaines d&amp;rsquo;années garantissent parfaitement la confidentialité des communications numériques modernes.&lt;/p>
&lt;hr>
&lt;h2 id="8-implémentation-jouet-du-chiffrement-rsa-python">8. Implémentation jouet du chiffrement RSA (Python)
&lt;/h2>&lt;p>Comme il est difficile de saisir cela uniquement en théorie, utilisons Python pour implémenter réellement le processus de génération de clés, de chiffrement et de déchiffrement RSA. Bien qu&amp;rsquo;il s&amp;rsquo;agisse d&amp;rsquo;une &amp;ldquo;implémentation jouet&amp;rdquo; à des fins éducatives, les mathématiques utilisées sont exactement les mêmes que les vraies.&lt;/p>
&lt;p>Nous inclurons également une implémentation de &amp;ldquo;l&amp;rsquo;algorithme d&amp;rsquo;Euclide étendu&amp;rdquo; pour trouver l&amp;rsquo;inverse modulaire $d$.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">random&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Trouver le plus grand commun diviseur&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Algorithme d&amp;#39;Euclide étendu (trouver x, y pour ax + by = gcd(a,b))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Utilisé pour trouver d pour e*d ≡ 1 (mod φ(N))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">extended_gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">extended_gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">g&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">//&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">mod_inverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">extended_gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">g&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">raise&lt;/span> &lt;span class="ne">Exception&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;L&amp;#39;inverse n&amp;#39;existe pas&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">phi&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Fonction de génération de nombres premiers (Version simplifiée : génère de petits nombres premiers)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">generate_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bits&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">p&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getrandbits&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bits&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Jugement simplifié au lieu du test de Fermat mentionné ci-dessus&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">p&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Génération de clés RSA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">generate_keypair&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bits&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">p&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">generate_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bits&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">q&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">generate_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bits&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># S&amp;#39;assurer que p et q ne sont pas identiques&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">q&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">q&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">generate_prime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bits&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">n&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">q&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phi&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># e est souvent un nombre premier comme 65537, mais ici il est choisi aléatoirement&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">e&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randrange&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="n">g&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">e&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randrange&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcul de la clé privée d&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">d&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_inverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Clé publique (e, n), Clé privée (d, n)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">encrypt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pk&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">plaintext&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pk&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calculer plaintext^e mod n&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cipher&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">ord&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">char&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">char&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">plaintext&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">cipher&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">decrypt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sk&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ciphertext&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sk&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calculer cipher^d mod n et reconvertir en caractères&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">plain&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="nb">chr&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">char&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">char&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">ciphertext&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">plain&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Exemple d&amp;#39;exécution&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s1">&amp;#39;__main__&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;--- Implémentation jouet du chiffrement RSA ---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">public_key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">private_key&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">generate_keypair&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bits&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">12&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># Utilisation de nombres premiers de 12 bits&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Clé publique (e, n): &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">public_key&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Clé privée (d, n): &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">private_key&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">message&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Hello Math!&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">Message d&amp;#39;origine : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">message&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Chiffrement&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">encrypted_msg&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">encrypt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">public_key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">message&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Texte chiffré : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">encrypted_msg&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Déchiffrement&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">decrypted_msg&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">decrypt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">private_key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">encrypted_msg&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Message déchiffré : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">decrypted_msg&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Lorsque vous exécutez ce code, vous pouvez voir le tableau de caractères être converti en un tableau de nombres peu familiers (texte chiffré), qui est ensuite magnifiquement restauré en la chaîne d&amp;rsquo;origine par la clé privée.&lt;/p>
&lt;hr>
&lt;h2 id="9-conclusion--lintersection-de-la-beauté-mathématique-et-de-la-praticité">9. Conclusion : L&amp;rsquo;intersection de la beauté mathématique et de la praticité
&lt;/h2>&lt;p>Au 17ème siècle, lorsque Pierre de Fermat a découvert ce &amp;ldquo;petit théorème&amp;rdquo;, personne ne pensait qu&amp;rsquo;il serait utile à quoi que ce soit. Fermat lui-même a mené des recherches en théorie des nombres par pure curiosité mathématique.&lt;/p>
&lt;p>Cependant, environ 300 ans plus tard, dans les années 1970, à l&amp;rsquo;aube des réseaux informatiques, le théorème de Fermat a fait un retour spectaculaire en tant que technologie cryptographique essentielle pour l&amp;rsquo;établissement de protocoles de communication sécurisés. La technologie de test de primalité basée sur le petit théorème de Fermat et le chiffrement RSA basé sur le théorème d&amp;rsquo;Euler soutiennent littéralement l&amp;rsquo;infrastructure Internet moderne.&lt;/p>
&lt;p>Les messages LINE que nous envoyons nonchalamment tous les jours, les achats sur Amazon, tout cela danse sur cette belle et simple formule $a^{p-1} \equiv 1 \pmod p$. Le petit théorème de Fermat nous enseigne que peu importe à quel point les mathématiques peuvent être abstraites, le moment viendra toujours où elles seront utiles à l&amp;rsquo;humanité.&lt;/p>
&lt;p>Dans l&amp;rsquo;apprentissage de la programmation et de la théorie cryptographique, comprendre les structures mathématiques à la base de celles-ci sera une arme puissante pour comprendre en profondeur le comportement des bibliothèques fournies sous forme de boîtes noires et pour concevoir des systèmes plus sécurisés.&lt;/p></description></item><item><title>L'intuition mathématique de la cryptographie basée sur les réseaux (Lattice-based cryptography)</title><link>http://kenji.blog/fr/p/lattice-based-cryptography-math-intuition/</link><pubDate>Fri, 11 Sep 2026 21:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/lattice-based-cryptography-math-intuition/</guid><description>&lt;img src="http://kenji.blog/p/lattice-based-cryptography-math-intuition/img/eyecatch.jpg" alt="Featured image of post L'intuition mathématique de la cryptographie basée sur les réseaux (Lattice-based cryptography)" />&lt;h1 id="1-introduction--laube-de-la-cryptographie-post-quantique-pqc-et-lessor-de-la-cryptographie-basée-sur-les-réseaux">1. Introduction : L&amp;rsquo;aube de la cryptographie post-quantique (PQC) et l&amp;rsquo;essor de la cryptographie basée sur les réseaux
&lt;/h1>&lt;p>L&amp;rsquo;infrastructure numérique de la société moderne repose sur des technologies de cryptographie à clé publique telles que le chiffrement RSA et la cryptographie sur les courbes elliptiques (ECC). Ces méthodes cryptographiques basent leur sécurité sur la difficulté mathématique de problèmes tels que le &amp;ldquo;problème de la factorisation en nombres premiers&amp;rdquo; ou le &amp;ldquo;problème du logarithme discret&amp;rdquo;, qui sont considérés comme impossibles à résoudre efficacement (nécessitant un temps exponentiel) par les ordinateurs classiques conventionnels.&lt;/p>
&lt;p>Cependant, en 1994, l&amp;rsquo;algorithme de Shor, publié par Peter Shor, a provoqué une onde de choc dans le monde de la cryptographie. Cet algorithme a prouvé mathématiquement qu&amp;rsquo;une fois qu&amp;rsquo;un ordinateur quantique à grande échelle sera réalisé, il pourra résoudre les problèmes de factorisation en nombres premiers et de logarithme discret en un temps polynomial. Cela signifie que la cryptographie à clé publique largement utilisée aujourd&amp;rsquo;hui deviendra complètement décryptable à l&amp;rsquo;avenir.&lt;/p>
&lt;p>Pour contrer cette &amp;ldquo;menace quantique (Quantum Threat)&amp;rdquo;, il est devenu urgent de rechercher de nouvelles méthodes cryptographiques difficiles à décrypter, même avec un ordinateur quantique. C&amp;rsquo;est le domaine appelé &amp;ldquo;Cryptographie Post-Quantique (Post-Quantum Cryptography : PQC)&amp;rdquo; ou &amp;ldquo;Cryptographie résistante aux ordinateurs quantiques&amp;rdquo;.&lt;/p>
&lt;p>Il existe plusieurs candidats prometteurs pour la PQC, tels que la cryptographie basée sur les fonctions de hachage, sur les codes, sur des polynômes multivariés et sur les isogénies. Parmi eux, celle qui attire actuellement le plus l&amp;rsquo;attention et qui est au cœur du processus de standardisation PQC par le NIST (Institut national des normes et de la technologie des États-Unis) est la &amp;ldquo;cryptographie basée sur les réseaux (Lattice-based cryptography)&amp;rdquo;. Comparée à d&amp;rsquo;autres méthodes, la cryptographie basée sur les réseaux se distingue par une vitesse de traitement très élevée pour le chiffrement et le déchiffrement. De plus, elle possède une caractéristique remarquable en théorie cryptographique : une preuve de sécurité extrêmement solide basée sur la réduction de la &amp;ldquo;complexité dans le pire des cas (Worst-case complexity)&amp;rdquo; à la &amp;ldquo;complexité en moyenne (Average-case complexity)&amp;rdquo;.&lt;/p>
&lt;p>Dans cet article, nous partirons de la définition mathématique du &amp;ldquo;réseau (Lattice)&amp;rdquo; qui est à la base de cette cryptographie, pour expliquer en profondeur les problèmes difficiles sur les réseaux tels que le SVP (Problème du vecteur le plus court) et le CVP (Problème du vecteur le plus proche), ainsi que le problème LWE (Learning With Errors) qui est le cœur de la cryptographie moderne sur les réseaux. Nous utiliserons des formules mathématiques, des intuitions géométriques et des exemples numériques concrets.&lt;/p>
&lt;h1 id="2-définition-mathématique-et-intuition-géométrique-du-réseau-lattice">2. Définition mathématique et intuition géométrique du réseau (Lattice)
&lt;/h1>&lt;h2 id="21-espace-vectoriel-et-réseau">2.1 Espace vectoriel et réseau
&lt;/h2>&lt;p>En mathématiques, un &amp;ldquo;réseau (Lattice)&amp;rdquo; est un ensemble de points discrets disposés de manière régulière dans un espace vectoriel réel à $n$ dimensions $\mathbb{R}^n$. Il ressemble à un espace vectoriel (Vector Space) étudié en algèbre linéaire, mais il présente une différence cruciale. Alors qu&amp;rsquo;un espace vectoriel est un espace continu représenté par des combinaisons linéaires de vecteurs de base avec des &amp;ldquo;coefficients réels&amp;rdquo;, un réseau est un espace discret représenté par des combinaisons linéaires de vecteurs de base avec des &amp;ldquo;coefficients entiers&amp;rdquo;.&lt;/p>
&lt;p>Donnons une définition mathématique rigoureuse. Considérons $n$ vecteurs linéairement indépendants ($n \le m$) $\mathbf{b}_1, \mathbf{b}_2, \dots, \mathbf{b}_n$ dans un espace vectoriel réel à $m$ dimensions $\mathbb{R}^m$. La matrice dont les colonnes sont ces vecteurs est notée $B = [\mathbf{b}_1, \mathbf{b}_2, \dots, \mathbf{b}_n] \in \mathbb{R}^{m \times n}$. On appelle $B$ la &amp;ldquo;base (Basis)&amp;rdquo; du réseau.&lt;/p>
&lt;p>Le réseau $\mathcal{L}(B)$ généré par cette base $B$ est défini comme suit :&lt;/p>
$$
\mathcal{L}(B) = \left\{ \sum_{i=1}^{n} x_i \mathbf{b}_i \mathrel{\bigg|} x_i \in \mathbb{Z} \right\} = \{ B \mathbf{x} \mid \mathbf{x} \in \mathbb{Z}^n \}
$$
&lt;p>Ce qui est important ici, c&amp;rsquo;est que les coefficients $x_i$ sont restreints aux entiers $\mathbb{Z}$ et non aux nombres réels $\mathbb{R}$. Par conséquent, au lieu de former un nombre infini de points continus dans l&amp;rsquo;espace, cela forme un &amp;ldquo;ensemble de points discrets&amp;rdquo; semblables à des intersections espacées uniformément.&lt;/p>
&lt;h2 id="22-image-géométrique">2.2 Image géométrique
&lt;/h2>&lt;p>Considérons l&amp;rsquo;exemple du plan bidimensionnel $\mathbb{R}^2$. Si nous choisissons les vecteurs de base $\mathbf{b}_1 = \begin{pmatrix} 1 \\ 0 \end{pmatrix}$ et $\mathbf{b}_2 = \begin{pmatrix} 0 \\ 1 \end{pmatrix}$, le réseau généré par ceux-ci est l&amp;rsquo;ensemble de toutes les coordonnées entières $(x, y) \in \mathbb{Z}^2$ sur le plan cartésien. C&amp;rsquo;est le &amp;ldquo;réseau carré&amp;rdquo; le plus simple.&lt;/p>
&lt;p>Cependant, les réseaux ne sont pas toujours orthogonaux. Par exemple, si nous considérons la base $\mathbf{b}_1 = \begin{pmatrix} 2 \\ 1 \end{pmatrix}$ et $\mathbf{b}_2 = \begin{pmatrix} 1 \\ 3 \end{pmatrix}$, les points générés ressembleront aux intersections d&amp;rsquo;une maille déformée en biais.&lt;/p>
&lt;h2 id="23-non-unicité-de-la-base-et-transformation-unimodulaire">2.3 Non-unicité de la base et transformation unimodulaire
&lt;/h2>&lt;p>Il existe une propriété importante liée au fondement de la sécurité de la cryptographie sur les réseaux : &amp;ldquo;Il existe une infinité de bases qui génèrent le même réseau&amp;rdquo;.&lt;/p>
&lt;p>Par exemple, la base $\mathbf{b}_1 = (1, 0)^T, \mathbf{b}_2 = (0, 1)^T$ qui génère le réseau $\mathbb{Z}^2$, génère exactement le même réseau $\mathbb{Z}^2$ si nous utilisons la base $\mathbf{b}'_1 = (1, 1)^T, \mathbf{b}'_2 = (2, 3)^T$.&lt;/p>
&lt;p>Une condition nécessaire et suffisante pour qu&amp;rsquo;une base $B$ et une autre base $B'$ génèrent le même réseau est l&amp;rsquo;existence d&amp;rsquo;une matrice à coefficients entiers $U \in \mathbb{Z}^{n \times n}$ avec un déterminant $\det(U) = \pm 1$, telle que
&lt;/p>
$$ B' = B U $$
&lt;p>
Une telle matrice $U$ est appelée &amp;ldquo;matrice unimodulaire (Unimodular matrix)&amp;rdquo;.&lt;/p>
&lt;p>L&amp;rsquo;idée fondamentale dans son application à la cryptographie est d&amp;rsquo;utiliser une &amp;ldquo;bonne base (une base proche de l&amp;rsquo;orthogonalité, composée de vecteurs courts)&amp;rdquo; comme clé privée, et une &amp;ldquo;mauvaise base (une base avec des vecteurs extrêmement obliques les uns par rapport aux autres et très longs)&amp;rdquo; comme clé publique. Calculer une bonne base à partir d&amp;rsquo;une mauvaise base devient extrêmement difficile à mesure que la dimension augmente. C&amp;rsquo;est l&amp;rsquo;intuition fondamentale de la cryptographie basée sur les réseaux.&lt;/p>
&lt;h1 id="3-problèmes-mathématiquement-difficiles-dans-les-réseaux">3. Problèmes mathématiquement difficiles dans les réseaux
&lt;/h1>&lt;p>La sécurité de la cryptographie basée sur les réseaux repose sur la difficulté de résoudre certains problèmes mathématiques sur les réseaux. Nous présentons ici les deux problèmes les plus fondamentaux et célèbres.&lt;/p>
&lt;h2 id="31-problème-du-vecteur-le-plus-court-shortest-vector-problem-svp">3.1 Problème du vecteur le plus court (Shortest Vector Problem: SVP)
&lt;/h2>&lt;p>Le SVP est le problème le plus classique et célèbre de la théorie des réseaux.&lt;/p>
&lt;p>&lt;strong>Définition (SVP) :&lt;/strong>
Étant donné une base de réseau arbitraire $B$, trouver le vecteur $\mathbf{v}$ non nul appartenant à ce réseau $\mathcal{L}(B)$ qui a la norme euclidienne (longueur) minimale.&lt;/p>
&lt;p>Mathématiquement, c&amp;rsquo;est le problème de trouver $\mathbf{v}$ tel que $\min_{\mathbf{v} \in \mathcal{L}(B) \setminus \{\mathbf{0}\}} \| \mathbf{v} \|$. Cette longueur minimale est notée $\lambda_1(\mathcal{L})$ et est appelée le &amp;ldquo;premier minimum successif (First successive minimum) du réseau&amp;rdquo;.&lt;/p>
&lt;p>En basse dimension, comme en 2 ou 3 dimensions, vous pouvez trouver le vecteur le plus court à l&amp;rsquo;œil nu en dessinant un graphique, ou bien le résoudre efficacement en utilisant l&amp;rsquo;algorithme de réduction de base de Gauss. Cependant, lorsque la dimension $n$ atteint des centaines ou des milliers de dimensions, il est connu que résoudre strictement le SVP est un problème NP-difficile.&lt;/p>
&lt;p>Dans les systèmes cryptographiques réels, on utilise le SVP approché ($\gamma$-SVP), qui consiste à trouver un &amp;ldquo;vecteur approximativement court&amp;rdquo; au lieu du vecteur strictement le plus court. Lorsque le facteur d&amp;rsquo;approximation $\gamma$ est de taille polynomiale, ce problème est toujours considéré comme extrêmement difficile.&lt;/p>
&lt;h2 id="32-problème-du-vecteur-le-plus-proche-closest-vector-problem-cvp">3.2 Problème du vecteur le plus proche (Closest Vector Problem: CVP)
&lt;/h2>&lt;p>Le CVP est également un problème extrêmement important dans la cryptographie sur les réseaux.&lt;/p>
&lt;p>&lt;strong>Définition (CVP) :&lt;/strong>
Étant donné une base de réseau arbitraire $B$ et un vecteur cible arbitraire $\mathbf{t} \in \mathbb{R}^m$ dans l&amp;rsquo;espace (qui n&amp;rsquo;est pas nécessairement un point du réseau), trouver le point du réseau $\mathbf{v} \in \mathcal{L}(B)$ qui est le plus proche de $\mathbf{t}$.&lt;/p>
&lt;p>Mathématiquement, c&amp;rsquo;est le problème de trouver un point du réseau $\mathbf{v}$ tel que $\min_{\mathbf{v} \in \mathcal{L}(B)} \| \mathbf{v} - \mathbf{t} \|$.&lt;/p>
&lt;p>Le CVP, tout comme le SVP, est NP-difficile en haute dimension. Du point de vue des applications cryptographiques, le problème LWE décrit ci-dessous est étroitement lié à une variante spéciale de ce CVP (Bounded Distance Decoding: BDD).&lt;/p>
&lt;h2 id="33-pourquoi-est-il-impossible-de-les-résoudre-en-haute-dimension--limites-de-lll-et-bkz">3.3 Pourquoi est-il impossible de les résoudre en haute dimension ? (Limites de LLL et BKZ)
&lt;/h2>&lt;p>L&amp;rsquo;algorithme LLL (algorithme de Lenstra-Lenstra-Lovász) est un algorithme célèbre pour résoudre les problèmes de réseau en haute dimension. L&amp;rsquo;algorithme LLL fonctionne en temps polynomial et peut réduire (Reduction) la base du réseau en une &amp;ldquo;bonne base&amp;rdquo; dans une certaine mesure. Cependant, le vecteur le plus court que l&amp;rsquo;algorithme LLL peut trouver a un facteur d&amp;rsquo;approximation exponentiel ($2^{\mathcal{O}(n)}$) par rapport à la longueur du vrai vecteur le plus court, ce qui ne suffit pas pour briser la sécurité de la cryptographie.&lt;/p>
&lt;p>En utilisant des algorithmes de réduction de base plus puissants comme l&amp;rsquo;algorithme BKZ (Block Korkine-Zolotarev), qui est une amélioration de LLL, il est possible de trouver des vecteurs plus courts, mais la complexité de calcul augmente de manière exponentielle par rapport à la taille du bloc. Dans la cryptographie sur les réseaux, des paramètres de sécurité (comme la taille de la dimension $n$) sont déterminés en estimant le temps d&amp;rsquo;exécution de cet algorithme BKZ. Avec les paramètres standard actuels de la PQC, la dimension $n$ est choisie avec des valeurs de 500 à plus de 1000, et on estime qu&amp;rsquo;il faudrait un temps supérieur à l&amp;rsquo;âge de l&amp;rsquo;univers pour la déchiffrer, même avec des superordinateurs ou de futurs ordinateurs quantiques.&lt;/p>
&lt;h1 id="4-formulation-mathématique-du-problème-lwe-learning-with-errors">4. Formulation mathématique du problème LWE (Learning With Errors)
&lt;/h1>&lt;p>La majeure partie de la cryptographie moderne sur les réseaux est basée sur le &amp;ldquo;problème LWE (Learning With Errors)&amp;rdquo; proposé par Oded Regev en 2005. La beauté du problème LWE réside dans la simplicité de sa formulation et dans sa solide preuve mathématique basée sur &amp;ldquo;la réduction de la complexité dans le pire des cas à la complexité en moyenne&amp;rdquo;.&lt;/p>
&lt;h2 id="41-système-déquations-linéaires-sans-bruit">4.1 Système d&amp;rsquo;équations linéaires sans bruit
&lt;/h2>&lt;p>Pour comprendre le problème LWE, considérons d&amp;rsquo;abord un simple système d&amp;rsquo;équations linéaires sans bruit.
Supposons qu&amp;rsquo;il existe un vecteur secret inconnu $\mathbf{s} \in \mathbb{Z}_q^n$ (chaque composante est un entier de $0$ à $q-1$). Ici, $q$ est un nombre premier.&lt;/p>
&lt;p>Nous choisissons des vecteurs de coefficients aléatoires $\mathbf{a}_1, \mathbf{a}_2, \dots \in \mathbb{Z}_q^n$ et calculons le produit scalaire avec le vecteur secret $\mathbf{s}$ modulo $q$.
$b_1 = \langle \mathbf{a}_1, \mathbf{s} \rangle \pmod q$
$b_2 = \langle \mathbf{a}_2, \mathbf{s} \rangle \pmod q$
$\vdots$&lt;/p>
&lt;p>Si l&amp;rsquo;on nous donne un nombre suffisant (plus de $n$) de paires $(\mathbf{a}_i, b_i)$, nous pouvons facilement restaurer le vecteur secret $\mathbf{s}$ en utilisant l&amp;rsquo;&amp;ldquo;élimination de Gauss (Gaussian elimination)&amp;rdquo; en algèbre linéaire. C&amp;rsquo;est un problème qui peut être facilement résolu en temps polynomial.&lt;/p>
&lt;h2 id="42-définition-du-problème-lwe--ajout-de-bruit">4.2 Définition du problème LWE : Ajout de bruit
&lt;/h2>&lt;p>Alors, que se passe-t-il si nous ajoutons un léger &amp;ldquo;bruit (erreur)&amp;rdquo; à ce problème ?
C&amp;rsquo;est là l&amp;rsquo;essence du problème LWE.&lt;/p>
&lt;p>Pour un vecteur secret inconnu $\mathbf{s} \in \mathbb{Z}_q^n$, nous ajoutons une petite erreur $e_i \in \mathbb{Z}_q$ au résultat de chaque équation.
$b_i = \langle \mathbf{a}_i, \mathbf{s} \rangle + e_i \pmod q$&lt;/p>
&lt;p>Ici, $e_i$ est une petite valeur entière dont la moyenne est 0 et l&amp;rsquo;écart-type est relativement faible (par exemple, choisie à partir d&amp;rsquo;une distribution gaussienne discrète, similaire à une distribution normale).
L&amp;rsquo;information fournie est une liste de paires de vecteurs aléatoires $\mathbf{a}_i$ et de $b_i$ calculés en ajoutant l&amp;rsquo;erreur.
$( \mathbf{a}_1, b_1 ), ( \mathbf{a}_2, b_2 ), \dots, ( \mathbf{a}_m, b_m )$&lt;/p>
&lt;p>C&amp;rsquo;est beaucoup plus clair lorsqu&amp;rsquo;on l&amp;rsquo;exprime sous forme de matrice.
En utilisant une matrice aléatoire $A \in \mathbb{Z}_q^{m \times n}$, un vecteur secret $\mathbf{s} \in \mathbb{Z}_q^n$, et un vecteur d&amp;rsquo;erreur $\mathbf{e} \in \mathbb{Z}_q^m$, on peut écrire :
&lt;/p>
$$ \mathbf{b} = A \mathbf{s} + \mathbf{e} \pmod q $$
&lt;p>
Seuls $A$ et $\mathbf{b}$ sont fournis. Le &amp;ldquo;problème de recherche LWE (Search LWE problem)&amp;rdquo; consiste à trouver $\mathbf{s}$ à partir de cela.&lt;/p>
&lt;p>Puisque l&amp;rsquo;erreur $e_i$ est introduite, si l&amp;rsquo;on essaie d&amp;rsquo;utiliser l&amp;rsquo;élimination de Gauss, l&amp;rsquo;erreur s&amp;rsquo;amplifiera de manière exponentielle lors de l&amp;rsquo;addition et de la soustraction d&amp;rsquo;équations, et il deviendra impossible d&amp;rsquo;arriver à la bonne réponse. À première vue, cela ressemble à un simple système d&amp;rsquo;équations linéaires, mais l&amp;rsquo;ajout de ce petit bruit fait bondir le niveau de difficulté au stade NP-difficile.&lt;/p>
&lt;h2 id="43-problème-de-décision-lwe-decision-lwe">4.3 Problème de décision LWE (Decision LWE)
&lt;/h2>&lt;p>Une variante du problème de recherche LWE, appelée &amp;ldquo;problème de décision LWE (Decision LWE problem)&amp;rdquo;, est fréquemment utilisée dans les preuves en théorie cryptographique.&lt;/p>
&lt;p>Le problème de décision LWE est le problème de déterminer, étant donné une liste d&amp;rsquo;échantillons obtenus à partir des deux distributions suivantes, de quelle distribution elle provient.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Distribution LWE&lt;/strong> : $(A, \mathbf{b} = A\mathbf{s} + \mathbf{e} \pmod q)$ calculé intentionnellement.&lt;/li>
&lt;li>&lt;strong>Distribution aléatoire uniforme&lt;/strong> : $(A, \mathbf{u})$ constitué d&amp;rsquo;une matrice $A$ et d&amp;rsquo;un vecteur $\mathbf{u}$ choisis de manière totalement aléatoire.&lt;/li>
&lt;/ol>
&lt;p>Étonnamment, si les paramètres du problème LWE sont choisis de manière appropriée, les paires obtenues à partir de la distribution LWE deviennent &amp;ldquo;informatiquement indiscernables (Computationally Indistinguishable)&amp;rdquo; des paires de données totalement aléatoires. Cette propriété est la raison pour laquelle la cryptographie basée sur LWE peut générer &amp;ldquo;un texte chiffré indiscernable de nombres aléatoires&amp;rdquo;.&lt;/p>
&lt;h2 id="44-réduction-de-la-complexité-du-pire-des-cas-à-la-complexité-en-moyenne-théorème-de-regev">4.4 Réduction de la complexité du pire des cas à la complexité en moyenne (Théorème de Regev)
&lt;/h2>&lt;p>La plus grande réalisation d&amp;rsquo;Oded Regev a été de lier mathématiquement la difficulté de ce problème LWE à la difficulté des problèmes de réseaux susmentionnés (SVP et CVP).&lt;/p>
&lt;p>En utilisant la réduction quantique (Quantum reduction), il a prouvé que &amp;ldquo;s&amp;rsquo;il existe un algorithme en temps polynomial capable de résoudre le problème LWE en moyenne (pour des $A$ et $\mathbf{e}$ choisis aléatoirement), alors il existe un algorithme quantique en temps polynomial capable de résoudre le Gap-SVP pour le pire des cas (le cas le plus difficile) de n&amp;rsquo;importe quel réseau.&amp;rdquo; (Plus tard, une réduction classique a également été démontrée par Peikert et al.).&lt;/p>
&lt;p>C&amp;rsquo;est une propriété de rêve en théorie cryptographique. En effet, elle dissipe la crainte que &amp;ldquo;la cryptographie puisse être brisée parce que nous avons peut-être choisi par hasard une clé faible (une partie du cas moyen)&amp;rdquo;, et fournit la puissante garantie que &amp;ldquo;si le LWE moyen peut être résolu, alors tous les problèmes difficiles des réseaux peuvent être résolus (donc LWE est absolument difficile)&amp;rdquo;.&lt;/p>
&lt;div class="mermaid">graph TD
A["Problèmes de réseau dans le pire des cas (Gap-SVP, SIVP)"] -->|Réduction quantique/classique| B["Problème LWE en moyenne"]
B -->|Construction cryptographique| C["Systèmes cryptographiques basés sur LWE (PKE, KEM, FHE)"]
style A fill:#ffcccc,stroke:#ff0000,stroke-width:2px,color:#000
style B fill:#ccffcc,stroke:#00aa00,stroke-width:2px,color:#000
style C fill:#ccccff,stroke:#0000ff,stroke-width:2px,color:#000&lt;/div>
&lt;h1 id="5-construction-du-cryptosystème-à-clé-publique-basé-sur-lwe-cryptosystème-de-regev">5. Construction du cryptosystème à clé publique basé sur LWE (Cryptosystème de Regev)
&lt;/h1>&lt;p>Maintenant que nous avons compris la difficulté du problème LWE, examinons le cryptosystème à clé publique de base proposé par Oded Regev pour voir comment il est utilisé pour le chiffrement et le déchiffrement. Nous expliquerons ici le mécanisme le plus fondamental de chiffrement d&amp;rsquo;un message d&amp;rsquo;un bit $M \in \{0, 1\}$.&lt;/p>
&lt;h2 id="51-génération-de-clé-key-generation">5.1 Génération de clé (Key Generation)
&lt;/h2>&lt;ol>
&lt;li>En tant que paramètres du système, déterminez le module premier $q$, la dimension $n$, et le nombre d&amp;rsquo;équations $m$ ($m > n \log q$).&lt;/li>
&lt;li>En tant que clé privée, choisissez aléatoirement un vecteur $\mathbf{s} \in \mathbb{Z}_q^n$.&lt;/li>
&lt;li>Générez une matrice aléatoire $A \in \mathbb{Z}_q^{m \times n}$.&lt;/li>
&lt;li>Choisissez un petit vecteur d&amp;rsquo;erreur $\mathbf{e} \in \mathbb{Z}_q^m$ à partir d&amp;rsquo;une distribution d&amp;rsquo;erreur telle que la distribution gaussienne discrète.&lt;/li>
&lt;li>Calculez le vecteur $\mathbf{b} = A \mathbf{s} + \mathbf{e} \pmod q$.&lt;/li>
&lt;li>La clé publique (Public Key) sera $(A, \mathbf{b})$.&lt;/li>
&lt;li>La clé secrète (Secret Key) sera $\mathbf{s}$.&lt;/li>
&lt;/ol>
&lt;p>La clé publique est littéralement une &amp;ldquo;instance du problème LWE&amp;rdquo;. Puisque trouver la clé secrète $\mathbf{s}$ à partir de la clé publique $(A, \mathbf{b})$ équivaut à résoudre le problème de recherche LWE, la sécurité est garantie.&lt;/p>
&lt;h2 id="52-chiffrement-encryption">5.2 Chiffrement (Encryption)
&lt;/h2>&lt;p>Alice utilise la clé publique de Bob $(A, \mathbf{b})$ pour chiffrer un message d&amp;rsquo;un bit $M \in \{0, 1\}$.&lt;/p>
&lt;ol>
&lt;li>Choisissez un vecteur binaire aléatoire (dont les composantes sont 0 ou 1) $\mathbf{r} \in \{0, 1\}^m$.&lt;/li>
&lt;li>Comme première partie du texte chiffré, calculez le vecteur $\mathbf{u} = A^T \mathbf{r} \pmod q$. ($A^T$ est la matrice transposée de $A$. C&amp;rsquo;est-à-dire que nous additionnons les lignes de $A$ dont la composante correspondante de $\mathbf{r}$ est 1).&lt;/li>
&lt;li>Comme deuxième partie du texte chiffré, calculez le scalaire $v = \mathbf{b}^T \mathbf{r} + M \cdot \lfloor \frac{q}{2} \rfloor \pmod q$.
(Si le message $M$ est 0, n&amp;rsquo;ajoutez rien ; s&amp;rsquo;il est $1$, ajoutez exactement la moitié de $q$, soit $\lfloor \frac{q}{2} \rfloor$).&lt;/li>
&lt;li>Le texte chiffré (Ciphertext) sera $(\mathbf{u}, v)$.&lt;/li>
&lt;/ol>
&lt;p>L&amp;rsquo;intuition derrière le chiffrement est de prendre la &amp;ldquo;somme d&amp;rsquo;un sous-ensemble aléatoire&amp;rdquo; par rapport à la matrice $A$ et au vecteur $\mathbf{b}$ de la clé publique. En raison de la difficulté du problème de décision LWE, ce texte chiffré $(\mathbf{u}, v)$ semble indiscernable de vecteurs totalement aléatoires et de nombres uniformément aléatoires (Sécurité sémantique : Semantic Security).&lt;/p>
&lt;div class="mermaid">flowchart LR
M["Message M dans {0,1}"] --> Enc
PK["Clé publique (A, b)"] --> Enc
r["Vecteur binaire aléatoire r"] --> Enc
subgraph Enc ["Processus de chiffrement"]
direction TB
u_calc["u = A^T * r mod q"]
v_calc["v = b^T * r + M * floor(q/2) mod q"]
end
Enc --> CT["Texte chiffré (u, v)"]&lt;/div>
&lt;h2 id="53-déchiffrement-decryption">5.3 Déchiffrement (Decryption)
&lt;/h2>&lt;p>Bob déchiffre le texte chiffré $(\mathbf{u}, v)$ en utilisant sa clé secrète $\mathbf{s}$.&lt;/p>
&lt;ol>
&lt;li>Calculez la valeur suivante : $D = v - \mathbf{s}^T \mathbf{u} \pmod q$&lt;/li>
&lt;li>Si le résultat calculé est proche de $0$, le message est de $M=0$, s&amp;rsquo;il est proche de $\lfloor \frac{q}{2} \rfloor$, le message est de $M=1$.&lt;/li>
&lt;/ol>
&lt;p>Montrons mathématiquement pourquoi cela permet le déchiffrement.
Rappelez-vous que $\mathbf{b} = A \mathbf{s} + \mathbf{e}$.&lt;/p>
$$
\begin{aligned}
v - \mathbf{s}^T \mathbf{u} &amp;= (\mathbf{b}^T \mathbf{r} + M \cdot \lfloor \frac{q}{2} \rfloor) - \mathbf{s}^T (A^T \mathbf{r}) \\
&amp;= ((A \mathbf{s} + \mathbf{e})^T \mathbf{r} + M \cdot \lfloor \frac{q}{2} \rfloor) - \mathbf{s}^T A^T \mathbf{r} \\
&amp;= (\mathbf{s}^T A^T \mathbf{r} + \mathbf{e}^T \mathbf{r} + M \cdot \lfloor \frac{q}{2} \rfloor) - \mathbf{s}^T A^T \mathbf{r} \\
&amp;= \mathbf{e}^T \mathbf{r} + M \cdot \lfloor \frac{q}{2} \rfloor \pmod q
\end{aligned}
$$
&lt;p>Ici, le terme $\mathbf{s}^T A^T \mathbf{r}$ s&amp;rsquo;est parfaitement annulé et a disparu de l&amp;rsquo;équation !
Ce qui reste, c&amp;rsquo;est $\mathbf{e}^T \mathbf{r} + M \cdot \lfloor \frac{q}{2} \rfloor$.&lt;/p>
&lt;p>$\mathbf{e}$ est un vecteur de bruit dont les composantes sont très petites, et $\mathbf{r}$ est un vecteur binaire dont les composantes sont 0 ou 1. Par conséquent, leur produit scalaire $\mathbf{e}^T \mathbf{r}$ restera également une valeur relativement faible (si les paramètres sont choisis de manière appropriée).&lt;/p>
&lt;ul>
&lt;li>Si $M=0$, le résultat sera $\mathbf{e}^T \mathbf{r}$, qui est une petite valeur proche de $0$.&lt;/li>
&lt;li>Si $M=1$, le résultat sera $\mathbf{e}^T \mathbf{r} + \lfloor \frac{q}{2} \rfloor$, qui sera situé autour de la moitié de $q$, soit $\lfloor \frac{q}{2} \rfloor$.&lt;/li>
&lt;/ul>
&lt;p>Si les paramètres sont conçus de sorte que la valeur absolue de l&amp;rsquo;erreur $\mathbf{e}^T \mathbf{r}$ soit inférieure à $\frac{q}{4}$, Bob peut déterminer (déchiffrer) avec précision le message $M$ en regardant simplement si le résultat du calcul est plus proche de $0$ ou de $\lfloor \frac{q}{2} \rfloor$. C&amp;rsquo;est le mécanisme élégant par lequel la cryptographie basée sur LWE fonctionne.&lt;/p>
&lt;div class="mermaid">flowchart LR
CT["Texte chiffré (u, v)"] --> Dec
SK["Clé secrète s"] --> Dec
subgraph Dec ["Processus de déchiffrement"]
direction TB
calc["Calculer D = v - s^T * u mod q"]
check["Vérifier si D est plus proche de 0 ou de q/2"]
end
calc --> check
Dec --> M_out["Message récupéré M"]&lt;/div>
&lt;h1 id="6-exemple-jouet-toy-example-de-chiffrement-lwe-avec-des-valeurs-numériques-spécifiques">6. Exemple jouet (Toy Example) de chiffrement LWE avec des valeurs numériques spécifiques
&lt;/h1>&lt;p>Il est difficile de comprendre seulement avec une liste de formules mathématiques, alors établissons des paramètres numériques très petits et suivons les calculs du chiffrement au déchiffrement.
(* Dans un système cryptographique réel, pour assurer la sécurité, $n$ est de 500 ou plus et $q$ est de plusieurs milliers).&lt;/p>
&lt;p>&lt;strong>【Paramétrage】&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Module $q = 17$ (Un nombre premier. Les valeurs seront donc de $0$ à $16$).&lt;/li>
&lt;li>Dimension $n = 2$&lt;/li>
&lt;li>Nombre d&amp;rsquo;équations $m = 4$&lt;/li>
&lt;li>Supposons que nous chiffrons le message $M = 1$.&lt;/li>
&lt;li>Montant du décalage du message : $\lfloor \frac{q}{2} \rfloor = \lfloor \frac{17}{2} \rfloor = 8$&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>【1. Phase de génération de clé】&lt;/strong>
Bob choisit aléatoirement une clé secrète $\mathbf{s}$, une matrice $A$, et un vecteur d&amp;rsquo;erreur $\mathbf{e}$.
&lt;/p>
$$ \mathbf{s} = \begin{pmatrix} 3 \\ 4 \end{pmatrix} \in \mathbb{Z}_{17}^2 $$
$$ A = \begin{pmatrix} 2 &amp; 15 \\ 1 &amp; 8 \\ 14 &amp; 5 \\ 9 &amp; 10 \end{pmatrix} \in \mathbb{Z}_{17}^{4 \times 2} $$
$$ \mathbf{e} = \begin{pmatrix} 1 \\ -1 \\ 0 \\ 2 \end{pmatrix} \equiv \begin{pmatrix} 1 \\ 16 \\ 0 \\ 2 \end{pmatrix} \pmod{17} $$
&lt;p>Ensuite, calculez la clé publique $\mathbf{b}$.
&lt;/p>
$$ A \mathbf{s} = \begin{pmatrix} 2 &amp; 15 \\ 1 &amp; 8 \\ 14 &amp; 5 \\ 9 &amp; 10 \end{pmatrix} \begin{pmatrix} 3 \\ 4 \end{pmatrix} = \begin{pmatrix} 2\times 3 + 15\times 4 \\ 1\times 3 + 8\times 4 \\ 14\times 3 + 5\times 4 \\ 9\times 3 + 10\times 4 \end{pmatrix} = \begin{pmatrix} 6 + 60 \\ 3 + 32 \\ 42 + 20 \\ 27 + 40 \end{pmatrix} = \begin{pmatrix} 66 \\ 35 \\ 62 \\ 67 \end{pmatrix} $$
&lt;p>
Nous calculons cela modulo 17. (par exemple, $66 = 17 \times 3 + 15$)
&lt;/p>
$$ A \mathbf{s} \pmod{17} = \begin{pmatrix} 15 \\ 1 \\ 11 \\ 16 \end{pmatrix} $$
&lt;p>
Ajoutez le vecteur d&amp;rsquo;erreur $\mathbf{e}$.
&lt;/p>
$$ \mathbf{b} = A \mathbf{s} + \mathbf{e} = \begin{pmatrix} 15 \\ 1 \\ 11 \\ 16 \end{pmatrix} + \begin{pmatrix} 1 \\ 16 \\ 0 \\ 2 \end{pmatrix} = \begin{pmatrix} 16 \\ 17 \\ 11 \\ 18 \end{pmatrix} \equiv \begin{pmatrix} 16 \\ 0 \\ 11 \\ 1 \end{pmatrix} \pmod{17} $$
&lt;p>La clé publique est $A$ et $\mathbf{b} = (16, 0, 11, 1)^T$.&lt;/p>
&lt;p>&lt;strong>【2. Phase de chiffrement】&lt;/strong>
Alice chiffre le message $M = 1$.
Choisissez un vecteur aléatoire $\mathbf{r}$. Ici, supposons $\mathbf{r} = (1, 0, 1, 0)^T$.&lt;/p>
&lt;p>Calculez $\mathbf{u}$.
&lt;/p>
$$ \mathbf{u} = A^T \mathbf{r} = \begin{pmatrix} 2 &amp; 1 &amp; 14 &amp; 9 \\ 15 &amp; 8 &amp; 5 &amp; 10 \end{pmatrix} \begin{pmatrix} 1 \\ 0 \\ 1 \\ 0 \end{pmatrix} = \begin{pmatrix} 2 \times 1 + 14 \times 1 \\ 15 \times 1 + 5 \times 1 \end{pmatrix} = \begin{pmatrix} 16 \\ 20 \end{pmatrix} \equiv \begin{pmatrix} 16 \\ 3 \end{pmatrix} \pmod{17} $$
&lt;p>Calculez $v$.
&lt;/p>
$$ \mathbf{b}^T \mathbf{r} = (16, 0, 11, 1) \begin{pmatrix} 1 \\ 0 \\ 1 \\ 0 \end{pmatrix} = 16 \times 1 + 11 \times 1 = 27 \equiv 10 \pmod{17} $$
&lt;p>
Ajoutez la valeur $\lfloor 17/2 \rfloor = 8$ correspondant au message $M=1$.
&lt;/p>
$$ v = \mathbf{b}^T \mathbf{r} + M \cdot 8 = 10 + 1 \times 8 = 18 \equiv 1 \pmod{17} $$
&lt;p>Alice envoie le texte chiffré $(\mathbf{u}, v) = \left( \begin{pmatrix} 16 \\ 3 \end{pmatrix}, 1 \right)$ à Bob.&lt;/p>
&lt;p>&lt;strong>【3. Phase de déchiffrement】&lt;/strong>
Après avoir reçu le texte chiffré, Bob le déchiffre en utilisant la clé secrète $\mathbf{s} = (3, 4)^T$.
Formule de déchiffrement : calculez $D = v - \mathbf{s}^T \mathbf{u} \pmod{17}$.&lt;/p>
$$ \mathbf{s}^T \mathbf{u} = (3, 4) \begin{pmatrix} 16 \\ 3 \end{pmatrix} = 3 \times 16 + 4 \times 3 = 48 + 12 = 60 \equiv 9 \pmod{17} $$
$$ D = v - \mathbf{s}^T \mathbf{u} = 1 - 9 = -8 \pmod{17} $$
&lt;p>Ici, dans le monde modulo 17, $-8$ est égal à $9$ ($-8 + 17 = 9$).
Déterminez si la valeur obtenue $D = 9$ est plus proche de $0$ ou de $8$ ($\lfloor 17/2 \rfloor$).
Étant donné que $9$ est clairement plus proche de $8$ que de $0$, Bob a pu restaurer correctement $M = 1$ !&lt;/p>
&lt;p>Pourquoi est-ce devenu $9$ ? Rappelons la preuve précédente.
La partie d&amp;rsquo;erreur est $\mathbf{e}^T \mathbf{r} = (1, -1, 0, 2) (1, 0, 1, 0)^T = 1 \times 1 + 0 \times 1 = 1$.
Par conséquent, le résultat du calcul est $\mathbf{e}^T \mathbf{r} + M \cdot 8 = 1 + 8 = 9$, et il est confirmé que la valeur théorique a été calculée.&lt;/p>
&lt;h1 id="7-évolution-vers-une-application-pratique--ring-lwe-et-module-lwe">7. Évolution vers une application pratique : Ring-LWE et Module-LWE
&lt;/h1>&lt;p>Le problème LWE standard (Standard LWE) expliqué jusqu&amp;rsquo;à présent possède une preuve de sécurité très solide, mais présente un défaut fatal dans la pratique. C&amp;rsquo;est &amp;ldquo;la taille énorme de la clé&amp;rdquo; et le &amp;ldquo;coût de calcul élevé&amp;rdquo;.&lt;/p>
&lt;p>Dans le Standard LWE, la clé publique contient une énorme matrice $A \in \mathbb{Z}_q^{m \times n}$. Lorsque le paramètre $n$ atteint des centaines ou des milliers, la taille de cette matrice atteint plusieurs mégaoctets, ce qui est trop lourd pour être envoyé et reçu à chaque fois dans les protocoles de communication Internet (tels que TLS). De plus, la multiplication d&amp;rsquo;une matrice et d&amp;rsquo;un vecteur nécessite une complexité de calcul de $\mathcal{O}(n^2)$.&lt;/p>
&lt;p>Pour résoudre ce problème, on a introduit &amp;ldquo;Ring-LWE (RLWE)&amp;rdquo; et &amp;ldquo;Module-LWE (MLWE)&amp;rdquo;, qui intègrent une structure algébrique appelée anneaux de polynômes (Polynomial rings) dans le réseau.&lt;/p>
&lt;h2 id="71-intuition-de-ring-lwe">7.1 Intuition de Ring-LWE
&lt;/h2>&lt;p>Dans Ring-LWE, les vecteurs et les matrices sont remplacés par des éléments (polynômes) sur l&amp;rsquo;anneau de polynômes $\mathcal{R}_q = \mathbb{Z}_q[X]/(X^n + 1)$. (Ici, $n$ est choisi comme une puissance de 2).&lt;/p>
&lt;p>Alors que la clé publique de Standard LWE était la matrice $A$, Ring-LWE utilise un seul polynôme $a(x)$. La clé secrète $s(x)$ et l&amp;rsquo;erreur $e(x)$ deviennent également des polynômes.
L&amp;rsquo;équation est la suivante :
&lt;/p>
$$ b(x) = a(x) \cdot s(x) + e(x) \pmod q $$
&lt;p>Comme il s&amp;rsquo;agit d&amp;rsquo;une multiplication de polynômes, la complexité de calcul peut être considérablement réduite à $\mathcal{O}(n \log n)$ en utilisant la &amp;ldquo;Transformation Numérique Théorique (Number Theoretic Transform: NTT)&amp;rdquo;, qui est similaire à la Transformation de Fourier Rapide (FFT). De plus, puisque la taille de la clé publique est également réduite d&amp;rsquo;une matrice à un seul polynôme, la taille des données est réduite à $\mathcal{O}(n)$. Cela apporte un avantage écrasant en termes de bande passante de communication.&lt;/p>
&lt;p>D&amp;rsquo;un point de vue mathématique, Ring-LWE ne repose pas sur un réseau général, mais se réduit à un problème sur un réseau doté d&amp;rsquo;une symétrie spéciale appelé &amp;ldquo;réseau idéal (Ideal Lattice)&amp;rdquo;.&lt;/p>
&lt;h2 id="72-module-lwe-et-normalisation-du-nist-kyber--ml-kem">7.2 Module-LWE et normalisation du NIST (Kyber / ML-KEM)
&lt;/h2>&lt;p>Ring-LWE est efficace, mais il y avait quelques inquiétudes quant au fait que la structure algébrique spéciale du réseau idéal puisse devenir un indice pour de futures attaques. Ainsi, le &amp;ldquo;Module-LWE (MLWE)&amp;rdquo; a été créé en prenant le meilleur des deux mondes : la sécurité conservatrice de Standard LWE et l&amp;rsquo;efficacité de Ring-LWE.&lt;/p>
&lt;p>Dans Module-LWE, nous considérons de petites matrices et des vecteurs dont les éléments sont des polynômes. En d&amp;rsquo;autres termes, nous traitons des modules sur l&amp;rsquo;anneau.
Actuellement, &amp;ldquo;CRYSTALS-Kyber&amp;rdquo; (nom standardisé : ML-KEM), qui a été sélectionné par le NIST comme norme pour l&amp;rsquo;algorithme d&amp;rsquo;échange de clés PQC (KEM), est construit précisément sur la difficulté de ce problème Module-LWE.&lt;/p>
&lt;h1 id="8-pourquoi-est-ce-sûr-face-aux-ordinateurs-quantiques-">8. Pourquoi est-ce sûr face aux ordinateurs quantiques ?
&lt;/h1>&lt;p>Enfin, abordons le point essentiel : &amp;ldquo;Pourquoi considère-t-on que la cryptographie basée sur les réseaux ne sera pas brisée même avec des ordinateurs quantiques ?&amp;rdquo;&lt;/p>
&lt;p>L&amp;rsquo;algorithme de Shor, grâce auquel les ordinateurs quantiques brisent le chiffrement RSA et la cryptographie sur les courbes elliptiques, est essentiellement un algorithme qui résout le &amp;ldquo;problème du sous-groupe caché (Hidden Subgroup Problem: HSP)&amp;rdquo;. La structure mathématique derrière RSA et ECC (groupes abéliens finis) présente une périodicité, et en utilisant une opération spécifique à l&amp;rsquo;algorithme quantique appelée Transformée de Fourier Quantique (QFT), cette période (le sous-groupe caché) peut être extraite en une seule fois.&lt;/p>
&lt;p>Cependant, les problèmes de réseaux sont fondamentalement différents. Bien que les réseaux aient également une périodicité, ce qui est requis dans SVP et CVP sont des propriétés géométriques non linéaires telles que &amp;ldquo;la distance la plus courte&amp;rdquo; ou &amp;ldquo;la suppression du bruit&amp;rdquo;. Même si nous appliquons la &amp;ldquo;Transformée de Fourier quantique sur un groupe abélien&amp;rdquo; comme l&amp;rsquo;algorithme de Shor tel quel, nous ne pouvons pas extraire efficacement les informations utiles qui seraient la solution au problème du réseau. Jusqu&amp;rsquo;à présent, aucun algorithme quantique capable de résoudre SVP ou LWE en temps polynomial n&amp;rsquo;a été découvert, et on croit largement que même avec la capacité de calcul parallèle des ordinateurs quantiques, seuls des moyens de résolution proches d&amp;rsquo;une recherche par force brute (une accélération de l&amp;rsquo;ordre de la racine carrée grâce à l&amp;rsquo;algorithme de Grover) sont valables.&lt;/p>
&lt;h1 id="9-conclusion">9. Conclusion
&lt;/h1>&lt;p>Dans cet article, nous avons expliqué en détail l&amp;rsquo;intuition mathématique de la cryptographie sur les réseaux, en commençant par la définition géométrique du réseau, la formulation du problème LWE, et jusqu&amp;rsquo;à la construction d&amp;rsquo;une cryptographie à clé publique.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Le réseau (Lattice)&lt;/strong> est un espace discret représenté par des combinaisons linéaires à coefficients entiers de vecteurs de base, et il devient difficile de trouver une &amp;ldquo;bonne base&amp;rdquo; proche de l&amp;rsquo;orthogonalité dans les dimensions élevées (SVP).&lt;/li>
&lt;li>&lt;strong>Le problème LWE (Learning With Errors)&lt;/strong> est le problème de la résolution d&amp;rsquo;équations linéaires simultanées avec du bruit, ce qui est lié à la difficulté du problème du pire cas du réseau, fournissant ainsi une base solide de sécurité.&lt;/li>
&lt;li>En utilisant le problème LWE, le chiffrement et le déchiffrement (&lt;strong>Cryptosystème de Regev&lt;/strong>) sont réalisés grâce à un mécanisme ingénieux d&amp;rsquo;ajout et de suppression intentionnelle de bruit.&lt;/li>
&lt;li>Dans les protocoles réels, &lt;strong>Ring-LWE&lt;/strong> et &lt;strong>Module-LWE&lt;/strong> utilisant des anneaux de polynômes sont adoptés pour améliorer l&amp;rsquo;efficacité de la communication et la vitesse de calcul, et servent de base au &lt;strong>ML-KEM&lt;/strong> standard du NIST.&lt;/li>
&lt;/ol>
&lt;p>À l&amp;rsquo;approche du changement de paradigme informatique sans précédent que représentent les ordinateurs quantiques, il est très romantique de penser que la &amp;ldquo;cryptographie sur les réseaux&amp;rdquo;, née des profondeurs de l&amp;rsquo;algèbre linéaire classique et de la théorie des nombres, soutiendra la fondation de la sécurité Internet de demain. Les mathématiques qui sous-tendent la cryptographie sur les réseaux ne sont en aucun cas trop complexes, et avec des connaissances de base en algèbre linéaire et en probabilités, vous pouvez parfaitement comprendre sa belle structure. Nous espérons que cet article vous aidera à comprendre la cryptographie basée sur les réseaux, qui est au cœur de la PQC.&lt;/p></description></item><item><title>Hypothèse de Riemann et distribution des nombres premiers : une relation profonde avec la cryptographie moderne</title><link>http://kenji.blog/fr/p/riemann-hypothesis-prime-distribution-cryptography/</link><pubDate>Fri, 11 Sep 2026 16:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/riemann-hypothesis-prime-distribution-cryptography/</guid><description>&lt;img src="http://kenji.blog/p/riemann-hypothesis-prime-distribution-cryptography/img/eyecatch.jpg" alt="Featured image of post Hypothèse de Riemann et distribution des nombres premiers : une relation profonde avec la cryptographie moderne" />&lt;h1 id="1-introduction--le-mystère-cosmique-des-nombres-premiers-et-lhypothèse-de-riemann">1. Introduction : Le mystère cosmique des nombres premiers et l&amp;rsquo;hypothèse de Riemann
&lt;/h1>&lt;p>Les « nombres premiers » (Prime Numbers) sont des entiers naturels qui ne sont divisibles que par 1 et par eux-mêmes, et sont souvent appelés les « atomes » du monde mathématique. La suite 2, 3, 5, 7, 11, 13&amp;hellip; semble à première vue désordonnée et aléatoire. Depuis que le mathématicien grec antique Euclide a prouvé qu&amp;rsquo;« il existe une infinité de nombres premiers », d&amp;rsquo;innombrables mathématiciens ont tenté de percer les régularités cachées dans cette suite de nombres premiers.&lt;/p>
&lt;p>Celle qui s&amp;rsquo;est le plus rapprochée du mystère des nombres premiers est l&amp;rsquo;&lt;strong>« Hypothèse de Riemann » (Riemann Hypothesis)&lt;/strong>, proposée en 1859 par le mathématicien allemand Bernhard Riemann. L&amp;rsquo;hypothèse de Riemann est l&amp;rsquo;un des problèmes les plus importants et non résolus des mathématiques modernes, et elle fait partie des Problèmes du prix du millénaire définis par l&amp;rsquo;Institut de mathématiques Clay, avec une récompense d&amp;rsquo;un million de dollars.&lt;/p>
&lt;p>À première vue, un problème difficile de mathématiques pures concernant la distribution des nombres premiers peut sembler sans rapport avec notre vie quotidienne. Cependant, la sécurité de l&amp;rsquo;infrastructure d&amp;rsquo;Internet qui soutient la société moderne, en particulier &lt;strong>les technologies de cryptographie moderne telles que le chiffrement RSA et la cryptographie sur les courbes elliptiques (ECC)&lt;/strong>, dépend profondément des propriétés des nombres premiers géants.&lt;/p>
&lt;p>Dans cet article, nous entreprendrons un voyage mathématique allant de la distribution des nombres premiers au théorème des nombres premiers, à la fonction zêta de Riemann, pour atteindre le cœur de l&amp;rsquo;hypothèse de Riemann. Nous explorerons en profondeur comment elle est liée à la cryptographie moderne et ce qu&amp;rsquo;il adviendrait du monde si l&amp;rsquo;hypothèse de Riemann venait à être prouvée.&lt;/p>
&lt;hr>
&lt;h1 id="2-le-théorème-des-nombres-premiers-et-la-distribution-des-nombres-premiers--la-découverte-de-gauss">2. Le théorème des nombres premiers et la distribution des nombres premiers : La découverte de Gauss
&lt;/h1>&lt;p>Afin de comprendre comment les nombres premiers sont distribués, les mathématiciens ont considéré la &lt;strong>fonction de compte des nombres premiers (Prime-counting function)&lt;/strong> $\pi(x)$, qui représente « combien de nombres premiers existent inférieurs ou égaux à un certain nombre $x$ ».&lt;/p>
&lt;p>Par exemple :&lt;/p>
&lt;ul>
&lt;li>$\pi(10) = 4$ (2, 3, 5, 7)&lt;/li>
&lt;li>$\pi(100) = 25$&lt;/li>
&lt;li>$\pi(1000) = 168$&lt;/li>
&lt;/ul>
&lt;p>Carl Friedrich Gauss, mathématicien de génie de 15 ans, a calculé d&amp;rsquo;énormes tables de nombres premiers et a découvert que la fréquence d&amp;rsquo;apparition des nombres premiers diminue de manière inversement proportionnelle au logarithme népérien $\ln x$. En d&amp;rsquo;autres termes, il a conjecturé que la probabilité de trouver un nombre premier autour d&amp;rsquo;un certain nombre $x$ est d&amp;rsquo;environ $\frac{1}{\ln x}$.&lt;/p>
&lt;p>L&amp;rsquo;expression de cela à l&amp;rsquo;aide d&amp;rsquo;une intégrale est le &lt;strong>logarithme intégral (Logarithmic integral)&lt;/strong> $\text{Li}(x)$.&lt;/p>
$$ \text{Li}(x) = \int_{2}^{x} \frac{dt}{\ln t} $$
&lt;p>La conjecture de Gauss a ensuite été prouvée indépendamment en 1896 par Jacques Hadamard et Charles-Jean de La Vallée Poussin, et a été établie en tant que &lt;strong>théorème des nombres premiers (Prime Number Theorem, PNT)&lt;/strong>.&lt;/p>
$$ \lim_{x \to \infty} \frac{\pi(x)}{\text{Li}(x)} = 1 $$
&lt;p>Ou de manière approximative, il s&amp;rsquo;exprime comme suit :&lt;/p>
$$ \pi(x) \sim \frac{x}{\ln x} $$
&lt;p>Grâce à ce théorème, nous savons que les nombres premiers ont une distribution très lisse et prévisible d&amp;rsquo;un point de vue macroscopique. Cependant, d&amp;rsquo;un point de vue microscopique, il existe toujours une « erreur » ou une « fluctuation » entre $\pi(x)$ et $\text{Li}(x)$. La véritable nature de cette fluctuation est le plus grand mystère que l&amp;rsquo;hypothèse de Riemann tente de résoudre.&lt;/p>
&lt;hr>
&lt;h1 id="3-la-fonction-zêta-de-riemann-et-le-produit-eulerien">3. La fonction zêta de Riemann et le produit eulerien
&lt;/h1>&lt;p>L&amp;rsquo;arme la plus puissante pour analyser la distribution des nombres premiers est la &lt;strong>fonction zêta de Riemann (Riemann Zeta Function)&lt;/strong>. À l&amp;rsquo;origine, il s&amp;rsquo;agissait d&amp;rsquo;une série infinie définie par Leonhard Euler pour les nombres réels $s > 1$.&lt;/p>
$$ \zeta(s) = \sum_{n=1}^\infty \frac{1}{n^s} = 1 + \frac{1}{2^s} + \frac{1}{3^s} + \frac{1}{4^s} + \dots $$
&lt;p>L&amp;rsquo;une des plus grandes réalisations d&amp;rsquo;Euler a été de prouver que cette série infinie peut être exprimée comme un produit infini sur tous les nombres premiers $p$. C&amp;rsquo;est le &lt;strong>produit eulerien (Euler Product Formula)&lt;/strong>.&lt;/p>
$$ \zeta(s) = \prod_{p \text{ prime}} \frac{1}{1 - p^{-s}} = \left( \frac{1}{1 - 2^{-s}} \right) \left( \frac{1}{1 - 3^{-s}} \right) \left( \frac{1}{1 - 5^{-s}} \right) \dots $$
&lt;p>La compréhension intuitive de la preuve est que si vous développez chaque terme du côté droit comme une série géométrique et que vous les multipliez, le théorème fondamental de l&amp;rsquo;arithmétique (tout entier naturel est exprimé de manière unique comme un produit de nombres premiers) reconstruira parfaitement la somme des inverses des entiers naturels du côté gauche.&lt;/p>
&lt;p>&lt;strong>Cette seule équation est devenue un pont reliant l&amp;rsquo;analyse (séries infinies / fonctions continues) et la théorie des nombres (nombres premiers / nombres discrets).&lt;/strong> Étudier la fonction zêta est synonyme d&amp;rsquo;étudier la distribution des nombres premiers.&lt;/p>
&lt;hr>
&lt;h1 id="4-prolongement-analytique-et-extension-au-plan-complexe">4. Prolongement analytique et extension au plan complexe
&lt;/h1>&lt;p>Le génie de Riemann réside dans l&amp;rsquo;extension de la variable $s$ de $\zeta(s)$, qu&amp;rsquo;Euler ne considérait que pour les nombres réels, à des &lt;strong>nombres complexes $s = \sigma + it$ ($\sigma$ est la partie réelle, $t$ est la partie imaginaire)&lt;/strong>.&lt;/p>
&lt;p>La série infinie originale ne converge que pour $\sigma > 1$, mais Riemann a utilisé une méthode appelée « prolongement analytique (Analytic Continuation) » pour étendre la définition de sorte que $\zeta(s)$ ait un sens sur l&amp;rsquo;ensemble du plan complexe, à l&amp;rsquo;exception du pôle en $s = 1$.&lt;/p>
&lt;p>Il a en outre dérivé une magnifique équation fonctionnelle (Functional equation) satisfaite par la fonction zêta.&lt;/p>
$$ \zeta(s) = 2^s \pi^{s-1} \sin\left(\frac{\pi s}{2}\right) \Gamma(1-s) \zeta(1-s) $$
&lt;p>Où $\Gamma(x)$ est la fonction gamma. Cette équation nous permet de connaître les propriétés du demi-plan gauche à partir des propriétés du demi-plan droit.&lt;/p>
&lt;h3 id="zéros-zeros-of-the-zeta-function">Zéros (Zeros of the Zeta Function)
&lt;/h3>&lt;p>Les nombres complexes $s$ où la valeur de la fonction zêta devient 0 sont appelés « zéros ».
D&amp;rsquo;après l&amp;rsquo;équation fonctionnelle, lorsque $s$ est un nombre pair négatif ($-2, -4, -6, \dots$), $\sin(\pi s / 2)$ devient 0, donc $\zeta(s) = 0$. Ceux-ci sont appelés les &lt;strong>zéros triviaux (Trivial zeros)&lt;/strong>.&lt;/p>
&lt;p>Cependant, ce qui est important dans la distribution des nombres premiers, ce sont les autres zéros, à savoir les &lt;strong>zéros non triviaux (Non-trivial zeros)&lt;/strong> qui existent dans la « bande critique (Critical strip) » où $0 \le \sigma \le 1$.&lt;/p>
&lt;hr>
&lt;h1 id="5-le-cœur-de-lhypothèse-de-riemann-et-la-formule-explicite">5. Le cœur de l&amp;rsquo;hypothèse de Riemann et la formule explicite
&lt;/h1>&lt;p>Riemann a calculé un petit nombre de zéros et a formulé une conjecture étonnante. C&amp;rsquo;est l&amp;rsquo;&lt;strong>hypothèse de Riemann&lt;/strong>.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Hypothèse de Riemann (Riemann Hypothesis)&lt;/strong>
Tous les zéros non triviaux de la fonction zêta de Riemann $\zeta(s)$ ont une partie réelle égale à $1/2$ (c&amp;rsquo;est-à-dire $\text{Re}(s) = 1/2$).&lt;/p>
&lt;/blockquote>
&lt;p>Cette droite où la partie réelle est de 1/2 est appelée la « droite critique (Critical line) ».&lt;/p>
&lt;div class="mermaid">graph TD
A["Fonction zêta de Riemann ζ(s)"] --> B["Extension au plan complexe par prolongement analytique"]
B --> C["Zéros triviaux (s = -2, -4, -6 ...)"]
B --> D["Zéros non triviaux (0 &lt;= Re(s) &lt;= 1)"]
D --> E["Hypothèse de Riemann"]
E --> F["Tous les zéros non triviaux sont sur Re(s) = 1/2"]
F --> G["Vers la preuve de la limite du terme d'erreur de la distribution des nombres premiers"]&lt;/div>
&lt;p>Pourquoi l&amp;rsquo;hypothèse de Riemann est-elle si importante ? C&amp;rsquo;est parce que les zéros de la fonction zêta déterminent &lt;strong>complètement&lt;/strong> la distribution des nombres premiers.&lt;/p>
&lt;p>Riemann, et plus tard le mathématicien von Mangoldt, ont dérivé une « formule explicite (Explicit formula) » qui décrit avec précision la distribution des nombres premiers. En utilisant la fonction de Tchebychev $\psi(x)$, elle s&amp;rsquo;exprime comme suit :&lt;/p>
$$ \psi(x) = x - \sum_{\rho} \frac{x^\rho}{\rho} - \ln(2\pi) - \frac{1}{2}\ln(1 - x^{-2}) $$
&lt;p>Où $\rho$ est la somme sur tous les zéros non triviaux de la fonction zêta.
Le terme principal est $x$ (qui correspond au théorème des nombres premiers), et en ajoutant et en soustrayant des termes ondulatoires dépendant des zéros $\rho$, la distribution en escalier exacte des nombres premiers est restaurée. On peut dire que les zéros non triviaux représentent les « fréquences (ondes) » de la distribution des nombres premiers.&lt;/p>
&lt;p>Si l&amp;rsquo;hypothèse de Riemann est vraie, et que la partie réelle de tous les zéros non triviaux $\rho$ est exactement de $1/2$, alors le terme d&amp;rsquo;erreur du théorème des nombres premiers se situera dans la plus petite plage théoriquement concevable.&lt;/p>
$$ |\pi(x) - \text{Li}(x)| \le \frac{1}{8\pi} \sqrt{x} \ln x \quad \text{for} \quad x \ge 2657 $$
&lt;p>En d&amp;rsquo;autres termes, &lt;strong>si l&amp;rsquo;hypothèse de Riemann est vraie, il sera prouvé que les nombres premiers sont distribués de la manière la plus « régulière et belle » que nous puissions imaginer&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="6-la-cryptographie-moderne-et-sa-relation-indissociable-avec-les-nombres-premiers">6. La cryptographie moderne et sa relation indissociable avec les nombres premiers
&lt;/h1>&lt;p>Jusqu&amp;rsquo;ici, nous étions dans le monde profond des mathématiques pures, mais ces propriétés des nombres premiers soutiennent fondamentalement la société numérique moderne. Le représentant de cela est la cryptographie à clé publique telle que le &lt;strong>chiffrement RSA&lt;/strong>.&lt;/p>
&lt;p>La sécurité de toutes les communications, y compris les paiements par carte de crédit sur Internet, la transmission de mots de passe et les signatures numériques de la blockchain, dépend des « nombres premiers ».&lt;/p>
&lt;h3 id="fonctionnement-du-chiffrement-rsa">Fonctionnement du chiffrement RSA
&lt;/h3>&lt;p>La sécurité du chiffrement RSA est basée sur le fait mathématique (problème de la factorisation) qu&amp;rsquo;« il est très difficile de factoriser un nombre composé avec un grand nombre de chiffres ».&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Génération de clés&lt;/strong>:
Choisissez au hasard de très grands nombres premiers $p$ et $q$ (par exemple, 2048 bits chacun).
Multipliez-les pour calculer $N = p \times q$. Ce $N$ fera partie de la clé publique.
En utilisant l&amp;rsquo;indicatrice d&amp;rsquo;Euler $\phi(N) = (p-1)(q-1)$, générez la clé privée $d$.&lt;/p>
$$ e \times d \equiv 1 \pmod{\phi(N)} $$
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Chiffrement et déchiffrement&lt;/strong>:
Le texte en clair $M$ est converti en texte chiffré $C$ à l&amp;rsquo;aide de la clé publique $e, N$.
&lt;/p>
$$ C \equiv M^e \pmod{N} $$
&lt;p>
Seul celui qui possède la clé privée $d$ peut le déchiffrer.
&lt;/p>
$$ M \equiv C^d \pmod{N} $$
&lt;/li>
&lt;/ol>
&lt;div class="mermaid">graph LR
A["Texte en clair (Plaintext)"] --> B["Chiffrer avec la clé publique (e, N)"]
B --> C["Texte chiffré (Ciphertext)"]
C --> D["Déchiffrer avec la clé privée (d)"]
D --> E["Texte en clair original"]
F["Attaquant (Attacker)"] -- "Tente de factoriser N" --> C
F -.-> G["Impossible de calculer d sans connaître p et q"]&lt;/div>
&lt;p>Pour casser le chiffrement RSA, il faut trouver (factoriser) les nombres premiers originaux $p$ et $q$ à partir du gigantesque $N$. Même en utilisant les algorithmes les plus courants (Crible algébrique : GNFS, etc.), la factorisation d&amp;rsquo;un nombre de centaines de chiffres prendrait un temps dépassant de loin l&amp;rsquo;âge de l&amp;rsquo;univers, même avec des superordinateurs.&lt;/p>
&lt;hr>
&lt;h1 id="7-limpact-de-lhypothèse-de-riemann-sur-la-cryptographie">7. L&amp;rsquo;impact de l&amp;rsquo;hypothèse de Riemann sur la cryptographie
&lt;/h1>&lt;p>Alors, comment « l&amp;rsquo;hypothèse de Riemann » au sommet des mathématiques pures et la « cryptographie » se croisent-elles ?&lt;/p>
&lt;h3 id="71-algorithmes-de-génération-de-nombres-premiers-test-de-primalité-et-lhypothèse-de-riemann-généralisée-grh">7.1. Algorithmes de génération de nombres premiers (test de primalité) et l&amp;rsquo;hypothèse de Riemann généralisée (GRH)
&lt;/h3>&lt;p>Pour utiliser le chiffrement RSA, il faut d&amp;rsquo;abord générer des nombres premiers géants $p$ et $q$. Cependant, déterminer de manière fiable et rapide si « un certain nombre est premier » n&amp;rsquo;est pas facile.&lt;/p>
&lt;p>Actuellement, l&amp;rsquo;algorithme pratique utilisé est le &lt;strong>test de primalité de Miller-Rabin (Miller-Rabin primality test)&lt;/strong>, qui est un algorithme probabiliste. Cet algorithme est rapide, mais il existe un risque de « pseudo-premiers » où un nombre composé est identifié à tort comme premier avec une probabilité extrêmement faible.&lt;/p>
&lt;p>Cependant, si l&amp;rsquo;&lt;strong>« Hypothèse de Riemann généralisée (Generalized Riemann Hypothesis, GRH) »&lt;/strong>, qui étend l&amp;rsquo;hypothèse de Riemann aux fonctions L de Dirichlet, est supposée vraie, la situation change radicalement.
Si la GRH est vraie, la limite supérieure du nombre de tests dans le test de Miller-Rabin est mathématiquement garantie, et elle passe d&amp;rsquo;un algorithme probabiliste à un &lt;strong>« algorithme déterministe en temps polynomial »&lt;/strong> (C&amp;rsquo;était un fait majeur connu avant même la découverte du test de primalité AKS).&lt;/p>
&lt;p>En d&amp;rsquo;autres termes, l&amp;rsquo;hypothèse de Riemann (et son extension) joue un rôle dans l&amp;rsquo;approbation directe de la génération de base de la cryptographie : « Pouvons-nous générer des nombres premiers géants rapidement et avec une confiance absolue ? ».&lt;/p>
&lt;h3 id="72-relation-avec-les-algorithmes-de-factorisation">7.2. Relation avec les algorithmes de factorisation
&lt;/h3>&lt;p>Lors de l&amp;rsquo;évaluation de la complexité des algorithmes pour le décryptage (comme le crible algébrique), la connaissance de la distribution des nombres premiers est indispensable. De nombreux algorithmes de factorisation dépendent de la distribution des « nombres friables (Smooth numbers : nombres qui n&amp;rsquo;ont que de petits facteurs premiers) ».&lt;/p>
&lt;p>Pour évaluer rigoureusement la fréquence d&amp;rsquo;apparition des nombres friables, une compréhension profonde de la distribution des nombres premiers est requise, et ici aussi, des techniques de théorie analytique des nombres directement liées à la fonction zêta et à l&amp;rsquo;hypothèse de Riemann sont pleinement utilisées. Si l&amp;rsquo;hypothèse de Riemann est prouvée et que l&amp;rsquo;erreur de la distribution des nombres premiers est complètement déterminée, il sera possible d&amp;rsquo;évaluer plus précisément les limites de performance des algorithmes de factorisation.&lt;/p>
&lt;hr>
&lt;h1 id="8-si-lhypothèse-de-riemann-est-prouvée-la-cryptographie-sera-t-elle-cassée-">8. Si l&amp;rsquo;hypothèse de Riemann est prouvée, la cryptographie sera-t-elle cassée ?
&lt;/h1>&lt;p>On dit parfois comme une légende urbaine que « si l&amp;rsquo;hypothèse de Riemann est résolue, le chiffrement RSA s&amp;rsquo;effondrera en un instant », mais &lt;strong>c&amp;rsquo;est mathématiquement inexact&lt;/strong>.&lt;/p>
&lt;p>La preuve de l&amp;rsquo;hypothèse de Riemann elle-même ne créera pas immédiatement un algorithme magique qui accélère considérablement la factorisation. L&amp;rsquo;hypothèse de Riemann n&amp;rsquo;est qu&amp;rsquo;un théorème sur la « régularité de la distribution macroscopique » des nombres premiers, et elle ne nous dit pas directement par quels nombres premiers un nombre individuel $N$ est divisible (propriété locale).&lt;/p>
&lt;p>Cependant, l&amp;rsquo;impact n&amp;rsquo;est pas nul.
Il est extrêmement probable que de &lt;strong>« nouveaux outils mathématiques » et des « méthodes analytiques inconnues » soient découverts&lt;/strong> au cours du processus de démonstration de l&amp;rsquo;hypothèse de Riemann. L&amp;rsquo;histoire montre que lorsque le dernier théorème de Fermat et la conjecture de Poincaré ont été prouvés, les nouvelles théories développées au cours du processus ont fait progresser les mathématiques dans leur ensemble.&lt;/p>
&lt;p>Si des méthodes géométriques algébriques inconnues ou des méthodes géométriques non commutatives permettant de manipuler complètement les propriétés des zéros de la fonction zêta de Riemann sont établies, il n&amp;rsquo;est pas exclu que cela conduise à la découverte d&amp;rsquo;un algorithme révolutionnaire de factorisation (par exemple, un algorithme classique qui réduit la complexité au temps polynomial). En ce sens, les cryptographes ne peuvent jamais quitter des yeux les développements de l&amp;rsquo;hypothèse de Riemann.&lt;/p>
&lt;h3 id="ordinateurs-quantiques-et-algorithme-de-shor">Ordinateurs quantiques et algorithme de Shor
&lt;/h3>&lt;p>Une menace plus directe et réaliste pour la cryptographie n&amp;rsquo;est pas la preuve de l&amp;rsquo;hypothèse de Riemann, mais les &lt;strong>ordinateurs quantiques&lt;/strong>. « L&amp;rsquo;algorithme de Shor » publié par Peter Shor en 1994 a prouvé qu&amp;rsquo;avec un ordinateur quantique suffisamment performant, la factorisation peut être résolue en temps polynomial. Cela casserait fondamentalement le chiffrement RSA et la cryptographie sur les courbes elliptiques.&lt;/p>
&lt;p>Actuellement, une transition vers la « cryptographie post-quantique (Post-Quantum Cryptography, PQC) » (comme la cryptographie fondée sur les réseaux) qui ne peut pas être déchiffrée même par des ordinateurs quantiques progresse dans le monde entier. Les technologies de cryptographie basées sur les nombres premiers peuvent en un sens atteindre la fin de leur âge d&amp;rsquo;or, mais la valeur mathématique des nombres premiers eux-mêmes ne sera jamais perdue.&lt;/p>
&lt;hr>
&lt;h1 id="9-conclusion--lintersection-de-labstraction-mathématique-et-de-la-société-réelle">9. Conclusion : L&amp;rsquo;intersection de l&amp;rsquo;abstraction mathématique et de la société réelle
&lt;/h1>&lt;div class="mermaid">graph TD
A["Exploration des mathématiques pures"] --> B["Élucidation de l'hypothèse de Riemann"]
B --> C["Compréhension complète de la distribution des nombres premiers"]
C --> D["Développement spectaculaire de la théorie des nombres et de la géométrie algébrique"]
D -.-> E["Possibilité de nouveaux algorithmes de factorisation"]
E -.-> F["Mise à jour de l'évaluation de la sécurité cryptographique"]
A --> G["Mathématiques appliquées et informatique"]
G --> H["Efficacité des tests de primalité et de la génération cryptographique"]
H --> F&lt;/div>
&lt;p>La quête insatiable des nombres premiers, qui se poursuit depuis la Grèce antique, a été sublimée par le génie de Riemann en une magnifique symphonie sur le plan complexe (les zéros de la fonction zêta). Et étonnamment, ce cristal pur et immaculé des mathématiques est appliqué des siècles plus tard comme le bouclier le plus puissant garantissant la sécurité de la société de l&amp;rsquo;information.&lt;/p>
&lt;p>L&amp;rsquo;hypothèse de Riemann est une entité qui symbolise à la fois la « beauté abstraite » des mathématiques et sa « stupéfiante applicabilité au monde physique et à la société réelle ».&lt;/p>
&lt;p>Lorsqu&amp;rsquo;un jour cette immense montagne mathématique, dont personne n&amp;rsquo;a encore atteint le sommet, sera conquise, nous comprendrons parfaitement la vérité cosmique des nombres premiers et acquerrons une nouvelle perspective sur les fondements de la société de l&amp;rsquo;information. L&amp;rsquo;étude de la cryptographie est aussi un voyage à travers l&amp;rsquo;histoire de la sagesse humaine.&lt;/p></description></item><item><title>【Explication mathématique】Le fonctionnement de la cryptographie RSA expliqué aux lycéens</title><link>http://kenji.blog/fr/p/rsa-encryption-math-explained-for-beginners/</link><pubDate>Fri, 11 Sep 2026 13:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/rsa-encryption-math-explained-for-beginners/</guid><description>&lt;img src="http://kenji.blog/p/rsa-encryption-math-explained-for-beginners/img/eyecatch.jpg" alt="Featured image of post 【Explication mathématique】Le fonctionnement de la cryptographie RSA expliqué aux lycéens" />&lt;p>L&amp;rsquo;une des technologies qui soutient fondamentalement la sécurité de la société Internet est la « cryptographie RSA ». La plupart des communications que nous utilisons négligemment chaque jour, telles que les paiements par carte de crédit lors des achats en ligne, les échanges sur les réseaux sociaux avec des amis, ou l&amp;rsquo;envoi et la réception d&amp;rsquo;informations confidentielles d&amp;rsquo;entreprise, sont protégées par cette cryptographie RSA ou par ses technologies successives.&lt;/p>
&lt;p>Cependant, lorsque l&amp;rsquo;on entend le mot « cryptographie », on peut imaginer des machines de chiffrement complexes comme celles des films d&amp;rsquo;espionnage, ou des mathématiques super avancées que seuls quelques génies peuvent comprendre. S&amp;rsquo;il est vrai que la théorie cryptographique moderne repose sur des mathématiques avancées, &lt;strong>le mécanisme fondamental de la cryptographie RSA peut être pleinement compris avec des connaissances mathématiques acquises au lycée (propriétés des entiers, nombres premiers, congruences, etc.)&lt;/strong>.&lt;/p>
&lt;p>Dans cet article, en partant des connaissances mathématiques du lycée, nous expliquerons étape par étape et de manière exhaustive les principes mathématiques sur lesquels repose la cryptographie RSA et pourquoi son décryptage est si difficile. Nous l&amp;rsquo;expliquerons soigneusement avec des exemples concrets pour que même ceux qui ne sont pas très à l&amp;rsquo;aise avec les mathématiques puissent comprendre.&lt;/p>
&lt;hr>
&lt;h2 id="1-cryptographie-à-clé-symétrique-et-cryptographie-à-clé-publique">1. Cryptographie à clé symétrique et cryptographie à clé publique
&lt;/h2>&lt;p>Avant d&amp;rsquo;aborder le mécanisme mathématique de la cryptographie RSA, passons d&amp;rsquo;abord en revue les concepts de base de la cryptographie. Les méthodes de chiffrement sont généralement divisées en deux types : la « cryptographie à clé symétrique » (ou clé secrète) et la « cryptographie à clé publique ».&lt;/p>
&lt;h3 id="11-les-limites-de-la-cryptographie-à-clé-symétrique">1.1 Les limites de la cryptographie à clé symétrique
&lt;/h3>&lt;p>La plupart des cryptographies utilisées depuis l&amp;rsquo;Antiquité sont appelées « cryptographie à clé symétrique ». C&amp;rsquo;est une méthode où &lt;strong>la même clé est utilisée pour le « chiffrement (conversion du message en un texte chiffré secret) » et le « déchiffrement (restauration du texte chiffré en son message d&amp;rsquo;origine) »&lt;/strong>.&lt;/p>
&lt;p>Par exemple, supposons qu&amp;rsquo;Alice veuille envoyer une lettre secrète à Bob. Alice met la lettre dans une boîte et la verrouille à l&amp;rsquo;aide d&amp;rsquo;un cadenas (clé symétrique). Pour que Bob puisse ouvrir cette boîte, il doit posséder la même clé que celle utilisée par Alice.&lt;/p>
&lt;p>Cette méthode pose un problème majeur : le « problème de distribution des clés ». Lorsque Alice et Bob, éloignés l&amp;rsquo;un de l&amp;rsquo;autre, communiquent pour la première fois, comment peuvent-ils partager la clé sans être sur écoute ? Si la clé est volée par un tiers pendant son envoi par la poste, toutes les communications chiffrées ultérieures seront complètement compromises.&lt;/p>
&lt;h3 id="12-linvention-révolutionnaire--la--cryptographie-à-clé-publique-">1.2 L&amp;rsquo;invention révolutionnaire : la « Cryptographie à clé publique »
&lt;/h3>&lt;p>La « cryptographie à clé publique » a été inventée pour résoudre ce problème de distribution des clés. La cryptographie RSA en est un type.&lt;/p>
&lt;p>Dans la cryptographie à clé publique, &lt;strong>deux clés différentes sont utilisées : une « clé pour chiffrer (clé publique) » et une « clé pour déchiffrer (clé privée) »&lt;/strong>.&lt;/p>
&lt;ol>
&lt;li>Le destinataire, Bob, crée une paire composée d&amp;rsquo;une « clé publique » et d&amp;rsquo;une « clé privée ».&lt;/li>
&lt;li>Bob publie la « clé publique » dans le monde entier (peu importe qui l&amp;rsquo;obtient).&lt;/li>
&lt;li>L&amp;rsquo;expéditrice, Alice, utilise la « clé publique » de Bob pour chiffrer son message et l&amp;rsquo;envoie.&lt;/li>
&lt;li>Le message chiffré ne peut être déchiffré qu&amp;rsquo;avec la « clé privée », que seul Bob possède.&lt;/li>
&lt;/ol>
&lt;p>Si l&amp;rsquo;on compare cela à un cadenas, Bob fabrique de nombreux « cadenas ouverts (clés publiques) » et les disperse à travers le monde. Alice place un message destiné à Bob dans une boîte et la verrouille avec un cadenas de Bob qu&amp;rsquo;elle a trouvé. Une fois fermé, le cadenas ne peut être ouvert qu&amp;rsquo;avec la « clé passe-partout (clé privée) » détenue par Bob. Même si quelqu&amp;rsquo;un vole la boîte en cours de route, il ne peut pas l&amp;rsquo;ouvrir sans la clé passe-partout.&lt;/p>
&lt;div class="mermaid">graph TD
A["Alice (Expéditrice)"] --> B["Texte clair (Message)"]
B --> C["Processus de chiffrement"]
D["Clé publique de Bob (Accessible à tous)"] --> C
C --> E["Transmission via Internet : Texte chiffré"]
E --> F["Processus de déchiffrement"]
G["Clé privée de Bob (Détenue uniquement par Bob)"] --> F
F --> H["Texte clair restauré (Message)"]
H --> I["Bob (Destinataire)"]&lt;/div>
&lt;p>Pour réaliser ce système révolutionnaire, une sorte de &lt;strong>« fonction à sens unique (un puzzle mathématique à sens unique) »&lt;/strong> est nécessaire : « un chiffrement facile avec la clé publique, mais un déchiffrement absolument impossible sans la clé privée ». C&amp;rsquo;est là que les « nombres premiers » que nous connaissons bien ont été choisis comme pièces de ce puzzle.&lt;/p>
&lt;hr>
&lt;h2 id="2-base-mathématique-de-la-cryptographie-rsa-1--nombres-premiers-et-décomposition-en-facteurs-premiers">2. Base mathématique de la cryptographie RSA 1 : Nombres premiers et décomposition en facteurs premiers
&lt;/h2>&lt;p>La sécurité de la cryptographie RSA repose sur le fait mathématique que &lt;strong>« la décomposition en facteurs premiers de nombres gigantesques est extrêmement difficile »&lt;/strong>.&lt;/p>
&lt;h3 id="21-quest-ce-quun-nombre-premier-">2.1 Qu&amp;rsquo;est-ce qu&amp;rsquo;un nombre premier ?
&lt;/h3>&lt;p>Un nombre premier est « un entier naturel supérieur à 1 qui ne peut être divisé de manière exacte que par 1 et par lui-même ».
Exemples : $2, 3, 5, 7, 11, 13, 17, 19, 23...$&lt;/p>
&lt;p>Les nombres premiers sont comme les « atomes » de tous les nombres entiers. Tout entier naturel peut être décomposé sous la forme d&amp;rsquo;une multiplication de nombres premiers. C&amp;rsquo;est ce qu&amp;rsquo;on appelle la &lt;strong>décomposition en facteurs premiers&lt;/strong>. Par exemple, $60 = 2^2 \times 3 \times 5$. Le fait que l&amp;rsquo;on puisse décomposer un nombre en facteurs premiers d&amp;rsquo;une seule et unique manière (si l&amp;rsquo;on ignore l&amp;rsquo;ordre) est connu sous le nom de « Théorème fondamental de l&amp;rsquo;arithmétique ».&lt;/p>
&lt;h3 id="22-la-difficulté-de-la-décomposition-en-facteurs-premiers-fonction-à-sens-unique">2.2 La difficulté de la décomposition en facteurs premiers (Fonction à sens unique)
&lt;/h3>&lt;p>Ce qui est important ici, c&amp;rsquo;est l&amp;rsquo;asymétrie selon laquelle &lt;strong>« la multiplication est facile, mais la décomposition en facteurs premiers est difficile »&lt;/strong>.&lt;/p>
&lt;p>Par exemple, essayez de calculer mentalement la multiplication des deux nombres premiers suivants.
$11 \times 13 = ?$
C&amp;rsquo;est facile. La réponse est $143$.&lt;/p>
&lt;p>Alors, qu&amp;rsquo;en est-il du nombre suivant ?
Décomposez $323$ en facteurs premiers.
Qu&amp;rsquo;en pensez-vous ? Cela devrait prendre un peu plus de temps. (La réponse est $17 \times 19$).&lt;/p>
&lt;p>Si les nombres sont petits, les humains peuvent s&amp;rsquo;en sortir d&amp;rsquo;une manière ou d&amp;rsquo;une autre, mais lorsque les nombres deviennent grands, les calculs deviennent explosivement difficiles, même avec des ordinateurs. Dans la cryptographie RSA principalement utilisée aujourd&amp;rsquo;hui, on utilise un nombre $N = p \times q$, qui est le produit de deux nombres premiers immenses, $p$ et $q$, de 2048 bits (environ 600 chiffres en base 10).&lt;/p>
&lt;p>Lorsqu&amp;rsquo;on donne deux immenses nombres premiers $p$ et $q$, un ordinateur peut calculer $N$ en un instant (moins d&amp;rsquo;une milliseconde). Cependant, à l&amp;rsquo;inverse, si l&amp;rsquo;on ne donne que $N$, trouver les $p$ et $q$ originaux prendrait tellement de temps que même les superordinateurs les plus rapides actuels ne pourraient pas le résoudre en le calculant pendant des milliers de milliards d&amp;rsquo;années.&lt;/p>
&lt;p>Cette &lt;strong>« asymétrie de calcul (l&amp;rsquo;aller est facile, le retour est difficile) »&lt;/strong> devient le fondement qui crée la relation entre la clé publique et la clé privée.&lt;/p>
&lt;hr>
&lt;h2 id="3-base-mathématique-de-la-cryptographie-rsa-2--congruence-arithmétique-modulaire">3. Base mathématique de la cryptographie RSA 2 : Congruence (Arithmétique modulaire)
&lt;/h2>&lt;p>Les calculs de la cryptographie RSA ne se font pas dans le monde des additions et multiplications où les nombres deviennent infiniment grands comme nous en avons l&amp;rsquo;habitude, mais dans le monde des « restes » après division par un certain nombre. C&amp;rsquo;est ce qu&amp;rsquo;on appelle la &lt;strong>congruence (ou arithmétique modulaire)&lt;/strong>.&lt;/p>
&lt;h3 id="31-les-mathématiques-de-lhorloge">3.1 Les mathématiques de l&amp;rsquo;horloge
&lt;/h3>&lt;p>L&amp;rsquo;arithmétique modulaire est souvent comparée aux « mathématiques de l&amp;rsquo;horloge ». S&amp;rsquo;il est 10 heures actuellement, quelle heure sera-t-il dans 5 heures ? $10 + 5 = 15$ heures, mais sur une horloge classique de 12 heures, on répond « 3 heures ». C&amp;rsquo;est parce que le reste de la division de 15 par 12 est 3.&lt;/p>
&lt;p>Dans le monde mathématique, on écrit cela comme suit :
&lt;/p>
$$ 15 \equiv 3 \pmod{12} $$
&lt;p>
Cela se lit « 15 est congru à 3 modulo 12 (le reste de la division par 12 est égal) ».&lt;/p>
&lt;h3 id="32-propriétés-fondamentales-des-congruences">3.2 Propriétés fondamentales des congruences
&lt;/h3>&lt;p>Les congruences ont des propriétés très pratiques qui ressemblent beaucoup à celles des équations ($=$). Soit $N$ le module (le diviseur).
Lorsque $a \equiv b \pmod N$ et $c \equiv d \pmod N$, ce qui suit est vrai :&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Addition :&lt;/strong> $a + c \equiv b + d \pmod N$&lt;/li>
&lt;li>&lt;strong>Soustraction :&lt;/strong> $a - c \equiv b - d \pmod N$&lt;/li>
&lt;li>&lt;strong>Multiplication :&lt;/strong> $a \times c \equiv b \times d \pmod N$&lt;/li>
&lt;li>&lt;strong>Exponentiation (puissance) :&lt;/strong> $a^k \equiv b^k \pmod N$ ($k$ est un entier naturel)&lt;/li>
&lt;/ol>
&lt;p>La propriété d&amp;rsquo;« exponentiation » est particulièrement importante. Elle signifie que &lt;strong>« le reste d&amp;rsquo;une puissance est égal à la puissance du reste »&lt;/strong>.
Par exemple, supposons que nous voulions trouver le reste de la division de $7^{100}$ par $5$. Il serait fastidieux de multiplier sérieusement $7$ cent fois avant de diviser par $5$, mais en utilisant la propriété des congruences, puisque $7 \equiv 2 \pmod 5$, on a $7^{100} \equiv 2^{100} \pmod 5$, ce qui permet de simplifier considérablement le calcul. Dans le monde de la cryptographie, on manipule des puissances de très grands nombres, cette propriété est donc indispensable.&lt;/p>
&lt;hr>
&lt;h2 id="4-base-mathématique-de-la-cryptographie-rsa-3--la-fonction-deuler-et-le-théorème-deuler">4. Base mathématique de la cryptographie RSA 3 : La fonction d&amp;rsquo;Euler et le théorème d&amp;rsquo;Euler
&lt;/h2>&lt;p>Voici la mathématique magique qui est au cœur de la cryptographie RSA. Le « théorème d&amp;rsquo;Euler », qui est une généralisation du « petit théorème de Fermat », fait son apparition.&lt;/p>
&lt;h3 id="41-lindicatrice-deuler-phin">4.1 L&amp;rsquo;indicatrice d&amp;rsquo;Euler $\phi(N)$
&lt;/h3>&lt;p>La fonction indicatrice d&amp;rsquo;Euler (fonction $\phi$) est une fonction qui, pour un entier naturel $N$ donné, renvoie le &lt;strong>« nombre d&amp;rsquo;entiers naturels compris entre 1 et $N$ qui sont premiers avec $N$ (dont le plus grand commun diviseur est 1) »&lt;/strong>.&lt;/p>
&lt;p>Regardons quelques exemples.&lt;/p>
&lt;ul>
&lt;li>$\phi(5)$ : Parmi 1, 2, 3, 4, 5, les nombres premiers avec 5 sont 1, 2, 3, 4, soit 4 nombres. Donc, $\phi(5) = 4$.&lt;/li>
&lt;li>$\phi(6)$ : Parmi 1, 2, 3, 4, 5, 6, les nombres premiers avec 6 sont 1, 5, soit 2 nombres. Donc, $\phi(6) = 2$.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>【Propriété spéciale dans le cas d&amp;rsquo;un nombre premier】&lt;/strong>
Si $p$ est un nombre premier, tous les nombres de 1 à $p-1$ sont premiers avec $p$. Par conséquent,
&lt;/p>
$$ \phi(p) = p - 1 $$
&lt;p>&lt;strong>【Propriété spéciale dans le cas du produit de deux nombres premiers】&lt;/strong>
Pour deux nombres premiers distincts $p$ et $q$, si on pose $N = p \times q$, $\phi(N)$ peut être facilement calculée avec la formule suivante.
&lt;/p>
$$ \phi(N) = \phi(p) \times \phi(q) = (p - 1)(q - 1) $$
&lt;p>
Cette propriété agit comme la « porte dérobée secrète (trapdoor) » de la cryptographie RSA. La personne qui connaît $p$ et $q$ (le créateur de la clé) peut calculer $\phi(N)$ en un instant, mais une tierce personne qui ne connaît que $N$ ne peut pas trouver $\phi(N)$ sans factoriser $N$.&lt;/p>
&lt;h3 id="42-le-théorème-deuler">4.2 Le théorème d&amp;rsquo;Euler
&lt;/h3>&lt;p>Leonhard Euler a prouvé le magnifique théorème suivant en utilisant cette $\phi(N)$.&lt;/p>
&lt;p>&lt;strong>Théorème d&amp;rsquo;Euler :&lt;/strong>
Si les entiers $a$ et $N$ sont premiers entre eux, la congruence suivante est vraie :
&lt;/p>
$$ a^{\phi(N)} \equiv 1 \pmod N $$
&lt;p>C&amp;rsquo;est une propriété surprenante selon laquelle « si l&amp;rsquo;on multiplie un certain nombre $a$ par lui-même $\phi(N)$ fois et qu&amp;rsquo;on le divise par $N$, le reste sera toujours $1$ ». (Si $N$ est un nombre premier $p$, cela devient $a^{p-1} \equiv 1 \pmod p$, ce qui est appelé le petit théorème de Fermat).&lt;/p>
&lt;p>Transformons ce théorème d&amp;rsquo;Euler. Multiplions les deux côtés par $a$ une fois de plus.
&lt;/p>
$$ a^{\phi(N) + 1} \equiv a \pmod N $$
&lt;p>De plus, pour tout entier $k$, comme $a^{k \cdot \phi(N)}$ sera également égal à $1^k = 1$, l&amp;rsquo;équation suivante est vraie :
&lt;/p>
$$ a^{k \cdot \phi(N) + 1} \equiv a \pmod N $$
&lt;p>Cette équation est le principe fondamental qui permet à la magie de la cryptographie RSA de fonctionner : &lt;strong>« chiffrer puis déchiffrer permet de revenir à l&amp;rsquo;original »&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h2 id="5-algorithme-de-la-cryptographie-rsa--étapes-de-génération-de-clé-de-chiffrement-et-de-déchiffrement">5. Algorithme de la cryptographie RSA : Étapes de génération de clé, de chiffrement et de déchiffrement
&lt;/h2>&lt;p>Maintenant que nous avons les connaissances de base, examinons les étapes spécifiques de la cryptographie RSA. La cryptographie RSA est globalement divisée en trois phases : « 1. Génération de la clé », « 2. Chiffrement » et « 3. Déchiffrement ».&lt;/p>
&lt;div class="mermaid">flowchart TD
A1["1. Choisir les nombres premiers p, q"] --> A2["Calculer N = p × q"]
A1 --> A3["Calculer φ(N) = (p-1)(q-1)"]
A3 --> A4["Choisir e premier avec φ(N)"]
A3 --> A5["Calculer d tel que e × d ≡ 1 (mod φ(N))"]
A2 --> A6["Clé publique (N, e)"]
A4 --> A6
A5 --> A7["Clé privée d"]
B1["2. Message en texte clair M"] --> B2["Calculer C ≡ M^e (mod N)"]
A6 -.-> B2
B2 --> B3["Envoyer le texte chiffré C"]
B3 --> C1["3. Texte chiffré reçu C"]
C1 --> C2["Calculer M ≡ C^d (mod N)"]
A7 -.-> C2
C2 --> C3["Obtenir le message en texte clair d'origine M"]&lt;/div>
&lt;h3 id="51-génération-de-clé-key-generation">5.1 Génération de clé (Key Generation)
&lt;/h3>&lt;p>Bob, qui est le destinataire, génère sa « clé publique » et sa « clé privée ».&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Sélection des nombres premiers :&lt;/strong> Il choisit aléatoirement deux grands nombres premiers $p$ et $q$.&lt;/li>
&lt;li>&lt;strong>Calcul du module $N$ :&lt;/strong> Il calcule $N = p \times q$. Ce $N$ est rendu public.&lt;/li>
&lt;li>&lt;strong>Calcul de $\phi(N)$ :&lt;/strong> Il calcule la fonction d&amp;rsquo;Euler $\phi(N) = (p - 1)(q - 1)$. C&amp;rsquo;est le nombre secret de Bob uniquement.&lt;/li>
&lt;li>&lt;strong>Sélection de la clé publique $e$ :&lt;/strong> Il choisit un entier $e$ tel que $1 &lt; e &lt; \phi(N)$ et qui est premier avec $\phi(N)$.&lt;/li>
&lt;li>&lt;strong>Calcul de la clé privée $d$ :&lt;/strong> Il trouve un entier $d$ qui satisfait la condition suivante.
$$ e \times d \equiv 1 \pmod{\phi(N)} $$
En d&amp;rsquo;autres termes, c&amp;rsquo;est « un nombre $d$ tel que le reste de $e \times d$ divisé par $\phi(N)$ est égal à $1$ ».&lt;/li>
&lt;/ol>
&lt;p>La préparation de la clé est maintenant terminée.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Clé publique :&lt;/strong> La paire $(N, e)$. Elle est publiée dans le monde entier.&lt;/li>
&lt;li>&lt;strong>Clé privée :&lt;/strong> $d$. Il ne le dit absolument à personne.&lt;/li>
&lt;/ul>
&lt;h3 id="52-chiffrement-encryption">5.2 Chiffrement (Encryption)
&lt;/h3>&lt;p>Supposons qu&amp;rsquo;Alice veuille envoyer un message secret $M$ à Bob. (On suppose que $M$ est un nombre représentant des caractères et $0 \le M &lt; N$). Alice utilise la clé publique de Bob $(N, e)$ et calcule comme suit :&lt;/p>
$$ C \equiv M^e \pmod N $$
&lt;p>Elle calcule « le reste $C$ de la division de la puissance $e$ du message $M$ par $N$ ». Ce $C$ est le texte chiffré.&lt;/p>
&lt;h3 id="53-déchiffrement-decryption">5.3 Déchiffrement (Decryption)
&lt;/h3>&lt;p>Bob reçoit le texte chiffré $C$. Bob utilise sa clé privée $d$ et calcule comme suit :&lt;/p>
$$ M \equiv C^d \pmod N $$
&lt;p>En calculant « le reste de la division de la puissance $d$ du texte chiffré $C$ par $N$ », étonnamment, le message d&amp;rsquo;origine $M$ est restauré !&lt;/p>
&lt;hr>
&lt;h2 id="6-pourquoi-le-déchiffrement-permet-il-de-revenir-à-loriginal--preuve-mathématique">6. Pourquoi le déchiffrement permet-il de revenir à l&amp;rsquo;original ? (Preuve mathématique)
&lt;/h2>&lt;p>Vous vous demandez peut-être : « Comment se fait-il que le simple fait d&amp;rsquo;élever $C$ à la puissance $d$ nous ramène au $M$ d&amp;rsquo;origine ? ». C&amp;rsquo;est ici que le « théorème d&amp;rsquo;Euler » que nous avons vu plus tôt entre en jeu.&lt;/p>
&lt;p>Substituons la formule de chiffrement $C = M^e$ dans la formule de déchiffrement $C^d \pmod N$.
&lt;/p>
$$ C^d \equiv (M^e)^d \equiv M^{ed} \pmod N $$
&lt;p>Rappelez-vous ici de l&amp;rsquo;étape 5 de la génération de clé. Lors de la création de $d$, Bob l&amp;rsquo;a choisi de sorte que $e \times d \equiv 1 \pmod{\phi(N)}$. Cela signifie que « $ed$ est un multiple de $\phi(N)$ plus $1$ ». En utilisant un entier $k$, on peut l&amp;rsquo;écrire comme suit :
&lt;/p>
$$ ed = k \cdot \phi(N) + 1 $$
&lt;p>Substituons cela dans l&amp;rsquo;exposant et décomposons-le en utilisant les lois des exposants.
&lt;/p>
$$ M^{ed} = M^{k \cdot \phi(N) + 1} = M^{k \cdot \phi(N)} \times M^1 = (M^{\phi(N)})^k \times M $$
&lt;p>Ici, en supposant que le message $M$ et $N$ sont premiers entre eux, d&amp;rsquo;après le &lt;strong>théorème d&amp;rsquo;Euler&lt;/strong>, on a $M^{\phi(N)} \equiv 1 \pmod N$.
&lt;/p>
$$ (M^{\phi(N)})^k \times M \equiv 1^k \times M \equiv M \pmod N $$
&lt;p>Par conséquent, la formule suivante est magnifiquement vérifiée.
&lt;/p>
$$ C^d \equiv M \pmod N $$
&lt;p>Alice ne connaît pas $d$, et les personnes sur écoute ne connaissent pas $d$ non plus, donc seul Bob, qui possède $d$, peut extraire $M$ de $C$.&lt;/p>
&lt;hr>
&lt;h2 id="7-exemple-concret--faisons-lexpérience-de-rsa-par-un-calcul-manuel-avec-de-petits-nombres-premiers">7. Exemple concret : Faisons l&amp;rsquo;expérience de RSA par un calcul manuel avec de petits nombres premiers
&lt;/h2>&lt;p>Faisons une communication chiffrée d&amp;rsquo;Alice à Bob en utilisant de petits nombres (nombres premiers) en pratique.&lt;/p>
&lt;p>&lt;strong>【Phase de génération de la clé de Bob】&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Choisir deux nombres premiers $p=11$, $q=13$.&lt;/li>
&lt;li>Calculer $N = 11 \times 13 = 143$.&lt;/li>
&lt;li>Calculer $\phi(N) = (11 - 1) \times (13 - 1) = 10 \times 12 = 120$.&lt;/li>
&lt;li>Choisir une clé publique $e$ première avec $\phi(N)=120$. Prenons ici $e=7$.&lt;/li>
&lt;li>Trouver la clé privée $d$. Chercher $d$ tel que $7 \times d \equiv 1 \pmod{120}$.
Dans l&amp;rsquo;équation $7d = 120k + 1$, pour $k=6$, on obtient $721$, et $721 \div 7 = 103$.
Donc, $d = 103$.&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>Clé publique : $(N=143, e=7)$&lt;/li>
&lt;li>Clé privée : $d=103$&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>【Phase de chiffrement d&amp;rsquo;Alice】&lt;/strong>
Supposons que nous voulions envoyer le message $M = 9$.
Formule : $C \equiv 9^7 \pmod{143}$
$9^7 = 4,782,969$. Divisé par 143, cela donne $33447$ avec un reste de $48$.
Le texte chiffré est devenu $C = 48$.&lt;/p>
&lt;p>&lt;strong>【Phase de déchiffrement de Bob】&lt;/strong>
Bob reçoit le texte chiffré $C = 48$ et le déchiffre à l&amp;rsquo;aide de sa clé privée $d = 103$.
Formule : $M \equiv 48^{103} \pmod{143}$
Si vous exécutez &lt;code>(48 ** 103) % 143&lt;/code> sur une calculatrice, le résultat est magnifiquement « &lt;strong>9&lt;/strong> » ! Il a pu recevoir avec succès le message d&amp;rsquo;origine.&lt;/p>
&lt;hr>
&lt;h2 id="8-comment-trouver-la-clé-privée-d--lalgorithme-deuclide-étendu">8. Comment trouver la clé privée $d$ : L&amp;rsquo;algorithme d&amp;rsquo;Euclide étendu
&lt;/h2>&lt;p>Dans l&amp;rsquo;exemple de calcul manuel, nous avons trouvé $k$ par intuition pour découvrir $d=103$, mais cette méthode est impossible lorsque les nombres atteignent des centaines de chiffres. Dans les programmes réels, nous utilisons un algorithme appelé &lt;strong>« algorithme d&amp;rsquo;Euclide étendu »&lt;/strong>.&lt;/p>
&lt;p>Résoudre $7d \equiv 1 \pmod{120}$ équivaut à trouver des entiers $d, y$ qui satisfont $7d + 120y = 1$. En calculant à l&amp;rsquo;envers avec l&amp;rsquo;algorithme d&amp;rsquo;Euclide, nous pouvons le trouver mécaniquement.&lt;/p>
&lt;ol>
&lt;li>$120 \div 7 = 17$ reste $1$&lt;/li>
&lt;li>En transformant cela, $1 = 120 - 17 \times 7$&lt;/li>
&lt;li>En d&amp;rsquo;autres termes, $-17 \times 7 \equiv 1 \pmod{120}$&lt;/li>
&lt;/ol>
&lt;p>$-17$ signifie la même chose que $120 - 17 = 103$ dans le monde du modulo $120$. Par conséquent, on trouve $d = 103$ en un instant. Cette méthode permet de calculer très rapidement même pour des nombres extrêmement grands.&lt;/p>
&lt;hr>
&lt;h2 id="9-lautre-visage-de-la-cryptographie-rsa--les-signatures-numériques">9. L&amp;rsquo;autre visage de la cryptographie RSA : Les signatures numériques
&lt;/h2>&lt;p>Ce qui est merveilleux avec la cryptographie RSA, c&amp;rsquo;est qu&amp;rsquo;en inversant les rôles de la clé publique et de la clé privée, on peut aussi l&amp;rsquo;utiliser comme &lt;strong>« signature numérique »&lt;/strong>.&lt;/p>
&lt;p>Pour le chiffrement, c&amp;rsquo;était « chiffrement avec la clé publique $\Rightarrow$ déchiffrement avec la clé privée », mais
pour la signature numérique, on suit les étapes : « chiffrement avec la clé privée $\Rightarrow$ déchiffrement avec la clé publique ».&lt;/p>
&lt;div class="mermaid">flowchart TD
A1["1. Alice crée une signature avec sa clé privée"] --> A2["S ≡ M^d (mod N)"]
A2 --> A3["Envoyer le message M et la signature S"]
A3 --> B1["2. Bob vérifie la signature avec la clé publique"]
B1 --> B2["Calculer M' ≡ S^e (mod N)"]
B2 --> B3["Vérifier si M' et M correspondent"]&lt;/div>
&lt;p>Alice convertit le message en utilisant sa propre clé privée $d$ (c&amp;rsquo;est la signature $S$) et l&amp;rsquo;envoie à Bob. Bob effectue le calcul de vérification en utilisant la clé publique $e$ d&amp;rsquo;Alice. Si le résultat du calcul correspond au message d&amp;rsquo;origine, cela prouve simultanément que « ce sont des données qui ne peuvent être créées qu&amp;rsquo;avec la clé privée d&amp;rsquo;Alice » et que « le message n&amp;rsquo;a pas été falsifié en cours de route ».&lt;/p>
&lt;hr>
&lt;h2 id="10-expérimenter-la-cryptographie-rsa-avec-la-programmation">10. Expérimenter la cryptographie RSA avec la programmation
&lt;/h2>&lt;p>Même les calculs de puissance qui sont difficiles à faire à la main peuvent être très facilement implémentés avec Python. Voici un code Python qui vous permet d&amp;rsquo;expérimenter la logique de base de la cryptographie RSA.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Trouver le plus grand commun diviseur&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">mod_inverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Trouver la clé privée d (utilisation de la fonction intégrée à partir de Python 3.8)&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. Génération de clé&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">11&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">13&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">N&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">q&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">phi&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">e&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">7&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">d&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_inverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Clé publique : (N=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, e=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">), Clé privée : d=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">d&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. Chiffrement&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">message&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ciphertext&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">message&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Texte chiffré : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">ciphertext&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Déchiffrement&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">decrypted_message&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ciphertext&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Message déchiffré : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">decrypted_message&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>La fonction &lt;code>pow(base, exp, mod)&lt;/code> de Python utilise un algorithme rapide appelé « exponentiation rapide (par carrés successifs) » en interne, de sorte que même pour des nombres de centaines de chiffres, le calcul se termine en un clin d&amp;rsquo;œil.&lt;/p>
&lt;hr>
&lt;h2 id="11-résumé-et-avenir-des-technologies-cryptographiques">11. Résumé et avenir des technologies cryptographiques
&lt;/h2>&lt;p>Nous avons percé les secrets du mécanisme de la cryptographie RSA, en nous basant sur les connaissances mathématiques du lycée.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>La difficulté de la décomposition en facteurs premiers :&lt;/strong> Il est facile de calculer $p \times q = N$, mais il est très difficile de trouver $p, q$ à partir de $N$.&lt;/li>
&lt;li>&lt;strong>Congruence et théorème d&amp;rsquo;Euler :&lt;/strong> Grâce à la règle $a^{\phi(N)} \equiv 1 \pmod N$, la porte dérobée magique « revenir à l&amp;rsquo;original lorsqu&amp;rsquo;on élève à une certaine puissance » est achevée.&lt;/li>
&lt;li>&lt;strong>Clé publique et clé privée :&lt;/strong> N&amp;rsquo;importe qui peut chiffrer, mais seul le destinataire légitime peut déchiffrer.&lt;/li>
&lt;/ol>
&lt;p>Le $N$ de la cryptographie RSA actuellement utilisé comporte plus de 600 chiffres, et même si on mobilisait tous les superordinateurs du monde, la décomposition en facteurs premiers prendrait plus de temps que l&amp;rsquo;âge de l&amp;rsquo;univers. Cependant, si les « ordinateurs quantiques » dont la recherche a progressé ces dernières années deviennent un jour utilisables en pratique, cette décomposition pourrait être résolue en un instant grâce à l&amp;rsquo;« algorithme de Shor ». Pour cette raison, le développement d&amp;rsquo;une « cryptographie post-quantique », qui ne pourrait pas être cassée même par des ordinateurs quantiques, avance rapidement partout dans le monde.&lt;/p>
&lt;p>Les mathématiques avancées, souvent perçues comme « inutiles », protègent en réalité fondamentalement notre vie quotidienne. La cryptographie RSA est le meilleur matériel pédagogique qui nous enseigne la profondeur et la beauté de telles mathématiques. J&amp;rsquo;espère qu&amp;rsquo;à travers cet article, vous avez pu ressentir, ne serait-ce qu&amp;rsquo;un peu, l&amp;rsquo;intérêt de la cryptographie et des mathématiques.&lt;/p></description></item></channel></rss>