Registros de identificadores de algoritmos
Os registros de identificadores nomeados para hashes, AEADs, KEMs, KDFs e assinaturas — e a regra de agilidade que torna a migração pós-quântica aditiva, em vez de incompatível.
Toda escolha criptográfica do Label 309 é nomeada por um identificador de
texto extraído de um registro extensível — sha2-256,
chacha20-poly1305-stream64k, EdDSA e assim por diante. Um registro nunca carrega
um número de algoritmo
bruto nem uma suposição implícita: ele declara qual primitiva usou, e o
verificador consulta esse identificador. É esse o mecanismo por trás do
invariante de agilidade quanto a algoritmos: os registros podem crescer com o
tempo, e um verificador que se depara com um identificador que não implementa
rejeita o registro com um erro tipado e estável — nunca quebra e nunca
aceita silenciosamente algo que não consegue conferir.
Essa única regra é o que torna a migração para algoritmos pós-quânticos aditiva. Um novo identificador é uma nova linha em uma tabela, não uma nova versão do formato de dados. Os registros antigos continuam sendo verificados exatamente como antes, e os verificadores antigos falham de forma segura diante de registros que nunca foram projetados para entender.
Duas regras permanentes
Em todos os registros, dois limites são absolutos. As implementações NÃO DEVEM inventar criptografia nova — toda primitiva remete a um padrão público nomeado. E toda criptografia DEVE ser autenticada: apenas construções AEAD são permitidas, jamais uma cifra não autenticada com uma verificação de integridade acoplada por fora (ou inexistente).
Hash
O hash do conteúdo é a afirmação central de todo registro, então o registro de identificadores de hash é o de maior responsabilidade. Ambas as funções registradas produzem um resumo de 32 bytes, e ambas são de suporte obrigatório para uma implementação que se pretenda conforme.
| Identificador | Algoritmo | Resumo |
|---|---|---|
sha2-256 | SHA-256 (FIPS 180-4) | 32 B |
blake2b-256 | BLAKE2b-256 (RFC 7693) | 32 B |
Um produtor PODE gerar o hash do mesmo conteúdo sob ambas as funções como defesa em profundidade; um único hash basta para um registro válido.
Comprometimento Merkle
Para comprometer-se com uma lista ordenada de folhas sob uma única raiz on-chain,
o Label 309 registra um identificador de comprometimento Merkle. Trata-se da
string registrada na IANA para a árvore Merkle binária com SHA-256,
compartilhando a separação de domínio por prefixo de folha (0x00) e prefixo de
nó interno (0x01) que impede colisões entre folhas e nós.
| Identificador | Algoritmo | Raiz |
|---|---|---|
rfc9162-sha256 | Árvore Merkle binária da RFC 9162, SHA-256 | 32 B |
Uma árvore de uma única folha compromete-se com SHA-256(0x00 ‖ leaf), e não
com a folha nua — por isso uma prova de um só arquivo DEVE usar um identificador
de hash simples, nunca uma árvore de 1 folha.
AEAD
O registro AEAD determina qual formato de conteúdo protege uma carga útil selada
em trânsito — o campo enc.aead. Exatamente um identificador está registrado sob
enc.scheme: 1, e ele é um formato segmentado, não uma cifra de passada única.
| Identificador | Algoritmo | Chave / Nonce / Nonce por bloco / Tag | Status |
|---|---|---|---|
chacha20-poly1305-stream64k | ChaCha20-Poly1305, STREAM segmentado de 64 KiB | 32 B / 24 B / 12 B / 16 B por bloco | Obrigatório — o formato em trânsito |
aes-256-gcm | AES-256-GCM | — | Reservado (perfil futuro) |
chacha20-poly1305-stream64k é o ChaCha20-Poly1305
(RFC 8439) no layout STREAM segmentado de
64 KiB da especificação age v1: o
texto claro é dividido em blocos de 65536 bytes, e cada bloco é selado sob a chave de
conteúdo com um nonce por bloco de 12 bytes uint88_be(counter) ‖ final_flag
(contador a partir de 0, final_flag 0x01 no último bloco) e um AAD por bloco
vazio, produzindo uma tag de 16 bytes por bloco. O enc.nonce de 24 bytes não é
um nonce de bloco: ele é o salt único do envelope do HKDF da chave de conteúdo, que é
o que mantém os nonces de contador seguros — a chave de conteúdo é de uso único, de
modo que dois fluxos nunca compartilham um par (key, nonce) e produtores sem estado
nunca coordenam nonces entre envelopes. O layout segmentado permite que um verificador
autentique e libere uma carga útil grande de forma incremental, com memória limitada,
e o sinalizador final torna o truncamento detectável. A grafia em trânsito é
exatamente chacha20-poly1305-stream64k; grafias alternativas NÃO DEVEM ser
produzidas. A construção completa está em PoE selada.
chacha20-poly1305-stream64k é o único identificador que pode aparecer como formato
de conteúdo em trânsito. Uma construção distinta, a chacha20-poly1305
(RFC 8439, chave de 32 bytes / nonce de 12
bytes / tag de 16 bytes), é usada internamente para envolver uma chave por
destinatário dentro da construção selada: um nonce de 12 bytes todo de zeros, com o
AAD definido como o rótulo info do KEM escolhido, produzindo um wrap de 48 bytes
(chave envolvida de 32 bytes + tag de 16 bytes). É uma peça de construção, não um
identificador de trânsito, e um registro que a nomeie em enc.aead DEVE ser
rejeitado. aes-256-gcm está nomeada, mas inativa; está reservada para um perfil de
criptografia futuro (enc.scheme: 2), e um verificador v1 rejeita qualquer registro
que a selecione.
KEM
O registro KEM cobre os mecanismos de encapsulamento de chaves usados para endereçar uma carga útil selada a destinatários específicos. O Label 309 registra um KEM de curva clássica e um híbrido pós-quântico que já vem ativo desde o primeiro lançamento.
| Identificador | Algoritmo | Chave pública / Segredo | Texto cifrado / Segredo compartilhado |
|---|---|---|---|
x25519 | X25519 ECDH (RFC 7748) | 32 B / 32 B | 32 B / 32 B |
mlkem768x25519 | Híbrido X-Wing (ML-KEM-768 + X25519) | 1216 B / 32 B | 1120 B / 32 B |
mlkem768x25519 é a construção X-Wing do
draft-connolly-cfrg-xwing-kem-10:
ela combina ML-KEM-768 (FIPS 203) com
X25519 (RFC 7748) de modo que um atacante
precise quebrar os dois para recuperar o segredo compartilhado. A chave pública
é a chave de encapsulamento ML-KEM-768 concatenada com a chave pública X25519
(1184 B ‖ 32 B = 1216 B); o segredo é uma semente de 32 bytes a partir da qual a
chave completa é derivada. O texto cifrado de cada destinatário é o texto cifrado
ML-KEM-768 concatenado com uma chave pública X25519 efêmera (1088 B ‖ 32 B =
1120 B), e os dois segredos compartilhados são combinados pelo combinador
SHA3-256 do X-Wing (FIPS 202) no
segredo final de 32 bytes. O Label 309 consome o X-Wing como um KEM de caixa
preta — encapsular, desencapsular, o segredo compartilhado de 32 bytes — e não se
apoia em nenhuma propriedade do hashing interno do combinador. O identificador é
grafado sem hifens internos para corresponder à grafia consagrada de X-Wing.
O híbrido é escolhido registro a registro pelo cabeçalho de criptografia, de forma independente do AEAD de conteúdo. Como já está registrado, a confidencialidade pós-quântica é uma questão de escolher o identificador — e não de esperar por uma nova versão do formato de dados.
Um único registro nomeia exatamente um enc.kem, e todo slot usa a forma desse
KEM; um slot com a forma errada é ENC_SLOT_INVALID_SHAPE, um epk (≠ 32 B) ou um
kem_ct (≠ 1120 B) com comprimento errado é KEM_EPK_LENGTH_MISMATCH /
KEM_CT_LENGTH_MISMATCH, e um enc.kem não registrado é UNSUPPORTED_KEM_ALG. O
material de encapsulamento também deve ser distinto dentro de um mesmo
slots[]: todos os valores de epk (no caso de x25519) ou todos os valores de
kem_ct (no caso de mlkem768x25519) DEVEM ser diferentes. Uma duplicata dentro do
mesmo registro é rejeitada com
ENC_SLOTS_DUPLICATE_KEM_MATERIAL antes que qualquer primitiva KEM ou AEAD seja
executada, porque um epk ou kem_ct repetido quebra a unicidade da chave por slot
da qual o envoltório de nonce zero depende. Um verificador também limita o uso de
recursos do parser antes de qualquer primitiva: um envelope cujo slots[] exceda o
limite de referência de 1024 slots é ENC_SLOTS_TOO_MANY, e um envelope enc
decodificado que exceda 65 536 bytes é ENC_ENVELOPE_TOO_LARGE. Ambos os limites
ficam muito acima do teto de ~16 KiB de metadados da Cardano que restringe qualquer
registro honesto; são constantes impostas pelo verificador e fixadas pela implantação
— não campos de transmissão — e as implantações PODEM restringi-las.
KDF
O registro KDF nomeia as funções de derivação de chaves. hkdf-sha256 deriva
chaves dentro da construção selada; argon2id fortalece uma frase secreta humana
contra ataques de força bruta e impõe um piso obrigatório de parâmetros.
| Identificador | Algoritmo | Parâmetros |
|---|---|---|
hkdf-sha256 | HKDF-SHA-256 (RFC 5869) | salt (opcional), info (opcional), comprimento de saída |
argon2id | Argon2id (RFC 9106) | memória ≥ 65536 KiB, iterações ≥ 3, paralelismo ≥ 1 |
O piso do Argon2id é normativo: uma carga útil protegida por frase secreta DEVE
usar pelo menos 64 MiB de memória, pelo menos três iterações e pelo menos uma
faixa. Um produtor PODE escolher parâmetros mais fortes, que acompanham o registro
para que um verificador possa reproduzir a derivação. Onde a plataforma der suporte,
os produtores DEVERIAM definir o paralelismo p = 4 — o segundo perfil recomendado
da RFC 9106 §4 — enquanto um
verificador PODE aceitar qualquer p ≥ 1, sujeito aos tetos da implantação. Esses
tetos são um DEVERIA de implementação, não um PODE: um verificador DEVERIA impor
limites superiores contra uma negação de serviço, do lado do verificador, causada por
parâmetros absurdos, reportando ENC_PASSPHRASE_PARAMS_EXCEED_POLICY. O teto depende
do hardware e não é normativo, e NÃO DEVE ser confundido com o código de piso
ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW.
Apenas argon2id é selecionável em trânsito: é o único identificador que um
registro pode nomear em enc.passphrase.alg. hkdf-sha256 é uma peça de
construção interna — é a etapa fixa de extração e expansão por trás da derivação
da chave a partir da semente, da derivação da KEK por slot, da chave do MAC do
conjunto de slots, da chave do MAC do compromisso de frase secreta e da derivação da
chave de conteúdo — e não carrega identificador de trânsito algum. Um registro que
nomeie hkdf-sha256 em enc.passphrase.alg DEVE
ser rejeitado: o HKDF foi feito para entradas de alta entropia, não para fortalecer
uma frase secreta de baixa entropia.
Os rótulos internos são constantes, nunca em trânsito
A construção selada extrai sua separação de domínio de um conjunto fixo de literais
de rótulo — tags info do HKDF e prefixos SHA-256 (prefixos de salt de KEK,
prefixos de transcrição e o prefixo de hashes de item). Cada um é uma constante do
enc.scheme: 1, ASCII exato sem terminador nem prefixo de comprimento; nenhum é
jamais serializado, e nenhum é selecionável por meio de qualquer registro. São onze:
| Rótulo | Função |
|---|---|
cardano-poe-kek-v1 | info do HKDF para a KEK por slot no caminho x25519 |
cardano-poe-kek-mlkem768x25519-v1 | info do HKDF para a KEK por slot no caminho mlkem768x25519 |
cardano-poe-x25519-kek-salt-v1 | prefixo SHA-256 para o salt do HKDF da KEK x25519 |
cardano-poe-xwing-kek-salt-v1 | prefixo SHA-256 para o salt do HKDF da KEK mlkem768x25519 |
cardano-poe-item-hashes-v1 | prefixo SHA-256 para o digest de hashes de item hashes_hash |
cardano-poe-slots-transcript-v1 | prefixo SHA-256 para o hash da transcrição de slots slots_hash |
cardano-poe-slots-mac-v1 | info do HKDF para a chave do MAC do conjunto de slots |
cardano-poe-passphrase-transcript-v1 | prefixo SHA-256 para o hash da transcrição de frase secreta pw_hash |
cardano-poe-passphrase-mac-v1 | info do HKDF para a chave do MAC do compromisso de frase secreta |
cardano-poe-payload-v1 | info do HKDF para a chave de conteúdo no caminho de slots |
cardano-poe-payload-passphrase-v1 | info do HKDF para a chave de conteúdo no caminho de frase secreta |
Os dois salts de KEK compartilham uma única forma de hash rotulado —
SHA-256(label ‖ enc.nonce ‖ <material de KEM do slot> ‖ pub_R) — sob seu próprio
rótulo por KEM. Esses rótulos são distintos das strings info de derivação a partir
da semente em Chaves e do prefixo de domínio da assinatura de registro
em Assinaturas: o conjunto é livre de colisões e livre de
prefixos, de modo que nenhum rótulo selado por registro é igual — nem é um prefixo de
bytes de — um rótulo de derivação de chave de longo prazo, e a derivação da chave de
identidade e o envoltório de chave por registro nunca colidem. Um verificador DEVE
usar cada literal byte a byte; um único byte divergente produz um slots_mac, um
compromisso ou uma tag AEAD que o produtor honesto não consegue reproduzir. A
construção em nível de bytes que consome cada rótulo está em PoE selada.
Assinatura
O Label 309 registra um único algoritmo de assinatura. As assinaturas de autoria
são sempre opcionais, mas, quando presentes, são carregadas como COSE_Sign1
(RFC 9052) com Ed25519.
| Identificador | alg COSE | Algoritmo | Invólucro |
|---|---|---|---|
EdDSA | -8 | Ed25519 (RFC 8032) | COSE_Sign1 (RFC 9052) |
A verificação é estrita, conforme a RFC 8032 §5.1.7: as implementações DEVEM rejeitar codificações de assinatura não canônicas e pontos de ordem pequena (sem extensão de eliminação de cofator). Isso corresponde aos critérios conservadores de aceitação usados nas carteiras Cardano, de modo que uma assinatura válida sob uma implementação conforme é válida sob todas elas.
O suporte a assinaturas é independente da afirmação sobre o conteúdo. Um verificador que não implementa o algoritmo de assinatura de um registro marca aquele campo de assinatura como não suportado e mantém o horário e a afirmação sobre o conteúdo plenamente válidos — um algoritmo de assinatura desconhecido nunca invalida o próprio registro.
Identificadores reservados
Vários identificadores estão nomeados, mas ainda não ativos. Eles demarcam o caminho de migração acordado, para que perfis futuros usem nomes estáveis e pré-comprometidos em vez de strings improvisadas. Um produtor conforme NÃO DEVE emiti-los, e um verificador conforme DEVE rejeitar qualquer registro que use um deles, com o erro tipado correspondente.
| Identificador | Algoritmo | Função |
|---|---|---|
aes-256-gcm | AES-256-GCM (NIST SP 800-38D) | AEAD de conteúdo |
ml-kem-768 | ML-KEM-768 (FIPS 203), autônomo | KEM |
ml-dsa-65 | ML-DSA (FIPS 204) | Assinatura |
slh-dsa-sha2-128s | SLH-DSA (FIPS 205) | Assinatura |
ml-kem-768 é o KEM pós-quântico puro, distinto do híbrido registrado
mlkem768x25519; o que o Label 309 entrega é o híbrido, segundo o princípio de
que uma alternativa clássica deve permanecer mesmo depois de adicionada a metade
pós-quântica.
Agilidade de algoritmos e migração
Adicionar um algoritmo é uma operação autocontida e aditiva: citar um padrão público para a primitiva, acrescentar o identificador ao registro adequado, fornecer uma implementação criteriosa e bem revisada e publicar um fixture de conformidade entre linguagens para que implementações independentes concordem byte a byte. A versão do formato de dados não muda, porque o esquema não muda — apenas o conjunto de strings reconhecidas cresce.
As consequências decorrem diretamente do desenho do registro:
- Os registros antigos continuam verificáveis. Seus identificadores seguem no registro, então cada registro existente é verificado exatamente como no dia em que foi publicado.
- Os verificadores antigos falham de forma segura. Um verificador anterior a
um novo identificador rejeita os registros que o usam com um erro estável
UNSUPPORTED_*, em vez de adivinhar — não há caminho para a aceitação silenciosa. - O suporte pós-quântico é aditivo. Como
mlkem768x25519já está registrado, e como novos KEMs e assinaturas se encaixam no mesmo mecanismo, a transição pós-quântica é um crescimento do registro, não uma migração incompatível.
Um aumento de versão do formato de dados fica reservado a mudanças de esquema genuinamente incompatíveis — um novo campo obrigatório, um campo removido, um tipo alterado. O crescimento do registro nunca se enquadra nisso, e é justamente o que permite ao catálogo criptográfico evoluir sem jamais deixar para trás uma prova publicada.
Conteúdo e hashing
Como o Label 309 vincula um registro ao seu conteúdo — o mapa de hashes, aquilo a que o digest se compromete e os compromissos de Merkle para ancorar muitos itens sob uma única raiz.
Chaves
O modelo de chaves do Label 309 — uma semente de 32 bytes, três pares de chaves derivados dela por HKDF-SHA-256 com separação de domínio, as chaves de criptografia de chave por slot que uma PoE selada deriva sobre elas, e como as chaves públicas e os segredos dos destinatários são codificados.