<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>GNFS on kenji.blog</title><link>http://kenji.blog/en/tags/gnfs/</link><description>Recent content in GNFS on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 13:04:59 +0900</lastBuildDate><atom:link href="http://kenji.blog/en/tags/gnfs/index.xml" rel="self" type="application/rss+xml"/><item><title>[Complete Anatomy] Understanding the Strongest Cryptanalysis Algorithm "GNFS" by Implementing it in C++</title><link>http://kenji.blog/en/p/gnfs-cpp-implementation/</link><pubDate>Sat, 05 Sep 2026 13:04:59 +0900</pubDate><guid>http://kenji.blog/en/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 [Complete Anatomy] Understanding the Strongest Cryptanalysis Algorithm "GNFS" by Implementing it in C++" />&lt;h1 id="complete-anatomy-understanding-the-strongest-cryptanalysis-algorithm-gnfs-by-implementing-it-in-c">[Complete Anatomy] Understanding the Strongest Cryptanalysis Algorithm &amp;ldquo;GNFS&amp;rdquo; by Implementing it in C++
&lt;/h1>&lt;p>The &amp;ldquo;RSA cryptography&amp;rdquo; fundamentally supports the modern Internet. Its robustness relies on the mathematical belief that &amp;ldquo;factoring huge composite numbers is practically impossible with current computers.&amp;rdquo;&lt;/p>
&lt;p>However, humanity has never given up. Currently, for classical computers (regular computers, not quantum computers), there exists the **strongest and most advanced algorithm of humanity ** for performing giant prime factorizations. That is the &lt;strong>&amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>In this article, we will strictly model the state-of-the-art computational logic of GNFS in C++ (using the multiple-precision integer &lt;code>boost::multiprecision&lt;/code> from the Boost library), publish the entire implementation code, and thoroughly explain the depths of &amp;ldquo;algebraic number theory&amp;rdquo; behind it.&lt;/p>
&lt;p>Please enjoy the mystery of mathematics and the brute force of computer science that wrestles it down, along with the source code.&lt;/p>
&lt;hr>
&lt;h2 id="1-gnfs-state-of-the-art-logic-framework-full-source-code">1. GNFS State-of-the-Art Logic Framework (Full Source Code)
&lt;/h2>&lt;p>First, here is the full picture of the C++ implementation of GNFS that we will explain this time. The actual number field sieve (such as CADO-NFS) is an ultra-massive distributed system spanning hundreds of thousands of lines, but this code extracts the &lt;strong>&amp;ldquo;5 essential pipelines (phases)&amp;rdquo;&lt;/strong> that make up GNFS, designs them as classes, and models them in a minimal configuration without losing their mathematical meaning.&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">// Using Boost.Multiprecision for multiple-precision integers
&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] General Number Field Sieve State-of-the-Art Logic Framework
&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">// This code strictly models the 5 pipelines of state-of-the-art GNFS used in
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// CADO-NFS etc., as a class design in 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: Polynomial Selection (KleinJung&amp;#39;s algorithm)
&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">// Algebraic side polynomial 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">// Rational side polynomial 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">// Initial polynomial generation based on base-m expansion (actually uses more advanced lattice basis reduction LLL)
&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">// Simple base-m expansion (degree 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">// Simple approximation of m (approximation without using Boost functions)
&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: 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">// In recent GNFS, instead of Line Sieve, Special-q Lattice Sieving by
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Franke-Kleinjung et al. is the de facto standard.
&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">// (Omitted) In reality, it generates primes and filters them using Legendre symbols, 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">// Mock implementation: Actual lattice sieving scans hundreds of GB of memory space block by block.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// It maps (a, b) pairs to lattices for each special prime q (a = i*q + j*...),
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// and executes a sieve that maximizes cache efficiency.
&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">// Add one dummy relation for demo
&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: Filtering (Singleton removal and clique merging)
&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. Singleton removal (removing relations with primes that appear only once)
&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. Clique merging (merging relations to make a sparse matrix denser)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// In reality, it compresses a matrix of hundreds of millions of rows down to several million using algorithms like Union-Find.
&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: Linear Algebra over GF(2) (Block Wiedemann method)
&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">// In modern supercomputing environments, the Block Wiedemann method (Coppersmith implementation),
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// which is more suitable for distributed computing than the Block Lanczos method, is used as the state-of-the-art.
&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">// Iterates matrix-vector multiplication of a sparse matrix,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// and finds multiple solution vectors (kernels) where 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">// List of dependencies
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Dummy data
&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: 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. Compute the rational side square root V (simple integer arithmetic)
&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. Compute the algebraic side square root gamma (Montgomery&amp;#39;s method, 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">// Find an element gamma in the huge algebraic field O_K, and map it to the real world using the homomorphism map 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">// Assuming that sequences of Quadratic Characters were added in Phases 2 and 4
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// to bypass the obstruction of the ideal class group and the unit group.
&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">// Main Execution Pipeline
&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">// Huge composite number N to factor, such as 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">// Degree of the polynomial (normally select degree 5-6 for numbers over 130 digits)
&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">// Initialize 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">// Actual bounds are tens of millions to hundreds of 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. Polynomial selection
&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. Sieving process
&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. Filtering (matrix compression)
&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. Linear algebra (nullspace search over 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. Algebraic square root computation and GCD
&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>Now, how does this code destroy the cryptographic wall? I will break down and explain the meticulous algorithm and advanced mathematics phase by phase.&lt;/p>
&lt;hr>
&lt;h2 id="2-the-final-goal-of-gnfs-x2-equiv-y2-pmod-n">2. The Final Goal of GNFS: $X^2 \equiv Y^2 \pmod N$
&lt;/h2>&lt;p>The goal that not only GNFS but most modern large integer factorization algorithms aim for is to find a non-trivial pair $(X, Y)$ that satisfies the following congruence:&lt;/p>
$$X^2 \equiv Y^2 \pmod N$$
&lt;p>This equation means that &amp;ldquo;the remainders of $X^2$ and $Y^2$ divided by $N$ are equal&amp;rdquo;. If we transform this:
$X^2 - Y^2 \equiv 0 \pmod N$
In other words, $(X-Y)(X+Y)$ becomes a multiple of $N$.&lt;/p>
&lt;p>If $X \not\equiv \pm Y \pmod N$ (a non-trivial solution), then between $(X-Y)$ and $N$, there exists a &amp;ldquo;common divisor greater than 1 and less than $N$&amp;rdquo;.
Here, if we compute &lt;strong>$\gcd(X-Y, N)$&lt;/strong> using the Euclidean algorithm, the prime factors of $N$ can be easily found.&lt;/p>
&lt;p>However, finding these $X$ and $Y$ is like looking for a needle in a desert. Thus, GNFS takes the genius approach of creating &lt;strong>two worlds&lt;/strong>, the &amp;ldquo;real integer world&amp;rdquo; and the &amp;ldquo;algebraic field of polynomials world&amp;rdquo;, and distributing the computation.&lt;/p>
&lt;hr>
&lt;h2 id="3-phase-1-polynomial-selection">3. Phase 1: 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">// Calculation of m = N^(1/d) and base-m expansion
&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>The first step of GNFS is to create a &amp;ldquo;magic polynomial&amp;rdquo; to bridge the two worlds.
For a huge number $N$, we choose an integer $m$. Usually, it is chosen such that $m \approx N^{1/d}$ (in the code, a polynomial of degree $d=6$ is assumed).&lt;/p>
&lt;p>Then, $N$ is expanded in base $m$, and its coefficients are used to construct the polynomial $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>This polynomial $f(x)$ has the extremely important property that &lt;strong>&amp;ldquo;substituting $m$ for the variable $x$ evaluates exactly to $N$ ($f(m) = N$)&amp;rdquo;&lt;/strong>. In other words, $f(m) \equiv 0 \pmod N$.
The rational side polynomial is defined as $g(x) = x - m$.&lt;/p>
&lt;p>This strongly connects the &lt;strong>&amp;ldquo;algebraic field world $\mathbb{Z}[\alpha]$&amp;rdquo;&lt;/strong> ruled by the root $\alpha$ of $f(x)=0$, and the normal &lt;strong>&amp;ldquo;rational (integer) world $\mathbb{Z}$&amp;rdquo;&lt;/strong>, via a &amp;ldquo;ring homomorphism&amp;rdquo; of $x \to m$.&lt;/p>
&lt;p>In state-of-the-art systems like CADO-NFS, it takes months to search for the &amp;ldquo;most convenient polynomial $f(x)$&amp;rdquo; using KleinJung&amp;rsquo;s algorithm and the LLL lattice basis reduction algorithm, so that the coefficients of the polynomial do not become excessively large, and primes are likely to appear (become smooth) in the subsequent steps.&lt;/p>
&lt;hr>
&lt;h2 id="4-phase-2-special-q-lattice-sieving">4. Phase 2: 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">// Maps (a, b) pairs to lattices for each special prime 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">// and executes a sieve that maximizes cache efficiency.
&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>Once the two worlds are prepared, the next step is to search for &amp;ldquo;smooth numbers (numbers composed entirely of small prime factors)&amp;rdquo; in both worlds.
An infinite number of integer pairs $(a, b)$ are generated, and the following two values are calculated:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Rational side value&lt;/strong>: $a - bm$&lt;/li>
&lt;li>&lt;strong>Algebraic side norm&lt;/strong>: $b^d f(a/b)$&lt;/li>
&lt;/ol>
&lt;p>The goal of GNFS is to collect tens of millions to hundreds of millions of these &lt;strong>&amp;ldquo;pairs (Relations) where both the rational side and algebraic side values can be completely factored into only small prime factors&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>In the early GNFS, a &amp;ldquo;Line Sieve&amp;rdquo; was used, lining up $(a, b)$ on the $xy$ plane and sequentially dividing them by primes from the edges. However, this caused frequent cache misses due to accessing various parts of memory, and its weakness was being extremely slow.&lt;/p>
&lt;p>Therefore, the current state-of-the-art code uses the &lt;strong>&amp;ldquo;Special-q Lattice Sieve&amp;rdquo;&lt;/strong> method.
By fixing a moderately large prime $q$, we restrict the calculation targets to only &amp;ldquo;pairs of $(a, b)$ where the algebraic side value is always divisible by $q$&amp;rdquo;. Since $(a, b)$ satisfying this condition form a &amp;ldquo;lattice&amp;rdquo; on the plane, the jump width of calculated addresses becomes constant, fitting perfectly into the CPU&amp;rsquo;s L1/L2 cache.
With the introduction of this lattice sieving, the calculation speed of GNFS improved dramatically.&lt;/p>
&lt;hr>
&lt;h2 id="5-phase-3-filtering">5. Phase 3: 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. Singleton removal (removing relations with primes that appear only once)
&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. Clique merging (merging relations to make a sparse matrix denser)
&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>Hundreds of millions of relations collected over months by computers around the world in Phase 2. However, if this is thrown as-is into the next &amp;ldquo;step of solving simultaneous equations (matrix calculation)&amp;rdquo;, the supercomputer&amp;rsquo;s memory will blow up.&lt;/p>
&lt;p>Thus, an ultra-compression process of the matrix called &lt;strong>Filtering&lt;/strong> is performed.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Singleton removal&lt;/strong>
Suppose a huge prime $p$ appeared &amp;ldquo;only once&amp;rdquo; in hundreds of millions of relations. Since our goal is to &amp;ldquo;make the exponents of all primes even (multiples of 2)&amp;rdquo;, a prime that appears only once can never be made even.
Therefore, relations containing that prime are immediately removed (purged) as &amp;ldquo;useless garbage&amp;rdquo;. As this happens in a chain reaction, the data that had hundreds of millions of rows is rapidly reduced.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Clique merging&lt;/strong>
Furthermore, by multiplying (adding) relations that share specific primes together, it reduces the number of rows while compressing the sparse (empty) matrix into a denser state (using a method similar to clique search in graph theory).&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>With this optimization, the massive sparse matrix is dramatically compressed to a computable size.&lt;/p>
&lt;hr>
&lt;h2 id="6-phase-4-linear-algebra-over-gf2-block-wiedemann-method">6. Phase 4: Linear Algebra over GF(2) (Block Wiedemann Method)
&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">// Iterates matrix-vector multiplication of a sparse matrix,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// and finds multiple solution vectors (kernels) where 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>Finally, the core of the puzzle.
We multiply the collected relations to find the &lt;strong>&amp;ldquo;combination where the exponents of all prime factors become even&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Mathematically, this means using a huge matrix $M$ whose elements are the &amp;ldquo;even/odd (i.e., 0 or 1)&amp;rdquo; of the exponent of each prime, and a vector $x$ representing which relations to use,
and finding the solution vector $x$ (nullspace/kernel) such that:
&lt;strong>$M \cdot x \equiv 0 \pmod 2$&lt;/strong>&lt;/p>
&lt;p>We must solve a system of simultaneous equations for a matrix of an enormous size, millions of rows by millions of columns. With standard Gaussian elimination, the computational complexity would be $O(N^3)$, and the calculation wouldn&amp;rsquo;t finish until the end of the universe.&lt;/p>
&lt;p>Thus, the &lt;strong>&amp;ldquo;Block Wiedemann method&amp;rdquo;&lt;/strong> is adopted in state-of-the-art implementations.
This is a type of Krylov subspace method that leverages the fact that the matrix $M$ is &amp;ldquo;extremely sparse (mostly 0s)&amp;rdquo; to derive a solution by iteratively performing matrix-vector multiplications.
Unlike the older Block Lanczos method, the Block Wiedemann method can completely divide the computational process across multiple clusters, making it overwhelmingly powerful for parallel computing in modern distributed cloud computing and supercomputers.&lt;/p>
&lt;hr>
&lt;h2 id="7-phase-5-algebraic-square-root-and-cryptographic-collapse">7. Phase 5: Algebraic Square Root and Cryptographic Collapse
&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. Compute the rational side square root 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. Compute the algebraic side square root 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>Through the matrix calculation in Phase 4, we obtained a &amp;ldquo;set of relations $S$ whose product yields even powers for all prime factors&amp;rdquo;.
With this, we can construct a &amp;ldquo;square&amp;rdquo; in both the rational side and the algebraic side worlds.&lt;/p>
&lt;p>For the rational side, it&amp;rsquo;s just integer multiplication, so computing the square root $V$ is easy.
&lt;/p>
$$V^2 = \prod_{S} (a - bm)$$
&lt;p>&lt;strong>However, the real hell lies on the &amp;ldquo;algebraic side&amp;rdquo;.&lt;/strong>
In the algebraic field world $\mathbb{Z}[\alpha]$, since the uniqueness of prime factorization does not hold, calculations have been performed using ideals. What was guaranteed by the matrix calculation is &lt;strong>only that it becomes a &amp;ldquo;square of an ideal&amp;rdquo;, and it is not guaranteed that it becomes a &amp;ldquo;square of an element ($\gamma^2$)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Here stands a formidable wall in algebraic number theory: the &amp;ldquo;obstruction of the ideal class group&amp;rdquo; and the &amp;ldquo;obstruction of the unit group&amp;rdquo;.
In GNFS, we use the magic of &lt;strong>&amp;ldquo;Quadratic Characters&amp;rdquo;&lt;/strong> to break through this wall.
Columns of quadratic residues (Legendre symbols) for several tens of special prime ideals are secretly added in advance to the matrix in Phase 4. As a result, the found set $S$ ignores the obstructions with an overwhelming probability and successfully forms the &amp;ldquo;true square of an element $\gamma^2$&amp;rdquo;.&lt;/p>
&lt;p>The work of finding $\gamma$ (algebraic square root) is computed using highly complex algorithms such as Montgomery&amp;rsquo;s method.&lt;/p>
&lt;p>And finally, we warp the algebraic side square root $\gamma$ into the real world (by substituting $m$ for $x$) via the ring homomorphism $\phi$, yielding $Y$.
If we simply set the rational side $V$ as $X$, the absolute equation we have been pursuing is finally complete.&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>All that is left is to compute $\gcd(X-Y, N)$. Running through the 0.001-second process, the moment a non-trivial factor is printed on the screen, the proudly impregnable RSA cryptography completely collapses.&lt;/p>
&lt;hr>
&lt;h2 id="conclusion">Conclusion
&lt;/h2>&lt;p>GNFS is not just a programming technique.
It is a crystal of human intellect that has wrestled down the &amp;ldquo;depths of pure mathematics&amp;rdquo; like abstract algebra, ring theory, and ideal class groups using &amp;ldquo;extreme engineering&amp;rdquo; like supercomputer distributed architectures and cache optimizations.&lt;/p>
&lt;p>The chat messages and credit card information we casually transmit are protected upon such astronomical mathematical defense and offense.&lt;/p>
&lt;p>Through this C++ framework, I hope you have felt the &amp;ldquo;romance of mathematics and computers&amp;rdquo; behind state-of-the-art cryptanalysis algorithms.&lt;/p></description></item><item><title>The True Mathematical Structure of the General Number Field Sieve (GNFS)</title><link>http://kenji.blog/en/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/en/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 The True Mathematical Structure of the General Number Field Sieve (GNFS)" />&lt;h1 id="the-true-mathematical-structure-of-the-general-number-field-sieve-gnfs">The True Mathematical Structure of the General Number Field Sieve (GNFS)
&lt;/h1>&lt;p>The ultimate goal of GNFS is to find $X^2 \equiv Y^2 \pmod N$.
To achieve this, mathematicians built a bridge between the &lt;strong>&amp;ldquo;world of real integers&amp;rdquo;&lt;/strong> and the &lt;strong>&amp;ldquo;world of algebraic number fields&amp;rdquo;&lt;/strong>. That bridge is the &amp;ldquo;homomorphism&amp;rdquo;.&lt;/p>
&lt;h2 id="stage-1-the-homomorphism-connecting-worlds">Stage 1: The &amp;ldquo;Homomorphism&amp;rdquo; Connecting Worlds
&lt;/h2>&lt;h3 id="1-polynomial-selection-and-root-definition">1. Polynomial Selection and Root Definition
&lt;/h3>&lt;p>For a massive composite number $N$, select an integer $m$ and a polynomial $f(x)$ such that $f(m) \equiv 0 \pmod N$.
(Example: Expand $N$ in base $m$ and create $f(x)$ from its coefficients. Here, assume $f(x)$ is irreducible (cannot be factored further) over the field of rational numbers $\mathbb{Q}$).&lt;/p>
&lt;p>Next, let one of the &amp;ldquo;complex roots&amp;rdquo; of the equation $f(x) = 0$ be $\alpha$.
Naturally, $f(\alpha) = 0$. $\alpha$ is not an integer but a complex number (an algebraic number) that may involve square roots or imaginary numbers.&lt;/p>
&lt;h3 id="2-construction-of-rings-and-homomorphisms">2. Construction of Rings and Homomorphisms
&lt;/h3>&lt;p>Now, prepare two mathematical &amp;ldquo;rings&amp;rdquo; (worlds where addition and multiplication are defined).&lt;/p>
&lt;ul>
&lt;li>&lt;strong>World A: $\mathbb{Z}[\alpha]$&lt;/strong> (Ring of algebraic integers containing $\alpha$)
A world of numbers represented in the form $a + b\alpha + c\alpha^2 + \dots$.&lt;/li>
&lt;li>&lt;strong>World B: $\mathbb{Z}/N\mathbb{Z}$&lt;/strong> (Ring of residues modulo $N$)
A modulo arithmetic world consisting only of integers from $0$ to $N-1$.&lt;/li>
&lt;/ul>
&lt;p>Here, we define a mapping $\phi$ from World A to World B as follows:
&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>This mapping $\phi$ is a magical operation that completely replaces the variable $\alpha$ in World A with the integer $m$ in World B.
This $\phi$ possesses an extremely powerful property known as a &lt;strong>&amp;ldquo;Ring Homomorphism&amp;rdquo;&lt;/strong>.
A homomorphism is the property of &lt;strong>&amp;ldquo;warping to another world without breaking the structure of addition and multiplication&amp;rdquo;&lt;/strong>. In other words, the following equations hold:&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>What does this mean? If we can create a &lt;strong>&amp;ldquo;square ($\gamma^2$)&amp;rdquo;&lt;/strong> of some complex element $\gamma$ in &amp;ldquo;World A (the world of $\alpha$)&amp;rdquo;, warping it to &amp;ldquo;World B (the modulo world)&amp;rdquo; via $\phi$ will ** perfectly preserve the square form $\phi(\gamma)^2$**.&lt;/p>
&lt;hr>
&lt;h2 id="stage-2-the-collapse-of-prime-factorization-and-the-birth-of-the-ideal">Stage 2: The Collapse of Prime Factorization and the Birth of the &amp;ldquo;Ideal&amp;rdquo;
&lt;/h2>&lt;p>We want to collect many appropriate elements $(a - b\alpha)$ in World A ($\mathbb{Z}[\alpha]$) and multiply them together to create a &amp;ldquo;perfect square (square element)&amp;rdquo;.
Normally, we could simply &amp;ldquo;prime factorize&amp;rdquo; each collected $(a - b\alpha)$ and combine them (solving via matrices) so that all prime exponents become even, thus creating a square.&lt;/p>
&lt;p>&lt;strong>However, here a devastating wall of algebra stands in our way.&lt;/strong>
In algebraic number fields like $\mathbb{Z}[\alpha]$, the &lt;strong>&amp;ldquo;uniqueness of prime factorization (any number can be uniquely expressed as a product of primes in exactly one way)&amp;rdquo;, which we learn in middle school, collapses.&lt;/strong>&lt;/p>
&lt;p>(Example: In a certain algebraic number field, $6 = 2 \times 3$, but at the same time $6 = (1+\sqrt{-5}) \times (1-\sqrt{-5})$, making it impossible to know which are the true primes.)&lt;/p>
&lt;p>If prime factorization is not uniquely determined, the puzzle (sieve method) of &amp;ldquo;counting the number of primes to make them even&amp;rdquo; becomes fundamentally impossible to execute.&lt;/p>
&lt;h3 id="the-salvation-by-kummer-and-dedekind-the-ideal">The Salvation by Kummer and Dedekind: The &amp;ldquo;Ideal&amp;rdquo;
&lt;/h3>&lt;p>What saved us from this collapse was the concept of the &lt;strong>&amp;ldquo;Ideal (ideal number)&amp;rdquo;&lt;/strong> created by 19th-century mathematicians.
By considering not the elements themselves but the &amp;ldquo;set of multiples (ideals)&amp;rdquo; generated by those elements, they made prime factorization possible again.&lt;/p>
&lt;p>In the ring of integers of an algebraic number field $\mathcal{O}_K$ (a more complete ring containing $\mathbb{Z}[\alpha]$), even if elements cannot be uniquely prime-factorized, it is proven that &lt;strong>&amp;ldquo;an ideal can always be uniquely prime-factorized into a product of &amp;lsquo;prime ideals ($\mathfrak{p}$)&amp;rsquo; in exactly one way&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Therefore, in GNFS, instead of factorizing the element $(a - b\alpha)$ itself, we perform &lt;strong>prime ideal factorization on the principal ideal $\langle a - b\alpha \rangle$&lt;/strong> that it generates.&lt;/p>
&lt;hr>
&lt;h2 id="stage-3-norms-and-the-two-sieves">Stage 3: Norms and the Two Sieves
&lt;/h2>&lt;p>So, how do we know which prime ideals the ideal $\langle a - b\alpha \rangle$ factors into?
Here, we use a function called the &lt;strong>&amp;ldquo;Norm&amp;rdquo;&lt;/strong>. The norm is a function that converts complex elements of an algebraic number field into &amp;ldquo;ordinary real integers $\mathbb{Z}$&amp;rdquo;.&lt;/p>
&lt;p>The norm of the element $(a - b\alpha)$ can be calculated by a simple polynomial calculation $b^d f(a/b)$ (where $d$ is the degree of $f(x)$).&lt;/p>
&lt;p>Due to algebraic theorems, it is known that &lt;strong>&amp;ldquo;if the norm of a certain ideal can be completely factored into small primes (is smooth), then the original ideal can also be completely factored into small prime ideals.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Thus, GNFS simultaneously calculates the following two values for a massive number of integer pairs $(a, b)$ and collects only the pairs where both values are &amp;ldquo;smooth numbers&amp;rdquo;.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Rational Sieve&lt;/strong>: $a - bm$ (Values in the real world)&lt;/li>
&lt;li>&lt;strong>Algebraic Sieve&lt;/strong>: $b^d f(a/b)$ (Norm in the algebraic number field world)&lt;/li>
&lt;/ol>
&lt;p>By collecting tens of millions of pairs $(a, b)$ where both are smooth, and solving the prime factorization data of ideals (how many prime ideals are included) as a giant matrix (linear algebra over GF(2)), we find a set $S$ of pairs such that &amp;ldquo;when multiplied together, the exponents of all prime ideals become even&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="stage-4-the-two-confronting-obstructions-and-the-ideal-class-group">Stage 4: The Two Confronting &amp;ldquo;Obstructions&amp;rdquo; and the Ideal Class Group
&lt;/h2>&lt;p>Through matrix calculations, we found that multiplying all the ideals of $(a - b\alpha)$ belonging to set $S$ results in the square of a certain ideal $I$.
&lt;/p>
$$\prod_{S} \langle a - b\alpha \rangle = I^2$$
&lt;p>&lt;strong>However, it doesn&amp;rsquo;t end here. The deepest and most difficult mathematical wall in GNFS lies here.&lt;/strong>&lt;/p>
&lt;p>What we ultimately want is not the &amp;ldquo;square of an ideal&amp;rdquo;, but the &lt;strong>&amp;ldquo;square of an element ($\gamma^2$)&amp;rdquo;&lt;/strong> to plug into the mapping $\phi$.
Just because the ideal is squared doesn&amp;rsquo;t necessarily mean the element itself is squared. There exist &lt;strong>two formidable mathematical obstructions&lt;/strong> here.&lt;/p>
&lt;h3 id="obstruction-1-the-wall-of-the-ideal-class-group">Obstruction 1: The Wall of the Ideal Class Group
&lt;/h3>&lt;p>The ideal $I$ is not always an &amp;ldquo;ideal generated by a single element (principal ideal)&amp;rdquo;.
It is impossible to extract a concrete element $\gamma$ from an ideal that is not principal.&lt;/p>
&lt;p>Here, the concept of the &lt;strong>&amp;ldquo;Ideal Class Group ($Cl_K$)&amp;rdquo;&lt;/strong> comes into play. The ideal class group is a group that measures &amp;ldquo;how many non-principal ideals exist in that algebraic number field (how much the uniqueness of prime factorization is broken)&amp;rdquo;.
Even if $\prod \langle a - b\alpha \rangle$ becomes $I^2$, if $I$ is not the identity element (principal ideal) in the ideal class group, it cannot be pulled back to the square of an element.&lt;/p>
&lt;h3 id="obstruction-2-the-wall-of-the-unit-group">Obstruction 2: The Wall of the Unit Group
&lt;/h3>&lt;p>Suppose we get lucky and $I$ is a principal ideal $\langle \gamma \rangle$.
Then, $\prod \langle a - b\alpha \rangle = \langle \gamma^2 \rangle$.
You might think, &amp;ldquo;Great, the element is squared too!&amp;rdquo;, but that is a huge mistake.&lt;/p>
&lt;p>The fact that ideals (sets of multiples) are equal does not mean the elements are completely equal. A deviation by a &lt;strong>&amp;ldquo;Unit (a number whose reciprocal is also an integer, like 1 or -1)&amp;rdquo;&lt;/strong> inevitably occurs.
In other words, the actual equality of the elements is as follows:
&lt;/p>
$$\prod_{S} (a - b\alpha) = u \cdot \gamma^2$$
&lt;p>
($u$ is an element of the unit group $U_K$)&lt;/p>
&lt;p>Unless this unit $u$ itself is the square of something (a square element), the left side can absolutely never become a &amp;ldquo;perfect square of an element&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="stage-5-adlemans-magic-quadratic-characters">Stage 5: Adleman&amp;rsquo;s Magic &amp;ldquo;Quadratic Characters&amp;rdquo;
&lt;/h2>&lt;p>The obstruction of the ideal class group and the obstruction of the unit group. How do we overcome these two?
Here, a genius method called &lt;strong>&amp;ldquo;Quadratic Characters&amp;rdquo;&lt;/strong>, introduced by cryptographer Leonard Adleman (the &amp;ldquo;A&amp;rdquo; in RSA) and others, makes its appearance.&lt;/p>
&lt;p>To determine &amp;ldquo;whether a certain element is a perfect square in the algebraic number field&amp;rdquo;, we use an algebraic number field version of the Legendre symbol (quadratic residue).
To the giant matrix from earlier (the puzzle to make the count of prime ideals even), we secretly append dozens of additional conditions (columns) stating that &lt;strong>&amp;ldquo;the quadratic characters for some special prime ideals $\mathfrak{q}$ also all become $1$ (even)&amp;rdquo;.&lt;/strong>&lt;/p>
&lt;p>When we find a set $S$ that satisfies even these additional conditions through matrix calculations, deep theorems of algebraic number theory guarantee that &lt;strong>&amp;ldquo;both the obstruction of the ideal class group and the obstruction of the unit group will naturally vanish with overwhelming probability.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>With this, we finally obtain the true equation.
&lt;/p>
$$\prod_{S} (a - b\alpha) = \gamma^2$$
&lt;hr>
&lt;h2 id="final-stage-the-convergence-of-worlds-and-the-fall-of-encryption">Final Stage: The Convergence of Worlds and the Fall of Encryption
&lt;/h2>&lt;p>Finally, all the pieces of the puzzle are in place.&lt;/p>
&lt;p>&lt;strong>[Element in the Algebraic Number Field World (World A)]&lt;/strong>
$\gamma^2 = \prod (a - b\alpha)$
(We find $\gamma$ from this using a square root algorithm)&lt;/p>
&lt;p>&lt;strong>[Element in the Real World (World of Rational Numbers)]&lt;/strong>
$V^2 = \prod (a - bm)$
(Since this is just ordinary integer multiplication, the square root $V$ can be found normally)&lt;/p>
&lt;p>Now, it&amp;rsquo;s time for the magical bridge we built at the very beginning, the &lt;strong>homomorphism $\phi$&lt;/strong>, to take the stage.
We warp the element $\gamma$ from World A to World B (the world modulo $N$) using $\phi$ (the mapping that substitutes $m$ for $\alpha$).
&lt;/p>
$$Y = \phi(\gamma) \pmod N$$
&lt;p>Meanwhile, we take the $V$ created in the real world directly to the modulo world and call it $X$.
&lt;/p>
$$X = V \pmod N$$
&lt;p>Due to the homomorphism&amp;rsquo;s property of &amp;ldquo;preserving structure&amp;rdquo;, the square relationship that held in World A is perfectly preserved in World B (the world modulo $N$) as well.
Furthermore, because the original pairs $(a, b)$ were correspondingly created in the forms $a - b\alpha$ and $a - bm$, these $X$ and $Y$ collide in the world modulo $N$ to produce the following absolute equation:&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>All that is left is to pray that these $X$ and $Y$ are not trivial solutions ($X \equiv \pm Y$) and calculate:
&lt;strong>$\gcd(X - Y, N)$&lt;/strong>&lt;/p>
&lt;p>If it is a non-trivial solution, the Euclidean algorithm will race through in 0.001 seconds, and the secret primes $p$ and $q$, which are the heart of RSA encryption, will be printed on the output screen.&lt;/p>
&lt;hr>
&lt;p>This is the &lt;strong>complete form of the &amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo;&lt;/strong>, gathering the essence of modern mathematics.&lt;/p></description></item><item><title>What is the "General Number Field Sieve (GNFS)", Humanity's Strongest Math that Breaks Internet Cryptography?</title><link>http://kenji.blog/en/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/en/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 What is the "General Number Field Sieve (GNFS)", Humanity's Strongest Math that Breaks Internet Cryptography?" />&lt;h1 id="what-is-the-general-number-field-sieve-gnfs-humanitys-strongest-math-that-breaks-internet-cryptography">What is the &amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo;, Humanity&amp;rsquo;s Strongest Math that Breaks Internet Cryptography?
&lt;/h1>&lt;p>The internet we use every day. LINE messages, YouTube, Amazon shopping—all communications are protected by &amp;ldquo;cryptography.&amp;rdquo;
Currently, the most widely used cryptography in the world is &amp;ldquo;RSA cryptography.&amp;rdquo;&lt;/p>
&lt;p>The cornerstone of RSA cryptography&amp;rsquo;s defense is very simple. It utilizes the mathematical property that &lt;strong>&amp;ldquo;factoring a gigantic number into primes cannot be solved even by computers.&amp;rdquo;&lt;/strong>
For example, for &amp;ldquo;15&amp;rdquo;, we immediately know it&amp;rsquo;s &amp;ldquo;3 × 5&amp;rdquo;, but the moment this becomes a &amp;ldquo;270-digit number&amp;rdquo;, even if we bundle all the supercomputers in the world, it would take hundreds of millions of years to solve.&lt;/p>
&lt;p>However, mathematicians do not stay silent either. To break this ironclad cryptography, humanity created a magical algorithm (calculation procedure) called the &lt;strong>&amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>In this article, without using any specialized jargon, and only with knowledge of &lt;strong>junior high school math (prime factorization, algebraic expressions, greatest common divisor)&lt;/strong>, we will completely explain the mechanism step-by-step by which this &amp;ldquo;humanity&amp;rsquo;s strongest algorithm&amp;rdquo; breaks cryptography!&lt;/p>
&lt;hr>
&lt;h2 id="chapter-1-the-goal-of-decryption-is-a-junior-high-school-formula">Chapter 1: The Goal of Decryption is a &amp;ldquo;Junior High School Formula&amp;rdquo;
&lt;/h2>&lt;p>The ultimate special move to confront gigantic prime factorizations. It&amp;rsquo;s this formula learned in junior high school.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>$X^2 - Y^2 = (X + Y)(X - Y)$&lt;/strong>&lt;/p>
&lt;/blockquote>
&lt;p>You might think, &amp;ldquo;Eh, can such a basic formula break cryptography?&amp;rdquo; However, this is the master key that unlocks everything.&lt;/p>
&lt;p>The ultimate goal for breaking the cryptography is to find, for a gigantic number $N$,
&lt;strong>&amp;ldquo;Numbers ($X$ and $Y$) where the remainder of $X^2$ and $Y^2$ divided by $N$ are the same.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;h3 id="why-does-same-remainder-solve-the-cryptography">Why does &amp;ldquo;same remainder&amp;rdquo; solve the cryptography?
&lt;/h3>&lt;p>Suppose two numbers, $X^2$ and $Y^2$, have the &amp;ldquo;same remainder when divided by $N$.&amp;rdquo;
Having the same remainder means there is a rule that &lt;strong>the subtracted &amp;ldquo;$X^2 - Y^2$&amp;rdquo; will always be perfectly divisible by $N$ (it becomes a multiple of $N$)&lt;/strong>.&lt;/p>
&lt;p>Here, let&amp;rsquo;s say the gigantic number $N$ used for cryptography is made of the multiplication of two secret prime numbers ($p$ and $q$) ($N = p \times q$).&lt;/p>
&lt;p>Factoring $X^2 - Y^2$ results in &lt;strong>$(X - Y)(X + Y)$&lt;/strong>.
The fact that this is a multiple of $N$ means that somewhere in this multiplication, the secret primes $p$ and $q$ are hidden.&lt;/p>
&lt;p>Here a miracle occurs.
There is mathematically a &lt;strong>50% (1/2)&lt;/strong> probability that the two prime numbers $p$ and $q$ will naturally separate into different rooms, with &lt;strong>&amp;quot;$p$ going to the $(X - Y)$ room&amp;quot;&lt;/strong> and &lt;strong>&amp;quot;$q$ going to the $(X + Y)$ room&amp;quot;&lt;/strong>.&lt;/p>
&lt;p>With only the prime number $p$ in the $(X - Y)$ room, let&amp;rsquo;s calculate the &lt;strong>&amp;ldquo;Greatest Common Divisor (the largest common part)&amp;rdquo;&lt;/strong> of $(X - Y)$ and $N$.&lt;/p>
&lt;ul>
&lt;li>Contents of $(X - Y)$ = $p \times$ some number&lt;/li>
&lt;li>Contents of $N$ = $p \times q$
The only common part is &lt;strong>&amp;quot;$p$&amp;quot;&lt;/strong>!&lt;/li>
&lt;/ul>
&lt;p>In other words, the moment you calculate the greatest common divisor, the hidden prime number $p$ pops out, and the cryptography is completely decrypted. (*The greatest common divisor can be calculated instantly even on a smartphone using the &amp;ldquo;Euclidean Algorithm&amp;rdquo;.)&lt;/p>
&lt;p>&lt;strong>[A Little Column: Why squared? Why not cubed or doubled?]&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>If it&amp;rsquo;s &amp;ldquo;$2X - 2Y$&amp;rdquo;, it becomes $2(X - Y)$, and since there&amp;rsquo;s only one room, you can&amp;rsquo;t separate the primes. If it&amp;rsquo;s &amp;ldquo;$X^3 - Y^3$&amp;rdquo;, the size of the rooms becomes unbalanced, making the calculations unnecessarily heavy. To separate the primes into two, &amp;ldquo;squaring&amp;rdquo;, which beautifully divides into two rooms, is the most cost-effective.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="chapter-2-how-to-find-x-and-y-the-prime-card-collection-puzzle">Chapter 2: How to Find X and Y? The &amp;ldquo;Prime Card Collection Puzzle&amp;rdquo;
&lt;/h2>&lt;p>The goal is clear. However, if you blindly search for &amp;ldquo;$X^2$ and $Y^2$ that yield the same remainder&amp;rdquo;, you won&amp;rsquo;t find it until the end of the universe.
Therefore, mathematicians came up with a genius method called the &lt;strong>&amp;ldquo;Prime Card Collection Puzzle&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="step-1-collect-only-gold-dust-smooth-numbers-with-a-sieve">Step 1: Collect Only Gold Dust (Smooth Numbers) with a Sieve
&lt;/h3>&lt;p>First, prepare an appropriate number $Z$, square it, and calculate the remainder $W$ when divided by $N$.
(The world of remainders where $Z^2 = W$)&lt;/p>
&lt;p>Factorize the resulting remainder $W$. Here, only when a &lt;strong>&amp;quot;$W$ made only of small prime numbers like 2, 3, 5, 7&amp;quot;&lt;/strong> appears, you keep that equation as a &amp;ldquo;winning card&amp;rdquo;, and throw it away if large primes are mixed in.
It&amp;rsquo;s a task like discarding large stones with a sieve in a river and collecting only gold dust.&lt;/p>
&lt;h3 id="step-2-the-puzzle-of-making-everything-an-even-number">Step 2: The Puzzle of Making Everything an &amp;ldquo;Even Number&amp;rdquo;
&lt;/h3>&lt;p>For example, suppose the following three gold dust cards were collected.&lt;/p>
&lt;ul>
&lt;li>Card A: $Z_1^2 = 2^3 \times 3^1$&lt;/li>
&lt;li>Card B: $Z_2^2 = 2^1 \times 5^1$&lt;/li>
&lt;li>Card C: $Z_3^2 = 3^1 \times 5^1$&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s multiply all these together.
The right side becomes $(2^3 \times 3^1) \times (2^1 \times 5^1) \times (3^1 \times 5^1)$, and
when summarized and organized, it becomes &lt;strong>&amp;quot;$2^4 \times 3^2 \times 5^2$&amp;quot;&lt;/strong>.&lt;/p>
&lt;p>Amazingly, the number of prime numbers became &amp;ldquo;4, 2, 2&amp;rdquo;, which are &lt;strong>all even numbers&lt;/strong>!
Having all even numbers means that if you halve the count of everything, it becomes the &amp;ldquo;square of something.&amp;rdquo;
In other words, $(2^2 \times 3^1 \times 5^1)^2 = (60)^2$.&lt;/p>
&lt;p>The left side is $(Z_1 \times Z_2 \times Z_3)^2$, so with this, finally,
&lt;strong>$X = (Z_1 \times Z_2 \times Z_3)$&lt;/strong>
&lt;strong>$Y = 60$&lt;/strong>
The long-awaited &amp;ldquo;$X^2 = Y^2$&amp;rdquo; pair is completed!&lt;/p>
&lt;p>For computers, the puzzle of calculating whether the number of primes is &amp;ldquo;even or odd (0 or 1)&amp;rdquo; is something they are very good at, so with this method, they can find $X$ and $Y$ at high speed.&lt;/p>
&lt;hr>
&lt;h2 id="chapter-3-the-wall-of-despair-that-stands-in-the-way">Chapter 3: The Wall of Despair That Stands in the Way
&lt;/h2>&lt;p>Now any cryptography can be broken!&amp;hellip; Or so we thought, but a big problem arises.
If the cryptography number $N$ is up to about &amp;ldquo;100 digits&amp;rdquo;, it can be solved with this method (called the Quadratic Sieve), but when $N$ becomes &amp;ldquo;200 digits or 300 digits&amp;rdquo;, the $W$ that appears during the calculation becomes too huge.&lt;/p>
&lt;p>When the numbers get too huge, &amp;ldquo;numbers made only of small prime numbers (gold dust)&amp;rdquo; completely stop appearing. It becomes harder than searching for a contact lens in a desert, and you can&amp;rsquo;t collect the cards to solve the puzzle at all.&lt;/p>
&lt;p>Here finally, humanity&amp;rsquo;s ultimate weapon, the &lt;strong>&amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo;&lt;/strong>, makes its appearance.&lt;/p>
&lt;hr>
&lt;h2 id="chapter-4-humanitys-strongest-idea-creating-two-worlds">Chapter 4: Humanity&amp;rsquo;s Strongest Idea, Creating &amp;ldquo;Two Worlds&amp;rdquo;
&lt;/h2>&lt;p>The genius idea of GNFS is: &lt;strong>&amp;ldquo;Calculating only in the real world makes the numbers huge. So, let&amp;rsquo;s create a &amp;lsquo;hidden world&amp;rsquo; using polynomials (algebraic expressions) and split the weight of the calculation into two.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;h3 id="the-magic-of-algebraic-expressions">The Magic of Algebraic Expressions
&lt;/h3>&lt;p>GNFS converts the gigantic number $N$ into an algebraic expression using a base number $m$.
For example, if $N=100$, let $m=4$, so $100 = 4^3 + 2(4^2) + 4$.
This is turned into the expression (the hidden world) &lt;strong>$f(x) = x^3 + 2x^2 + x$&lt;/strong> using the letter $x$.&lt;/p>
&lt;p>The interesting thing about this expression is that it has the property: &lt;strong>&amp;ldquo;If you substitute $m$ (4 in the example above) for the letter $x$, you can always warp back to the real number $N$.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;h3 id="searching-for-gold-dust-in-two-worlds-simultaneously">Searching for Gold Dust in Two Worlds Simultaneously
&lt;/h3>&lt;p>GNFS creates many pairs of random integers $(a, b)$ and performs the following two calculations simultaneously.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Real World&lt;/strong>: $a - b \times m$&lt;/li>
&lt;li>&lt;strong>World of Algebraic Expressions&lt;/strong>: The value calculated by the rules of algebraic expressions for $a - b \times x$&lt;/li>
&lt;/ol>
&lt;p>By splitting the problem into two worlds, the size of the numbers handled becomes dramatically smaller (lighter). It&amp;rsquo;s the image of splitting a huge rock into two to make them easy-to-handle stones.&lt;/p>
&lt;p>Then, you sift and collect only the miracle pairs $(a, b)$ where &lt;strong>&amp;ldquo;Both in the real world and in the world of algebraic expressions, they are &amp;lsquo;made only of small prime numbers (gold dust)&amp;rsquo;&amp;rdquo;&lt;/strong>. This is the origin of the name &amp;ldquo;Number Field Sieve.&amp;rdquo;&lt;/p>
&lt;h3 id="the-moment-the-cryptography-is-finally-broken">The Moment the Cryptography is Finally Broken
&lt;/h3>&lt;p>Once tens of millions of &amp;ldquo;gold dust cards&amp;rdquo; are collected from both worlds, using the giant matrix calculations of supercomputers, you find the &amp;ldquo;combination where the number of prime numbers all become even&amp;rdquo;, just as we did in Chapter 2.&lt;/p>
&lt;p>Once the combination is found,&lt;/p>
&lt;ul>
&lt;li>Let the squared number made in the real world be &lt;strong>$X^2$&lt;/strong>&lt;/li>
&lt;li>Let the squared expression made in the world of algebraic expressions be &lt;strong>$Y(x)^2$&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Finally, substitute $m$ into $x$ of $Y(x)$ in the world of algebraic expressions to warp to the real world and merge them.
Then, just like mathematical magic, a state where &lt;strong>&amp;ldquo;the remainders of $X^2$ and $Y^2$ are the same&amp;rdquo;&lt;/strong> is strictly completed!&lt;/p>
&lt;p>After that, just like in Chapter 1, if you calculate the greatest common divisor of $X - Y$ and $N$, the impregnable RSA cryptography collapses with a crash, and the secret primes reveal themselves.&lt;/p>
&lt;hr>
&lt;h2 id="conclusion-mathematics-never-ends">Conclusion: Mathematics Never Ends
&lt;/h2>&lt;p>You might have thought, &amp;ldquo;Alright, with GNFS, any cryptography can be broken!&amp;rdquo;
However, RSA cryptography is not giving up either. What is currently used on the internet is a monstrously huge number called &amp;ldquo;RSA-2048 (about 617 digits)&amp;rdquo;.&lt;/p>
&lt;p>Even though GNFS is humanity&amp;rsquo;s strongest algorithm, it is said that even to solve 270 digits (RSA-270), it would take thousands or tens of thousands of years even if all the computers in the world were connected. For now, our LINE and bank data are safe.&lt;/p>
&lt;p>But what if a &lt;strong>&amp;ldquo;magic that instantly finds $X$ and $Y$ for any gigantic number&amp;rdquo;&lt;/strong> appears?
Actually, the closest thing to that is the &lt;strong>&amp;ldquo;Quantum Computer (Shor&amp;rsquo;s Algorithm)&amp;rdquo;&lt;/strong> currently under development. It has been mathematically proven that by using the wave properties of quantum mechanics, one can ignore the tedious card collecting puzzle and draw the answer in one shot.&lt;/p>
&lt;p>The endless battle of wits between the people who make cryptography (defense) and the people who make algorithms to break it (attack).
When you learn that the &amp;ldquo;prime factorization&amp;rdquo; and &amp;ldquo;algebraic expressions&amp;rdquo; learned in junior high school are actually weapons fiercely fighting on the front lines of global security, doesn&amp;rsquo;t math class seem just a little bit more interesting?&lt;/p>
&lt;p>The person to discover the strongest algorithm of the future might just be you reading this article!&lt;/p>
&lt;hr>
&lt;p>&lt;em>(Note: This article conceptualizes the mathematical charm of cryptography decryption for junior high school students. Actual GNFS is strictly calculated using advanced university mathematics such as ideal class groups of algebraic number fields and homomorphisms.)&lt;/em>&lt;/p></description></item><item><title>[Complete Mathematical Guide] Why the Ultimate Classical 'GNFS' Loses to Quantum Algorithms: The Paradigm Shift in Prime Factorization</title><link>http://kenji.blog/en/p/gnfs-to-shors-algorithm-math-deepdive/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://kenji.blog/en/p/gnfs-to-shors-algorithm-math-deepdive/</guid><description>&lt;img src="http://kenji.blog/p/gnfs-to-shors-algorithm-math-deepdive/quantum_vs_gnfs_eyecatch_1788616101508.jpg" alt="Featured image of post [Complete Mathematical Guide] Why the Ultimate Classical 'GNFS' Loses to Quantum Algorithms: The Paradigm Shift in Prime Factorization" />&lt;p>Information security in the modern internet society is protected by public-key cryptography, such as RSA cryptography. The basis for the security of RSA relies on the fact that &lt;strong>&amp;ldquo;the prime factorization of huge composite numbers is computationally extremely difficult.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>In this article, we will unravel the mathematical mechanism of the &lt;strong>&amp;ldquo;General Number Field Sieve&amp;rdquo;&lt;/strong> (GNFS), which is the most powerful prime factorization algorithm for classical computers. We will also dive deeply into why it is completely defeated by &lt;strong>&amp;ldquo;Shor&amp;rsquo;s Algorithm,&amp;rdquo;&lt;/strong> discovered by Peter Shor, exploring this paradigm shift thoroughly with mathematical formulas and conceptual diagrams.&lt;/p>
&lt;hr>
&lt;h2 id="1-the-approach-to-prime-factorization-in-classical-computing-evolution-from-fermats-factorization-method">1. The Approach to Prime Factorization in Classical Computing: Evolution from Fermat&amp;rsquo;s Factorization Method
&lt;/h2>&lt;p>The prime factorization problem is the problem of finding prime numbers $p$ and $q$ such that $N = p \times q$ for a given composite number $N$.&lt;/p>
&lt;p>The basic idea reduces to finding non-trivial $x$ and $y$ that satisfy the following congruence:&lt;/p>
$$ x^2 \equiv y^2 \pmod N $$
&lt;p>By rearranging this, we get:&lt;/p>
$$ x^2 - y^2 \equiv 0 \pmod N $$
$$ (x - y)(x + y) \equiv 0 \pmod N $$
&lt;p>Here, if $x \not\equiv \pm y \pmod N$, we can obtain a non-trivial factor of $N$ by calculating $\gcd(x-y, N)$ or $\gcd(x+y, N)$. This fact is the foundation of modern prime factorization algorithms like GNFS.&lt;/p>
&lt;hr>
&lt;h2 id="2-the-ultimate-classical-algorithm-the-depths-of-the-general-number-field-sieve-gnfs">2. The Ultimate Classical Algorithm: The Depths of the &amp;ldquo;General Number Field Sieve&amp;rdquo; (GNFS)
&lt;/h2>&lt;p>&lt;strong>&amp;ldquo;GNFS&amp;rdquo;&lt;/strong> is the fastest known prime factorization algorithm for classical computers today. Its time complexity requires sub-exponential time.&lt;/p>
&lt;h3 id="complexity-of-gnfs">Complexity of GNFS
&lt;/h3>&lt;p>Letting the number of digits (bits) of the number $N$ be $b = \log_2 N$, the computational complexity of GNFS is expressed as follows:&lt;/p>
$$ O\left( \exp \left( \left(\frac{64}{9} b\right)^{1/3} (\log b)^{2/3} \right) \right) $$
&lt;p>As can be seen from this formula, the computational complexity is not polynomial time, but &lt;strong>&amp;ldquo;sub-exponential time,&amp;rdquo;&lt;/strong> which is slightly slower than exponential time. Still, as the number of digits increases, the computation time grows astronomically.&lt;/p>
&lt;h3 id="mathematical-mechanism-of-gnfs">Mathematical Mechanism of GNFS
&lt;/h3>&lt;p>GNFS consists broadly of four steps:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Polynomial Selection&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Sieving&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Matrix Reduction&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Square Root&lt;/strong>&lt;/li>
&lt;/ol>
&lt;h4 id="21-polynomial-selection-and-number-fields">2.1. Polynomial Selection and Number Fields
&lt;/h4>&lt;p>First, we select irreducible polynomials $f(x)$ and $g(x)$ with integer coefficients. These are set to have a common root $m$ modulo $N$. That is,&lt;/p>
$$ f(m) \equiv 0 \pmod N $$
$$ g(m) \equiv 0 \pmod N $$
&lt;p>Usually, $g(x)$ is chosen as a linear polynomial $g(x) = x - m$. If we let $\alpha$ be a root of $f(x)$, a &lt;strong>&amp;ldquo;Number Field&amp;rdquo;&lt;/strong> $\mathbb{Q}(\alpha)$ is constructed. We compare operations in the ring of $\mathbb{Q}(\alpha)$ and operations in the normal integer ring $\mathbb{Z}$ through the homomorphism $\phi: \alpha \mapsto m$.&lt;/p>
&lt;h4 id="22-sieving">2.2. Sieving
&lt;/h4>&lt;p>Next, we search for a massive number of coprime integer pairs $(a, b)$. The goal is to find pairs such that the following two values are both &lt;strong>&amp;ldquo;B-smooth&amp;rdquo;&lt;/strong> (composed only of relatively small prime factors):&lt;/p>
&lt;ol>
&lt;li>$a - bm$ (value over the integer ring)&lt;/li>
&lt;li>$b^d f(a/b)$ (corresponding to the norm $N(a - b\alpha)$ over the number field)&lt;/li>
&lt;/ol>
&lt;p>Here, a high-speed search method called a &lt;strong>&amp;ldquo;Sieve&amp;rdquo;&lt;/strong> is used. This efficiently extracts $(a, b)$ pairs that satisfy the conditions from a vast number of candidates.&lt;/p>
&lt;h4 id="23-linear-algebra-over-gf2-matrix-reduction">2.3. Linear Algebra over GF(2) (Matrix Reduction)
&lt;/h4>&lt;p>From the collected pairs $(a, b)$, we construct exponent vectors and find the left null space of a massive sparse matrix over $\mathbb{F}_2$ (the field with only elements 0 and 1).&lt;/p>
&lt;p>We find a vector $v$ as a solution so that the relations $ \prod (a_i - b_i m) $ and $ \prod (a_i - b_i \alpha) $ both become squares. This is nothing but solving a system of linear equations:&lt;/p>
$$ M \mathbf{x} \equiv \mathbf{0} \pmod 2 $$
&lt;p>Advanced numerical algorithms such as the Block Lanczos Algorithm and the Block Wiedemann Algorithm are utilized here.&lt;/p>
&lt;h4 id="24-square-root">2.4. Square Root
&lt;/h4>&lt;p>Finally, we take square roots in both the number field and the integer ring to derive the relation $x^2 \equiv y^2 \pmod N$. Then, we calculate $\gcd(x-y, N)$ to obtain the factor.&lt;/p>
&lt;hr>
&lt;h2 id="3-the-breakthrough-by-quantum-computing-shors-algorithm">3. The Breakthrough by Quantum Computing: &amp;ldquo;Shor&amp;rsquo;s Algorithm&amp;rdquo;
&lt;/h2>&lt;p>While GNFS requires sub-exponential time, &lt;strong>&amp;ldquo;Shor&amp;rsquo;s Algorithm,&amp;rdquo;&lt;/strong> published by Peter Shor in 1994, can solve this problem in &lt;strong>&amp;ldquo;polynomial time&amp;rdquo;&lt;/strong> by using a quantum computer.&lt;/p>
&lt;h3 id="complexity-of-shors-algorithm">Complexity of Shor&amp;rsquo;s Algorithm
&lt;/h3>&lt;p>When the number of qubits is $O(\log N)$, the time complexity is as follows:&lt;/p>
$$ O((\log N)^3) $$
&lt;p>This means it does not cause an exponential explosion with respect to the number of bits. This is an astonishing result: even for huge composite numbers where the complexity of &lt;strong>&amp;ldquo;classical computing&amp;rdquo;&lt;/strong> exceeds the lifespan of the universe, they can be cracked in hours to days with &lt;strong>&amp;ldquo;quantum computing.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;h3 id="overview-of-shors-algorithm-reduction-to-the-period-finding-problem">Overview of Shor&amp;rsquo;s Algorithm: Reduction to the Period-Finding Problem
&lt;/h3>&lt;p>Shor&amp;rsquo;s algorithm cleverly reduces the prime factorization problem to a &lt;strong>&amp;ldquo;period-finding problem.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Choose a random integer $a$ coprime to $N$ ($1 &lt; a &lt; N$).&lt;/li>
&lt;li>Define the function $f(x) = a^x \bmod N$.&lt;/li>
&lt;li>Find the period $r$ of $f(x)$, i.e., the smallest positive integer $r$ such that $a^r \equiv 1 \pmod N$.&lt;/li>
&lt;li>If $r$ is even, check if $a^{r/2} \not\equiv -1 \pmod N$, and calculate $\gcd(a^{r/2} \pm 1, N)$ to obtain a prime factor.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>&amp;ldquo;Finding the period $r$&amp;rdquo;&lt;/strong> in step 3 is the bottleneck that requires exponential time on classical computers, but quantum computers solve this instantly using &lt;strong>&amp;ldquo;quantum superposition&amp;rdquo;&lt;/strong> and the &lt;strong>&amp;ldquo;Quantum Fourier Transform&amp;rdquo;&lt;/strong> (QFT).&lt;/p>
&lt;hr>
&lt;h2 id="4-quantum-fourier-transform-qft-and-period-extraction">4. Quantum Fourier Transform (QFT) and Period Extraction
&lt;/h2>&lt;p>Let&amp;rsquo;s look in detail with formulas at the manipulation of quantum states, which is the core of Shor&amp;rsquo;s algorithm.&lt;/p>
&lt;h3 id="41-generation-of-quantum-superposition">4.1. Generation of Quantum Superposition
&lt;/h3>&lt;p>First, we prepare two quantum registers. Register 1 holds a superposition state of inputs $x$, and Register 2 holds the computation result $f(x)$. We apply the Hadamard Transform to the initial state $|0\rangle |0\rangle$ to create a superposition of all possible $x$.&lt;/p>
$$ |\psi_1\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle |0\rangle $$
&lt;p>
(Here $Q$ is a power of 2 satisfying $N^2 \le Q &lt; 2N^2$)&lt;/p>
&lt;p>Next, we use a quantum oracle $U_f$ to compute $f(x) = a^x \bmod N$ and store it in Register 2.&lt;/p>
$$ |\psi_2\rangle = U_f |\psi_1\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle |a^x \bmod N\rangle $$
&lt;p>Let&amp;rsquo;s assume here that we measure Register 2 (in reality, the mathematical structure is the same even without measurement). If a value $y = a^{x_0} \bmod N$ is observed, the state of Register 1 collapses into a superposition of all $x$ such that $f(x) = y$. Letting the period be $r$, such $x$ are $x_0, x_0 + r, x_0 + 2r, \dots$&lt;/p>
$$ |\psi_3\rangle = \frac{1}{\sqrt{M}} \sum_{k=0}^{M-1} |x_0 + kr\rangle $$
&lt;p>
(Here $M \approx Q/r$ is the number of terms)&lt;/p>
&lt;p>This state inherently contains information about the period $r$, but direct measurement will only yield a random $x_0 + kr$, and the period $r$ remains unknown. This is where QFT comes in.&lt;/p>
&lt;h3 id="42-application-of-the-quantum-fourier-transform-qft">4.2. Application of the Quantum Fourier Transform (QFT)
&lt;/h3>&lt;p>QFT is an operation that performs a discrete Fourier transform on the amplitudes of quantum states. The action of QFT on state $|x\rangle$ is defined as follows:&lt;/p>
$$ \text{QFT} |x\rangle = \frac{1}{\sqrt{Q}} \sum_{y=0}^{Q-1} e^{2\pi i \frac{xy}{Q}} |y\rangle $$
&lt;p>When this is applied to $|\psi_3\rangle$, phase interference (quantum interference) occurs.&lt;/p>
$$ |\psi_4\rangle = \text{QFT} |\psi_3\rangle = \frac{1}{\sqrt{MQ}} \sum_{y=0}^{Q-1} \sum_{k=0}^{M-1} e^{2\pi i \frac{(x_0 + kr)y}{Q}} |y\rangle $$
&lt;p>Expanding the sum in this equation reveals the part:&lt;/p>
$$ \sum_{k=0}^{M-1} e^{2\pi i \frac{kry}{Q}} $$
&lt;p>This sum of a geometric series reinforces each other (Constructive Interference) only when $ry/Q$ is close to an integer, and cancels each other out (Destructive Interference) otherwise.&lt;/p>
&lt;p>Therefore, the state $|y\rangle$ measured with high probability will be an integer $y$ that satisfies the condition:&lt;/p>
$$ \frac{y}{Q} \approx \frac{c}{r} $$
&lt;p>(where $c$ is some integer).&lt;/p>
&lt;h3 id="43-identifying-the-period-via-continued-fraction-expansion">4.3. Identifying the Period via Continued Fraction Expansion
&lt;/h3>&lt;p>After obtaining $y$ through measurement, we perform a &lt;strong>&amp;ldquo;Continued Fraction Expansion&amp;rdquo;&lt;/strong> of $y/Q$ using a classical computer. This allows us to calculate the convergent fraction $c/r$ of $y/Q$, and extract candidates for the period $r$ from the denominator with high efficiency.&lt;/p>
&lt;hr>
&lt;h2 id="5-comparison-of-conceptual-models-and-the-paradigm-shift">5. Comparison of Conceptual Models and the Paradigm Shift
&lt;/h2>&lt;p>To intuitively understand the difference between GNFS and Shor&amp;rsquo;s algorithm, we present a conceptual diagram using Mermaid notation.&lt;/p>
&lt;h3 id="conceptual-diagram-of-shors-algorithm-via-quantum-circuit">Conceptual Diagram of Shor&amp;rsquo;s Algorithm via Quantum Circuit
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;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-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">graph TD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[Initial State: 0...0] --&amp;gt; B[Superposition of all states via Hadamard Transform]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C[Modular exponentiation a^x mod N]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|Quantum Entanglement| D[Collapse to a state with periodicity]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> D --&amp;gt; E[Quantum Fourier Transform QFT]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> E --&amp;gt;|Probability amplification via interference| F[Measurement: Obtain y]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> F --&amp;gt; G[Classical processing: Continued Fraction Expansion]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt; H[Discovery of period r]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H --&amp;gt; I[Calculate prime factors of N]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> style A fill:#f9f,stroke:#333,stroke-width:2px
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> style E fill:#bbf,stroke:#333,stroke-width:2px
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> style I fill:#bfb,stroke:#333,stroke-width:2px
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="the-essence-of-the-paradigm-shift">The Essence of the Paradigm Shift
&lt;/h3>&lt;p>GNFS takes the approach of &lt;strong>&amp;ldquo;searching for relations within a mathematical space (number field).&amp;rdquo;&lt;/strong> However, since the search space expands exponentially with the number of digits, it becomes virtually unsolvable for classical computer capabilities (even including parallelization) when the key length exceeds 2048 bits.&lt;/p>
&lt;p>On the other hand, Shor&amp;rsquo;s algorithm utilizes the &lt;strong>&amp;ldquo;wave nature of quantum interference.&amp;rdquo;&lt;/strong> It simultaneously evaluates all computation paths in a superposition state, uses QFT to cancel out (destructively interfere) unnecessary answers, and amplifies (constructively interferes) only the probability amplitude of the period that is the correct answer. Through this, instead of searching space, it realizes a completely different dimensional approach of &lt;strong>&amp;ldquo;making the correct answer itself surface.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;h2 id="6-summary">6. Summary
&lt;/h2>&lt;p>In this article, we deeply compared the mathematical backgrounds and algorithmic structures of &lt;strong>&amp;ldquo;GNFS,&amp;rdquo;&lt;/strong> the pinnacle of classical limits, and &lt;strong>&amp;ldquo;Shor&amp;rsquo;s Algorithm,&amp;rdquo;&lt;/strong> which demonstrates the power of quantum computing.&lt;/p>
&lt;p>While GNFS drove computational complexity down to sub-exponential time by employing mathematical tricks such as polynomial selection and massive matrix calculations, Shor&amp;rsquo;s algorithm fused the fundamental principles of quantum mechanics—superposition and interference—with a mathematical tool (QFT), achieving a breakthrough to polynomial time in one stroke.&lt;/p>
&lt;p>Currently, Fault-Tolerant Quantum Computers (FTQC) capable of executing Shor&amp;rsquo;s algorithm at a practical scale (thousands of qubits) do not exist. However, the very existence of this mathematical and theoretical paradigm shift is the primary reason why the transition to Post-Quantum Cryptography (PQC) is urgently being accelerated worldwide today.&lt;/p></description></item></channel></rss>