<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RSA on kenji.blog</title><link>http://kenji.blog/pt/tags/rsa/</link><description>Recent content in RSA on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>pt</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 05 Sep 2026 22:09:21 +0900</lastBuildDate><atom:link href="http://kenji.blog/pt/tags/rsa/index.xml" rel="self" type="application/rss+xml"/><item><title>Computadores Quânticos Realmente Destruirão a Criptografia RSA? ~O Algoritmo de Shor e o Estado Atual~</title><link>http://kenji.blog/pt/p/shors-algorithm-and-rsa-breaking/</link><pubDate>Sat, 05 Sep 2026 22:09:21 +0900</pubDate><guid>http://kenji.blog/pt/p/shors-algorithm-and-rsa-breaking/</guid><description>&lt;img src="http://kenji.blog/p/shors-algorithm-and-rsa-breaking/quantum_breaking_rsa_1788613722990.jpg" alt="Featured image of post Computadores Quânticos Realmente Destruirão a Criptografia RSA? ~O Algoritmo de Shor e o Estado Atual~" />&lt;h2 id="introdução-a-interseção-entre-criptografia-e-computadores-quânticos">Introdução: A Interseção entre Criptografia e Computadores Quânticos
&lt;/h2>&lt;p>Na sociedade da internet moderna, a base para proteger o segredo das comunicações é a &amp;ldquo;criptografia de chave pública&amp;rdquo;. Um dos mais representativos é a &amp;ldquo;Criptografia RSA&amp;rdquo;, desenvolvida em 1977 por Ron Rivest, Adi Shamir e Leonard Adleman. Desde pagamentos de compras online que usamos diariamente, navegação em sites (HTTPS), até envio e recebimento de e-mails, a criptografia RSA funciona como o coração da infraestrutura da internet.&lt;/p>
&lt;p>No entanto, com o surgimento dos &amp;ldquo;computadores quânticos&amp;rdquo;, foi apontado que essa segurança pode ser subvertida desde a base. Na mídia, às vezes vemos manchetes sensacionalistas como &amp;ldquo;Se um computador quântico for concluído, senhas e criptografias em todo o mundo serão decifradas em segundos&amp;rdquo;. Mas será que isso é verdade?&lt;/p>
&lt;p>Neste artigo, aprofundaremos como funcionam o GNFS (General Number Field Sieve), um método clássico de descriptografia, e a versão definitiva dos algoritmos de descriptografia usando computadores quânticos, o &amp;ldquo;Algoritmo de Shor (Shor&amp;rsquo;s Algorithm)&amp;rdquo;. Explicaremos de forma fácil conceitos avançados, como a transformação quântica de Fourier e a descoberta de períodos, e examinaremos em detalhes o estado atual do hardware quântico na era NISQ (Noisy Intermediate-Scale Quantum) e os obstáculos reais necessários para quebrar a RSA-2048.&lt;/p>
&lt;hr>
&lt;h2 id="o-núcleo-da-criptografia-rsa-a-dificuldade-da-fatoração-em-números-primos">O Núcleo da Criptografia RSA: A Dificuldade da Fatoração em Números Primos
&lt;/h2>&lt;p>A segurança da criptografia RSA depende de uma assimetria extremamente simples na matemática. Trata-se do fato de que &amp;ldquo;é fácil multiplicar dois números primos gigantes, mas é extremamente difícil encontrar (fatorar em números primos) os dois números primos originais a partir do resultado dessa multiplicação (número composto)&amp;rdquo;.&lt;/p>
&lt;p>Por exemplo, suponha que existam dois números primos, $ p = 61 $ e $ q = 53 $. Calcular esta multiplicação $ N = p \times q = 3233 $ é instantâneo. No entanto, se receber apenas o número &amp;ldquo;3233&amp;rdquo; e tiver que resolver &amp;ldquo;de quais números primos essa é a multiplicação?&amp;rdquo;, a quantidade de cálculos explode à medida que o número se torna maior.&lt;/p>
&lt;p>No RSA-2048, que é a norma atual, o comprimento da chave é de 2048 bits, ou seja, é usado um número composto gigante $ N $ que chega a cerca de 617 dígitos em decimal. Se esse $ N $ puder ser fatorado em números primos, a criptografia será essencialmente decifrada.&lt;/p>
&lt;h3 id="o-desafio-dos-computadores-clássicos-gnfs-general-number-field-sieve">O Desafio dos Computadores Clássicos: GNFS (General Number Field Sieve)
&lt;/h3>&lt;p>Para resolver o problema da fatoração em números primos, matemáticos e criptógrafos desenvolveram vários algoritmos ao longo dos anos. Entre eles, o que atualmente é considerado o mais rápido em computadores clássicos é o &lt;strong>GNFS: General Number Field Sieve&lt;/strong>.&lt;/p>
&lt;p>O GNFS é um método que expande e analisa os cálculos no anel de inteiros para um corpo algébrico (Number Field) mais abstrato, a fim de fatorar o número gigante $ N $. O fluxo geral é o seguinte.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Seleção de Polinômio&lt;/strong> : Encontrar um polinômio $ f(x) $ com grau e coeficientes apropriados, que tenha $ N $ como raiz.&lt;/li>
&lt;li>&lt;strong>Coleta de Dados (Peneiramento)&lt;/strong> : No corpo dos números racionais e no corpo algébrico, procuramos em grande quantidade por pares de números que podem ser decompostos em números primos pequenos (números suaves, Smooth numbers). Esse processo é chamado de &amp;ldquo;peneiramento&amp;rdquo; e é a parte que leva mais tempo.&lt;/li>
&lt;li>&lt;strong>Geração e Redução de Matriz&lt;/strong> : Com base nas relações coletadas, uma enorme matriz esparsa (uma matriz em que a maioria dos componentes é zero) é gerada e resolvida usando métodos de álgebra linear (como o método de Block Lanczos).&lt;/li>
&lt;li>&lt;strong>Cálculo da Raiz Quadrada&lt;/strong> : Finalmente, calcula-se a raiz quadrada no corpo algébrico para derivar os fatores (fatores primos) de $ N $.&lt;/li>
&lt;/ol>
&lt;p>A complexidade computacional do GNFS é avaliada não assintoticamente como $ O(\exp((\sqrt[3]{\frac{64}{9}} + o(1)) (\log N)^{\frac{1}{3}} (\log \log N)^{\frac{2}{3}})) $. Isso é chamado de complexidade de tempo &amp;ldquo;Sub-exponencial&amp;rdquo; (Sub-exponential). Embora seja mais rápido que o tempo exponencial, é muito mais lento que o tempo polinomial (Polynomial time).&lt;/p>
&lt;p>De fato, em 2020, uma equipe de pesquisa internacional obteve sucesso em fatorar a RSA-250 (829 bits, número composto de 250 dígitos) usando o GNFS. Esse cálculo consumiu um tempo computacional enorme, equivalente a cerca de 2700 CPU-core anos, reunindo recursos de computação de todo o mundo. No entanto, quando isso chega a 2048 bits, é mencionado que a quantidade de cálculo necessária explodiria para trilhões de vezes a idade do universo, tornando impossível descriptografar em um tempo realista com métodos clássicos, não importa quantos supercomputadores atuais funcionem em paralelo.&lt;/p>
&lt;hr>
&lt;h2 id="o-trunfo-do-computador-quântico-algoritmo-de-shor">O Trunfo do Computador Quântico: Algoritmo de Shor
&lt;/h2>&lt;p>Aqui é onde entra o &amp;ldquo;Algoritmo de Shor&amp;rdquo;, publicado por Peter Shor em 1994. Esse algoritmo foi revolucionário por permitir que o problema de fatoração em números primos fosse resolvido no computador quântico em &lt;strong>tempo polinomial&lt;/strong> ( $ O((\log N)^3) $ ). A diferença entre tempo sub-exponencial e polinomial é decisiva e significa, na teoria, que a criptografia RSA será completamente destruída se um computador quântico for usado.&lt;/p>
&lt;h3 id="fluxo-geral-do-algoritmo-de-shor">Fluxo Geral do Algoritmo de Shor
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">graph TD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[Inserir o número N que se deseja fatorar] --&amp;gt; B[Selecionar um número inteiro aleatório a]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C{Máximo divisor comum&amp;lt;br&amp;gt;entre a e N}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|Maior que 1| D[Por sorte, um fator primo foi encontrado!]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> C --&amp;gt;|1 Primos entre si| E[Vez do computador quântico]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> E --&amp;gt; F[Encontrar o período r da&amp;lt;br&amp;gt;função f_x = a^x mod N por Transformação Quântica de Fourier]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> F --&amp;gt; G{O período r é par e&amp;lt;br&amp;gt;a^r/2 ≢ -1 mod N}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|Sim| H[Calcular o máximo divisor comum gcd_a^r/2 ± 1, N]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H --&amp;gt; I((Fatoração bem sucedida!))
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> G --&amp;gt;|Não| B
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>O algoritmo de Shor não resolve o problema da fatoração em números primos diretamente, mas usa teoremas da teoria dos números para convertê-lo em outro problema chamado &amp;ldquo;Problema de Descoberta de Período&amp;rdquo; (Period Finding Problem) e, em seguida, resolve isso rapidamente aproveitando as características do computador quântico.&lt;/p>
&lt;h3 id="passo-1-redução-da-fatoração-ao-problema-de-descoberta-de-período-processamento-clássico">Passo 1: Redução da Fatoração ao Problema de Descoberta de Período (Processamento Clássico)
&lt;/h3>&lt;p>O primeiro passo do algoritmo é feito em um computador clássico.
Para o número $ N $ que se deseja fatorar, escolhe-se um número inteiro aleatório $ a $ ( $ 1 &lt; a &lt; N $ ) que seja co-primo (com o máximo divisor comum igual a 1) com $ N $. Se por acaso o máximo divisor comum não for 1, o divisor comum encontrado nesse momento já é um fator de $ N $, e a fatoração está concluída, mas a probabilidade é extremamente baixa.&lt;/p>
&lt;p>Em seguida, considere a sequência das seguintes equações modulares:
$ f(x) = a^x \pmod N $&lt;/p>
&lt;p>Substituindo $ x = 1, 2, 3, \dots $ nesta função $ f(x) $, os valores parecem aleatórios, mas como são calculados em um limite finito, eles sempre voltarão ao valor original em algum ponto, repetindo a mesma sequência de números. Este ciclo de repetição é chamado de período $ r $. Ou seja,
O problema de encontrar o menor número inteiro positivo $ r $ tal que $ a^r \equiv 1 \pmod N $, este é o &amp;ldquo;Problema de Descoberta de Período&amp;rdquo;.&lt;/p>
&lt;p>Se este período $ r $ for encontrado, e $ r $ for um número par, então $ a^r - 1 \equiv 0 \pmod N $, e usando a fórmula de fatoração,
pode ser transformado em $ (a^{r/2} - 1)(a^{r/2} + 1) \equiv 0 \pmod N $. A partir daqui, ao calcular o máximo divisor comum entre $ N $ e $ a^{r/2} \pm 1 $ usando o algoritmo de Euclides, um fator de $ N $ pode ser obtido com uma probabilidade extremamente alta.&lt;/p>
&lt;p>Para encontrar o período $ r $ em um computador clássico, no final, etapas exponenciais são necessárias e isso não pode ser acelerado. No entanto, com um computador quântico, este período $ r $ pode ser encontrado em um instante (tempo polinomial).&lt;/p>
&lt;h3 id="passo-2-preparação-e-superposição-do-estado-quântico">Passo 2: Preparação e Superposição do Estado Quântico
&lt;/h3>&lt;p>A partir daqui é a vez do computador quântico.
Os computadores quânticos usam &amp;ldquo;qubits&amp;rdquo;, que podem ter o estado &amp;ldquo;0&amp;rdquo; e &amp;ldquo;1&amp;rdquo; simultaneamente. No algoritmo de Shor, são preparados dois registradores: o primeiro para armazenar a entrada e o segundo para os resultados do cálculo.&lt;/p>
&lt;p>Primeiro, uma operação de porta quântica chamada porta de Hadamard (Hadamard gate) é aplicada a todos os qubits do primeiro registrador. Isso coloca o primeiro registrador em um &lt;strong>estado de superposição uniforme&lt;/strong> de todos os valores concebíveis de $ x $ (de $ 0 $ a $ 2^n-1 $. $ n $ é um número de bits suficientemente grande).&lt;/p>
&lt;p>Em outras palavras, dentro do computador quântico, é criado um estado em que incontáveis valores de entrada como $ x=0, 1, 2, 3, \dots $ existem em paralelo ao mesmo tempo.&lt;/p>
&lt;h3 id="passo-3-exponenciação-modular-quântica-quantum-modular-exponentiation">Passo 3: Exponenciação Modular Quântica (Quantum Modular Exponentiation)
&lt;/h3>&lt;p>Em seguida, o estado de superposição do primeiro registrador é usado como entrada para calcular $ f(x) = a^x \pmod N $, e o resultado é armazenado no segundo registrador.
Como este cálculo é executado como uma transformação unitária no circuito quântico, o cálculo de $ f(x) $ para todos os $ x $ é feito de forma &amp;ldquo;paralela (paralelismo quântico)&amp;rdquo; enquanto a superposição é mantida.&lt;/p>
&lt;p>O espaço do sistema quântico inteiro neste ponto,
torna-se uma enorme superposição de estados $ |x, a^x \bmod N\rangle $.&lt;/p>
&lt;p>No entanto, se você simplesmente medir (observar) o segundo registrador aqui, um valor aleatório de $ a^x \bmod N $ será probabilisticamente selecionado, e em conjunto com isso, o $ x $ do primeiro registrador também será determinado. Isso não é diferente de calcular uma vez em um computador clássico, e você não conseguirá encontrar o período $ r $.&lt;/p>
&lt;p>Nas regras da mecânica quântica, você não pode observar o conteúdo de um estado de superposição diretamente. Então, como extrair a informação global chamada &amp;ldquo;período&amp;rdquo;?&lt;/p>
&lt;h3 id="passo-4-transformada-quântica-de-fourier-qft-quantum-fourier-transform">Passo 4: Transformada Quântica de Fourier (QFT: Quantum Fourier Transform)
&lt;/h3>&lt;p>O verdadeiro valor do algoritmo de Shor, que supera esse obstáculo, é a aplicação da &lt;strong>Transformada Quântica de Fourier (QFT)&lt;/strong> ao primeiro registrador.&lt;/p>
&lt;p>Antes de medir, analisamos a natureza da onda da função $ f(x) $. Vamos supor que o segundo registrador foi observado. Suponha que um valor $ y $ foi obtido. Então, o estado do primeiro registrador encolhe para &amp;ldquo;a superposição de todos os $ x $ tais que $ a^x \pmod N = y $&amp;rdquo;.
O valor deste $ x $ estará em um estado discreto com intervalos do período $ r $ (uma espécie de distribuição de amplitude de probabilidade em forma de pente), como $ x_0, x_0 + r, x_0 + 2r, x_0 + 3r, \dots $.&lt;/p>
&lt;p>Aplicamos a Transformada Quântica de Fourier (QFT) a este estado. Assim como a Transformada Discreta de Fourier clássica converte sinais no domínio do tempo para o domínio da frequência, a QFT faz com que as amplitudes de probabilidade do estado quântico interfiram.&lt;/p>
&lt;p>Quando a QFT é aplicada, devido ao efeito de interferência quântica, as probabilidades de respostas incorretas que não ressoam com o período $ r $ (fases não alinhadas) se cancelam mutuamente chegando perto de zero (interferência destrutiva), e apenas as probabilidades da resposta correta contendo a informação do período $ r $ são amplificadas (interferência construtiva).&lt;/p>
&lt;h3 id="passo-5-medição-e-fração-contínua-pós-processamento-clássico">Passo 5: Medição e Fração Contínua (Pós-processamento Clássico)
&lt;/h3>&lt;p>Após aplicar a QFT, se você medir o primeiro registrador, com uma probabilidade muito alta, um número inteiro $ c $ próximo à forma $ c \approx \frac{j \cdot 2^n}{r} $ será obtido ( $ j $ é um inteiro desconhecido, e $ 2^n $ é o tamanho do registrador).&lt;/p>
&lt;p>Trazendo o resultado desta medição $ c $ de volta para um computador clássico, criamos uma fração $ \frac{c}{2^n} \approx \frac{j}{r} $. Em seguida, usando o método matemático da &amp;ldquo;Expansão de Fração Contínua&amp;rdquo; (Continued fraction expansion) para calcular valores aproximados, podemos descobrir o período $ r $, que é o denominador.&lt;/p>
&lt;p>Uma vez conhecido o $ r $, o resto é calcular os fatores de $ N $ usando a fórmula do Passo 1, e a criptografia RSA é completamente quebrada.&lt;/p>
&lt;hr>
&lt;h2 id="a-força-e-os-desafios-do-computador-quântico-atual-nisq">A Força e os Desafios do Computador Quântico Atual (NISQ)
&lt;/h2>&lt;p>Embora teoricamente o algoritmo de Shor seja perfeito, se perguntado &amp;ldquo;A criptografia RSA será quebrada amanhã?&amp;rdquo;, a resposta é claramente &amp;ldquo;Não&amp;rdquo;. O motivo está nas limitações da tecnologia de hardware dos computadores quânticos atuais.&lt;/p>
&lt;h3 id="a-era-nisq-noisy-intermediate-scale-quantum">A Era NISQ (Noisy Intermediate-Scale Quantum)
&lt;/h3>&lt;p>A era em que nos encontramos atualmente é chamada de &amp;ldquo;NISQ&amp;rdquo;. Dispositivos NISQ possuem dezenas a centenas de qubits físicos, mas são extremamente vulneráveis ao ruído.&lt;/p>
&lt;p>Os qubits são facilmente afetados pelo ambiente externo, como calor e ondas eletromagnéticas, e ocorrem frequentemente &amp;ldquo;decoerência&amp;rdquo; (perda de emaranhamento quântico), onde o estado quântico se quebra, e &amp;ldquo;erros de porta&amp;rdquo; durante as operações. Quando se tenta executar um circuito quântico muito profundo (com um número enorme de passos operacionais) como o algoritmo de Shor, os erros se acumulam durante o cálculo e a saída final torna-se puro ruído sem significado.&lt;/p>
&lt;h3 id="qubit-físico-e-qubit-lógico">Qubit Físico e Qubit Lógico
&lt;/h3>&lt;p>O que é essencial para resolver este problema de erros é a &amp;ldquo;Correção de Erros Quânticos&amp;rdquo; (Quantum Error Correction).
Embora códigos de correção de erros também sejam usados em computadores clássicos, devido ao &amp;ldquo;teorema da não-clonagem&amp;rdquo;, que proíbe a cópia de estados quânticos, a correção de erros quânticos é extremamente complexa.&lt;/p>
&lt;p>Na correção de erros quânticos, utilizando tecnologias como &amp;ldquo;Código de Superfície&amp;rdquo; (Surface Code), muitos &amp;ldquo;qubits físicos&amp;rdquo; ruidosos são combinados para criar um &amp;ldquo;qubit lógico&amp;rdquo; ideal e livre de erros.&lt;/p>
&lt;p>Assumindo a taxa de erro atual, estima-se que cerca de 1.000 a 10.000 qubits físicos seriam necessários para criar um único qubit lógico. Isso é chamado de &amp;ldquo;overhead da correção de erros&amp;rdquo;.&lt;/p>
&lt;h3 id="que-recursos-são-necessários-para-quebrar-a-rsa-2048">Que Recursos são Necessários para Quebrar a RSA-2048?
&lt;/h3>&lt;p>Então, para realmente descriptografar a RSA-2048, quantos recursos seriam necessários para rodar o algoritmo de Shor?&lt;/p>
&lt;p>Em uma estimativa inovadora de recursos em um artigo de 2021 de Craig Gidney (Google) e Martin Ekerå, foi afirmado que se um algoritmo de Shor otimizado fosse usado, e correção de erros com código de superfície fosse realizada, os seguintes recursos seriam necessários:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Número de qubits lógicos&lt;/strong> : Aproximadamente 4.096&lt;/li>
&lt;li>&lt;strong>Número de qubits físicos&lt;/strong> : &lt;strong>Aproximadamente 20 milhões&lt;/strong> (assumindo uma taxa de erro de $10^{-3}$)&lt;/li>
&lt;li>&lt;strong>Tempo de cálculo&lt;/strong> : Aproximadamente 8 horas (milhões a bilhões de operações físicas de porta necessárias)&lt;/li>
&lt;/ul>
&lt;p>Em contraste com isso, qual é o nível que o hardware quântico atual alcançou?
O processador quântico supercondutor &amp;ldquo;Condor&amp;rdquo;, anunciado pela IBM no final de 2023, possui 1.121 qubits. Além disso, pesquisas inovadoras sobre a geração de qubits lógicos têm aparecido (como a geração de 48 qubits lógicos usando computadores quânticos de átomos neutros pela Universidade de Harvard, QuEra, etc.), mas ainda não chegamos no estágio de conseguir executar &amp;ldquo;cálculos perfeitos e sem ruído&amp;rdquo; continuamente por longos períodos.&lt;/p>
&lt;p>Passar de alguns milhares de qubits físicos para &lt;strong>20 milhões&lt;/strong> de qubits físicos práticos (que estão interconectados, operam de forma estável em temperaturas ultrabaixas e podem processar sinais de controle em velocidades ultrarrápidas) apresenta uma enorme barreira na engenharia (problemas de fiação, limites da capacidade de refrigeração e inchaço da eletrônica de controle). Muitos especialistas preveem que levará pelo menos 10 a 30 anos, ou mais, até que um &amp;ldquo;Computador Quântico Tolerante a Falhas&amp;rdquo; (FTQC - Fault-Tolerant Quantum Computer), capaz de quebrar a RSA-2048, se torne uma realidade.&lt;/p>
&lt;hr>
&lt;h2 id="a-ameaça-silenciosa-de-store-now-decrypt-later-e-o-amanhecer-da-pqc">A Ameaça Silenciosa de &amp;ldquo;Store Now, Decrypt Later&amp;rdquo; e o Amanhecer da PQC
&lt;/h2>&lt;p>Concluir que &amp;ldquo;estamos seguros porque ainda levará mais de 10 anos&amp;rdquo; é precipitado. Atualmente, existem dados que devem ser mantidos em segredo por décadas no futuro, como segredos de estado, dados médicos e projetos de infraestrutura de longo prazo.&lt;/p>
&lt;p>A preocupação aqui é o método de ataque chamado &lt;strong>&amp;ldquo;Store Now, Decrypt Later&amp;rdquo; (Armazene Agora, Descriptografe Depois)&lt;/strong>. Nações ou organizações mal-intencionadas interceptam todos os dados de comunicação atualmente criptografados usando RSA ou ECC (Criptografia de Curva Elíptica) e os guardam no armazenamento. E então, no momento em que um poderoso computador quântico for concluído em 10 ou 20 anos, eles usarão o algoritmo de Shor para descriptografar todos os dados do passado e expor os segredos.&lt;/p>
&lt;p>Para combater essa ameaça de tempo, liderado pelo NIST (Instituto Nacional de Padrões e Tecnologia dos EUA), o processo de padronização da &lt;strong>&amp;ldquo;Criptografia Pós-Quântica&amp;rdquo; (PQC: Post-Quantum Cryptography)&lt;/strong> tem sido acelerado em ritmo acelerado.&lt;/p>
&lt;p>A PQC é um novo algoritmo de criptografia baseado em problemas matemáticos que são difíceis de descriptografar mesmo usando um computador quântico (ou seja, o algoritmo de Shor não pode ser aplicado). Como principais abordagens, temos:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Criptografia baseada em reticulados (Lattice-based cryptography)&lt;/strong> : Baseado em problemas como LWE (Learning with Errors). O método dominante na padronização do NIST (Kyber, Dilithium, etc.).&lt;/li>
&lt;li>&lt;strong>Criptografia baseada em códigos (Code-based cryptography)&lt;/strong> : Depende da dificuldade do problema de decodificação de códigos corretores de erro.&lt;/li>
&lt;li>&lt;strong>Criptografia polinomial multivariável (Multivariate cryptography)&lt;/strong> : Depende da dificuldade de resolver equações quadráticas simultâneas multivariáveis.&lt;/li>
&lt;li>&lt;strong>Assinaturas baseadas em hash (Hash-based signatures)&lt;/strong> : Assinaturas digitais que dependem exclusivamente da segurança das funções de hash.&lt;/li>
&lt;/ul>
&lt;p>Testes de implementação e implementações híbridas da PQC já foram iniciados nos principais softwares e plataformas, como o Google Chrome e o iMessage da Apple.&lt;/p>
&lt;h2 id="conclusão">Conclusão
&lt;/h2>&lt;p>Os computadores quânticos estão passando de histórias de ficção científica para desafios reais de engenharia. O algoritmo de Shor é uma grande conquista intelectual da humanidade que mescla a matemática e a mecânica quântica, mas, ao mesmo tempo, guarda um &amp;ldquo;poder destrutivo&amp;rdquo; para sacudir as bases da nossa sociedade digital.&lt;/p>
&lt;p>Isso não significa que a criptografia RSA se tornará inutilizável a partir de amanhã. No entanto, considerando a evolução da tecnologia quântica e o risco do &amp;ldquo;Store Now, Decrypt Later&amp;rdquo;, a grande migração que ficará na história da criptografia - a transição para a PQC - já começou. Agora estamos testemunhando a linha de frente de uma mudança de paradigma na segurança da informação.&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></channel></rss>