<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Criptografia on kenji.blog</title><link>http://kenji.blog/pt/tags/criptografia/</link><description>Recent content in Criptografia on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>pt</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 22:09:22 +0900</lastBuildDate><atom:link href="http://kenji.blog/pt/tags/criptografia/index.xml" rel="self" type="application/rss+xml"/><item><title>【PQC】A Visão Geral da "Criptografia Pós-Quântica", a Criptografia da Próxima Geração na Era da Computação Quântica</title><link>http://kenji.blog/pt/p/post-quantum-cryptography/</link><pubDate>Sat, 05 Sep 2026 22:09:22 +0900</pubDate><guid>http://kenji.blog/pt/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】A Visão Geral da "Criptografia Pós-Quântica", a Criptografia da Próxima Geração na Era da Computação Quântica" />&lt;h2 id="introdução-a-ameaça-dos-computadores-quânticos-à-criptografia">Introdução: A &amp;ldquo;Ameaça&amp;rdquo; dos Computadores Quânticos à Criptografia
&lt;/h2>&lt;p>Atualmente, muitas das comunicações que realizamos diariamente na internet —— desde pagamentos em serviços bancários online, navegação em sites (HTTPS), troca de mensagens em aplicativos, até transações de blockchain e criptomoedas —— são protegidas por uma tecnologia chamada &amp;ldquo;criptografia de chave pública&amp;rdquo;. Especificamente, algoritmos como a criptografia RSA e a criptografia de curva elíptica (ECC) são os pilares que sustentam a confiabilidade da nossa sociedade digital moderna.&lt;/p>
&lt;p>Esses métodos de criptografia baseiam sua segurança em problemas matemáticos complexos, como a &amp;ldquo;fatoração de números primos gigantes&amp;rdquo; e o &amp;ldquo;problema do logaritmo discreto&amp;rdquo;, que levariam um tempo astronômico para serem resolvidos por computadores clássicos atuais (incluindo supercomputadores). No entanto, com a concretização dos &lt;strong>&amp;ldquo;computadores quânticos&amp;rdquo;&lt;/strong> , que têm feito progressos notáveis nos últimos anos, essa premissa será fundamentalmente derrubada.&lt;/p>
&lt;p>O &amp;ldquo;Algoritmo de Shor&amp;rdquo;, publicado por Peter Shor em 1994, provou matematicamente que, se usarmos um computador quântico com desempenho suficiente, poderemos resolver a fatoração de números primos e o problema do logaritmo discreto em um tempo extremamente curto. Isso significa que a comunicação criptografada que protege a internet hoje corre o risco de ser totalmente decodificada no futuro (um problema conhecido como Y2Q: Years to Quantum, ou Q-Day).&lt;/p>
&lt;p>Ainda mais grave é a existência de um método de ataque chamado &amp;ldquo;Harvest Now, Decrypt Later&amp;rdquo; (Roube agora, decifre depois). Dados que precisam manter a confidencialidade por décadas, como informações confidenciais de estados, propriedade intelectual corporativa e informações biométricas pessoais, já podem ser alvo de roubo hoje, com a intenção de serem decodificados no futuro.&lt;/p>
&lt;p>Para responder a essa crise sem precedentes, criptógrafos e instituições de pesquisa em todo o mundo estão trabalhando juntos para desenvolver a criptografia de próxima geração que pode manter a segurança mesmo contra ataques de computadores quânticos, a &lt;strong>Criptografia Pós-Quântica (PQC)&lt;/strong> . Neste artigo, explicaremos em detalhes desde os fundamentos da PQC até os mecanismos de seus principais algoritmos e as tendências mais recentes de padronização global lideradas pelo Instituto Nacional de Padrões e Tecnologia dos EUA (NIST).&lt;/p>
&lt;hr>
&lt;h2 id="o-que-é-a-criptografia-pós-quântica-pqc">O que é a Criptografia Pós-Quântica (PQC)?
&lt;/h2>&lt;p>A Criptografia Pós-Quântica (Post-Quantum Cryptography, PQC) é um termo genérico para algoritmos de criptografia projetados para operar em computadores clássicos existentes e, ao mesmo tempo, serem resistentes a ataques (como o algoritmo de Shor) de computadores quânticos de grande escala que surgirão no futuro.&lt;/p>
&lt;p>Tecnologias frequentemente confundidas com ela são a &amp;ldquo;Criptografia Quântica (Quantum Cryptography)&amp;rdquo; e a &amp;ldquo;Distribuição Quântica de Chaves (QKD)&amp;rdquo;, mas estas são abordagens completamente diferentes. A criptografia quântica (QKD) é uma tecnologia baseada em hardware que utiliza as leis físicas da mecânica quântica (como a propriedade de que o estado muda ao ser observado) para tornar a espionagem nos canais de comunicação fisicamente impossível. Ela requer fibras ópticas dedicadas e equipamentos especiais, enfrentando desafios como custos de implementação e limitações de distância.&lt;/p>
&lt;p>Por outro lado, &lt;strong>a PQC é uma tecnologia de criptografia baseada em software, fundamentada puramente em &amp;ldquo;matemática&amp;rdquo;&lt;/strong> . Portanto, ela pode ser incorporada à infraestrutura de internet existente, servidores, smartphones, navegadores, etc., como uma atualização de software, sendo altamente aplicável ao mundo real. Empresas de TI e governos de todo o mundo consideram urgente substituir (migrar) o RSA e o ECC atualmente em uso por esta PQC.&lt;/p>
&lt;hr>
&lt;h2 id="as-4-principais-abordagens-matemáticas-que-sustentam-a-pqc">As 4 Principais Abordagens Matemáticas que Sustentam a PQC
&lt;/h2>&lt;p>Vários algoritmos de PQC foram propostos, baseando-se em problemas matemáticos complexos (como problemas NP-difíceis) que não podem ser resolvidos de forma eficiente mesmo com um computador quântico. Aqui, apresentaremos as 4 principais categorias que dominam atualmente.&lt;/p>
&lt;h3 id="principais-abordagens-da-criptografia-pós-quântica-pqc">Principais Abordagens da Criptografia Pós-Quâ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">Criptografia&lt;/span> &lt;span class="n">Pós&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">Quâ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">Criptografia&lt;/span> &lt;span class="n">baseada&lt;/span> &lt;span class="n">em&lt;/span> &lt;span class="n">reticulados&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">Criptografia&lt;/span> &lt;span class="n">baseada&lt;/span> &lt;span class="n">em&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">Criptografia&lt;/span> &lt;span class="n">multivariada&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">Criptografia&lt;/span> &lt;span class="n">baseada&lt;/span> &lt;span class="n">em&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-criptografia-baseada-em-reticulados-lattice-based-cryptography">1. Criptografia baseada em reticulados (Lattice-based Cryptography)
&lt;/h3>&lt;p>Atualmente, esta &amp;ldquo;criptografia baseada em reticulados&amp;rdquo; é considerada a mais promissora e é a principal tendência no campo da PQC. A criptografia de reticulados baseia sua segurança em problemas relacionados a pontos dispostos regularmente (pontos de reticulado) em um espaço multidimensional. Problemas famosos incluem o &amp;ldquo;Problema do Vetor Mais Curto (SVP: Shortest Vector Problem)&amp;rdquo; e o &amp;ldquo;Problema de Aprendizado com Erros (LWE: Learning With Errors)&amp;rdquo;.&lt;/p>
&lt;p>&lt;strong>Visão geral do mecanismo:&lt;/strong>
Imagine que inumeráveis pontos estão dispostos em forma de grade (reticulado) dentro de um espaço de dimensão muito alta (centenas a milhares de dimensões). Encontrar um ponto de reticulado específico é fácil em 2 ou 3 dimensões, mas quando se trata de centenas de dimensões, ainda não foi descoberto nenhum algoritmo que o encontre de forma eficiente, seja em um computador clássico ou quântico. O problema LWE, em particular, utiliza a propriedade de que &amp;ldquo;se você adicionar propositalmente um pequeno &amp;lsquo;ruído (erro)&amp;rsquo; a um sistema de equações lineares, torna-se drasticamente mais difícil adivinhar as variáveis originais&amp;rdquo;.&lt;/p>
&lt;p>&lt;strong>Vantagens:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Aplicável tanto ao compartilhamento de chaves (KEM) quanto às assinaturas digitais.&lt;/li>
&lt;li>A velocidade de processamento é muito rápida (em alguns casos, mais rápida que RSA e ECC).&lt;/li>
&lt;li>O tamanho da chave e o tamanho do texto cifrado são relativamente pequenos, oferecendo um bom equilíbrio.&lt;/li>
&lt;/ul>
&lt;p>Muitos dos algoritmos atualmente sendo padronizados pelo NIST (como ML-KEM e ML-DSA) adotam essa criptografia baseada em reticulados.&lt;/p>
&lt;h3 id="2-criptografia-baseada-em-hash-hash-based-cryptography">2. Criptografia baseada em hash (Hash-based Cryptography)
&lt;/h3>&lt;p>A criptografia baseada em hash é um algoritmo PQC especializado em assinaturas digitais. A base de sua segurança depende exclusivamente da resistência à colisão e da unidirecionalidade de &amp;ldquo;funções de hash criptográficas&amp;rdquo; seguras, como SHA-2 e SHA-3.&lt;/p>
&lt;p>&lt;strong>Visão geral do mecanismo:&lt;/strong>
Ela tem como ponto de partida um esquema de assinatura descartável de uso único (assinatura de uso único) chamado &amp;ldquo;Assinatura Lamport (Lamport Signature)&amp;rdquo;. Ao agrupar isso em um formato de dados em estrutura de árvore chamado &amp;ldquo;Árvore de Merkle (Merkle Tree)&amp;rdquo;, possibilita múltiplas assinaturas com um único par de chaves.&lt;/p>
&lt;p>&lt;strong>Vantagens:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>A base de segurança é extremamente robusta, com a forte prova de que &amp;ldquo;é segura desde que a função de hash seja segura&amp;rdquo;.&lt;/li>
&lt;li>Como a dependência de estruturas matemáticas é baixa, o risco de serem descobertos métodos inesperados de decodificação é menor.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Desvantagens:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Não pode ser usada para compartilhamento de chaves (KEM), servindo apenas para assinaturas digitais.&lt;/li>
&lt;li>O tamanho da assinatura tende a ser grande.&lt;/li>
&lt;li>Existem as modalidades &amp;ldquo;stateful&amp;rdquo; (com estado) e &amp;ldquo;stateless&amp;rdquo; (sem estado). A versão stateful (como XMSS) requer um gerenciamento rigoroso do número de vezes que a chave é usada, tornando a implementação mais difícil.&lt;/li>
&lt;/ul>
&lt;p>O NIST padronizou o &amp;ldquo;SLH-DSA (anteriormente SPHINCS+)&amp;rdquo; como uma assinatura baseada em hash stateless.&lt;/p>
&lt;h3 id="3-criptografia-multivariada-multivariate-cryptography">3. Criptografia multivariada (Multivariate Cryptography)
&lt;/h3>&lt;p>A criptografia de polinômios multivariados baseia sua segurança na dificuldade de resolver um sistema de equações polinomiais quadráticas simultâneas com muitas variáveis (Problema MQ: Multivariate Quadratic problem). Sabe-se que este problema é NP-difícil.&lt;/p>
&lt;p>&lt;strong>Visão geral do mecanismo:&lt;/strong>
O remetente cria um texto cifrado (assinatura) substituindo o texto simples (ou valor de hash) em uma equação complexa com muitas variáveis fornecida como chave pública. O destinatário legítimo possui como chave privada uma &amp;ldquo;informação oculta (alçapão) que converte a estrutura da equação em uma forma fácil de resolver&amp;rdquo;, usando-a para realizar a decodificação (ou verificação de assinatura).&lt;/p>
&lt;p>&lt;strong>Vantagens:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>O tamanho da assinatura é muito pequeno.&lt;/li>
&lt;li>A velocidade de verificação da assinatura é extremamente alta. É adequado para dispositivos de IoT com recursos limitados.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Desvantagens:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>O tamanho da chave pública é muito grande (pode chegar a dezenas ou centenas de kilobytes).&lt;/li>
&lt;li>No passado, algoritmos proeminentes (como Rainbow) foram quebrados por ataques clássicos, tornando mais difícil estabelecer a confiança na segurança em comparação com outros métodos.&lt;/li>
&lt;/ul>
&lt;h3 id="4-criptografia-baseada-em-códigos-code-based-cryptography">4. Criptografia baseada em códigos (Code-based Cryptography)
&lt;/h3>&lt;p>A criptografia baseada em códigos aplica a teoria dos &amp;ldquo;códigos de correção de erros&amp;rdquo;, usados para corrigir erros nos canais de comunicação, à criptografia. A &amp;ldquo;Criptografia McEliece&amp;rdquo;, proposta em 1978, é a mais famosa e uma das mais antigas entre as PQC.&lt;/p>
&lt;p>&lt;strong>Visão geral do mecanismo:&lt;/strong>
O remetente codifica o texto simples usando a chave pública do destinatário (a matriz geradora de um código de correção de erros que oculta uma estrutura específica), adiciona um erro intencional (ruído) e o envia. O destinatário usa a chave privada para remover o erro e extrair o texto simples. Um decodificador precisaria corrigir os erros a partir de um código aleatório sem conhecer sua estrutura; isso é chamado de &amp;ldquo;problema geral de decodificação de síndrome&amp;rdquo;, que é comprovadamente NP-difícil.&lt;/p>
&lt;p>&lt;strong>Vantagens:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Tendo sido exaustivamente estudada por mais de 40 anos e sem nenhum ataque eficaz encontrado até agora, a confiança na sua segurança é extremamente alta.&lt;/li>
&lt;li>Os processos de criptografia e descriptografia são rápidos.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Desvantagens:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>O tamanho da chave pública é imenso (pode chegar a vários megabytes). Portanto, é difícil usá-la em ambientes com limitações de largura de banda de comunicação ou memória (como no handshake de TLS).&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="tendências-recentes-na-padronização-pqc-pelo-nist">Tendências Recentes na Padronização PQC pelo NIST
&lt;/h2>&lt;p>O Instituto Nacional de Padrões e Tecnologia dos EUA (NIST) iniciou em 2016 uma chamada global para algoritmos de criptografia pós-quântica de próxima geração, realizando avaliações rigorosas e várias rodadas de análises ao longo de anos.&lt;/p>
&lt;p>Em 2024, o NIST finalmente anunciou os seguintes três algoritmos como Padrões Federais de Processamento de Informações (FIPS) oficiais. Isso concluiu a formação de uma base sólida para que organizações em todo o mundo comecem a implementá-los em ambientes de produção.&lt;/p>
&lt;h3 id="padrões-fips-estabelecidos-2024">Padrões FIPS Estabelecidos (2024)
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>FIPS 203: ML-KEM (Nome anterior: CRYSTALS-Kyber)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Uso:&lt;/strong> Mecanismo de encapsulamento de chaves (KEM) / Criptografia e compartilhamento de chaves&lt;/li>
&lt;li>&lt;strong>Tecnologia base:&lt;/strong> Criptografia baseada em reticulados (Module-LWE)&lt;/li>
&lt;li>&lt;strong>Características:&lt;/strong> Oferece um excelente equilíbrio entre o tamanho da chave e a velocidade. Servirá como o compartilhamento de chaves PQC padrão para usos comuns da internet, como comunicação na Web (TLS) e aplicativos de mensagens seguros.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>FIPS 204: ML-DSA (Nome anterior: CRYSTALS-Dilithium)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Uso:&lt;/strong> Assinatura digital&lt;/li>
&lt;li>&lt;strong>Tecnologia base:&lt;/strong> Criptografia baseada em reticulados (Module-LWE)&lt;/li>
&lt;li>&lt;strong>Características:&lt;/strong> O principal padrão para assinaturas digitais. Permite processamento eficiente, tornando-se o novo padrão para todas as aplicações de assinatura eletrônica, como assinaturas de software e autenticação de documentos.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>FIPS 205: SLH-DSA (Nome anterior: SPHINCS+)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Uso:&lt;/strong> Assinatura digital&lt;/li>
&lt;li>&lt;strong>Tecnologia base:&lt;/strong> Criptografia baseada em hash (stateless)&lt;/li>
&lt;li>&lt;strong>Características:&lt;/strong> Desempenha um papel vital como um backup caso vulnerabilidades sejam descobertas na criptografia baseada em reticulados no futuro. Embora o tamanho da assinatura seja grande, é adequado para aplicações que exigem confiabilidade de longo prazo.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="busca-por-maior-diversidade">Busca por Maior Diversidade
&lt;/h3>&lt;p>Embora o NIST tenha concluído o processo inicial de padronização, ele continua buscando mais algoritmos. Especialmente porque os padrões estão muito inclinados para a &amp;ldquo;criptografia baseada em reticulados&amp;rdquo;, a garantia da &lt;strong>diversidade de algoritmos (Crypto Diversity)&lt;/strong> é altamente valorizada. A avaliação da criptografia baseada em códigos e outros métodos está em andamento como padrão de backup para compartilhamento de chaves, e a base da PQC deve se tornar ainda mais robusta no futuro.&lt;/p>
&lt;hr>
&lt;h2 id="cenários-e-desafios-da-transição-para-a-pqc-a-importância-da-agilidade-criptográfica">Cenários e Desafios da Transição para a PQC: A Importância da &amp;ldquo;Agilidade Criptográfica&amp;rdquo;
&lt;/h2>&lt;p>Com o lançamento de padrões oficiais pelo NIST, agências governamentais, instituições financeiras e empresas de tecnologia em todo o mundo acelerarão a transição (migração) do RSA/ECC existente para a PQC. Diretrizes de agências como a NSA (Agência de Segurança Nacional dos EUA) também recomendam a conclusão antecipada dessa transição.&lt;/p>
&lt;h3 id="adoção-da-abordagem-híbrida">Adoção da Abordagem Híbrida
&lt;/h3>&lt;p>Como os algoritmos PQC são novos, eles não passaram pelo &amp;ldquo;teste do tempo&amp;rdquo; em comparação com a criptografia clássica. Considerando os riscos de bugs ocultos em implementações ou a descoberta de novos métodos de ataque, recomenda-se uma &lt;strong>&amp;ldquo;abordagem híbrida&amp;rdquo;&lt;/strong> durante o período de transição. Isso envolve realizar a troca de chaves combinando criptografia existente e comprovada (por exemplo, ECDHE) com a nova PQC (por exemplo, ML-KEM). Atualmente, as principais implementações de teste dessa abordagem estão avançando rapidamente em navegadores e serviços em nuvem.&lt;/p>
&lt;h3 id="atingindo-a-agilidade-criptográfica-crypto-agility">Atingindo a Agilidade Criptográfica (Crypto-Agility)
&lt;/h3>&lt;p>O que empresas e desenvolvedores de sistemas devem ter mais em mente daqui para frente é garantir a &lt;strong>&amp;ldquo;Agilidade Criptográfica (Crypto-Agility)&amp;rdquo;&lt;/strong> . É essencial ter um projeto arquitetônico flexível que permita a substituição e atualização rápida dos algoritmos de criptografia sem paralisar o sistema, caso falhas sejam encontradas nos algoritmos no futuro ou surjam novos padrões.&lt;/p>
&lt;p>Criar um inventário criptográfico (CBOM: Cryptography Bill of Materials) que identifique com precisão &amp;ldquo;onde&amp;rdquo;, &amp;ldquo;qual criptografia&amp;rdquo; e &amp;ldquo;para qual propósito&amp;rdquo; está sendo usada dentro do sistema da empresa é um primeiro passo vital em direção à transição para PQC.&lt;/p>
&lt;hr>
&lt;h2 id="conclusão-preparando-se-para-o-q-day-iminente">Conclusão: Preparando-se para o &amp;ldquo;Q-Day&amp;rdquo; Iminente
&lt;/h2>&lt;p>A evolução dos computadores quânticos trará enormes benefícios à humanidade, mas ao mesmo tempo representa a maior ameaça à segurança criptográfica que é a base de nossa sociedade digital moderna. A Criptografia Pós-Quântica (PQC) não é mais um &amp;ldquo;tema de pesquisa para um futuro distante&amp;rdquo;. Com o marco da publicação dos padrões FIPS pelo NIST, a PQC entrou na fase de &amp;ldquo;implementação e transição&amp;rdquo; em larga escala.&lt;/p>
&lt;p>Considerando a ameaça do &amp;ldquo;Harvest Now, Decrypt Later&amp;rdquo;, a transição para a PQC é a maior prioridade a ser tratada &amp;ldquo;agora mesmo&amp;rdquo; por todas as organizações que lidam com dados altamente confidenciais. Ao entender profundamente as tecnologias de criptografia de próxima geração e aumentar a agilidade criptográfica dos sistemas, poderemos superar com segurança a iminente era dos computadores quânticos.&lt;/p></description></item><item><title>【Análise Completa】Entendendo e Implementando o Mais Forte Algoritmo de Quebra de Criptografia 'GNFS' em C++</title><link>http://kenji.blog/pt/p/gnfs-cpp-implementation/</link><pubDate>Sat, 05 Sep 2026 13:04:59 +0900</pubDate><guid>http://kenji.blog/pt/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álise Completa】Entendendo e Implementando o Mais Forte Algoritmo de Quebra de Criptografia 'GNFS' em C++" />&lt;h1 id="análise-completaentendendo-e-implementando-o-mais-forte-algoritmo-de-quebra-de-criptografia-gnfs-em-c">【Análise Completa】Entendendo e Implementando o Mais Forte Algoritmo de Quebra de Criptografia &amp;ldquo;GNFS&amp;rdquo; em C++
&lt;/h1>&lt;p>A criptografia RSA, que sustenta a internet moderna, baseia-se na crença matemática de que &amp;ldquo;é virtualmente impossível para os computadores atuais fatorar números compostos gigantescos&amp;rdquo;.&lt;/p>
&lt;p>No entanto, a humanidade nunca desistiu. Atualmente, existe o &lt;strong>mais forte e avançado algoritmo&lt;/strong> da humanidade para a fatoração de grandes números primos em computadores clássicos (não quânticos). É o &lt;strong>&amp;ldquo;General Number Field Sieve (GNFS - Crivo Geral do Corpo de Números)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Neste artigo, publicaremos o código de implementação completo que modela estritamente a lógica de computação mais avançada do GNFS em C++ (usando os inteiros de multiprecisão &lt;code>boost::multiprecision&lt;/code> da biblioteca Boost), e explicaremos minuciosamente as profundezas da &amp;ldquo;teoria algébrica dos números&amp;rdquo; por trás dele.&lt;/p>
&lt;p>Por favor, aproveite os mistérios da matemática e a força bruta da ciência da computação que os domina, juntamente com o código-fonte.&lt;/p>
&lt;hr>
&lt;h2 id="1-framework-de-lógica-gnfs-avançado-código-fonte-completo">1. Framework de Lógica GNFS Avançado (Código Fonte Completo)
&lt;/h2>&lt;p>Primeiro, apresentaremos o quadro geral da implementação C++ do GNFS que explicaremos desta vez. Embora o GNFS real (como o CADO-NFS) seja um enorme sistema distribuído que abrange centenas de milhares de linhas, este código extrai e modela as &lt;strong>&amp;ldquo;5 pipelines (fases) essenciais&amp;rdquo;&lt;/strong> que compõem o GNFS no design de classes, na configuração mínima, sem perder seu 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;span class="lnt">228
&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 inteiros de multiprecisão do 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] Framework Lógico Avançado do General Number Field Sieve (Crivo Geral do Corpo de Números)
&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 estritamente os 5 pipelines avançados do GNFS usados
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// no CADO-NFS etc., como o design de classes 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: Polynomial Selection (Seleção 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">// Polinômio do lado algébrico 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">// Polinômio do 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">// Geração do polinômio inicial baseado na expansão base-m (Na realidade, usa a redução de base reticulada LLL, que é mais avançada)
&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] Seleção Polinomial (Grau &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">// Expansão base-m simples (grau 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">// Aproximação simples de m (Aproximação sem usar as funções do 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] Concluída.&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 (Crivo de Reticulado)
&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">// Nos últimos anos, em vez de Line Sieve (Crivo de Linha), o Special-q Lattice Sieving (Crivo de Reticulado q Especial)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// de Franke-Kleinjung e outros é o padrão de fato.
&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] Gerando Bases de Fator (Limite 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;, Limite Algébrico: &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) Na realidade, ele gera números primos e restringe usando o 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 ativo...&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">// Implementação simulada: O crivo de reticulado real varre centenas de GB de espaço de memória em unidades de bloco.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Mapeia o par (a, b) para a grade para cada primo especial q (a = i*q + j*...) e
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// executa um sieve (crivo) que maximiza a eficiência do cache ao limite.
&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">// Adicionando uma relação simulada para fins de demonstração
&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; relações.&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 (Expurgo de Singularidades e Fusão 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 Relações...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. Singleton removal (Remoção de relações com números primos que aparecem apenas uma 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. Clique merging (Fusão de relações para tornar uma matriz esparsa em uma matriz densa)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Na verdade, comprime matrizes de centenas de milhões de linhas em alguns milhões 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] Tamanho da matriz reduzido idealmente.&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: Linear Algebra over 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">// Em ambientes de supercomputadores recentes, o Método Block Wiedemann (Implementação de Coppersmith)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// é usado como a tecnologia mais avançada porque é mais adequado para computação distribuída
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// do que o 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 de 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">// Repete a operação de produto da matriz esparsa e vetor,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// e encontra vários vetores de solução (kernel) em que 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 dependências
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Dados simulados
&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; dependências lineares (quadrados perfeitos).&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: Algebraic Square Root (Raiz Quadrada Algébrica)
&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] Computação da Raiz Quadrada Algébrica...&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 da raiz quadrada V no lado racional (Operação de inteiro simples)
&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 da raiz quadrada gamma no lado algébrico (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">// Obtém o elemento gamma do enorme corpo algébrico O_K e o mapeia para o mundo real com o 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">// Pressupõe que sequências de Caracteres Quadráticos (Quadratic Characters)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// foram adicionadas nas Fases 2 e 4 para evitar a obstrução (Obstruction) do grupo de classes de ideais e o 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;[SUCESSO] Fator não 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; Outro fator: &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;[FALHA] Solução trivial. Tentando próxima dependência...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ============================================================================
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Main Execution Pipeline (Pipeline de Execução 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 do 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">// O grande número composto N que queremos fatorar, como 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">// Grau do polinômio (Normalmente, de 5º a 6º grau é selecionado para números com mais de 130 dígitos)
&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">// Inicializando pipelines
&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">// Na realidade, os limites são dezenas de milhões a centenas de milhões
&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. Seleção 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. Processamento do Sieve (Crivo)
&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. Filtragem (Compressão 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 Linear (Busca de espaço nulo (Nullspace) em 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 da Raiz Quadrada Algébrica e 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 GNFS Avançado concluído em &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>Então, como este código quebra os muros da criptografia? Explicaremos detalhadamente a matemática avançada e os algoritmos precisos para cada uma das 5 fases.&lt;/p>
&lt;hr>
&lt;h2 id="2-objetivo-final-do-gnfs-x2-equiv-y2-pmod-n">2. Objetivo Final do GNFS: $X^2 \equiv Y^2 \pmod N$
&lt;/h2>&lt;p>O objetivo da maioria dos algoritmos modernos de fatoração de grandes números, não apenas o GNFS, é encontrar um par não trivial $(X, Y)$ que satisfaça a seguinte congruência:&lt;/p>
$$X^2 \equiv Y^2 \pmod N$$
&lt;p>Esta fórmula significa que &amp;ldquo;o resto de $X^2$ e $Y^2$ quando divididos por $N$ é o mesmo&amp;rdquo;. Se reescrevermos isso, obtemos:
$X^2 - Y^2 \equiv 0 \pmod N$
Em outras palavras, $(X-Y)(X+Y)$ é um múltiplo de $N$.&lt;/p>
&lt;p>Se $X \not\equiv \pm Y \pmod N$ (uma solução não trivial), então haverá um &amp;ldquo;divisor comum maior que 1 e menor que $N$&amp;rdquo; entre $(X-Y)$ e $N$.
Aqui, usando o algoritmo de Euclides para calcular &lt;strong>$\gcd(X-Y, N)$&lt;/strong> , os fatores primos de $N$ podem ser encontrados muito facilmente.&lt;/p>
&lt;p>No entanto, encontrar esses $X$ e $Y$ é como procurar uma agulha em um palheiro. Portanto, o GNFS tem uma abordagem genial: criar &lt;strong>dois mundos&lt;/strong> - &amp;ldquo;o mundo dos inteiros reais&amp;rdquo; e &amp;ldquo;o mundo dos corpos algébricos dos polinômios&amp;rdquo; - e distribuir a computação.&lt;/p>
&lt;hr>
&lt;h2 id="3-fase-1-seleção-polinomial-polynomial-selection">3. Fase 1: Seleção 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) e expansão 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>O primeiro passo do GNFS é criar os &amp;ldquo;polinômios mágicos&amp;rdquo; para fazer a ponte entre os dois mundos.
Para um número muito grande $N$, escolhemos um número inteiro $m$. Normalmente o escolhemos de modo que $m \approx N^{1/d}$ (no código, assumimos um polinômio de grau $d=6$).&lt;/p>
&lt;p>Em seguida, o $N$ é expandido na base $m$, e esses coeficientes são usados para construir um polinômio $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 polinômio $f(x)$ tem uma propriedade muito importante: &lt;strong>&amp;ldquo;Se substituirmos $x$ por $m$, o resultado será exatamente $N$ ($f(m) = N$)&amp;rdquo;&lt;/strong> . Em outras palavras, $f(m) \equiv 0 \pmod N$.
O polinômio do lado racional é definido como $g(x) = x - m$.&lt;/p>
&lt;p>Com isso, &amp;ldquo;o mundo do corpo algébrico $\mathbb{Z}[\alpha]$&amp;rdquo; governado pela raiz $\alpha$ de $f(x)=0$, e &amp;ldquo;o mundo dos números racionais (inteiros) $\mathbb{Z}$&amp;rdquo; estão fortemente ligados pelo &amp;ldquo;mapa de homomorfismo de anel&amp;rdquo; $x \to m$.&lt;/p>
&lt;p>No CADO-NFS mais avançado, usa-se o algoritmo de KleinJung ou o algoritmo de redução de base de reticulado LLL para passar meses procurando o &amp;ldquo;polinômio mais conveniente $f(x)$&amp;rdquo; cujos coeficientes não são extremamente grandes e em que os números primos são mais propensos a aparecer (lisos) nas etapas subsequentes.&lt;/p>
&lt;hr>
&lt;h2 id="4-fase-2-crivo-de-reticulado-q-especial-special-q-lattice-sieving">4. Fase 2: Crivo de Reticulado $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">// Mapeia os pares (a, b) para reticulados baseados em cada número 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">// e executa o sieve (crivo) de forma muito eficiente usando a memória cache.
&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>Com os dois mundos prontos, o próximo passo é procurar &amp;ldquo;números lisos&amp;rdquo; (números compostos apenas por números primos pequenos) em ambos os mundos.
Geramos inúmeros pares de inteiros $(a, b)$ e calculamos os dois valores a seguir:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Valor racional:&lt;/strong> $a - bm$&lt;/li>
&lt;li>&lt;strong>Norma algébrica:&lt;/strong> $b^d f(a/b)$&lt;/li>
&lt;/ol>
&lt;p>O objetivo do GNFS é coletar de dezenas a centenas de milhões desses &lt;strong>&amp;ldquo;pares (Relação) em que os valores dos lados racional e algébrico podem ser completamente decompostos em fatores primos pequenos&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>No GNFS inicial, era usado o &amp;ldquo;Line Sieve&amp;rdquo; (Crivo de Linha), no qual $(a, b)$ são alinhados em um plano $xy$ e sequencialmente divididos por números primos da borda. Mas esse método apresentava a fraqueza de ser muito lento por acessar memórias espalhadas causando muitos erros de cache.&lt;/p>
&lt;p>Por isso, na vanguarda, utiliza-se a técnica &lt;strong>&amp;ldquo;Crivo de Reticulado $q$ Especial (Special-q Lattice Sieve)&amp;rdquo;&lt;/strong>.
Isso fixa um número primo consideravelmente grande $q$ e visa calcular apenas &amp;ldquo;os pares $(a, b)$ nos quais o valor algébrico é sempre divisível por $q$&amp;rdquo;. Os $(a, b)$ que satisfazem essa condição formam uma &amp;ldquo;Lattice&amp;rdquo; (Reticulado) no plano. Então, a largura do salto dos endereços de memória a calcular torna-se constante, o que se adapta perfeitamente aos caches L1/L2 da CPU.
Graças a essa introdução do Crivo de Reticulado, a velocidade de computação do GNFS aumentou drasticamente.&lt;/p>
&lt;hr>
&lt;h2 id="5-fase-3-filtragem-filtering">5. Fase 3: Filtragem (Filtering)
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">Filter&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="n">reduce_matrix&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Relation&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">relations&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. Singleton removal (Remoção de relações com números primos que aparecem apenas uma 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. Clique merging (Fusão de relações para tornar uma matriz esparsa em uma matriz densa)
&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>Na Fase 2, as relações coletadas ao longo de meses por computadores em todo o mundo somam centenas de milhões. No entanto, se inserirmos isso como está no próximo passo de &amp;ldquo;resolução do sistema de equações&amp;rdquo; (cálculo de matriz), a memória dos supercomputadores falhará.&lt;/p>
&lt;p>Portanto, ocorre um processo de supercompressão de matriz chamado &lt;strong>Filtering (Filtragem)&lt;/strong> .&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Singleton removal (Expurgo de singularidades):&lt;/strong>
Suponha que um número primo enorme $p$ apareça &amp;ldquo;apenas uma vez&amp;rdquo; entre as centenas de milhões de relações. Nosso objetivo é &amp;ldquo;tornar o expoente de todos os números primos um número par (múltiplo de 2)&amp;rdquo;; os números primos que aparecem apenas uma vez nunca podem ser tornados pares.
Portanto, a relação que inclui aquele número primo é imediatamente removida (expurgada) como &amp;ldquo;lixo sem utilidade&amp;rdquo;. Quando isso acontece em cadeia, os dados que antes eram de centenas de milhões de linhas são sistematicamente reduzidos.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Clique merging (Fusão de cliques):&lt;/strong>
Ao cruzar e somar relações que compartilham um número primo em comum, diminuímos o número de linhas e, simultaneamente, transformamos a matriz esparsa (cheia de zeros) numa matriz mais densa (método semelhante à busca de cliques na teoria dos grafos).&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Com essas otimizações, a gigantesca matriz esparsa é comprimida a um tamanho possível de calcular.&lt;/p>
&lt;hr>
&lt;h2 id="6-fase-4-álgebra-linear-em-gf2-método-block-wiedemann">6. Fase 4: Álgebra Linear em 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">// Repete a operação de produto da matriz esparsa e vetor,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// e encontra vários vetores de solução (kernel) em que 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>Finalmente, a essência do quebra-cabeça.
Multiplicamos as relações recolhidas buscando as &lt;strong>&amp;ldquo;combinações que tornam o expoente de todos os fatores primos par&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Em termos matemáticos, isso equivale a encontrar um vetor de solução $x$ (espaço nulo / kernel) onde, utilizando uma matriz gigante $M$ com elementos sendo o expoente de cada número primo no &amp;ldquo;par ou ímpar (ou seja, 0 ou 1)&amp;rdquo; e um vetor $x$ que diz quais relações usar, temos:
&lt;strong>$M \cdot x \equiv 0 \pmod 2$&lt;/strong>&lt;/p>
&lt;p>É necessário resolver equações simultâneas de uma matriz de milhões de linhas por milhões de colunas. O uso tradicional do método de eliminação de Gauss levaria $O(N^3)$ em tempo de cálculo e não acabaria antes do fim do universo.&lt;/p>
&lt;p>Por esse motivo, as implementações de ponta utilizam o &lt;strong>&amp;ldquo;Método de Block Wiedemann&amp;rdquo;&lt;/strong>.
Esse método aproveita que a matriz $M$ é &amp;ldquo;extremamente esparsa (quase totalmente zeros)&amp;rdquo; para obter a solução multiplicando iterativamente matrizes por vetores. É um tipo de método do subespaço de Krylov.
Diferente do antigo Block Lanczos, o método Block Wiedemann pode particionar totalmente o processo computacional entre vários clusters, tornando seu uso extremamente valioso em clusters modernos e em sistemas paralelos de computação distribuída (cloud e supercomputadores).&lt;/p>
&lt;hr>
&lt;h2 id="7-fase-5-raiz-quadrada-algébrica-algebraic-square-root-e-o-colapso-criptográfico">7. Fase 5: Raiz Quadrada Algébrica (Algebraic Square Root) e o Colapso Criptográfico
&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 da raiz quadrada V no lado racional
&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 da raiz quadrada gamma no lado algébrico
&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>Pelo cálculo matricial na Fase 4, adquirimos o &amp;ldquo;conjunto de relações $S$ cujos expoentes de todos os fatores primos formam um expoente par quando multiplicados juntos&amp;rdquo;.
Isto possibilita construir o &amp;ldquo;quadrado perfeito&amp;rdquo; em ambos os mundos: o lado racional e o lado algébrico.&lt;/p>
&lt;p>No lado racional, o cálculo é uma simples multiplicação de números inteiros, por isso é simples calcular sua raiz quadrada $V$.
&lt;/p>
$$V^2 = \prod_{S} (a - bm)$$
&lt;p>&lt;strong>Porém, o real pesadelo encontra-se no &amp;ldquo;lado algébrico&amp;rdquo;.&lt;/strong>
No mundo do corpo algébrico $\mathbb{Z}[\alpha]$, dado que a unicidade da fatoração em primos não é mantida, realizávamos cálculos usando ideais. A garantia dada pelo cálculo matricial era &lt;strong>&amp;ldquo;apenas que seria o quadrado de um ideal, e não garantia que seria o quadrado de um elemento ($\gamma^2$)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Deste modo, surge uma imensa barreira provinda da teoria algébrica dos números, as chamadas &amp;ldquo;Obstrução do grupo de classes de ideais&amp;rdquo; e a &amp;ldquo;Obstrução do grupo das unidades&amp;rdquo;.
No GNFS, usamos a mágica do &lt;strong>&amp;ldquo;Caracter Quadrático (Quadratic Characters)&amp;rdquo;&lt;/strong> para quebrar essa parede.
Inserimos sorrateiramente várias colunas de símbolos residuais quadráticos (símbolos de Legendre) na matriz da Fase 4 para uma dezena de números ideais primos, de forma que a chance de as obstruções sumirem aumente brutalmente, e que assim, garantam finalmente &amp;ldquo;o autêntico quadrado de um elemento $\gamma^2$&amp;rdquo;.&lt;/p>
&lt;p>Em seguida, calcula-se o $\gamma$ (raiz quadrada algébrica) usando algoritmos complexos, como o método de Montgomery.&lt;/p>
&lt;p>Por último, fazemos a raiz algébrica $\gamma$ sofrer um &amp;ldquo;warp&amp;rdquo; para o mundo verdadeiro usando o mapa de homomorfismo de anéis $\phi$ (substituindo $x$ por $m$) para encontrar $Y$.
Quando colocamos o $V$ do lado racional para ser o $X$, a equação absoluta cobiçada está finalmente perfeita.&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>O restante é somente resolver o $\gcd(X-Y, N)$. Em milissegundos o processo acaba e exibe o fator não trivial impresso na tela. Nesse instante, a criptografia impenetrável RSA é inteiramente derrubada.&lt;/p>
&lt;hr>
&lt;h2 id="conclusão">Conclusão
&lt;/h2>&lt;p>O GNFS não é só uma técnica de programação.
Trata-se de forçar as &amp;ldquo;profundezas da matemática pura&amp;rdquo; como álgebra abstrata, teoria dos anéis e os grupos de classe ideal através do poder colossal da &amp;ldquo;engenharia extrema&amp;rdquo;, como arquitetura de computadores distribuída em supercomputadores, além de otimizações de cache; um pilar glorioso da mente humana.&lt;/p>
&lt;p>Por trás de transações por cartão de crédito ou simples chats do dia-a-dia, encontra-se esta astronômica barreira defensiva construída através do poderio e batalha da matemática.&lt;/p>
&lt;p>Espero que compreendam que, na retaguarda dos fortes algoritmos criptográficos, existe um &amp;ldquo;romance dos computadores com a matemática&amp;rdquo; oculto neste simples framework em C++.&lt;/p></description></item><item><title>A Verdadeira Estrutura Matemática do Crivo Geral dos Corpos de Números (GNFS)</title><link>http://kenji.blog/pt/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/pt/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 A Verdadeira Estrutura Matemática do Crivo Geral dos Corpos de Números (GNFS)" />&lt;h1 id="a-verdadeira-estrutura-matemática-do-crivo-geral-dos-corpos-de-números-gnfs">A Verdadeira Estrutura Matemática do Crivo Geral dos Corpos de Números (GNFS)
&lt;/h1>&lt;p>O objetivo final do GNFS é encontrar $X, Y$ tais que $X^2 \equiv Y^2 \pmod N$.
Para alcançar isso, os matemáticos construíram uma ponte entre o &lt;strong>&amp;ldquo;mundo dos inteiros reais&amp;rdquo;&lt;/strong> e o &lt;strong>&amp;ldquo;mundo dos corpos algébricos&amp;rdquo;&lt;/strong> . Essa ponte é exatamente o &amp;ldquo;homomorfismo&amp;rdquo;.&lt;/p>
&lt;h2 id="fase-1-conectando-os-mundos-com-homomorfismo">Fase 1: Conectando os mundos com &amp;ldquo;Homomorfismo&amp;rdquo;
&lt;/h2>&lt;h3 id="1-seleção-do-polinômio-e-definição-das-raízes">1. Seleção do polinômio e definição das raízes
&lt;/h3>&lt;p>Para um número composto gigante $N$, escolhemos um inteiro $m$ e um polinômio $f(x)$ tais que $f(m) \equiv 0 \pmod N$.
(Exemplo: Expandimos $N$ na base $m$ e criamos $f(x)$ a partir de seus coeficientes. Neste momento, assumimos que $f(x)$ é irredutível sobre o corpo dos números racionais $\mathbb{Q}$ (não pode ser mais fatorado)).&lt;/p>
&lt;p>Em seguida, definimos uma das &amp;ldquo;raízes complexas&amp;rdquo; da equação $f(x) = 0$ como $\alpha$.
Naturalmente, $f(\alpha) = 0$. $\alpha$ não é um número inteiro, mas um número complexo envolvendo raízes e números imaginários (um número algébrico).&lt;/p>
&lt;h3 id="2-construção-de-anéis-rings-e-homomorfismo">2. Construção de Anéis (Rings) e Homomorfismo
&lt;/h3>&lt;p>Aqui, preparamos dois &amp;ldquo;anéis&amp;rdquo; matemáticos (mundos onde adição e multiplicação são definidas).&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mundo A: $\mathbb{Z}[\alpha]$&lt;/strong> (O anel dos inteiros algébricos contendo $\alpha$)
Um mundo de números expressos na forma $a + b\alpha + c\alpha^2 + \dots$.&lt;/li>
&lt;li>&lt;strong>Mundo B: $\mathbb{Z}/N\mathbb{Z}$&lt;/strong> (O anel dos restos módulo $N$)
Um mundo de congruências composto apenas por inteiros de $0$ a $N-1$.&lt;/li>
&lt;/ul>
&lt;p>Aqui, definimos um mapeamento $\phi$ do Mundo A para o Mundo B da seguinte forma.
&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 mapeamento $\phi$ é uma operação mágica que substitui exatamente a variável $\alpha$ do Mundo A pelo inteiro $m$ do Mundo B.
Este $\phi$ possui uma propriedade extremamente poderosa chamada &lt;strong>&amp;ldquo;Homomorfismo de Anéis (Ring Homomorphism)&amp;rdquo;&lt;/strong> .
Homomorfismo é a propriedade de &lt;strong>&amp;ldquo;teleportar para outro mundo sem destruir a estrutura da adição e multiplicação&amp;rdquo;&lt;/strong> . Em outras palavras, as seguintes equações são válidas:&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>O que isso significa? Se pudermos criar o &lt;strong>&amp;ldquo;quadrado ($\gamma^2$)&amp;rdquo;&lt;/strong> de algum elemento complexo $\gamma$ no &amp;ldquo;Mundo A (o mundo de $\alpha$)&amp;rdquo;, e teleportá-lo para o &amp;ldquo;Mundo B (mundo dos restos)&amp;rdquo; usando $\phi$, &lt;strong>a forma quadrada $\phi(\gamma)^2$ é perfeitamente preservada&lt;/strong> .&lt;/p>
&lt;hr>
&lt;h2 id="fase-2-o-colapso-da-fatoração-em-números-primos-e-o-nascimento-dos-ideais">Fase 2: O Colapso da Fatoração em Números Primos e o Nascimento dos &amp;ldquo;Ideais&amp;rdquo;
&lt;/h2>&lt;p>No Mundo A ($\mathbb{Z}[\alpha]$), queremos reunir muitos elementos adequados $(a - b\alpha)$ e multiplicá-los para criar um &amp;ldquo;quadrado perfeito (elemento quadrado)&amp;rdquo;.
Normalmente, faríamos a &amp;ldquo;fatoração em números primos&amp;rdquo; de cada $(a - b\alpha)$ coletado e os combinaríamos de forma que os expoentes dos primos fossem todos pares (resolvendo com matrizes) para formar um quadrado.&lt;/p>
&lt;p>&lt;strong>No entanto, aqui, a parede desesperadora da álgebra se ergue.&lt;/strong>
Em mundos de corpos algébricos como $\mathbb{Z}[\alpha]$, a &lt;strong>&amp;ldquo;unicidade da fatoração em números primos (qualquer número pode ser expresso de forma única como o produto de primos)&amp;rdquo;&lt;/strong> ensinada no ensino médio &lt;strong>colapsa&lt;/strong> .&lt;/p>
&lt;p>(Exemplo: Em um certo mundo de corpo algébrico, $6 = 2 \times 3$, mas ao mesmo tempo $6 = (1+\sqrt{-5}) \times (1-\sqrt{-5})$, e não sabemos mais quais são os verdadeiros primos)&lt;/p>
&lt;p>Se a fatoração não for única, o quebra-cabeça de &amp;ldquo;contar o número de primos para torná-los pares&amp;rdquo; (o método do crivo) é, em princípio, impossível de executar.&lt;/p>
&lt;h3 id="a-salvação-de-kummer-e-dedekind-ideais">A Salvação de Kummer e Dedekind: &amp;ldquo;Ideais&amp;rdquo;
&lt;/h3>&lt;p>O que salvou esse colapso foi o conceito de &lt;strong>&amp;ldquo;Ideal (Ideal: número ideal)&amp;rdquo;&lt;/strong> criado pelos matemáticos do século 19.
Pensando não no elemento em si, mas no &amp;ldquo;conjunto de múltiplos (ideal)&amp;rdquo; gerado por esse elemento, a fatoração em números primos tornou-se possível novamente.&lt;/p>
&lt;p>No anel de inteiros de um corpo algébrico $\mathcal{O}_K$ (um anel mais completo contendo $\mathbb{Z}[\alpha]$), é provado que mesmo que um elemento não possa ser fatorado unicamente, &lt;strong>&amp;ldquo;um ideal sempre pode ser fatorado unicamente como o produto de &amp;lsquo;Ideais Primos ($\mathfrak{p}$)&amp;rsquo;&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Portanto, no GNFS, em vez de fatorar o próprio elemento $(a - b\alpha)$, fatoramos o &lt;strong>ideal principal $\langle a - b\alpha \rangle$ gerado por ele em ideais primos&lt;/strong> .&lt;/p>
&lt;hr>
&lt;h2 id="fase-3-a-norma-norm-e-os-dois-crivos-sieves">Fase 3: A Norma (Norm) e os Dois Crivos (Sieves)
&lt;/h2>&lt;p>Então, como sabemos em quais ideais primos o ideal $\langle a - b\alpha \rangle$ é decomposto?
Aqui usamos uma função chamada &lt;strong>&amp;ldquo;Norma (Norm)&amp;rdquo;&lt;/strong> . A Norma é uma função que converte elementos complexos de corpos algébricos em &amp;ldquo;inteiros reais normais $\mathbb{Z}$&amp;rdquo;.&lt;/p>
&lt;p>A norma do elemento $(a - b\alpha)$ é encontrada por um cálculo polinomial simples $b^d f(a/b)$ ($d$ é o grau de $f(x)$).&lt;/p>
&lt;p>Por um teorema algébrico, sabemos que &lt;strong>&amp;ldquo;se a norma de um certo ideal puder ser completamente fatorada em pequenos números primos (for suave), então o ideal original também pode ser completamente fatorado em pequenos ideais primos&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Então, para um grande número de pares de inteiros $(a, b)$, o GNFS calcula os dois seguintes simultaneamente e coleta apenas os pares em que ambos se tornam &amp;ldquo;números suaves&amp;rdquo;:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Crivo Racional (Rational Sieve)&lt;/strong> : $a - bm$ (o valor no mundo real)&lt;/li>
&lt;li>&lt;strong>Crivo Algébrico (Algebraic Sieve)&lt;/strong> : $b^d f(a/b)$ (a norma no mundo dos corpos algébricos)&lt;/li>
&lt;/ol>
&lt;p>Coletando dezenas de milhões de pares $(a, b)$ em que ambos são suaves, resolvemos os dados de fatoração de ideais primos (quantos ideais primos estão incluídos) como uma matriz gigante (álgebra linear sobre GF(2)) para encontrar um conjunto $S$ de pares tal que &amp;ldquo;quando multiplicados, os expoentes de todos os ideais primos se tornem pares&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="fase-4-os-dois-obstáculos-e-o-grupo-de-classes-de-ideais">Fase 4: Os Dois &amp;ldquo;Obstáculos&amp;rdquo; e o Grupo de Classes de Ideais
&lt;/h2>&lt;p>A partir do cálculo da matriz, descobrimos que multiplicar todos os ideais de $(a - b\alpha)$ pertencentes ao conjunto $S$ resulta no quadrado de um certo ideal $I$.
&lt;/p>
$$\prod_{S} \langle a - b\alpha \rangle = I^2$$
&lt;p>&lt;strong>No entanto, ainda não acabou. A barreira matemática mais profunda e difícil do GNFS está aqui.&lt;/strong>&lt;/p>
&lt;p>O que queremos no final não é o &amp;ldquo;quadrado de um ideal&amp;rdquo;, mas o &lt;strong>&amp;ldquo;quadrado de um elemento ($\gamma^2$)&amp;rdquo;&lt;/strong> para substituir no mapeamento $\phi$.
Só porque se tornou o quadrado de um ideal, não significa necessariamente que o elemento em si é um quadrado. Existem &lt;strong>dois fortes obstáculos matemáticos (Obstructions)&lt;/strong> aqui.&lt;/p>
&lt;h3 id="obstáculo--a-barreira-do-grupo-de-classes-de-ideais-ideal-class-group">Obstáculo ①: A Barreira do Grupo de Classes de Ideais (Ideal Class Group)
&lt;/h3>&lt;p>O ideal $I$ nem sempre é um &amp;ldquo;ideal gerado por um único elemento (ideal principal)&amp;rdquo;.
É impossível extrair um elemento específico $\gamma$ de um ideal que não é principal.&lt;/p>
&lt;p>Aqui entra o conceito de &lt;strong>&amp;ldquo;Grupo de Classes de Ideais (Class Group, $Cl_K$)&amp;rdquo;&lt;/strong> . O grupo de classes de ideais é um grupo que mede &amp;ldquo;quantos ideais existem no mundo daquele corpo algébrico que não são principais (o quanto a unicidade da fatoração se quebra)&amp;rdquo;.
Mesmo que $\prod \langle a - b\alpha \rangle$ se torne $I^2$, se $I$ não for o elemento de identidade (ideal principal) no grupo de classes de ideais, ele não pode ser trazido de volta ao quadrado de um elemento.&lt;/p>
&lt;h3 id="obstáculo--a-barreira-do-grupo-de-unidades-unit-group">Obstáculo ②: A Barreira do Grupo de Unidades (Unit Group)
&lt;/h3>&lt;p>Suponhamos que, por sorte, $I$ fosse o ideal principal $\langle \gamma \rangle$.
Então, teríamos $\prod \langle a - b\alpha \rangle = \langle \gamma^2 \rangle$.
Você pode pensar, &amp;ldquo;Ótimo, o elemento também é um quadrado!&amp;rdquo;, mas isso é um grande erro.&lt;/p>
&lt;p>Ideais (conjuntos de múltiplos) sendo iguais não significa que os elementos sejam perfeitamente iguais. Sempre haverá um desvio por uma &lt;strong>&amp;ldquo;Unidade (Unit: um número cujo inverso também é um inteiro. Por exemplo, 1 ou -1)&amp;rdquo;&lt;/strong> .
Em outras palavras, a verdadeira equação dos elementos se torna assim:
&lt;/p>
$$\prod_{S} (a - b\alpha) = u \cdot \gamma^2$$
&lt;p>
($u$ é um elemento do grupo de unidades $U_K$)&lt;/p>
&lt;p>A menos que esta unidade $u$ em si seja o quadrado de algo, o lado esquerdo nunca pode se tornar um &amp;ldquo;quadrado perfeito de um elemento&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="fase-5-a-magia-de-adleman-caracteres-quadráticos-quadratic-characters">Fase 5: A Magia de Adleman &amp;ldquo;Caracteres Quadráticos&amp;rdquo; (Quadratic Characters)
&lt;/h2>&lt;p>O obstáculo do grupo de classes de ideais e o obstáculo do grupo de unidades. Como superar esses dois?
Aqui entra o brilhante método dos &lt;strong>&amp;ldquo;Caracteres Quadráticos (Quadratic Characters)&amp;rdquo;&lt;/strong> , introduzido pelo criptógrafo Leonard Adleman (o &amp;ldquo;A&amp;rdquo; do RSA) e outros.&lt;/p>
&lt;p>Para determinar &amp;ldquo;se um certo elemento é um quadrado perfeito no corpo algébrico&amp;rdquo;, usamos a versão de corpos algébricos do Símbolo de Legendre (resíduo quadratique).
Naquela matriz gigante anterior (o quebra-cabeça para tornar pares as contagens de ideais primos), nós &lt;strong>furtivamente adicionamos algumas dezenas de condições extras (colunas) dizendo &amp;ldquo;os caracteres quadráticos para certos ideais primos especiais $\mathfrak{q}$ também devem ser todos $1$ (par)&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Quando encontramos um conjunto $S$ que satisfaz até mesmo essas condições adicionais através de cálculos de matrizes, teoremas profundos da teoria algébrica dos números garantem que &lt;strong>&amp;ldquo;tanto o obstáculo do grupo de classes de ideais quanto o obstáculo do grupo de unidades desaparecerão naturalmente com uma probabilidade esmagadora&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Com isso, finalmente obtemos a verdadeira equação.
&lt;/p>
$$\prod_{S} (a - b\alpha) = \gamma^2$$
&lt;hr>
&lt;h2 id="fase-final-a-fusão-dos-mundos-e-o-colapso-criptográfico">Fase Final: A Fusão dos Mundos e o Colapso Criptográfico
&lt;/h2>&lt;p>Finalmente, todas as peças do quebra-cabeça estão no lugar.&lt;/p>
&lt;p>&lt;strong>[Elementos no Mundo dos Corpos Algébricos (Mundo A)]&lt;/strong>
$\gamma^2 = \prod (a - b\alpha)$
(Nós usamos um algoritmo de raiz quadrada para encontrar $\gamma$)&lt;/p>
&lt;p>&lt;strong>[Elementos no Mundo Real (Mundo dos Números Racionais)]&lt;/strong>
$V^2 = \prod (a - bm)$
(Como esta é uma simples multiplicação de inteiros, $V$ é encontrado normalmente)&lt;/p>
&lt;p>Agora é hora daquela ponte mágica que construímos no início, o &lt;strong>homomorfismo $\phi$&lt;/strong> .
Nós teleportamos o elemento $\gamma$ do Mundo A para o Mundo B (o mundo dos restos de $N$) usando $\phi$ (o mapeamento onde substituímos $\alpha$ por $m$).
&lt;/p>
$$Y = \phi(\gamma) \pmod N$$
&lt;p>Por outro lado, levamos o $V$ construído no mundo real diretamente para o mundo dos restos e o chamamos de $X$.
&lt;/p>
$$X = V \pmod N$$
&lt;p>Devido à propriedade &amp;ldquo;preservadora de estrutura&amp;rdquo; do homomorfismo, a relação quadrada que se manteve no Mundo A é perfeitamente preservada no Mundo B (o mundo módulo $N$).
Além disso, como os pares originais $(a, b)$ foram feitos em correspondência nas formas $a - b\alpha$ e $a - bm$, estes $X$ e $Y$ colidem no mundo módulo $N$ e produzem a seguinte equação absoluta.&lt;/p>
&lt;p>&lt;strong>$$X^2 \equiv Y^2 \pmod N$$&lt;/strong>&lt;/p>
&lt;p>Tudo o que resta é rezar para que esses $X$ e $Y$ não sejam soluções triviais ($X \equiv \pm Y$) e calcular
&lt;strong>$\gcd(X - Y, N)$&lt;/strong> .&lt;/p>
&lt;p>Se for uma solução não trivial, o algoritmo euclidiano avança em 0.001 segundos, e os números primos secretos $p$ e $q$, que são o coração da criptografia RSA, são impressos na tela de saída.&lt;/p>
&lt;hr>
&lt;p>Este é o quadro completo do &lt;strong>&amp;ldquo;Crivo Geral dos Corpos de Números (GNFS)&amp;rdquo;&lt;/strong> , a essência da matemática moderna.&lt;/p></description></item><item><title>O que é o "General Number Field Sieve (GNFS)", a matemática mais poderosa da humanidade que quebra a criptografia da internet?</title><link>http://kenji.blog/pt/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/pt/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 O que é o "General Number Field Sieve (GNFS)", a matemática mais poderosa da humanidade que quebra a criptografia da internet?" />&lt;h1 id="o-que-é-o-general-number-field-sieve-gnfs-a-matemática-mais-poderosa-da-humanidade-que-quebra-a-criptografia-da-internet">O que é o &amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo;, a matemática mais poderosa da humanidade que quebra a criptografia da internet?
&lt;/h1>&lt;p>A internet que usamos todos os dias. Mensagens no LINE, YouTube, compras na Amazon etc., todas as comunicações são protegidas por &amp;ldquo;criptografia&amp;rdquo;.
Atualmente, a criptografia mais utilizada em todo o mundo é a &amp;ldquo;Criptografia RSA&amp;rdquo;.&lt;/p>
&lt;p>O núcleo da defesa da Criptografia RSA é muito simples. Ele utiliza a propriedade matemática de que ** &amp;ldquo;a fatoração em números primos de números gigantescos não pode ser resolvida nem mesmo por computadores&amp;rdquo; ** .
Por exemplo, para &amp;ldquo;15&amp;rdquo;, sabemos imediatamente que é &amp;ldquo;3 × 5&amp;rdquo;, mas no instante em que isso se torna um &amp;ldquo;número de 270 dígitos&amp;rdquo;, levaria centenas de milhões de anos para ser resolvido, mesmo se conectássemos todos os supercomputadores do mundo.&lt;/p>
&lt;p>No entanto, os matemáticos não ficaram em silêncio. Para quebrar essa criptografia impenetrável, a humanidade criou um algoritmo (procedimento de cálculo) quase mágico chamado ** &amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo; ** .&lt;/p>
&lt;p>Neste artigo, sem usar nenhum jargão técnico e apenas com o conhecimento da ** matemática do ensino fundamental (fatoração em primos, expressões algébricas, máximo divisor comum) ** , explicaremos passo a passo como esse &amp;ldquo;algoritmo mais forte da humanidade&amp;rdquo; quebra a criptografia!&lt;/p>
&lt;hr>
&lt;h2 id="capítulo-1-o-objetivo-da-decodificação-é-uma-fórmula-da-8ª-série">Capítulo 1: O objetivo da decodificação é uma &amp;ldquo;fórmula da 8ª série&amp;rdquo;
&lt;/h2>&lt;p>O maior golpe especial para enfrentar a gigantesca fatoração em números primos. É essa fórmula aprendida na 8ª série:&lt;/p>
&lt;blockquote>
&lt;p>** $X^2 - Y^2 = (X + Y)(X - Y)$ **&lt;/p>
&lt;/blockquote>
&lt;p>Você pode pensar: &amp;ldquo;Sério que uma fórmula tão básica pode quebrar a criptografia?&amp;rdquo;. No entanto, esta é a chave mestra que revela tudo.&lt;/p>
&lt;p>O maior objetivo para quebrar a criptografia é, para um número gigante $N$, encontrar ** &amp;ldquo;números ($X$ e $Y$) onde o resto da divisão de $X^2$ e $Y^2$ por $N$ seja o mesmo&amp;rdquo; ** .&lt;/p>
&lt;h3 id="por-que-ter-o-mesmo-resto-quebra-a-criptografia">Por que &amp;ldquo;ter o mesmo resto&amp;rdquo; quebra a criptografia?
&lt;/h3>&lt;p>Suponha que dois números, $X^2$ e $Y^2$, tenham &amp;ldquo;o mesmo resto quando divididos por $N$&amp;rdquo;.
Ter o mesmo resto significa que existe uma regra onde ** a subtração &amp;ldquo;$X^2 - Y^2$&amp;rdquo; será sempre perfeitamente divisível por $N$ (será um múltiplo de $N$) ** .&lt;/p>
&lt;p>Aqui, vamos supor que o número gigante $N$ usado na criptografia seja composto pela multiplicação de dois números primos secretos ($p$ e $q$) ($N = p \times q$).&lt;/p>
&lt;p>Fatorando $X^2 - Y^2$, obtemos ** $(X - Y)(X + Y)$ ** .
O fato de isso ser um múltiplo de $N$ significa que, em algum lugar dessa multiplicação, os primos secretos $p$ e $q$ estão escondidos.&lt;/p>
&lt;p>Aqui, um milagre acontece.
Há uma probabilidade matemática de ** 50% (metade) ** de que os dois primos $p$ e $q$ se separem em salas diferentes: ** &amp;ldquo;$p$ vai para a sala de $(X - Y)$&amp;rdquo; e &amp;ldquo;$q$ vai para a sala de $(X + Y)$&amp;rdquo; ** .&lt;/p>
&lt;p>Com apenas o primo $p$ tendo entrado na sala de $(X - Y)$, vamos calcular o ** &amp;ldquo;máximo divisor comum (a maior peça em comum)&amp;rdquo; ** de $(X - Y)$ e $N$.&lt;/p>
&lt;ul>
&lt;li>Conteúdo de $(X - Y)$ = $p \times$ algum número&lt;/li>
&lt;li>Conteúdo de $N$ = $p \times q$
A única peça comum é ** &amp;ldquo;$p$&amp;rdquo; ** !&lt;/li>
&lt;/ul>
&lt;p>Ou seja, no instante em que o máximo divisor comum é calculado, o número primo oculto $p$ é revelado e a criptografia é completamente decodificada. (*O máximo divisor comum pode ser calculado instantaneamente em um smartphone usando o &amp;ldquo;Algoritmo de Euclides&amp;rdquo;).&lt;/p>
&lt;p>** 【Pequena Coluna: Por que o quadrado? Cubo ou o dobro não servem?】 **&lt;/p>
&lt;blockquote>
&lt;p>Com &amp;ldquo;$2X - 2Y$&amp;rdquo;, torna-se $2(X - Y)$ e há apenas uma sala, então você não pode separar os primos. Com &amp;ldquo;$X^3 - Y^3$&amp;rdquo;, os tamanhos das salas ficam desequilibrados e o cálculo torna-se desnecessariamente pesado. Para separar os primos em dois, o &amp;ldquo;quadrado&amp;rdquo; que se divide perfeitamente em duas salas tem o melhor custo-benefício.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="capítulo-2-como-encontrar-x-e-y-quebra-cabeça-de-coleta-de-cartas-de-números-primos">Capítulo 2: Como encontrar X e Y? &amp;ldquo;Quebra-cabeça de coleta de cartas de números primos&amp;rdquo;
&lt;/h2>&lt;p>O objetivo é claro. No entanto, mesmo se procurarmos cegamente por &amp;ldquo;$X^2$ e $Y^2$ que têm o mesmo resto&amp;rdquo;, o fim do universo chegaria antes de encontrá-los.
Então, os matemáticos criaram um método genial chamado ** &amp;ldquo;quebra-cabeça de coleta de cartas de números primos&amp;rdquo; ** .&lt;/p>
&lt;h3 id="step-1-coletar-apenas-ouro-em-pó-números-suaves-com-uma-peneira">Step 1: Coletar apenas ouro em pó (números suaves) com uma peneira
&lt;/h3>&lt;p>Primeiro, prepare um número apropriado $Z$, eleve-o ao quadrado e calcule o resto $W$ ao dividi-lo por $N$.
(O mundo dos restos de $Z^2 = W$)&lt;/p>
&lt;p>Fatore o resto obtido $W$ em números primos. Aqui, apenas quando aparecer ** &amp;ldquo;um $W$ composto apenas de pequenos primos como 2, 3, 5, 7, etc.&amp;rdquo; ** , guarde essa equação como um &amp;ldquo;cartão premiado&amp;rdquo; e jogue-a fora se houver primos grandes misturados.
É como jogar fora as pedras grandes com uma peneira num rio para coletar apenas o pó de ouro.&lt;/p>
&lt;h3 id="step-2-o-quebra-cabeça-para-tornar-tudo-par">Step 2: O quebra-cabeça para tornar tudo &amp;ldquo;par&amp;rdquo;
&lt;/h3>&lt;p>Por exemplo, suponha que as 3 seguintes cartas de pó de ouro foram coletadas.&lt;/p>
&lt;ul>
&lt;li>Carta A: $Z_1^2 = 2^3 \times 3^1$&lt;/li>
&lt;li>Carta B: $Z_2^2 = 2^1 \times 5^1$&lt;/li>
&lt;li>Carta C: $Z_3^2 = 3^1 \times 5^1$&lt;/li>
&lt;/ul>
&lt;p>Vamos multiplicar todos eles.
O lado direito se torna $(2^3 \times 3^1) \times (2^1 \times 5^1) \times (3^1 \times 5^1)$,
E ao organizá-los juntos, obtemos ** &amp;ldquo;$2^4 \times 3^2 \times 5^2$&amp;rdquo; ** .&lt;/p>
&lt;p>Surpreendentemente, a quantidade de números primos tornou-se &amp;ldquo;4, 2, 2&amp;rdquo;, ** todos sendo um número par ** !
O fato de todos serem pares significa que se você reduzir a quantidade total pela metade, será &amp;ldquo;o quadrado de algo&amp;rdquo;.
Ou seja, $(2^2 \times 3^1 \times 5^1)^2 = (60)^2$.&lt;/p>
&lt;p>O lado esquerdo é $(Z_1 \times Z_2 \times Z_3)^2$, então finalmente chegamos a:
** $X = (Z_1 \times Z_2 \times Z_3)$ **
** $Y = 60$ **
O tão esperado par &amp;ldquo;$X^2 = Y^2$&amp;rdquo; está completo!&lt;/p>
&lt;p>Para computadores, o quebra-cabeça de calcular se a quantidade de números primos é &amp;ldquo;par ou ímpar (0 ou 1)&amp;rdquo; é algo em que eles são muito bons, então, com este método, é possível encontrar $X$ e $Y$ em alta velocidade.&lt;/p>
&lt;hr>
&lt;h2 id="capítulo-3-a-parede-do-desespero-se-ergue">Capítulo 3: A Parede do Desespero se ergue
&lt;/h2>&lt;p>Agora qualquer criptografia pode ser quebrada! &amp;hellip;ou assim pensávamos, mas um grande problema ocorreu.
Se o número da criptografia $N$ tiver até cerca de &amp;ldquo;100 dígitos&amp;rdquo;, este método (chamado Sieve Quadrático) pode resolvê-lo, mas quando $N$ se torna &amp;ldquo;200 ou 300 dígitos&amp;rdquo;, o $W$ que surge no meio do cálculo torna-se demasiado grande.&lt;/p>
&lt;p>Quando os números ficam demasiado grandes, &amp;ldquo;números compostos apenas por pequenos números primos (pó de ouro)&amp;rdquo; deixam de aparecer. Torna-se mais difícil do que procurar lentes de contacto no deserto, e as cartas necessárias para resolver o quebra-cabeça não se acumulam de forma alguma.&lt;/p>
&lt;p>Aqui, a arma final da humanidade, o ** &amp;ldquo;General Number Field Sieve (GNFS)&amp;rdquo; ** , finalmente entra em cena.&lt;/p>
&lt;hr>
&lt;h2 id="capítulo-4-a-ideia-mais-forte-da-humanidade-de-criar-dois-mundos">Capítulo 4: A ideia mais forte da humanidade de criar &amp;ldquo;Dois Mundos&amp;rdquo;
&lt;/h2>&lt;p>A ideia genial do GNFS é: ** &amp;ldquo;Os números tornam-se gigantescos porque calculamos apenas no mundo real. Então, vamos criar um &amp;lsquo;mundo dos bastidores&amp;rsquo; usando polinómios (fórmulas com letras) para dividir o peso do cálculo em dois.&amp;rdquo; **&lt;/p>
&lt;h3 id="a-magia-das-fórmulas-com-letras">A magia das fórmulas com letras
&lt;/h3>&lt;p>O GNFS converte o número gigante $N$ em uma fórmula com letras, utilizando um número base $m$.
Por exemplo, se $N=100$, com $m=4$, então $100 = 4^3 + 2(4^2) + 4$.
Transformamos isso numa fórmula (o mundo dos bastidores) usando a letra $x$: ** $f(x) = x^3 + 2x^2 + x$ ** .&lt;/p>
&lt;p>O mais interessante dessa fórmula é que ela possui a propriedade de que ** &amp;ldquo;se substituirmos $x$ por $m$ (4 no exemplo acima), sempre podemos voltar ao número real $N$&amp;rdquo; ** .&lt;/p>
&lt;h3 id="procurando-pó-de-ouro-em-2-mundos-simultaneamente">Procurando pó de ouro em 2 mundos simultaneamente
&lt;/h3>&lt;p>O GNFS cria muitos pares de números inteiros aleatórios $(a, b)$ e realiza os seguintes dois cálculos em simultâneo:&lt;/p>
&lt;ol>
&lt;li>** Mundo Real ** : $a - b \times m$&lt;/li>
&lt;li>** Mundo das Letras ** : O valor de $a - b \times x$ calculado pelas regras dos polinómios&lt;/li>
&lt;/ol>
&lt;p>Ao dividir o problema em dois mundos, o tamanho dos números tratados diminui (fica mais leve) drasticamente. É como dividir uma pedra gigante em dois para transformá-la em pedras mais fáceis de manusear.&lt;/p>
&lt;p>Então, utilizamos uma peneira para separar e recolher apenas os pares milagrosos $(a, b)$ onde ** &amp;ldquo;tanto no mundo real quanto no mundo das letras, ambos são &amp;lsquo;compostos apenas de pequenos primos (pó de ouro)&amp;rsquo;&amp;rdquo; ** . Esta é a origem do nome &amp;ldquo;Crivo do Corpo de Números&amp;rdquo;.&lt;/p>
&lt;h3 id="o-momento-em-que-a-criptografia-é-finalmente-quebrada">O momento em que a criptografia é finalmente quebrada
&lt;/h3>&lt;p>Quando dezenas de milhões de &amp;ldquo;cartões de pó de ouro&amp;rdquo; são recolhidos de ambos os mundos, o supercomputador utiliza cálculos gigantescos de matrizes para encontrar &amp;ldquo;uma combinação em que o número de primos seja todo par&amp;rdquo;, tal como fizemos no Capítulo 2.&lt;/p>
&lt;p>Assim que a combinação for encontrada:&lt;/p>
&lt;ul>
&lt;li>Deixe o número ao quadrado no mundo real ser ** $X^2$ **&lt;/li>
&lt;li>Deixe a fórmula quadrada criada no mundo das letras ser ** $Y(x)^2$ **&lt;/li>
&lt;/ul>
&lt;p>Por fim, substitua $x$ na fórmula de letras $Y(x)$ por $m$, saltando de volta para o mundo real e unindo-os.
Então, como que por magia matemática, a condição onde ** &amp;ldquo;os restos de $X^2$ e $Y^2$ são iguais&amp;rdquo; ** é estritamente alcançada!&lt;/p>
&lt;p>O resto, como no Capítulo 1, é apenas calcular o máximo divisor comum entre $X - Y$ e $N$, e a impenetrável criptografia RSA desmoronará, revelando os primos secretos.&lt;/p>
&lt;hr>
&lt;h2 id="conclusão-a-matemática-não-acaba">Conclusão: A matemática não acaba
&lt;/h2>&lt;p>Você pode estar a pensar: &amp;ldquo;Fantástico, com o GNFS qualquer criptografia pode ser quebrada!&amp;rdquo;.
No entanto, a criptografia RSA também não se deu por vencida. O que é utilizado na internet atual é um número gigantesco e monstruoso chamado &amp;ldquo;RSA-2048 (cerca de 617 dígitos)&amp;rdquo;.&lt;/p>
&lt;p>Por mais que o GNFS seja o algoritmo mais poderoso da humanidade, diz-se que para resolver até mesmo 270 dígitos (RSA-270), levaria milhares ou dezenas de milhares de anos, mesmo conectando computadores do mundo inteiro. Por agora, os nossos dados bancários e do LINE estão seguros.&lt;/p>
&lt;p>Mas e se aparecesse uma ** &amp;ldquo;magia capaz de encontrar instantaneamente $X$ e $Y$ para qualquer número gigante&amp;rdquo; ** ?
Na verdade, a coisa mais próxima disso é o ** &amp;ldquo;Computador Quântico (Algoritmo de Shor)&amp;rdquo; ** , que está atualmente em desenvolvimento. Utilizando a natureza ondulatória da mecânica quântica, foi provado matematicamente que é possível ignorar o aborrecido quebra-cabeças da recolha de cartas e chegar à resposta de uma só vez.&lt;/p>
&lt;p>A interminável batalha de inteligência entre os que criam a criptografia (defesa) e os que criam algoritmos para a quebrar (ataque).
Saber que a &amp;ldquo;fatoração em números primos&amp;rdquo; e as &amp;ldquo;fórmulas com letras&amp;rdquo; ensinadas na escola secundária são, na verdade, as armas na linha da frente da segurança global não faz com que as aulas de matemática pareçam um pouco mais interessantes?&lt;/p>
&lt;p>Quem descobrirá o algoritmo mais forte do futuro poderá ser você, que está a ler este artigo!&lt;/p>
&lt;hr>
&lt;p>&lt;em>(※Este artigo é uma adaptação conceptual do encanto matemático da quebra de códigos para estudantes. O GNFS real é rigorosamente calculado utilizando matemática universitária avançada, tal como os grupos da classe de ideais dos corpos numéricos algébricos e homomorfismos)&lt;/em>&lt;/p></description></item><item><title>Princípio de Kerckhoffs</title><link>http://kenji.blog/pt/p/principio-de-kerckhoffs/</link><pubDate>Wed, 16 Apr 2025 23:53:08 +0900</pubDate><guid>http://kenji.blog/pt/p/principio-de-kerckhoffs/</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 Princípio de Kerckhoffs" />&lt;h1 id="princípio-de-kerckhoffs">&amp;ldquo;Princípio de Kerckhoffs&amp;rdquo;
&lt;/h1>&lt;hr>
&lt;p>Olá!&lt;/p>
&lt;p>Hoje eu gostaria de falar sobre algo um pouco interessante e, na verdade, extremamente importante chamado &amp;ldquo;Princípio de Kerckhoffs&amp;rdquo;.&lt;/p>
&lt;p>Ah, espere, espere.&lt;br>
Alguns de vocês podem pensar: &amp;ldquo;Nunca ouvi falar do &amp;lsquo;Princípio de Kerckhoffs&amp;rsquo; e tem muitos termos técnicos&amp;hellip;&amp;rdquo;. Não se preocupe. Este artigo é exatamente o que eu quero que pessoas como você leiam.&lt;/p>
&lt;hr>
&lt;h2 id="o-que-significa-criptografia-segura">O que significa &amp;ldquo;criptografia segura&amp;rdquo;?
&lt;/h2>&lt;p>Por exemplo, digamos que alguém diga: &amp;ldquo;Este cofre só pode ser aberto por alguém que saiba a maneira secreta de abri-lo&amp;rdquo;.&lt;/p>
&lt;p>À primeira vista, isso parece muito seguro, não é?&lt;br>
Mas, se você pensar bem, não é um pouco preocupante?&lt;/p>
&lt;p>Como, &amp;ldquo;Se o segredo for revelado, é o fim?&amp;rdquo;.&lt;/p>
&lt;p>Na verdade, foi isso que desencadeou o surgimento do Princípio de Kerckhoffs.&lt;/p>
&lt;hr>
&lt;h2 id="o-que-é-o-princípio-de-kerckhoffs-afinal">O que é o &amp;ldquo;Princípio de Kerckhoffs&amp;rdquo; afinal?
&lt;/h2>&lt;p>Explicando de forma bem simples, é a ideia de que&lt;/p>
&lt;p>&lt;strong>&amp;ldquo;A criptografia deve ser segura mesmo se o seu funcionamento for descoberto&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Em outras palavras, &amp;ldquo;A segurança deve depender apenas da &amp;lsquo;chave secreta&amp;rsquo;, e o método de criptografia em si pode ser público!&amp;rdquo;.&lt;/p>
&lt;p>Por outro lado, &amp;ldquo;Um estado em que o algoritmo (mecanismo) de criptografia é mantido em segredo é considerado de baixa confiabilidade&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="se-o-mecanismo-for-secreto-é-seguro-pode-ser-um-pouco-perigoso">&amp;ldquo;Se o mecanismo for secreto, é seguro&amp;rdquo; pode ser um pouco perigoso
&lt;/h2>&lt;p>Essa é uma maneira comum de pensar:&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Não mostrei o interior deste aplicativo a ninguém, então a segurança está ok&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Eu entendo o sentimento.&lt;br>
Mas isso é o mesmo que dizer: &amp;ldquo;Ninguém está olhando, então nenhum ponto fraco será encontrado, certo?&amp;rdquo;.&lt;/p>
&lt;p>Na realidade, o próprio fato de que &amp;ldquo;ninguém está olhando&amp;rdquo; pode se tornar um risco.&lt;/p>
&lt;hr>
&lt;h2 id="mas-por-que-esse-princípio-é-importante">Mas por que esse princípio é importante?
&lt;/h2>&lt;p>Porque, se alguém colocar as mãos no mecanismo e puder decifrá-lo facilmente, essa criptografia está acabada.&lt;/p>
&lt;p>Para usar uma analogia, é como se a fechadura de uma porta tivesse um mecanismo muito complexo, mas na verdade pudesse ser aberta com uma chave reserva feita em uma loja de artigos de um dólar.&lt;/p>
&lt;p>O importante não é &amp;ldquo;A chave é secreta, então está tudo bem&amp;rdquo;, mas &amp;ldquo;Mesmo se você mostrar todo o mecanismo, ele não pode ser aberto sem a chave certa&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="a-sensação-de-mas-isso-não-é-um-pouco-assustador">A sensação de &amp;ldquo;Mas isso não é um pouco assustador?&amp;rdquo;
&lt;/h2>&lt;p>O que muitas pessoas sentem aqui é a ansiedade de&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Não é meio assustador expor todo o mecanismo?&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Eu entendo.&lt;br>
Porque você pensa: &amp;ldquo;Se eu mostrar o interior inteiro, não será imitado ou usado para o mal?&amp;rdquo;.&lt;/p>
&lt;p>Mas esse é exatamente o cerne do Princípio de Kerckhoffs.&lt;br>
A &amp;ldquo;força que não entra em colapso mesmo quando o interior é mostrado&amp;rdquo; é a verdadeira segurança.&lt;/p>
&lt;hr>
&lt;h2 id="dito-isso-requer-um-pouco-de-coragem-no-começo">Dito isso, requer um pouco de coragem no começo
&lt;/h2>&lt;p>Colocando-se no lugar do desenvolvedor, parece que &amp;ldquo;publicar o mecanismo = revelar suas fraquezas&amp;rdquo;, então é claro que é de dar frio na barriga.&lt;/p>
&lt;p>Mas pense sobre isso.&lt;/p>
&lt;p>Algo que você pode mostrar adequadamente e dizer: &amp;ldquo;Qualquer um pode verificar&amp;rdquo;, acabará sendo mais confiável.&lt;/p>
&lt;p>Isso é semelhante às relações humanas.&lt;/p>
&lt;p>Você pode se sentir mais seguro com &amp;ldquo;uma pessoa que se dá bem com você depois de mostrar o seu verdadeiro eu&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="conclusão">Conclusão
&lt;/h2>&lt;p>O Princípio de Kerckhoffs pode soar um pouco teórico, mas sua essência é muito simples.&lt;/p>
&lt;p>É apenas uma questão de &lt;strong>&amp;ldquo;Vamos criar um sistema que não quebre, não importa para quem você o mostre&amp;rdquo;&lt;/strong> .&lt;/p>
&lt;p>Um design adequado em vez de segredos superficiais.&lt;br>
Código do qual você não se envergonha de mostrar, em vez de código que você não quer que ninguém veja.&lt;/p>
&lt;p>Talvez esse tipo de &amp;ldquo;força&amp;rdquo; seja cada vez mais necessário na próxima era.&lt;/p>
&lt;hr>
&lt;p>Muito obrigado por ler!&lt;/p>
&lt;p>A segurança é um assunto um pouco difícil, mas há partes que se conectam a &amp;ldquo;relacionamentos com pessoas&amp;rdquo; e &amp;ldquo;paz de espírito cotidiana&amp;rdquo;.&lt;br>
Se você aprender um pouco de cada vez sem se sentir sobrecarregado, tenho certeza de que coisas boas acontecerão.&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>