Resumo. Um modelo interno da Anthropic ajudou a reconstruir a origem de parâmetros criptográficos. Uma reprodução local mostra o que pode ser conferido — e por que isso não significa quebrar a segurança digital.
Um número publicado em um manual pode guardar um mistério por décadas. Não porque esteja escondido, mas porque ninguém documentou como chegou até ali. Foi esse tipo de problema que uma equipe da Anthropic investigou com ajuda de IA: a origem de valores usados na construção de curvas criptográficas. O resultado interessa muito além da segurança digital. Ele mostra uma diferença decisiva entre uma máquina apresentar uma explicação convincente e produzir uma explicação que outras pessoas conseguem conferir.
Como ler este artigo. Distingo o relato da Anthropic, a verificação externa de Filippo Valsorda e uma reprodução executada pelo Codex, assistente de IA, durante esta preparação editorial. Essa reprodução confere números publicados; não testa o Claude usado na descoberta nem demonstra a segurança do sistema criptográfico.
Em 16 de outubro, a Anthropic divulgou que um modelo interno de pesquisa identificou como foram geradas as sementes de cinco curvas NIST: P-192, P-224, P-256, P-384 e P-521. Segundo a empresa, a descoberta ocorreu naquele mês, em menos de meia hora, e envolveu um gerador de números pseudoaleatórios inicializado com horários de 1997 e 1998. O comunicado não identifica uma versão comercial equivalente: não é o lançamento de uma função disponível para todos os assinantes. [1]
Em texto também publicado em 16 de outubro, o criptógrafo Filippo Valsorda informa ter reimplementado o algoritmo em Go para verificá-lo. A reivindicação do prêmio chegou em 15 de outubro, às 01h07min51s UTC. Organizador da recompensa, ele é uma fonte externa participante da iniciativa, não um auditor independente do modelo. [2]
O prêmio base era de US$ 12.288 e triplicava na opção de doação. A equipe escolheu o ISRG, responsável pelo Let’s Encrypt, levando o valor a US$ 36.864. [5] [2]
ECDSA significa Elliptic Curve Digital Signature Algorithm: algoritmo de assinatura digital com curvas elípticas. Uma assinatura digital permite verificar se dados foram alterados e se a assinatura corresponde à chave pública esperada. Não é simplesmente uma imagem da assinatura de alguém, nem é sinônimo de esconder o conteúdo de um documento. [3]
Pense em duas perguntas diferentes sobre um arquivo: “alguém modificou isto?” e “alguém consegue ler isto?”. Assinatura e cifragem têm funções distintas. A primeira ajuda a verificar integridade e origem; a segunda trata da confidencialidade. O caso desta notícia pertence à história dos parâmetros de um mecanismo de assinatura.
Uma curva elíptica, nesse contexto, é uma estrutura matemática definida por regras e números. A semente investigada é um valor público usado na derivação de parâmetros dessa estrutura. Ela não é a chave privada de um usuário. Saber de onde veio esse número não fornece, por si só, a capacidade de assinar documentos em nome de outra pessoa.
O padrão histórico FIPS 186-2, publicado pelo NIST em 27 de janeiro de 2000, já apresentava os números. Para a P-256, por exemplo, a semente começa com C49D3608. Não era necessário invadir um computador para conhecê-la: estava no documento público, hoje arquivado. [3]
A questão era outra: por que escolheram exatamente esse valor? Em setembro de 2023, Stephen A. Weis reuniu relatos sobre as sementes fornecidas pela NSA, agência de segurança dos Estados Unidos. Havia lembranças de uma frase bem-humorada transformada por uma função de hash, cálculo que produz uma sequência de tamanho definido a partir de uma entrada. Weis também integra a equipe do relato da Anthropic de 2026; sua investigação histórica não é uma confirmação externa desse trabalho. [4] [1]
A pista da frase estava errada para essas sementes: elas eram saídas de um gerador, não de hash. Segundo a Anthropic, o modelo não recebeu essa pista. Isso não elimina o uso posterior de hash na derivação das curvas; corrige a história da etapa anterior, a geração das sementes públicas. [1]
Em outubro de 2023, Valsorda anunciou a recompensa e descreveu essa pista como uma hipótese a investigar, não uma memória infalível. [5] Aqui há uma lição de documentação: publicar o resultado não é o mesmo que preservar o processo. Uma planilha pode guardar o total e perder a regra de cálculo; um sistema pode manter a configuração e perder a justificativa. A lacuna convida tanto à investigação séria quanto à especulação.
A suspeita era que a NSA pudesse escolher sementes até encontrar curvas com uma fraqueza oculta. O precedente Dual_EC_DRBG, outro mecanismo criptográfico, alimentava a desconfiança: em 2014, o NIST anunciou sua retirada da revisão das recomendações para geradores de números aleatórios, após preocupações sobre sua confiabilidade. Isso não prova a mesma falha nas curvas desta notícia. [7]
Valsorda retoma uma técnica de seleção descrita por Daniel Bernstein e Tanja Lange que dependia de grande liberdade de escolha. Para ele, a receita reconstruída a descarta: mesmo permitindo qualquer horário de 1997–1998 e os primeiros dezesseis candidatos válidos, restariam cerca de 30 bits de liberdade. [2] Trata-se da quantidade de escolhas possíveis no cenário analisado, não de uma medida da força das chaves. A descoberta restringe uma hipótese concreta de manipulação; não constitui uma prova universal de segurança.
Um gerador pseudoaleatório produz números que aparentam variar ao acaso, mas seguem um procedimento determinístico: com o mesmo estado inicial e as mesmas regras, a sequência se repete. A família de funções drand48, documentada pelo padrão POSIX, usa aritmética de 48 bits. A função srand48 define seu estado inicial; lrand48 fornece uma das formas de saída. São partes da mesma família, não nomes intercambiáveis de uma única função. [6]
Na receita reproduzida abaixo, o ponto de partida é um timestamp Unix: a representação numérica de um instante em segundos desde 1º de janeiro de 1970, em UTC. Esse número alimenta o gerador. Extraem-se bytes, unidades de oito bits, e cada grupo de vinte forma uma semente candidata. A receita conhecida permite chegar novamente a um valor publicado décadas antes.

Durante a preparação deste artigo, o Codex executou uma implementação local em Python 3.12.14, em Linux. O script calculou as saídas deterministicamente, sem chamar uma API de IA. Foram usadas as cinco combinações de horário e posição já divulgadas, comparando a saída com as sementes do padrão histórico.
As cinco sequências coincidiram integralmente. Na P-256, o instante de 16 de agosto de 1997, às 01h52min34s UTC, corresponde ao timestamp 871696354. O candidato de posição 1.842 produziu C49D360886E704936A6678E1139D26B7819F7E90: os mesmos vinte bytes publicados.
Também foram executados dois controles para cada curva: aumentar o horário inicial em um segundo e usar o candidato imediatamente anterior. Nas dez verificações, a sequência deixou de coincidir. Isso ajuda a conferir se a implementação responde às entradas, em vez de apenas devolver um valor fixo. Não demonstra que a receita é única, nem substitui a investigação que a encontrou.

Reproduzir uma receita depois de conhecer suas entradas é muito mais fácil que descobri-la. Essa distinção não diminui a descoberta; define o que foi conferido aqui. O código completo e seu registro de execução acompanham a versão preparada deste artigo, em uma seção técnica recolhível.
A Anthropic diz que não houve quebra criptográfica nem necessidade de ação pelos usuários. Atribui seis pontos-base, referências matemáticas para operações nas curvas, ao gerador FreeLIP. Permanecem sem explicação os pontos-base da P-224, P-256, P-384, P-521 e das curvas binárias, além da semente B-163. [1]
Na P-256, o candidato 876 era válido, mas foi pulado antes da escolha do 1.842. Valsorda encontra cerca do dobro de sementes válidas em relação às publicadas e um critério ainda desconhecido. [2] Explicar a origem não explica cada decisão.
Há ainda três avaliações separadas: conferir a origem dos parâmetros, analisar a segurança matemática e verificar a implementação de um sistema real. Um resultado positivo na primeira não responde automaticamente às outras duas. Tampouco autoriza usar um gerador antigo, inicializado pelo relógio, para criar senhas ou chaves privadas: parâmetros públicos e segredos têm exigências diferentes.
Minha leitura é que o maior valor prático do caso está na forma de trabalhar com a IA. Imagine um relatório que mostra uma queda de custos. Em vez de pedir apenas uma explicação, peça as entradas, o cálculo e uma maneira de repetir o resultado. Veja também como verificar respostas da inteligência artificial antes de usá-las no trabalho. Depois altere deliberadamente uma condição: retire um mês, mude uma unidade ou acrescente um registro conhecido. A resposta deve mudar de maneira previsível.
O mesmo vale para uma automação que recupera regras de um sistema antigo. Separe o que foi encontrado no código, o que foi inferido e o que foi confirmado em execução. Não permita que uma descrição elegante elimine as pendências. Uma hipótese útil precisa carregar junto uma forma de ser contrariada.
Para estudar ou ensinar, proponho um exercício simples: um grupo recebe apenas a sequência final; outro recebe a sequência e a receita. Ambos explicam como verificariam a origem. A comparação ajuda a perceber por que reconhecer um padrão, reproduzi-lo e compreender sua causa são tarefas relacionadas, mas distintas. É uma proposta didática, não um resultado de pesquisa sobre aprendizagem.
Esse hábito também serve ao desenvolvimento pessoal: trocar a pergunta “a explicação parece inteligente?” por “o que me faria mudar de opinião?”. Neste caso, a contribuição da IA ganha força justamente porque não precisa ser aceita por confiança. A receita sai da conversa e encontra um teste. O avanço não foi descobrir uma chave secreta: foi tornar verificável uma parte antes obscura da história.
Execução pelo Codex em Linux, Python 3.12.14. SHA-256 do código: 7ca0b5dd35ef04b5caa03c9ba87531ffeb045760f857810e99dcf3ef75ebb26e. São cinco casos com correspondência esperada e dez controles com divergência esperada; não são quinze avaliações de segurança.
O deslocamento state >> 40 equivale a lrand48() >> 23: a função já descarta os 17 bits inferiores do estado, e 17 + 23 = 40. O código abaixo foi preservado integralmente.
"""Reprodução editorial da receita pública da Anthropic, não da descoberta.
Referência: https://www.anthropic.com/research/ecdsa-curve-origins
Código da fonte dedicado a CC0. Implementação editorial por Codex.
Não gera chaves, não assina e não avalia a segurança de curvas.
"""
from datetime import datetime, timezone
import hashlib
import json
import platform
from pathlib import Path
CASES = [
("P-192", "1997-05-18 14:45:34", 139, "3045AE6FC8422F64ED579528D38120EAE12196D5"),
("P-224", "1998-04-03 12:52:07", 7026, "BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"),
("P-256", "1997-08-16 01:52:34", 1842, "C49D360886E704936A6678E1139D26B7819F7E90"),
("P-384", "1997-08-30 14:50:08", 2688, "A335926AA319A27A1D00896A6773A4827ACDAC73"),
("P-521", "1997-08-08 01:12:04", 1136, "D09E8800291CB85396CC6717393284AAA0DA64BA"),
]
def generate(timestamp, candidate_index):
if candidate_index < 1:
raise ValueError("O índice começa em 1")
state = ((timestamp & 0xFFFFFFFF) << 16) | 0x330E
output = bytearray()
for step in range(20 * candidate_index):
state = (0x5DEECE66D * state + 0xB) % (1 << 48)
if step >= 20 * (candidate_index - 1):
output.append(state >> 40)
return output.hex().upper()
rows = []
for name, when, index, expected in CASES:
stamp = int(datetime.fromisoformat(when).replace(tzinfo=timezone.utc).timestamp())
actual = generate(stamp, index)
controls = {
"timestamp_mais_um_segundo_diverge": generate(stamp + 1, index) != expected,
"candidato_anterior_diverge": generate(stamp, index - 1) != expected,
}
assert actual == expected, name
assert all(controls.values()), name
rows.append(dict(curva=name, data_utc=when, timestamp=stamp, candidato=index,
esperado=expected, obtido=actual, coincide=True, controles=controls))
report = {
"executor": "Codex, assistente de IA, execução local isolada",
"data": datetime.now(timezone.utc).isoformat(),
"python": platform.python_version(),
"plataforma": platform.system(),
"sha256_codigo": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),
"casos_positivos": len(rows), "controles_negativos": len(rows) * 2,
"resultados": rows,
"limites": "Reprodução de bytes com entradas já divulgadas; não repete a busca, não calcula curvas, não demonstra segurança e não testa o modelo interno.",
}
print(json.dumps(report, ensure_ascii=False, indent=2))
{
"executor": "Codex, assistente de IA, execução local isolada",
"data": "2026-10-18T19:40:19.320852+00:00",
"python": "3.12.14",
"plataforma": "Linux",
"sha256_codigo": "7ca0b5dd35ef04b5caa03c9ba87531ffeb045760f857810e99dcf3ef75ebb26e",
"casos_positivos": 5,
"controles_negativos": 10,
"resultados": [
{
"curva": "P-192",
"data_utc": "1997-05-18 14:45:34",
"timestamp": 863966734,
"candidato": 139,
"esperado": "3045AE6FC8422F64ED579528D38120EAE12196D5",
"obtido": "3045AE6FC8422F64ED579528D38120EAE12196D5",
"coincide": true,
"controles": {
"timestamp_mais_um_segundo_diverge": true,
"candidato_anterior_diverge": true
}
},
{
"curva": "P-224",
"data_utc": "1998-04-03 12:52:07",
"timestamp": 891607927,
"candidato": 7026,
"esperado": "BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5",
"obtido": "BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5",
"coincide": true,
"controles": {
"timestamp_mais_um_segundo_diverge": true,
"candidato_anterior_diverge": true
}
},
{
"curva": "P-256",
"data_utc": "1997-08-16 01:52:34",
"timestamp": 871696354,
"candidato": 1842,
"esperado": "C49D360886E704936A6678E1139D26B7819F7E90",
"obtido": "C49D360886E704936A6678E1139D26B7819F7E90",
"coincide": true,
"controles": {
"timestamp_mais_um_segundo_diverge": true,
"candidato_anterior_diverge": true
}
},
{
"curva": "P-384",
"data_utc": "1997-08-30 14:50:08",
"timestamp": 872952608,
"candidato": 2688,
"esperado": "A335926AA319A27A1D00896A6773A4827ACDAC73",
"obtido": "A335926AA319A27A1D00896A6773A4827ACDAC73",
"coincide": true,
"controles": {
"timestamp_mais_um_segundo_diverge": true,
"candidato_anterior_diverge": true
}
},
{
"curva": "P-521",
"data_utc": "1997-08-08 01:12:04",
"timestamp": 871002724,
"candidato": 1136,
"esperado": "D09E8800291CB85396CC6717393284AAA0DA64BA",
"obtido": "D09E8800291CB85396CC6717393284AAA0DA64BA",
"coincide": true,
"controles": {
"timestamp_mais_um_segundo_diverge": true,
"candidato_anterior_diverge": true
}
}
],
"limites": "Reprodução de bytes com entradas já divulgadas; não repete a busca, não calcula curvas, não demonstra segurança e não testa o modelo interno."
}
Capa: ilustração conceitual gerada por IA. Não retrata os pesquisadores ou equipamentos da descoberta.
Assine a newsletter e receba conteúdos objetivos para aplicar no trabalho e na carreira.
Quero receber os conteúdos