<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>GNFS on kenji.blog</title><link>http://kenji.blog/ko/tags/gnfs/</link><description>Recent content in GNFS on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ko</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 13:04:59 +0900</lastBuildDate><atom:link href="http://kenji.blog/ko/tags/gnfs/index.xml" rel="self" type="application/rss+xml"/><item><title>[완전 해부] 최강의 암호 해독 알고리즘 'GNFS'를 C++로 구현하고 이해하기</title><link>http://kenji.blog/ko/p/gnfs-cpp-implementation/</link><pubDate>Sat, 05 Sep 2026 13:04:59 +0900</pubDate><guid>http://kenji.blog/ko/p/gnfs-cpp-implementation/</guid><description>&lt;img src="http://kenji.blog/p/gnfs-cpp-implementation/gnfs_cpp_blog_eyecatch_1788580949217.jpg" alt="Featured image of post [완전 해부] 최강의 암호 해독 알고리즘 'GNFS'를 C++로 구현하고 이해하기" />&lt;h1 id="완전-해부-최강의-암호-해독-알고리즘-gnfs를-c로-구현하여-이해하기">【완전 해부】 최강의 암호 해독 알고리즘 「GNFS」를 C++로 구현하여 이해하기
&lt;/h1>&lt;p>현대 인터넷의 근간을 지탱하는 「RSA 암호」. 그 견고함은 「거대한 합성수를 소인수분해하는 것은 현재의 컴퓨터로는 사실상 불가능하다」는 수학적 신념에 의존하고 있습니다.&lt;/p>
&lt;p>하지만 인류는 결코 포기하지 않았습니다. 현재 고전 컴퓨터(양자 컴퓨터가 아닌 일반 컴퓨터)에서 거대한 소인수분해를 수행하기 위한 **인류 최강·최첨단 알고리즘 ** 이 존재합니다. 그것이 바로 &lt;strong>「일반 수체 체(GNFS: General Number Field Sieve)」&lt;/strong> 입니다.&lt;/p>
&lt;p>본 기사에서는 이 GNFS의 최첨단 계산 로직을 C++(Boost 라이브러리의 다정밀도 정수 &lt;code>boost::multiprecision&lt;/code>을 사용)로 엄밀하게 모델화한 구현 코드를 전면 공개하고, 그 이면에 있는 「대수적 정수론」의 심연을 철저히 해설합니다.&lt;/p>
&lt;p>수학의 신비와 그것을 굴복시키는 컴퓨터 사이언스의 힘을 꼭 소스 코드와 함께 만끽하시기 바랍니다.&lt;/p>
&lt;hr>
&lt;h2 id="1-gnfs-최첨단-로직-프레임워크-전체-소스-코드">1. GNFS 최첨단 로직 프레임워크 (전체 소스 코드)
&lt;/h2>&lt;p>먼저, 이번에 해설할 GNFS의 C++ 구현의 전모를 싣습니다. 실제 수체 체(CADO-NFS 등)는 수십만 줄에 달하는 초대형 분산 시스템이지만, 본 코드는 GNFS를 구성하는 &lt;strong>「5가지 필수 파이프라인(단계)」&lt;/strong> 을 추출하여 클래스로 설계하고, 수학적인 의미를 잃지 않으면서 최소 구성으로 모델화한 것입니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt"> 10
&lt;/span>&lt;span class="lnt"> 11
&lt;/span>&lt;span class="lnt"> 12
&lt;/span>&lt;span class="lnt"> 13
&lt;/span>&lt;span class="lnt"> 14
&lt;/span>&lt;span class="lnt"> 15
&lt;/span>&lt;span class="lnt"> 16
&lt;/span>&lt;span class="lnt"> 17
&lt;/span>&lt;span class="lnt"> 18
&lt;/span>&lt;span class="lnt"> 19
&lt;/span>&lt;span class="lnt"> 20
&lt;/span>&lt;span class="lnt"> 21
&lt;/span>&lt;span class="lnt"> 22
&lt;/span>&lt;span class="lnt"> 23
&lt;/span>&lt;span class="lnt"> 24
&lt;/span>&lt;span class="lnt"> 25
&lt;/span>&lt;span class="lnt"> 26
&lt;/span>&lt;span class="lnt"> 27
&lt;/span>&lt;span class="lnt"> 28
&lt;/span>&lt;span class="lnt"> 29
&lt;/span>&lt;span class="lnt"> 30
&lt;/span>&lt;span class="lnt"> 31
&lt;/span>&lt;span class="lnt"> 32
&lt;/span>&lt;span class="lnt"> 33
&lt;/span>&lt;span class="lnt"> 34
&lt;/span>&lt;span class="lnt"> 35
&lt;/span>&lt;span class="lnt"> 36
&lt;/span>&lt;span class="lnt"> 37
&lt;/span>&lt;span class="lnt"> 38
&lt;/span>&lt;span class="lnt"> 39
&lt;/span>&lt;span class="lnt"> 40
&lt;/span>&lt;span class="lnt"> 41
&lt;/span>&lt;span class="lnt"> 42
&lt;/span>&lt;span class="lnt"> 43
&lt;/span>&lt;span class="lnt"> 44
&lt;/span>&lt;span class="lnt"> 45
&lt;/span>&lt;span class="lnt"> 46
&lt;/span>&lt;span class="lnt"> 47
&lt;/span>&lt;span class="lnt"> 48
&lt;/span>&lt;span class="lnt"> 49
&lt;/span>&lt;span class="lnt"> 50
&lt;/span>&lt;span class="lnt"> 51
&lt;/span>&lt;span class="lnt"> 52
&lt;/span>&lt;span class="lnt"> 53
&lt;/span>&lt;span class="lnt"> 54
&lt;/span>&lt;span class="lnt"> 55
&lt;/span>&lt;span class="lnt"> 56
&lt;/span>&lt;span class="lnt"> 57
&lt;/span>&lt;span class="lnt"> 58
&lt;/span>&lt;span class="lnt"> 59
&lt;/span>&lt;span class="lnt"> 60
&lt;/span>&lt;span class="lnt"> 61
&lt;/span>&lt;span class="lnt"> 62
&lt;/span>&lt;span class="lnt"> 63
&lt;/span>&lt;span class="lnt"> 64
&lt;/span>&lt;span class="lnt"> 65
&lt;/span>&lt;span class="lnt"> 66
&lt;/span>&lt;span class="lnt"> 67
&lt;/span>&lt;span class="lnt"> 68
&lt;/span>&lt;span class="lnt"> 69
&lt;/span>&lt;span class="lnt"> 70
&lt;/span>&lt;span class="lnt"> 71
&lt;/span>&lt;span class="lnt"> 72
&lt;/span>&lt;span class="lnt"> 73
&lt;/span>&lt;span class="lnt"> 74
&lt;/span>&lt;span class="lnt"> 75
&lt;/span>&lt;span class="lnt"> 76
&lt;/span>&lt;span class="lnt"> 77
&lt;/span>&lt;span class="lnt"> 78
&lt;/span>&lt;span class="lnt"> 79
&lt;/span>&lt;span class="lnt"> 80
&lt;/span>&lt;span class="lnt"> 81
&lt;/span>&lt;span class="lnt"> 82
&lt;/span>&lt;span class="lnt"> 83
&lt;/span>&lt;span class="lnt"> 84
&lt;/span>&lt;span class="lnt"> 85
&lt;/span>&lt;span class="lnt"> 86
&lt;/span>&lt;span class="lnt"> 87
&lt;/span>&lt;span class="lnt"> 88
&lt;/span>&lt;span class="lnt"> 89
&lt;/span>&lt;span class="lnt"> 90
&lt;/span>&lt;span class="lnt"> 91
&lt;/span>&lt;span class="lnt"> 92
&lt;/span>&lt;span class="lnt"> 93
&lt;/span>&lt;span class="lnt"> 94
&lt;/span>&lt;span class="lnt"> 95
&lt;/span>&lt;span class="lnt"> 96
&lt;/span>&lt;span class="lnt"> 97
&lt;/span>&lt;span class="lnt"> 98
&lt;/span>&lt;span class="lnt"> 99
&lt;/span>&lt;span class="lnt">100
&lt;/span>&lt;span class="lnt">101
&lt;/span>&lt;span class="lnt">102
&lt;/span>&lt;span class="lnt">103
&lt;/span>&lt;span class="lnt">104
&lt;/span>&lt;span class="lnt">105
&lt;/span>&lt;span class="lnt">106
&lt;/span>&lt;span class="lnt">107
&lt;/span>&lt;span class="lnt">108
&lt;/span>&lt;span class="lnt">109
&lt;/span>&lt;span class="lnt">110
&lt;/span>&lt;span class="lnt">111
&lt;/span>&lt;span class="lnt">112
&lt;/span>&lt;span class="lnt">113
&lt;/span>&lt;span class="lnt">114
&lt;/span>&lt;span class="lnt">115
&lt;/span>&lt;span class="lnt">116
&lt;/span>&lt;span class="lnt">117
&lt;/span>&lt;span class="lnt">118
&lt;/span>&lt;span class="lnt">119
&lt;/span>&lt;span class="lnt">120
&lt;/span>&lt;span class="lnt">121
&lt;/span>&lt;span class="lnt">122
&lt;/span>&lt;span class="lnt">123
&lt;/span>&lt;span class="lnt">124
&lt;/span>&lt;span class="lnt">125
&lt;/span>&lt;span class="lnt">126
&lt;/span>&lt;span class="lnt">127
&lt;/span>&lt;span class="lnt">128
&lt;/span>&lt;span class="lnt">129
&lt;/span>&lt;span class="lnt">130
&lt;/span>&lt;span class="lnt">131
&lt;/span>&lt;span class="lnt">132
&lt;/span>&lt;span class="lnt">133
&lt;/span>&lt;span class="lnt">134
&lt;/span>&lt;span class="lnt">135
&lt;/span>&lt;span class="lnt">136
&lt;/span>&lt;span class="lnt">137
&lt;/span>&lt;span class="lnt">138
&lt;/span>&lt;span class="lnt">139
&lt;/span>&lt;span class="lnt">140
&lt;/span>&lt;span class="lnt">141
&lt;/span>&lt;span class="lnt">142
&lt;/span>&lt;span class="lnt">143
&lt;/span>&lt;span class="lnt">144
&lt;/span>&lt;span class="lnt">145
&lt;/span>&lt;span class="lnt">146
&lt;/span>&lt;span class="lnt">147
&lt;/span>&lt;span class="lnt">148
&lt;/span>&lt;span class="lnt">149
&lt;/span>&lt;span class="lnt">150
&lt;/span>&lt;span class="lnt">151
&lt;/span>&lt;span class="lnt">152
&lt;/span>&lt;span class="lnt">153
&lt;/span>&lt;span class="lnt">154
&lt;/span>&lt;span class="lnt">155
&lt;/span>&lt;span class="lnt">156
&lt;/span>&lt;span class="lnt">157
&lt;/span>&lt;span class="lnt">158
&lt;/span>&lt;span class="lnt">159
&lt;/span>&lt;span class="lnt">160
&lt;/span>&lt;span class="lnt">161
&lt;/span>&lt;span class="lnt">162
&lt;/span>&lt;span class="lnt">163
&lt;/span>&lt;span class="lnt">164
&lt;/span>&lt;span class="lnt">165
&lt;/span>&lt;span class="lnt">166
&lt;/span>&lt;span class="lnt">167
&lt;/span>&lt;span class="lnt">168
&lt;/span>&lt;span class="lnt">169
&lt;/span>&lt;span class="lnt">170
&lt;/span>&lt;span class="lnt">171
&lt;/span>&lt;span class="lnt">172
&lt;/span>&lt;span class="lnt">173
&lt;/span>&lt;span class="lnt">174
&lt;/span>&lt;span class="lnt">175
&lt;/span>&lt;span class="lnt">176
&lt;/span>&lt;span class="lnt">177
&lt;/span>&lt;span class="lnt">178
&lt;/span>&lt;span class="lnt">179
&lt;/span>&lt;span class="lnt">180
&lt;/span>&lt;span class="lnt">181
&lt;/span>&lt;span class="lnt">182
&lt;/span>&lt;span class="lnt">183
&lt;/span>&lt;span class="lnt">184
&lt;/span>&lt;span class="lnt">185
&lt;/span>&lt;span class="lnt">186
&lt;/span>&lt;span class="lnt">187
&lt;/span>&lt;span class="lnt">188
&lt;/span>&lt;span class="lnt">189
&lt;/span>&lt;span class="lnt">190
&lt;/span>&lt;span class="lnt">191
&lt;/span>&lt;span class="lnt">192
&lt;/span>&lt;span class="lnt">193
&lt;/span>&lt;span class="lnt">194
&lt;/span>&lt;span class="lnt">195
&lt;/span>&lt;span class="lnt">196
&lt;/span>&lt;span class="lnt">197
&lt;/span>&lt;span class="lnt">198
&lt;/span>&lt;span class="lnt">199
&lt;/span>&lt;span class="lnt">200
&lt;/span>&lt;span class="lnt">201
&lt;/span>&lt;span class="lnt">202
&lt;/span>&lt;span class="lnt">203
&lt;/span>&lt;span class="lnt">204
&lt;/span>&lt;span class="lnt">205
&lt;/span>&lt;span class="lnt">206
&lt;/span>&lt;span class="lnt">207
&lt;/span>&lt;span class="lnt">208
&lt;/span>&lt;span class="lnt">209
&lt;/span>&lt;span class="lnt">210
&lt;/span>&lt;span class="lnt">211
&lt;/span>&lt;span class="lnt">212
&lt;/span>&lt;span class="lnt">213
&lt;/span>&lt;span class="lnt">214
&lt;/span>&lt;span class="lnt">215
&lt;/span>&lt;span class="lnt">216
&lt;/span>&lt;span class="lnt">217
&lt;/span>&lt;span class="lnt">218
&lt;/span>&lt;span class="lnt">219
&lt;/span>&lt;span class="lnt">220
&lt;/span>&lt;span class="lnt">221
&lt;/span>&lt;span class="lnt">222
&lt;/span>&lt;span class="lnt">223
&lt;/span>&lt;span class="lnt">224
&lt;/span>&lt;span class="lnt">225
&lt;/span>&lt;span class="lnt">226
&lt;/span>&lt;span class="lnt">227
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;cmath&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;map&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;set&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;chrono&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;boost/multiprecision/cpp_int.hpp&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Boost.Multiprecision의 다정밀도 정수를 사용
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">boost&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">multiprecision&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// [SOTA GNFS] General Number Field Sieve (일반 수체 체) 최첨단 로직 프레임워크
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">//
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 본 코드는 CADO-NFS 등에서 사용되는 최첨단 GNFS의 5가지 파이프라인을
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// C++ (Boost)의 클래스 설계로서 엄밀하게 모델화한 것입니다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Relation&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int64_t&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int64_t&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">rational_primes&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">algebraic_primes&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 1: Polynomial Selection (KleinJung의 알고리즘)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">PolynomialSelector&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// 대수 측 다항식 f(x)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">g&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// 유리 측 다항식 g(x) = x - m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">d&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// base-m 전개를 기반으로 한 초기 다항식 생성 (실제로는 더 고도화된 격자 기저 축소 LLL을 사용)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 1] Polynomial Selection (Degree &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">degree&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;) starting...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 간단한 base-m 전개 (d차)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// m = N^(1/d)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">N_copy&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">m&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 간단한 m의 근사 (Boost 함수를 사용하지 않는 근사)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">high&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">low&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">high&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">mid&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">high&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">low&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="n">mid&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">low&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">high&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mid&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">degree&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">temp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">temp&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">temp&lt;/span> &lt;span class="o">/=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// g(x) = x - m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; m = &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; f(x) = &amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">--&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;x^&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="s">&amp;#34; + &amp;#34;&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">[Phase 1] Complete.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 2: Lattice Sieving (격자 체)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 최근의 GNFS는 Line Sieve(직선 체)가 아닌 Franke-Kleinjung 등이 제안한
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 특수 q 격자 체 (Special-q Lattice Sieving)를 사용하는 것이 사실상 표준(de facto standard)입니다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">LatticeSieve&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">rational_bound&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">algebraic_bound&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">rational_fb&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">algebraic_fb&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LatticeSieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">rb&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">ab&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">rational_bound&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">rb&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">algebraic_bound&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ab&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">generate_factor_bases&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 2] Generating Factor Bases (Rational Bound: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">rational_bound&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;, Algebraic Bound: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">algebraic_bound&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;)&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// (생략) 실제로는 소수 생성 및 르장드르 기호 등으로 필터링을 수행
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">poly&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 2] Special-q Lattice Sieving active...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">relations&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 모의 구현: 실제 격자 체는 수백 GB의 메모리 공간을 블록 단위로 스캔한다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// (a, b)의 쌍을 특수 소수 q마다의 격자 (a = i*q + j*...) 에 매핑하고,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 캐시 효율을 극한까지 높인 체(Sieve)를 실행한다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 데모용으로 더미 관계식(relation)을 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">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">// 실제로는 Union-Find 알고리즘 등으로 수억 행의 행렬을 수백만 행까지 압축한다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 3] Matrix size reduced optimally.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Phase 4: Linear Algebra over GF(2) (Block Wiedemann 법)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">LinearAlgebraGF2&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 최근의 슈퍼컴퓨터 환경에서는 Block Lanczos 법보다 분산 컴퓨팅에
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 적합한 Block Wiedemann 법(Coppersmith 구현)이 최첨단 기술로 사용된다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">solve_nullspace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 4] Block Wiedemann algorithm over GF(2) starting...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 스파스(희소) 행렬과 벡터의 곱셈 연산을 반복하여,
&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&amp;#39;s method 등)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 거대한 대수체 O_K의 원소 gamma를 구하고, 준동형 사상 phi로 현실 세계에 매핑한다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Y = phi(gamma) mod N
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">Y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 아이디얼 군과 단수 군의 장애물(Obstruction)을 회피하기 위해,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Phase 2와 4에서 이차 잉여 기호(Quadratic Characters) 열이 추가되어 있다는 전제.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; -&amp;gt; Homomorphism map phi applied.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Phase 5] Calculating GCD(V - Y, N)...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">factor&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">V&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">Y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// GCD(X-Y, N)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">factor&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">factor&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[SUCCESS] Non-trivial factor found: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">factor&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; Other factor: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">N&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">factor&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[FAILURE] Trivial solution. Trying next dependency...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Main Execution Pipeline
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; [SOTA GNFS] General Number Field Sieve Engine (Boost C++) &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// RSA-270 등, 소인수분해하고 싶은 거대한 합성수 N
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;233108530344407544527637656910680524145619812480305449042948611968495918245135782867888369318577116418213919268572658314913060672626911354027609793166341626693946596196427744273886601876896313468704059066746903123910748277606548649151920812699309766587514735456594993207&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 다항식의 차수 (130자리가 넘는 경우는 통상 5~6차를 선택)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">degree&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">6&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 파이프라인 초기화
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span> &lt;span class="n">poly_select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">degree&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LatticeSieve&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10000000&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">20000000&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// 실제 바운드는 수천만~수억
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Filter&lt;/span> &lt;span class="n">filter&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LinearAlgebraGF2&lt;/span> &lt;span class="n">linalg&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AlgebraicSquareRoot&lt;/span> &lt;span class="n">sqrt_step&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">start_time&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">high_resolution_clock&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. 다항식 선택
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">poly_select&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2. 체(Sieve) 처리
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">generate_factor_bases&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">relations&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">poly_select&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. 필터링 (행렬 압축)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">filter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">reduce_matrix&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">relations&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 4. 선형 대수 (GF(2)에서의 널 스페이스 탐색)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">dependencies&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">linalg&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">solve_nullspace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">relations&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 5. 대수적 제곱근 계산 및 GCD
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="nl">dep&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">dependencies&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sqrt_step&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">compute_and_factor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">relations&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">dep&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">end_time&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">high_resolution_clock&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">duration&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">double&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">elapsed&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">end_time&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">start_time&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">[System] SOTA GNFS Pipeline completed in &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">elapsed&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; seconds.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>그렇다면 이 코드가 어떻게 암호의 장벽을 부숴나가는 것일까요. 5개의 단계별로 그 치밀한 알고리즘과 고도의 수학을 알기 쉽게 해설해 보겠습니다.&lt;/p>
&lt;hr>
&lt;h2 id="2-gnfs의-최종-목적-x2-equiv-y2-pmod-n">2. GNFS의 최종 목적: $X^2 \equiv Y^2 \pmod N$
&lt;/h2>&lt;p>GNFS뿐만 아니라 현대의 거대 소인수분해 알고리즘 대부분이 목표로 하는 것은 다음 합동식을 만족하는 자명하지 않은 쌍 $(X, Y)$를 찾는 것입니다.&lt;/p>
$$X^2 \equiv Y^2 \pmod N$$
&lt;p>이 식은 「$X^2$과 $Y^2$을 $N$으로 나눈 나머지가 같다」는 것을 의미합니다. 이를 변형하면,
$X^2 - Y^2 \equiv 0 \pmod N$
즉, $(X-Y)(X+Y)$가 $N$의 배수가 됩니다.&lt;/p>
&lt;p>만약 $X \not\equiv \pm Y \pmod N$ (비자명한 해)라면, $(X-Y)$와 $N$ 사이에는 「1보다 크고 $N$보다 작은 공약수」가 존재하게 됩니다.
여기서 유클리드 호제법을 사용하여 &lt;strong>$\gcd(X-Y, N)$&lt;/strong> 을 계산하면, $N$의 소인수를 아주 쉽게 구할 수 있습니다.&lt;/p>
&lt;p>하지만 이 $X$와 $Y$를 찾는 것은 사막에서 바늘을 찾는 것과 같습니다. 그래서 GNFS는 「현실의 정수 세계」와 「다항식의 대수체 세계」라는 &lt;strong>두 세계&lt;/strong> 를 만들어내고, 계산을 분산시키는 천재적인 접근법을 취합니다.&lt;/p>
&lt;hr>
&lt;h2 id="3-phase-1-다항식-선택-polynomial-selection">3. Phase 1: 다항식 선택 (Polynomial Selection)
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">PolynomialSelector&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// m = N^(1/d) 의 계산 및 base-m 전개
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">degree&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">temp&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">temp&lt;/span> &lt;span class="o">/=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// g(x) = x - m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>GNFS의 첫 번째 단계는 두 세계를 이어주는 「마법의 다항식」을 만드는 것입니다.
거대한 수 $N$에 대해, 정수 $m$을 선택합니다. 보통 $m \approx N^{1/d}$이 되도록 선택합니다(코드에서는 $d=6$차 다항식을 가정).&lt;/p>
&lt;p>그리고 $N$을 $m$진수로 전개하고, 그 계수를 사용하여 다항식 $f(x)$를 구성합니다.
&lt;/p>
$$N = c_d m^d + c_{d-1} m^{d-1} + \dots + c_1 m + c_0$$
$$f(x) = c_d x^d + c_{d-1} x^{d-1} + \dots + c_1 x + c_0$$
&lt;p>이 다항식 $f(x)$에는 &lt;strong>「변수 $x$에 $m$을 대입하면 정확히 $N$이 된다 ($f(m) = N$)」&lt;/strong> 는 매우 중요한 성질이 있습니다. 다시 말해, $f(m) \equiv 0 \pmod N$입니다.
유리 측 다항식은 $g(x) = x - m$으로 정의됩니다.&lt;/p>
&lt;p>이로 인해, $f(x)=0$의 근 $\alpha$가 지배하는 &lt;strong>「대수체의 세계 $\mathbb{Z}[\alpha]$」&lt;/strong> 와 일반적인 &lt;strong>「유리수(정수)의 세계 $\mathbb{Z}$」&lt;/strong> 가 $x \to m$이라는 「환 준동형 사상(Homomorphism)」에 의해 강력하게 연결됩니다.&lt;/p>
&lt;p>최첨단 CADO-NFS 등에서는 KleinJung의 알고리즘이나 LLL 격자 기저 축소 알고리즘을 사용하여, 다항식의 계수가 극단적으로 커지지 않으면서 후속 단계에서 소수가 쉽게 나타날 수 있는 (매끄러워지기 쉬운) 「가장 적합한 다항식 $f(x)$」를 수개월에 걸쳐 탐색합니다.&lt;/p>
&lt;hr>
&lt;h2 id="4-phase-2-특수-q-격자-체-special-q-lattice-sieving">4. Phase 2: 특수 $q$ 격자 체 (Special-q Lattice Sieving)
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">LatticeSieve&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">poly&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// (a, b)의 쌍을 특수 소수 q마다의 격자에 매핑하고,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 캐시 효율을 극한까지 높인 체(Sieve)를 실행한다.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>두 세계를 준비했다면, 다음은 양쪽 세계 모두에서 「매끄러운 수(작은 소수들로만 이루어진 수)」를 찾는 단계로 들어갑니다.
정수 쌍 $(a, b)$를 무수히 생성하고, 다음 두 값을 계산합니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>유리 측의 값&lt;/strong>: $a - bm$&lt;/li>
&lt;li>&lt;strong>대수 측의 노름(Norm)&lt;/strong>: $b^d f(a/b)$&lt;/li>
&lt;/ol>
&lt;p>GNFS의 목적은 이 &lt;strong>「유리 측과 대수 측의 값이 모두 작은 소인수로만 완전히 분해되는 쌍(Relation: 관계식)」&lt;/strong> 을 수천만에서 수억 개 모으는 것입니다.&lt;/p>
&lt;p>초기 GNFS에서는 $(a, b)$를 $xy$ 평면에 나열하고 가장자리부터 차례로 소수로 나누어가는 「직선 체(Line Sieve)」가 사용되었습니다. 하지만 이 방식은 메모리의 여기저기를 접근하기 때문에 캐시 미스가 다발하여, 매우 느리다는 약점이 있었습니다.&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$가 수억 개의 관계식 중에서 「단 1번」만 등장했다고 가정해봅시다. 우리가 목표로 하는 것은 「모든 소수의 지수를 짝수(2의 배수)로 만드는 것」이므로, 1번만 등장하는 소수는 절대 짝수로 만들 수 없습니다.
따라서 그 소수를 포함하는 관계식은 「쓸모없는 쓰레기」로 간주되어 즉시 삭제(제거)됩니다. 이것이 연쇄적으로 일어나면서 수억 행이었던 데이터가 점점 줄어듭니다.&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> 이 채택되어 있습니다.
이는 행렬 $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]$에서는 소인수분해의 유일성이 성립하지 않기 때문에, 아이디얼을 사용하여 계산을 수행해 왔습니다. 행렬 계산으로 보장된 것은 &lt;strong>「아이디얼의 제곱」이 되는 것뿐이며, 「원소의 제곱($\gamma^2$)」이 되는 것은 보장되지 않은&lt;/strong> 것입니다.&lt;/p>
&lt;p>여기에는 「아이디얼 군의 장애물」과 「단수 군의 장애물」이라는 대수적 정수론의 거대한 벽이 가로막고 있습니다.
GNFS에서는 이 벽을 깨뜨리기 위해 &lt;strong>「이차 잉여 기호 (Quadratic Characters)」&lt;/strong> 라는 마법을 사용합니다.
Phase 4의 행렬에 미리 수십 개의 특별한 소아이디얼에 대한 이차 잉여(르장드르 기호)의 열을 몰래 추가해 두는 것입니다. 이로 인해 찾아낸 집합 $S$는 압도적인 확률로 장애물을 통과하여 무사히 「진정한 원소의 제곱 $\gamma^2$」을 형성해 줍니다.&lt;/p>
&lt;p>$\gamma$를 구하는 작업(대수적 제곱근)은 Montgomery 법 등의 매우 복잡한 알고리즘을 사용하여 계산됩니다.&lt;/p>
&lt;p>그리고 마침내 대수 측의 제곱근 $\gamma$를, 환 준동형 사상 $\phi$를 통해 현실 세계로 워프($x$에 $m$ 대입)시켜 $Y$를 얻습니다.
유리 측의 $V$를 그대로 $X$로 두면, 마침내 쫓고 쫓던 절대 등식이 완성됩니다.&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>남은 것은 $\gcd(X-Y, N)$을 계산하는 것뿐입니다. 0.001초의 처리가 순식간에 지나가고 비자명한 인수가 화면에 인쇄되는 순간, 난공불락을 자랑하던 RSA 암호는 완전히 붕괴됩니다.&lt;/p>
&lt;hr>
&lt;h2 id="맺음말">맺음말
&lt;/h2>&lt;p>GNFS는 단순한 프로그래밍 테크닉이 아닙니다.
추상대수학, 환론, 아이디얼 군과 같은 「순수 수학의 심연」을 슈퍼컴퓨터의 분산 아키텍처나 캐시 최적화와 같은 「극한의 엔지니어링」으로 굴복시킨 인류 지성의 결정체입니다.&lt;/p>
&lt;p>우리가 무심코 전송하고 있는 채팅이나 신용카드 정보는 이러한 천문학적인 수학의 공방 위에서 지켜지고 있는 것입니다.&lt;/p>
&lt;p>이 C++ 프레임워크를 통해 최첨단 암호 해독 알고리즘의 이면에 있는 「수학과 컴퓨터의 로망」을 느껴보시기 바랍니다.&lt;/p></description></item><item><title>일반 수체 체(GNFS)의 진정한 수학적 구조</title><link>http://kenji.blog/ko/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/ko/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="제1단계-세계를-연결하는-준동형-사상homomorphism">제1단계: 세계를 연결하는 「준동형 사상(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="제2단계-소인수분해의-붕괴와-아이디얼ideal의-탄생">제2단계: 소인수분해의 붕괴와 「아이디얼(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="제3단계-노름norm과-두-개의-체sieve">제3단계: 노름(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="제4단계-앞을-가로막는-두-개의-장애물과-아이디얼-류군">제4단계: 앞을 가로막는 두 개의 「장애물」과 아이디얼 류군
&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="제5단계-애들먼의-마법-이차-잉여-지표quadratic-characters">제5단계: 애들먼의 마법 「이차 잉여 지표(Quadratic Characters)」
&lt;/h2>&lt;p>아이디얼 류군의 장애물과 단수군의 장애물. 이 두 가지를 어떻게 뛰어넘을 것인가?
여기서 암호학자 레너드 애들먼(RSA의 &amp;ldquo;A&amp;rdquo;) 등이 도입한 천재적인 수법 &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/ko/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/ko/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에서의 쇼핑 등 모든 통신은 &amp;ldquo;암호&amp;quot;에 의해 보호받고 있습니다.
현재 전 세계에서 가장 많이 사용되는 암호의 대표가 &amp;ldquo;RSA 암호&amp;quot;입니다.&lt;/p>
&lt;p>RSA 암호 방어의 핵심은 매우 간단합니다. 그것은 &lt;strong>&amp;ldquo;거대한 수의 소인수분해는 컴퓨터로도 풀 수 없다&amp;rdquo;&lt;/strong> 는 수학적 성질을 이용하고 있다는 것입니다.
예를 들어 &amp;ldquo;15&amp;quot;라면 &amp;ldquo;3 × 5&amp;quot;라고 바로 알 수 있지만, 이것이 &amp;ldquo;270자리 숫자&amp;quot;가 되는 순간 전 세계의 슈퍼컴퓨터를 모두 모아도 푸는 데 수억 년이 걸리고 맙니다.&lt;/p>
&lt;p>하지만 수학자들도 가만히 있지는 않습니다. 이 철벽같은 암호를 깨기 위해 인류는 &lt;strong>&amp;ldquo;일반 수체 체(GNFS: General Number Field Sieve)&amp;rdquo;&lt;/strong> 라는 마법 같은 알고리즘(계산 절차)을 만들어 냈습니다.&lt;/p>
&lt;p>이 글에서는 전문 용어를 전혀 사용하지 않고, &lt;strong>중학교에서 배우는 수학(소인수분해, 문자식, 최대공약수)&lt;/strong> 지식만으로 이 &amp;ldquo;인류 최강의 알고리즘&amp;quot;이 암호를 깨는 원리를 단계별로 완전 해설합니다!&lt;/p>
&lt;hr>
&lt;h2 id="제1장-암호-해독의-목표는-중학교-3학년-공식">제1장: 암호 해독의 목표는 &amp;ldquo;중학교 3학년 공식&amp;rdquo;
&lt;/h2>&lt;p>거대한 소인수분해에 맞서기 위한 최대의 필살기. 그것은 중학교 3학년 때 배우는 이 공식입니다.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>$X^2 - Y^2 = (X + Y)(X - Y)$&lt;/strong>&lt;/p>
&lt;/blockquote>
&lt;p>&amp;ldquo;어, 이런 기초적인 공식으로 암호를 깰 수 있다고?&amp;ldquo;라고 생각할지 모릅니다. 하지만 이것이야말로 모든 것을 밝혀낼 마스터키입니다.&lt;/p>
&lt;p>암호를 깨기 위한 최대의 목표는 거대한 수 $N$에 대해,
&lt;strong>&amp;quot;$X^2$과 $Y^2$을 $N$으로 나눈 나머지가 같아지는 수($X$와 $Y$)&amp;rdquo;&lt;/strong> 를 찾는 것입니다.&lt;/p>
&lt;h3 id="왜-나머지가-같으면-암호가-풀리는-걸까">왜 &amp;ldquo;나머지가 같으면&amp;rdquo; 암호가 풀리는 걸까?
&lt;/h3>&lt;p>어떤 두 수 $X^2$과 $Y^2$의 &amp;ldquo;$N$으로 나눈 나머지가 같다&amp;quot;고 가정해 봅시다.
나머지가 같다는 것은 &lt;strong>뺄셈을 한 &amp;ldquo;$X^2 - Y^2$&amp;ldquo;는 반드시 $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>&amp;quot;$p$는 $(X - Y)$의 방으로&amp;rdquo;, &amp;ldquo;$q$는 $(X + Y)$의 방으로&amp;rdquo;&lt;/strong> 서로 다른 방으로 나뉘어 들어갈 확률이 수학적으로 ** 50%(2분의 1)** 나 되는 것입니다.&lt;/p>
&lt;p>소수 $p$만이 $(X - Y)$의 방에 들어간 상태에서 $(X - Y)$와 $N$의 &lt;strong>&amp;ldquo;최대공약수(공통되는 가장 큰 부품)&amp;rdquo;&lt;/strong> 를 계산해 봅시다.&lt;/p>
&lt;ul>
&lt;li>$(X - Y)$의 내용물 = $p \times$ 어떤 수&lt;/li>
&lt;li>$N$의 내용물 = $p \times q$
공통된 부품은 &lt;strong>&amp;quot;$p$&amp;rdquo;&lt;/strong> 밖에 없죠!&lt;/li>
&lt;/ul>
&lt;p>즉, 최대공약수를 계산하는 순간 숨어 있던 소수 $p$가 툭 떨어져 나와 암호가 완전히 해독되어 버리는 것입니다. (※최대공약수는 &amp;ldquo;유클리드 호제법&amp;quot;을 사용하면 스마트폰으로도 순식간에 계산할 수 있습니다)&lt;/p>
&lt;p>&lt;strong>【잠깐 칼럼: 왜 제곱일까? 세제곱이나 2배는 안 될까?】&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;$2X - 2Y$&amp;ldquo;라면 $2(X - Y)$가 되어 방이 하나밖에 없으므로 소수를 떼어놓을 수 없습니다. &amp;ldquo;$X^3 - Y^3$&amp;ldquo;라면 방의 크기가 불균형해져서 계산이 쓸데없이 무거워집니다. 소수를 두 개로 떼어놓기 위해서는 아름답게 두 개의 방으로 나뉘는 &amp;ldquo;제곱&amp;quot;이 가성비가 가장 좋습니다.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="제2장-x와-y를-어떻게-찾을까-소수-카드-모으기-퍼즐">제2장: X와 Y를 어떻게 찾을까? &amp;ldquo;소수 카드 모으기 퍼즐&amp;rdquo;
&lt;/h2>&lt;p>목표는 알았습니다. 하지만 &amp;ldquo;나머지가 같아지는 $X^2$과 $Y^2$&amp;ldquo;를 무턱대고 찾아봤자 우주의 수명이 다할 때까지 찾을 수 없습니다.
그래서 수학자들은 &lt;strong>&amp;ldquo;소수 카드 모으기 퍼즐&amp;rdquo;&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>&amp;ldquo;2, 3, 5, 7 등의 작은 소수로만 이루어진 $W$&amp;rdquo;&lt;/strong> 가 나왔을 때만 그 식을 &amp;ldquo;당첨 카드&amp;quot;로 남기고, 큰 소수가 섞여 있으면 버립니다.
강에서 큰 돌을 체로 걸러 버리고 사금만을 모으는 것과 같은 작업입니다.&lt;/p>
&lt;h3 id="step-2-모두-짝수-개로-만드는-퍼즐">Step 2: 모두 &amp;ldquo;짝수 개&amp;quot;로 만드는 퍼즐
&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>&amp;quot;$2^4 \times 3^2 \times 5^2$&amp;rdquo;&lt;/strong> 가 됩니다.&lt;/p>
&lt;p>놀랍게도 소수의 개수가 &amp;ldquo;4개, 2개, 2개&amp;quot;로 &lt;strong>모두 짝수 개&lt;/strong> 가 되었습니다!
모두 짝수 개라는 것은 전체를 절반의 개수로 만들면 &amp;ldquo;어떤 수의 제곱&amp;quot;이 된다는 것입니다.
즉, $(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>
이라는 기다리고 기다리던 &amp;ldquo;$X^2 = Y^2$&amp;ldquo;의 쌍이 완성된 것입니다!&lt;/p>
&lt;p>컴퓨터에 있어 소수의 개수를 &amp;ldquo;짝수인가 홀수인가(0인가 1인가)&amp;ldquo;로 계산하는 퍼즐은 매우 능숙하므로, 이 방법이라면 빠르게 $X$와 $Y$를 찾을 수 있습니다.&lt;/p>
&lt;hr>
&lt;h2 id="제3장-앞을-가로막는-절망의-벽">제3장: 앞을 가로막는 절망의 벽
&lt;/h2>&lt;p>이제 어떤 암호라도 깰 수 있다!&amp;hellip; 라고 생각했지만, 큰 문제가 발생합니다.
암호 숫자 $N$이 &amp;ldquo;100자리&amp;rdquo; 정도까지라면 이 방법(이차 체라고 합니다)으로 풀 수 있지만, $N$이 &amp;ldquo;200자리, 300자리&amp;quot;가 되면 계산 도중에 나오는 $W$가 너무 커집니다.&lt;/p>
&lt;p>숫자가 너무 커지면 &amp;ldquo;작은 소수로만 이루어진 수(사금)&amp;ldquo;가 뚝 끊기고 맙니다. 사막에서 콘택트렌즈를 찾는 것보다 어려워져서, 퍼즐을 풀기 위한 카드가 전혀 모이지 않게 되는 것입니다.&lt;/p>
&lt;p>여기서 마침내 인류의 최종 병기 &lt;strong>&amp;ldquo;일반 수체 체(GNFS)&amp;rdquo;&lt;/strong> 가 등장합니다.&lt;/p>
&lt;hr>
&lt;h2 id="제4장-인류-최강의-아이디어-두-개의-세계-만들기">제4장: 인류 최강의 아이디어 &amp;ldquo;두 개의 세계&amp;rdquo; 만들기
&lt;/h2>&lt;p>GNFS의 천재적인 발상은 &lt;strong>&amp;ldquo;현실 세계에서만 계산하니까 숫자가 커진다. 그렇다면 다항식(문자식)을 사용한 &amp;lsquo;이면의 세계&amp;rsquo;를 만들어서 계산의 무게를 둘로 분산시키자&amp;rdquo;&lt;/strong> 라는 것입니다.&lt;/p>
&lt;h3 id="문자식의-마법">문자식의 마법
&lt;/h3>&lt;p>GNFS는 거대한 수 $N$을 베이스가 되는 수 $m$을 사용하여 문자식으로 변환합니다.
예를 들어 $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>&amp;ldquo;문자 $x$에 $m$(위의 예라면 4)을 대입하면 언제든지 현실의 수 $N$으로 워프해서 돌아올 수 있다&amp;rdquo;&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>&amp;ldquo;현실 세계에서도, 문자식 세계에서도 양쪽 모두 &amp;lsquo;작은 소수로만 이루어져 있는(사금)&amp;rsquo;&amp;rdquo;&lt;/strong> 기적의 쌍 $(a, b)$만을 체로 걸러내어 모읍니다. 이것이 &amp;ldquo;수체 체&amp;quot;라는 이름의 유래입니다.&lt;/p>
&lt;h3 id="마침내-암호가-깨지는-순간">마침내 암호가 깨지는 순간
&lt;/h3>&lt;p>양쪽 세계에서 수천만 장의 &amp;ldquo;사금 카드&amp;quot;가 모이면 슈퍼컴퓨터의 거대한 행렬 계산을 사용하여, 제2장에서 했던 &amp;ldquo;소수의 개수가 모두 짝수가 되는 조합&amp;quot;을 찾아냅니다.&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>마지막으로 문자식의 $Y(x)$의 $x$에 $m$을 대입하여 현실 세계로 워프시켜 합류시킵니다.
그러면 수학의 마법처럼 &lt;strong>&amp;quot;$X^2$과 $Y^2$의 나머지가 같아진다&amp;rdquo;&lt;/strong> 는 상태가 엄밀하게 완성되는 것입니다!&lt;/p>
&lt;p>이제 제1장에서와 같이 $X - Y$와 $N$의 최대공약수를 계산하면, 난공불락의 RSA 암호는 소리를 내며 무너져 내리고 비밀 소수가 모습을 드러냅니다.&lt;/p>
&lt;hr>
&lt;h2 id="맺음말-수학은-끝나지-않는다">맺음말: 수학은 끝나지 않는다
&lt;/h2>&lt;p>&amp;ldquo;좋아, GNFS를 사용하면 어떤 암호라도 깰 수 있겠구나!&amp;ldquo;라고 생각했을지도 모릅니다.
하지만 RSA 암호도 만만치 않습니다. 현재 인터넷에서 사용되는 것은 &amp;ldquo;RSA-2048(약 617자리)&amp;ldquo;이라는 괴물 같은 거대 수입니다.&lt;/p>
&lt;p>GNFS가 아무리 인류 최강의 알고리즘이라 하더라도, 270자리(RSA-270)를 푸는 데만도 전 세계의 컴퓨터를 연결해도 수천 년, 수만 년이 걸린다고 합니다. 지금으로서는 우리의 LINE이나 은행 데이터는 안전합니다.&lt;/p>
&lt;p>하지만 만약 &lt;strong>&amp;ldquo;어떤 거대한 수라도 순식간에 $X$와 $Y$를 찾는 마법&amp;rdquo;&lt;/strong> 이 나타난다면 어떻게 될까요?
사실 거기에 가장 가까운 존재가 현재 개발 중인 &lt;strong>&amp;ldquo;양자 컴퓨터(쇼어의 알고리즘)&amp;rdquo;&lt;/strong> 입니다. 양자 역학의 파동 성질을 사용하면 귀찮은 카드 모으기 퍼즐을 무시하고 단번에 답을 뽑아낼 수 있다고 수학적으로 증명되어 있습니다.&lt;/p>
&lt;p>암호를 만드는 사람(방어)과 암호를 깨는 알고리즘을 만드는 사람(공격)의 끝없는 지혜 겨루기.
중학교에서 배우는 &amp;ldquo;소인수분해&amp;quot;나 &amp;ldquo;문자식&amp;quot;이 사실은 세계 보안의 최전선에서 치열하게 싸우고 있는 무기라는 것을 알면 수학 수업이 조금은 더 재미있어 보이지 않나요?&lt;/p>
&lt;p>미래의 최강 알고리즘을 발견하는 것은 이 글을 읽고 있는 당신일지도 모릅니다!&lt;/p>
&lt;hr>
&lt;p>&lt;em>(※본 기사는 암호 해독의 수학적 매력을 중학생용으로 개념화한 것입니다. 실제 GNFS는 대수체의 이데알 류군이나 준동형 사상 등의 고도화된 대학 수학을 이용하여 엄밀하게 계산됩니다)&lt;/em>&lt;/p></description></item><item><title>[수학적 고찰] 왜 암호 해독 알고리즘 'GNFS'는 양자 컴퓨터 시대의 Shor 알고리즘에 패배하는가?</title><link>http://kenji.blog/ko/p/gnfs-to-shors-algorithm-math-deepdive/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://kenji.blog/ko/p/gnfs-to-shors-algorithm-math-deepdive/</guid><description>&lt;img src="http://kenji.blog/p/gnfs-to-shors-algorithm-math-deepdive/quantum_vs_gnfs_eyecatch_1788616101508.jpg" alt="Featured image of post [수학적 고찰] 왜 암호 해독 알고리즘 'GNFS'는 양자 컴퓨터 시대의 Shor 알고리즘에 패배하는가?" />&lt;p>현대 인터넷 사회의 정보 보안은 RSA 암호를 비롯한 공개키 암호 방식에 의해 보호받고 있습니다. RSA 암호의 안전성 근거는, &lt;strong>&amp;lsquo;거대한 합성수의 소인수분해는 계산량적으로 극히 어렵다&amp;rsquo;&lt;/strong> 는 사실에 의존하고 있습니다.&lt;/p>
&lt;p>이 글에서는 고전 컴퓨터에서 최강의 소인수분해 알고리즘인 &lt;strong>&amp;lsquo;일반 수체 체(General Number Field Sieve, GNFS)&amp;rsquo;&lt;/strong> 의 수학적 메커니즘을 파헤치고, 그것이 왜 피터 쇼어(Peter Shor)가 발견한 &lt;strong>&amp;lsquo;쇼어 알고리즘(Shor&amp;rsquo;s Algorithm)&amp;rsquo;&lt;/strong> 에 의해 완전히 무너지는지, 그 패러다임 시프트를 수식과 개념도를 이용해 철저히 깊이 있게 다룹니다.&lt;/p>
&lt;hr>
&lt;h2 id="1-고전-계산에서의-소인수분해-접근법-페르마의-소인수분해법으로부터의-발전">1. 고전 계산에서의 소인수분해 접근법: 페르마의 소인수분해법으로부터의 발전
&lt;/h2>&lt;p>소인수분해 문제란, 주어진 합성수 $N$에 대하여 $N = p \times q$가 되는 소수 $p, q$를 찾는 문제입니다.&lt;/p>
&lt;p>기본적인 아이디어는 다음 합동식을 만족하는 자명하지 않은 $x, y$를 찾는 것으로 귀결됩니다.&lt;/p>
$$ x^2 \equiv y^2 \pmod N $$
&lt;p>이를 변형하면,&lt;/p>
$$ x^2 - y^2 \equiv 0 \pmod N $$
$$ (x - y)(x + y) \equiv 0 \pmod N $$
&lt;p>여기서 $x \not\equiv \pm y \pmod N$ 이라면, $\gcd(x-y, N)$ 또는 $\gcd(x+y, N)$을 계산함으로써 $N$의 자명하지 않은 인수를 얻을 수 있습니다. 이 사실이 GNFS 등 근대적인 소인수분해 알고리즘의 기초가 됩니다.&lt;/p>
&lt;hr>
&lt;h2 id="2-고전-최강의-알고리즘-일반-수체-체gnfs의-심연">2. 고전 최강의 알고리즘: &amp;lsquo;일반 수체 체(GNFS)&amp;lsquo;의 심연
&lt;/h2>&lt;p>&lt;strong>&amp;lsquo;GNFS&amp;rsquo;&lt;/strong> 는 오늘날 알려진 고전 컴퓨터용 소인수분해 알고리즘 중에서 가장 빠른 것입니다. 그 시간 복잡도는 준지수 함수적(Sub-exponential)인 시간을 필요로 합니다.&lt;/p>
&lt;h3 id="gnfs의-계산량">GNFS의 계산량
&lt;/h3>&lt;p>수 $N$의 자릿수를 $b = \log_2 N$이라고 할 때, GNFS의 계산량은 다음과 같이 표현됩니다.&lt;/p>
$$ O\left( \exp \left( \left(\frac{64}{9} b\right)^{1/3} (\log b)^{2/3} \right) \right) $$
&lt;p>이 식에서 알 수 있듯이, 계산량은 다항식 시간이 아니라 지수 함수보다는 약간 느린 &lt;strong>&amp;lsquo;준지수 시간&amp;rsquo;&lt;/strong> 이 됩니다. 그럼에도 자릿수가 늘어나면 계산 시간은 천문학적으로 증대합니다.&lt;/p>
&lt;h3 id="gnfs의-수학적-메커니즘">GNFS의 수학적 메커니즘
&lt;/h3>&lt;p>GNFS는 크게 4개의 단계로 구성됩니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>다항식 선택 (Polynomial Selection)&lt;/strong>&lt;/li>
&lt;li>&lt;strong>체질 (Sieving)&lt;/strong>&lt;/li>
&lt;li>&lt;strong>행렬의 간소화 (Matrix Reduction)&lt;/strong>&lt;/li>
&lt;li>&lt;strong>제곱근 계산 (Square Root)&lt;/strong>&lt;/li>
&lt;/ol>
&lt;h4 id="21-다항식-선택과-대수체">2.1. 다항식 선택과 대수체
&lt;/h4>&lt;p>먼저, 정수를 계수로 하는 기약 다항식 $f(x)$와 $g(x)$를 선택합니다. 이들은 공통의 근 $m$을 modulo $N$으로 가지도록 설정됩니다. 즉,&lt;/p>
$$ f(m) \equiv 0 \pmod N $$
$$ g(m) \equiv 0 \pmod N $$
&lt;p>일반적으로 $g(x)$는 일차 다항식 $g(x) = x - m$으로 선택됩니다. $f(x)$의 근을 $\alpha$라고 두면, $\mathbb{Q}(\alpha)$라는 &lt;strong>&amp;lsquo;대수체&amp;rsquo;&lt;/strong>(Number Field)가 구성됩니다. $\mathbb{Q}(\alpha)$의 환에서의 연산과 일반적인 정수환 $\mathbb{Z}$의 연산을 준동형 사상 $\phi: \alpha \mapsto m$을 통해 비교합니다.&lt;/p>
&lt;h4 id="22-체질-sieving">2.2. 체질 (Sieving)
&lt;/h4>&lt;p>다음으로 서로소인 정수 쌍 $(a, b)$를 대량으로 탐색합니다. 목적은 다음 두 값이 각각 &lt;strong>&amp;lsquo;B-smooth&amp;rsquo;&lt;/strong>(비교적 작은 소인수로만 구성됨)가 되는 쌍을 찾는 것입니다.&lt;/p>
&lt;ol>
&lt;li>$a - bm$ (정수환 위에서의 값)&lt;/li>
&lt;li>$b^d f(a/b)$ (대수체 위에서의 노름 $N(a - b\alpha)$에 대응)&lt;/li>
&lt;/ol>
&lt;p>여기서 &lt;strong>&amp;lsquo;체&amp;rsquo;&lt;/strong>(Sieve)라고 불리는 고속 탐색 기법이 사용됩니다. 이를 통해 방대한 후보 중에서 조건을 만족하는 $(a, b)$ 쌍을 효율적으로 추출합니다.&lt;/p>
&lt;h4 id="23-행렬의-간소화-linear-algebra-over-gf2">2.3. 행렬의 간소화 (Linear Algebra over GF(2))
&lt;/h4>&lt;p>수집한 쌍 $(a, b)$로부터 지수 벡터를 구성하고, 거대한 희소 행렬의 왼쪽 영공간(Left Null Space)을 $\mathbb{F}_2$(요소가 0과 1뿐인 체) 위에서 구합니다.&lt;/p>
&lt;p>관계식 $ \prod (a_i - b_i m) $ 와 $ \prod (a_i - b_i \alpha) $ 가 각각 제곱원이 되도록 벡터 $v$를 해로 찾습니다. 이는,&lt;/p>
$$ M \mathbf{x} \equiv \mathbf{0} \pmod 2 $$
&lt;p>라는 선형 방정식계를 푸는 것과 다름없습니다. 여기서 블록 란초스 알고리즘(Block Lanczos Algorithm)이나 블록 위데만 알고리즘(Block Wiedemann Algorithm) 등의 고도화된 수치 계산 알고리즘이 활용됩니다.&lt;/p>
&lt;h4 id="24-제곱근-계산">2.4. 제곱근 계산
&lt;/h4>&lt;p>마지막으로 대수체와 정수환 양쪽에서 제곱근을 취하고, $x^2 \equiv y^2 \pmod N$이라는 관계식을 도출해 냅니다. 그리고 $\gcd(x-y, N)$을 계산하여 인수를 얻습니다.&lt;/p>
&lt;hr>
&lt;h2 id="3-양자-계산에-의한-혁신-쇼어-알고리즘">3. 양자 계산에 의한 혁신: &amp;lsquo;쇼어 알고리즘&amp;rsquo;
&lt;/h2>&lt;p>GNFS가 준지수 함수적인 시간을 필요로 하는 반면, 1994년 피터 쇼어가 발표한 &lt;strong>&amp;lsquo;쇼어 알고리즘&amp;rsquo;&lt;/strong> 은 양자 컴퓨터를 사용하여 이 문제를 &lt;strong>&amp;lsquo;다항식 시간&amp;rsquo;&lt;/strong> 에 풀 수 있습니다.&lt;/p>
&lt;h3 id="쇼어-알고리즘의-계산량">쇼어 알고리즘의 계산량
&lt;/h3>&lt;p>양자 비트 수를 $O(\log N)$이라고 할 때, 시간 복잡도는 다음과 같습니다.&lt;/p>
$$ O((\log N)^3) $$
&lt;p>이는 비트 수에 대해 지수 함수적인 폭발을 일으키지 않음을 의미합니다. &lt;strong>&amp;lsquo;고전 계산&amp;rsquo;&lt;/strong> 의 계산량이 우주의 수명을 초과할 만한 거대한 합성수라도, &lt;strong>&amp;lsquo;양자 계산&amp;rsquo;&lt;/strong> 에서는 몇 시간～며칠 만에 해독 가능해진다는 경이로운 결과입니다.&lt;/p>
&lt;h3 id="쇼어-알고리즘의-전체상-주기-찾기-문제로의-귀결">쇼어 알고리즘의 전체상: 주기 찾기 문제로의 귀결
&lt;/h3>&lt;p>쇼어 알고리즘은 소인수분해 문제를 &lt;strong>&amp;lsquo;주기 찾기 문제&amp;rsquo;&lt;/strong> 로 교묘하게 귀결시킵니다.&lt;/p>
&lt;ol>
&lt;li>$N$과 서로소인 무작위 정수 $a$를 선택합니다 ($1 &lt; a &lt; N$).&lt;/li>
&lt;li>함수 $f(x) = a^x \bmod N$을 정의합니다.&lt;/li>
&lt;li>$f(x)$의 주기 $r$, 즉 $a^r \equiv 1 \pmod N$이 되는 최소의 양의 정수 $r$을 찾습니다.&lt;/li>
&lt;li>$r$이 짝수이면, $a^{r/2} \not\equiv -1 \pmod N$인지 확인하고, $\gcd(a^{r/2} \pm 1, N)$을 계산하여 소인수를 얻습니다.&lt;/li>
&lt;/ol>
&lt;p>이 3단계의 &lt;strong>&amp;lsquo;주기 $r$의 발견&amp;rsquo;&lt;/strong> 이야말로 고전 컴퓨터에서는 지수 함수적 시간을 필요로 하는 병목 현상이지만, 양자 컴퓨터는 &lt;strong>&amp;lsquo;양자 중첩&amp;rsquo;&lt;/strong> 과 &lt;strong>&amp;lsquo;양자 푸리에 변환&amp;rsquo;&lt;/strong>(QFT)을 사용하여 이를 순식간에 해결합니다.&lt;/p>
&lt;hr>
&lt;h2 id="4-양자-푸리에-변환qft과-주기의-추출">4. 양자 푸리에 변환(QFT)과 주기의 추출
&lt;/h2>&lt;p>쇼어 알고리즘의 핵심인 양자 상태의 조작에 대해 수식으로 자세히 살펴보겠습니다.&lt;/p>
&lt;h3 id="41-양자-중첩의-생성">4.1. 양자 중첩의 생성
&lt;/h3>&lt;p>먼저 2개의 양자 레지스터를 준비합니다. 레지스터 1은 입력 $x$의 중첩 상태를 유지하고, 레지스터 2는 함수의 계산 결과 $f(x)$를 유지합니다. 초기 상태 $|0\rangle |0\rangle$에 아다마르 변환(Hadamard Transform)을 적용하여 가능한 모든 $x$의 중첩을 만들어 냅니다.&lt;/p>
$$ |\psi_1\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle |0\rangle $$
&lt;p>
(여기서 $Q$는 $N^2 \le Q &lt; 2N^2$을 만족하는 2의 거듭제곱)&lt;/p>
&lt;p>다음으로 양자 오라클 $U_f$를 사용하여 $f(x) = a^x \bmod N$을 계산하고 레지스터 2에 저장합니다.&lt;/p>
$$ |\psi_2\rangle = U_f |\psi_1\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle |a^x \bmod N\rangle $$
&lt;p>여기서 레지스터 2를 측정했다고 가정해 봅시다 (실제로 측정하지 않아도 수학적 구조는 동일합니다). 어떤 값 $y = a^{x_0} \bmod N$이 관측되었다고 하면, 레지스터 1의 상태는 $f(x) = y$가 되는 모든 $x$의 중첩으로 수축합니다. 주기를 $r$이라고 하면, 그러한 $x$는 $x_0, x_0 + r, x_0 + 2r, \dots$가 됩니다.&lt;/p>
$$ |\psi_3\rangle = \frac{1}{\sqrt{M}} \sum_{k=0}^{M-1} |x_0 + kr\rangle $$
&lt;p>
(여기서 $M \approx Q/r$은 항의 수)&lt;/p>
&lt;p>이 상태는 주기 $r$의 정보를 내포하고 있지만, 직접 측정해도 무작위한 $x_0 + kr$이 얻어질 뿐, 주기 $r$은 알 수 없습니다. 여기서 QFT가 등장합니다.&lt;/p>
&lt;h3 id="42-양자-푸리에-변환-quantum-fourier-transform-의-적용">4.2. 양자 푸리에 변환 (Quantum Fourier Transform) 의 적용
&lt;/h3>&lt;p>QFT는 양자 상태의 진폭에 대해 이산 푸리에 변환을 수행하는 조작입니다. 상태 $|x\rangle$에 대한 QFT의 작용은 다음과 같이 정의됩니다.&lt;/p>
$$ \text{QFT} |x\rangle = \frac{1}{\sqrt{Q}} \sum_{y=0}^{Q-1} e^{2\pi i \frac{xy}{Q}} |y\rangle $$
&lt;p>이것을 $|\psi_3\rangle$에 적용하면, 위상의 간섭(양자 간섭)이 일어납니다.&lt;/p>
$$ |\psi_4\rangle = \text{QFT} |\psi_3\rangle = \frac{1}{\sqrt{MQ}} \sum_{y=0}^{Q-1} \sum_{k=0}^{M-1} e^{2\pi i \frac{(x_0 + kr)y}{Q}} |y\rangle $$
&lt;p>이 식의 합을 전개하면,&lt;/p>
$$ \sum_{k=0}^{M-1} e^{2\pi i \frac{kry}{Q}} $$
&lt;p>라는 부분이 나타납니다. 이 기하급수의 합은 $ry/Q$가 정수에 가까울 때에만 보강 간섭(Constructive Interference)이 일어나고, 그 외의 경우에는 상쇄 간섭(Destructive Interference)이 일어납니다.&lt;/p>
&lt;p>따라서 높은 확률로 측정되는 상태 $|y\rangle$는,&lt;/p>
$$ \frac{y}{Q} \approx \frac{c}{r} $$
&lt;p>이라는 조건을 만족하는 정수 $y$가 됩니다 ($c$는 어떤 정수).&lt;/p>
&lt;h3 id="43-연분수-전개에-의한-주기-특정">4.3. 연분수 전개에 의한 주기 특정
&lt;/h3>&lt;p>측정을 통해 $y$를 얻은 후, 고전 컴퓨터를 이용하여 $y/Q$를 &lt;strong>&amp;lsquo;연분수 전개&amp;rsquo;&lt;/strong>(Continued Fraction Expansion)합니다. 이를 통해 $y/Q$의 근사 분수 $c/r$을 계산하고, 분모로부터 주기 $r$의 후보를 고효율로 추출할 수 있습니다.&lt;/p>
&lt;hr>
&lt;h2 id="5-개념-모델의-비교와-패러다임-시프트">5. 개념 모델의 비교와 패러다임 시프트
&lt;/h2>&lt;p>GNFS와 쇼어 알고리즘의 차이를 직관적으로 이해하기 위해, Mermaid 기법을 사용한 개념도를 제시합니다.&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;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">graph TD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[초기 상태: 0...0] --&amp;gt; B[아다마르 변환으로 모든 상태의 중첩]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C[모듈러 거듭제곱 연산 a^x mod N]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|양자 얽힘| D[주기성을 가지는 상태로의 수축]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> D --&amp;gt; E[양자 푸리에 변환 QFT]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> E --&amp;gt;|간섭에 의한 확률 증폭| F[측정: y를 얻음]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> F --&amp;gt; G[고전 처리: 연분수 전개]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt; H[주기 r 발견]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H --&amp;gt; I[N의 소인수 산출]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> style A fill:#f9f,stroke:#333,stroke-width:2px
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> style E fill:#bbf,stroke:#333,stroke-width:2px
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> style I fill:#bfb,stroke:#333,stroke-width:2px
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="패러다임-시프트의-본질">패러다임 시프트의 본질
&lt;/h3>&lt;p>GNFS는 &lt;strong>&amp;lsquo;수학적인 공간(대수체) 안에서 관계식을 탐색한다&amp;rsquo;&lt;/strong> 라는 접근 방식을 취합니다. 하지만 탐색 공간은 자릿수에 대해 지수 함수적으로 확대되기 때문에, 고전 컴퓨터의 계산 능력(병렬화를 포함하더라도)으로는 키 길이가 2048비트 등을 초과하면 사실상 해독이 불가능해집니다.&lt;/p>
&lt;p>반면, 쇼어 알고리즘은 &lt;strong>&amp;lsquo;양자 간섭에 의한 파동의 성질&amp;rsquo;&lt;/strong> 을 이용합니다. 중첩 상태에 있는 모든 계산 경로를 동시에 평가하고, QFT에 의해 불필요한 답을 상쇄(약화)시키고, 정답이 되는 주기의 확률 진폭만을 증폭(강화)시킵니다. 이를 통해 공간을 탐색하는 것이 아니라, &lt;strong>&amp;lsquo;정답 그 자체를 떠오르게 한다&amp;rsquo;&lt;/strong> 는 전혀 다른 차원의 접근 방식을 실현하고 있는 것입니다.&lt;/p>
&lt;h2 id="6-요약">6. 요약
&lt;/h2>&lt;p>이 글에서는 고전 한계의 끝판왕인 &lt;strong>&amp;lsquo;GNFS&amp;rsquo;&lt;/strong> 와 양자 계산의 힘을 보여주는 &lt;strong>&amp;lsquo;쇼어 알고리즘&amp;rsquo;&lt;/strong> 에 대해, 각각의 수학적 배경과 알고리즘의 구조를 깊이 비교했습니다.&lt;/p>
&lt;p>GNFS가 다항식의 선택이나 거대한 행렬의 계산 등 수학적 기교를 부려 준지수 시간으로 계산량을 끌어내린 반면, 쇼어 알고리즘은 양자 역학의 기본 원리인 중첩과 간섭을 수학적 도구(QFT)와 융합시켜 단숨에 다항식 시간으로의 혁신을 이루어냈습니다.&lt;/p>
&lt;p>현재 시점에서는 실용적인 규모(수천 양자 비트)로 쇼어 알고리즘을 실행할 수 있는 결함 허용 양자 컴퓨터(FTQC)는 존재하지 않습니다. 하지만 이 수학적·이론적인 패러다임 시프트의 존재야말로, 현재 전 세계적으로 양자 내성 암호(PQC: Post-Quantum Cryptography)로의 이행이 시급해진 가장 큰 이유입니다.&lt;/p></description></item></channel></rss>