<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RSA on kenji.blog</title><link>http://kenji.blog/zh-cn/tags/rsa/</link><description>Recent content in RSA on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 22:09:21 +0900</lastBuildDate><atom:link href="http://kenji.blog/zh-cn/tags/rsa/index.xml" rel="self" type="application/rss+xml"/><item><title>量子计算机真的会破坏RSA加密吗？——秀尔算法与当前进展</title><link>http://kenji.blog/zh-cn/p/shors-algorithm-and-rsa-breaking/</link><pubDate>Sat, 05 Sep 2026 22:09:21 +0900</pubDate><guid>http://kenji.blog/zh-cn/p/shors-algorithm-and-rsa-breaking/</guid><description>&lt;img src="http://kenji.blog/p/shors-algorithm-and-rsa-breaking/quantum_breaking_rsa_1788613722990.jpg" alt="Featured image of post 量子计算机真的会破坏RSA加密吗？——秀尔算法与当前进展" />&lt;h2 id="引言密码学技术与量子计算机的交汇点">引言：密码学技术与量子计算机的交汇点
&lt;/h2>&lt;p>在现代互联网社会中，“公钥加密”是保护通信机密的基础。其中最具代表性的，是1977年由Ron Rivest、Adi Shamir和Leonard Adleman三位学者开发的“RSA加密”。从我们每天使用的在线购物支付、网站浏览（HTTPS）到电子邮件的收发，RSA加密作为互联网基础设施的心脏发挥着作用。&lt;/p>
&lt;p>然而，随着“量子计算机”的出现，人们指出这种安全性有可能被彻底颠覆。媒体上甚至会看到“量子计算机一旦完成，世界上的密码和加密将在几秒钟内被破解”这样耸人听闻的标题。这到底是不是真的呢？&lt;/p>
&lt;p>在本文中，我们将深入探讨经典的密码破解方法GNFS（一般数域筛选法），以及使用量子计算机的密码破解算法终极武器——“秀尔算法（Shor&amp;rsquo;s Algorithm）”的原理。我们将通俗易懂地讲解量子傅里叶变换和周期寻找等高级概念，并详细验证在当前NISQ（含噪中型量子）时代的量子硬件现状，以及实际破解RSA-2048所需跨越的障碍。&lt;/p>
&lt;hr>
&lt;h2 id="rsa加密的根基大数质因数分解的困难性">RSA加密的根基：大数质因数分解的困难性
&lt;/h2>&lt;p>RSA加密的安全性依赖于数学中极其简单的非对称性。那就是这样一个事实：“将两个巨大的质数相乘很容易，但要从它们相乘的结果（合数）中找出原来的两个质数（质因数分解）却极其困难。”&lt;/p>
&lt;p>例如，假设有两个质数 $ p = 61 $、$ q = 53 $。计算它们的乘积 $ N = p \times q = 3233 $ 只需一瞬。但是，如果只给你“3233”这个数字，问你“这是哪两个质数相乘的结果？”，随着数字变大，解题的计算量会呈爆炸性增长。&lt;/p>
&lt;p>在目前主流的RSA-2048中，使用的密钥长度为2048位，即十进制下约有617位的巨大合数 $ N $。如果能将这个 $ N $ 进行质因数分解，加密就等同于被破解了。&lt;/p>
&lt;h3 id="经典计算机的挑战gnfs一般数域筛选法">经典计算机的挑战：GNFS（一般数域筛选法）
&lt;/h3>&lt;p>为了解决质因数分解问题，数学家和密码学家多年来开发了各种算法。其中，目前在经典计算机上被认为最快的是 &lt;strong>一般数域筛选法（GNFS: General Number Field Sieve）&lt;/strong>。&lt;/p>
&lt;p>GNFS为了将巨大的数 $ N $ 进行质因数分解，会将整数环中的计算扩展到更抽象的代数域（Number Field）中进行分析。其大致流程如下：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>选择多项式&lt;/strong>：寻找一个以 $ N $ 为根、具有适当次数和系数的多项式 $ f(x) $。&lt;/li>
&lt;li>&lt;strong>数据收集（筛选）&lt;/strong>：在有理数域和代数域上，大量寻找能够分解为小质数（平滑数，Smooth numbers）的数对。这个过程被称为“筛选”，是耗时最长的部分。&lt;/li>
&lt;li>&lt;strong>矩阵生成与化简&lt;/strong>：基于收集到的关系式生成一个巨大的稀疏矩阵（大部分元素为0的矩阵），并使用线性代数的方法（如块Lanczos算法）求解。&lt;/li>
&lt;li>&lt;strong>平方根计算&lt;/strong>：最后在代数域上计算平方根，推导出 $ N $ 的因数（质因数）。&lt;/li>
&lt;/ol>
&lt;p>GNFS的计算复杂度非渐进地评估为 $ O(\exp((\sqrt[3]{\frac{64}{9}} + o(1)) (\log N)^{\frac{1}{3}} (\log \log N)^{\frac{2}{3}})) $。这被称为“亚指数（Sub-exponential）”时间复杂度。虽然比指数时间快，但比多项式时间（Polynomial time）慢得多。&lt;/p>
&lt;p>实际上，在2020年，一个国际研究团队使用GNFS成功完成了RSA-250（829位，250位的合数）的质因数分解。这项计算汇集了世界各地的计算机资源，耗费了约2700个CPU核心年的庞大计算时间。然而，如果换成2048位，所需的计算量将膨胀到宇宙寿命的数兆倍。无论现在用多少台超级计算机并行运行，使用经典方法都不可能在现实时间内完成破解。&lt;/p>
&lt;hr>
&lt;h2 id="量子计算机的杀手锏秀尔算法">量子计算机的杀手锏：秀尔算法
&lt;/h2>&lt;p>在这里登场的是1994年由彼得·秀尔（Peter Shor）提出的“秀尔算法（Shor&amp;rsquo;s Algorithm）”。该算法具有划时代的意义，它能够让质因数分解问题在量子计算机上以 &lt;strong>多项式时间&lt;/strong>（ $ O((\log N)^3) $ ）被解出。亚指数时间和多项式时间之间的差距是决定性的，这在理论上意味着，如果使用量子计算机，RSA加密将被彻底破坏。&lt;/p>
&lt;h3 id="秀尔算法的整体流程">秀尔算法的整体流程
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">graph TD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[输入想要分解质因数的数 N] --&amp;gt; B[随机选择一个整数 a]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C{a 与 N 的&amp;lt;br&amp;gt;最大公约数}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|大于1| D[幸运地发现了质因数！]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|等于1 互质| E[量子计算机登场]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> E --&amp;gt; F[通过量子傅里叶变换求得&amp;lt;br&amp;gt;函数 f_x = a^x mod N 的周期 r]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> F --&amp;gt; G{周期 r 为偶数 且&amp;lt;br&amp;gt;a^r/2 ≢ -1 mod N}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|Yes| H[计算最大公约数 gcd_a^r/2 ± 1, N]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H --&amp;gt; I((质因数分解成功！))
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|No| B
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>秀尔算法并不是直接去解质因数分解问题，而是利用数论定理将其转换为另一个称为“周期寻找问题（Period Finding Problem）”的问题，并利用量子计算机的特性来高速求解。&lt;/p>
&lt;h3 id="步骤1从质因数分解还原为周期寻找问题经典计算处理">步骤1：从质因数分解还原为周期寻找问题（经典计算处理）
&lt;/h3>&lt;p>算法的第一步在经典计算机上进行。
对于想要进行质因数分解的数 $ N $，随机选择一个与 $ N $ 互质（最大公约数为1）的整数 $ a $（ $ 1 &lt; a &lt; N $ ）。如果很偶然地最大公约数不为1，那么此时找到的公约数就是 $ N $ 的质因数，破解完成，但这种概率极低。&lt;/p>
&lt;p>接下来，考虑以下模方程序列：
$ f(x) = a^x \pmod N $&lt;/p>
&lt;p>如果将 $ x = 1, 2, 3, \dots $ 代入该函数 $ f(x) $，得到的值看起来可能是随机的，但由于是在有限范围内计算，它必然会在某个点回到原来的值，并重复相同的数列。这个重复的周期被称为 $ r $。也就是说，
寻找使得
$ a^r \equiv 1 \pmod N $
成立的最小正整数 $ r $ 的问题，这就是“周期寻找问题”。&lt;/p>
&lt;p>如果找到了这个周期 $ r $，且 $ r $ 是偶数，则 $ a^r - 1 \equiv 0 \pmod N $，利用因式分解公式可以变形为：
$ (a^{r/2} - 1)(a^{r/2} + 1) \equiv 0 \pmod N $
由此，通过使用欧几里得算法（辗转相除法）计算 $ N $ 与 $ a^{r/2} \pm 1 $ 的最大公约数，就能以极高的概率获得 $ N $ 的质因数。&lt;/p>
&lt;p>在经典计算机上寻找周期 $ r $ 最终还是需要指数级的步骤，无法实现加速。但是，如果是量子计算机，就能在瞬间（多项式时间内）找到这个周期 $ r $。&lt;/p>
&lt;h3 id="步骤2量子态的准备与叠加">步骤2：量子态的准备与叠加
&lt;/h3>&lt;p>接下来就是量子计算机的舞台了。
量子计算机使用能够同时拥有“0”和“1”状态的“量子比特（Qubit）”。在秀尔算法中，准备了两个寄存器：用于存储输入的寄存器（第一寄存器）和用于存储计算结果的寄存器（第二寄存器）。&lt;/p>
&lt;p>首先，将一种称为阿达马门（Hadamard gate）的量子逻辑门操作应用于第一寄存器的所有量子比特。借此，第一寄存器会进入所有可能的 $ x $ 值（从 $ 0 $ 到 $ 2^n-1 $，$ n $ 为足够大的比特数）的 &lt;strong>均匀叠加态&lt;/strong>。&lt;/p>
&lt;p>也就是说，在量子计算机内部，构建出了一个无数个输入值 $ x=0, 1, 2, 3, \dots $ 同时并行存在的状态。&lt;/p>
&lt;h3 id="步骤3量子模幂运算quantum-modular-exponentiation">步骤3：量子模幂运算（Quantum Modular Exponentiation）
&lt;/h3>&lt;p>接下来，以第一寄存器的叠加态作为输入，计算 $ f(x) = a^x \pmod N $，并将结果存储在第二寄存器中。
由于这种计算是作为量子电路上的幺正变换（Unitary transformation）执行的，因此在保持叠加态的同时，对所有 $ x $ 的 $ f(x) $ 计算是“同时并行地（量子并行性）”进行的。&lt;/p>
&lt;p>此时整个量子系统的空间，变成了
$ |x, a^x \bmod N\rangle $
这种状态的庞大叠加。&lt;/p>
&lt;p>但是，如果在这里简单地对第二寄存器进行测量（观测），就会按概率随机选出一个 $ a^x \bmod N $ 的值，与之联动的第一寄存器中的 $ x $ 也会确定为一个值。这就和用经典计算机计算一次是一样的，无法找到周期 $ r $。&lt;/p>
&lt;p>根据量子力学的规则，我们无法直接窥探叠加态的内容。那么，如何提取出整体“周期”这种全局信息呢？&lt;/p>
&lt;h3 id="步骤4量子傅里叶变换qft-quantum-fourier-transform">步骤4：量子傅里叶变换（QFT: Quantum Fourier Transform）
&lt;/h3>&lt;p>突破这道壁垒的秀尔算法之精髓，就在于对第一寄存器应用 &lt;strong>量子傅里叶变换（QFT）&lt;/strong>。&lt;/p>
&lt;p>在进行测量之前，分析函数 $ f(x) $ 的波的性质。假设我们观测了第二寄存器，并得到了一个值 $ y $。那么，第一寄存器的状态就会坍缩为“所有满足 $ a^x \pmod N = y $ 的 $ x $ 的叠加”。
这个 $ x $ 的值，会变成像 $ x_0, x_0 + r, x_0 + 2r, x_0 + 3r, \dots $ 这样以周期 $ r $ 为间隔离散排列的状态（一种梳状的概率幅分布）。&lt;/p>
&lt;p>对这种状态应用量子傅里叶变换（QFT）。就像经典的离散傅里叶变换将时域信号转换为频域一样，QFT会让量子态的概率幅发生干涉。&lt;/p>
&lt;p>应用QFT后，由于量子干涉效应，与周期 $ r $ 不共振（相位不一致）的错误答案的概率会相互抵消并趋近于零（破坏性干涉），而只有包含周期 $ r $ 信息的正确答案的概率才会被放大（建设性干涉）。&lt;/p>
&lt;h3 id="步骤5测量与连分数展开经典后处理">步骤5：测量与连分数展开（经典后处理）
&lt;/h3>&lt;p>在应用QFT之后测量第一寄存器，以极高的概率可以得到一个非常接近 $ c \approx \frac{j \cdot 2^n}{r} $ 这种形式的整数 $ c $（其中 $ j $ 是一个未知的整数，$ 2^n $ 是寄存器的大小）。&lt;/p>
&lt;p>将这个测量结果 $ c $ 传回经典计算机，构建分数 $ \frac{c}{2^n} \approx \frac{j}{r} $。然后，利用称为“连分数展开（Continued fraction expansion）”的数学方法计算近似值，就能巧妙地找出作为分母的周期 $ r $。&lt;/p>
&lt;p>一旦知道了 $ r $，剩下的就是使用步骤1的公式计算出 $ N $ 的质因数，RSA加密就被彻底破解了。&lt;/p>
&lt;hr>
&lt;h2 id="当前量子计算机nisq的实力与课题">当前量子计算机（NISQ）的实力与课题
&lt;/h2>&lt;p>虽然秀尔算法在理论上是完美的，但如果问“明天RSA加密就会被破解吗？”，答案明确是“否定”的。其原因在于当前量子计算机的硬件技术限制。&lt;/p>
&lt;h3 id="nisq含噪中型量子时代">NISQ（含噪中型量子）时代
&lt;/h3>&lt;p>我们目前正处于被称为“NISQ”的时代。NISQ设备拥有几十到几百个物理量子比特，但对噪声极为脆弱。&lt;/p>
&lt;p>量子比特很容易受到热量和电磁波等外部环境的影响，从而频繁发生导致量子态被破坏的“退相干（量子纠缠丧失）”或门操作时的“门错误”。如果试图运行像秀尔算法这样极其深（运算步骤庞大）的量子电路，错误会在计算过程中累积，最终的输出将变成毫无意义的完全噪声。&lt;/p>
&lt;h3 id="物理量子比特与逻辑量子比特">物理量子比特与逻辑量子比特
&lt;/h3>&lt;p>为了解决这个错误问题，“量子纠错（Quantum Error Correction）”是不可或缺的。
虽然经典计算机中也使用了纠错码，但由于存在禁止复制量子态的“不可克隆定理”，量子纠错极其复杂。&lt;/p>
&lt;p>在量子纠错中，通过使用“表面码（Surface Code）”等技术，将许多充满噪声的“物理量子比特”组合起来，从而创造出一个没有错误的理想“逻辑量子比特”。&lt;/p>
&lt;p>在当前错误率的前提下，据估算，制造1个逻辑量子比特大约需要1,000到10,000个物理量子比特。这被称为“纠错开销（Overhead）”。&lt;/p>
&lt;h3 id="破坏rsa-2048需要怎样的资源">破坏RSA-2048需要怎样的资源？
&lt;/h3>&lt;p>那么，为了实际破解RSA-2048而运行秀尔算法，需要多少资源呢？&lt;/p>
&lt;p>Craig Gidney（谷歌）和Martin Ekerå在2021年的一篇论文中进行的突破性资源估算表明，如果使用优化的秀尔算法，并使用表面码进行纠错，则需要以下资源：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>逻辑量子比特数&lt;/strong>：约 4,096 个&lt;/li>
&lt;li>&lt;strong>物理量子比特数 &lt;strong>：&lt;/strong> 约 2000万个&lt;/strong>（假设错误率在 $10^{-3}$ 左右）&lt;/li>
&lt;li>&lt;strong>计算时间&lt;/strong>：约 8小时（需要数百万到数十亿次物理门操作）&lt;/li>
&lt;/ul>
&lt;p>对此，当前量子硬件的水平达到了什么程度呢？
2023年底，IBM发布的超导量子处理器“Condor”达到了1,121个量子比特。此外，有关逻辑量子比特生成的突破性研究（如哈佛大学和QuEra公司等利用中性原子量子计算机生成了48个逻辑量子比特）也已涌现，但目前仍未达到能够长时间连续执行“无噪声完美运算”的阶段。&lt;/p>
&lt;p>从几千个物理量子比特，扩展到 &lt;strong>2000万个&lt;/strong> 实用的物理量子比特（且互相连接，在极低温下稳定工作，并能超高速处理控制信号的系统），在工程上存在着巨大的壁垒（布线问题、冷却能力限制、控制电子设备的臃肿化）。许多专家预测，能够破解RSA-2048的“容错量子计算机（FTQC）”至少需要10到30年，甚至更长的时间才能实现。&lt;/p>
&lt;hr>
&lt;h2 id="悄然逼近的store-now-decrypt-later威胁与pqc的曙光">悄然逼近的“Store Now, Decrypt Later”威胁与PQC的曙光
&lt;/h2>&lt;p>认为“既然还需要10年以上，那就安心了”还为时过早。目前，诸如国家机密信息、医疗数据以及长期的基础设施设计等，存在着必须确保未来几十年内依然保密的数据。&lt;/p>
&lt;p>在此令人担忧的，是一种被称为 &lt;strong>“Store Now, Decrypt Later（现在存储，以后解密）”&lt;/strong> 的攻击手法。恶意的国家或组织会拦截当前所有用RSA或ECC（椭圆曲线加密）加密的通信数据，并将它们保存在存储器中。然后等到10年、20年后强大的量子计算机完成的瞬间，再使用秀尔算法将过去的数据全部解密，从而暴露机密信息。&lt;/p>
&lt;p>为了对抗这种时间差带来的威胁，以NIST（美国国家标准与技术研究院）为中心，&lt;strong>“后量子密码学（PQC: Post-Quantum Cryptography）”&lt;/strong> 的标准化进程一直在加紧推进。&lt;/p>
&lt;p>PQC是基于即使使用量子计算机也很难破解（即无法应用秀尔算法）的数学问题的新型加密算法。主要的方法有以下几种：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>基于格的密码学（Lattice-based cryptography）&lt;/strong>：以LWE（容错学习）等问题为基础。在NIST标准化中占据主流（如Kyber、Dilithium等）。&lt;/li>
&lt;li>&lt;strong>基于编码的密码学（Code-based cryptography）&lt;/strong>：依赖于纠错码解码问题的困难性。&lt;/li>
&lt;li>&lt;strong>多变量密码学（Multivariate cryptography）&lt;/strong>：依赖于求解多变量非线性多项式方程组的困难性。&lt;/li>
&lt;li>&lt;strong>基于哈希的签名（Hash-based signatures）&lt;/strong>：仅依赖于哈希函数安全性的数字签名。&lt;/li>
&lt;/ul>
&lt;p>目前在Google Chrome和Apple的iMessage等主要软件和平台上，PQC的导入测试和混合实现已经启动。&lt;/p>
&lt;h2 id="结语">结语
&lt;/h2>&lt;p>量子计算机正在从科幻世界里的梦想，转变为现实的工程挑战。秀尔算法是数学与量子力学融合的人类伟大智力成果，但同时，它也暗藏着动摇我们数字社会基石的“破坏力”。&lt;/p>
&lt;p>RSA加密并不会明天立刻就变得不可用。但是，考虑到量子技术的发展以及“Store Now, Decrypt Later”的风险，向PQC过渡这一密码学史上规模空前的迁移已经开始。我们现在正在见证信息安全领域范式转移的最前线。&lt;/p></description></item><item><title>【完全解剖】使用C++实现并理解最强密码破解算法「GNFS」</title><link>http://kenji.blog/zh-cn/p/gnfs-cpp-implementation/</link><pubDate>Sat, 05 Sep 2026 13:04:59 +0900</pubDate><guid>http://kenji.blog/zh-cn/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 【完全解剖】使用C++实现并理解最强密码破解算法「GNFS」" />&lt;h1 id="完全解剖使用c实现并理解最强密码破解算法gnfs">【完全解剖】使用C++实现并理解最强密码破解算法「GNFS」
&lt;/h1>&lt;p>支撑现代互联网根基的「RSA加密」。其坚固性依赖于一种数学信念：“以目前的计算机，想要对巨大的合数进行素数分解实际上是不可能的”。&lt;/p>
&lt;p>然而，人类从未放弃。如今，在经典计算机（非量子计算机）上，存在着一种用于进行巨大素数分解的 **人类最强、最尖端的算法 **。那就是 &lt;strong>「一般数域筛选法（GNFS：General Number Field Sieve）」&lt;/strong>。&lt;/p>
&lt;p>本文将完全公开使用C++（使用了Boost库的多精度整数 &lt;code>boost::multiprecision&lt;/code>）严格建模这一GNFS最尖端计算逻辑的实现代码，并彻底解说其背后的「代数数论」深渊。&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">// 执行将缓存效率提升到极限的筛选。
&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="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 (删除仅出现1次的素数所对应的关系)
&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 (合并关系以使稀疏矩阵变稠密)
&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">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">// 迭代进行稀疏矩阵与向量的乘积运算，
&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 的解向量(零空间)。
&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法等)
&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">// 为了回避理想类群与单位群的障碍(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">// 想要进行素数分解的巨大合数 N (如 RSA-270 等)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;233108530344407544527637656910680524145619812480305449042948611968495918245135782867888369318577116418213919268572658314913060672626911354027609793166341626693946596196427744273886601876896313468704059066746903123910748277606548649151920812699309766587514735456594993207&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 多项式的次数 (超过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">// 执行将缓存效率提升到极限的筛选。
&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>代数侧的范数&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$ 平面上，从头开始依次用素数去除。然而，这种做法会导致在内存各处跳跃访问，引发频繁的缓存未命中，速度非常慢。&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 (删除仅出现1次的素数所对应的关系)
&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 (合并关系以使稀疏矩阵变稠密)
&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中全球计算机花费数月收集到的数亿个关系。但是，如果直接将这些关系丢给下一个“解方程组步骤（矩阵计算）”，超级计算机的内存也会被撑爆。&lt;/p>
&lt;p>因此，需要进行称为 &lt;strong>Filtering（过滤）&lt;/strong> 的矩阵超压缩过程。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Singleton removal（奇异点清除）&lt;/strong>
假设一个巨大的素数 $p$ 在数亿个关系中“仅仅出现了一次”。因为我们的目标是“让所有素数的指数都变为偶数（2的倍数）”，所以只出现一次的素数是绝对无法变成偶数的。
因此，包含该素数的关系会被视为“无用的垃圾”立即删除（清除）。由于这会引起连锁反应，原本数亿行的数据会迅速减少。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Clique merging（团合并）&lt;/strong>
进一步地，将共享特定素数的关系互相相乘（相加），从而在减少行数的同时，把稀疏（空洞多）的矩阵压缩成更稠密的状态（使用类似图论中的团搜索技术）。&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">// 迭代进行稀疏矩阵与向量的乘积运算，
&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 的解向量(零空间)。
&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>终于到了拼图的核心。
将收集到的关系相乘，寻找 &lt;strong>“所有素因子的指数都变成偶数次方的组合”&lt;/strong>。&lt;/p>
&lt;p>这在数学上等同于，用一个元素为各素数指数的“偶数/奇数（即0或1）”的巨大矩阵 $M$，和一个表示使用哪些关系的向量 $x$，
求解满足 &lt;strong>$M \cdot x \equiv 0 \pmod 2$&lt;/strong> 的解向量 $x$（零空间、核）。&lt;/p>
&lt;p>我们需要解开数百万行 × 数百万列这种惊人规模矩阵的联立方程式。如果使用普通的高斯消元法，计算复杂度将达到 $O(N^3)$，即使到宇宙终结也算不完。&lt;/p>
&lt;p>因此，最尖端的实现采用了 &lt;strong>“Block Wiedemann（分块维德曼）法”&lt;/strong>。
这是一种Krylov子空间法，利用矩阵 $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的矩阵计算，我们得到了“一旦相乘，所有素因子都会变为偶数次方的关系集合 $S$”。
借此，我们能够在有理侧和代数侧各自的世界中构建出“平方”。&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>最后，通过环同态映射 $\phi$（将 $x$ 替换为 $m$），把代数侧的平方根 $\gamma$ 传送回现实世界，得到 $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-cn/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-cn/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^2 \equiv Y^2 \pmod N$ 的 $X, Y$。
为了实现这一目标，数学家们在 &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$ 的整数构成的同余（模）世界。&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（余数的世界）”，** 也能完美保持平方的形式 $\phi(\gamma)^2$**。&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> 终于要登场了。
将世界A的元素 $\gamma$，通过 $\phi$（将 $\alpha$ 替换为 $m$ 的映射），跃迁到世界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-cn/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-cn/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密码防御的核心非常简单。那就是利用了 &lt;strong>“即使是计算机也无法解开巨大数字的质因数分解”&lt;/strong> 这一数学性质。
例如，如果是“15”，我们很快就能知道是“3 × 5”，但如果这变成一个“270位的数字”，即使把全世界的超级计算机联合起来，也需要几亿年才能解开。&lt;/p>
&lt;p>然而，数学家们也没有沉默。为了打破这个坚不可摧的密码，人类创造出了一种如同魔法般的算法（计算步骤）——&lt;strong>“一般数域筛选法（GNFS：General Number Field Sieve）”&lt;/strong>。&lt;/p>
&lt;p>在这篇文章中，我们将不使用任何专业术语，仅凭 &lt;strong>初中学的数学知识（质因数分解、代数式、最大公约数）&lt;/strong>，分步为您完全解析这个“人类最强算法”破解密码的奥秘！&lt;/p>
&lt;hr>
&lt;h2 id="第1章密码破译的目标是初三的公式">第1章：密码破译的目标是“初三的公式”
&lt;/h2>&lt;p>面对巨大的质因数分解，最大的必杀技就是初三年级学的这个公式。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>$X^2 - Y^2 = (X + Y)(X - Y)$&lt;/strong>&lt;/p>
&lt;/blockquote>
&lt;p>你可能会想：“哎，这么基础的公式就能破解密码吗？”但正是这个公式，是解开一切的大师级钥匙。&lt;/p>
&lt;p>破解密码的最大目标，是对于一个巨大的数字 $N$，
找到 &lt;strong>“将 $X^2$ 和 $Y^2$ 除以 $N$ 后的余数相同的数字（$X$ 和 $Y$）”&lt;/strong>。&lt;/p>
&lt;h3 id="为什么余数相同就能解开密码">为什么“余数相同”就能解开密码？
&lt;/h3>&lt;p>假设有两个数字 $X^2$ 和 $Y^2$，“除以 $N$ 的余数相同”。
余数相同意味着，&lt;strong>做减法得到的“$X^2 - Y^2$”，必定能被 $N$ 整除（成为 $N$ 的倍数）&lt;/strong>，这是一个法则。&lt;/p>
&lt;p>这里，假设用于密码的巨大数字 $N$ 是由两个秘密的质数（$p$ 和 $q$）相乘得到的（$N = p \times q$）。&lt;/p>
&lt;p>将 $X^2 - Y^2$ 进行因式分解，就变成了 &lt;strong>$(X - Y)(X + Y)$&lt;/strong>。
这既然是 $N$ 的倍数，就意味着在这个乘法中的某个地方，隐藏着秘密的质数 $p$ 和 $q$。&lt;/p>
&lt;p>奇迹在此发生。
这两个质数 $p$ 和 $q$，&lt;strong>“$p$ 进入 $(X - Y)$ 的房间”、“$q$ 进入 $(X + Y)$ 的房间”&lt;/strong>，被分到不同房间的概率，在数学上是 ** 50%（二分之一）**。&lt;/p>
&lt;p>在只有质数 $p$ 进入了 $(X - Y)$ 房间的状态下，让我们来计算 $(X - Y)$ 和 $N$ 的 &lt;strong>“最大公约数（最大的共同部分）”&lt;/strong>。&lt;/p>
&lt;ul>
&lt;li>$(X - Y)$ 的内容 ＝ $p \times$ 某个数&lt;/li>
&lt;li>$N$ 的内容 ＝ $p \times q$
共同的部分只有 &lt;strong>“$p$”&lt;/strong> 吧！&lt;/li>
&lt;/ul>
&lt;p>也就是说，在计算出最大公约数的瞬间，隐藏着的质数 $p$ 就会掉落出来，密码也就被完全破译了。（※使用“辗转相除法”，即使在智能手机上也能瞬间计算出最大公约数）&lt;/p>
&lt;p>&lt;strong>【小专栏：为什么是平方？三次方或两倍不行吗？】&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>如果是“$2X - 2Y$”，就会变成 $2(X - Y)$，因为只有一个房间，所以无法分离出质数。如果是“$X^3 - Y^3$”，房间的大小会变得不平衡，计算量会无谓地增加。为了将质数分离成两个，能优美地分成两个房间的“平方”性价比最高。&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="第2章如何寻找x和y收集质数卡片的拼图">第2章：如何寻找X和Y？“收集质数卡片的拼图”
&lt;/h2>&lt;p>目标已经明确。然而，即使盲目地去寻找“余数相同的 $X^2$ 和 $Y^2$”，直到宇宙寿命结束也找不到。
于是，数学家们想出了一个极其天才的方法，称为 &lt;strong>“收集质数卡片的拼图”&lt;/strong>。&lt;/p>
&lt;h3 id="step-1用筛子只收集沙金平滑数">Step 1：用筛子只收集沙金（平滑数）
&lt;/h3>&lt;p>首先，准备一个随意的数字 $Z$，计算其平方后除以 $N$ 的余数 $W$。
（$Z^2 = W$ 的余数世界）&lt;/p>
&lt;p>将得到的余数 $W$ 进行质因数分解。这里，只有当出现 &lt;strong>“仅由 2, 3, 5, 7 等小质数组成的 $W$”&lt;/strong> 时，才将该式子作为“中奖卡片”保留下来；如果混杂了大的质数就丢掉。
这就好比在河里用筛子把大石头过滤掉，只收集沙金一样的作业。&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)$，
整理后变成 &lt;strong>“$2^4 \times 3^2 \times 5^2$”&lt;/strong>。&lt;/p>
&lt;p>不可思议的是，质数的个数变成了“4个、2个、2个”，&lt;strong>全部都是偶数个&lt;/strong>！
全部都是偶数个，意味着把整体的个数减半，就会变成“某个数的平方”。
也就是说，$(2^2 \times 3^1 \times 5^1)^2 = (60)^2$。&lt;/p>
&lt;p>左侧是 $(Z_1 \times Z_2 \times Z_3)^2$，这样一来，终于
&lt;strong>$X = (Z_1 \times Z_2 \times Z_3)$&lt;/strong>
&lt;strong>$Y = 60$&lt;/strong>
这组期待已久的“$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>在这里，人类的终极武器 &lt;strong>“一般数域筛选法（GNFS）”&lt;/strong> 终于登场了。&lt;/p>
&lt;hr>
&lt;h2 id="第4章人类最强的点子创造两个世界">第4章：人类最强的点子，创造“两个世界”
&lt;/h2>&lt;p>GNFS 的天才构想是：&lt;strong>“因为只在现实世界里计算，所以数字才会变大。那么，就创造一个使用多项式（代数式）的『里世界』，把计算的负担分散成两份吧。”&lt;/strong>&lt;/p>
&lt;h3 id="代数式的魔法">代数式的魔法
&lt;/h3>&lt;p>GNFS 利用一个基准数 $m$，将巨大的数字 $N$ 转换为代数式。
例如，如果 $N=100$，设 $m=4$，则 $100 = 4^3 + 2(4^2) + 4$。
使用字母 $x$，将其变为 &lt;strong>$f(x) = x^3 + 2x^2 + x$&lt;/strong> 这样一个式子（里世界）。&lt;/p>
&lt;p>这个式子有趣的地方在于，它具有 &lt;strong>“只要将 $m$（上例中是4）代入字母 $x$，就随时能穿越回到现实的数字 $N$”&lt;/strong> 这一性质。&lt;/p>
&lt;h3 id="在两个世界同时寻找沙金">在两个世界同时寻找沙金
&lt;/h3>&lt;p>GNFS 会制造许多随意的整数对 $(a, b)$，并同时进行以下两个计算：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>现实世界&lt;/strong>： $a - b \times m$&lt;/li>
&lt;li>&lt;strong>代数式世界&lt;/strong>： 用代数式的规则计算出的 $a - b \times x$ 的值&lt;/li>
&lt;/ol>
&lt;p>通过将问题分为两个世界，所处理的数字尺寸就会剧烈减小（变轻）。这就像是把一块巨岩劈成两半，变成易于处理的石块的感觉。&lt;/p>
&lt;p>然后，只有当 &lt;strong>“在现实世界和代数式世界中，两边都『仅由小质数组成（沙金）』”&lt;/strong> 时，才用筛子把这种奇迹般的数对 $(a, b)$ 筛选出来并收集。这就是“数域筛选法”这个名字的由来。&lt;/p>
&lt;h3 id="密码终于被破译的瞬间">密码终于被破译的瞬间
&lt;/h3>&lt;p>当从两个世界收集到数千万张“沙金卡片”后，就利用超级计算机庞大的矩阵计算，找出在第2章做过的“质数个数全部变成偶数的组合”。&lt;/p>
&lt;p>找到组合后：&lt;/p>
&lt;ul>
&lt;li>将在现实世界中形成的平方数设为 &lt;strong>$X^2$&lt;/strong>&lt;/li>
&lt;li>将在代数式世界中形成的平方代数式设为 &lt;strong>$Y(x)^2$&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>最后，将 $m$ 代入代数式 $Y(x)$ 的 $x$ 中，使其穿越到现实世界并汇合。
于是，就像数学魔法一样，&lt;strong>“$X^2$ 和 $Y^2$ 的余数相同”&lt;/strong> 的状态就严密地完成了！&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>然而，如果出现了 &lt;strong>“无论多巨大的数字，都能瞬间找到 $X$ 和 $Y$ 的魔法”&lt;/strong>，那会怎么样呢？
其实，最接近这种魔法的存在就是目前正在开发中的 &lt;strong>“量子计算机（Shor 算法）”&lt;/strong>。在数学上已经证明，如果利用量子力学的波动性质，就能无视麻烦的卡片收集拼图，一击命中答案。&lt;/p>
&lt;p>制造密码的人（防御）与制造破解密码算法的人（攻击）之间无止境的智慧较量。
当你知道初中学到的“质因数分解”和“代数式”，其实是活跃在世界安全最前线激烈交锋的武器时，是不是觉得数学课稍微变得有趣了一点呢？&lt;/p>
&lt;p>发现未来最强算法的，也许就是正在读这篇文章的你！&lt;/p>
&lt;hr>
&lt;p>&lt;em>(※本文是为了向初中生概念化地展示密码破译的数学魅力而写的。实际的 GNFS 使用了代数域的理想类群、同态映射等高级大学数学知识进行严密计算。)&lt;/em>&lt;/p></description></item></channel></rss>