<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RSA on kenji.blog</title><link>http://kenji.blog/fr/tags/rsa/</link><description>Recent content in RSA on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 22:09:21 +0900</lastBuildDate><atom:link href="http://kenji.blog/fr/tags/rsa/index.xml" rel="self" type="application/rss+xml"/><item><title>Les ordinateurs quantiques vont-ils vraiment détruire le cryptage RSA ? ~ L'algorithme de Shor et les avancées actuelles ~</title><link>http://kenji.blog/fr/p/shors-algorithm-and-rsa-breaking/</link><pubDate>Sat, 05 Sep 2026 22:09:21 +0900</pubDate><guid>http://kenji.blog/fr/p/shors-algorithm-and-rsa-breaking/</guid><description>&lt;img src="http://kenji.blog/p/shors-algorithm-and-rsa-breaking/quantum_breaking_rsa_1788613722990.jpg" alt="Featured image of post Les ordinateurs quantiques vont-ils vraiment détruire le cryptage RSA ? ~ L'algorithme de Shor et les avancées actuelles ~" />&lt;h2 id="introduction--à-la-croisée-de-la-cryptographie-et-de-linformatique-quantique">Introduction : À la croisée de la cryptographie et de l&amp;rsquo;informatique quantique
&lt;/h2>&lt;p>Dans la société Internet moderne, la cryptographie à clé publique est la base de la protection du secret des communications. Le représentant le plus célèbre est le &amp;ldquo;cryptage RSA&amp;rdquo;, développé en 1977 par Ron Rivest, Adi Shamir et Leonard Adleman. Du paiement des achats en ligne que nous utilisons tous les jours, à la navigation sur des sites Web (HTTPS), en passant par l&amp;rsquo;envoi et la réception d&amp;rsquo;e-mails, le cryptage RSA fonctionne comme le cœur de l&amp;rsquo;infrastructure Internet.&lt;/p>
&lt;p>Cependant, avec l&amp;rsquo;avènement de l&amp;rsquo;&amp;ldquo;ordinateur quantique&amp;rdquo;, il a été souligné que cette sécurité pourrait être fondamentalement bouleversée. Dans les médias, on voit parfois des gros titres sensationnels comme : &amp;ldquo;Une fois l&amp;rsquo;ordinateur quantique achevé, les mots de passe et les cryptages du monde entier seront décryptés en quelques secondes&amp;rdquo;. Est-ce vraiment le cas ?&lt;/p>
&lt;p>Cet article se penche sur les mécanismes de la méthode classique de décryptage GNFS (Crible du corps de nombres généralisé) et sur l&amp;rsquo;algorithme définitif de décryptage utilisant des ordinateurs quantiques, l&amp;rsquo;&amp;ldquo;Algorithme de Shor&amp;rdquo; (Shor&amp;rsquo;s Algorithm). Nous expliquerons de manière simple des concepts avancés tels que la transformée de Fourier quantique et la recherche de période, et examinerons en détail l&amp;rsquo;état actuel du matériel quantique à l&amp;rsquo;ère NISQ (Noisy Intermediate-Scale Quantum) ainsi que les obstacles nécessaires pour briser réellement le RSA-2048.&lt;/p>
&lt;hr>
&lt;h2 id="les-fondements-du-cryptage-rsa--la-difficulté-de-la-factorisation-en-nombres-premiers">Les fondements du cryptage RSA : La difficulté de la factorisation en nombres premiers
&lt;/h2>&lt;p>La sécurité du cryptage RSA repose sur une asymétrie mathématique extrêmement simple. Il s&amp;rsquo;agit du fait qu&amp;rsquo; &amp;ldquo;il est facile de multiplier deux nombres premiers géants, mais il est extrêmement difficile de retrouver les deux nombres premiers originaux (factorisation) à partir du résultat de cette multiplication (nombre composé)&amp;rdquo;.&lt;/p>
&lt;p>Par exemple, supposons qu&amp;rsquo;il y ait deux nombres premiers, $ p = 61 $ et $ q = 53 $. Le calcul de leur multiplication $ N = p \times q = 3233 $ est instantané. Cependant, si on ne vous donne que le nombre &amp;ldquo;3233&amp;rdquo; et qu&amp;rsquo;on vous demande &amp;ldquo;quelle est la multiplication de quels nombres premiers ?&amp;rdquo;, la complexité du calcul augmente de façon explosive à mesure que les nombres s&amp;rsquo;agrandissent.&lt;/p>
&lt;p>Dans le RSA-2048, actuellement dominant, on utilise une longueur de clé de 2048 bits, c&amp;rsquo;est-à-dire un nombre composé géant $ N $ d&amp;rsquo;environ 617 chiffres en base 10. Si l&amp;rsquo;on parvient à factoriser ce $ N $, le cryptage sera considéré comme déchiffré.&lt;/p>
&lt;h3 id="le-défi-des-ordinateurs-classiques--gnfs-crible-du-corps-de-nombres-généralisé">Le défi des ordinateurs classiques : GNFS (Crible du corps de nombres généralisé)
&lt;/h3>&lt;p>Pour résoudre le problème de la factorisation, les mathématiciens et les cryptographes ont développé divers algorithmes au fil des ans. Parmi eux, le plus rapide actuellement sur les ordinateurs classiques est le ** Crible du corps de nombres généralisé (GNFS : General Number Field Sieve) **.&lt;/p>
&lt;p>GNFS est une méthode qui étend les calculs dans l&amp;rsquo;anneau des entiers à un corps algébrique plus abstrait (Number Field) afin de factoriser un nombre géant $ N $. Le processus général est le suivant :&lt;/p>
&lt;ol>
&lt;li>** Sélection de polynômes ** : Trouver un polynôme $ f(x) $ avec un degré et des coefficients appropriés qui a $ N $ comme racine.&lt;/li>
&lt;li>** Collecte de données (criblage) ** : Rechercher un grand nombre de paires de nombres qui peuvent être décomposées en petits nombres premiers (nombres friables, Smooth numbers) sur le corps des rationnels et des corps algébriques. Ce processus est appelé &amp;ldquo;criblage&amp;rdquo; et est la partie la plus chronophage.&lt;/li>
&lt;li>** Génération et réduction de matrices ** : Générer une matrice creuse géante (une matrice dont la plupart des éléments sont 0) sur la base des relations collectées, et trouver une solution à l&amp;rsquo;aide de méthodes d&amp;rsquo;algèbre linéaire (comme la méthode de Lanczos par blocs).&lt;/li>
&lt;li>** Calcul des racines carrées ** : Enfin, calculer la racine carrée sur le corps algébrique pour dériver les facteurs (facteurs premiers) de $ N $.&lt;/li>
&lt;/ol>
&lt;p>La complexité de GNFS est évaluée de manière non asymptotique à $ O(\exp((\sqrt[3]{\frac{64}{9}} + o(1)) (\log N)^{\frac{1}{3}} (\log \log N)^{\frac{2}{3}})) $. C&amp;rsquo;est ce qu&amp;rsquo;on appelle une complexité temporelle &amp;ldquo;sous-exponentielle&amp;rdquo; (Sub-exponential). Bien que plus rapide qu&amp;rsquo;un temps exponentiel, c&amp;rsquo;est une complexité beaucoup plus lente qu&amp;rsquo;un temps polynomial (Polynomial time).&lt;/p>
&lt;p>En fait, en 2020, une équipe de recherche internationale a réussi à factoriser le RSA-250 (un nombre composé de 829 bits et 250 chiffres) en utilisant GNFS. Ce calcul a nécessité un temps de calcul énorme d&amp;rsquo;environ 2700 cœurs-années de CPU en rassemblant les ressources informatiques du monde entier. Cependant, lorsqu&amp;rsquo;il s&amp;rsquo;agit de 2048 bits, on dit que la complexité de calcul requise gonflerait jusqu&amp;rsquo;à des billions de fois l&amp;rsquo;âge de l&amp;rsquo;univers, et peu importe le nombre de superordinateurs actuels fonctionnant en parallèle, il est impossible de le décrypter dans un temps réaliste avec des méthodes classiques.&lt;/p>
&lt;hr>
&lt;h2 id="latout-des-ordinateurs-quantiques--lalgorithme-de-shor">L&amp;rsquo;atout des ordinateurs quantiques : L&amp;rsquo;algorithme de Shor
&lt;/h2>&lt;p>C&amp;rsquo;est ici qu&amp;rsquo;intervient l&amp;rsquo;&amp;ldquo;Algorithme de Shor&amp;rdquo;, présenté par Peter Shor en 1994. Cet algorithme était révolutionnaire car il permettait de résoudre le problème de la factorisation sur un ordinateur quantique en ** temps polynomial ** ( $ O((\log N)^3) $ ). La différence entre le temps sous-exponentiel et le temps polynomial est décisive et signifie qu&amp;rsquo;en théorie, les ordinateurs quantiques détruiront complètement le cryptage RSA.&lt;/p>
&lt;h3 id="flux-global-de-lalgorithme-de-shor">Flux global de l&amp;rsquo;algorithme de Shor
&lt;/h3>&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">graph TD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[Entrez le nombre N à factoriser] --&amp;gt; B[Sélectionnez un entier aléatoire a]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C{Le PGCD&amp;lt;br&amp;gt;de a et N}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|Supérieur à 1| D[Par chance, un facteur premier est trouvé !]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|1 Premiers entre eux| E[C&amp;#39;est au tour de l&amp;#39;ordinateur quantique]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> E --&amp;gt; F[Trouver la période r de la fonction f_x = a^x mod N&amp;lt;br&amp;gt;par transformée de Fourier quantique]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> F --&amp;gt; G{La période r est paire ET&amp;lt;br&amp;gt;a^r/2 ≢ -1 mod N}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|Oui| H[Calculer le PGCD gcd_a^r/2 ± 1, N]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H --&amp;gt; I((Factorisation réussie !))
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|Non| B
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>L&amp;rsquo;algorithme de Shor ne résout pas directement le problème de la factorisation, mais utilise des théorèmes de la théorie des nombres pour le convertir en un autre problème appelé &amp;ldquo;problème de recherche de période&amp;rdquo; (Period Finding Problem), puis utilise les caractéristiques des ordinateurs quantiques pour le résoudre rapidement.&lt;/p>
&lt;h3 id="étape-1--réduction-de-la-factorisation-au-problème-de-recherche-de-période-traitement-classique">Étape 1 : Réduction de la factorisation au problème de recherche de période (Traitement classique)
&lt;/h3>&lt;p>La première étape de l&amp;rsquo;algorithme est exécutée sur un ordinateur classique.
Pour le nombre $ N $ à factoriser, choisissez un entier aléatoire $ a $ ($ 1 &lt; a &lt; N $) premier avec $ N $ (le plus grand commun diviseur est 1). Si, par hasard, le plus grand commun diviseur n&amp;rsquo;est pas 1, le diviseur commun trouvé à ce moment-là est un facteur premier de $ N $, et le décryptage est terminé, mais la probabilité est extrêmement faible.&lt;/p>
&lt;p>Ensuite, considérez la suite d&amp;rsquo;équations modulo suivante :
$ f(x) = a^x \pmod N $&lt;/p>
&lt;p>En substituant $ x = 1, 2, 3, \dots $ dans cette fonction $ f(x) $, les valeurs semblent aléatoires, mais puisqu&amp;rsquo;elles sont calculées dans une plage finie, elles reviendront toujours à la valeur d&amp;rsquo;origine à un moment donné et répéteront la même suite de nombres. La période de cette répétition est appelée $ r $. En d&amp;rsquo;autres termes,
$ a^r \equiv 1 \pmod N $
Le problème de trouver le plus petit entier positif $ r $ qui satisfait cette condition est le &amp;ldquo;problème de recherche de période&amp;rdquo;.&lt;/p>
&lt;p>Si cette période $ r $ est trouvée et que $ r $ est pair, alors $ a^r - 1 \equiv 0 \pmod N $, et en utilisant la formule de factorisation, on peut la transformer en
$ (a^{r/2} - 1)(a^{r/2} + 1) \equiv 0 \pmod N $
À partir de là, en utilisant l&amp;rsquo;algorithme d&amp;rsquo;Euclide pour calculer le plus grand commun diviseur de $ N $ et de $ a^{r/2} \pm 1 $, les facteurs premiers de $ N $ peuvent être obtenus avec une probabilité extrêmement élevée.&lt;/p>
&lt;p>En fin de compte, pour trouver la période $ r $ avec un ordinateur classique, des étapes exponentielles sont nécessaires et ne peuvent pas être accélérées. Cependant, avec un ordinateur quantique, cette période $ r $ peut être trouvée instantanément (en temps polynomial).&lt;/p>
&lt;h3 id="étape-2--préparation-de-létat-quantique-et-superposition">Étape 2 : Préparation de l&amp;rsquo;état quantique et superposition
&lt;/h3>&lt;p>C&amp;rsquo;est ici qu&amp;rsquo;interviennent les ordinateurs quantiques.
Les ordinateurs quantiques utilisent des &amp;ldquo;qubits&amp;rdquo; qui peuvent avoir simultanément les états &amp;ldquo;0&amp;rdquo; et &amp;ldquo;1&amp;rdquo;. L&amp;rsquo;algorithme de Shor prépare deux registres : un registre pour stocker les entrées (premier registre) et un registre pour stocker les résultats du calcul (deuxième registre).&lt;/p>
&lt;p>Tout d&amp;rsquo;abord, une opération de porte quantique appelée porte de Hadamard est appliquée à tous les qubits du premier registre. En conséquence, le premier registre sera dans un ** état de superposition uniforme ** de toutes les valeurs possibles de $ x $ (de $ 0 $ à $ 2^n-1 $. $ n $ est un nombre de bits suffisamment grand).&lt;/p>
&lt;p>En d&amp;rsquo;autres termes, un état est créé à l&amp;rsquo;intérieur de l&amp;rsquo;ordinateur quantique où un nombre infini de valeurs d&amp;rsquo;entrée, $ x = 0, 1, 2, 3, \dots $, existent simultanément et en parallèle.&lt;/p>
&lt;h3 id="étape-3--exponentiation-modulaire-quantique-quantum-modular-exponentiation">Étape 3 : Exponentiation modulaire quantique (Quantum Modular Exponentiation)
&lt;/h3>&lt;p>Ensuite, en prenant l&amp;rsquo;état de superposition du premier registre comme entrée, calculez $ f(x) = a^x \pmod N $ et stockez le résultat dans le deuxième registre.
Étant donné que ce calcul est exécuté sous forme de transformation unitaire sur un circuit quantique, le calcul de $ f(x) $ pour tout $ x $ est effectué &amp;ldquo;simultanément et en parallèle (parallélisme quantique)&amp;rdquo; tout en maintenant la superposition.&lt;/p>
&lt;p>L&amp;rsquo;espace de l&amp;rsquo;ensemble du système quantique à ce stade est une vaste superposition d&amp;rsquo;états :
$ |x, a^x \bmod N\rangle $&lt;/p>
&lt;p>Cependant, si l&amp;rsquo;on se contente de mesurer (observer) le deuxième registre à ce stade, seule une valeur aléatoire de $ a^x \bmod N $ sera choisie de manière probabiliste, et en conjonction avec cela, le $ x $ du premier registre sera également fixé à une seule valeur. Cela équivaut à calculer une seule fois sur un ordinateur classique et ne permet pas de trouver la période $ r $.&lt;/p>
&lt;p>Selon les règles de la mécanique quantique, vous ne pouvez pas regarder directement à l&amp;rsquo;intérieur d&amp;rsquo;un état superposé. Alors, comment extraire l&amp;rsquo;information globale de &amp;ldquo;période&amp;rdquo; de l&amp;rsquo;ensemble ?&lt;/p>
&lt;h3 id="étape-4--transformée-de-fourier-quantique-qft-quantum-fourier-transform">Étape 4 : Transformée de Fourier quantique (QFT: Quantum Fourier Transform)
&lt;/h3>&lt;p>La véritable valeur de l&amp;rsquo;algorithme de Shor, qui permet de franchir ce mur, est l&amp;rsquo;application de la ** Transformée de Fourier Quantique (QFT) ** au premier registre.&lt;/p>
&lt;p>Avant de mesurer, on analyse les propriétés ondulatoires de la fonction $ f(x) $. Supposons que nous observions le deuxième registre. Supposons qu&amp;rsquo;une valeur $ y $ soit obtenue. Ensuite, l&amp;rsquo;état du premier registre se réduit à la &amp;ldquo;superposition de tous les $ x $ tels que $ a^x \pmod N = y $&amp;rdquo;.
Les valeurs de ce $ x $ seront un état discret (une sorte de distribution d&amp;rsquo;amplitude de probabilité en forme de peigne) espacé par des intervalles de période $ r $, tel que $ x_0, x_0 + r, x_0 + 2r, x_0 + 3r, \dots $.&lt;/p>
&lt;p>La transformée de Fourier quantique (QFT) est appliquée à cet état. Tout comme la transformée de Fourier discrète classique convertit un signal dans le domaine temporel en domaine fréquentiel, la QFT provoque des interférences dans l&amp;rsquo;amplitude de probabilité des états quantiques.&lt;/p>
&lt;p>Lorsque la QFT est appliquée, en raison des effets d&amp;rsquo;interférence quantique, la probabilité de réponses incorrectes qui ne résonnent pas avec la période $ r $ (phases non alignées) s&amp;rsquo;annule mutuellement pour s&amp;rsquo;approcher de zéro (interférence destructive), et seule la probabilité de la réponse correcte contenant les informations de la période $ r $ est amplifiée (interférence constructive).&lt;/p>
&lt;h3 id="étape-5--mesure-et-expansion-en-fraction-continue-post-traitement-classique">Étape 5 : Mesure et expansion en fraction continue (Post-traitement classique)
&lt;/h3>&lt;p>Lorsque le premier registre est mesuré après l&amp;rsquo;application de la QFT, un entier $ c $ proche de la forme $ c \approx \frac{j \cdot 2^n}{r} $ est obtenu avec une probabilité très élevée ($ j $ est un entier inconnu et $ 2^n $ est la taille du registre).&lt;/p>
&lt;p>Ce résultat de mesure $ c $ est renvoyé à l&amp;rsquo;ordinateur classique pour créer la fraction $ \frac{c}{2^n} \approx \frac{j}{r} $. Ensuite, en calculant une valeur approximative à l&amp;rsquo;aide d&amp;rsquo;une méthode mathématique appelée &amp;ldquo;expansion en fraction continue&amp;rdquo; (Continued fraction expansion), on peut brillamment extraire le dénominateur, la période $ r $.&lt;/p>
&lt;p>Une fois que l&amp;rsquo;on connaît $ r $, il suffit de calculer les facteurs premiers de $ N $ en utilisant la formule de l&amp;rsquo;étape 1, et le cryptage RSA est complètement déchiffré.&lt;/p>
&lt;hr>
&lt;h2 id="capacités-et-défis-actuels-des-ordinateurs-quantiques-nisq">Capacités et défis actuels des ordinateurs quantiques (NISQ)
&lt;/h2>&lt;p>Bien que l&amp;rsquo;algorithme de Shor soit parfait en théorie, si l&amp;rsquo;on se demande &amp;ldquo;Le cryptage RSA sera-t-il brisé demain ?&amp;rdquo;, la réponse est clairement &amp;ldquo;Non&amp;rdquo;. La raison réside dans les limites de la technologie matérielle des ordinateurs quantiques actuels.&lt;/p>
&lt;h3 id="lère-nisq-noisy-intermediate-scale-quantum">L&amp;rsquo;ère NISQ (Noisy Intermediate-Scale Quantum)
&lt;/h3>&lt;p>L&amp;rsquo;ère dans laquelle nous nous trouvons actuellement est appelée l&amp;rsquo;ère &amp;ldquo;NISQ&amp;rdquo;. Les dispositifs NISQ possèdent de quelques dizaines à quelques centaines de qubits physiques, mais sont extrêmement vulnérables au bruit.&lt;/p>
&lt;p>Les qubits sont sensibles aux environnements externes tels que la chaleur et les ondes électromagnétiques, entraînant de fréquentes &amp;ldquo;décohérences&amp;rdquo; (pertes d&amp;rsquo;intrication quantique) où l&amp;rsquo;état quantique se brise, et des &amp;ldquo;erreurs de porte&amp;rdquo; lors des opérations de porte. Lorsque vous essayez d&amp;rsquo;exécuter un circuit quantique très profond (avec un nombre énorme d&amp;rsquo;étapes de calcul) comme l&amp;rsquo;algorithme de Shor, des erreurs s&amp;rsquo;accumulent pendant le calcul et la sortie finale devient un bruit complet et dénué de sens.&lt;/p>
&lt;h3 id="qubits-physiques-et-qubits-logiques">Qubits physiques et Qubits logiques
&lt;/h3>&lt;p>La &amp;ldquo;correction d&amp;rsquo;erreurs quantiques&amp;rdquo; (Quantum Error Correction) est essentielle pour résoudre ce problème d&amp;rsquo;erreur.
Des codes de correction d&amp;rsquo;erreurs sont également utilisés dans les ordinateurs classiques, mais comme il existe un &amp;ldquo;théorème de non-clonage quantique&amp;rdquo; qui interdit de copier les états quantiques, la correction d&amp;rsquo;erreurs quantiques est extrêmement complexe.&lt;/p>
&lt;p>Dans la correction d&amp;rsquo;erreurs quantiques, en utilisant des technologies telles que le &amp;ldquo;code de surface&amp;rdquo; (Surface Code), on combine un grand nombre de &amp;ldquo;qubits physiques&amp;rdquo; bruyants pour créer un seul &amp;ldquo;qubit logique&amp;rdquo; idéal et sans erreur.&lt;/p>
&lt;p>En supposant le taux d&amp;rsquo;erreur actuel, on estime qu&amp;rsquo;il faudrait entre 1 000 et 10 000 qubits physiques pour créer un seul qubit logique. On appelle cela la &amp;ldquo;surcharge de correction d&amp;rsquo;erreur&amp;rdquo;.&lt;/p>
&lt;h3 id="quelles-sont-les-ressources-nécessaires-pour-briser-le-rsa-2048-">Quelles sont les ressources nécessaires pour briser le RSA-2048 ?
&lt;/h3>&lt;p>Alors, combien de ressources sont nécessaires pour exécuter l&amp;rsquo;algorithme de Shor afin de décrypter réellement le RSA-2048 ?&lt;/p>
&lt;p>Selon une estimation révolutionnaire des ressources dans un article de 2021 de Craig Gidney (Google) et Martin Ekerå, si l&amp;rsquo;on utilise un algorithme de Shor optimisé et une correction d&amp;rsquo;erreur par code de surface, les ressources suivantes sont nécessaires :&lt;/p>
&lt;ul>
&lt;li>** Nombre de qubits logiques ** : environ 4 096&lt;/li>
&lt;li>** Nombre de qubits physiques ** : ** environ 20 millions ** (en supposant un taux d&amp;rsquo;erreur d&amp;rsquo;environ $10^{-3}$)&lt;/li>
&lt;li>** Temps de calcul ** : environ 8 heures (des millions à des milliards d&amp;rsquo;opérations de portes physiques sont nécessaires)&lt;/li>
&lt;/ul>
&lt;p>Face à cela, où en est le matériel quantique actuel ?
Le processeur quantique supraconducteur &amp;ldquo;Condor&amp;rdquo; annoncé par IBM fin 2023 compte 1 121 qubits. Par ailleurs, des recherches révolutionnaires sur la génération de qubits logiques ont émergé (telles que la génération de 48 qubits logiques à l&amp;rsquo;aide d&amp;rsquo;un ordinateur quantique à atomes neutres par l&amp;rsquo;Université de Harvard et QuEra, etc.), mais on n&amp;rsquo;en est pas encore au stade où des &amp;ldquo;calculs parfaits et sans bruit&amp;rdquo; peuvent être exécutés en continu pendant de longues périodes.&lt;/p>
&lt;p>Il existe des obstacles d&amp;rsquo;ingénierie colossaux (problèmes de câblage, limites de la capacité de refroidissement, hypertrophie de l&amp;rsquo;électronique de contrôle) pour passer de quelques milliers de qubits physiques à un système avec ** 20 millions ** de qubits physiques pratiques (interconnectés, fonctionnant de manière stable à des températures cryogéniques et capables de traiter les signaux de contrôle à des vitesses ultra-rapides). De nombreux experts prédisent qu&amp;rsquo;il faudra au moins 10 à 30 ans, ou plus, avant qu&amp;rsquo;un &amp;ldquo;ordinateur quantique tolérant aux pannes (FTQC)&amp;rdquo; capable de décrypter le RSA-2048 ne devienne une réalité.&lt;/p>
&lt;hr>
&lt;h2 id="la-menace-imminente-de-store-now-decrypt-later-et-laube-de-la-pqc">La menace imminente de &amp;ldquo;Store Now, Decrypt Later&amp;rdquo; et l&amp;rsquo;aube de la PQC
&lt;/h2>&lt;p>Il est prématuré de penser : &amp;ldquo;Nous sommes en sécurité car cela prendra encore plus de 10 ans&amp;rdquo;. À l&amp;rsquo;heure actuelle, il existe des données dont la confidentialité doit être garantie pendant des décennies, comme les secrets d&amp;rsquo;État, les données médicales et la conception d&amp;rsquo;infrastructures à long terme.&lt;/p>
&lt;p>Ce que l&amp;rsquo;on craint ici, c&amp;rsquo;est une méthode d&amp;rsquo;attaque appelée ** &amp;ldquo;Store Now, Decrypt Later&amp;rdquo; (Stockez maintenant, décryptez plus tard) **. Des pays ou des organisations malveillants interceptent toutes les données de communication cryptées avec le RSA ou ECC (cryptographie sur les courbes elliptiques) actuels et les stockent. Puis, 10 ou 20 ans plus tard, au moment où un puissant ordinateur quantique est achevé, ils utilisent l&amp;rsquo;algorithme de Shor pour décrypter toutes les données passées et révéler des secrets.&lt;/p>
&lt;p>Pour lutter contre cette menace de décalage temporel, le NIST (National Institute of Standards and Technology des États-Unis) a dirigé le processus de standardisation de la ** &amp;ldquo;Cryptographie post-quantique (PQC: Post-Quantum Cryptography)&amp;rdquo; ** à un rythme effréné.&lt;/p>
&lt;p>La PQC est un nouvel algorithme cryptographique basé sur des problèmes mathématiques difficiles à décrypter même à l&amp;rsquo;aide d&amp;rsquo;ordinateurs quantiques (c&amp;rsquo;est-à-dire que l&amp;rsquo;algorithme de Shor ne peut pas être appliqué). Les principales approches incluent :&lt;/p>
&lt;ul>
&lt;li>** Cryptographie basée sur les réseaux euclidiens (Lattice-based cryptography) ** : Basée sur des problèmes tels que LWE (Learning with Errors). Actuellement le courant dominant dans la standardisation du NIST (Kyber, Dilithium, etc.).&lt;/li>
&lt;li>** Cryptographie basée sur les codes (Code-based cryptography) ** : Repose sur la difficulté de décodage des codes correcteurs d&amp;rsquo;erreurs.&lt;/li>
&lt;li>** Cryptographie multivariée (Multivariate cryptography) ** : Repose sur la difficulté de résoudre un système d&amp;rsquo;équations quadratiques à plusieurs variables.&lt;/li>
&lt;li>** Signatures basées sur le hachage (Hash-based signatures) ** : Signatures numériques qui reposent uniquement sur la sécurité des fonctions de hachage.&lt;/li>
&lt;/ul>
&lt;p>Les principaux logiciels et plateformes tels que Google Chrome et Apple iMessage ont déjà commencé les tests de déploiement de la PQC et des implémentations hybrides.&lt;/p>
&lt;h2 id="conclusion">Conclusion
&lt;/h2>&lt;p>L&amp;rsquo;ordinateur quantique est passé d&amp;rsquo;un conte de fées de science-fiction à un véritable défi d&amp;rsquo;ingénierie. L&amp;rsquo;algorithme de Shor est une grande réalisation intellectuelle de l&amp;rsquo;humanité combinant les mathématiques et la mécanique quantique, mais en même temps, il cache un &amp;ldquo;pouvoir destructeur&amp;rdquo; qui ébranle les fondements de notre société numérique.&lt;/p>
&lt;p>Le cryptage RSA ne deviendra pas inutilisable dès demain. Cependant, compte tenu de l&amp;rsquo;évolution de la technologie quantique et du risque du &amp;ldquo;Store Now, Decrypt Later&amp;rdquo;, une migration massive vers la PQC, qui restera dans l&amp;rsquo;histoire de la cryptographie, a déjà commencé. Nous sommes actuellement témoins d&amp;rsquo;un changement de paradigme en matière de sécurité de l&amp;rsquo;information.&lt;/p></description></item><item><title>【Anatomie Complète】Comprendre et implémenter l'algorithme de décryptage ultime « GNFS » en C++</title><link>http://kenji.blog/fr/p/gnfs-cpp-implementation/</link><pubDate>Sat, 05 Sep 2026 13:04:59 +0900</pubDate><guid>http://kenji.blog/fr/p/gnfs-cpp-implementation/</guid><description>&lt;img src="http://kenji.blog/p/gnfs-cpp-implementation/gnfs_cpp_blog_eyecatch_1788580949217.jpg" alt="Featured image of post 【Anatomie Complète】Comprendre et implémenter l'algorithme de décryptage ultime « GNFS » en C++" />&lt;h1 id="anatomie-complètecomprendre-et-implémenter-lalgorithme-de-décryptage-ultime--gnfs--en-c">【Anatomie Complète】Comprendre et implémenter l&amp;rsquo;algorithme de décryptage ultime « GNFS » en C++
&lt;/h1>&lt;p>La cryptographie RSA, qui soutient l&amp;rsquo;Internet moderne, repose sur une croyance mathématique : « il est virtuellement impossible pour les ordinateurs actuels de factoriser d&amp;rsquo;énormes nombres composés ».&lt;/p>
&lt;p>Cependant, l&amp;rsquo;humanité n&amp;rsquo;a jamais abandonné. Actuellement, pour les ordinateurs classiques (non quantiques), il existe &lt;strong>l&amp;rsquo;algorithme le plus puissant et le plus avancé de l&amp;rsquo;humanité&lt;/strong> pour effectuer des factorisations géantes. C&amp;rsquo;est le &lt;strong>« Crible Général du Corps de Nombres (GNFS : General Number Field Sieve) »&lt;/strong>.&lt;/p>
&lt;p>Dans cet article, nous publions entièrement le code d&amp;rsquo;implémentation modélisant strictement la logique de pointe de ce GNFS en C++ (utilisant les entiers à précision multiple &lt;code>boost::multiprecision&lt;/code> de la bibliothèque Boost), et nous expliquerons en profondeur la « théorie algébrique des nombres » qui se cache derrière.&lt;/p>
&lt;p>Appréciez les mystères mathématiques et la puissance de l&amp;rsquo;informatique qui les surmonte, à travers ce code source.&lt;/p>
&lt;hr>
&lt;h2 id="1-cadre-logique-de-pointe-du-gnfs-code-source-complet">1. Cadre logique de pointe du GNFS (Code source complet)
&lt;/h2>&lt;p>Tout d&amp;rsquo;abord, voici la vue d&amp;rsquo;ensemble de l&amp;rsquo;implémentation C++ du GNFS que nous allons expliquer. Le crible de corps de nombres réel (comme CADO-NFS) est un système distribué gigantesque de centaines de milliers de lignes, mais ce code extrait les &lt;strong>« 5 pipelines (phases) essentiels »&lt;/strong> constituant le GNFS, les conçoit en classes, et les modélise avec une configuration minimale sans perdre leur signification mathématique.&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;span class="lnt"> 87
&lt;/span>&lt;span class="lnt"> 88
&lt;/span>&lt;span class="lnt"> 89
&lt;/span>&lt;span class="lnt"> 90
&lt;/span>&lt;span class="lnt"> 91
&lt;/span>&lt;span class="lnt"> 92
&lt;/span>&lt;span class="lnt"> 93
&lt;/span>&lt;span class="lnt"> 94
&lt;/span>&lt;span class="lnt"> 95
&lt;/span>&lt;span class="lnt"> 96
&lt;/span>&lt;span class="lnt"> 97
&lt;/span>&lt;span class="lnt"> 98
&lt;/span>&lt;span class="lnt"> 99
&lt;/span>&lt;span class="lnt">100
&lt;/span>&lt;span class="lnt">101
&lt;/span>&lt;span class="lnt">102
&lt;/span>&lt;span class="lnt">103
&lt;/span>&lt;span class="lnt">104
&lt;/span>&lt;span class="lnt">105
&lt;/span>&lt;span class="lnt">106
&lt;/span>&lt;span class="lnt">107
&lt;/span>&lt;span class="lnt">108
&lt;/span>&lt;span class="lnt">109
&lt;/span>&lt;span class="lnt">110
&lt;/span>&lt;span class="lnt">111
&lt;/span>&lt;span class="lnt">112
&lt;/span>&lt;span class="lnt">113
&lt;/span>&lt;span class="lnt">114
&lt;/span>&lt;span class="lnt">115
&lt;/span>&lt;span class="lnt">116
&lt;/span>&lt;span class="lnt">117
&lt;/span>&lt;span class="lnt">118
&lt;/span>&lt;span class="lnt">119
&lt;/span>&lt;span class="lnt">120
&lt;/span>&lt;span class="lnt">121
&lt;/span>&lt;span class="lnt">122
&lt;/span>&lt;span class="lnt">123
&lt;/span>&lt;span class="lnt">124
&lt;/span>&lt;span class="lnt">125
&lt;/span>&lt;span class="lnt">126
&lt;/span>&lt;span class="lnt">127
&lt;/span>&lt;span class="lnt">128
&lt;/span>&lt;span class="lnt">129
&lt;/span>&lt;span class="lnt">130
&lt;/span>&lt;span class="lnt">131
&lt;/span>&lt;span class="lnt">132
&lt;/span>&lt;span class="lnt">133
&lt;/span>&lt;span class="lnt">134
&lt;/span>&lt;span class="lnt">135
&lt;/span>&lt;span class="lnt">136
&lt;/span>&lt;span class="lnt">137
&lt;/span>&lt;span class="lnt">138
&lt;/span>&lt;span class="lnt">139
&lt;/span>&lt;span class="lnt">140
&lt;/span>&lt;span class="lnt">141
&lt;/span>&lt;span class="lnt">142
&lt;/span>&lt;span class="lnt">143
&lt;/span>&lt;span class="lnt">144
&lt;/span>&lt;span class="lnt">145
&lt;/span>&lt;span class="lnt">146
&lt;/span>&lt;span class="lnt">147
&lt;/span>&lt;span class="lnt">148
&lt;/span>&lt;span class="lnt">149
&lt;/span>&lt;span class="lnt">150
&lt;/span>&lt;span class="lnt">151
&lt;/span>&lt;span class="lnt">152
&lt;/span>&lt;span class="lnt">153
&lt;/span>&lt;span class="lnt">154
&lt;/span>&lt;span class="lnt">155
&lt;/span>&lt;span class="lnt">156
&lt;/span>&lt;span class="lnt">157
&lt;/span>&lt;span class="lnt">158
&lt;/span>&lt;span class="lnt">159
&lt;/span>&lt;span class="lnt">160
&lt;/span>&lt;span class="lnt">161
&lt;/span>&lt;span class="lnt">162
&lt;/span>&lt;span class="lnt">163
&lt;/span>&lt;span class="lnt">164
&lt;/span>&lt;span class="lnt">165
&lt;/span>&lt;span class="lnt">166
&lt;/span>&lt;span class="lnt">167
&lt;/span>&lt;span class="lnt">168
&lt;/span>&lt;span class="lnt">169
&lt;/span>&lt;span class="lnt">170
&lt;/span>&lt;span class="lnt">171
&lt;/span>&lt;span class="lnt">172
&lt;/span>&lt;span class="lnt">173
&lt;/span>&lt;span class="lnt">174
&lt;/span>&lt;span class="lnt">175
&lt;/span>&lt;span class="lnt">176
&lt;/span>&lt;span class="lnt">177
&lt;/span>&lt;span class="lnt">178
&lt;/span>&lt;span class="lnt">179
&lt;/span>&lt;span class="lnt">180
&lt;/span>&lt;span class="lnt">181
&lt;/span>&lt;span class="lnt">182
&lt;/span>&lt;span class="lnt">183
&lt;/span>&lt;span class="lnt">184
&lt;/span>&lt;span class="lnt">185
&lt;/span>&lt;span class="lnt">186
&lt;/span>&lt;span class="lnt">187
&lt;/span>&lt;span class="lnt">188
&lt;/span>&lt;span class="lnt">189
&lt;/span>&lt;span class="lnt">190
&lt;/span>&lt;span class="lnt">191
&lt;/span>&lt;span class="lnt">192
&lt;/span>&lt;span class="lnt">193
&lt;/span>&lt;span class="lnt">194
&lt;/span>&lt;span class="lnt">195
&lt;/span>&lt;span class="lnt">196
&lt;/span>&lt;span class="lnt">197
&lt;/span>&lt;span class="lnt">198
&lt;/span>&lt;span class="lnt">199
&lt;/span>&lt;span class="lnt">200
&lt;/span>&lt;span class="lnt">201
&lt;/span>&lt;span class="lnt">202
&lt;/span>&lt;span class="lnt">203
&lt;/span>&lt;span class="lnt">204
&lt;/span>&lt;span class="lnt">205
&lt;/span>&lt;span class="lnt">206
&lt;/span>&lt;span class="lnt">207
&lt;/span>&lt;span class="lnt">208
&lt;/span>&lt;span class="lnt">209
&lt;/span>&lt;span class="lnt">210
&lt;/span>&lt;span class="lnt">211
&lt;/span>&lt;span class="lnt">212
&lt;/span>&lt;span class="lnt">213
&lt;/span>&lt;span class="lnt">214
&lt;/span>&lt;span class="lnt">215
&lt;/span>&lt;span class="lnt">216
&lt;/span>&lt;span class="lnt">217
&lt;/span>&lt;span class="lnt">218
&lt;/span>&lt;span class="lnt">219
&lt;/span>&lt;span class="lnt">220
&lt;/span>&lt;span class="lnt">221
&lt;/span>&lt;span class="lnt">222
&lt;/span>&lt;span class="lnt">223
&lt;/span>&lt;span class="lnt">224
&lt;/span>&lt;span class="lnt">225
&lt;/span>&lt;span class="lnt">226
&lt;/span>&lt;span class="lnt">227
&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;vector&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;cmath&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;map&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;set&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;chrono&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;boost/multiprecision/cpp_int.hpp&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="c1">// Utilisation des entiers à précision multiple de Boost.Multiprecision
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">boost&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">multiprecision&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">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// [SOTA GNFS] Cadre logique de pointe du General Number Field Sieve (Crible Général du Corps de Nombres)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">//
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Ce code modélise strictement les 5 pipelines du GNFS de pointe utilisés dans CADO-NFS etc.,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// en tant que conception de classes C++ (Boost).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Relation&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int64_t&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="kt">int64_t&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">rational_primes&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">algebraic_primes&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">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 1 : Sélection de polynômes (Algorithme de Kleinjung)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">PolynomialSelector&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Polynôme côté algébrique f(x)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">g&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Polynôme côté rationnel g(x) = x - m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">d&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Génération du polynôme initial basée sur l&amp;#39;expansion en base m (en réalité, une réduction de base de réseau LLL plus avancée est utilisée)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">N&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 1] Polynomial Selection (Degree &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">degree&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;) starting...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="c1">// Expansion simplifiée en base m (degré d)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// m = N^(1/d)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">N_copy&lt;/span> &lt;span class="o">=&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="n">m&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="c1">// Approximation simple de m (sans utiliser les fonctions de Boost)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">low&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">high&lt;/span> &lt;span class="o">=&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="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">low&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">high&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">cpp_int&lt;/span> &lt;span class="n">mid&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">high&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">low&lt;/span>&lt;span class="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="n">cpp_int&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>&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">degree&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="n">p&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="n">mid&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="n">N&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&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">else&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">high&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&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="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">f&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">degree&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">cpp_int&lt;/span> &lt;span class="n">temp&lt;/span> &lt;span class="o">=&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="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">degree&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="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">temp&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="n">temp&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="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">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// g(x) = x - m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; m = &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; f(x) = &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">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="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&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="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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;x^&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="s">&amp;#34; + &amp;#34;&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s">&amp;#34;&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="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">[Phase 1] Complete.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="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">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 2 : Crible de réseau (Lattice Sieving)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Le GNFS récent utilise, au lieu du crible linéaire (Line Sieve),
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// le crible de réseau spécial-q (Special-q Lattice Sieving) de Franke-Kleinjung etc., comme standard de facto.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">LatticeSieve&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">rational_bound&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">algebraic_bound&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">rational_fb&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">algebraic_fb&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">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LatticeSieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">rb&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">ab&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">rational_bound&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">rb&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">algebraic_bound&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ab&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">generate_factor_bases&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 2] Generating Factor Bases (Rational Bound: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">rational_bound&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;, Algebraic Bound: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">algebraic_bound&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;)&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="c1">// (Omis) En réalité, on génère des nombres premiers et on filtre avec le symbole de Legendre etc.
&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">poly&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 2] Special-q Lattice Sieving active...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">relations&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Implémentation factice : le crible de réseau réel scanne des centaines de Go d&amp;#39;espace mémoire par blocs.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Mappe les paires (a, b) sur un réseau (a = i*q + j*...) pour chaque nombre premier spécial q,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// et exécute un crible (sieve) avec une efficacité de cache maximisée.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Ajout d&amp;#39;une relation factice pour la démonstration
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Relation&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">17&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&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">3&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">rational_primes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&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="n">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">algebraic_primes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">relations&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 2] Found &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">relations&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; relations.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="k">return&lt;/span> &lt;span class="n">relations&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 3 : Filtrage (Purge des singularités et fusion de cliques)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">Filter&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="n">reduce_matrix&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 3] Filtering Relations...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="c1">// 1. Suppression des singletons (suppression des relations ayant des nombres premiers n&amp;#39;apparaissant qu&amp;#39;une fois)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 2. Fusion de cliques (combinaison de relations pour densifier une matrice creuse)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// En réalité, des algorithmes comme Union-Find compressent des centaines de millions de lignes à quelques millions.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 3] Matrix size reduced optimally.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="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">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 4 : Algèbre linéaire sur GF(2) (Méthode de Block Wiedemann)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">LinearAlgebraGF2&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Dans les environnements de supercalculateurs récents, la méthode de Block Wiedemann
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// (implémentation de Coppersmith), plus adaptée au calcul distribué que Block Lanczos, est utilisée à la pointe.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">solve_nullspace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 4] Block Wiedemann algorithm over GF(2) starting...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="c1">// Répète les opérations de produit entre une matrice creuse et un vecteur,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// et trouve plusieurs vecteurs solutions (noyau) tels que M * x = 0 mod 2.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">dependencies&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Liste des dépendances
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Données factices
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">dependencies&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">({&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 4] Found &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">dependencies&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; linear dependencies (perfect squares).&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="k">return&lt;/span> &lt;span class="n">dependencies&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 5 : Racine carrée algébrique (Algebraic Square Root)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">AlgebraicSquareRoot&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="n">compute_and_factor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">dep&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">N&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 5] Algebraic Square Root computation...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. Calcul de la racine carrée côté rationnel V (opérations entières simples)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">V&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="c1">// V = sqrt( prod(a - bm) ) mod N
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2. Calcul de la racine carrée côté algébrique gamma (méthode de Montgomery etc.)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Trouve l&amp;#39;élément gamma de l&amp;#39;énorme corps algébrique O_K et le mappe dans le monde réel par homomorphisme phi
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Y = phi(gamma) mod N
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">Y&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">// On suppose que des colonnes de caractères quadratiques (Quadratic Characters) ont été ajoutées
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// en Phase 2 et 4 pour éviter les obstructions du groupe des classes d&amp;#39;idéaux et du groupe des unités.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; Homomorphism map phi applied.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 5] Calculating GCD(V - Y, N)...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">factor&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">V&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">N&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// GCD(X-Y, N)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&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">factor&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">factor&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">N&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[SUCCESS] Non-trivial factor found: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">factor&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; Other factor: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">N&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">factor&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[FAILURE] Trivial solution. Trying next dependency...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="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">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Pipeline d&amp;#39;exécution principal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; [SOTA GNFS] General Number Field Sieve Engine (Boost C++) &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Nombre composé géant N à factoriser, ex. RSA-270
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;233108530344407544527637656910680524145619812480305449042948611968495918245135782867888369318577116418213919268572658314913060672626911354027609793166341626693946596196427744273886601876896313468704059066746903123910748277606548649151920812699309766587514735456594993207&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">// Degré du polynôme (généralement 5ème ou 6ème degré pour plus de 130 chiffres)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">degree&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">6&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">// Initialisation du pipeline
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span> &lt;span class="n">poly_select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">degree&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LatticeSieve&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10000000&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">20000000&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// Les bornes réelles vont de dizaines à centaines de millions
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Filter&lt;/span> &lt;span class="n">filter&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LinearAlgebraGF2&lt;/span> &lt;span class="n">linalg&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AlgebraicSquareRoot&lt;/span> &lt;span class="n">sqrt_step&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">auto&lt;/span> &lt;span class="n">start_time&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">high_resolution_clock&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">now&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. Sélection de polynômes
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">poly_select&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">select&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="c1">// 2. Traitement du crible (sieve)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">generate_factor_bases&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">relations&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">poly_select&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. Filtrage (Compression de matrice)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">filter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">reduce_matrix&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">relations&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">// 4. Algèbre linéaire (Recherche du noyau sur GF(2))
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">dependencies&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">linalg&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">solve_nullspace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">relations&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">// 5. Calcul de la racine carrée algébrique et PGCD
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="nl">dep&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">dependencies&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">sqrt_step&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">compute_and_factor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">relations&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">dep&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="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">auto&lt;/span> &lt;span class="n">end_time&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">high_resolution_clock&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">duration&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">double&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">elapsed&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">end_time&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">start_time&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">[System] SOTA GNFS Pipeline completed in &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">elapsed&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; seconds.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&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>&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;p>Alors, comment ce code détruit-il les murs du cryptage ? Pour chacune des 5 phases, nous allons analyser et expliquer son algorithme minutieux et ses mathématiques avancées.&lt;/p>
&lt;hr>
&lt;h2 id="2-objectif-final-du-gnfs--x2-equiv-y2-pmod-n">2. Objectif final du GNFS : $X^2 \equiv Y^2 \pmod N$
&lt;/h2>&lt;p>Le but de presque tous les algorithmes modernes de factorisation de grands nombres, y compris le GNFS, est de trouver une paire non triviale $(X, Y)$ satisfaisant la congruence suivante.&lt;/p>
$$X^2 \equiv Y^2 \pmod N$$
&lt;p>Cette équation signifie que « le reste de la division de $X^2$ et $Y^2$ par $N$ est égal ». En transformant cela, on obtient :
$X^2 - Y^2 \equiv 0 \pmod N$
C&amp;rsquo;est-à-dire que $(X-Y)(X+Y)$ est un multiple de $N$.&lt;/p>
&lt;p>Si $X \not\equiv \pm Y \pmod N$ (solution non triviale), alors il existe un « diviseur commun supérieur à 1 et inférieur à $N$ » entre $(X-Y)$ et $N$.
Ici, si nous calculons &lt;strong>$\gcd(X-Y, N)$&lt;/strong> à l&amp;rsquo;aide de l&amp;rsquo;algorithme d&amp;rsquo;Euclide, nous pouvons facilement trouver les facteurs premiers de $N$.&lt;/p>
&lt;p>Cependant, trouver ce $X$ et ce $Y$ est comme chercher une aiguille dans un désert. C&amp;rsquo;est pourquoi le GNFS adopte une approche géniale consistant à créer &lt;strong>2 mondes&lt;/strong> — le « monde des entiers réels » et le « monde des corps algébriques des polynômes » — et à distribuer les calculs.&lt;/p>
&lt;hr>
&lt;h2 id="3-phase-1--sélection-de-polynômes-polynomial-selection">3. Phase 1 : Sélection de polynômes (Polynomial Selection)
&lt;/h2>&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;/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="k">class&lt;/span> &lt;span class="nc">PolynomialSelector&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">N&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">// Calcul de m = N^(1/d) et expansion en base m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &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">degree&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="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">temp&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="n">temp&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="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="p">{&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// g(x) = x - m
&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="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>La première étape du GNFS consiste à créer un « polynôme magique » pour relier les deux mondes.
Pour un grand nombre $N$, nous choisissons un entier $m$. Habituellement, nous choisissons $m \approx N^{1/d}$ (le code suppose un polynôme de degré $d=6$).&lt;/p>
&lt;p>Ensuite, nous développons $N$ en base $m$ et utilisons ces coefficients pour construire un polynôme $f(x)$.
&lt;/p>
$$N = c_d m^d + c_{d-1} m^{d-1} + \dots + c_1 m + c_0$$
$$f(x) = c_d x^d + c_{d-1} x^{d-1} + \dots + c_1 x + c_0$$
&lt;p>Ce polynôme $f(x)$ a une propriété extrêmement importante : &lt;strong>« si l&amp;rsquo;on substitue $m$ à la variable $x$, cela devient exactement $N$ ($f(m) = N$) »&lt;/strong>. En d&amp;rsquo;autres termes, $f(m) \equiv 0 \pmod N$.
Le polynôme côté rationnel est défini comme $g(x) = x - m$.&lt;/p>
&lt;p>Ainsi, le &lt;strong>« monde du corps algébrique $\mathbb{Z}[\alpha]$ »&lt;/strong> régi par la racine $\alpha$ de $f(x)=0$ et le &lt;strong>« monde des nombres rationnels (entiers) habituels $\mathbb{Z}$ »&lt;/strong> sont solidement liés par un « homomorphisme d&amp;rsquo;anneaux » $x \to m$.&lt;/p>
&lt;p>Dans CADO-NFS et d&amp;rsquo;autres systèmes de pointe, des algorithmes comme celui de Kleinjung ou la réduction de base de réseau LLL sont utilisés pour rechercher pendant des mois le « polynôme $f(x)$ le plus pratique ». Cela garantit que les coefficients du polynôme ne deviennent pas extrêmement grands et que des nombres premiers apparaissent facilement (deviennent friables) dans les étapes suivantes.&lt;/p>
&lt;hr>
&lt;h2 id="4-phase-2--crible-de-réseau-spécial-q-special-q-lattice-sieving">4. Phase 2 : Crible de réseau spécial-$q$ (Special-q Lattice Sieving)
&lt;/h2>&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;/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="k">class&lt;/span> &lt;span class="nc">LatticeSieve&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">poly&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">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Mappe les paires (a, b) sur un réseau pour chaque nombre premier spécial q,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// et exécute un crible (sieve) avec une efficacité de cache maximisée.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ...
&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="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Après avoir préparé les deux mondes, l&amp;rsquo;étape suivante consiste à rechercher des « nombres friables (nombres composés uniquement de petits facteurs premiers) » dans ces deux mondes.
Nous générons d&amp;rsquo;innombrables paires d&amp;rsquo;entiers $(a, b)$ et calculons les deux valeurs suivantes :&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Valeur côté rationnel&lt;/strong> : $a - bm$&lt;/li>
&lt;li>&lt;strong>Norme côté algébrique&lt;/strong> : $b^d f(a/b)$&lt;/li>
&lt;/ol>
&lt;p>Le but du GNFS est de collecter des dizaines à centaines de millions de &lt;strong>« paires (Relations) où les valeurs des côtés rationnel et algébrique peuvent toutes deux être complètement factorisées uniquement avec de petits facteurs premiers »&lt;/strong>.&lt;/p>
&lt;p>Dans les premiers GNFS, on utilisait un « crible linéaire (Line Sieve) » qui alignait $(a, b)$ sur le plan $xy$ et les divisait par des nombres premiers de bout en bout. Cependant, cette méthode causait de nombreux défauts de cache en accédant partout dans la mémoire et était très lente.&lt;/p>
&lt;p>Par conséquent, les codes de pointe actuels utilisent une méthode appelée &lt;strong>« Crible de réseau spécial-$q$ (Special-q Lattice Sieve) »&lt;/strong>.
Un nombre premier raisonnablement grand $q$ est fixé, et seules les paires $(a, b)$ « dont la valeur côté algébrique est toujours divisible par $q$ » sont calculées. Ces $(a, b)$ remplissant la condition forment un « réseau (Lattice) » sur le plan, rendant les sauts d&amp;rsquo;adresses constants lors des calculs, ce qui s&amp;rsquo;adapte parfaitement au cache L1/L2 du CPU.
Grâce à l&amp;rsquo;introduction de ce crible de réseau, la vitesse de calcul du GNFS a considérablement augmenté.&lt;/p>
&lt;hr>
&lt;h2 id="5-phase-3--filtrage-filtering">5. Phase 3 : Filtrage (Filtering)
&lt;/h2>&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;/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="k">class&lt;/span> &lt;span class="nc">Filter&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="n">reduce_matrix&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&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">// 1. Suppression des singletons (suppression des relations ayant des nombres premiers n&amp;#39;apparaissant qu&amp;#39;une fois)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 2. Fusion de cliques (combinaison de relations pour densifier une matrice creuse)
&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="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Des centaines de millions de relations ont été collectées en plusieurs mois par des ordinateurs du monde entier lors de la Phase 2. Cependant, si on les injecte telles quelles dans « l&amp;rsquo;étape de résolution du système d&amp;rsquo;équations (calcul matriciel) » suivante, la mémoire des supercalculateurs explosera.&lt;/p>
&lt;p>C&amp;rsquo;est pourquoi un processus de super compression matricielle appelé &lt;strong>Filtrage (Filtering)&lt;/strong> est effectué.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Suppression des singletons (Purge des singularités)&lt;/strong>
Supposons qu&amp;rsquo;un énorme nombre premier $p$ n&amp;rsquo;apparaisse « qu&amp;rsquo;une seule fois » parmi les centaines de millions de relations. Puisque notre but est de « rendre l&amp;rsquo;exposant de tous les nombres premiers pair (multiple de 2) », un nombre premier qui n&amp;rsquo;apparaît qu&amp;rsquo;une fois ne peut jamais devenir pair.
Par conséquent, la relation contenant ce nombre premier est immédiatement supprimée (purgée) comme « déchet inutile ». En provoquant cela en chaîne, les données qui comptaient des centaines de millions de lignes sont drastiquement réduites.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Fusion de cliques (Clique merging)&lt;/strong>
De plus, en multipliant (additionnant) les relations qui partagent un nombre premier spécifique, on réduit le nombre de lignes tout en compressant la matrice creuse (pleine de vides) vers un état plus dense (en utilisant une méthode similaire à la recherche de cliques en théorie des graphes).&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Grâce à cette optimisation, la gigantesque matrice creuse est drastiquement compressée à une taille calculable.&lt;/p>
&lt;hr>
&lt;h2 id="6-phase-4--algèbre-linéaire-sur-gf2-méthode-de-block-wiedemann">6. Phase 4 : Algèbre linéaire sur GF(2) (Méthode de Block Wiedemann)
&lt;/h2>&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;/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="k">class&lt;/span> &lt;span class="nc">LinearAlgebraGF2&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">solve_nullspace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&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">// Répète les opérations de produit entre une matrice creuse et un vecteur,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// et trouve plusieurs vecteurs solutions (noyau) tels que M * x = 0 mod 2.
&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="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>C&amp;rsquo;est enfin le cœur du puzzle.
Nous multiplions les relations collectées pour trouver la &lt;strong>« combinaison où les exposants de tous les facteurs premiers deviennent pairs »&lt;/strong>.&lt;/p>
&lt;p>Mathématiquement, cela équivaut à utiliser une immense matrice $M$ dont les éléments sont la parité de l&amp;rsquo;exposant de chaque nombre premier (c&amp;rsquo;est-à-dire 0 ou 1) et un vecteur $x$ représentant quelles relations utiliser,
pour trouver un vecteur solution $x$ (noyau, nullspace) tel que :
&lt;strong>$M \cdot x \equiv 0 \pmod 2$&lt;/strong>&lt;/p>
&lt;p>Nous devons résoudre un système d&amp;rsquo;équations pour une matrice d&amp;rsquo;une taille incroyable de millions de lignes × millions de colonnes. Avec l&amp;rsquo;élimination de Gauss habituelle, la complexité algorithmique serait de $O(N^3)$, et le calcul ne se terminerait pas avant la fin de l&amp;rsquo;univers.&lt;/p>
&lt;p>Ainsi, la &lt;strong>« Méthode de Block Wiedemann »&lt;/strong> est adoptée dans les implémentations de pointe.
Il s&amp;rsquo;agit d&amp;rsquo;un type de méthode du sous-espace de Krylov qui exploite le fait que la matrice $M$ est « très creuse (presque que des 0) » pour dériver des solutions en effectuant itérativement la multiplication de la matrice et du vecteur.
Contrairement à l&amp;rsquo;ancienne méthode de Block Lanczos, la méthode de Block Wiedemann peut diviser entièrement le processus de calcul sur plusieurs clusters, démontrant ainsi une puissance écrasante dans le cloud computing distribué moderne et le calcul parallèle sur supercalculateurs.&lt;/p>
&lt;hr>
&lt;h2 id="7-phase-5--racine-carrée-algébrique-algebraic-square-root-et-effondrement-de-la-cryptographie">7. Phase 5 : Racine carrée algébrique (Algebraic Square Root) et effondrement de la cryptographie
&lt;/h2>&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;/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="k">class&lt;/span> &lt;span class="nc">AlgebraicSquareRoot&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="n">compute_and_factor&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">// 1. Calcul de la racine carrée côté rationnel V
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">V&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">// 2. Calcul de la racine carrée côté algébrique gamma
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">Y&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">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">factor&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">V&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">N&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// GCD(X-Y, N)
&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="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Grâce au calcul matriciel de la Phase 4, nous avons obtenu « un ensemble $S$ de relations qui, lorsqu&amp;rsquo;elles sont multipliées ensemble, ont des facteurs premiers élevés à une puissance paire ».
Cela nous permet de construire des « carrés » dans les mondes rationnel et algébrique respectivement.&lt;/p>
&lt;p>Côté rationnel, comme il s&amp;rsquo;agit d&amp;rsquo;une simple multiplication d&amp;rsquo;entiers, il est facile de calculer la racine carrée $V$.
&lt;/p>
$$V^2 = \prod_{S} (a - bm)$$
&lt;p>&lt;strong>Cependant, le véritable enfer réside du « côté algébrique ».&lt;/strong>
Dans le monde du corps algébrique $\mathbb{Z}[\alpha]$, comme l&amp;rsquo;unicité de la factorisation première ne tient pas, nous avons utilisé des idéaux pour les calculs. Ce qui a été garanti par le calcul matriciel, c&amp;rsquo;est &lt;strong>« seulement qu&amp;rsquo;il devient le carré d&amp;rsquo;un idéal », et il n&amp;rsquo;est pas garanti qu&amp;rsquo;il devienne « le carré d&amp;rsquo;un élément ($\gamma^2$) »&lt;/strong>.&lt;/p>
&lt;p>Ici, nous faisons face à de puissants murs en théorie algébrique des nombres : « l&amp;rsquo;obstruction du groupe des classes d&amp;rsquo;idéaux » et « l&amp;rsquo;obstruction du groupe des unités ».
Le GNFS utilise la magie des &lt;strong>« caractères quadratiques (Quadratic Characters) »&lt;/strong> pour briser ces murs.
Nous ajoutons secrètement à la matrice de la Phase 4 les colonnes des résidus quadratiques (symbole de Legendre) pour plusieurs dizaines d&amp;rsquo;idéaux premiers spéciaux. Grâce à cela, l&amp;rsquo;ensemble $S$ trouvé évitera les obstacles avec une probabilité écrasante, et formera sans problème « le vrai carré de l&amp;rsquo;élément $\gamma^2$ ».&lt;/p>
&lt;p>L&amp;rsquo;opération pour trouver $\gamma$ (racine carrée algébrique) est calculée à l&amp;rsquo;aide d&amp;rsquo;algorithmes très complexes comme la méthode de Montgomery.&lt;/p>
&lt;p>Et finalement, la racine carrée algébrique $\gamma$ est téléportée dans le monde réel par l&amp;rsquo;homomorphisme d&amp;rsquo;anneaux $\phi$ (en substituant $m$ à $x$) pour obtenir $Y$.
Si on pose $V$ du côté rationnel tel quel comme $X$, l&amp;rsquo;équation absolue que nous poursuivions est enfin accomplie.&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>Ensuite, il suffit de calculer $\gcd(X-Y, N)$. Au moment où le traitement de 0,001 seconde s&amp;rsquo;achève et qu&amp;rsquo;un facteur non trivial s&amp;rsquo;imprime à l&amp;rsquo;écran, le cryptage RSA, autrefois considéré comme imprenable, s&amp;rsquo;effondre complètement.&lt;/p>
&lt;hr>
&lt;h2 id="conclusion">Conclusion
&lt;/h2>&lt;p>Le GNFS n&amp;rsquo;est pas qu&amp;rsquo;une simple technique de programmation.
C&amp;rsquo;est le sommet de l&amp;rsquo;intelligence humaine, où les « abîmes des mathématiques pures » telles que l&amp;rsquo;algèbre abstraite, la théorie des anneaux, et les groupes de classes d&amp;rsquo;idéaux ont été surmontés par une « ingénierie de l&amp;rsquo;extrême » comme l&amp;rsquo;architecture distribuée des supercalculateurs et l&amp;rsquo;optimisation des caches.&lt;/p>
&lt;p>Les chats et les informations de carte de crédit que nous envoyons sans y penser sont protégés au-dessus de ces luttes mathématiques astronomiques.&lt;/p>
&lt;p>Nous espérons qu&amp;rsquo;à travers ce framework C++, vous ressentirez le « romantisme des mathématiques et des ordinateurs » qui se cache derrière les algorithmes de décryptage les plus avancés.&lt;/p></description></item><item><title>La Véritable Structure Mathématique du Crible Général du Corps de Nombres (GNFS)</title><link>http://kenji.blog/fr/p/%E4%B8%80%E8%88%AC%E6%95%B0%E4%BD%93%E7%AF%A9%E6%B3%95gnfs%E3%81%AE%E7%9C%9F%E3%81%AE%E6%95%B0%E5%AD%A6%E7%9A%84%E6%A7%8B%E9%80%A0/</link><pubDate>Sat, 05 Sep 2026 02:26:13 +0900</pubDate><guid>http://kenji.blog/fr/p/%E4%B8%80%E8%88%AC%E6%95%B0%E4%BD%93%E7%AF%A9%E6%B3%95gnfs%E3%81%AE%E7%9C%9F%E3%81%AE%E6%95%B0%E5%AD%A6%E7%9A%84%E6%A7%8B%E9%80%A0/</guid><description>&lt;img src="http://kenji.blog/p/%E4%B8%80%E8%88%AC%E6%95%B0%E4%BD%93%E7%AF%A9%E6%B3%95gnfs%E3%81%AE%E7%9C%9F%E3%81%AE%E6%95%B0%E5%AD%A6%E7%9A%84%E6%A7%8B%E9%80%A0/rsa_encryption_break_1788542156523.jpg" alt="Featured image of post La Véritable Structure Mathématique du Crible Général du Corps de Nombres (GNFS)" />&lt;h1 id="la-véritable-structure-mathématique-du-crible-général-du-corps-de-nombres-gnfs">La Véritable Structure Mathématique du Crible Général du Corps de Nombres (GNFS)
&lt;/h1>&lt;p>L&amp;rsquo;objectif ultime du GNFS est de trouver $X, Y$ tels que $X^2 \equiv Y^2 \pmod N$.
Pour y parvenir, les mathématiciens ont construit un pont entre le &lt;strong>&amp;ldquo;monde des entiers réels&amp;rdquo;&lt;/strong> et le &lt;strong>&amp;ldquo;monde des corps algébriques&amp;rdquo;&lt;/strong> . Ce pont est l&amp;rsquo;&amp;ldquo;homomorphisme&amp;rdquo;.&lt;/p>
&lt;h2 id="phase-1--relier-les-mondes-avec-lhomomorphisme">Phase 1 : Relier les mondes avec l&amp;rsquo;&amp;ldquo;Homomorphisme&amp;rdquo;
&lt;/h2>&lt;h3 id="1-sélection-du-polynôme-et-définition-des-racines">1. Sélection du polynôme et définition des racines
&lt;/h3>&lt;p>Pour un nombre composé géant $N$, on choisit un entier $m$ et un polynôme $f(x)$ tels que $f(m) \equiv 0 \pmod N$.
(Exemple : on développe $N$ en base $m$ et on crée $f(x)$ à partir de ses coefficients. On suppose ici que $f(x)$ est irréductible sur le corps des rationnels $\mathbb{Q}$ (ne peut pas être factorisé davantage)).&lt;/p>
&lt;p>Ensuite, on définit l&amp;rsquo;une des &amp;ldquo;racines complexes&amp;rdquo; de l&amp;rsquo;équation $f(x) = 0$ comme étant $\alpha$.
Naturellement, $f(\alpha) = 0$. $\alpha$ n&amp;rsquo;est pas un entier, mais un nombre complexe impliquant des racines et des nombres imaginaires (un nombre algébrique).&lt;/p>
&lt;h3 id="2-construction-danneaux-rings-et-dhomomorphismes">2. Construction d&amp;rsquo;Anneaux (Rings) et d&amp;rsquo;Homomorphismes
&lt;/h3>&lt;p>Ici, on prépare deux &amp;ldquo;anneaux&amp;rdquo; mathématiques (des mondes où l&amp;rsquo;addition et la multiplication sont définies).&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Monde A : $\mathbb{Z}[\alpha]$&lt;/strong> (L&amp;rsquo;anneau des entiers algébriques contenant $\alpha$)
Un monde de nombres exprimés sous la forme $a + b\alpha + c\alpha^2 + \dots$.&lt;/li>
&lt;li>&lt;strong>Monde B : $\mathbb{Z}/N\mathbb{Z}$&lt;/strong> (L&amp;rsquo;anneau des restes modulo $N$)
Un monde de congruences composé uniquement des entiers de $0$ à $N-1$.&lt;/li>
&lt;/ul>
&lt;p>Ici, on définit une application $\phi$ du Monde A vers le Monde B comme suit.
&lt;strong>$$\phi : \mathbb{Z}[\alpha] \to \mathbb{Z}/N\mathbb{Z}$$&lt;/strong>
&lt;strong>$$\phi(\alpha) = m \pmod N$$&lt;/strong>&lt;/p>
&lt;p>Cette application $\phi$ est une opération magique qui remplace exactement la variable $\alpha$ du Monde A par l&amp;rsquo;entier $m$ du Monde B.
Ce $\phi$ possède une propriété extrêmement puissante appelée &lt;strong>&amp;ldquo;Homomorphisme d&amp;rsquo;Anneau (Ring Homomorphism)&amp;rdquo;&lt;/strong> .
L&amp;rsquo;homomorphisme est la propriété de &lt;strong>&amp;ldquo;se téléporter dans un autre monde sans détruire la structure de l&amp;rsquo;addition et de la multiplication&amp;rdquo;&lt;/strong> . En d&amp;rsquo;autres termes, les équations suivantes sont vraies :&lt;/p>
&lt;ul>
&lt;li>$\phi(X \times Y) = \phi(X) \times \phi(Y)$&lt;/li>
&lt;li>$\phi(X^2) = \phi(X)^2$&lt;/li>
&lt;/ul>
&lt;p>Qu&amp;rsquo;est-ce que cela signifie ? Si nous pouvons créer le &lt;strong>&amp;ldquo;carré ($\gamma^2$)&amp;rdquo;&lt;/strong> d&amp;rsquo;un élément complexe $\gamma$ dans le &amp;ldquo;Monde A (le monde de $\alpha$)&amp;rdquo;, et le téléporter dans le &amp;ldquo;Monde B (le monde des restes)&amp;rdquo; en utilisant $\phi$, &lt;strong>la forme carrée $\phi(\gamma)^2$ est parfaitement préservée&lt;/strong> .&lt;/p>
&lt;hr>
&lt;h2 id="phase-2--leffondrement-de-la-factorisation-première-et-la-naissance-des-idéaux">Phase 2 : L&amp;rsquo;Effondrement de la Factorisation Première et la Naissance des &amp;ldquo;Idéaux&amp;rdquo;
&lt;/h2>&lt;p>Dans le Monde A ($\mathbb{Z}[\alpha]$), on souhaite rassembler de nombreux éléments appropriés $(a - b\alpha)$ et les multiplier pour créer un &amp;ldquo;carré parfait (élément carré)&amp;rdquo;.
Normalement, on procéderait à la &amp;ldquo;factorisation première&amp;rdquo; de chaque $(a - b\alpha)$ collecté et on les combinerait de manière à ce que les exposants des nombres premiers soient tous pairs (en résolvant avec des matrices) pour former un carré.&lt;/p>
&lt;p>&lt;strong>Cependant, ici, le mur désespérant de l&amp;rsquo;algèbre se dresse.&lt;/strong>
Dans des mondes algébriques comme $\mathbb{Z}[\alpha]$, &lt;strong>l&amp;rsquo;&amp;ldquo;unicité de la factorisation première (tout nombre peut être exprimé de manière unique comme un produit de nombres premiers)&amp;rdquo;&lt;/strong> enseignée au collège &lt;strong>s&amp;rsquo;effondre&lt;/strong> .&lt;/p>
&lt;p>(Exemple : Dans un certain monde algébrique, $6 = 2 \times 3$, mais en même temps $6 = (1+\sqrt{-5}) \times (1-\sqrt{-5})$, et on ne sait plus quels sont les vrais nombres premiers)&lt;/p>
&lt;p>Si la factorisation n&amp;rsquo;est pas unique, le puzzle consistant à &amp;ldquo;compter le nombre de nombres premiers pour les rendre pairs&amp;rdquo; (la méthode du crible) est, en principe, impossible à exécuter.&lt;/p>
&lt;h3 id="le-sauvetage-de-kummer-et-dedekind--les-idéaux">Le Sauvetage de Kummer et Dedekind : les &amp;ldquo;Idéaux&amp;rdquo;
&lt;/h3>&lt;p>Ce qui a sauvé cet effondrement, c&amp;rsquo;est le concept d&amp;rsquo; &lt;strong>&amp;ldquo;Idéal (Ideal : nombre idéal)&amp;rdquo;&lt;/strong> créé par les mathématiciens du 19ème siècle.
En pensant non pas à l&amp;rsquo;élément lui-même, mais à &amp;ldquo;l&amp;rsquo;ensemble des multiples (idéal)&amp;rdquo; généré par cet élément, la factorisation première est redevenue possible.&lt;/p>
&lt;p>Dans l&amp;rsquo;anneau des entiers d&amp;rsquo;un corps algébrique $\mathcal{O}_K$ (un anneau plus complet contenant $\mathbb{Z}[\alpha]$), il est prouvé que même si un élément ne peut pas être factorisé de manière unique, &lt;strong>&amp;ldquo;un idéal peut toujours être factorisé de manière unique comme le produit d&amp;rsquo;&amp;lsquo;Idéaux Premiers ($\mathfrak{p}$)&amp;rsquo;&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Par conséquent, dans le GNFS, au lieu de factoriser l&amp;rsquo;élément $(a - b\alpha)$ lui-même, on factorise &lt;strong>l&amp;rsquo;idéal principal $\langle a - b\alpha \rangle$ qu&amp;rsquo;il génère en idéaux premiers&lt;/strong> .&lt;/p>
&lt;hr>
&lt;h2 id="phase-3--la-norme-norm-et-les-deux-cribles-sieves">Phase 3 : La Norme (Norm) et les Deux Cribles (Sieves)
&lt;/h2>&lt;p>Alors, comment savoir en quels idéaux premiers l&amp;rsquo;idéal $\langle a - b\alpha \rangle$ se décompose ?
Ici on utilise une fonction appelée &lt;strong>&amp;ldquo;Norme (Norm)&amp;rdquo;&lt;/strong> . La Norme est une fonction qui convertit des éléments complexes de corps algébriques en &amp;ldquo;entiers réels normaux $\mathbb{Z}$&amp;rdquo;.&lt;/p>
&lt;p>La norme de l&amp;rsquo;élément $(a - b\alpha)$ est trouvée par un simple calcul polynomial $b^d f(a/b)$ ($d$ est le degré de $f(x)$).&lt;/p>
&lt;p>D&amp;rsquo;après un théorème algébrique, on sait que &lt;strong>&amp;ldquo;si la norme d&amp;rsquo;un certain idéal peut être complètement factorisée en petits nombres premiers (est friable), alors l&amp;rsquo;idéal d&amp;rsquo;origine peut également être complètement factorisé en petits idéaux premiers&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Ainsi, pour un grand nombre de paires d&amp;rsquo;entiers $(a, b)$, le GNFS calcule les deux valeurs suivantes simultanément et ne collecte que les paires où les deux deviennent des &amp;ldquo;nombres friables (smooth numbers)&amp;rdquo; :&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Crible Rationnel (Rational Sieve)&lt;/strong> : $a - bm$ (la valeur dans le monde réel)&lt;/li>
&lt;li>&lt;strong>Crible Algébrique (Algebraic Sieve)&lt;/strong> : $b^d f(a/b)$ (la norme dans le monde algébrique)&lt;/li>
&lt;/ol>
&lt;p>En collectant des dizaines de millions de paires $(a, b)$ où les deux sont friables, on résout les données de factorisation des idéaux premiers (combien d&amp;rsquo;idéaux premiers sont inclus) sous la forme d&amp;rsquo;une matrice géante (algèbre linéaire sur GF(2)) pour trouver un ensemble $S$ de paires tel que &amp;ldquo;multipliés ensemble, les exposants de tous les idéaux premiers deviennent pairs&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="phase-4--les-deux-obstacles-et-le-groupe-des-classes-didéaux">Phase 4 : Les Deux &amp;ldquo;Obstacles&amp;rdquo; et le Groupe des Classes d&amp;rsquo;Idéaux
&lt;/h2>&lt;p>À partir du calcul matriciel, on a découvert qu&amp;rsquo;en multipliant tous les idéaux de $(a - b\alpha)$ appartenant à l&amp;rsquo;ensemble $S$, on obtient le carré d&amp;rsquo;un certain idéal $I$.
&lt;/p>
$$\prod_{S} \langle a - b\alpha \rangle = I^2$$
&lt;p>&lt;strong>Cependant, ce n&amp;rsquo;est pas encore terminé. Le mur mathématique le plus profond et le plus difficile du GNFS se trouve ici.&lt;/strong>&lt;/p>
&lt;p>Ce que nous voulons à la fin, ce n&amp;rsquo;est pas &amp;ldquo;le carré d&amp;rsquo;un idéal&amp;rdquo;, mais le &lt;strong>&amp;ldquo;carré d&amp;rsquo;un élément ($\gamma^2$)&amp;rdquo;&lt;/strong> à substituer dans l&amp;rsquo;application $\phi$.
Ce n&amp;rsquo;est pas parce que c&amp;rsquo;est devenu le carré d&amp;rsquo;un idéal que l&amp;rsquo;élément lui-même est nécessairement un carré. Il y a ici &lt;strong>deux puissants obstacles mathématiques (Obstructions)&lt;/strong> .&lt;/p>
&lt;h3 id="obstacle---la-barrière-du-groupe-des-classes-didéaux-ideal-class-group">Obstacle ① : La Barrière du Groupe des Classes d&amp;rsquo;Idéaux (Ideal Class Group)
&lt;/h3>&lt;p>L&amp;rsquo;idéal $I$ n&amp;rsquo;est pas toujours un &amp;ldquo;idéal généré par un seul élément (idéal principal)&amp;rdquo;.
Il est impossible d&amp;rsquo;extraire un élément spécifique $\gamma$ d&amp;rsquo;un idéal qui n&amp;rsquo;est pas principal.&lt;/p>
&lt;p>C&amp;rsquo;est ici qu&amp;rsquo;intervient le concept de &lt;strong>&amp;ldquo;Groupe des Classes d&amp;rsquo;Idéaux (Class Group, $Cl_K$)&amp;rdquo;&lt;/strong> . Le groupe des classes d&amp;rsquo;idéaux est un groupe qui mesure &amp;ldquo;combien d&amp;rsquo;idéaux existent dans ce corps algébrique qui ne sont pas principaux (à quel point l&amp;rsquo;unicité de la factorisation est brisée)&amp;rdquo;.
Même si $\prod \langle a - b\alpha \rangle$ devient $I^2$, si $I$ n&amp;rsquo;est pas l&amp;rsquo;élément neutre (idéal principal) dans le groupe des classes d&amp;rsquo;idéaux, il ne peut pas être ramené au carré d&amp;rsquo;un élément.&lt;/p>
&lt;h3 id="obstacle---la-barrière-du-groupe-des-unités-unit-group">Obstacle ② : La Barrière du Groupe des Unités (Unit Group)
&lt;/h3>&lt;p>Supposons que, par chance, $I$ soit l&amp;rsquo;idéal principal $\langle \gamma \rangle$.
Alors, on a $\prod \langle a - b\alpha \rangle = \langle \gamma^2 \rangle$.
Vous pourriez penser : &amp;ldquo;Super, l&amp;rsquo;élément est aussi un carré !&amp;rdquo;, mais c&amp;rsquo;est une grosse erreur.&lt;/p>
&lt;p>Le fait que des idéaux (ensembles de multiples) soient égaux ne signifie pas que les éléments sont parfaitement égaux. Il y aura toujours un décalage par une &lt;strong>&amp;ldquo;Unité (Unit : un nombre dont l&amp;rsquo;inverse est aussi un entier. Comme 1 ou -1)&amp;rdquo;&lt;/strong> .
En d&amp;rsquo;autres termes, l&amp;rsquo;équation réelle des éléments devient la suivante :
&lt;/p>
$$\prod_{S} (a - b\alpha) = u \cdot \gamma^2$$
&lt;p>
($u$ est un élément du groupe des unités $U_K$)&lt;/p>
&lt;p>À moins que cette unité $u$ ne soit elle-même le carré de quelque chose, le côté gauche ne pourra jamais devenir le &amp;ldquo;carré parfait d&amp;rsquo;un élément&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="phase-5--la-magie-dadleman-caractères-quadratiques-quadratic-characters">Phase 5 : La Magie d&amp;rsquo;Adleman &amp;ldquo;Caractères Quadratiques&amp;rdquo; (Quadratic Characters)
&lt;/h2>&lt;p>L&amp;rsquo;obstacle du groupe des classes d&amp;rsquo;idéaux et l&amp;rsquo;obstacle du groupe des unités. Comment surmonter ces deux-là ?
C&amp;rsquo;est ici qu&amp;rsquo;intervient la brillante méthode des &lt;strong>&amp;ldquo;Caractères Quadratiques (Quadratic Characters)&amp;rdquo;&lt;/strong> , introduzido par le cryptographe Leonard Adleman (le &amp;ldquo;A&amp;rdquo; de RSA) et d&amp;rsquo;autres.&lt;/p>
&lt;p>Pour déterminer &amp;ldquo;si un certain élément est un carré parfait dans le corps algébrique&amp;rdquo;, on utilise la version pour corps algébriques du Symbole de Legendre (résidu quadratique).
Dans cette matrice géante d&amp;rsquo;avant (le puzzle pour rendre pairs les comptes d&amp;rsquo;idéaux premiers), on &lt;strong>ajoute furtivement quelques dizaines de conditions supplémentaires (colonnes) disant que &amp;ldquo;les caractères quadratiques pour certains idéaux premiers spéciaux $\mathfrak{q}$ doivent également tous être $1$ (pairs)&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Lorsqu&amp;rsquo;on trouve un ensemble $S$ qui satisfait même à ces conditions supplémentaires par le calcul matriciel, des théorèmes profonds de la théorie algébrique des nombres garantissent que &lt;strong>&amp;ldquo;l&amp;rsquo;obstacle du groupe des classes d&amp;rsquo;idéaux et l&amp;rsquo;obstacle du groupe des unités disparaîtront naturellement avec une probabilité écrasante&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Avec cela, nous obtenons enfin la véritable équation.
&lt;/p>
$$\prod_{S} (a - b\alpha) = \gamma^2$$
&lt;hr>
&lt;h2 id="phase-finale--la-fusion-des-mondes-et-leffondrement-cryptographique">Phase Finale : La Fusion des Mondes et l&amp;rsquo;Effondrement Cryptographique
&lt;/h2>&lt;p>Enfin, toutes les pièces du puzzle sont en place.&lt;/p>
&lt;p>&lt;strong>[Éléments dans le Monde Algébrique (Monde A)]&lt;/strong>
$\gamma^2 = \prod (a - b\alpha)$
(On utilise un algorithme de racine carrée pour trouver $\gamma$)&lt;/p>
&lt;p>&lt;strong>[Éléments dans le Monde Réel (Monde des Nombres Rationnels)]&lt;/strong>
$V^2 = \prod (a - bm)$
(Comme il s&amp;rsquo;agit d&amp;rsquo;une simple multiplication d&amp;rsquo;entiers, $V$ est trouvé normalement)&lt;/p>
&lt;p>Maintenant, il est temps d&amp;rsquo;utiliser ce pont magique que nous avons construit au début, l&amp;rsquo; &lt;strong>homomorphisme $\phi$&lt;/strong> .
On téléporte l&amp;rsquo;élément $\gamma$ du Monde A vers le Monde B (le monde des restes de $N$) en utilisant $\phi$ (l&amp;rsquo;application où on remplace $\alpha$ par $m$).
&lt;/p>
$$Y = \phi(\gamma) \pmod N$$
&lt;p>D&amp;rsquo;autre part, on amène directement le $V$ construit dans le monde réel dans le monde des restes et on l&amp;rsquo;appelle $X$.
&lt;/p>
$$X = V \pmod N$$
&lt;p>Grâce à la propriété de &amp;ldquo;préservation de structure&amp;rdquo; de l&amp;rsquo;homomorphisme, la relation carrée qui tenait dans le Monde A est parfaitement préservée dans le Monde B (le monde modulo $N$).
De plus, puisque les paires originales $(a, b)$ ont été créées en correspondance sous les formes $a - b\alpha$ et $a - bm$, ces $X$ et $Y$ entrent en collision dans le monde modulo $N$ et produisent l&amp;rsquo;équation absolue suivante :&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>Il ne reste plus qu&amp;rsquo;à prier pour que ces $X$ et $Y$ ne soient pas des solutions triviales ($X \equiv \pm Y$), et à calculer
&lt;strong>$\gcd(X - Y, N)$&lt;/strong> .&lt;/p>
&lt;p>S&amp;rsquo;il s&amp;rsquo;agit d&amp;rsquo;une solution non triviale, l&amp;rsquo;algorithme d&amp;rsquo;Euclide s&amp;rsquo;exécutera en 0,001 seconde, et les nombres premiers secrets $p$ et $q$, qui sont le cœur de la cryptographie RSA, seront imprimés sur l&amp;rsquo;écran de sortie.&lt;/p>
&lt;hr>
&lt;p>Ceci est l&amp;rsquo;image complète du &lt;strong>&amp;ldquo;Crible Général du Corps de Nombres (GNFS)&amp;rdquo;&lt;/strong> , l&amp;rsquo;essence des mathématiques modernes.&lt;/p></description></item><item><title>Qu'est-ce que le "Crible du corps de nombres généralisé (GNFS)", la mathématique la plus puissante de l'humanité qui brise le chiffrement d'Internet ?</title><link>http://kenji.blog/fr/p/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AE%E6%9A%97%E5%8F%B7%E3%82%92%E7%A0%B4%E3%82%8B%E4%BA%BA%E9%A1%9E%E6%9C%80%E5%BC%B7%E3%81%AE%E6%95%B0%E5%AD%A6%E4%B8%80%E8%88%AC%E6%95%B0%E4%BD%93%E7%AF%A9%E6%B3%95gnfs%E3%81%A8%E3%81%AF/</link><pubDate>Sat, 05 Sep 2026 02:09:08 +0900</pubDate><guid>http://kenji.blog/fr/p/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AE%E6%9A%97%E5%8F%B7%E3%82%92%E7%A0%B4%E3%82%8B%E4%BA%BA%E9%A1%9E%E6%9C%80%E5%BC%B7%E3%81%AE%E6%95%B0%E5%AD%A6%E4%B8%80%E8%88%AC%E6%95%B0%E4%BD%93%E7%AF%A9%E6%B3%95gnfs%E3%81%A8%E3%81%AF/</guid><description>&lt;img src="http://kenji.blog/p/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AE%E6%9A%97%E5%8F%B7%E3%82%92%E7%A0%B4%E3%82%8B%E4%BA%BA%E9%A1%9E%E6%9C%80%E5%BC%B7%E3%81%AE%E6%95%B0%E5%AD%A6%E4%B8%80%E8%88%AC%E6%95%B0%E4%BD%93%E7%AF%A9%E6%B3%95gnfs%E3%81%A8%E3%81%AF/gnfs_two_worlds_1788542142485.jpg" alt="Featured image of post Qu'est-ce que le "Crible du corps de nombres généralisé (GNFS)", la mathématique la plus puissante de l'humanité qui brise le chiffrement d'Internet ?" />&lt;h1 id="quest-ce-que-le--crible-du-corps-de-nombres-généralisé-gnfs--la-mathématique-la-plus-puissante-de-lhumanité-qui-brise-le-chiffrement-dinternet-">Qu&amp;rsquo;est-ce que le « Crible du corps de nombres généralisé (GNFS) », la mathématique la plus puissante de l&amp;rsquo;humanité qui brise le chiffrement d&amp;rsquo;Internet ?
&lt;/h1>&lt;p>L&amp;rsquo;Internet que nous utilisons tous les jours. Les messages sur LINE, YouTube, les achats sur Amazon, toutes les communications sont protégées par le « chiffrement ».
Actuellement, le chiffrement le plus utilisé dans le monde est le « Chiffrement RSA ».&lt;/p>
&lt;p>La clé de la défense du chiffrement RSA est très simple. Elle utilise la propriété mathématique selon laquelle ** « la factorisation en nombres premiers de nombres gigantesques ne peut être résolue, même par des ordinateurs » ** .
Par exemple, pour « 15 », nous savons tout de suite que c&amp;rsquo;est « 3 × 5 », mais dès que cela devient un « nombre à 270 chiffres », même si tous les superordinateurs du monde étaient combinés, cela prendrait des centaines de millions d&amp;rsquo;années à résoudre.&lt;/p>
&lt;p>Cependant, les mathématiciens ne sont pas restés silencieux. Pour briser ce chiffrement impénétrable, l&amp;rsquo;humanité a créé un algorithme (procédure de calcul) presque magique appelé ** « Crible du corps de nombres généralisé (GNFS : General Number Field Sieve) » ** .&lt;/p>
&lt;p>Dans cet article, sans utiliser de jargon technique, avec seulement les connaissances des ** mathématiques du collège (factorisation, expressions algébriques, plus grand commun diviseur) ** , nous vous expliquerons étape par étape comment « l&amp;rsquo;algorithme le plus puissant de l&amp;rsquo;humanité » brise le code !&lt;/p>
&lt;hr>
&lt;h2 id="chapitre-1--le-but-du-déchiffrement-est-une--formule-de-3ème-">Chapitre 1 : Le but du déchiffrement est une « formule de 3ème »
&lt;/h2>&lt;p>Le plus grand coup spécial pour faire face à la gigantesque factorisation en nombres premiers. C&amp;rsquo;est cette formule apprise en classe de 3ème :&lt;/p>
&lt;blockquote>
&lt;p>** $X^2 - Y^2 = (X + Y)(X - Y)$ **&lt;/p>
&lt;/blockquote>
&lt;p>Vous pourriez vous dire : « Sérieusement, une formule aussi basique peut briser le chiffrement ? ». Cependant, c&amp;rsquo;est la clé maîtresse qui révèle tout.&lt;/p>
&lt;p>Le but ultime pour briser le chiffrement, pour un nombre gigantesque $N$, est de trouver ** « des nombres ($X$ et $Y$) dont le reste de la division de $X^2$ et $Y^2$ par $N$ est le même » ** .&lt;/p>
&lt;h3 id="pourquoi-avoir-le--même-reste--brise-t-il-le-chiffrement-">Pourquoi avoir le « même reste » brise-t-il le chiffrement ?
&lt;/h3>&lt;p>Supposons que deux nombres, $X^2$ et $Y^2$, aient « le même reste lorsqu&amp;rsquo;ils sont divisés par $N$ ».
Avoir le même reste signifie qu&amp;rsquo;il y a une règle selon laquelle ** la soustraction « $X^2 - Y^2$ » sera toujours parfaitement divisible par $N$ (sera un multiple de $N$) ** .&lt;/p>
&lt;p>Ici, supposons que le nombre géant $N$ utilisé dans le chiffrement soit constitué de la multiplication de deux nombres premiers secrets ($p$ et $q$) ($N = p \times q$).&lt;/p>
&lt;p>En factorisant $X^2 - Y^2$, nous obtenons ** $(X - Y)(X + Y)$ ** .
Le fait que ce soit un multiple de $N$ signifie que, quelque part dans cette multiplication, les nombres premiers secrets $p$ et $q$ sont cachés.&lt;/p>
&lt;p>Ici, un miracle se produit.
Il y a une probabilité mathématique de ** 50 % (la moitié) ** que les deux nombres premiers $p$ et $q$ se séparent dans des pièces différentes : ** « $p$ va dans la pièce de $(X - Y)$ » et « $q$ va dans la pièce de $(X + Y)$ » ** .&lt;/p>
&lt;p>Avec seulement le nombre premier $p$ étant entré dans la pièce de $(X - Y)$, calculons le ** « plus grand commun diviseur (la plus grande partie commune) » ** de $(X - Y)$ et $N$.&lt;/p>
&lt;ul>
&lt;li>Contenu de $(X - Y)$ = $p \times$ un certain nombre&lt;/li>
&lt;li>Contenu de $N$ = $p \times q$
La seule partie commune est ** « $p$ » ** !&lt;/li>
&lt;/ul>
&lt;p>En d&amp;rsquo;autres termes, au moment où le plus grand commun diviseur est calculé, le nombre premier caché $p$ est révélé et le chiffrement est complètement décodé. (*Le plus grand commun diviseur peut être calculé instantanément sur un smartphone en utilisant « l&amp;rsquo;Algorithme d&amp;rsquo;Euclide »).&lt;/p>
&lt;p>** 【Petite Chronique : Pourquoi le carré ? Le cube ou le double ne fonctionnent-ils pas ?】 **&lt;/p>
&lt;blockquote>
&lt;p>Avec « $2X - 2Y$ », cela devient $2(X - Y)$ et il n&amp;rsquo;y a qu&amp;rsquo;une seule pièce, vous ne pouvez donc pas séparer les nombres premiers. Avec « $X^3 - Y^3$ », la taille des pièces devient déséquilibrée et le calcul devient inutilement lourd. Pour séparer les nombres premiers en deux, le « carré » qui se divise parfaitement en deux pièces est le plus rentable.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="chapitre-2--comment-trouver-x-et-y---le-puzzle-de-collecte-de-cartes-de-nombres-premiers-">Chapitre 2 : Comment trouver X et Y ? « Le puzzle de collecte de cartes de nombres premiers »
&lt;/h2>&lt;p>L&amp;rsquo;objectif est clair. Cependant, même si nous cherchons aveuglément des « $X^2$ et $Y^2$ qui ont le même reste », la fin de l&amp;rsquo;univers arriverait avant de les trouver.
Alors, les mathématiciens ont imaginé une méthode géniale appelée ** « le puzzle de collecte de cartes de nombres premiers » ** .&lt;/p>
&lt;h3 id="étape-1--collecter-uniquement-de-la-poudre-dor-nombres-friables-avec-un-tamis">Étape 1 : Collecter uniquement de la poudre d&amp;rsquo;or (nombres friables) avec un tamis
&lt;/h3>&lt;p>Tout d&amp;rsquo;abord, préparez un nombre approprié $Z$, élevez-le au carré et calculez le reste $W$ en le divisant par $N$.
(Le monde des restes de $Z^2 = W$)&lt;/p>
&lt;p>Factorisez le reste obtenu $W$ en nombres premiers. Ici, seulement lorsqu&amp;rsquo;il apparaît ** « un $W$ composé uniquement de petits nombres premiers tels que 2, 3, 5, 7, etc. » ** , gardez cette équation comme une « carte gagnante » et jetez-la si de grands nombres premiers sont mélangés.
C&amp;rsquo;est comme jeter de grosses pierres avec un tamis dans une rivière pour ne récolter que de la poudre d&amp;rsquo;or.&lt;/p>
&lt;h3 id="étape-2--le-puzzle-pour-tout-rendre--pair-">Étape 2 : Le puzzle pour tout rendre « pair »
&lt;/h3>&lt;p>Par exemple, supposons que les 3 cartes de poudre d&amp;rsquo;or suivantes ont été collectées.&lt;/p>
&lt;ul>
&lt;li>Carte A : $Z_1^2 = 2^3 \times 3^1$&lt;/li>
&lt;li>Carte B : $Z_2^2 = 2^1 \times 5^1$&lt;/li>
&lt;li>Carte C : $Z_3^2 = 3^1 \times 5^1$&lt;/li>
&lt;/ul>
&lt;p>Multiplions-les toutes.
Le côté droit devient $(2^3 \times 3^1) \times (2^1 \times 5^1) \times (3^1 \times 5^1)$,
Et en organisant le tout ensemble, cela devient ** « $2^4 \times 3^2 \times 5^2$ » ** .&lt;/p>
&lt;p>Étonnamment, la quantité de nombres premiers est devenue « 4, 2, 2 », ** tous étant un nombre pair ** !
Le fait qu&amp;rsquo;ils soient tous pairs signifie que si vous divisez la quantité totale par deux, ce sera « le carré de quelque chose ».
En d&amp;rsquo;autres termes, $(2^2 \times 3^1 \times 5^1)^2 = (60)^2$.&lt;/p>
&lt;p>Le côté gauche est $(Z_1 \times Z_2 \times Z_3)^2$, donc finalement,
** $X = (Z_1 \times Z_2 \times Z_3)$ **
** $Y = 60$ **
La paire tant attendue de « $X^2 = Y^2$ » est complète !&lt;/p>
&lt;p>Pour les ordinateurs, le puzzle consistant à calculer si la quantité de nombres premiers est « paire ou impaire (0 ou 1) » est quelque chose dans lequel ils sont très doués, donc avec cette méthode, $X$ et $Y$ peuvent être trouvés à grande vitesse.&lt;/p>
&lt;hr>
&lt;h2 id="chapitre-3--le-mur-du-désespoir">Chapitre 3 : Le mur du désespoir
&lt;/h2>&lt;p>Maintenant n&amp;rsquo;importe quel code peut être brisé ! &amp;hellip; Ou du moins le pensions-nous, mais un problème majeur survient.
Si le nombre du chiffrement $N$ compte jusqu&amp;rsquo;à « 100 chiffres », cette méthode (appelée Crible Quadratique) peut le résoudre, mais lorsque $N$ atteint « 200 ou 300 chiffres », le $W$ qui apparaît au milieu du calcul devient beaucoup trop grand.&lt;/p>
&lt;p>Lorsque les nombres deviennent trop grands, les « nombres composés uniquement de petits nombres premiers (poudre d&amp;rsquo;or) » cessent purement et simplement d&amp;rsquo;apparaître. Cela devient plus difficile que de chercher des lentilles de contact dans le désert, et les cartes nécessaires pour résoudre le puzzle ne s&amp;rsquo;accumuleront plus du tout.&lt;/p>
&lt;p>Ici, l&amp;rsquo;arme ultime de l&amp;rsquo;humanité, le ** « Crible du corps de nombres généralisé (GNFS) » ** , entre enfin en scène.&lt;/p>
&lt;hr>
&lt;h2 id="chapitre-4--lidée-la-plus-puissante-de-lhumanité-de-créer--deux-mondes-">Chapitre 4 : L&amp;rsquo;idée la plus puissante de l&amp;rsquo;humanité de créer « Deux Mondes »
&lt;/h2>&lt;p>L&amp;rsquo;idée géniale du GNFS est : ** « Les nombres deviennent gigantesques car nous calculons uniquement dans le monde réel. Créons donc un &amp;lsquo;monde caché&amp;rsquo; en utilisant des polynômes (formules avec des lettres) pour diviser le poids du calcul en deux. » **&lt;/p>
&lt;h3 id="la-magie-des-formules-avec-des-lettres">La magie des formules avec des lettres
&lt;/h3>&lt;p>Le GNFS convertit le nombre géant $N$ en une expression littérale à l&amp;rsquo;aide d&amp;rsquo;un nombre de base $m$.
Par exemple si $N=100$, avec $m=4$, alors $100 = 4^3 + 2(4^2) + 4$.
En utilisant la lettre $x$, nous en faisons une formule (le monde caché) : ** $f(x) = x^3 + 2x^2 + x$ ** .&lt;/p>
&lt;p>Ce qui est intéressant avec cette formule, c&amp;rsquo;est qu&amp;rsquo;elle a la propriété que ** « si vous remplacez $x$ par $m$ (4 dans l&amp;rsquo;exemple ci-dessus), vous pouvez toujours revenir au nombre réel $N$ » ** .&lt;/p>
&lt;h3 id="chercher-de-la-poudre-dor-dans-2-mondes-en-même-temps">Chercher de la poudre d&amp;rsquo;or dans 2 mondes en même temps
&lt;/h3>&lt;p>Le GNFS crée de nombreuses paires d&amp;rsquo;entiers aléatoires $(a, b)$ et effectue les deux calculs suivants simultanément :&lt;/p>
&lt;ol>
&lt;li>** Monde Réel ** : $a - b \times m$&lt;/li>
&lt;li>** Monde des Lettres ** : La valeur de $a - b \times x$ calculée selon les règles des polynômes&lt;/li>
&lt;/ol>
&lt;p>En séparant le problème en deux mondes, la taille des nombres manipulés diminue (devient plus légère) de manière spectaculaire. C&amp;rsquo;est comme fendre un rocher géant en deux pierres plus faciles à manipuler.&lt;/p>
&lt;p>Ensuite, vous utilisez un crible (tamis) pour séparer et ne collecter que les paires miraculeuses $(a, b)$ où ** « à la fois dans le monde réel et dans le monde des lettres, les deux sont &amp;lsquo;composés uniquement de petits nombres premiers (poudre d&amp;rsquo;or)&amp;rsquo; » ** . D&amp;rsquo;où le nom de « Crible du corps de nombres ».&lt;/p>
&lt;h3 id="le-moment-où-le-chiffrement-est-enfin-brisé">Le moment où le chiffrement est enfin brisé
&lt;/h3>&lt;p>Une fois que des dizaines de millions de « cartes de poudre d&amp;rsquo;or » sont collectées dans les deux mondes, le superordinateur utilise des calculs matriciels gigantesques pour trouver « une combinaison où le nombre de nombres premiers est entièrement pair », tout comme nous l&amp;rsquo;avons fait au Chapitre 2.&lt;/p>
&lt;p>Une fois la combinaison trouvée :&lt;/p>
&lt;ul>
&lt;li>Que le nombre au carré dans le monde réel soit ** $X^2$ **&lt;/li>
&lt;li>Que la formule au carré créée dans le monde des lettres soit ** $Y(x)^2$ **&lt;/li>
&lt;/ul>
&lt;p>Enfin, remplacez le $x$ dans la formule littérale $Y(x)$ par $m$, en revenant au monde réel et en les rejoignant.
Alors, comme par magie mathématique, la condition où ** « les restes de $X^2$ et $Y^2$ sont les mêmes » ** est strictement remplie !&lt;/p>
&lt;p>Le reste, comme au Chapitre 1, consiste simplement à calculer le plus grand commun diviseur de $X - Y$ et $N$, et le chiffrement RSA impénétrable s&amp;rsquo;effondrera, révélant les nombres premiers secrets.&lt;/p>
&lt;hr>
&lt;h2 id="conclusion--les-mathématiques-ne-finissent-jamais">Conclusion : Les mathématiques ne finissent jamais
&lt;/h2>&lt;p>Vous pourriez penser : « Super, avec le GNFS n&amp;rsquo;importe quel chiffrement peut être brisé ! ».
Cependant, le chiffrement RSA ne s&amp;rsquo;est pas non plus avoué vaincu. Ce qui est utilisé sur l&amp;rsquo;Internet d&amp;rsquo;aujourd&amp;rsquo;hui est un nombre gigantesque et monstrueux appelé « RSA-2048 (environ 617 chiffres) ».&lt;/p>
&lt;p>Bien que le GNFS soit l&amp;rsquo;algorithme le plus puissant de l&amp;rsquo;humanité, même pour résoudre 270 chiffres (RSA-270), on dit que cela prendrait des milliers ou des dizaines de milliers d&amp;rsquo;années, même en connectant des ordinateurs du monde entier. Pour l&amp;rsquo;instant, nos données LINE et bancaires sont en sécurité.&lt;/p>
&lt;p>Mais que se passerait-il si ** « une magie capable de trouver instantanément $X$ et $Y$ pour n&amp;rsquo;importe quel nombre géant » ** apparaissait ?
En fait, la chose qui s&amp;rsquo;en rapproche le plus est l&amp;rsquo; ** « Ordinateur Quantique (Algorithme de Shor) » ** , actuellement en développement. En utilisant la nature ondulatoire de la mécanique quantique, il a été prouvé mathématiquement qu&amp;rsquo;il est possible d&amp;rsquo;ignorer le fastidieux puzzle de collecte de cartes et de tirer la réponse d&amp;rsquo;un seul coup.&lt;/p>
&lt;p>La bataille d&amp;rsquo;intelligence sans fin entre ceux qui créent le chiffrement (la défense) et ceux qui créent des algorithmes pour le briser (l&amp;rsquo;attaque).
Savoir que la « factorisation en nombres premiers » et les « expressions littérales apprises au collège sont en fait les armes qui s&amp;rsquo;affrontent sur la ligne de front de la sécurité mondiale ne rend-il pas les cours de mathématiques un peu plus intéressants ?&lt;/p>
&lt;p>La personne qui découvrira l&amp;rsquo;algorithme le plus puissant du futur, c&amp;rsquo;est peut-être vous qui lisez cet article !&lt;/p>
&lt;hr>
&lt;p>&lt;em>(※Cet article est une adaptation conceptuelle de l&amp;rsquo;attrait mathématique du cassage de code pour les collégiens. Le GNFS réel est rigoureusement calculé à l&amp;rsquo;aide de mathématiques universitaires avancées, telles que les groupes de classes d&amp;rsquo;idéaux des corps de nombres algébriques et les homomorphismes)&lt;/em>&lt;/p></description></item></channel></rss>