<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cryptographie on kenji.blog</title><link>http://kenji.blog/fr/tags/cryptographie/</link><description>Recent content in Cryptographie on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 13:04:59 +0900</lastBuildDate><atom:link href="http://kenji.blog/fr/tags/cryptographie/index.xml" rel="self" type="application/rss+xml"/><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><item><title>Principe de Kerckhoffs</title><link>http://kenji.blog/fr/p/principe-de-kerckhoffs/</link><pubDate>Wed, 16 Apr 2025 23:53:08 +0900</pubDate><guid>http://kenji.blog/fr/p/principe-de-kerckhoffs/</guid><description>&lt;img src="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_2.png" alt="Featured image of post Principe de Kerckhoffs" />&lt;h1 id="principe-de-kerckhoffs">&amp;ldquo;Principe de Kerckhoffs&amp;rdquo;
&lt;/h1>&lt;hr>
&lt;p>Bonjour !&lt;/p>
&lt;p>Aujourd&amp;rsquo;hui, j&amp;rsquo;aimerais parler de quelque chose d&amp;rsquo;un peu intéressant et, en fait, d&amp;rsquo;extrêmement important, appelé le &amp;ldquo;principe de Kerckhoffs&amp;rdquo;.&lt;/p>
&lt;p>Ah, attendez, attendez.&lt;br>
Certains d&amp;rsquo;entre vous pourraient penser : &amp;ldquo;Je n&amp;rsquo;ai jamais entendu parler du &amp;lsquo;principe de Kerckhoffs&amp;rsquo;, et ça a l&amp;rsquo;air un peu technique&amp;hellip;&amp;rdquo;. Ne vous inquiétez pas. Cet article est exactement ce que je veux que les personnes comme vous lisent.&lt;/p>
&lt;hr>
&lt;h2 id="que-signifie-cryptographie-sûre-">Que signifie &amp;ldquo;cryptographie sûre&amp;rdquo; ?
&lt;/h2>&lt;p>Par exemple, supposons que quelqu&amp;rsquo;un dise : &amp;ldquo;Ce coffre-fort ne peut être ouvert que par quelqu&amp;rsquo;un qui connaît la méthode secrète pour l&amp;rsquo;ouvrir&amp;rdquo;.&lt;/p>
&lt;p>À première vue, cela semble très sûr, n&amp;rsquo;est-ce pas ?&lt;br>
Mais, si vous y réfléchissez, n&amp;rsquo;est-ce pas un peu inquiétant ?&lt;/p>
&lt;p>Du genre, &amp;ldquo;Si ce secret est découvert, c&amp;rsquo;est fini ?&amp;rdquo;.&lt;/p>
&lt;p>En fait, c&amp;rsquo;est ce qui a déclenché l&amp;rsquo;apparition du principe de Kerckhoffs.&lt;/p>
&lt;hr>
&lt;h2 id="quest-ce-que-le-principe-de-kerckhoffs-au-juste-">Qu&amp;rsquo;est-ce que le &amp;ldquo;principe de Kerckhoffs&amp;rdquo; au juste ?
&lt;/h2>&lt;p>Pour le dire très simplement, c&amp;rsquo;est l&amp;rsquo;idée que&lt;/p>
&lt;p>&lt;strong>&amp;ldquo;La cryptographie doit être sûre même si son fonctionnement est découvert.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Pour être plus précis, &amp;ldquo;La sécurité ne doit reposer que sur la &amp;lsquo;clé secrète&amp;rsquo;, et la méthode de cryptographie elle-même peut être publique !&amp;rdquo;.&lt;/p>
&lt;p>À l&amp;rsquo;inverse, &amp;ldquo;Un état dans lequel l&amp;rsquo;algorithme (le mécanisme) de chiffrement est gardé secret est considéré comme peu fiable&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="si-le-mécanisme-est-secret-cest-sûr-peut-être-un-peu-dangereux">&amp;ldquo;Si le mécanisme est secret, c&amp;rsquo;est sûr&amp;rdquo; peut être un peu dangereux
&lt;/h2>&lt;p>C&amp;rsquo;est une façon de penser courante :&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Je n&amp;rsquo;ai montré l&amp;rsquo;intérieur de cette application à personne, donc la sécurité est bonne&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Je comprends le sentiment.&lt;br>
Mais cela revient à dire : &amp;ldquo;Personne ne regarde, donc aucun point faible ne sera trouvé, n&amp;rsquo;est-ce pas ?&amp;rdquo;.&lt;/p>
&lt;p>En réalité, le fait même que &amp;ldquo;personne ne regarde&amp;rdquo; peut devenir un risque.&lt;/p>
&lt;hr>
&lt;h2 id="mais-pourquoi-ce-principe-est-il-important-">Mais pourquoi ce principe est-il important ?
&lt;/h2>&lt;p>Parce que, si quelqu&amp;rsquo;un met la main sur le mécanisme et peut facilement le déchiffrer, cette cryptographie est finie.&lt;/p>
&lt;p>Pour utiliser une analogie, c&amp;rsquo;est comme si la serrure d&amp;rsquo;une porte avait un mécanisme très complexe, mais qu&amp;rsquo;elle pouvait en fait être ouverte avec une clé de rechange fabriquée dans un magasin à un dollar.&lt;/p>
&lt;p>Ce n&amp;rsquo;est pas &amp;ldquo;La clé est secrète donc c&amp;rsquo;est bon&amp;rdquo;, mais &amp;ldquo;Même si vous montrez tout le mécanisme, il ne peut pas être ouvert sans la bonne clé&amp;rdquo; qui est important.&lt;/p>
&lt;hr>
&lt;h2 id="le-sentiment-de-mais-nest-ce-pas-un-peu-effrayant-">Le sentiment de &amp;ldquo;Mais n&amp;rsquo;est-ce pas un peu effrayant ?&amp;rdquo;
&lt;/h2>&lt;p>Ce que beaucoup de gens ressentent ici, c&amp;rsquo;est de l&amp;rsquo;anxiété :&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;N&amp;rsquo;est-ce pas un peu effrayant d&amp;rsquo;exposer tout le mécanisme ?&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Je comprends.&lt;br>
Parce que vous vous dites : &amp;ldquo;Si je montre tout l&amp;rsquo;intérieur, ne sera-t-il pas imité ou utilisé à mauvais escient ?&amp;rdquo;.&lt;/p>
&lt;p>Mais c&amp;rsquo;est exactement le cœur du principe de Kerckhoffs.&lt;br>
La &amp;ldquo;force qui ne s&amp;rsquo;effondre pas même quand on montre l&amp;rsquo;intérieur&amp;rdquo; est la véritable sécurité.&lt;/p>
&lt;hr>
&lt;h2 id="cela-dit-il-faut-un-peu-de-courage-au-début">Cela dit, il faut un peu de courage au début
&lt;/h2>&lt;p>Du point de vue du développeur, il semble que &amp;ldquo;publier le mécanisme = exposer ses faiblesses&amp;rdquo;, donc c&amp;rsquo;est bien sûr angoissant.&lt;/p>
&lt;p>Mais pensez-y.&lt;/p>
&lt;p>Quelque chose que vous pouvez montrer correctement en disant : &amp;ldquo;N&amp;rsquo;importe qui peut vérifier&amp;rdquo;, finira par être plus fiable.&lt;/p>
&lt;p>C&amp;rsquo;est semblable aux relations humaines.&lt;/p>
&lt;p>&amp;ldquo;Une personne qui s&amp;rsquo;entend bien avec vous après avoir montré votre vrai moi&amp;rdquo; est finalement la plus rassurante.&lt;/p>
&lt;hr>
&lt;h2 id="en-conclusion">En conclusion
&lt;/h2>&lt;p>Le principe de Kerckhoffs peut sembler un peu théorique, mais son essence est très simple.&lt;/p>
&lt;p>Il s&amp;rsquo;agit simplement de &lt;strong>&amp;ldquo;Créons un mécanisme qui ne se brisera pas, peu importe à qui vous le montrez.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Une conception appropriée plutôt que des secrets superficiels.&lt;br>
Un code que vous n&amp;rsquo;avez pas honte de montrer, plutôt qu&amp;rsquo;un code que vous ne voulez montrer à personne.&lt;/p>
&lt;p>Peut-être que ce type de &amp;ldquo;force&amp;rdquo; sera de plus en plus nécessaire dans l&amp;rsquo;ère à venir.&lt;/p>
&lt;hr>
&lt;p>Merci beaucoup de m&amp;rsquo;avoir lu !&lt;/p>
&lt;p>La sécurité est un sujet un peu difficile, mais certaines parties sont également liées aux &amp;ldquo;relations avec les personnes&amp;rdquo; et à la &amp;ldquo;tranquillité d&amp;rsquo;esprit quotidienne&amp;rdquo;.&lt;br>
Si vous apprenez petit à petit sans vous sentir accablé, je suis sûr que de bonnes choses arriveront.&lt;/p>
&lt;hr>
&lt;p>&lt;img src="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img.png"
width="189"
height="282"
srcset="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_hu715032b7fe5224f655ebb7d29b676305_77325_480x0_resize_box_3.png 480w, http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_hu715032b7fe5224f655ebb7d29b676305_77325_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="Auguste Kerckhoffs"
class="gallery-image"
data-flex-grow="67"
data-flex-basis="160px"
>&lt;/p></description></item></channel></rss>