<?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/es/tags/rsa/</link><description>Recent content in RSA on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>es</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 22:09:21 +0900</lastBuildDate><atom:link href="http://kenji.blog/es/tags/rsa/index.xml" rel="self" type="application/rss+xml"/><item><title>¿Realmente las computadoras cuánticas destruirán el cifrado RSA? ~ El algoritmo de Shor y el estado actual ~</title><link>http://kenji.blog/es/p/shors-algorithm-and-rsa-breaking/</link><pubDate>Sat, 05 Sep 2026 22:09:21 +0900</pubDate><guid>http://kenji.blog/es/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 ¿Realmente las computadoras cuánticas destruirán el cifrado RSA? ~ El algoritmo de Shor y el estado actual ~" />&lt;h2 id="introducción-la-intersección-entre-la-criptografía-y-la-computación-cuántica">Introducción: La intersección entre la criptografía y la computación cuántica
&lt;/h2>&lt;p>En la sociedad de Internet moderna, la base para proteger el secreto de las comunicaciones es la &amp;ldquo;criptografía de clave pública&amp;rdquo;. Entre ellas, un representante típico es el &amp;ldquo;cifrado RSA&amp;rdquo;, desarrollado en 1977 por Ron Rivest, Adi Shamir y Leonard Adleman. Desde los pagos en compras en línea que utilizamos todos los días, la navegación de sitios web (HTTPS) hasta el envío y recepción de correos electrónicos, el cifrado RSA funciona como el corazón de la infraestructura de Internet.&lt;/p>
&lt;p>Sin embargo, con la llegada de las &amp;ldquo;computadoras cuánticas&amp;rdquo;, se ha señalado la posibilidad de que esta seguridad se vea socavada desde sus cimientos. A veces, en los medios de comunicación aparecen titulares sensacionalistas como: &amp;ldquo;Si se perfecciona la computadora cuántica, las contraseñas y códigos de todo el mundo serán descifrados en segundos&amp;rdquo;. Pero, ¿es esto realmente cierto?&lt;/p>
&lt;p>En este artículo, profundizaremos en los mecanismos del GNFS (Criba General del Cuerpo de Números), que es un método clásico de criptoanálisis, y el &amp;ldquo;Algoritmo de Shor&amp;rdquo; (Shor&amp;rsquo;s Algorithm), que es la versión definitiva del algoritmo de descifrado utilizando computadoras cuánticas. Explicaremos de manera sencilla conceptos avanzados como la transformada cuántica de Fourier y el hallazgo de períodos, y examinaremos en detalle el estado actual del hardware cuántico en la era actual NISQ (Noisy Intermediate-Scale Quantum) y los obstáculos necesarios para romper realmente RSA-2048.&lt;/p>
&lt;hr>
&lt;h2 id="la-base-del-cifrado-rsa-la-dificultad-de-la-factorización-de-enteros">La base del cifrado RSA: La dificultad de la factorización de enteros
&lt;/h2>&lt;p>La seguridad del cifrado RSA depende de una asimetría extremadamente simple en matemáticas. Es el hecho de que &amp;ldquo;multiplicar dos números primos gigantescos es fácil, pero encontrar (factorizar) los dos números primos originales a partir del resultado multiplicado (número compuesto) es extremadamente difícil&amp;rdquo;.&lt;/p>
&lt;p>Por ejemplo, supongamos que hay dos números primos $ p = 61 $ y $ q = 53 $. Calcular esta multiplicación $ N = p \times q = 3233 $ es instantáneo. Sin embargo, si solo se da el número &amp;ldquo;3233&amp;rdquo; y se nos pide resolver &amp;ldquo;¿de qué números primos es esta la multiplicación?&amp;rdquo;, a medida que el número crece, la cantidad de cálculo explota exponencialmente.&lt;/p>
&lt;p>En el RSA-2048, que es la corriente principal en la actualidad, la longitud de la clave es de 2048 bits, es decir, se utiliza un gigantesco número compuesto $ N $ de unos 617 dígitos decimales. Si este $ N $ pudiera ser factorizado, el cifrado estaría prácticamente descifrado.&lt;/p>
&lt;h3 id="el-desafío-de-las-computadoras-clásicas-gnfs-criba-general-del-cuerpo-de-números">El desafío de las computadoras clásicas: GNFS (Criba General del Cuerpo de Números)
&lt;/h3>&lt;p>Para resolver el problema de la factorización, matemáticos y criptógrafos han desarrollado varios algoritmos a lo largo de los años. Entre ellos, el que actualmente se considera el más rápido en computadoras clásicas es la &lt;strong>Criba General del Cuerpo de Números (GNFS: General Number Field Sieve)&lt;/strong>.&lt;/p>
&lt;p>GNFS es un método para factorizar un número gigantesco $ N $ extendiendo el cálculo en el anillo de enteros a un cuerpo de números algebraicos más abstracto (Number Field) para su análisis. El flujo general es el siguiente:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Selección de polinomios&lt;/strong> : Encontrar un polinomio $ f(x) $ con el grado y los coeficientes adecuados que tenga a $ N $ como raíz.&lt;/li>
&lt;li>&lt;strong>Recopilación de datos (cribado)&lt;/strong> : Buscar en el cuerpo de los números racionales y en el cuerpo algebraico una gran cantidad de pares de números que se puedan descomponer en números primos pequeños (números suaves, Smooth numbers). Este proceso se llama &amp;ldquo;cribado&amp;rdquo; y es la parte que requiere más tiempo.&lt;/li>
&lt;li>&lt;strong>Generación y reducción de matrices&lt;/strong> : Generar una matriz dispersa gigante (una matriz donde la mayoría de los componentes son 0) basada en las relaciones recopiladas, y usar métodos de álgebra lineal (como el método de Block-Lanczos) para encontrar una solución.&lt;/li>
&lt;li>&lt;strong>Cálculo de raíces cuadradas&lt;/strong> : Finalmente, calcular la raíz cuadrada sobre el cuerpo algebraico para derivar los factores (factores primos) de $ N $.&lt;/li>
&lt;/ol>
&lt;p>La complejidad computacional de GNFS se evalúa asintóticamente como $ O(\exp((\sqrt[3]{\frac{64}{9}} + o(1)) (\log N)^{\frac{1}{3}} (\log \log N)^{\frac{2}{3}})) $. Esto se llama complejidad temporal &amp;ldquo;subexponencial&amp;rdquo; (Sub-exponential). Aunque es más rápido que el tiempo exponencial, es mucho más lento que el tiempo polinómico (Polynomial time).&lt;/p>
&lt;p>De hecho, en 2020, un equipo de investigación internacional logró factorizar el RSA-250 (un número compuesto de 829 bits y 250 dígitos) utilizando GNFS. Este cálculo consumió un enorme tiempo de computación de aproximadamente 2700 CPU core-años, reuniendo recursos informáticos de todo el mundo. Sin embargo, cuando se trata de 2048 bits, se menciona que la cantidad de cálculo necesaria aumentaría a billones de veces la edad del universo, por lo que no importa cuántas supercomputadoras actuales funcionen en paralelo, es imposible descifrarlo en un tiempo realista utilizando métodos clásicos.&lt;/p>
&lt;hr>
&lt;h2 id="la-carta-de-triunfo-de-la-computadora-cuántica-el-algoritmo-de-shor">La carta de triunfo de la computadora cuántica: El algoritmo de Shor
&lt;/h2>&lt;p>Aquí es donde entra en juego el &amp;ldquo;Algoritmo de Shor&amp;rdquo;, publicado por Peter Shor en 1994. Este algoritmo fue revolucionario al poder resolver el problema de la factorización de enteros en una computadora cuántica en &lt;strong>tiempo polinómico&lt;/strong> ( $ O((\log N)^3) $ ). La diferencia entre el tiempo subexponencial y el tiempo polinómico es decisiva, lo que significa que, en teoría, el uso de una computadora cuántica destruiría por completo el cifrado RSA.&lt;/p>
&lt;h3 id="flujo-general-del-algoritmo-de-shor">Flujo general del algoritmo de Shor
&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[Ingresar el número N a factorizar] --&amp;gt; B[Seleccionar un número entero aleatorio a]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C{Máximo común divisor&amp;lt;br&amp;gt;de a y N}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|Mayor que 1| D[¡Afortunadamente encontramos un factor primo!]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|1 Coprimos| E[Turno de la computadora cuántica]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> E --&amp;gt; F[Encontrar el período r de la función&amp;lt;br&amp;gt;f_x = a^x mod N mediante&amp;lt;br&amp;gt;la transformada cuántica de Fourier]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> F --&amp;gt; G{¿Es el período r par y&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;|Sí| H[Calcular el máximo común divisor gcd_a^r/2 ± 1, N]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H --&amp;gt; I((¡Factorización exitosa!))
&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>El algoritmo de Shor no resuelve directamente el problema de la factorización, sino que utiliza teoremas de la teoría de números para convertirlo en otro problema llamado &amp;ldquo;Problema de hallazgo de períodos&amp;rdquo; (Period Finding Problem), y aborda resolverlo rápidamente aprovechando las características de las computadoras cuánticas.&lt;/p>
&lt;h3 id="paso-1-reducción-de-la-factorización-al-problema-de-hallazgo-de-períodos-procesamiento-clásico">Paso 1: Reducción de la factorización al problema de hallazgo de períodos (Procesamiento clásico)
&lt;/h3>&lt;p>El primer paso del algoritmo se realiza en una computadora clásica.
Para el número $ N $ que queremos factorizar, elegimos un entero aleatorio $ a $ ( $ 1 &lt; a &lt; N $ ) que sea coprimo con $ N $ (su máximo común divisor es 1). Si, por casualidad, el máximo común divisor no es 1, entonces el divisor común encontrado en ese punto es un factor primo de $ N $ y el descifrado está completo, pero la probabilidad es extremadamente baja.&lt;/p>
&lt;p>Luego, consideramos la siguiente secuencia de ecuaciones modulares:
$ f(x) = a^x \pmod N $&lt;/p>
&lt;p>Si sustituimos $ x = 1, 2, 3, \dots $ en esta función $ f(x) $, los valores parecen ser aleatorios, pero dado que estamos calculando dentro de un rango finito, inevitablemente volverá al valor original en algún punto y repetirá la misma secuencia de números. A este período de repetición lo llamamos $ r $. Es decir,
$ a^r \equiv 1 \pmod N $
El problema de encontrar el entero positivo más pequeño $ r $ que cumpla con esto, es el &amp;ldquo;Problema de hallazgo de períodos&amp;rdquo;.&lt;/p>
&lt;p>Si se encuentra este período $ r $, y si $ r $ es par, entonces $ a^r - 1 \equiv 0 \pmod N $, y usando la fórmula de factorización se puede transformar en:
$ (a^{r/2} - 1)(a^{r/2} + 1) \equiv 0 \pmod N $
A partir de aquí, al calcular el máximo común divisor de $ N $ y $ a^{r/2} \pm 1 $ usando el algoritmo de Euclides, se puede obtener un factor primo de $ N $ con una probabilidad extremadamente alta.&lt;/p>
&lt;p>Para encontrar el período $ r $ en una computadora clásica, en última instancia, se requieren pasos exponenciales y no se puede acelerar. Sin embargo, una computadora cuántica puede encontrar este período $ r $ en un instante (en tiempo polinómico).&lt;/p>
&lt;h3 id="paso-2-preparación-del-estado-cuántico-y-superposición">Paso 2: Preparación del estado cuántico y superposición
&lt;/h3>&lt;p>A partir de aquí es el turno de la computadora cuántica.
Las computadoras cuánticas utilizan &amp;ldquo;cúbits&amp;rdquo; (Qubits) que pueden tener los estados &amp;ldquo;0&amp;rdquo; y &amp;ldquo;1&amp;rdquo; simultáneamente. En el algoritmo de Shor, se preparan dos registros: un registro para almacenar la entrada (el primer registro) y un registro para almacenar los resultados del cálculo (el segundo registro).&lt;/p>
&lt;p>Primero, se aplica una operación de puerta cuántica llamada Puerta de Hadamard (Hadamard gate) a todos los cúbits del primer registro. Como resultado, el primer registro se convierte en un &lt;strong>estado de superposición uniforme&lt;/strong> de todos los valores posibles de $ x $ (desde $ 0 $ hasta $ 2^n-1 $, donde $ n $ es un número de bits suficientemente grande).&lt;/p>
&lt;p>En otras palabras, dentro de la computadora cuántica se crea un estado en el que existen de manera simultánea y paralela innumerables valores de entrada $ x=0, 1, 2, 3, \dots $.&lt;/p>
&lt;h3 id="paso-3-exponenciación-modular-cuántica-quantum-modular-exponentiation">Paso 3: Exponenciación modular cuántica (Quantum Modular Exponentiation)
&lt;/h3>&lt;p>A continuación, tomando el estado de superposición del primer registro como entrada, calculamos $ f(x) = a^x \pmod N $ y almacenamos el resultado en el segundo registro.
Dado que este cálculo se ejecuta como una transformación unitaria en el circuito cuántico, el cálculo de $ f(x) $ para todos los $ x $ se realiza &amp;ldquo;simultáneamente y en paralelo (paralelismo cuántico)&amp;rdquo; manteniendo la superposición.&lt;/p>
&lt;p>En este punto, el espacio general del sistema cuántico es:
$ |x, a^x \bmod N\rangle $
que es una enorme superposición de estados.&lt;/p>
&lt;p>Sin embargo, si simplemente medimos (observamos) el segundo registro aquí, un valor aleatorio de $ a^x \bmod N $ se elegirá probabilísticamente, y en conjunto con esto, el $ x $ del primer registro también se fijará a uno solo. Hacer esto equivaldría a calcularlo una vez en una computadora clásica y no nos permitiría encontrar el período $ r $.&lt;/p>
&lt;p>Bajo las reglas de la mecánica cuántica, no podemos mirar directamente el contenido de un estado de superposición. Entonces, ¿cómo extraemos la información global, que es el &amp;ldquo;período&amp;rdquo; de todo el sistema?&lt;/p>
&lt;h3 id="paso-4-transformada-cuántica-de-fourier-qft-quantum-fourier-transform">Paso 4: Transformada Cuántica de Fourier (QFT: Quantum Fourier Transform)
&lt;/h3>&lt;p>La verdadera genialidad del algoritmo de Shor para superar este obstáculo es la aplicación de la &lt;strong>Transformada Cuántica de Fourier (QFT)&lt;/strong> al primer registro.&lt;/p>
&lt;p>Antes de realizar la medición, analizamos las propiedades de onda de la función $ f(x) $. Supongamos que observamos el segundo registro. Asumamos que se obtuvo un valor $ y $. Entonces, el estado del primer registro colapsa en &amp;ldquo;la superposición de todos los $ x $ tal que $ a^x \pmod N = y $&amp;rdquo;.
Los valores de este $ x $ estarán separados por un intervalo del período $ r $ de la forma $ x_0, x_0 + r, x_0 + 2r, x_0 + 3r, \dots $, resultando en un estado discretamente alineado (una especie de distribución de amplitud de probabilidad en forma de peine).&lt;/p>
&lt;p>Aplicamos la Transformada Cuántica de Fourier (QFT) a este estado. Así como la transformada discreta de Fourier clásica convierte una señal en el dominio del tiempo al dominio de la frecuencia, la QFT causa interferencia en las amplitudes de probabilidad del estado cuántico.&lt;/p>
&lt;p>Al aplicar la QFT, debido al efecto de interferencia cuántica, las probabilidades de respuestas incorrectas que no resuenan (están desfasadas) con el período $ r $ se anulan mutuamente y se acercan a cero (interferencia destructiva), y solo se amplifica la probabilidad de la respuesta correcta que tiene la información del período $ r $ (interferencia constructiva).&lt;/p>
&lt;h3 id="paso-5-medición-y-expansión-en-fracciones-continuas-post-procesamiento-clásico">Paso 5: Medición y expansión en fracciones continuas (Post-procesamiento clásico)
&lt;/h3>&lt;p>Si se mide el primer registro después de aplicar la QFT, con una probabilidad muy alta se obtendrá un entero $ c $ muy cercano a la forma $ c \approx \frac{j \cdot 2^n}{r} $ (donde $ j $ es un número entero desconocido y $ 2^n $ es el tamaño del registro).&lt;/p>
&lt;p>Este resultado de medición $ c $ se devuelve a la computadora clásica para crear una fracción $ \frac{c}{2^n} \approx \frac{j}{r} $. Luego, calculando una aproximación utilizando un método matemático llamado &amp;ldquo;expansión en fracciones continuas&amp;rdquo; (Continued fraction expansion), podemos extraer de manera brillante el período $ r $ que está en el denominador.&lt;/p>
&lt;p>Una vez que conocemos $ r $, todo lo que queda es usar la fórmula del Paso 1 para calcular los factores primos de $ N $ y el cifrado RSA estará completamente descifrado.&lt;/p>
&lt;hr>
&lt;h2 id="el-poder-y-los-desafíos-de-las-computadoras-cuánticas-actuales-nisq">El poder y los desafíos de las computadoras cuánticas actuales (NISQ)
&lt;/h2>&lt;p>El algoritmo de Shor es teóricamente perfecto, pero si se pregunta &amp;ldquo;¿Se romperá el cifrado RSA mañana?&amp;rdquo;, la respuesta es claramente &amp;ldquo;no&amp;rdquo;. La razón radica en las limitaciones de la tecnología de hardware de las computadoras cuánticas actuales.&lt;/p>
&lt;h3 id="la-era-nisq-noisy-intermediate-scale-quantum">La era NISQ (Noisy Intermediate-Scale Quantum)
&lt;/h3>&lt;p>En la actualidad nos encontramos en una era llamada &amp;ldquo;NISQ&amp;rdquo;. Los dispositivos NISQ tienen decenas a cientos de cúbits físicos, pero son extremadamente vulnerables al ruido.&lt;/p>
&lt;p>Los cúbits son susceptibles a influencias ambientales externas como el calor y las ondas electromagnéticas, lo que hace que ocurra con frecuencia la &amp;ldquo;decoherencia&amp;rdquo; (pérdida de entrelazamiento cuántico), que destruye el estado cuántico, o los &amp;ldquo;errores de puerta&amp;rdquo; al operar las puertas cuánticas. Si se intenta ejecutar un circuito cuántico muy profundo (con una cantidad masiva de pasos de cálculo) como el algoritmo de Shor, los errores se acumulan durante el cálculo y el resultado final será ruido completo sin significado.&lt;/p>
&lt;h3 id="cúbits-físicos-y-cúbits-lógicos">Cúbits físicos y cúbits lógicos
&lt;/h3>&lt;p>Para resolver este problema de errores, es indispensable la &amp;ldquo;Corrección de errores cuánticos&amp;rdquo; (Quantum Error Correction).
Aunque también se utilizan códigos de corrección de errores en las computadoras clásicas, la corrección de errores cuánticos es muy compleja debido al &amp;ldquo;Teorema de no clonación cuántica&amp;rdquo; que prohíbe copiar estados cuánticos.&lt;/p>
&lt;p>En la corrección de errores cuánticos, se utilizan tecnologías como el &amp;ldquo;Código de superficie&amp;rdquo; (Surface Code) para combinar muchos &amp;ldquo;cúbits físicos&amp;rdquo; ruidosos, y así crear un &amp;ldquo;cúbit lógico&amp;rdquo; ideal y sin errores.&lt;/p>
&lt;p>Teniendo en cuenta las tasas de error actuales, se estima que se necesitarán aproximadamente de 1,000 a 10,000 cúbits físicos para crear un solo cúbit lógico. Esto se denomina la &amp;ldquo;sobrecarga de la corrección de errores&amp;rdquo;.&lt;/p>
&lt;h3 id="cuáles-son-los-recursos-necesarios-para-destruir-rsa-2048">¿Cuáles son los recursos necesarios para destruir RSA-2048?
&lt;/h3>&lt;p>Entonces, para descifrar realmente RSA-2048, ¿cuántos recursos se necesitan para ejecutar el algoritmo de Shor?&lt;/p>
&lt;p>En una estimación de recursos revolucionaria realizada en un artículo de 2021 por Craig Gidney (Google) y Martin Ekerå, utilizando un algoritmo de Shor optimizado y realizando la corrección de errores con código de superficie, se requerirían los siguientes recursos:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Número de cúbits lógicos&lt;/strong> : Aproximadamente 4,096&lt;/li>
&lt;li>&lt;strong>Número de cúbits físicos ** : ** Aproximadamente 20 millones&lt;/strong> (asumiendo una tasa de error de alrededor de $10^{-3}$)&lt;/li>
&lt;li>&lt;strong>Tiempo de cálculo&lt;/strong> : Aproximadamente 8 horas (se requieren de millones a miles de millones de operaciones de puertas físicas)&lt;/li>
&lt;/ul>
&lt;p>Por el contrario, ¿cuál es el nivel alcanzado por el hardware cuántico actual?
A finales de 2023, el procesador cuántico superconductor &amp;ldquo;Condor&amp;rdquo;, anunciado por IBM, tiene 1,121 cúbits. Además, también han aparecido investigaciones innovadoras sobre la generación de cúbits lógicos (como la generación de 48 cúbits lógicos utilizando una computadora cuántica de átomos neutros por la Universidad de Harvard y la empresa QuEra), pero aún no estamos en la etapa en que se puedan ejecutar &amp;ldquo;cálculos perfectos sin ruido&amp;rdquo; de manera continua y prolongada.&lt;/p>
&lt;p>Para escalar desde unos miles de cúbits físicos hasta &lt;strong>20 millones&lt;/strong> de cúbits físicos prácticos (y un sistema interconectado, operando de manera estable a temperaturas criogénicas y capaz de procesar señales de control a ultra alta velocidad) existe un muro de ingeniería tremendo (problemas de cableado, límites de capacidad de enfriamiento y la expansión excesiva de la electrónica de control). Muchos expertos predicen que tomará al menos de 10 a 30 años, o incluso más, lograr una &amp;ldquo;Computadora cuántica tolerante a fallas (FTQC)&amp;rdquo; capaz de descifrar RSA-2048.&lt;/p>
&lt;hr>
&lt;h2 id="la-inminente-amenaza-de-store-now-decrypt-later-y-el-amanecer-de-pqc">La inminente amenaza de &amp;ldquo;Store Now, Decrypt Later&amp;rdquo; y el amanecer de PQC
&lt;/h2>&lt;p>Es prematuro pensar: &amp;ldquo;Si faltan más de 10 años, estamos a salvo&amp;rdquo;. Actualmente existen datos cuyo secreto debe garantizarse durante décadas en el futuro, como la información confidencial del estado, los datos médicos y el diseño de infraestructura a largo plazo.&lt;/p>
&lt;p>Lo que preocupa aquí es el método de ataque &lt;strong>&amp;ldquo;Store Now, Decrypt Later&amp;rdquo; (Almacenar ahora, descifrar después)&lt;/strong> . Estados u organizaciones malintencionadas interceptan todos los datos de comunicaciones cifrados actualmente con RSA o ECC (Criptografía de curva elíptica) y los guardan en sistemas de almacenamiento. Luego, dentro de 10 o 20 años, en el momento en que se complete una poderosa computadora cuántica, utilizarán el algoritmo de Shor para descifrar todos los datos pasados y exponer los secretos.&lt;/p>
&lt;p>Para contrarrestar la amenaza de este desfase temporal, el proceso de estandarización de la &lt;strong>&amp;ldquo;Criptografía Post-Cuántica (PQC: Post-Quantum Cryptography)&amp;rdquo;&lt;/strong> ha avanzado a un ritmo acelerado, centrado principalmente en el NIST (Instituto Nacional de Estándares y Tecnología de EE. UU.).&lt;/p>
&lt;p>PQC es un nuevo algoritmo criptográfico basado en problemas matemáticos que son difíciles de resolver incluso utilizando computadoras cuánticas (es decir, a los que no se puede aplicar el algoritmo de Shor). Los enfoques principales incluyen los siguientes:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Criptografía basada en retículos (Lattice-based cryptography)&lt;/strong> : Basado en el problema LWE (Learning with Errors), entre otros. Es la corriente principal en la estandarización del NIST (Kyber, Dilithium, etc.).&lt;/li>
&lt;li>&lt;strong>Criptografía basada en códigos (Code-based cryptography)&lt;/strong> : Depende de la dificultad del problema de decodificar códigos de corrección de errores.&lt;/li>
&lt;li>&lt;strong>Criptografía multivariante (Multivariate cryptography)&lt;/strong> : Depende de la dificultad de resolver sistemas de ecuaciones cuadráticas con múltiples variables.&lt;/li>
&lt;li>&lt;strong>Firmas basadas en hash (Hash-based signatures)&lt;/strong> : Firmas digitales que dependen únicamente de la seguridad de la función hash.&lt;/li>
&lt;/ul>
&lt;p>Ya se han iniciado las pruebas de implementación y las implementaciones híbridas de PQC en los principales software y plataformas, como Google Chrome y el iMessage de Apple.&lt;/p>
&lt;h2 id="conclusión">Conclusión
&lt;/h2>&lt;p>Las computadoras cuánticas están pasando de ser el sueño del mundo de la ciencia ficción a un desafío de ingeniería en la realidad. El algoritmo de Shor es un gran logro intelectual de la humanidad que fusiona las matemáticas y la mecánica cuántica, pero al mismo tiempo tiene un &amp;ldquo;poder destructivo&amp;rdquo; oculto que puede sacudir los cimientos de nuestra sociedad digital.&lt;/p>
&lt;p>El cifrado RSA no quedará inutilizable inmediatamente mañana. Sin embargo, considerando la evolución de la tecnología cuántica y el riesgo de &amp;ldquo;Store Now, Decrypt Later&amp;rdquo;, la migración masiva en la historia de la criptografía, que es la transición a PQC, ya ha comenzado. Ahora mismo somos testigos de la primera línea de un cambio de paradigma en la seguridad de la información.&lt;/p></description></item><item><title>[Análisis completo] Implementando y entendiendo el algoritmo de descifrado más fuerte 'GNFS' en C++</title><link>http://kenji.blog/es/p/gnfs-cpp-implementation/</link><pubDate>Sat, 05 Sep 2026 13:04:59 +0900</pubDate><guid>http://kenji.blog/es/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 [Análisis completo] Implementando y entendiendo el algoritmo de descifrado más fuerte 'GNFS' en C++" />&lt;h1 id="análisis-completoentendiendo-el-algoritmo-de-descifrado-más-fuerte-gnfs-implementándolo-en-c">【Análisis Completo】Entendiendo el algoritmo de descifrado más fuerte &amp;ldquo;GNFS&amp;rdquo; implementándolo en C++
&lt;/h1>&lt;p>El cifrado &amp;ldquo;RSA&amp;rdquo; es la base que sostiene la Internet moderna. Su robustez depende de la creencia matemática de que &amp;ldquo;factorizar un número compuesto gigante en números primos es virtualmente imposible con las computadoras actuales&amp;rdquo;.&lt;/p>
&lt;p>Sin embargo, la humanidad nunca se rinde. Actualmente, existe el **algoritmo más fuerte y avanzado de la humanidad ** para realizar factorizaciones gigantescas en computadoras clásicas (computadoras normales, no cuánticas). Este es el &lt;strong>&amp;ldquo;General Number Field Sieve (GNFS) o Criba General del Cuerpo de Números&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>En este artículo, publicaremos todo el código de implementación que modela estrictamente la lógica computacional más avanzada de GNFS en C++ (usando enteros de precisión múltiple &lt;code>boost::multiprecision&lt;/code> de la biblioteca Boost), y explicaremos a fondo los abismos de la &amp;ldquo;teoría algebraica de números&amp;rdquo; detrás de él.&lt;/p>
&lt;p>Por favor, disfruten del misterio de las matemáticas y del poder de la ciencia computacional que lo domina, junto con el código fuente.&lt;/p>
&lt;hr>
&lt;h2 id="1-gnfs-framework-lógico-de-vanguardia-código-fuente-completo">1. GNFS Framework Lógico de Vanguardia (Código fuente completo)
&lt;/h2>&lt;p>Primero, aquí está la visión general de la implementación de GNFS en C++ que explicaremos. La criba de cuerpo de números real (como CADO-NFS) es un sistema distribuido masivo de cientos de miles de líneas de código, pero este código diseña y modela las &lt;strong>&amp;ldquo;5 tuberías (fases) esenciales&amp;rdquo;&lt;/strong> que componen GNFS en clases, manteniéndolo en una configuración mínima sin perder su significado matemático.&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">// Usando enteros de precisión múltiple de 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 (Criba General del Cuerpo de Números) Framework Lógico de Vanguardia
&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">// Este código modela estrictamente las 5 tuberías del GNFS más avanzado utilizado en CADO-NFS, etc.,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// como diseño de clases en 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">// Fase 1: Selección Polinomial (Algoritmo de 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">// Polinomio lado algebraico 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">// Polinomio lado racional 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">// Generación del polinomio inicial basado en expansión en base m (En realidad se usa reducción de bases de retículos LLL más avanzada)
&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;[Fase 1] Polynomial Selection (Grado &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;) iniciando...&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">// Expansión simple en base m (grado 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">// Aproximación simple de m (sin usar funciones de 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">[Fase 1] Completo.&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">// Fase 2: Lattice Sieving (Criba de Retículos)
&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">// En el GNFS moderno, el estándar de facto no es Line Sieve (Criba Lineal), sino
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// la Criba de Retículos q-Especial (Special-q Lattice Sieving) de Franke-Kleinjung y otros.
&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;[Fase 2] Generando Factor Bases (Límite Racional: &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;, Límite Algebraico: &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">// (Omitido) En realidad realiza generación de primos y filtrado con el símbolo de Legendre, etc.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">poly&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Fase 2] Special-q Lattice Sieving activo...&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">// Implementación Mock: La criba de retículos real escanea cientos de GB de espacio de memoria en bloques,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// mapea pares (a, b) a retículos para cada primo especial 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">// y ejecuta un sieving (criba) maximizando la eficiencia de la caché al extremo.
&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">// Añadiendo una relación dummy para la demo
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Relation&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">17&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">rational_primes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">5&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">algebraic_primes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">relations&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Fase 2] Encontradas &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; relaciones.&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">// Fase 3: Filtering (Purga de singletons y mezcla de cliques)
&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;[Fase 3] Filtrando Relaciones...&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. Eliminación de Singletons (eliminación de relaciones con primos que aparecen solo 1 vez)
&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. Fusión de Cliques (combinación de relaciones para hacer densa una matriz dispersa)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// En realidad, comprime una matriz de cientos de millones de filas a unos pocos millones usando algoritmos como 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;[Fase 3] Tamaño de la matriz reducido óptimamente.&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">// Fase 4: Álgebra Lineal sobre GF(2) (Método 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">// En los entornos de supercomputadoras recientes, se utiliza como vanguardia el método Block Wiedemann
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// (implementación de Coppersmith) que es más adecuado para computación distribuida que el método 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="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;[Fase 4] Algoritmo Block Wiedemann sobre GF(2) iniciando...&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">// Repite la operación de producto de matrices dispersas y vectores,
&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 encuentra múltiples vectores solución (kernels) donde 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">// Lista de dependencias
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Datos dummy
&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;[Fase 4] Encontradas &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; dependencias lineales (cuadrados perfectos).&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">// Fase 5: Raíz Cuadrada Algebraica (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;[Fase 5] Computación de Raíz Cuadrada Algebraica...&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. Cálculo de la raíz cuadrada racional V (operación de enteros simple)
&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. Cálculo de la raíz cuadrada algebraica gamma (Método de Montgomery, etc.)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Encuentra el elemento gamma del cuerpo algebraico gigante O_K, y lo mapea al mundo real con el homomorfismo 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">// Asumiendo que se añadieron columnas de Caracteres Cuadráticos (Quadratic Characters) en la Fase 2 y 4
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// para evitar la obstrucción del grupo de clases de ideales y el grupo de unidades.
&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; Mapa de homomorfismo phi aplicado.&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;[Fase 5] Calculando 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;[ÉXITO] Factor no trivial encontrado: &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; Otro 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;[FALLO] Solución trivial. Probando la siguiente dependencia...&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">// Pipeline de Ejecución Principal
&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] Motor General Number Field Sieve (Boost C++) &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;================================================================&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Número compuesto gigante N que queremos factorizar, ej. RSA-270
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;233108530344407544527637656910680524145619812480305449042948611968495918245135782867888369318577116418213919268572658314913060672626911354027609793166341626693946596196427744273886601876896313468704059066746903123910748277606548649151920812699309766587514735456594993207&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Grado del polinomio (para más de 130 dígitos usualmente se selecciona grado 5 a 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">// Inicialización del pipeline
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">PolynomialSelector&lt;/span> &lt;span class="n">poly_select&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">degree&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LatticeSieve&lt;/span> &lt;span class="n">sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10000000&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">20000000&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// Los límites reales son decenas a cientos de millones
&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. Selección Polinomial
&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. Proceso de Criba (Sieving)
&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. Filtrado (Compresión de matriz)
&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. Álgebra Lineal (Búsqueda del espacio nulo sobre 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. Cálculo de Raíz Cuadrada Algebraica y 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">[Sistema] Pipeline SOTA GNFS completado en &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; segundos.&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>Entonces, ¿cómo es que este código destruye los muros de la criptografía? Explicaremos los minuciosos algoritmos y las matemáticas avanzadas para cada una de las 5 fases.&lt;/p>
&lt;hr>
&lt;h2 id="2-el-objetivo-final-de-gnfs-x2-equiv-y2-pmod-n">2. El objetivo final de GNFS: $X^2 \equiv Y^2 \pmod N$
&lt;/h2>&lt;p>El objetivo de la mayoría de los algoritmos de factorización gigante moderna, no solo de GNFS, es encontrar un par no trivial $(X, Y)$ que satisfaga la siguiente congruencia:&lt;/p>
$$X^2 \equiv Y^2 \pmod N$$
&lt;p>Esta fórmula significa que &amp;ldquo;los restos al dividir $X^2$ y $Y^2$ por $N$ son iguales&amp;rdquo;. Reorganizando esto:
$X^2 - Y^2 \equiv 0 \pmod N$
En otras palabras, $(X-Y)(X+Y)$ es un múltiplo de $N$.&lt;/p>
&lt;p>Si $X \not\equiv \pm Y \pmod N$ (solución no trivial), existirá un &amp;ldquo;divisor común mayor que 1 y menor que $N$&amp;rdquo; entre $(X-Y)$ y $N$.
Aquí, si usamos el algoritmo de Euclides para calcular &lt;strong>$\gcd(X-Y, N)$&lt;/strong>, podemos encontrar los factores primos de $N$ con mucha facilidad.&lt;/p>
&lt;p>Sin embargo, encontrar estos $X$ e $Y$ es como buscar una aguja en un desierto. Por lo tanto, GNFS adopta el ingenioso enfoque de crear &lt;strong>dos mundos&lt;/strong>, el &amp;ldquo;mundo de los enteros reales&amp;rdquo; y el &amp;ldquo;mundo de los cuerpos algebraicos de los polinomios&amp;rdquo;, y distribuye los cálculos.&lt;/p>
&lt;hr>
&lt;h2 id="3-fase-1-selección-polinomial-polynomial-selection">3. Fase 1: Selección Polinomial (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">// Cálculo de m = N^(1/d) y expansión en 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>El primer paso de GNFS es crear un &amp;ldquo;polinomio mágico&amp;rdquo; que sirva de puente entre los dos mundos.
Para un número gigante $N$, elegimos un entero $m$. Usualmente se elige de tal manera que $m \approx N^{1/d}$ (el código asume un polinomio de grado $d=6$).&lt;/p>
&lt;p>Luego, expandimos $N$ en base $m$ y usamos esos coeficientes para construir el polinomio $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>Este polinomio $f(x)$ tiene una propiedad extremadamente importante: &lt;strong>&amp;ldquo;al sustituir la variable $x$ con $m$, resulta ser exactamente $N$ ($f(m) = N$)&amp;rdquo;&lt;/strong>. En otras palabras, $f(m) \equiv 0 \pmod N$.
El polinomio en el lado racional se define como $g(x) = x - m$.&lt;/p>
&lt;p>Con esto, el &lt;strong>&amp;ldquo;mundo del cuerpo algebraico $\mathbb{Z}[\alpha]$&amp;rdquo;&lt;/strong> dominado por la raíz $\alpha$ de $f(x)=0$ y el &lt;strong>&amp;ldquo;mundo normal de los racionales (enteros) $\mathbb{Z}$&amp;rdquo;&lt;/strong> quedan firmemente conectados por un &amp;ldquo;homomorfismo de anillos&amp;rdquo; (Homomorphism) de $x \to m$.&lt;/p>
&lt;p>En herramientas de vanguardia como CADO-NFS, el polinomio &amp;ldquo;más conveniente $f(x)$&amp;rdquo; donde los coeficientes no se vuelven extremadamente grandes y es probable que aparezcan primos en pasos posteriores (más fácil que sea liso), se busca durante meses utilizando el algoritmo de KleinJung y el algoritmo de reducción de bases de retículos LLL.&lt;/p>
&lt;hr>
&lt;h2 id="4-fase-2-criba-de-retículos-q-especial-special-q-lattice-sieving">4. Fase 2: Criba de Retículos q-Especial (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">// mapea pares (a, b) a retículos para cada primo especial 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">// y ejecuta un sieving (criba) maximizando la eficiencia de la caché al extremo.
&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>Una vez preparados ambos mundos, el siguiente paso es buscar &amp;ldquo;números lisos&amp;rdquo; (números formados solo por factores primos pequeños) en ambos mundos.
Generamos infinitos pares de enteros $(a, b)$ y calculamos los siguientes dos valores:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Valor racional&lt;/strong>: $a - bm$&lt;/li>
&lt;li>&lt;strong>Norma algebraica&lt;/strong>: $b^d f(a/b)$&lt;/li>
&lt;/ol>
&lt;p>El propósito de GNFS es recolectar de decenas a cientos de millones de estos &lt;strong>&amp;ldquo;pares donde tanto el valor racional como el algebraico pueden descomponerse completamente en factores primos pequeños (Relation: relaciones)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>En los primeros GNFS, se utilizaba una &amp;ldquo;Criba Lineal (Line Sieve)&amp;rdquo; que alineaba $(a, b)$ en el plano $xy$ y dividía por primos desde un extremo. Sin embargo, esto causaba muchas fallas de caché al acceder a la memoria en todas partes, y tenía la debilidad de ser muy lento.&lt;/p>
&lt;p>Por lo tanto, el código de vanguardia actual utiliza un método llamado &lt;strong>&amp;ldquo;Criba de Retículos q-Especial (Special-q Lattice Sieve)&amp;rdquo;&lt;/strong>.
Se fija un número primo $q$ moderadamente grande y solo se consideran &amp;ldquo;los pares $(a, b)$ donde el valor algebraico siempre es divisible por $q$&amp;rdquo;. Dado que estos $(a, b)$ forman un &amp;ldquo;retículo (Lattice)&amp;rdquo; en el plano, el tamaño del salto de la dirección calculada es constante y se ajusta perfectamente a las memorias caché L1/L2 de la CPU.
Gracias a la introducción de esta criba de retículos, la velocidad de cálculo de GNFS ha mejorado drásticamente.&lt;/p>
&lt;hr>
&lt;h2 id="5-fase-3-filtrado-filtering">5. Fase 3: Filtrado (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. Eliminación de Singletons (eliminación de relaciones con primos que aparecen solo 1 vez)
&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. Fusión de Cliques (combinación de relaciones para hacer densa una matriz dispersa)
&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>Cientos de millones de relaciones recolectadas durante meses por computadoras de todo el mundo en la Fase 2. Sin embargo, si metemos esto directamente en el siguiente &amp;ldquo;paso de resolución de ecuaciones simultáneas (cálculo matricial)&amp;rdquo;, la memoria de la supercomputadora estallará.&lt;/p>
&lt;p>Por eso, se realiza un proceso de supercompresión de la matriz llamado &lt;strong>Filtering (Filtrado)&lt;/strong>.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Eliminación de Singletons (Singleton removal / Purga de singularidades)&lt;/strong>
Suponga que un primo gigante $p$ aparece &amp;ldquo;solo 1 vez&amp;rdquo; entre cientos de millones de relaciones. Dado que nuestro objetivo es &amp;ldquo;hacer que los exponentes de todos los primos sean pares (múltiplos de 2)&amp;rdquo;, un primo que aparece solo 1 vez nunca podrá hacerse par.
Por lo tanto, las relaciones que contienen ese primo se eliminan instantáneamente (se purgan) por considerarse &amp;ldquo;basura inútil&amp;rdquo;. A medida que esto ocurre en cadena, los datos de cientos de millones de filas se reducen rápidamente.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Fusión de Cliques (Clique merging)&lt;/strong>
Además, multiplicar (sumar) relaciones que comparten un número primo específico reduce el número de filas al tiempo que comprime una matriz dispersa en un estado más denso (se utiliza una técnica similar a la búsqueda de cliques en la teoría de grafos).&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Con esta optimización, la enorme matriz dispersa se comprime drásticamente a un tamaño computable.&lt;/p>
&lt;hr>
&lt;h2 id="6-fase-4-álgebra-lineal-sobre-gf2-método-block-wiedemann">6. Fase 4: Álgebra Lineal sobre GF(2) (Método 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">// Repite la operación de producto de matrices dispersas y vectores,
&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 encuentra múltiples vectores solución (kernels) donde 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>Por fin, el núcleo del rompecabezas.
Multiplicamos las relaciones recolectadas para buscar &lt;strong>&amp;ldquo;combinaciones donde los exponentes de los factores primos sean todos números pares&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Matemáticamente, esto no es más que encontrar un vector solución $x$ (espacio nulo/kernel) usando una matriz gigante $M$ cuyos elementos son &amp;ldquo;par/impar (es decir, 0 o 1)&amp;rdquo; de los exponentes de cada primo y un vector $x$ que indica qué relaciones utilizar:
&lt;strong>$M \cdot x \equiv 0 \pmod 2$&lt;/strong>&lt;/p>
&lt;p>Tenemos que resolver un sistema de ecuaciones de una matriz de tamaño absurdo de millones de filas × millones de columnas. Con el método normal de eliminación de Gauss, la complejidad sería $O(N^3)$, y el cálculo no terminaría hasta el final del universo.&lt;/p>
&lt;p>Por lo tanto, la implementación más avanzada utiliza el &lt;strong>&amp;ldquo;Método Block Wiedemann (Bloque Wiedemann)&amp;rdquo;&lt;/strong>.
Este es un tipo de método del subespacio de Krylov que aprovecha el hecho de que la matriz $M$ es &amp;ldquo;extremadamente dispersa (casi toda ceros)&amp;rdquo; y deriva la solución iterando la multiplicación de matriz y vector.
A diferencia del antiguo método Block Lanczos, el método Block Wiedemann puede dividir completamente el proceso de cálculo en múltiples grupos, por lo que ejerce un poder abrumador en la computación en nube distribuida moderna y en la computación paralela en supercomputadoras.&lt;/p>
&lt;hr>
&lt;h2 id="7-fase-5-raíz-cuadrada-algebraica-algebraic-square-root-y-el-colapso-de-la-criptografía">7. Fase 5: Raíz Cuadrada Algebraica (Algebraic Square Root) y el Colapso de la Criptografía
&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. Cálculo de la raíz cuadrada racional 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. Cálculo de la raíz cuadrada algebraica 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>A través de los cálculos matriciales de la Fase 4, hemos obtenido un &amp;ldquo;conjunto de relaciones $S$ que al multiplicarse hacen que todos los factores primos tengan potencias pares&amp;rdquo;.
Con esto, podemos construir el &amp;ldquo;cuadrado&amp;rdquo; en ambos mundos, el racional y el algebraico.&lt;/p>
&lt;p>Para el lado racional, es simplemente una multiplicación de enteros, por lo que calcular la raíz cuadrada $V$ es fácil.
&lt;/p>
$$V^2 = \prod_{S} (a - bm)$$
&lt;p>&lt;strong>Sin embargo, el verdadero infierno reside en el &amp;ldquo;lado algebraico&amp;rdquo;.&lt;/strong>
En el mundo del cuerpo algebraico $\mathbb{Z}[\alpha]$, dado que la factorización única de factores primos no es válida, hemos estado calculando usando ideales. Lo único que garantiza el cálculo matricial es que &lt;strong>&amp;ldquo;es el cuadrado de un ideal&amp;rdquo;, y no se garantiza que sea &amp;ldquo;el cuadrado de un elemento ($\gamma^2$)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Aquí se levantan poderosos muros en la teoría algebraica de números llamados &amp;ldquo;obstrucción del grupo de clases de ideales&amp;rdquo; y &amp;ldquo;obstrucción del grupo de unidades&amp;rdquo;.
Para romper este muro, GNFS utiliza la magia llamada &lt;strong>&amp;ldquo;Caracteres Cuadráticos (Quadratic Characters)&amp;rdquo;&lt;/strong>.
A la matriz de la Fase 4, se añaden secretamente de antemano columnas de residuos cuadráticos (Símbolo de Legendre) para decenas de ideales primos especiales. Con esto, hay una probabilidad abrumadora de que el conjunto $S$ encontrado evite la obstrucción y forme con éxito el &amp;ldquo;cuadrado del elemento verdadero $\gamma^2$&amp;rdquo;.&lt;/p>
&lt;p>El proceso de encontrar $\gamma$ (raíz cuadrada algebraica) se calcula utilizando algoritmos muy complejos como el método de Montgomery.&lt;/p>
&lt;p>Y por fin, la raíz cuadrada algebraica $\gamma$ es teletransportada al mundo real (sustituyendo $m$ por $x$) mediante el homomorfismo de anillos $\phi$, y obtenemos $Y$.
Si ponemos el $V$ del lado racional directamente como $X$, la ecuación absoluta que hemos estado buscando finalmente se completa.&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>Solo queda calcular $\gcd(X-Y, N)$. En el momento en que se ejecuta el proceso de 0.001 segundos y el factor no trivial se imprime en la pantalla, el cifrado RSA, que se jactaba de ser inexpugnable, colapsa por completo.&lt;/p>
&lt;hr>
&lt;h2 id="conclusión">Conclusión
&lt;/h2>&lt;p>GNFS no es simplemente una técnica de programación.
Es el cristal del intelecto humano que ha dominado el &amp;ldquo;abismo de las matemáticas puras&amp;rdquo; como el álgebra abstracta, la teoría de anillos y los grupos de clases de ideales, con la &amp;ldquo;ingeniería extrema&amp;rdquo; como la arquitectura distribuida de supercomputadoras y la optimización de cachés.&lt;/p>
&lt;p>La información de chat y de tarjetas de crédito que enviamos de manera informal está protegida sobre una defensa matemática tan astronómica.&lt;/p>
&lt;p>Esperamos que, a través de este framework de C++, hayan sentido el &amp;ldquo;romanticismo de las matemáticas y la informática&amp;rdquo; detrás del algoritmo de descifrado más avanzado.&lt;/p></description></item><item><title>La verdadera estructura matemática de la Criba General del Cuerpo de Números (GNFS)</title><link>http://kenji.blog/es/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/es/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 La verdadera estructura matemática de la Criba General del Cuerpo de Números (GNFS)" />&lt;h1 id="la-verdadera-estructura-matemática-de-la-criba-general-del-cuerpo-de-números-gnfs">La verdadera estructura matemática de la Criba General del Cuerpo de Números (GNFS)
&lt;/h1>&lt;p>El objetivo final de GNFS es encontrar $X, Y$ tales que $X^2 \equiv Y^2 \pmod N$.
Para lograr esto, los matemáticos construyeron un puente entre el &lt;strong>&amp;ldquo;mundo real de los números enteros&amp;rdquo;&lt;/strong> y el &lt;strong>&amp;ldquo;mundo de los cuerpos algebraicos&amp;rdquo;&lt;/strong>. Ese puente es el &amp;ldquo;homomorfismo&amp;rdquo;.&lt;/p>
&lt;h2 id="etapa-1-conectando-mundos-con-el-homomorfismo-homomorphism">Etapa 1: Conectando mundos con el &amp;ldquo;Homomorfismo&amp;rdquo; (Homomorphism)
&lt;/h2>&lt;h3 id="1-selección-de-polinomios-y-definición-de-raíces">1. Selección de polinomios y definición de raíces
&lt;/h3>&lt;p>Para un número compuesto gigante $N$, elegimos un entero $m$ y un polinomio $f(x)$ de manera que $f(m) \equiv 0 \pmod N$.
(Ejemplo: expandimos $N$ en base $m$, y formamos $f(x)$ a partir de sus coeficientes. Aquí asumimos que $f(x)$ es irreducible sobre el cuerpo de los números racionales $\mathbb{Q}$ (no se puede factorizar más)).&lt;/p>
&lt;p>A continuación, definimos una de las &amp;ldquo;raíces complejas&amp;rdquo; de la ecuación $f(x) = 0$ como $\alpha$.
Naturalmente, $f(\alpha) = 0$. $\alpha$ no es un entero, sino un número complejo (número algebraico) que puede incluir raíces o números imaginarios.&lt;/p>
&lt;h3 id="2-construcción-de-anillos-rings-y-homomorfismos">2. Construcción de Anillos (Rings) y Homomorfismos
&lt;/h3>&lt;p>Aquí preparamos dos &amp;ldquo;anillos&amp;rdquo; matemáticos (mundos donde se definen la suma y la multiplicación):&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mundo A: $\mathbb{Z}[\alpha]$&lt;/strong> (el anillo de enteros algebraicos que contiene a $\alpha$)
Un mundo de números expresados en la forma $a + b\alpha + c\alpha^2 + \dots$.&lt;/li>
&lt;li>&lt;strong>Mundo B: $\mathbb{Z}/N\mathbb{Z}$&lt;/strong> (el anillo de restos módulo $N$)
Un mundo de congruencias (módulos) compuesto solo por números enteros del $0$ al $N-1$.&lt;/li>
&lt;/ul>
&lt;p>Aquí, definimos el siguiente mapeo (función) $\phi$ del Mundo A al Mundo B:
&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>Este mapeo $\phi$ es una operación mágica que reemplaza exactamente la variable $\alpha$ del Mundo A por el entero $m$ del Mundo B.
Este $\phi$ tiene una propiedad extremadamente poderosa llamada &lt;strong>&amp;ldquo;Homomorfismo de Anillos&amp;rdquo; (Ring Homomorphism)&lt;/strong>.
Un homomorfismo es la propiedad de &lt;strong>&amp;ldquo;transportarse a otro mundo sin destruir la estructura de sumas y multiplicaciones&amp;rdquo;&lt;/strong>. Es decir, se cumplen las siguientes ecuaciones:&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>Qué significa esto. Si podemos crear un &lt;strong>&amp;ldquo;cuadrado ($\gamma^2$)&amp;rdquo;&lt;/strong> de algún elemento complejo $\gamma$ en el &amp;ldquo;Mundo A (el mundo de $\alpha$)&amp;rdquo;, al transportarlo al &amp;ldquo;Mundo B (el mundo de los restos)&amp;rdquo; con $\phi$, ** la forma del cuadrado $\phi(\gamma)^2$ se conservará perfectamente**.&lt;/p>
&lt;hr>
&lt;h2 id="etapa-2-el-colapso-de-la-factorización-prima-y-el-nacimiento-del-ideal-ideal">Etapa 2: El colapso de la factorización prima y el nacimiento del &amp;ldquo;Ideal&amp;rdquo; (Ideal)
&lt;/h2>&lt;p>Queremos recolectar muchos elementos apropiados $(a - b\alpha)$ dentro del Mundo A ($\mathbb{Z}[\alpha]$) y multiplicarlos juntos para crear un &amp;ldquo;cuadrado perfecto&amp;rdquo;.
Normalmente, factorizaríamos cada $(a - b\alpha)$ en &amp;ldquo;factores primos&amp;rdquo; y los combinariamos para que los exponentes de los números primos sean todos pares (resolviéndolo con matrices) para formar un cuadrado.&lt;/p>
&lt;p>&lt;strong>Sin embargo, aquí nos encontramos con un muro algebraico desesperante.&lt;/strong>
En un mundo de cuerpos algebraicos como $\mathbb{Z}[\alpha]$, &lt;strong>se derrumba la &amp;ldquo;unicidad de la factorización prima&amp;rdquo; (la idea que nos enseñaron de que cualquier número puede expresarse como el producto de números primos de una sola manera)&lt;/strong>.&lt;/p>
&lt;p>(Ejemplo: en cierto mundo de cuerpos algebraicos, $6 = 2 \times 3$, y al mismo tiempo $6 = (1+\sqrt{-5}) \times (1-\sqrt{-5})$, haciendo imposible saber cuáles son los verdaderos primos).&lt;/p>
&lt;p>Si la factorización prima no es única, el rompecabezas de &amp;ldquo;contar el número de primos para hacerlos pares&amp;rdquo; (la criba) es en principio imposible de ejecutar.&lt;/p>
&lt;h3 id="la-salvación-de-kummer-y-dedekind-el-ideal">La salvación de Kummer y Dedekind: el &amp;ldquo;Ideal&amp;rdquo;
&lt;/h3>&lt;p>Lo que salvó a las matemáticas de este colapso fue el concepto de &lt;strong>&amp;ldquo;Ideal&amp;rdquo; (número ideal)&lt;/strong> creado por los matemáticos del siglo XIX.
Al pensar en el &amp;ldquo;conjunto de múltiplos (ideal)&amp;rdquo; generado por un elemento en lugar del elemento en sí, volvieron a hacer posible la factorización prima.&lt;/p>
&lt;p>En el anillo de enteros de un cuerpo algebraico $\mathcal{O}_K$ (un anillo más completo que contiene a $\mathbb{Z}[\alpha]$), aunque los elementos no puedan ser factorizados de manera única, se ha demostrado que &lt;strong>&amp;ldquo;los ideales siempre pueden ser factorizados de forma única como un producto de &amp;lsquo;ideales primos ($\mathfrak{p}$)&amp;rsquo;&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Por lo tanto, en GNFS, no descomponemos el elemento $(a - b\alpha)$ en sí, sino que hacemos la &lt;strong>factorización en ideales primos del ideal principal $\langle a - b\alpha \rangle$&lt;/strong> que este genera.&lt;/p>
&lt;hr>
&lt;h2 id="etapa-3-norma-norm-y-las-dos-cribas-sieves">Etapa 3: Norma (Norm) y las dos Cribas (Sieves)
&lt;/h2>&lt;p>Entonces, ¿cómo sabemos en qué ideales primos se descompone el ideal $\langle a - b\alpha \rangle$?
Aquí utilizamos una función llamada &lt;strong>&amp;ldquo;Norma&amp;rdquo; (Norm)&lt;/strong>. La norma es una función que convierte los elementos complejos de los cuerpos algebraicos en &amp;ldquo;números enteros reales ordinarios $\mathbb{Z}$&amp;rdquo;.&lt;/p>
&lt;p>La norma del elemento $(a - b\alpha)$ se calcula mediante un simple cálculo polinomial $b^d f(a/b)$ (donde $d$ es el grado de $f(x)$).&lt;/p>
&lt;p>Por teoremas algebraicos, sabemos que &lt;strong>&amp;ldquo;si la norma de un ideal se descompone completamente en primos pequeños (es un número liso o &amp;lsquo;smooth&amp;rsquo;), entonces su ideal original también se descompone completamente en ideales primos pequeños&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Por lo tanto, GNFS calcula simultáneamente lo siguiente para una gran cantidad de pares de enteros $(a, b)$, y recolecta solo los pares donde ambos son &amp;ldquo;números lisos&amp;rdquo;:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Criba Racional (Rational Sieve)&lt;/strong>: $a - bm$ (valor en el mundo real)&lt;/li>
&lt;li>&lt;strong>Criba Algebraica (Algebraic Sieve)&lt;/strong>: $b^d f(a/b)$ (norma en el mundo del cuerpo algebraico)&lt;/li>
&lt;/ol>
&lt;p>Recolecta decenas de millones de pares $(a, b)$ donde ambos son lisos, resuelve los datos de factorización prima de los ideales (cuántos ideales primos están incluidos) como una matriz gigante (álgebra lineal sobre GF(2)), y encuentra un conjunto de pares $S$ de manera que &amp;ldquo;cuando se multiplican, los exponentes de todos los ideales primos se vuelven pares&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="etapa-4-dos-obstáculos-que-se-interponen-y-el-grupo-de-clases-de-ideales">Etapa 4: Dos &amp;ldquo;Obstáculos&amp;rdquo; que se interponen y el Grupo de Clases de Ideales
&lt;/h2>&lt;p>Mediante cálculos de matrices, encontramos que multiplicar todos los ideales de $(a - b\alpha)$ que pertenecen al conjunto $S$ resulta en el cuadrado de cierto ideal $I$.
&lt;/p>
$$\prod_{S} \langle a - b\alpha \rangle = I^2$$
&lt;p>&lt;strong>Sin embargo, esto aún no ha terminado. Aquí es donde se encuentra el muro matemático más profundo y difícil de GNFS.&lt;/strong>&lt;/p>
&lt;p>Lo que finalmente queremos no es el &amp;ldquo;cuadrado de un ideal&amp;rdquo;, sino el &lt;strong>&amp;ldquo;cuadrado de un elemento ($\gamma^2$)&amp;rdquo;&lt;/strong> para sustituirlo en el mapeo $\phi$.
El hecho de que se haya convertido en el cuadrado de un ideal no significa que el elemento en sí sea un cuadrado. Aquí existen &lt;strong>dos obstáculos matemáticos (Obstructions) formidables&lt;/strong>.&lt;/p>
&lt;h3 id="obstáculo-1-el-muro-del-grupo-de-clases-de-ideales-ideal-class-group">Obstáculo 1: El muro del Grupo de Clases de Ideales (Ideal Class Group)
&lt;/h3>&lt;p>El ideal $I$ no es necesariamente un &amp;ldquo;ideal generado por un solo elemento (ideal principal)&amp;rdquo;.
Es imposible extraer un elemento concreto $\gamma$ de un ideal que no sea principal.&lt;/p>
&lt;p>Aquí entra el concepto de &lt;strong>&amp;ldquo;Grupo de Clases de Ideales&amp;rdquo; (Class Group, $Cl_K$)&lt;/strong>. El grupo de clases de ideales es un grupo que mide &amp;ldquo;cuántos ideales que no son principales existen en ese mundo del cuerpo algebraico (qué tan destruida está la unicidad de la factorización prima)&amp;rdquo;.
Incluso si $\prod \langle a - b\alpha \rangle$ se convierte en $I^2$, si $I$ no es el elemento identidad (ideal principal) en el grupo de clases de ideales, no podemos retroceder al cuadrado de un elemento.&lt;/p>
&lt;h3 id="obstáculo-2-el-muro-del-grupo-de-unidades-unit-group">Obstáculo 2: El muro del Grupo de Unidades (Unit Group)
&lt;/h3>&lt;p>Supongamos que por suerte $I$ era un ideal principal $\langle \gamma \rangle$.
Entonces tenemos que $\prod \langle a - b\alpha \rangle = \langle \gamma^2 \rangle$.
Podrías pensar &amp;ldquo;¡Genial, el elemento también es un cuadrado!&amp;rdquo;, pero estarías muy equivocado.&lt;/p>
&lt;p>Que los ideales (conjuntos de múltiplos) sean iguales no significa que los elementos sean completamente iguales. Siempre ocurre una desviación por una &lt;strong>&amp;ldquo;Unidad&amp;rdquo; (Unit: un número cuyo inverso multiplicativo también es entero. Por ejemplo, 1 o -1)&lt;/strong>.
Es decir, la verdadera igualdad de los elementos es la siguiente:
&lt;/p>
$$\prod_{S} (a - b\alpha) = u \cdot \gamma^2$$
&lt;p>
($u$ es un elemento del grupo de unidades $U_K$)&lt;/p>
&lt;p>A menos que esta unidad $u$ sea en sí misma un cuadrado (elemento cuadrático) de algo, el lado izquierdo nunca podrá ser un &amp;ldquo;cuadrado perfecto de un elemento&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="etapa-5-la-magia-de-adleman-caracteres-cuadráticos-quadratic-characters">Etapa 5: La magia de Adleman, &amp;ldquo;Caracteres Cuadráticos&amp;rdquo; (Quadratic Characters)
&lt;/h2>&lt;p>Los obstáculos del grupo de clases de ideales y del grupo de unidades. ¿Cómo los superamos?
Aquí es donde entra la genial técnica introducida por el criptógrafo Leonard Adleman (la &amp;ldquo;A&amp;rdquo; de RSA) y otros: los &lt;strong>&amp;ldquo;Caracteres Cuadráticos&amp;rdquo; (Quadratic Characters)&lt;/strong>.&lt;/p>
&lt;p>Para determinar &amp;ldquo;si un elemento es un cuadrado perfecto dentro de un cuerpo algebraico&amp;rdquo;, utilizamos una versión para cuerpos algebraicos del símbolo de Legendre (residuo cuadrático).
En la matriz gigante anterior (el rompecabezas para hacer que el número de ideales primos sea par), &lt;strong>añadimos en secreto unas cuantas decenas de condiciones (columnas) adicionales para que &amp;ldquo;los caracteres cuadráticos para algunos ideales primos especiales $\mathfrak{q}$ también sean todos $1$ (pares)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Cuando encontramos un conjunto $S$ que incluso satisface estas condiciones adicionales mediante el cálculo de matrices, por los teoremas profundos de la teoría de números algebraicos, se garantiza que &lt;strong>&amp;ldquo;los obstáculos tanto del grupo de clases de ideales como del grupo de unidades desaparecerán naturalmente con una probabilidad abrumadora&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Con esto, por fin obtenemos la verdadera ecuación.
&lt;/p>
$$\prod_{S} (a - b\alpha) = \gamma^2$$
&lt;hr>
&lt;h2 id="etapa-final-la-fusión-de-los-mundos-y-el-colapso-criptográfico">Etapa Final: La fusión de los mundos y el colapso criptográfico
&lt;/h2>&lt;p>Por fin, todas las piezas del rompecabezas están en su lugar.&lt;/p>
&lt;p>&lt;strong>[Elementos del Mundo del Cuerpo Algebraico (Mundo A)]&lt;/strong>
$\gamma^2 = \prod (a - b\alpha)$
(De aquí usamos un algoritmo de raíz cuadrada para encontrar $\gamma$)&lt;/p>
&lt;p>&lt;strong>[Elementos del Mundo Real (Mundo de los Números Racionales)]&lt;/strong>
$V^2 = \prod (a - bm)$
(Como esta es una simple multiplicación de enteros, podemos encontrar la raíz cuadrada $V$ normalmente)&lt;/p>
&lt;p>Ahora, es el turno del puente mágico que construimos al principio: &lt;strong>el homomorfismo $\phi$&lt;/strong>.
Transportamos el elemento $\gamma$ del Mundo A al Mundo B (el mundo de restos módulo $N$) usando $\phi$ (el mapeo que sustituye $\alpha$ por $m$).
&lt;/p>
$$Y = \phi(\gamma) \pmod N$$
&lt;p>Por otro lado, tomamos la $V$ que creamos en el mundo real directamente al mundo de los restos y la llamamos $X$.
&lt;/p>
$$X = V \pmod N$$
&lt;p>Debido a la propiedad de &amp;ldquo;conservar estructuras&amp;rdquo; del homomorfismo, la relación de los cuadrados que se sostenía en el Mundo A se preserva perfectamente en el Mundo B (el mundo módulo $N$).
Además, dado que el par original $(a, b)$ fue creado correspondientemente en la forma $a - b\alpha$ y $a - bm$, estas $X$ e $Y$ chocan en el mundo módulo $N$ y producen la siguiente igualdad absoluta:&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>El resto es rezar para que $X$ e $Y$ no sean una solución trivial ($X \equiv \pm Y$), y calcular:
&lt;strong>$\gcd(X - Y, N)$&lt;/strong>&lt;/p>
&lt;p>Si es una solución no trivial, el algoritmo de Euclides correrá en 0.001 segundos e imprimirá en la pantalla de salida el corazón del cifrado RSA: los primos secretos $p$ y $q$.&lt;/p>
&lt;hr>
&lt;p>Esta es la &lt;strong>forma completa de la &amp;ldquo;Criba General del Cuerpo de Números (GNFS)&amp;rdquo;&lt;/strong>, que reúne lo mejor de las matemáticas modernas.&lt;/p></description></item><item><title>¿Qué es la 'Criba General del Cuerpo de Números (GNFS)', la matemática más fuerte de la humanidad que rompe el cifrado de Internet?</title><link>http://kenji.blog/es/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/es/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 ¿Qué es la 'Criba General del Cuerpo de Números (GNFS)', la matemática más fuerte de la humanidad que rompe el cifrado de Internet?" />&lt;h1 id="qué-es-la-criba-general-del-cuerpo-de-números-gnfs-las-matemáticas-más-fuertes-de-la-humanidad-que-rompen-el-cifrado-de-internet">¿Qué es la &amp;ldquo;Criba General del Cuerpo de Números (GNFS)&amp;rdquo;, las matemáticas más fuertes de la humanidad que rompen el cifrado de Internet?
&lt;/h1>&lt;p>El Internet que usamos todos los días. Los mensajes de LINE, YouTube, las compras en Amazon, todas las comunicaciones están protegidas por &amp;ldquo;cifrado&amp;rdquo;.
Actualmente, el representante del cifrado más utilizado en todo el mundo es el &amp;ldquo;Cifrado RSA&amp;rdquo;.&lt;/p>
&lt;p>La clave de la defensa del cifrado RSA es muy simple. Utiliza la propiedad matemática de que &lt;strong>&amp;ldquo;la factorización de números primos gigantescos no puede ser resuelta ni siquiera por computadoras&amp;rdquo;&lt;/strong>.
Por ejemplo, si es &amp;ldquo;15&amp;rdquo;, se sabe inmediatamente que es &amp;ldquo;3 × 5&amp;rdquo;, pero en el momento en que esto se convierte en un &amp;ldquo;número de 270 dígitos&amp;rdquo;, incluso reuniendo las supercomputadoras de todo el mundo llevaría cientos de millones de años resolverlo.&lt;/p>
&lt;p>Sin embargo, los matemáticos tampoco se han quedado callados. Para romper este cifrado inexpugnable, la humanidad ha creado un algoritmo (procedimiento de cálculo) parecido a la magia llamado &lt;strong>&amp;ldquo;Criba General del Cuerpo de Números (GNFS: General Number Field Sieve)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>En este artículo, sin usar términos técnicos en absoluto, explicaremos paso a paso y de manera completa el truco por el cual este &amp;ldquo;algoritmo más fuerte de la humanidad&amp;rdquo; rompe el cifrado, solo con conocimientos de &lt;strong>matemáticas de secundaria (factorización de primos, álgebra, máximo común divisor)&lt;/strong>!&lt;/p>
&lt;hr>
&lt;h2 id="capítulo-1-el-objetivo-de-descifrar-el-código-es-la-fórmula-de-tercer-año-de-secundaria">Capítulo 1: El objetivo de descifrar el código es &amp;ldquo;la fórmula de tercer año de secundaria&amp;rdquo;
&lt;/h2>&lt;p>El mayor ataque especial para enfrentar la factorización de números primos gigantes. Es esta fórmula que se aprende en tercer año de secundaria.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>$X^2 - Y^2 = (X + Y)(X - Y)$&lt;/strong>&lt;/p>
&lt;/blockquote>
&lt;p>Puede que pienses: &amp;ldquo;¿Eh, se puede romper un cifrado con una fórmula tan básica?&amp;rdquo;. Sin embargo, esta es precisamente la llave maestra que lo revela todo.&lt;/p>
&lt;p>El objetivo principal para romper el cifrado es, para un número gigante $N$,
encontrar &lt;strong>&amp;ldquo;números ($X$ e $Y$) cuyo residuo al dividir $X^2$ e $Y^2$ por $N$ sea el mismo&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="por-qué-se-puede-descifrar-el-código-si-el-residuo-es-el-mismo">¿Por qué se puede descifrar el código si &amp;ldquo;el residuo es el mismo&amp;rdquo;?
&lt;/h3>&lt;p>Supongamos que el &amp;ldquo;residuo al dividir por $N$&amp;rdquo; de dos números, $X^2$ e $Y^2$, es el mismo.
Que el residuo sea el mismo significa que existe la regla de que &lt;strong>la resta &amp;ldquo;$X^2 - Y^2$&amp;rdquo; siempre se divide exactamente por $N$ (es un múltiplo de $N$)&lt;/strong>.&lt;/p>
&lt;p>Aquí, supongamos que el número gigante $N$ usado en el cifrado está hecho por la multiplicación de dos números primos secretos ($p$ y $q$) ($N = p \times q$).&lt;/p>
&lt;p>Al factorizar $X^2 - Y^2$, se convierte en &lt;strong>$(X - Y)(X + Y)$&lt;/strong>.
El hecho de que esto sea un múltiplo de $N$ significa que en algún lugar de esta multiplicación están escondidos los números primos secretos $p$ y $q$.&lt;/p>
&lt;p>Aquí ocurre un milagro.
La probabilidad de que los dos números primos $p$ y $q$ se separen en habitaciones diferentes, &lt;strong>&amp;quot;$p$ va a la habitación de $(X - Y)$&amp;quot; y &amp;ldquo;$q$ va a la habitación de $(X + Y)$&amp;rdquo;&lt;/strong>, es matemáticamente del ** 50% (un medio)**.&lt;/p>
&lt;p>Con solo el número primo $p$ entrando en la habitación de $(X - Y)$, calculemos el &lt;strong>&amp;ldquo;máximo común divisor (la pieza común más grande)&amp;rdquo;&lt;/strong> de $(X - Y)$ y $N$.&lt;/p>
&lt;ul>
&lt;li>Contenido de $(X - Y)$ = $p \times$ algún número&lt;/li>
&lt;li>Contenido de $N$ = $p \times q$
¡La única pieza común es &lt;strong>&amp;quot;$p$&amp;quot;&lt;/strong>!&lt;/li>
&lt;/ul>
&lt;p>Es decir, en el momento en que se calcula el máximo común divisor, el número primo oculto $p$ cae, ¡y el cifrado se descifra por completo! (*El máximo común divisor se puede calcular en un instante incluso en un teléfono inteligente si usas el &amp;ldquo;Algoritmo de Euclides&amp;rdquo;).&lt;/p>
&lt;p>&lt;strong>[Breve columna: ¿Por qué al cuadrado? ¿No se puede al cubo o al doble?]&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>Si es &amp;ldquo;$2X - 2Y$&amp;rdquo;, se convierte en $2(X - Y)$ y como solo hay una habitación, no se pueden separar los números primos. Si es &amp;ldquo;$X^3 - Y^3$&amp;rdquo;, el tamaño de las habitaciones se desequilibra y el cálculo se vuelve innecesariamente pesado. Para separar los números primos en dos, la opción más eficiente que se divide bellamente en dos habitaciones es &amp;ldquo;al cuadrado&amp;rdquo;.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="capítulo-2-cómo-buscar-x-e-y-el-rompecabezas-de-recolectar-tarjetas-de-números-primos">Capítulo 2: ¿Cómo buscar X e Y? &amp;ldquo;El rompecabezas de recolectar tarjetas de números primos&amp;rdquo;
&lt;/h2>&lt;p>Ya sabemos el objetivo. Sin embargo, incluso si buscas al azar &amp;ldquo;$X^2$ e $Y^2$ que tengan el mismo residuo&amp;rdquo;, no lo encontrarás hasta que se acabe la vida útil del universo.
Por eso, los matemáticos idearon un método genial llamado &lt;strong>&amp;ldquo;el rompecabezas de recolectar tarjetas de números primos&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="paso-1-recolectar-solo-el-oro-en-polvo-números-suaves-con-un-tamiz">Paso 1: Recolectar solo el oro en polvo (números suaves) con un tamiz
&lt;/h3>&lt;p>Primero, preparamos un número adecuado $Z$, lo elevamos al cuadrado y calculamos el residuo $W$ al dividirlo por $N$.
(El mundo del residuo de $Z^2 = W$)&lt;/p>
&lt;p>Factorizamos el residuo $W$ resultante. Aquí, solo cuando aparece un &lt;strong>&amp;quot;$W$ compuesto solo de números primos pequeños como 2, 3, 5, 7, etc.&amp;quot;&lt;/strong>, guardamos esa fórmula como una &amp;ldquo;tarjeta ganadora&amp;rdquo;, y si se mezclan números primos grandes, la tiramos.
Es como la tarea de tirar piedras grandes con un tamiz en un río y recolectar solo el polvo de oro.&lt;/p>
&lt;h3 id="paso-2-el-rompecabezas-de-hacer-todo-número-par">Paso 2: El rompecabezas de hacer todo &amp;ldquo;número par&amp;rdquo;
&lt;/h3>&lt;p>Por ejemplo, supongamos que se reunieron las siguientes tres tarjetas de polvo de oro:&lt;/p>
&lt;ul>
&lt;li>Tarjeta A: $Z_1^2 = 2^3 \times 3^1$&lt;/li>
&lt;li>Tarjeta B: $Z_2^2 = 2^1 \times 5^1$&lt;/li>
&lt;li>Tarjeta C: $Z_3^2 = 3^1 \times 5^1$&lt;/li>
&lt;/ul>
&lt;p>Multipliquemos todo esto.
El lado derecho se convierte en $(2^3 \times 3^1) \times (2^1 \times 5^1) \times (3^1 \times 5^1)$,
y al organizarlo todo junto queda &lt;strong>&amp;quot;$2^4 \times 3^2 \times 5^2$&amp;quot;&lt;/strong>.&lt;/p>
&lt;p>¡Increíblemente, la cantidad de números primos se ha vuelto &amp;ldquo;4, 2, 2&amp;rdquo;, &lt;strong>todos en cantidades pares&lt;/strong>!
El hecho de que todos sean cantidades pares significa que si reducimos la cantidad total a la mitad, se convierte en el &amp;ldquo;cuadrado de algo&amp;rdquo;.
Es decir, $(2^2 \times 3^1 \times 5^1)^2 = (60)^2$.&lt;/p>
&lt;p>Dado que el lado izquierdo es $(Z_1 \times Z_2 \times Z_3)^2$, ¡con esto finalmente se completa el tan esperado par de &amp;ldquo;$X^2 = Y^2$&amp;rdquo; que es
&lt;strong>$X = (Z_1 \times Z_2 \times Z_3)$&lt;/strong>
&lt;strong>$Y = 60$&lt;/strong>!&lt;/p>
&lt;p>Dado que a las computadoras se les da muy bien el rompecabezas de calcular si la cantidad de números primos es &amp;ldquo;par o impar (0 o 1)&amp;rdquo;, con este método pueden encontrar $X$ e $Y$ a alta velocidad.&lt;/p>
&lt;hr>
&lt;h2 id="capítulo-3-el-muro-de-la-desesperación-que-se-interpone">Capítulo 3: El muro de la desesperación que se interpone
&lt;/h2>&lt;p>¡Con esto se puede romper cualquier cifrado!&amp;hellip; Eso pensarías, pero surge un gran problema.
Si el número $N$ del cifrado tiene hasta &amp;ldquo;100 dígitos&amp;rdquo;, se puede resolver con este método (llamado criba cuadrática), pero cuando $N$ se convierte en &amp;ldquo;200 dígitos, 300 dígitos&amp;rdquo;, el $W$ que aparece en el medio del cálculo se vuelve demasiado grande.&lt;/p>
&lt;p>Cuando los números se vuelven demasiado grandes, de repente dejan de aparecer los &amp;ldquo;números hechos solo de primos pequeños (polvo de oro)&amp;rdquo;. Se vuelve más difícil que buscar una lente de contacto en el desierto, y ya no se pueden juntar en absoluto las tarjetas para resolver el rompecabezas.&lt;/p>
&lt;p>Aquí finalmente aparece el arma definitiva de la humanidad, la &lt;strong>&amp;ldquo;Criba General del Cuerpo de Números (GNFS)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h2 id="capítulo-4-la-idea-más-fuerte-de-la-humanidad-crear-dos-mundos">Capítulo 4: La idea más fuerte de la humanidad: Crear &amp;ldquo;dos mundos&amp;rdquo;
&lt;/h2>&lt;p>La idea genial de GNFS es: &lt;strong>&amp;ldquo;Como calculamos solo en el mundo real, los números se vuelven enormes. Entonces, hagamos un &amp;lsquo;mundo oculto&amp;rsquo; usando polinomios (expresiones algebraicas) y dividamos el peso del cálculo en dos&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="la-magia-de-las-expresiones-algebraicas">La magia de las expresiones algebraicas
&lt;/h3>&lt;p>GNFS convierte un número gigante $N$ en una expresión algebraica usando un número base $m$.
Por ejemplo, si $N=100$, usando $m=4$, $100 = 4^3 + 2(4^2) + 4$.
Usando la letra $x$, convertimos esto en la expresión (el mundo oculto) &lt;strong>$f(x) = x^3 + 2x^2 + x$&lt;/strong>.&lt;/p>
&lt;p>Lo interesante de esta expresión es que tiene la propiedad de que &lt;strong>&amp;ldquo;si sustituyes la letra $x$ por $m$ (4 en el ejemplo anterior), siempre puedes regresar (teletransportarte) al número real $N$&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="buscar-oro-en-polvo-en-dos-mundos-al-mismo-tiempo">Buscar oro en polvo en dos mundos al mismo tiempo
&lt;/h3>&lt;p>GNFS crea muchos pares de números enteros $(a, b)$ y realiza los siguientes dos cálculos al mismo tiempo:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>El mundo real&lt;/strong>: $a - b \times m$&lt;/li>
&lt;li>&lt;strong>El mundo algebraico&lt;/strong>: el valor de calcular $a - b \times x$ con las reglas del álgebra&lt;/li>
&lt;/ol>
&lt;p>Al dividir el problema en dos mundos, el tamaño de los números manejados se vuelve drásticamente menor (más ligero). Es la imagen de partir una roca gigante en dos para convertirla en piedras fáciles de manejar.&lt;/p>
&lt;p>Luego, con un tamiz (criba), se recolectan solo los pares milagrosos $(a, b)$ que son &lt;strong>&amp;ldquo;tanto en el mundo real como en el mundo algebraico, &amp;lsquo;hechos solo de números primos pequeños (polvo de oro)&amp;rsquo;&amp;rdquo;&lt;/strong>. Este es el origen del nombre &amp;ldquo;Criba del Cuerpo de Números&amp;rdquo;.&lt;/p>
&lt;h3 id="el-momento-en-que-finalmente-se-rompe-el-cifrado">El momento en que finalmente se rompe el cifrado
&lt;/h3>&lt;p>Cuando se reúnen decenas de millones de &amp;ldquo;tarjetas de polvo de oro&amp;rdquo; de ambos mundos, utilizando los cálculos de matrices gigantes de una supercomputadora, descubrimos las &amp;ldquo;combinaciones donde la cantidad de números primos se vuelve toda par&amp;rdquo; que hicimos en el Capítulo 2.&lt;/p>
&lt;p>Una vez que se encuentra la combinación,&lt;/p>
&lt;ul>
&lt;li>Sea el número al cuadrado creado en el mundo real &lt;strong>$X^2$&lt;/strong>&lt;/li>
&lt;li>Sea la expresión al cuadrado creada en el mundo algebraico &lt;strong>$Y(x)^2$&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Finalmente, sustituimos $x$ en el $Y(x)$ del mundo algebraico por $m$, para teletransportarlo y unirlo al mundo real.
Entonces, como magia matemática, se completa estrictamente el estado en que &lt;strong>&amp;ldquo;el residuo de $X^2$ y $Y^2$ es el mismo&amp;rdquo;&lt;/strong>!&lt;/p>
&lt;p>El resto es como en el Capítulo 1, si calculamos el máximo común divisor de $X - Y$ y $N$, el inexpugnable cifrado RSA colapsa estruendosamente, y los números primos secretos hacen su aparición.&lt;/p>
&lt;hr>
&lt;h2 id="conclusión-las-matemáticas-no-terminan">Conclusión: Las matemáticas no terminan
&lt;/h2>&lt;p>Es posible que hayas pensado: &amp;ldquo;¡Genial, con GNFS se puede romper cualquier cifrado!&amp;rdquo;.
Sin embargo, el cifrado RSA tampoco se queda atrás. Lo que se utiliza en el Internet actual es un número gigantesco monstruoso llamado &amp;ldquo;RSA-2048 (unos 617 dígitos)&amp;rdquo;.&lt;/p>
&lt;p>Aunque GNFS es el algoritmo más fuerte de la humanidad, se dice que incluso para resolver 270 dígitos (RSA-270), llevaría miles o decenas de miles de años incluso conectando las computadoras de todo el mundo. Por ahora, nuestros datos de LINE o bancos están a salvo.&lt;/p>
&lt;p>Sin embargo, ¿qué pasaría si apareciera &lt;strong>&amp;ldquo;una magia para encontrar $X$ e $Y$ en un instante sin importar cuán grande sea el número&amp;rdquo;&lt;/strong>?
En realidad, la existencia más cercana a eso es la &lt;strong>&amp;ldquo;computadora cuántica (Algoritmo de Shor)&amp;rdquo;&lt;/strong> actualmente en desarrollo. Usando las propiedades ondulatorias de la mecánica cuántica, se ha demostrado matemáticamente que se puede ignorar el molesto rompecabezas de recolección de tarjetas y encontrar la respuesta en un solo intento.&lt;/p>
&lt;p>La interminable batalla de ingenio entre los creadores de cifrados (defensa) y los creadores de algoritmos para romperlos (ataque).
Saber que la &amp;ldquo;factorización de primos&amp;rdquo; o el &amp;ldquo;álgebra&amp;rdquo; que se aprenden en la secundaria son en realidad armas que luchan ferozmente en la vanguardia de la seguridad mundial, ¿no hace que las clases de matemáticas parezcan un poco más interesantes?&lt;/p>
&lt;p>¡Podrías ser tú, que estás leyendo este artículo, quien descubra el algoritmo más fuerte del futuro!&lt;/p>
&lt;hr>
&lt;p>&lt;em>(※Este artículo conceptualiza el encanto matemático del criptoanálisis para estudiantes de secundaria. El GNFS real se calcula estrictamente usando matemáticas universitarias avanzadas, como el grupo de clases de ideales de cuerpos algebraicos y homomorfismos)&lt;/em>&lt;/p></description></item></channel></rss>