<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RSA on kenji.blog</title><link>http://kenji.blog/ko/tags/rsa/</link><description>Recent content in RSA on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ko</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 22:09:21 +0900</lastBuildDate><atom:link href="http://kenji.blog/ko/tags/rsa/index.xml" rel="self" type="application/rss+xml"/><item><title>양자 컴퓨터는 정말 RSA 암호를 파괴할 것인가? ~쇼어의 알고리즘과 현재의 도달점~</title><link>http://kenji.blog/ko/p/shors-algorithm-and-rsa-breaking/</link><pubDate>Sat, 05 Sep 2026 22:09:21 +0900</pubDate><guid>http://kenji.blog/ko/p/shors-algorithm-and-rsa-breaking/</guid><description>&lt;img src="http://kenji.blog/p/shors-algorithm-and-rsa-breaking/quantum_breaking_rsa_1788613722990.jpg" alt="Featured image of post 양자 컴퓨터는 정말 RSA 암호를 파괴할 것인가? ~쇼어의 알고리즘과 현재의 도달점~" />&lt;h2 id="시작하며-암호-기술과-양자-컴퓨터의-교차점">시작하며: 암호 기술과 양자 컴퓨터의 교차점
&lt;/h2>&lt;p>현대 인터넷 사회에서 통신의 비밀을 지키기 위한 기반이 되고 있는 것이 &amp;lsquo;공개키 암호&amp;rsquo;입니다. 그 중에서도 대표적인 것이 1977년 Ron Rivest, Adi Shamir, Leonard Adleman 세 사람에 의해 개발된 &amp;lsquo;RSA 암호&amp;rsquo;입니다. 우리가 매일 이용하는 온라인 쇼핑 결제, 웹사이트 열람(HTTPS), 이메일 송수신에 이르기까지 RSA 암호는 인터넷 인프라의 심장부로서 기능하고 있습니다.&lt;/p>
&lt;p>그러나 &amp;lsquo;양자 컴퓨터&amp;rsquo;의 등장으로 인해 이러한 안전성이 근본부터 뒤집힐 가능성이 지적되고 있습니다. 미디어에서는 &amp;ldquo;양자 컴퓨터가 완성되면 전 세계의 비밀번호나 암호가 몇 초 만에 해독되어 버린다&amp;quot;는 등 선정적인 헤드라인이 장식되기도 합니다. 과연 그것은 사실일까요?&lt;/p>
&lt;p>이 글에서는 고전적인 암호 해독 기법인 GNFS(일반 수체 체)와 양자 컴퓨터를 이용한 암호 해독 알고리즘의 결정판인 &amp;lsquo;쇼어의 알고리즘(Shor&amp;rsquo;&amp;rsquo;s Algorithm)&amp;lsquo;의 구조를 깊이 파헤쳐 봅니다. 양자 푸리에 변환이나 주기 발견과 같은 고도의 개념을 알기 쉽게 해설하고, 현재의 NISQ(Noisy Intermediate-Scale Quantum) 시대에 있어서 양자 하드웨어의 현황과, 실제로 RSA-2048을 깨기 위해 필요한 난관들에 대해 상세히 검증해 보겠습니다.&lt;/p>
&lt;hr>
&lt;h2 id="rsa-암호의-근간-소인수-분해의-어려움">RSA 암호의 근간: 소인수 분해의 어려움
&lt;/h2>&lt;p>RSA 암호의 안전성은 수학에서의 매우 단순한 비대칭성에 의존하고 있습니다. 그것은 &amp;ldquo;두 개의 거대한 소수를 곱하는 것은 간단하지만, 그 곱한 결과(합성수)로부터 원래의 두 소수를 찾아내는(소인수 분해하는) 것은 극히 어렵다&amp;quot;는 사실입니다.&lt;/p>
&lt;p>예를 들어, $ p = 61 $, $ q = 53 $ 이라는 두 개의 소수가 있다고 가정해 봅시다. 이 곱셈 $ N = p \times q = 3233 $ 을 계산하는 것은 순식간입니다. 하지만 &amp;lsquo;3233&amp;rsquo;이라는 숫자만 주어지고 &amp;ldquo;이것은 어느 소수와 어느 소수의 곱셈인가?&amp;ldquo;를 푸는 것은 숫자가 커질수록 계산량이 폭발적으로 증가합니다.&lt;/p>
&lt;p>현재 주류가 되고 있는 RSA-2048에서는 키 길이가 2048비트, 즉 10진수로 약 617자리에 달하는 거대한 합성수 $ N $ 이 사용되고 있습니다. 이 $ N $ 을 소인수 분해할 수 있다면, 암호는 해독된 거나 다름없게 됩니다.&lt;/p>
&lt;h3 id="고전-컴퓨터의-도전-gnfs-일반-수체-체">고전 컴퓨터의 도전: GNFS (일반 수체 체)
&lt;/h3>&lt;p>소인수 분해 문제를 풀기 위해 수학자나 암호학자들은 오랜 세월에 걸쳐 다양한 알고리즘을 개발해 왔습니다. 그 중에서도 고전 컴퓨터에서 현재 가장 빠르다고 여겨지는 것이 &lt;strong>일반 수체 체(GNFS: General Number Field Sieve)&lt;/strong> 입니다.&lt;/p>
&lt;p>GNFS는 거대한 수 $ N $ 을 소인수 분해하기 위해, 정수환에서의 계산을 더 추상적인 대수체(Number Field)로 확장하여 해석하는 기법입니다. 대략적인 흐름은 다음과 같습니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>다항식의 선택&lt;/strong> : $ N $ 을 근으로 가지는, 적절한 차수와 계수를 가진 다항식 $ f(x) $ 를 찾습니다.&lt;/li>
&lt;li>&lt;strong>데이터 수집(체질)&lt;/strong> : 유리수체 및 대수체 위에서, 작은 소수(매끄러운 수, Smooth numbers)로 분해될 수 있는 수의 쌍을 대량으로 탐색합니다. 이 과정이 &amp;lsquo;체질(Sieving)&amp;lsquo;이라 불리며 가장 많은 시간을 필요로 하는 부분입니다.&lt;/li>
&lt;li>&lt;strong>행렬의 생성과 축약&lt;/strong> : 수집한 관계식을 바탕으로 거대한 희소 행렬(성분의 대부분이 0인 행렬)을 생성하고, 선형대수학적 기법(블록 란초스 방법 등)을 사용하여 해를 구합니다.&lt;/li>
&lt;li>&lt;strong>제곱근의 계산&lt;/strong> : 마지막으로 대수체 위에서 제곱근을 계산하여, $ N $ 의 인수(소인수)를 도출해 냅니다.&lt;/li>
&lt;/ol>
&lt;p>GNFS의 계산량은 점근적으로 $ O(\exp((\sqrt[3]{\frac{64}{9}} + o(1)) (\log N)^{\frac{1}{3}} (\log \log N)^{\frac{2}{3}})) $ 로 평가됩니다. 이는 &amp;lsquo;준지수함수적(Sub-exponential)&amp;rsquo; 시간 계산량이라 불립니다. 지수 시간보다는 빠르지만, 다항 시간(Polynomial time)보다는 훨씬 느린 계산량입니다.&lt;/p>
&lt;p>실제로 2020년에는 국제적인 연구팀이 GNFS를 사용하여 RSA-250(829비트, 250자리 합성수)의 소인수 분해에 성공했습니다. 이 계산에는 전 세계의 컴퓨터 자원을 끌어모아 약 2700 CPU 코어 연도라는 방대한 계산 시간을 소모했습니다. 그러나 이것이 2048비트가 되면, 필요한 계산량은 우주의 수명의 수조 배로 부풀어 오른다고 언급되고 있어, 현재의 슈퍼컴퓨터를 아무리 병렬로 가동시킨다 해도 고전적인 기법으로는 현실적인 시간 내에 해독하는 것이 불가능합니다.&lt;/p>
&lt;hr>
&lt;h2 id="양자-컴퓨터의-비장의-카드-쇼어의-알고리즘">양자 컴퓨터의 비장의 카드: 쇼어의 알고리즘
&lt;/h2>&lt;p>여기서 등장하는 것이 1994년 피터 쇼어(Peter Shor)에 의해 발표된 &amp;lsquo;쇼어의 알고리즘&amp;rsquo;입니다. 이 알고리즘은 소인수 분해 문제를 양자 컴퓨터 상에서 &lt;strong>다항 시간&lt;/strong> ( $ O((\log N)^3) $ ) 안에 풀 수 있다는 획기적인 것이었습니다. 준지수함수적 시간과 다항 시간의 차이는 결정적인 것이며, 이론상 양자 컴퓨터를 사용하면 RSA 암호는 완전히 파괴됨을 의미합니다.&lt;/p>
&lt;h3 id="쇼어의-알고리즘의-전체-흐름">쇼어의 알고리즘의 전체 흐름
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">graph TD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[소인수 분해하고 싶은 수 N을 입력] --&amp;gt; B[랜덤한 정수 a를 선택]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C{a와 N의&amp;lt;br&amp;gt;최대공약수}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|1보다 크다| D[운 좋게 소인수를 발견!]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|1 즉, 서로소| E[양자 컴퓨터의 차례]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> E --&amp;gt; F[함수 f_x = a^x mod N 의&amp;lt;br&amp;gt;주기 r을 양자 푸리에 변환으로 구함]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> F --&amp;gt; G{주기 r이 짝수 이고&amp;lt;br&amp;gt;a^r/2 ≢ -1 mod N}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|Yes| H[최대공약수 gcd_a^r/2 ± 1, N 을 계산]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H --&amp;gt; I((소인수 분해 성공!))
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|No| B
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>쇼어의 알고리즘은 소인수 분해라는 문제를 직접 푸는 것이 아니라, 정수론의 정리를 이용하여 &amp;lsquo;주기 발견 문제(Period Finding Problem)&amp;lsquo;라는 별개의 문제로 변환하고, 그것을 양자 컴퓨터의 특성을 살려 고속으로 푸는 접근법을 취합니다.&lt;/p>
&lt;h3 id="단계-1-소인수-분해에서-주기-발견-문제로의-환원-고전적-처리">단계 1: 소인수 분해에서 주기 발견 문제로의 환원 (고전적 처리)
&lt;/h3>&lt;p>알고리즘의 첫 단계는 고전 컴퓨터에서 이루어집니다.
소인수 분해하고자 하는 수 $ N $ 에 대해, $ N $ 과 서로소인(최대공약수가 1인) 랜덤한 정수 $ a $ ( $ 1 &lt; a &lt; N $ )를 선택합니다. 만약 우연히도 최대공약수가 1이 아니라면, 그 시점에서 찾은 공약수가 $ N $ 의 소인수이므로 해독 완료이지만 확률은 극히 낮습니다.&lt;/p>
&lt;p>다음으로 이하의 모듈로 방정식 수열을 생각합니다.
$ f(x) = a^x \pmod N $&lt;/p>
&lt;p>이 함수 $ f(x) $ 에 $ x = 1, 2, 3, \dots $ 를 대입해 가면 값은 무작위인 것처럼 보이지만, 유한한 범위 내에서 계산하고 있기 때문에 반드시 어딘가에서 원래 값으로 돌아오고 같은 수열을 반복합니다. 이 반복의 주기를 $ r $ 이라고 부릅니다. 즉,
$ a^r \equiv 1 \pmod N $
이 되는 최소의 양의 정수 $ r $ 을 찾는 문제, 이것이 &amp;lsquo;주기 발견 문제&amp;rsquo;입니다.&lt;/p>
&lt;p>만약 이 주기 $ r $ 이 발견되고 $ r $ 이 짝수라면, $ a^r - 1 \equiv 0 \pmod N $ 이 되어 인수 분해 공식을 사용하여
$ (a^{r/2} - 1)(a^{r/2} + 1) \equiv 0 \pmod N $
와 같이 변형할 수 있습니다. 여기서 유클리드 호제법을 사용하여 $ N $ 과 $ a^{r/2} \pm 1 $ 의 최대공약수를 계산함으로써, $ N $ 의 소인수를 극히 높은 확률로 얻을 수 있습니다.&lt;/p>
&lt;p>고전 컴퓨터로 주기 $ r $ 을 찾기 위해서는 결국 지수 시간적인 단계가 필요해져 고속화할 수 없습니다. 하지만 양자 컴퓨터라면 이 주기 $ r $ 을 순식간에(다항 시간 안에) 찾을 수 있는 것입니다.&lt;/p>
&lt;h3 id="단계-2-양자-상태의-준비와-중첩">단계 2: 양자 상태의 준비와 중첩
&lt;/h3>&lt;p>여기서부터 양자 컴퓨터가 나설 차례입니다.
양자 컴퓨터는 &amp;lsquo;0&amp;rsquo;과 &amp;lsquo;1&amp;rsquo;의 상태를 동시에 가질 수 있는 &amp;lsquo;양자 비트(Qubit)&amp;lsquo;를 사용합니다. 쇼어의 알고리즘에서는 입력을 저장하는 레지스터(제1 레지스터)와 계산 결과를 저장하는 레지스터(제2 레지스터) 두 가지를 준비합니다.&lt;/p>
&lt;p>먼저 아다마르 게이트(Hadamard gate)라 불리는 양자 게이트 조작을 제1 레지스터의 모든 양자 비트에 적용합니다. 이로써 제1 레지스터는 생각할 수 있는 모든 $ x $ 의 값( $ 0 $ 부터 $ 2^n-1 $ 까지. $ n $ 은 충분히 큰 비트 수)의 &lt;strong>균등한 중첩 상태&lt;/strong> 가 됩니다.&lt;/p>
&lt;p>즉, 양자 컴퓨터의 내부에는 $ x=0, 1, 2, 3, \dots $ 이라는 무수한 입력값이 동시에 병행하여 존재하고 있는 상태가 만들어집니다.&lt;/p>
&lt;h3 id="단계-3-양자-모듈로-거듭제곱-quantum-modular-exponentiation">단계 3: 양자 모듈로 거듭제곱 (Quantum Modular Exponentiation)
&lt;/h3>&lt;p>다음으로 제1 레지스터의 중첩 상태를 입력으로 하여 $ f(x) = a^x \pmod N $ 을 계산하고, 그 결과를 제2 레지스터에 저장합니다.
이 계산은 양자 회로 상의 유니터리 변환으로서 실행되기 때문에, 중첩이 유지된 채 모든 $ x $ 에 대한 $ f(x) $ 의 계산이 &amp;lsquo;동시 병행적으로(양자 병렬성)&amp;rsquo; 이루어집니다.&lt;/p>
&lt;p>이 시점에서의 양자 시스템 전체의 공간은,
$ |x, a^x \bmod N\rangle $
이라는 상태의 방대한 중첩으로 되어 있습니다.&lt;/p>
&lt;p>그러나 여기서 단순히 제2 레지스터를 측정(관측)해 버리면, 랜덤한 $ a^x \bmod N $ 의 값이 단 하나만 확률적으로 선택되고, 그에 연동되어 제1 레지스터의 $ x $ 도 하나로 확정되어 버립니다. 이래서는 고전 컴퓨터로 한 번 계산한 것과 다를 바 없어, 주기 $ r $ 을 찾을 수 없습니다.&lt;/p>
&lt;p>양자역학의 규칙에서는 중첩 상태의 내용을 직접 들여다보는 것은 불가능합니다. 그렇다면 어떻게 전체의 &amp;lsquo;주기&amp;rsquo;라는 전역적인(global) 정보를 추출하는 것일까요?&lt;/p>
&lt;h3 id="단계-4-양자-푸리에-변환-qft-quantum-fourier-transform">단계 4: 양자 푸리에 변환 (QFT: Quantum Fourier Transform)
&lt;/h3>&lt;p>이 벽을 돌파하는 쇼어 알고리즘의 진면목이 바로 제1 레지스터에 대한 &lt;strong>양자 푸리에 변환(QFT)&lt;/strong> 의 적용입니다.&lt;/p>
&lt;p>측정을 실시하기 전에, 함수 $ f(x) $ 의 파동적 성질을 해석합니다. 제2 레지스터를 관측했다고 가정해 봅시다. 어떤 값 $ y $ 를 얻었다고 합시다. 그러면 제1 레지스터의 상태는 &amp;ldquo;$ a^x \pmod N = y $ 가 되는 모든 $ x $ 의 중첩&amp;quot;으로 수축됩니다.
이 $ x $ 의 값은 $ x_0, x_0 + r, x_0 + 2r, x_0 + 3r, \dots $ 와 같이 주기 $ r $ 의 간격으로 이산적으로 나열된 상태(일종의 빗 모양의 확률 진폭 분포)가 됩니다.&lt;/p>
&lt;p>이 상태에 대해 양자 푸리에 변환(QFT)을 적용합니다. 고전적인 이산 푸리에 변환이 시간 영역의 신호를 주파수 영역으로 변환하듯이, QFT는 양자 상태의 확률 진폭에 간섭을 일으킵니다.&lt;/p>
&lt;p>QFT를 걸면 양자 간섭 효과에 의해 주기 $ r $ 과 공명하지 않는(위상이 맞지 않는) 잘못된 답의 확률은 서로 상쇄되어 0에 가까워지고(상쇄 간섭), 주기 $ r $ 의 정보를 가진 올바른 답의 확률만이 증폭됩니다(보강 간섭).&lt;/p>
&lt;h3 id="단계-5-측정과-연분수-전개-고전적-후처리">단계 5: 측정과 연분수 전개 (고전적 후처리)
&lt;/h3>&lt;p>QFT 적용 후에 제1 레지스터를 측정하면, 매우 높은 확률로 $ c \approx \frac{j \cdot 2^n}{r} $ 이라는 형태에 가까운 정수 $ c $ 를 얻게 됩니다( $ j $ 는 미지의 정수, $ 2^n $ 은 레지스터의 크기).&lt;/p>
&lt;p>이 측정 결과 $ c $ 를 고전 컴퓨터로 가져와서 $ \frac{c}{2^n} \approx \frac{j}{r} $ 이라는 분수를 만듭니다. 그리고 수학적 기법인 &amp;lsquo;연분수 전개(Continued fraction expansion)&amp;lsquo;를 사용하여 근사치를 계산함으로써 분모인 주기 $ r $ 을 멋지게 찾아낼 수 있습니다.&lt;/p>
&lt;p>$ r $ 을 알게 되면, 남은 것은 단계 1의 공식을 사용하여 $ N $ 의 소인수를 계산하기만 하면 되며 RSA 암호는 완전히 해독됩니다.&lt;/p>
&lt;hr>
&lt;h2 id="현재의-양자-컴퓨터nisq의-실력과-과제">현재의 양자 컴퓨터(NISQ)의 실력과 과제
&lt;/h2>&lt;p>이론적으로는 완벽한 쇼어의 알고리즘이지만, &amp;ldquo;내일이라도 당장 RSA 암호가 깨지는가?&amp;ldquo;라고 묻는다면 답은 명확히 &amp;ldquo;아니오&amp;quot;입니다. 그 이유는 현재의 양자 컴퓨터의 하드웨어 기술의 한계에 있습니다.&lt;/p>
&lt;h3 id="nisq-noisy-intermediate-scale-quantum-시대">NISQ (Noisy Intermediate-Scale Quantum) 시대
&lt;/h3>&lt;p>현재 우리가 살고 있는 것은 &amp;lsquo;NISQ&amp;rsquo;라 불리는 시대입니다. NISQ 디바이스는 수십에서 수백 개의 물리 양자 비트를 가지지만, 노이즈에 대해 극히 취약합니다.&lt;/p>
&lt;p>양자 비트는 열이나 전자파 등의 외부 환경의 영향을 받기 쉬워, 양자 상태가 깨져 버리는 &amp;lsquo;결어긋남(Decoherence, 양자 얽힘 상실)&amp;lsquo;이나 게이트 조작 시의 &amp;lsquo;게이트 에러&amp;rsquo;가 빈번하게 발생합니다. 쇼어의 알고리즘과 같이 매우 깊은(연산 단계 수가 방대한) 양자 회로를 실행하려고 하면, 계산 도중에 에러가 축적되어 최종적인 출력은 의미를 가지지 않는 완전한 노이즈가 되어 버립니다.&lt;/p>
&lt;h3 id="물리-양자-비트와-논리-양자-비트">물리 양자 비트와 논리 양자 비트
&lt;/h3>&lt;p>이 에러 문제를 해결하기 위해 필수불가결한 것이 &amp;lsquo;양자 오류 정정(Quantum Error Correction)&amp;lsquo;입니다.
고전 컴퓨터에서도 오류 정정 코드가 사용되고 있지만, 양자 상태의 복제를 금지하는 &amp;lsquo;복제 불가능성 정리(No-cloning theorem)&amp;lsquo;가 있기 때문에 양자 오류 정정은 매우 복잡합니다.&lt;/p>
&lt;p>양자 오류 정정에서는 &amp;lsquo;표면 부호(Surface Code)&amp;rsquo; 등의 기술을 이용하여, 다수의 노이즈투성이인 &amp;lsquo;물리 양자 비트&amp;rsquo;를 조합함으로써 에러가 없는 이상적인 하나의 &amp;lsquo;논리 양자 비트&amp;rsquo;를 만들어 냅니다.&lt;/p>
&lt;p>현재의 에러율을 전제로 하면, 하나의 논리 양자 비트를 만들기 위해서는 약 1,000～10,000개의 물리 양자 비트가 필요해진다고 추산되고 있습니다. 이를 &amp;lsquo;오류 정정의 오버헤드&amp;rsquo;라고 부릅니다.&lt;/p>
&lt;h3 id="rsa-2048을-파괴하기-위해-필요한-자원이란">RSA-2048을 파괴하기 위해 필요한 자원이란?
&lt;/h3>&lt;p>그렇다면 실제로 RSA-2048을 해독하기 위해, 쇼어의 알고리즘을 구동시키려면 어느 정도의 자원이 필요할까요?&lt;/p>
&lt;p>Craig Gidney (Google) 와 Martin Ekerå 의 2021년 논문에 따른 획기적인 자원 추정에 의하면, 최적화된 쇼어의 알고리즘을 사용하고 표면 부호에 의한 오류 정정을 수행할 경우 다음과 같은 자원이 필요하다고 합니다.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>논리 양자 비트 수&lt;/strong> : 약 4,096 개&lt;/li>
&lt;li>&lt;strong>물리 양자 비트 수 ** : ** 약 2000만 개&lt;/strong> (에러율 $10^{-3}$ 정도를 가정)&lt;/li>
&lt;li>&lt;strong>계산 시간&lt;/strong> : 약 8시간 (물리 게이트 조작이 수백만～수십억 회 필요)&lt;/li>
&lt;/ul>
&lt;p>이에 반해, 현재의 양자 하드웨어의 도달점은 어떨까요?
2023년 말에 IBM이 발표한 초전도 양자 프로세서 &amp;lsquo;Condor(콘도르)&amp;lsquo;는 1,121 양자 비트입니다. 또한 논리 양자 비트의 생성과 관련된 획기적인 연구(하버드 대학이나 QuEra사 등에 의한 중성 원자 양자 컴퓨터를 이용한 48개의 논리 양자 비트 생성 등)도 등장하고 있지만, 아직 &amp;ldquo;노이즈 없는 완벽한 연산&amp;quot;을 장시간 연속으로 실행할 수 있는 단계에는 이르지 못했습니다.&lt;/p>
&lt;p>수천 개의 물리 양자 비트에서 &lt;strong>2000만 개&lt;/strong> 의 실용적인 물리 양자 비트(게다가 상호 결선되어 극저온에서 안정적으로 동작하고 초고속으로 제어 신호를 처리할 수 있는 시스템)로의 스케일업은 공학적으로 엄청난 장벽(배선 문제, 냉각 능력의 한계, 제어 전자장치의 비대화)이 존재합니다. 많은 전문가들은 RSA-2048을 해독할 수 있는 &amp;lsquo;결함 허용(Fault-Tolerant) 양자 컴퓨터(FTQC)&amp;lsquo;가 실현되려면 적어도 10년에서 30년, 혹은 그 이상의 세월이 필요하다고 예측하고 있습니다.&lt;/p>
&lt;hr>
&lt;h2 id="다가오는-store-now-decrypt-later의-위협과-pqc의-여명">다가오는 &amp;lsquo;Store Now, Decrypt Later&amp;rsquo;의 위협과 PQC의 여명
&lt;/h2>&lt;p>&amp;ldquo;아직 10년 이상 걸린다면 안심이다&amp;quot;라고 생각하는 것은 시기상조입니다. 현재 국가 기밀정보나 의료 데이터, 장기적인 인프라 설계 등 수십 년 후까지 비밀을 보장해야만 하는 데이터가 존재합니다.&lt;/p>
&lt;p>여기서 우려되고 있는 것이 바로 &lt;strong>&amp;lsquo;Store Now, Decrypt Later (지금 저장하고, 나중에 해독한다)&amp;rsquo;&lt;/strong> 는 공격 기법입니다. 악의가 있는 국가나 조직이 현재의 RSA나 ECC(타원곡선암호)로 암호화된 통신 데이터를 모두 도청하여 스토리지에 저장해 두는 것입니다. 그리고 10년 후, 20년 후에 강력한 양자 컴퓨터가 완성되는 순간에 쇼어의 알고리즘을 사용하여 과거의 데이터를 모두 해독해내어 비밀을 폭로한다는 기법입니다.&lt;/p>
&lt;p>이러한 타임 래그의 위협에 대항하기 위해 NIST(미국 국립표준기술연구소)를 중심으로 &lt;strong>&amp;lsquo;양자 내성 암호 (PQC: Post-Quantum Cryptography)&amp;rsquo;&lt;/strong> 의 표준화 프로세스가 급피치로 진행되어 왔습니다.&lt;/p>
&lt;p>PQC는 양자 컴퓨터를 이용하더라도 해독이 곤란한(즉, 쇼어의 알고리즘을 적용할 수 없는) 수학적 문제를 기반으로 한 새로운 암호 알고리즘입니다. 주요 접근법으로는 다음과 같은 것들이 있습니다.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>격자 암호 (Lattice-based cryptography)&lt;/strong> : LWE(Learning with Errors) 문제 등을 기초로 합니다. NIST의 표준화에서 주류 (Kyber, Dilithium 등).&lt;/li>
&lt;li>&lt;strong>부호 기반 암호 (Code-based cryptography)&lt;/strong> : 오류 정정 부호의 복호 문제의 어려움에 의존합니다.&lt;/li>
&lt;li>&lt;strong>다변수 다항식 암호 (Multivariate cryptography)&lt;/strong> : 다변수의 연립 이차방정식을 푸는 어려움에 의존합니다.&lt;/li>
&lt;li>&lt;strong>해시 기반 서명 (Hash-based signatures)&lt;/strong> : 해시 함수의 안전성에만 의존하는 디지털 서명입니다.&lt;/li>
&lt;/ul>
&lt;p>이미 Google Chrome이나 Apple의 iMessage 등 주요 소프트웨어나 플랫폼에서는 PQC의 도입 테스트나 하이브리드 구현이 시작되었습니다.&lt;/p>
&lt;h2 id="마치며">마치며
&lt;/h2>&lt;p>양자 컴퓨터는 SF 세계의 꿈 같은 이야기에서 현실적인 공학적 도전으로 넘어가고 있습니다. 쇼어의 알고리즘은 수학과 양자역학이 융합된 인류의 위대한 지적 성과이지만, 동시에 우리 디지털 사회의 기반을 뒤흔드는 &amp;lsquo;파괴적인 힘&amp;rsquo;을 간직하고 있습니다.&lt;/p>
&lt;p>RSA 암호가 내일 당장 쓰지 못하게 되는 것은 아닙니다. 하지만 양자 기술의 진화와 &amp;lsquo;Store Now, Decrypt Later&amp;rsquo;의 리스크를 감안한다면, PQC로의 이행이라는 암호 역사에 남을 대규모의 마이그레이션은 이미 시작되었습니다. 우리는 지금 정보 보안의 패러다임 시프트의 최전선을 목격하고 있는 것입니다.&lt;/p></description></item><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></channel></rss>