<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Criptografía on kenji.blog</title><link>http://kenji.blog/es/tags/criptograf%C3%ADa/</link><description>Recent content in Criptografía on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>es</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 22:09:22 +0900</lastBuildDate><atom:link href="http://kenji.blog/es/tags/criptograf%C3%ADa/index.xml" rel="self" type="application/rss+xml"/><item><title>【PQC】La visión completa de la criptografía post-cuántica: La criptografía de próxima generación de la era de las computadoras cuánticas</title><link>http://kenji.blog/es/p/post-quantum-cryptography/</link><pubDate>Sat, 05 Sep 2026 22:09:22 +0900</pubDate><guid>http://kenji.blog/es/p/post-quantum-cryptography/</guid><description>&lt;img src="http://kenji.blog/p/post-quantum-cryptography/post_quantum_cryptography_1788613735417.jpg" alt="Featured image of post 【PQC】La visión completa de la criptografía post-cuántica: La criptografía de próxima generación de la era de las computadoras cuánticas" />&lt;h2 id="introducción-la-amenaza-de-las-computadoras-cuánticas-a-la-criptografía">Introducción: La &amp;ldquo;amenaza&amp;rdquo; de las computadoras cuánticas a la criptografía
&lt;/h2>&lt;p>En la actualidad, gran parte de nuestras comunicaciones diarias en Internet (como los pagos bancarios en línea, la navegación web (HTTPS), los mensajes en aplicaciones de mensajería, el blockchain y las transacciones de criptomonedas) están protegidas por una tecnología llamada &amp;ldquo;criptografía de clave pública&amp;rdquo;. Específicamente, algoritmos como RSA y la criptografía de curva elíptica (ECC) constituyen la base fundamental que sustenta la fiabilidad de nuestra sociedad digital moderna.&lt;/p>
&lt;p>Estos sistemas criptográficos basan su seguridad en problemas matemáticos difíciles, como la &amp;ldquo;factorización de enteros gigantes&amp;rdquo; y el &amp;ldquo;problema del logaritmo discreto&amp;rdquo;, cuya resolución tomaría un tiempo astronómico para las computadoras clásicas actuales (incluyendo las supercomputadoras). Sin embargo, cuando se materialice el rápido progreso reciente y las &lt;strong>&amp;ldquo;computadoras cuánticas&amp;rdquo;&lt;/strong> se vuelvan prácticas, esta premisa se verá alterada desde sus cimientos.&lt;/p>
&lt;p>En 1994, Peter Shor publicó el &amp;ldquo;Algoritmo de Shor&amp;rdquo;, demostrando matemáticamente que una computadora cuántica con suficiente capacidad puede resolver la factorización de enteros y los problemas de logaritmos discretos en muy poco tiempo. Esto significa el riesgo (conocido como Y2Q: Years to Quantum, o el problema Q-Day) de que toda la comunicación cifrada que protege la Internet actual sea descifrada en el futuro.&lt;/p>
&lt;p>Aún más grave es la existencia de una técnica de ataque llamada &amp;ldquo;Cosechar ahora, descifrar después&amp;rdquo; (Harvest Now, Decrypt Later), en la cual los datos se roban y almacenan hoy para descifrarlos en el futuro cuando la tecnología lo permita. Los datos que requieren mantenerse confidenciales durante décadas, como la información clasificada del estado, la propiedad intelectual corporativa y la información biométrica personal, ya podrían ser objeto de robo con la premisa de ser descifrados en el futuro.&lt;/p>
&lt;p>Para hacer frente a esta crisis sin precedentes, criptógrafos e institutos de investigación de todo el mundo están aunando esfuerzos para desarrollar una tecnología criptográfica de próxima generación que pueda mantener la seguridad incluso contra ataques de computadoras cuánticas: la &lt;strong>Criptografía Post-Cuántica (PQC: Post-Quantum Cryptography)&lt;/strong>. En este artículo, explicaremos en detalle desde los fundamentos de la PQC hasta cómo funcionan sus principales algoritmos, así como las últimas tendencias de estandarización global impulsadas por el Instituto Nacional de Estándares y Tecnología de los Estados Unidos (NIST).&lt;/p>
&lt;hr>
&lt;h2 id="qué-es-la-criptografía-post-cuántica-pqc">¿Qué es la Criptografía Post-Cuántica (PQC)?
&lt;/h2>&lt;p>La Criptografía Post-Cuántica (PQC) es un término general para los algoritmos criptográficos diseñados para funcionar en las computadoras clásicas existentes y, al mismo tiempo, ser resistentes a ataques de las computadoras cuánticas a gran escala que surgirán en el futuro (como el algoritmo de Shor).&lt;/p>
&lt;p>A menudo se confunde con tecnologías como la &amp;ldquo;Criptografía Cuántica&amp;rdquo; y la &amp;ldquo;Distribución Cuántica de Claves (QKD)&amp;rdquo;, pero estos son enfoques completamente diferentes. La Criptografía Cuántica (QKD) es una tecnología basada en hardware que utiliza las leyes de la física cuántica (como la propiedad de que la observación altera el estado) para hacer que las escuchas clandestinas en la ruta de comunicación sean físicamente imposibles. Requiere fibra óptica dedicada y equipo especial, lo que presenta desafíos en términos de costos de implementación y limitaciones de distancia.&lt;/p>
&lt;p>Por otro lado, &lt;strong>la PQC es una tecnología criptográfica basada en software fundamentada puramente en &amp;ldquo;matemáticas&amp;rdquo;&lt;/strong>. Por lo tanto, puede incorporarse como actualizaciones de software en la infraestructura de Internet existente, servidores, teléfonos inteligentes, navegadores, etc., lo que la hace altamente aplicable en el mundo real. Las empresas de TI y las agencias gubernamentales de todo el mundo consideran urgente reemplazar (migrar) los actuales RSA y ECC por esta PQC.&lt;/p>
&lt;hr>
&lt;h2 id="los-4-enfoques-matemáticos-principales-que-sustentan-la-pqc">Los 4 enfoques matemáticos principales que sustentan la PQC
&lt;/h2>&lt;p>Se han propuesto varios algoritmos de PQC basados en problemas matemáticos difíciles de resolver de manera eficiente incluso con computadoras cuánticas (como los problemas NP-difíciles). Aquí presentamos las 4 categorías principales que dominan actualmente.&lt;/p>
&lt;h3 id="enfoques-principales-de-la-criptografía-post-cuántica-pqc">Enfoques principales de la Criptografía Post-Cuántica (PQC)
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span class="line">&lt;span class="cl">&lt;span class="n">graph&lt;/span> &lt;span class="n">LR&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PQC&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">Criptografía&lt;/span> &lt;span class="n">Post&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">Cuántica&lt;/span> &lt;span class="n">PQC&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">--&amp;gt;&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">Criptografía&lt;/span> &lt;span class="n">basada&lt;/span> &lt;span class="n">en&lt;/span> &lt;span class="n">retículos&lt;/span> &lt;span class="n">Lattice&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">based&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PQC&lt;/span> &lt;span class="o">--&amp;gt;&lt;/span> &lt;span class="n">H&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">Criptografía&lt;/span> &lt;span class="n">basada&lt;/span> &lt;span class="n">en&lt;/span> &lt;span class="nb">hash&lt;/span> &lt;span class="n">Hash&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">based&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PQC&lt;/span> &lt;span class="o">--&amp;gt;&lt;/span> &lt;span class="n">M&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">Criptografía&lt;/span> &lt;span class="n">multivariante&lt;/span> &lt;span class="n">Multivariate&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PQC&lt;/span> &lt;span class="o">--&amp;gt;&lt;/span> &lt;span class="n">C&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">Criptografía&lt;/span> &lt;span class="n">basada&lt;/span> &lt;span class="n">en&lt;/span> &lt;span class="n">códigos&lt;/span> &lt;span class="n">Code&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">based&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">L&lt;/span> &lt;span class="o">--&amp;gt;&lt;/span> &lt;span class="n">L1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">FIPS&lt;/span> &lt;span class="mi">203&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">ML&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">KEM&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">L&lt;/span> &lt;span class="o">--&amp;gt;&lt;/span> &lt;span class="n">L2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">FIPS&lt;/span> &lt;span class="mi">204&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">ML&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">DSA&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">H&lt;/span> &lt;span class="o">--&amp;gt;&lt;/span> &lt;span class="n">H1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">FIPS&lt;/span> &lt;span class="mi">205&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">SLH&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">DSA&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">style&lt;/span> &lt;span class="n">PQC&lt;/span> &lt;span class="n">fill&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="c1">#f9f,stroke:#333,stroke-width:2px&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="1-criptografía-basada-en-retículos-lattice-based-cryptography">1. Criptografía basada en retículos (Lattice-based Cryptography)
&lt;/h3>&lt;p>Actualmente, la criptografía basada en retículos es la más prometedora y predominante en el campo de la PQC. Su seguridad se fundamenta en problemas relacionados con puntos dispuestos regularmente (puntos de retículo) en espacios multidimensionales. Problemas famosos incluyen el &amp;ldquo;Problema del Vector Más Corto (SVP)&amp;rdquo; y el &amp;ldquo;Aprendizaje con Errores (LWE)&amp;rdquo;.&lt;/p>
&lt;p>&lt;strong>Resumen del funcionamiento:&lt;/strong>
Imagine innumerables puntos dispuestos como una cuadrícula (retículo) en un espacio de altísima dimensión (cientos a miles de dimensiones). Encontrar un punto de retículo específico es fácil en 2 o 3 dimensiones, pero a cientos de dimensiones, no se ha descubierto un algoritmo eficiente para encontrarlo, ni para computadoras clásicas ni cuánticas. El problema LWE, en particular, aprovecha la propiedad de que &amp;ldquo;si se agrega intencionalmente un pequeño &amp;lsquo;ruido (error)&amp;rsquo; a un sistema de ecuaciones lineales, se vuelve drásticamente más difícil adivinar las variables originales&amp;rdquo;.&lt;/p>
&lt;p>&lt;strong>Ventajas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Aplicable tanto a la encapsulación de claves (KEM) como a firmas digitales.&lt;/li>
&lt;li>Velocidad de procesamiento extremadamente rápida (a veces más rápida que RSA y ECC).&lt;/li>
&lt;li>Buen equilibrio entre el tamaño de la clave y el tamaño del texto cifrado.&lt;/li>
&lt;/ul>
&lt;p>Muchos de los algoritmos actualmente estandarizados por el NIST (como ML-KEM y ML-DSA) utilizan esta criptografía basada en retículos.&lt;/p>
&lt;h3 id="2-criptografía-basada-en-hash-hash-based-cryptography">2. Criptografía basada en hash (Hash-based Cryptography)
&lt;/h3>&lt;p>La criptografía basada en hash es un algoritmo PQC especializado en firmas digitales. La base de su seguridad depende únicamente de la resistencia a colisiones y la unidireccionalidad de &amp;ldquo;funciones hash criptográficas&amp;rdquo; seguras como SHA-2 y SHA-3.&lt;/p>
&lt;p>&lt;strong>Resumen del funcionamiento:&lt;/strong>
Comienza con un esquema de firma de un solo uso llamado &amp;ldquo;Firma de Lamport&amp;rdquo;. Al agrupar estas firmas utilizando una estructura de datos en forma de árbol llamada &amp;ldquo;Árbol de Merkle&amp;rdquo;, se permiten múltiples firmas con un solo par de claves.&lt;/p>
&lt;p>&lt;strong>Ventajas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>La base de seguridad es extremadamente robusta; hay una fuerte prueba de que &amp;ldquo;es seguro mientras la función hash sea segura&amp;rdquo;.&lt;/li>
&lt;li>Al depender poco de una estructura matemática, el riesgo de que se descubra un método de descifrado imprevisto es bajo.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Desventajas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Solo se puede usar para firmas digitales, no para el establecimiento de claves (KEM).&lt;/li>
&lt;li>El tamaño de la firma tiende a ser grande.&lt;/li>
&lt;li>Existen variantes &amp;ldquo;con estado&amp;rdquo; (stateful) y &amp;ldquo;sin estado&amp;rdquo; (stateless). Las variantes con estado (como XMSS) requieren una gestión estricta del número de usos de la clave, lo que dificulta su implementación.&lt;/li>
&lt;/ul>
&lt;p>NIST ha estandarizado &amp;ldquo;SLH-DSA (anteriormente SPHINCS+)&amp;rdquo; como una firma basada en hash sin estado.&lt;/p>
&lt;h3 id="3-criptografía-multivariante-multivariate-cryptography">3. Criptografía multivariante (Multivariate Cryptography)
&lt;/h3>&lt;p>La criptografía de polinomios multivariantes basa su seguridad en la dificultad de resolver un sistema de ecuaciones polinómicas cuadráticas simultáneas con múltiples variables (el problema MQ). Se sabe que este problema es NP-difícil.&lt;/p>
&lt;p>&lt;strong>Resumen del funcionamiento:&lt;/strong>
El remitente crea un texto cifrado (firma) sustituyendo el texto sin formato (o el valor hash) en una compleja ecuación con múltiples variables proporcionada como clave pública. El destinatario legítimo posee &amp;ldquo;información oculta (una puerta trasera) que transforma la estructura de la ecuación en una forma fácil de resolver&amp;rdquo; como su clave privada, y la utiliza para descifrar (o verificar la firma).&lt;/p>
&lt;p>&lt;strong>Ventajas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>El tamaño de la firma es muy pequeño.&lt;/li>
&lt;li>La velocidad de verificación de la firma es extremadamente rápida. Adecuado para dispositivos IoT con recursos limitados.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Desventajas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>El tamaño de la clave pública es muy grande (puede ser de decenas a cientos de kilobytes).&lt;/li>
&lt;li>En el pasado, algoritmos prominentes (como Rainbow) han sido quebrados por ataques clásicos, lo que dificulta establecer la confianza en su seguridad en comparación con otros métodos.&lt;/li>
&lt;/ul>
&lt;h3 id="4-criptografía-basada-en-códigos-code-based-cryptography">4. Criptografía basada en códigos (Code-based Cryptography)
&lt;/h3>&lt;p>La criptografía basada en códigos aplica a la criptografía la teoría de los &amp;ldquo;códigos de corrección de errores&amp;rdquo; utilizados para corregir errores en las rutas de comunicación. El &amp;ldquo;criptosistema McEliece&amp;rdquo;, propuesto en 1978, es el más famoso y uno de los más antiguos de la PQC.&lt;/p>
&lt;p>&lt;strong>Resumen del funcionamiento:&lt;/strong>
El remitente codifica el texto sin formato utilizando la clave pública del destinatario (una matriz generadora de un código de corrección de errores con una estructura oculta), agrega un error intencional (ruido) y lo envía. El destinatario elimina el error usando la clave privada y extrae el texto sin formato. El atacante debe corregir el error de un código aparentemente aleatorio sin conocer su estructura, lo que se conoce como el &amp;ldquo;problema general de decodificación de síndrome&amp;rdquo;, probado como NP-difícil.&lt;/p>
&lt;p>&lt;strong>Ventajas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Tras más de 40 años de estudio exhaustivo, no se han encontrado ataques efectivos, lo que le otorga una altísima confianza en su seguridad.&lt;/li>
&lt;li>Procesamiento de cifrado y descifrado rápido.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Desventajas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>El tamaño de la clave pública es gigantesco (puede ser de varios megabytes). Por lo tanto, es difícil de utilizar en entornos con ancho de banda de comunicación o memoria limitados (como en el handshake de TLS).&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="últimas-tendencias-en-la-estandarización-de-pqc-por-parte-del-nist">Últimas tendencias en la estandarización de PQC por parte del NIST
&lt;/h2>&lt;p>El Instituto Nacional de Estándares y Tecnología de los Estados Unidos (NIST) comenzó en 2016 a solicitar algoritmos criptográficos post-cuánticos de próxima generación en todo el mundo, llevando a cabo evaluaciones rigurosas y múltiples rondas durante varios años.&lt;/p>
&lt;p>En 2024, el NIST anunció finalmente los siguientes tres algoritmos como Estándares Federales de Procesamiento de Información (FIPS) oficiales. Esto proporciona una base sólida para que las organizaciones de todo el mundo comiencen a implementarlos en entornos de producción.&lt;/p>
&lt;h3 id="estándares-fips-promulgados-2024">Estándares FIPS Promulgados (2024)
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>FIPS 203: ML-KEM (anteriormente CRYSTALS-Kyber)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Uso:&lt;/strong> Mecanismo de encapsulación de claves (KEM) / Cifrado e intercambio de claves&lt;/li>
&lt;li>&lt;strong>Tecnología base:&lt;/strong> Criptografía de retículos (Module-LWE)&lt;/li>
&lt;li>&lt;strong>Características:&lt;/strong> Excelente equilibrio entre tamaño de clave y velocidad. Actuará como el intercambio de claves PQC predeterminado en aplicaciones comunes de Internet, como la comunicación web (TLS) y las aplicaciones de mensajería segura.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>FIPS 204: ML-DSA (anteriormente CRYSTALS-Dilithium)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Uso:&lt;/strong> Firma digital&lt;/li>
&lt;li>&lt;strong>Tecnología base:&lt;/strong> Criptografía de retículos (Module-LWE)&lt;/li>
&lt;li>&lt;strong>Características:&lt;/strong> El estándar principal para firmas digitales. Permite un procesamiento eficiente y se convertirá en el nuevo estándar para todos los propósitos de firmas electrónicas, como la firma de software y la autenticación de documentos.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>FIPS 205: SLH-DSA (anteriormente SPHINCS+)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Uso:&lt;/strong> Firma digital&lt;/li>
&lt;li>&lt;strong>Tecnología base:&lt;/strong> Criptografía basada en hash (sin estado)&lt;/li>
&lt;li>&lt;strong>Características:&lt;/strong> Juega un papel crucial al actuar como respaldo en caso de que se descubran vulnerabilidades en la criptografía de retículos en el futuro. Aunque el tamaño de la firma es mayor, es adecuado para aplicaciones que requieren confiabilidad a largo plazo.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="en-busca-de-una-mayor-diversidad">En busca de una mayor diversidad
&lt;/h3>&lt;p>Si bien el NIST ha completado su proceso de estandarización inicial, continúa explorando más algoritmos. Debido a que el estándar está fuertemente sesgado hacia la &amp;ldquo;criptografía de retículos&amp;rdquo;, se hace hincapié en asegurar la &lt;strong>&amp;ldquo;Diversidad Criptográfica&amp;rdquo; (Crypto Diversity)&lt;/strong>. Se están evaluando métodos como la criptografía basada en códigos como estándares de respaldo para el intercambio de claves, lo que fortalecerá aún más la base de la PQC en el futuro.&lt;/p>
&lt;hr>
&lt;h2 id="escenarios-y-desafíos-en-la-transición-a-pqc-la-importancia-de-la-agilidad-criptográfica">Escenarios y desafíos en la transición a PQC: La importancia de la &amp;ldquo;Agilidad Criptográfica&amp;rdquo;
&lt;/h2>&lt;p>Con el lanzamiento de las normas oficiales por parte del NIST, agencias gubernamentales, instituciones financieras y empresas tecnológicas de todo el mundo intensificarán su transición (migración) del RSA/ECC existente a PQC. Las pautas de la NSA (Agencia de Seguridad Nacional de EE. UU.) y otros también recomiendan completar esta transición de manera temprana.&lt;/p>
&lt;h3 id="adopción-de-un-enfoque-híbrido">Adopción de un enfoque híbrido
&lt;/h3>&lt;p>Como los algoritmos PQC son nuevos, no han superado la &amp;ldquo;prueba del tiempo&amp;rdquo; en comparación con la criptografía clásica. Considerando el riesgo de posibles errores de implementación o el descubrimiento de nuevos métodos de ataque, se recomienda un &lt;strong>&amp;ldquo;enfoque híbrido&amp;rdquo;&lt;/strong> durante el período de transición. Esto implica combinar criptografía existente probada (por ejemplo, ECDHE) con la nueva PQC (por ejemplo, ML-KEM) para el intercambio de claves. Actualmente, los principales navegadores y servicios en la nube están avanzando rápidamente en implementaciones de prueba de este método.&lt;/p>
&lt;h3 id="lograr-la-agilidad-criptográfica-crypto-agility">Lograr la Agilidad Criptográfica (Crypto-Agility)
&lt;/h3>&lt;p>Lo que las empresas y los desarrolladores de sistemas deben tener más presente en el futuro es asegurar la &lt;strong>&amp;ldquo;Agilidad Criptográfica&amp;rdquo; (Crypto-Agility)&lt;/strong>. Es indispensable diseñar una arquitectura flexible que permita reemplazar y actualizar rápidamente los algoritmos criptográficos sin detener el sistema, en caso de que se descubran fallos en los algoritmos en el futuro o surjan nuevos estándares.&lt;/p>
&lt;p>El primer y crucial paso para la transición a PQC es la creación de un Inventario Criptográfico (CBOM: Cryptography Bill of Materials), que permita saber exactamente &amp;ldquo;dónde&amp;rdquo;, &amp;ldquo;qué criptografía&amp;rdquo; y &amp;ldquo;con qué propósito&amp;rdquo; se está utilizando dentro de los sistemas de la empresa.&lt;/p>
&lt;hr>
&lt;h2 id="conclusión-preparándose-para-el-día-q-q-day">Conclusión: Preparándose para el &amp;ldquo;Día Q&amp;rdquo; (Q-Day)
&lt;/h2>&lt;p>Si bien la evolución de las computadoras cuánticas traerá enormes beneficios a la humanidad, también representa la mayor amenaza para la seguridad criptográfica, que es la columna vertebral de nuestra sociedad digital actual. La Criptografía Post-Cuántica (PQC) ya no es un &amp;ldquo;tema de investigación en un futuro lejano&amp;rdquo;. Con el hito de la publicación de los estándares FIPS por parte del NIST, la PQC ha entrado en una fase de &amp;ldquo;implementación y transición&amp;rdquo; a gran escala.&lt;/p>
&lt;p>Teniendo en cuenta la amenaza de &amp;ldquo;Cosechar ahora, descifrar después&amp;rdquo;, migrar a PQC es una prioridad absoluta que todas las organizaciones que manejan datos altamente confidenciales deben abordar &amp;ldquo;ahora mismo&amp;rdquo;. Comprendiendo profundamente las tecnologías criptográficas de próxima generación y aumentando la agilidad criptográfica de los sistemas, preparémonos para superar de forma segura la inminente era de las computadoras cuánticas.&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><item><title>Principio de Kerckhoffs</title><link>http://kenji.blog/es/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/</link><pubDate>Wed, 16 Apr 2025 23:53:08 +0900</pubDate><guid>http://kenji.blog/es/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/</guid><description>&lt;img src="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_2.png" alt="Featured image of post Principio de Kerckhoffs" />&lt;h1 id="principio-de-kerckhoffs">Principio de Kerckhoffs
&lt;/h1>&lt;hr>
&lt;p>¡Hola!&lt;/p>
&lt;p>Hoy me gustaría hablar sobre un tema un poco interesante y, de hecho, extremadamente importante: el &amp;ldquo;Principio de Kerckhoffs&amp;rdquo;.&lt;/p>
&lt;p>Ah, esperen, esperen.
Quizás algunos de ustedes piensen: &amp;ldquo;Nunca he oído hablar del &amp;lsquo;Principio de Kerckhoffs&amp;rsquo; y suena demasiado técnico&amp;hellip;&amp;rdquo;. No se preocupen. Este artículo está escrito precisamente para ustedes.&lt;/p>
&lt;hr>
&lt;h2 id="qué-significa-una-criptografía-segura">¿Qué significa una &amp;ldquo;criptografía segura&amp;rdquo;?
&lt;/h2>&lt;p>Por ejemplo, imaginen que alguien les dice: &amp;ldquo;Esta caja fuerte solo puede ser abierta por quienes conocen el método secreto&amp;rdquo;.&lt;/p>
&lt;p>A primera vista, eso parece muy seguro, ¿verdad?
Pero, si lo piensan bien, ¿no les da un poco de inquietud?&lt;/p>
&lt;p>Algo así como, &amp;ldquo;¿qué pasa si se descubre ese secreto? ¿Se acabó todo?&amp;rdquo;.&lt;/p>
&lt;p>De hecho, este es el motivo por el cual aparece el Principio de Kerckhoffs.&lt;/p>
&lt;hr>
&lt;h2 id="pero-qué-es-el-principio-de-kerckhoffs">Pero, ¿qué es el &amp;ldquo;Principio de Kerckhoffs&amp;rdquo;?
&lt;/h2>&lt;p>En términos muy generales, es la idea de que:&lt;/p>
&lt;p>&lt;strong>&amp;ldquo;Un sistema criptográfico debe ser seguro incluso si se conoce su funcionamiento.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Dicho de otra manera: &amp;ldquo;La seguridad debe depender únicamente de la &amp;lsquo;clave secreta&amp;rsquo;, ¡y está bien que el método de encriptación en sí sea público!&amp;rdquo;.&lt;/p>
&lt;p>Por el contrario, esto significa que &amp;ldquo;un sistema donde solo el algoritmo (el funcionamiento) es un secreto, se considera poco confiable&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="si-el-funcionamiento-es-secreto-es-seguro-puede-ser-un-poco-peligroso">&amp;ldquo;Si el funcionamiento es secreto, es seguro&amp;rdquo; puede ser un poco peligroso
&lt;/h2>&lt;p>Una forma de pensar muy común es esta:&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Nadie ha visto el interior de esta aplicación, así que la seguridad está bien.&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Entiendo el sentimiento.
Pero, eso es lo mismo que decir &amp;ldquo;como nadie lo ha visto, no encontrarán los defectos, así que estamos a salvo&amp;rdquo;.&lt;/p>
&lt;p>En realidad, el simple hecho de que &amp;ldquo;nadie lo haya visto&amp;rdquo; puede convertirse en un riesgo en sí mismo.&lt;/p>
&lt;hr>
&lt;h2 id="pero-por-qué-es-tan-importante-este-principio">¿Pero por qué es tan importante este principio?
&lt;/h2>&lt;p>La razón es que, si alguien logra descubrir cómo funciona y puede descifrarlo fácilmente, entonces ese sistema criptográfico ya no sirve.&lt;/p>
&lt;p>Para usar una analogía, es como tener una cerradura con un mecanismo muy complejo, pero que resulta que se puede abrir con una llave maestra comprada en una tienda de todo a un dólar.&lt;/p>
&lt;p>Lo importante no es decir &amp;ldquo;estamos seguros porque la llave es secreta&amp;rdquo;, sino &amp;ldquo;incluso si mostramos todo el mecanismo, no se puede abrir sin la llave correcta&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="el-sentimiento-de-pero-no-da-un-poco-de-miedo">El sentimiento de &amp;ldquo;¿pero no da un poco de miedo?&amp;rdquo;
&lt;/h2>&lt;p>Aquí es donde muchas personas sienten:&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Revelar todo el mecanismo, ¿no da un poco de miedo?&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Esa inquietud es comprensible.
Porque es natural pensar: &amp;ldquo;Si muestro todo lo que hay dentro, ¿no me copiarán o lo usarán con malas intenciones?&amp;rdquo;.&lt;/p>
&lt;p>Pero, ahí es exactamente donde radica el núcleo del Principio de Kerckhoffs.
La &amp;ldquo;fortaleza que no se desmorona incluso al mostrar el interior&amp;rdquo; es lo que constituye la verdadera seguridad.&lt;/p>
&lt;hr>
&lt;h2 id="dicho-esto-requiere-un-poco-de-valor-al-principio">Dicho esto, requiere un poco de valor al principio
&lt;/h2>&lt;p>Si nos ponemos en el lugar de los desarrolladores, &amp;ldquo;hacer público el funcionamiento = que se vean las debilidades&amp;rdquo;, y claro, eso da nervios.&lt;/p>
&lt;p>Pero piénsenlo un momento.&lt;/p>
&lt;p>Un sistema que se muestra de forma transparente y dice &amp;ldquo;cualquiera puede verificarlo&amp;rdquo;, al final resulta más confiable.&lt;/p>
&lt;p>Es parecido a las relaciones humanas, ¿verdad?&lt;/p>
&lt;p>&amp;ldquo;Las personas que nos aceptan después de mostrarles nuestro verdadero yo&amp;rdquo; son, al fin y al cabo, las que más tranquilidad nos dan.&lt;/p>
&lt;hr>
&lt;h2 id="en-conclusión">En conclusión
&lt;/h2>&lt;p>El Principio de Kerckhoffs puede sonar un poco teórico, pero su esencia es muy simple.&lt;/p>
&lt;p>Se trata simplemente de:
&lt;strong>&amp;ldquo;Creemos un sistema que no se rompa sin importar a quién se lo mostremos.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Más allá de los secretos superficiales, un diseño sólido.
En lugar de código que no quieres que nadie vea, código que no te dé vergüenza mostrar.&lt;/p>
&lt;p>Ese tipo de &amp;ldquo;fortaleza&amp;rdquo; será cada vez más demandado en los tiempos venideros.&lt;/p>
&lt;hr>
&lt;p>¡Gracias por leer!&lt;/p>
&lt;p>Hablar de seguridad puede ser un poco difícil, pero tiene partes que se conectan con &amp;ldquo;las relaciones humanas&amp;rdquo; o &amp;ldquo;la sensación de seguridad en la vida diaria&amp;rdquo;, ¿verdad?
Sin presiones, si vamos aprendiendo poco a poco, seguro que traerá cosas buenas.&lt;/p>
&lt;hr>
&lt;p>&lt;img src="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img.png"
width="189"
height="282"
srcset="http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_hu715032b7fe5224f655ebb7d29b676305_77325_480x0_resize_box_3.png 480w, http://kenji.blog/p/%E3%82%B1%E3%83%AB%E3%82%AF%E3%83%9B%E3%83%95%E3%82%B9%E3%81%AE%E5%8E%9F%E7%90%86/img_hu715032b7fe5224f655ebb7d29b676305_77325_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="Auguste Kerckhoffs"
class="gallery-image"
data-flex-grow="67"
data-flex-basis="160px"
>&lt;/p></description></item></channel></rss>