<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>密碼學 on kenji.blog</title><link>http://kenji.blog/zh-tw/tags/%E5%AF%86%E7%A2%BC%E5%AD%B8/</link><description>Recent content in 密碼學 on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 13:04:59 +0900</lastBuildDate><atom:link href="http://kenji.blog/zh-tw/tags/%E5%AF%86%E7%A2%BC%E5%AD%B8/index.xml" rel="self" type="application/rss+xml"/><item><title>【完全解剖】最強密碼破解演算法「GNFS」C++實作與理解</title><link>http://kenji.blog/zh-tw/p/gnfs-cpp-implementation/</link><pubDate>Sat, 05 Sep 2026 13:04:59 +0900</pubDate><guid>http://kenji.blog/zh-tw/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 【完全解剖】最強密碼破解演算法「GNFS」C++實作與理解" />&lt;h1 id="完全解剖最強密碼破解演算法gnfsc實作與理解">【完全解剖】最強密碼破解演算法「GNFS」C++實作與理解
&lt;/h1>&lt;p>支撐現代網際網路基礎的「RSA密碼學」，其堅固性仰賴於一個數學信念：「在目前的電腦技術下，要對巨大的合成數進行質因數分解實際上是不可能的」。&lt;/p>
&lt;p>然而，人類從未放棄。目前在古典電腦（非量子電腦的一般電腦）上，存在著用於進行巨大質因數分解的 &lt;strong>人類最強、最尖端的演算法&lt;/strong> 。那就是 &lt;strong>「普通數體篩法（GNFS：General Number Field Sieve）」&lt;/strong> 。&lt;/p>
&lt;p>在本篇文章中，我們將完全公開這個 GNFS 最尖端計算邏輯的 C++ 實作程式碼（使用 Boost 函式庫的多精度整數 &lt;code>boost::multiprecision&lt;/code> 進行嚴格建模），並徹底解說其背後「代數整數論」的深淵。&lt;/p>
&lt;p>請務必與原始碼一起，盡情品味數學的神秘以及用電腦科學暴力屈服它的力量。&lt;/p>
&lt;hr>
&lt;h2 id="1-gnfs-最尖端邏輯框架完整原始碼">1. GNFS 最尖端邏輯・框架（完整原始碼）
&lt;/h2>&lt;p>首先，列出本次解說的 GNFS C++ 實作全貌。實際的數體篩法（如 CADO-NFS 等）是高達數十萬行程式碼的超巨大分散式系統，但本程式碼提取了構成 GNFS 的 &lt;strong>「5個必須的管線（階段）」&lt;/strong> 進行類別設計，並在不失去數學意義的前提下，以最小配置進行了建模。&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">// 使用 Boost.Multiprecision 的多精度整數
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">boost&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">multiprecision&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// [SOTA GNFS] General Number Field Sieve (普通數體篩法) 最尖端邏輯框架
&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">// 本程式碼將 CADO-NFS 等所使用的最尖端 GNFS 的 5 個管線
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 嚴格建模為 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 演算法)
&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">// 代數側多項式 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">// 有理側多項式 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">// 基於 base-m 展開產生初始多項式 (實際上會使用更高階的晶格基底歸約 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">// 簡易的 base-m 展開 (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">// 簡易的 m 近似值計算 (不使用 Boost 函式的近似)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">high&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">low&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">high&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">mid&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">high&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">low&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="n">mid&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">high&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">degree&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">temp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">temp&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">temp&lt;/span> &lt;span class="o">/=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// g(x) = x - m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; m = &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; f(x) = &amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">--&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;x^&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="s">&amp;#34; + &amp;#34;&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">[Phase 1] Complete.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 2: 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">// 近年的 GNFS 已不再使用 Line Sieve (直線篩法)，而是以 Franke-Kleinjung 等人的
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 特殊 q 晶格篩法 (Special-q Lattice Sieving) 為業界標準。
&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">// (省略) 實際上會進行質數生成與勒讓德符號等的篩選
&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">// 模擬實作：實際的晶格篩法會以區塊為單位掃描數百 GB 的記憶體空間
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 將 (a, b) 的數對映射到每個特殊質數 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">// 執行將快取效率提升到極限的篩法 (Sieve)。
&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">// 為了展示，加入一個虛擬的 Relation (關係)
&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 (奇異點清除與派系合併)
&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 (刪除只出現過一次的質數的 Relation)
&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 (為使稀疏矩陣變密集而合併 Relation)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 實際上會使用 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 法)
&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">// 在近年的超級電腦環境中，相較於 Block Lanczos 法，更適合分散式運算的
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Block Wiedemann 法 (Coppersmith 實作) 被作為最尖端技術使用。
&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">// 反覆進行稀疏矩陣 (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">// 找到多個滿足 M * x = 0 mod 2 的解向量 (核, Kernel)。
&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">// 依賴關係列表
&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="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. 有理側的平方根 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 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. 代數側的平方根 gamma 的計算 (Montgomery&amp;#39;s method 等)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 求出巨大代數體 O_K 的元素 gamma，並透過同態映射 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">// 為迴避理想類群 (Ideal Class Group) 與單位群 (Unit Group) 的障礙 (Obstruction)，
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 假設在 Phase 2 與 4 中已經加入了二次剩餘特徵 (Quadratic Characters) 序列。
&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">// RSA-270 等，想要質因數分解的巨大合成數 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">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">// 多項式的次數 (超過 130 位數時通常選擇 5 次至 6 次)
&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">// 管線初始化
&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">// 實際的邊界是數千萬至數億
&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. 多項式選擇
&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. 篩法 (Sieve) 處理
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">generate_factor_bases&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">relations&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">poly_select&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. 過濾 (矩陣壓縮)
&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. 線性代數 (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. 代數平方根的計算與 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>那麼，這段程式碼究竟是如何突破密碼學的高牆呢？我們將按 5 個階段，將其縝密的演算法與高等數學咀嚼並解說。&lt;/p>
&lt;hr>
&lt;h2 id="2-gnfs-的最終目的-x2-equiv-y2-pmod-n">2. GNFS 的最終目的： $X^2 \equiv Y^2 \pmod N$
&lt;/h2>&lt;p>不僅是 GNFS，現代巨大質因數分解演算法的目標，大多都是要找到滿足以下同餘式的非平凡數對 $(X, Y)$。&lt;/p>
$$X^2 \equiv Y^2 \pmod N$$
&lt;p>這個式子代表「$X^2$ 與 $Y^2$ 除以 $N$ 的餘數相等」。將其變形後可得：
$X^2 - Y^2 \equiv 0 \pmod N$
也就是說，$(X-Y)(X+Y)$ 是 $N$ 的倍數。&lt;/p>
&lt;p>如果 $X \not\equiv \pm Y \pmod N$（非平凡解），那麼在 $(X-Y)$ 與 $N$ 之間，就會存在「大於 1 且小於 $N$ 的公因數」。
此時，只要使用歐幾里得輾轉相除法計算 &lt;strong>$\gcd(X-Y, N)$&lt;/strong> ，就能輕易求出 $N$ 的質因數。&lt;/p>
&lt;p>然而，要找到這個 $X$ 與 $Y$ 猶如大海撈針。因此 GNFS 採取了天才般的策略：創造出「現實整數的世界」與「多項式代數體的世界」這 &lt;strong>兩個世界&lt;/strong> ，並將計算分散。&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">// m = N^(1/d) 的計算與 base-m 展開
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">temp&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">temp&lt;/span> &lt;span class="o">/=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// g(x) = x - m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>GNFS 的第一步，是建立用來橋接這兩個世界的「魔法多項式」。
對於巨大的數字 $N$，我們選擇一個整數 $m$。通常會選擇讓 $m \approx N^{1/d}$ （在程式碼中假設為 $d=6$ 次的多項式）。&lt;/p>
&lt;p>接著，將 $N$ 進行 $m$ 進位展開，並使用其係數來建構多項式 $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>這個多項式 $f(x)$ 有一個極為重要的性質： &lt;strong>「當變數 $x$ 代入 $m$ 時，剛好會等於 $N$（$f(m) = N$）」&lt;/strong> 。換句話說，$f(m) \equiv 0 \pmod N$。
有理側的多項式則定義為 $g(x) = x - m$。&lt;/p>
&lt;p>藉此，由 $f(x)=0$ 的根 $\alpha$ 所支配的 &lt;strong>「代數體的世界 $\mathbb{Z}[\alpha]$」&lt;/strong> ，與一般的 &lt;strong>「有理數（整數）的世界 $\mathbb{Z}$」&lt;/strong> ，將透過 $x \to m$ 這個「環同態映射（Homomorphism）」被緊密地連結起來。&lt;/p>
&lt;p>在最尖端的 CADO-NFS 等實作中，會使用 KleinJung 演算法或 LLL 晶格基底歸約演算法，花費數個月的時間來尋找「極致完美的多項式 $f(x)$」，使其係數不會過大，且在後續步驟中更容易出現質數（更容易變得平滑）。&lt;/p>
&lt;hr>
&lt;h2 id="4-phase-2-特殊-q-晶格篩法special-q-lattice-sieving">4. Phase 2: 特殊 $q$ 晶格篩法（Special-q Lattice Sieving）
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">LatticeSieve&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">poly&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 將 (a, b) 的數對映射到每個特殊質數 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">// 執行將快取效率提升到極限的篩法 (Sieve)。
&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>準備好兩個世界後，接下來進入在兩個世界中尋找「平滑數（僅由小質數構成的數）」的步驟。
產生無數個整數對 $(a, b)$，並計算以下兩個值：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>有理側的值&lt;/strong> ： $a - bm$&lt;/li>
&lt;li>&lt;strong>代數側的範數 (Norm)&lt;/strong> ： $b^d f(a/b)$&lt;/li>
&lt;/ol>
&lt;p>GNFS 的目標是收集數千萬至數億個 &lt;strong>「有理側與代數側的值，兩者都能完全被小質因數分解的數對（Relation：關係）」&lt;/strong> 。&lt;/p>
&lt;p>早期的 GNFS 使用「直線篩法（Line Sieve）」，將 $(a, b)$ 排列在 $xy$ 平面上，從頭開始依序用質數去除。但這種方法會造成記憶體到處存取而頻繁發生快取未命中（Cache Miss），這是一個非常慢的弱點。&lt;/p>
&lt;p>因此，現在最尖端的程式碼中使用了 &lt;strong>「特殊 $q$ 晶格篩法（Special-q Lattice Sieve）」&lt;/strong> 。
固定一個適度大的質數 $q$，只將「代數側的值必定能被 $q$ 整除的 $(a, b)$ 數對」作為計算對象。滿足此條件的 $(a, b)$ 會在平面上形成「晶格（Lattice）」，因此計算的位址跳躍幅度會固定，完美契合 CPU 的 L1/L2 快取。
導入這個晶格篩法後，GNFS 的計算速度獲得了戲劇性的提升。&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 (刪除只出現過一次的質數的 Relation)
&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 (為使稀疏矩陣變密集而合併 Relation)
&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>在 Phase 2 中，全世界的電腦花費數個月收集了數億個 Relation。然而，如果直接將這些資料丟進下一個「解聯立方程式的步驟（矩陣計算）」中，超級電腦的記憶體也會被撐爆。&lt;/p>
&lt;p>因此，會進行被稱為 &lt;strong>Filtering（過濾）&lt;/strong> 的矩陣超壓縮過程。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Singleton removal（奇異點清除）&lt;/strong>
假設某個巨大的質數 $p$，在數億個 Relation 中「只出現了一次」。我們的目標是「讓所有質數的指數都變成偶數（2 的倍數）」，所以只出現一次的質數絕對不可能變成偶數。
因此，包含該質數的 Relation 會立即被視為「無用的垃圾」而刪除（清除）。這個連鎖反應發生後，原本數億行的資料就會不斷被削減。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Clique merging（派系合併）&lt;/strong>
進一步地，將共享特定質數的 Relation 互相相乘（相加），在減少行數的同時，將稀疏（空洞）的矩陣壓縮成更密集的狀態（使用類似圖論中派系搜尋的手法）。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>透過這個最佳化，巨大的稀疏矩陣將被戲劇性地壓縮至可計算的大小。&lt;/p>
&lt;hr>
&lt;h2 id="6-phase-4-gf2-上的線性代數block-wiedemann-法">6. Phase 4: GF(2) 上的線性代數（Block Wiedemann 法）
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">LinearAlgebraGF2&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">solve_nullspace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 反覆進行稀疏矩陣 (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">// 找到多個滿足 M * x = 0 mod 2 的解向量 (核, Kernel)。
&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>終於來到了謎題的核心。
將收集到的 Relation 相乘，尋找 &lt;strong>「所有質因數的指數都變成偶數的組合」&lt;/strong> 。&lt;/p>
&lt;p>這在數學上，等同於使用一個以各質數指數的「偶數・奇數（亦即 0 或 1）」為元素的巨大矩陣 $M$，以及一個表示要使用哪些 Relation 的向量 $x$，來求解滿足
&lt;strong>$M \cdot x \equiv 0 \pmod 2$&lt;/strong>
的解向量 $x$ （零空間・核，Nullspace / Kernel）。&lt;/p>
&lt;p>這需要解開數百萬行 × 數百萬列這種龐大尺寸矩陣的聯立方程式。若使用一般的基斯消去法（高斯消去法），計算複雜度將達到 $O(N^3)$，就算到宇宙毀滅也算不完。&lt;/p>
&lt;p>因此，最尖端的實作採用了 &lt;strong>「Block Wiedemann（區塊・維德曼）法」&lt;/strong> 。
這是一種克雷洛夫子空間法（Krylov Subspace Method），利用矩陣 $M$ 「非常稀疏（幾乎都是 0）」的特性，反覆進行矩陣與向量的乘法來導出解。
與舊有的 Block Lanczos 法不同，Block Wiedemann 法可以將計算過程完全分割到多個叢集中，因此在現代的分散式雲端運算或超級電腦的平行計算中，能發揮壓倒性的威力。&lt;/p>
&lt;hr>
&lt;h2 id="7-phase-5-代數平方根algebraic-square-root與密碼崩潰">7. Phase 5: 代數平方根（Algebraic Square Root）與密碼崩潰
&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. 有理側的平方根 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. 代數側的平方根 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>透過 Phase 4 的矩陣計算，我們獲得了「相乘後所有質因數皆為偶數次方的 Relation 集合 $S$」。
藉此，我們可以在有理側與代數側這兩個世界中，各自建構出「平方（2 次方）」。&lt;/p>
&lt;p>有理側只是單純的整數乘法，所以計算平方根 $V$ 非常容易。
&lt;/p>
$$V^2 = \prod_{S} (a - bm)$$
&lt;p>&lt;strong>然而，真正的地獄在「代數側」。&lt;/strong>
在代數體的世界 $\mathbb{Z}[\alpha]$ 中，質因數分解的唯一性並不成立，因此我們一直使用理想（Ideal）來進行計算。矩陣計算所保證的 &lt;strong>只有「成為理想的平方」，並不能保證成為「元素的平方（$\gamma^2$）」&lt;/strong> 。&lt;/p>
&lt;p>這裡會遇到被稱為「理想類群的障礙」與「單位群的障礙」，這是代數整數論中非常巨大的高牆。
GNFS 為了打破這面牆，使用了被稱為 &lt;strong>「二次剩餘特徵（Quadratic Characters）」&lt;/strong> 的魔法。
在 Phase 4 的矩陣中，事先偷偷加入針對幾十個特殊質理想的二次剩餘（勒讓德符號）序列。這樣一來，找到的集合 $S$ 就有極大的機率能避開障礙，順利形成「真正元素的平方 $\gamma^2$」。&lt;/p>
&lt;p>求取 $\gamma$ 的工作（代數平方根），是使用 Montgomery 法等極其複雜的演算法來計算的。&lt;/p>
&lt;p>最終，將代數側的平方根 $\gamma$，透過環同態映射 $\phi$ 瞬移回現實世界（將 $x$ 代入 $m$），得到 $Y$。
將有理側的 $V$ 直接當作 $X$，我們夢寐以求的絕對等式終於完成了。&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>剩下的就只有計算 $\gcd(X-Y, N)$ 而已。0.001 秒的處理一閃而過，當非平凡的因數印在螢幕上的那一刻，號稱堅不可摧的 RSA 密碼便徹底崩潰。&lt;/p>
&lt;hr>
&lt;h2 id="結語">結語
&lt;/h2>&lt;p>GNFS 不僅僅是一種程式設計的技巧。
它是用超級電腦的分散式架構與快取最佳化等「極致的工程學」，去折服抽象代數學、環論、理想類群等「純數學深淵」的人類智慧結晶。&lt;/p>
&lt;p>我們不經意傳送的聊天訊息或信用卡資訊，就是建立在這種天文數字般的數學攻防之上受到保護的。&lt;/p>
&lt;p>希望透過這個 C++ 框架，能讓各位感受到最尖端密碼破解演算法背後的「數學與計算機的浪漫」。&lt;/p></description></item><item><title>一般數域篩法（GNFS）的真正數學結構</title><link>http://kenji.blog/zh-tw/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/zh-tw/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 一般數域篩法（GNFS）的真正數學結構" />&lt;h1 id="一般數域篩法gnfs的真正數學結構">一般數域篩法（GNFS）的真正數學結構
&lt;/h1>&lt;p>GNFS 的終極目標是找到 $X, Y$，使得 $X^2 \equiv Y^2 \pmod N$。
為了達成這個目標，數學家們在 &lt;strong>「現實的整數世界」&lt;/strong> 與 &lt;strong>「代數體世界」&lt;/strong> 之間架起了一座橋樑。那座橋樑正是「同態映射」。&lt;/p>
&lt;h2 id="第一階段連結世界的同態映射homomorphism">第一階段：連結世界的「同態映射（Homomorphism）」
&lt;/h2>&lt;h3 id="1-多項式的選定與根的定義">1. 多項式的選定與根的定義
&lt;/h3>&lt;p>對於巨大的合成數 $N$，選擇某個整數 $m$ 與多項式 $f(x)$，使得 $f(m) \equiv 0 \pmod N$。
（例如：將 $N$ 進行 $m$ 進制展開，並從其係數構造 $f(x)$。此時假設 $f(x)$ 在有理數域 $\mathbb{Q}$ 上是不可約的（無法再因式分解））。&lt;/p>
&lt;p>接著，將方程式 $f(x) = 0$ 的其中一個「複數根」設為 $\alpha$。
理所當然，$f(\alpha) = 0$。$\alpha$ 不是整數，而是包含根號或虛數的複雜數（代數數）。&lt;/p>
&lt;h3 id="2-環ring與同態映射的建構">2. 環（Ring）與同態映射的建構
&lt;/h3>&lt;p>在這裡，我們準備兩個數學上的「環（定義了加法與乘法的世界）」。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>世界A： $\mathbb{Z}[\alpha]$&lt;/strong> （包含 $\alpha$ 的代數整數環）
這是一個由 $a + b\alpha + c\alpha^2 + \dots$ 這種形式構成的數字世界。&lt;/li>
&lt;li>&lt;strong>世界B： $\mathbb{Z}/N\mathbb{Z}$&lt;/strong> （除以 $N$ 的餘數環）
這是一個僅由 $0$ 到 $N-1$ 的整數構成的同餘（Modulo）世界。&lt;/li>
&lt;/ul>
&lt;p>在這裡，我們定義一個從世界A到世界B的映射 $\phi$。
&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>這個映射 $\phi$ 是一個神奇的操作，能將世界A中的變數 $\alpha$ 直接替換成世界B中的整數 $m$。
這個 $\phi$ 具有極其強大的性質，稱為 &lt;strong>「環同態映射（Ring Homomorphism）」&lt;/strong> 。
同態指的是 &lt;strong>「在不破壞加法與乘法結構的情況下，傳送到另一個世界」&lt;/strong> 的性質。也就是說，以下方程式成立：&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>這意味著什麼呢？如果我們能在「世界A（$\alpha$的世界）」中，創造出某個複雜元素 $\gamma$ 的 &lt;strong>「平方（$\gamma^2$）」&lt;/strong> ，那麼即使使用 $\phi$ 將其傳送到「世界B（餘數世界）」， &lt;strong>它的平方形式 $\phi(\gamma)^2$ 依然會完美保留&lt;/strong> 。&lt;/p>
&lt;hr>
&lt;h2 id="第二階段質因數分解的崩壞與理想ideal的誕生">第二階段：質因數分解的崩壞與「理想（Ideal）」的誕生
&lt;/h2>&lt;p>我們希望在世界A（$\mathbb{Z}[\alpha]$）中，收集許多適當的元素 $(a - b\alpha)$，並將它們相乘，創造出一個「完全平方（平方元）」。
通常，我們會將收集到的 $(a - b\alpha)$ 分別進行「質因數分解」，並確保質數的指數全為偶數來組合（利用矩陣求解）以創造平方。&lt;/p>
&lt;p>&lt;strong>然而，在這裡，代數學令人絕望的高牆擋住了去路。&lt;/strong>
在像 $\mathbb{Z}[\alpha]$ 這樣的代數體世界中，國中學到的 &lt;strong>「質因數分解的唯一性（任何數字都能唯一地表示為質數相乘）」崩壞了&lt;/strong> 。&lt;/p>
&lt;p>（例如：在某個代數體的世界中，$6 = 2 \times 3$，但同時 $6 = (1+\sqrt{-5}) \times (1-\sqrt{-5})$，我們將無從得知哪個才是真正的質數）&lt;/p>
&lt;p>如果質因數分解不唯一，那麼「計算質數個數以湊成偶數個」的解謎（篩法）在原理上便無法執行。&lt;/p>
&lt;h3 id="庫默爾與戴德金的救贖理想">庫默爾與戴德金的救贖：「理想」
&lt;/h3>&lt;p>拯救這種崩壞的，是 19 世紀數學家創造的概念—— &lt;strong>「理想（Ideal：理想數）」&lt;/strong> 。
藉由不考慮元素本身，而是考慮該元素生成的「倍數集合（理想）」，再次使得質因數分解成為可能。&lt;/p>
&lt;p>在代數體的整數環 $\mathcal{O}_K$（包含 $\mathbb{Z}[\alpha]$ 更完整的環）中，即使元素無法唯一質因數分解，已經證明了 &lt;strong>「理想必定能唯一地質因數分解為『質理想（$\mathfrak{p}$）』的乘積」&lt;/strong> 。&lt;/p>
&lt;p>因此在 GNFS 中，我們不是分解元素 $(a - b\alpha)$ 本身，而是將其生成的 &lt;strong>主理想 $\langle a - b\alpha \rangle$ 進行質理想分解&lt;/strong> 。&lt;/p>
&lt;hr>
&lt;h2 id="第三階段範數norm與兩種篩子sieve">第三階段：範數（Norm）與兩種篩子（Sieve）
&lt;/h2>&lt;p>那麼，我們該如何知道理想 $\langle a - b\alpha \rangle$ 會被分解成哪些質理想呢？
這時我們使用一個稱為 &lt;strong>「範數（Norm）」&lt;/strong> 的函數。範數是將代數體的複雜元素轉換為「現實世界普通整數 $\mathbb{Z}$」的函數。&lt;/p>
&lt;p>元素 $(a - b\alpha)$ 的範數，可透過簡單的多項式計算 $b^d f(a/b)$ 來求得（$d$ 為 $f(x)$ 的次數）。&lt;/p>
&lt;p>根據代數定理，我們知道： &lt;strong>「如果某個理想的範數可以完全分解為較小的質數（平滑），那麼原來的理想也可以完全分解為較小的質理想」&lt;/strong> 。&lt;/p>
&lt;p>因此，GNFS 針對大量的整數對 $(a, b)$，同時計算以下兩者，並只收集兩者皆成為「平滑數」的整數對。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>有理篩（Rational Sieve）&lt;/strong> ： $a - bm$ （現實世界的值）&lt;/li>
&lt;li>&lt;strong>代數篩（Algebraic Sieve）&lt;/strong> ： $b^d f(a/b)$ （代數體世界的範數）&lt;/li>
&lt;/ol>
&lt;p>收集數千萬個兩者皆平滑的整數對 $(a, b)$，將理想的質因數分解數據（包含幾個質理想）作為巨大的矩陣（在 GF(2) 上的線性代數）來求解，找到一個整數對的集合 $S$，使得「相乘後所有質理想的指數皆為偶數」。&lt;/p>
&lt;hr>
&lt;h2 id="第四階段阻擋在前的兩個障礙與理想類群">第四階段：阻擋在前的兩個「障礙」與理想類群
&lt;/h2>&lt;p>透過矩陣計算，我們知道將屬於集合 $S$ 的 $(a - b\alpha)$ 的理想全部相乘，會變成某個理想 $I$ 的平方。
&lt;/p>
$$\prod_{S} \langle a - b\alpha \rangle = I^2$$
&lt;p>&lt;strong>然而，這還沒結束。GNFS 中最深奧、最困難的數學高牆就在這裡。&lt;/strong>&lt;/p>
&lt;p>我們最終想要的，不是「理想的平方」，而是為了代入映射 $\phi$ 的 &lt;strong>「元素的平方（$\gamma^2$）」&lt;/strong> 。
變成理想的平方，並不代表元素本身也一定是平方。這裡存在著 &lt;strong>兩個強烈的數學障礙（Obstruction）&lt;/strong> 。&lt;/p>
&lt;h3 id="障礙理想類群ideal-class-group的高牆">障礙①：理想類群（Ideal Class Group）的高牆
&lt;/h3>&lt;p>理想 $I$ 未必是「由單一元素生成的理想（主理想）」。
我們無法從非主理想的理想中，提取出具體的元素 $\gamma$。&lt;/p>
&lt;p>這時登場的概念是 &lt;strong>「理想類群（Class Group, $Cl_K$）」&lt;/strong> 。理想類群是用來衡量「該代數體世界中存在多少非主理想的理想（質因數分解的唯一性被破壞到什麼程度）」的群。
即使 $\prod \langle a - b\alpha \rangle$ 變成了 $I^2$，如果 $I$ 在理想類群中不是單位元素（主理想），就無法將其拉回為元素的平方。&lt;/p>
&lt;h3 id="障礙單位群unit-group的高牆">障礙②：單位群（Unit Group）的高牆
&lt;/h3>&lt;p>假設運氣好，$I$ 剛好是主理想 $\langle \gamma \rangle$ 吧。
那麼，$\prod \langle a - b\alpha \rangle = \langle \gamma^2 \rangle$。
你可能會想「太好了，元素也是平方了！」，但這可是大錯特錯。&lt;/p>
&lt;p>理想（倍數的集合）相等，並不代表元素完全相等。這兩者之間必定會產生 &lt;strong>「單位（Unit：倒數也是整數的數字。如 1 或 -1 等）」&lt;/strong> 的偏差。
也就是說，實際的元素等式會變成這樣：
&lt;/p>
$$\prod_{S} (a - b\alpha) = u \cdot \gamma^2$$
&lt;p>
（$u$ 為單位群 $U_K$ 的元素）&lt;/p>
&lt;p>如果這個單位 $u$ 本身不是某個東西的平方（平方元），那麼左邊絕對無法成為「完美的元素平方」。&lt;/p>
&lt;hr>
&lt;h2 id="第五階段阿德曼的魔法二次特徵quadratic-characters">第五階段：阿德曼的魔法「二次特徵（Quadratic Characters）」
&lt;/h2>&lt;p>理想類群的障礙與單位群的障礙。這兩個障礙該如何克服呢？
這裡登場的是由密碼學家雷納德·阿德曼（RSA中的&amp;quot;A&amp;quot;）等人引入的天才手法—— &lt;strong>「二次特徵（Quadratic Characters）」&lt;/strong> 。&lt;/p>
&lt;p>為了判定「某個元素在代數體中是否為完全平方」，我們使用勒讓德符號（二次剩餘）的代數體版本。
在剛才那個巨大的矩陣（為了將質理想個數湊成偶數的解謎）中，我們 &lt;strong>偷偷加上了幾十個額外條件（行），要求「對某些特殊質理想 $\mathfrak{q}$ 的二次特徵也全都要是 $1$（偶數）」&lt;/strong> 。&lt;/p>
&lt;p>當我們透過矩陣計算找到連這些額外條件都滿足的集合 $S$ 時，根據代數數論的深奧定理，保證 &lt;strong>「理想類群的障礙和單位群的障礙，將以壓倒性的機率自然消滅」&lt;/strong> 。&lt;/p>
&lt;p>於是，我們終於得到了真正的等式：
&lt;/p>
$$\prod_{S} (a - b\alpha) = \gamma^2$$
&lt;hr>
&lt;h2 id="最終階段世界的融合與密碼崩壞">最終階段：世界的融合與密碼崩壞
&lt;/h2>&lt;p>拼圖的最後一塊終於拼上了。&lt;/p>
&lt;p>&lt;strong>【代數體世界（世界A）的元素】&lt;/strong>
$\gamma^2 = \prod (a - b\alpha)$
（我們使用平方根演算法求出 $\gamma$）&lt;/p>
&lt;p>&lt;strong>【現實世界（有理數世界）的元素】&lt;/strong>
$V^2 = \prod (a - bm)$
（因為這只是單純的整數相乘，可以正常求出平方根 $V$）&lt;/p>
&lt;p>好了，我們一開始建造的魔法橋樑， &lt;strong>同態映射 $\phi$&lt;/strong> 該上場了。
我們利用 $\phi$（將 $\alpha$ 代入為 $m$ 的映射），將世界A的元素 $\gamma$ 傳送到世界B（除以 $N$ 的餘數世界）。
&lt;/p>
$$Y = \phi(\gamma) \pmod N$$
&lt;p>另一方面，我們將在現實世界中產生的 $V$，直接帶入餘數世界成為 $X$。
&lt;/p>
$$X = V \pmod N$$
&lt;p>由於同態映射「保留結構」的性質，在世界A中成立的平方關係，在世界B（模 $N$ 的世界）中也完美保留。
此外，由於原來的整數對 $(a, b)$ 是以 $a - b\alpha$ 和 $a - bm$ 的形式對應生成的，這個 $X$ 和 $Y$ 在模 $N$ 的世界中將會碰撞，產生以下絕對的等式：&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>剩下能做的，就是祈禱這對 $X$ 與 $Y$ 不是平凡解（$X \equiv \pm Y$），然後計算
&lt;strong>$\gcd(X - Y, N)$&lt;/strong> 。&lt;/p>
&lt;p>如果是非平凡解，歐幾里得演算法會在 0.001 秒內跑完，將作為 RSA 密碼心臟的秘密質數 $p$ 和 $q$ 印在輸出畫面上。&lt;/p>
&lt;hr>
&lt;p>這就是集現代數學精華於一身的 &lt;strong>「一般數域篩法（GNFS）」的完整樣貌&lt;/strong> 。&lt;/p></description></item><item><title>什麼是打破網際網路加密的人類最強數學 "一般數體篩法（GNFS）"？</title><link>http://kenji.blog/zh-tw/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/zh-tw/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 什麼是打破網際網路加密的人類最強數學 "一般數體篩法（GNFS）"？" />&lt;h1 id="什麼是打破網際網路加密的人類最強數學一般數體篩法gnfs">什麼是打破網際網路加密的人類最強數學「一般數體篩法（GNFS）」？
&lt;/h1>&lt;p>我們每天使用的網際網路。LINE 訊息、YouTube、Amazon 購物等，所有的通訊都受到「加密」保護。
目前世界上最廣泛使用的加密技術代表是「RSA 加密」。&lt;/p>
&lt;p>RSA 加密防禦的核心非常簡單。它利用了 ** 「即使是電腦也無法解開巨大數字的質因數分解」 ** 這個數學特性。
例如，「15」我們馬上就知道是「3 × 5」，但一旦變成「270 位數的數字」，即使集結全世界的超級電腦，也需要耗費數億年才能解開。&lt;/p>
&lt;p>然而，數學家們並沒有閒著。為了打破這道堅不可摧的密碼防線，人類創造了一種宛如魔法般的演算法（計算步驟），稱為 ** 「一般數體篩法（GNFS：General Number Field Sieve）」 ** 。&lt;/p>
&lt;p>在這篇文章中，我們完全不使用專業術語，僅使用 ** 國中學到的數學（質因數分解、代數式、最大公因數） ** 知識，一步步徹底解說這個「人類最強演算法」破解密碼的原理！&lt;/p>
&lt;hr>
&lt;h2 id="第-1-章破解密碼的目標是國三的公式">第 1 章：破解密碼的目標是「國三的公式」
&lt;/h2>&lt;p>面對巨大質因數分解的最大必殺技。這就是在國三學到的這個公式。&lt;/p>
&lt;blockquote>
&lt;p>** $X^2 - Y^2 = (X + Y)(X - Y)$ **&lt;/p>
&lt;/blockquote>
&lt;p>你可能會想：「咦，這麼基礎的公式就能破解密碼嗎？」。然而，這正是解開一切的萬能鑰匙。&lt;/p>
&lt;p>破解密碼的最終目標，對於一個巨大的數字 $N$，就是找到 ** 「將 $X^2$ 和 $Y^2$ 除以 $N$ 後，餘數會相同的數字（$X$ 和 $Y$）」 ** 。&lt;/p>
&lt;h3 id="為什麼餘數相同就能破解密碼">為什麼「餘數相同」就能破解密碼？
&lt;/h3>&lt;p>假設有兩個數字 $X^2$ 和 $Y^2$，它們「除以 $N$ 的餘數相同」。
餘數相同代表著，相減後的 ** 「$X^2 - Y^2$」必定能被 $N$ 整除（成為 $N$ 的倍數） ** ，這是一個法則。&lt;/p>
&lt;p>在這裡，我們假設用於加密的巨大數字 $N$ 是由兩個秘密質數（$p$ 和 $q$）相乘而成的（$N = p \times q$）。&lt;/p>
&lt;p>將 $X^2 - Y^2$ 因式分解後會變成 ** $(X - Y)(X + Y)$ ** 。
這成為 $N$ 的倍數，意味著在這個乘法中的某處，隱藏著秘密質數 $p$ 和 $q$。&lt;/p>
&lt;p>奇蹟在此發生。
這兩個質數 $p$ 和 $q$，有 ** 50%（二分之一） ** 的數學機率，會分開進入不同的房間： ** 「$p$ 進入 $(X - Y)$ 的房間」和「$q$ 進入 $(X + Y)$ 的房間」 ** 。&lt;/p>
&lt;p>在只有質數 $p$ 進入 $(X - Y)$ 房間的狀態下，讓我們計算 $(X - Y)$ 和 $N$ 的 ** 「最大公因數（共通的最大零件）」 ** 。&lt;/p>
&lt;ul>
&lt;li>$(X - Y)$ 的內容 ＝ $p \times$ 某個數字&lt;/li>
&lt;li>$N$ 的內容 ＝ $p \times q$
共通的零件只有 ** 「$p$」 ** ！&lt;/li>
&lt;/ul>
&lt;p>也就是說，在計算出最大公因數的瞬間，隱藏的質數 $p$ 就會掉出來，密碼就被完全破解了。（※最大公因數只要使用「輾轉相除法」，用手機也能瞬間計算出來）&lt;/p>
&lt;p>** 【小專欄：為什麼是 2 次方？3 次方或 2 倍不行嗎？】 **&lt;/p>
&lt;blockquote>
&lt;p>如果是「$2X - 2Y$」會變成 $2(X - Y)$，因為只有一個房間，所以無法將質數分開。如果是「$X^3 - Y^3$」，房間的大小會變得不平衡，計算會變得不必要的繁重。為了將質數漂亮地分開到兩個房間，「2 次方」是成本效益最高的。&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="第-2-章如何尋找-x-和-y收集質數卡片的拼圖">第 2 章：如何尋找 X 和 Y？「收集質數卡片的拼圖」
&lt;/h2>&lt;p>目標已經很清楚了。但是，如果盲目地尋找「餘數相同的 $X^2$ 和 $Y^2$」，直到宇宙毀滅也找不到。
因此，數學家們想出了一個被稱為 ** 「收集質數卡片的拼圖」 ** 的天才方法。&lt;/p>
&lt;h3 id="step-1只用篩子收集沙金平滑數">Step 1：只用篩子收集沙金（平滑數）
&lt;/h3>&lt;p>首先，準備一個適當的數字 $Z$，將其平方後除以 $N$ 算出餘數 $W$。
（$Z^2 = W$ 的餘數世界）&lt;/p>
&lt;p>將得出的餘數 $W$ 進行質因數分解。在這裡，只有當出現 ** 「只由 2、3、5、7 等小質數組成的 $W$」 ** 時，才將該算式作為「中獎卡片」保留下來，如果混入了大的質數就丟棄。
這就像在河裡用篩子過濾掉大石頭，只收集沙金一樣的作業。&lt;/p>
&lt;h3 id="step-2全部變成偶數個的拼圖">Step 2：全部變成「偶數個」的拼圖
&lt;/h3>&lt;p>例如，假設收集到了以下 3 張沙金卡片。&lt;/p>
&lt;ul>
&lt;li>卡片 A： $Z_1^2 = 2^3 \times 3^1$&lt;/li>
&lt;li>卡片 B： $Z_2^2 = 2^1 \times 5^1$&lt;/li>
&lt;li>卡片 C： $Z_3^2 = 3^1 \times 5^1$&lt;/li>
&lt;/ul>
&lt;p>我們將這些全部相乘。
右側會變成 $(2^3 \times 3^1) \times (2^1 \times 5^1) \times (3^1 \times 5^1)$，
整理過後會變成 ** 「$2^4 \times 3^2 \times 5^2$」 ** 。&lt;/p>
&lt;p>令人驚訝的是，質數的個數變成了「4 個、2 個、2 個」， ** 全部都是偶數個 ** ！
全部都是偶數個，意味著只要將整體的數量減半，就會變成「某個東西的平方」。
也就是說，$(2^2 \times 3^1 \times 5^1)^2 = (60)^2$.&lt;/p>
&lt;p>左側是 $(Z_1 \times Z_2 \times Z_3)^2$，所以終於，
** $X = (Z_1 \times Z_2 \times Z_3)$ **
** $Y = 60$ **
這對期待已久的「$X^2 = Y^2$」組合就完成了！&lt;/p>
&lt;p>對於電腦來說，計算質數個數「是偶數還是奇數（0 或 1）」的拼圖是它們非常擅長的，所以用這個方法就能高速找到 $X$ 和 $Y$。&lt;/p>
&lt;hr>
&lt;h2 id="第-3-章阻擋在前方的絕望之壁">第 3 章：阻擋在前方的絕望之壁
&lt;/h2>&lt;p>這樣就能破解任何密碼了！……正當我們這麼想時，大問題發生了。
如果密碼數字 $N$ 大約在「100 位數」以內，用這個方法（稱為二次篩法）是可以解開的，但當 $N$ 變成「200 位數、300 位數」時，計算過程中出現的 $W$ 就會變得太大。&lt;/p>
&lt;p>數字一旦變得太大，「只由小質數組成的數字（沙金）」就不再出現。這變得比在沙漠中尋找隱形眼鏡還要困難，完全無法收集到解開拼圖所需的卡片。&lt;/p>
&lt;p>這時候，人類的最終兵器 ** 「一般數體篩法（GNFS）」 ** 終於登場了。&lt;/p>
&lt;hr>
&lt;h2 id="第-4-章人類最強的想法創造兩個世界">第 4 章：人類最強的想法，創造「兩個世界」
&lt;/h2>&lt;p>GNFS 的天才發想是： ** 「因為只在現實世界中計算，所以數字才會變得巨大。那麼，我們就用多項式（代數式）創造一個『裏世界』，將計算的負擔分散成兩半吧。」 **&lt;/p>
&lt;h3 id="代數式的魔法">代數式的魔法
&lt;/h3>&lt;p>GNFS 使用一個基準數字 $m$，將巨大的數字 $N$ 轉換成代數式。
例如如果 $N=100$，設 $m=4$，則 $100 = 4^3 + 2(4^2) + 4$。
使用字母 $x$ 將其變成 ** $f(x) = x^3 + 2x^2 + x$ ** 這個算式（裏世界）。&lt;/p>
&lt;p>這個算式有趣的地方在於，它具有 ** 「只要將字母 $x$ 代入 $m$（在上面的例子中是 4），隨時都能瞬間移動回到現實數字 $N$」 ** 的特性。&lt;/p>
&lt;h3 id="在兩個世界中同時尋找沙金">在兩個世界中同時尋找沙金
&lt;/h3>&lt;p>GNFS 製造出許多隨機的整數對 $(a, b)$，並同時進行以下兩個計算：&lt;/p>
&lt;ol>
&lt;li>** 現實世界 ** ： $a - b \times m$&lt;/li>
&lt;li>** 代數式的世界 ** ： 依照代數式規則計算 $a - b \times x$ 的值&lt;/li>
&lt;/ol>
&lt;p>藉由將問題分成兩個世界，處理的數字大小會戲劇性地變小（變輕）。這就像是把巨大的岩石劈成兩半，變成容易處理的石塊一樣的概念。&lt;/p>
&lt;p>然後，我們用篩子過濾，只收集那些在 ** 「現實世界和代數式的世界中，兩者都是『只由小質數組成（沙金）』」 ** 的奇蹟整數對 $(a, b)$。這就是「數體篩法」名稱的由來。&lt;/p>
&lt;h3 id="密碼終於被破解的瞬間">密碼終於被破解的瞬間
&lt;/h3>&lt;p>當從兩個世界收集到數千萬張「沙金卡片」後，就會使用超級電腦的巨大矩陣計算，找出在第 2 章做過的「質數個數全部變成偶數的組合」。&lt;/p>
&lt;p>找到組合後，&lt;/p>
&lt;ul>
&lt;li>將現實世界中產生的平方數設為 ** $X^2$ **&lt;/li>
&lt;li>將代數式世界中產生的平方算式設為 ** $Y(x)^2$ **&lt;/li>
&lt;/ul>
&lt;p>最後，將代數式 $Y(x)$ 中的 $x$ 代入 $m$，使其瞬間移動到現實世界並會合。
這樣一來，宛如數學魔法般， ** 「$X^2$ 和 $Y^2$ 的餘數相同」 ** 的狀態就嚴格地完成了！&lt;/p>
&lt;p>接下來只要按照第 1 章的說明，計算 $X - Y$ 和 $N$ 的最大公因數，堅不可摧的 RSA 加密就會應聲瓦解，秘密質數也將隨之現身。&lt;/p>
&lt;hr>
&lt;h2 id="結語數學永無止境">結語：數學永無止境
&lt;/h2>&lt;p>你可能會想：「太好了，只要用 GNFS 就能破解任何密碼了吧！」。
然而，RSA 加密也沒有認輸。目前網際網路上使用的是被稱為「RSA-2048（約 617 位數）」這種怪物級的巨大數字。&lt;/p>
&lt;p>儘管 GNFS 號稱是人類最強的演算法，但要解開 270 位數（RSA-270），據說即使將全世界的電腦連線在一起，也需要數千年甚至數萬年。就目前而言，我們的 LINE 或銀行資料還是安全的。&lt;/p>
&lt;p>不過，如果出現了 ** 「能瞬間找出任何巨大數字 $X$ 和 $Y$ 的魔法」 ** 會怎麼樣呢？
事實上，最接近這個存在的，就是目前正在開發的 ** 「量子電腦（Shor 演算法）」 ** 。數學上已經證明，只要利用量子力學波的特性，就能無視麻煩的卡片收集拼圖，一次就抽出正確答案。&lt;/p>
&lt;p>製造密碼的人（防禦）與製造破解密碼演算法的人（攻擊）之間，無止盡的鬥智。
當你知道國中學到的「質因數分解」和「代數式」，其實是在世界資安最前線激烈交鋒的武器時，是否覺得數學課變得稍微有趣一點了呢？&lt;/p>
&lt;p>發現未來最強演算法的人，或許就是正在讀這篇文章的你！&lt;/p>
&lt;hr>
&lt;p>&lt;em>(※本文為了讓中學生能理解，將密碼破解的數學魅力概念化。實際的 GNFS 是使用了代數體的理想類群、同態映射等高等大學數學來進行嚴格計算的)&lt;/em>&lt;/p></description></item><item><title>柯克霍夫原則</title><link>http://kenji.blog/zh-tw/p/%E6%9F%AF%E5%85%8B%E9%9C%8D%E5%A4%AB%E5%8E%9F%E5%89%87/</link><pubDate>Wed, 16 Apr 2025 23:53:08 +0900</pubDate><guid>http://kenji.blog/zh-tw/p/%E6%9F%AF%E5%85%8B%E9%9C%8D%E5%A4%AB%E5%8E%9F%E5%89%87/</guid><description>&lt;img src="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_2.png" alt="Featured image of post 柯克霍夫原則" />&lt;h1 id="柯克霍夫原則">&amp;ldquo;柯克霍夫原則&amp;rdquo;
&lt;/h1>&lt;hr>
&lt;p>你好！&lt;/p>
&lt;p>今天我想談談一個有點有趣、實際上非常重要的東西，叫做「柯克霍夫原則」。&lt;/p>
&lt;p>啊，等等。&lt;br>
有些人可能會想：「我從來沒有聽過『柯克霍夫原則』，聽起來好像很難懂……」。請放心，這篇文章正是寫給有這種想法的你讀的。&lt;/p>
&lt;hr>
&lt;h2 id="什麼是安全的密碼">什麼是「安全的密碼」？
&lt;/h2>&lt;p>例如，假設有人說：「這個保險箱，只有知道秘密開啟方法的人才能打開。」&lt;/p>
&lt;p>乍看之下，這似乎非常安全，對吧？&lt;br>
但是，仔細想想，這不是有點令人不安嗎？&lt;/p>
&lt;p>像是「如果那個秘密被發現了，不就完蛋了？」&lt;/p>
&lt;p>事實上，這正是柯克霍夫原則出現的契機。&lt;/p>
&lt;hr>
&lt;h2 id="到底什麼是柯克霍夫原則">到底什麼是「柯克霍夫原則」？
&lt;/h2>&lt;p>簡單來說，這是一種概念：&lt;/p>
&lt;p>&lt;strong>「密碼應該在機制被公開的情況下依然安全。」&lt;/strong>&lt;/p>
&lt;p>更進一步說，「安全性應該只依賴『秘密的鑰匙』，密碼的方法本身公開也沒關係！」&lt;/p>
&lt;p>反過來說，「只把密碼的演算法（機制）保密的狀態，會被認為是可靠性很低的。」&lt;/p>
&lt;hr>
&lt;h2 id="機制保密就很安全可能有點危險">「機制保密就很安全」可能有點危險
&lt;/h2>&lt;p>這是常見的想法：&lt;/p>
&lt;blockquote>
&lt;p>「這個應用程式的內部沒有給任何人看過，所以安全性沒問題」&lt;/p>
&lt;/blockquote>
&lt;p>我了解這種感覺。&lt;br>
但這就等於在說：「因為沒有人看，所以不會發現缺點，沒問題的。」&lt;/p>
&lt;p>實際上，這種「沒有人看」的狀態本身可能就會成為一種風險。&lt;/p>
&lt;hr>
&lt;h2 id="但是為什麼這個原則這麼重要">但是，為什麼這個原則這麼重要？
&lt;/h2>&lt;p>因為，如果有人取得了這個機制，並且可以輕易解碼，那這個密碼就沒用了。&lt;/p>
&lt;p>打個比方，就像是一扇門的鎖機制非常複雜，但實際上卻可以用百元商店打的備用鑰匙打開。&lt;/p>
&lt;p>重要的不是「鑰匙是秘密的所以沒問題」，而是「即使公開所有的機制，沒有正確的鑰匙也打不開」。&lt;/p>
&lt;hr>
&lt;h2 id="但是這樣不會有點可怕嗎的心情">「但是，這樣不會有點可怕嗎？」的心情
&lt;/h2>&lt;p>很多人在這裡會感到不安：&lt;/p>
&lt;blockquote>
&lt;p>「把所有的機制都公開，不會有點可怕嗎？」&lt;/p>
&lt;/blockquote>
&lt;p>我懂。&lt;br>
因為你會想：「如果我把內部全部公開，不會被模仿或惡意利用嗎？」&lt;/p>
&lt;p>但這正是柯克霍夫原則的核心。&lt;br>
「即使讓人看到內部也不會崩潰的強度」才是真正的安全。&lt;/p>
&lt;hr>
&lt;h2 id="話雖如此一開始確實需要一點勇氣">話雖如此，一開始確實需要一點勇氣
&lt;/h2>&lt;p>站在開發者的角度來看，似乎「公開機制 = 暴露弱點」，這當然會讓人感到緊張。&lt;/p>
&lt;p>但是請想想看。&lt;/p>
&lt;p>能夠大方展示機制並說出「任何人都可以來驗證」的東西，結果反而更令人信賴。&lt;/p>
&lt;p>這跟人際關係很像。&lt;/p>
&lt;p>「在展現真實自我後還能好好相處的人」，終究是最讓人安心的。&lt;/p>
&lt;hr>
&lt;h2 id="總而言之">總而言之
&lt;/h2>&lt;p>柯克霍夫原則聽起來可能有點理論化，但本質上非常簡單。&lt;/p>
&lt;p>其實就是 &lt;strong>「讓我們建立一個不管給誰看都不會崩壞的機制」&lt;/strong> 而已。&lt;/p>
&lt;p>與其保持表面的秘密，不如有良好的設計。&lt;br>
與其寫出不想讓任何人看的程式碼，不如寫出展示給別人看也不會覺得丟臉的程式碼。&lt;/p>
&lt;p>或許，未來的時代會越來越需要這種「強度」。&lt;/p>
&lt;hr>
&lt;p>非常感謝您的閱讀！&lt;/p>
&lt;p>雖然安全性的話題有點困難，但也有些部分與「人際關係」或「日常的安心感」相連呢。&lt;br>
不用感到有壓力，只要一點一點地去了解，相信一定會有好事的。&lt;/p>
&lt;hr>
&lt;p>&lt;img src="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img.png"
width="189"
height="282"
srcset="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_hu715032b7fe5224f655ebb7d29b676305_77325_480x0_resize_box_3.png 480w, http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_hu715032b7fe5224f655ebb7d29b676305_77325_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="Auguste Kerckhoffs"
class="gallery-image"
data-flex-grow="67"
data-flex-basis="160px"
>&lt;/p></description></item></channel></rss>