Capítulo 30 — Laboratório de verificação I
Mapa da aula
Aula 30 publicada. Mapa, exemplo, EX059.
flowchart TD
N0["30.1 Testes de resposta conhecida"]
N1["30.2 Atividade prática — Laboratório V"]
N2["30.3 Interoperabilidade"]
N3["30.4 Evidências"]
N4["Nota de engenharia"]
N5["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5
N5 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX059"]
Desenho lógico
flowchart LR
N0["30.1 Testes de resposta conhecida"]
N1["30.2 Atividade prática — Laboratório V"]
N2["30.3 Interoperabilidade"]
N3["30.4 Evidências"]
N4["Nota de engenharia"]
N5["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX059"]
[30.1 Testes de resposta conhecida]
|
v
[30.2 Atividade prática — Laboratório V]
|
v
[30.3 Interoperabilidade]
|
v
[30.4 Evidências]
|
v
[Nota de engenharia]
|
v
[Síntese]
|
v
[Exemplo resolvido] --> [Exercício EX059]
Objetivos de aprendizagem
Você vai (1) verificar implementações com testes de resposta conhecida; (2) escrever testes negativos para entradas malformadas; (3) testar a interoperabilidade entre bibliotecas; e (4) registrar as evidências de verificação. O capítulo parte dos Capítulos 9, 28 e 29.
30.1 Testes de resposta conhecida
Os testes de resposta conhecida (KATs) alimentam entradas fixas e comparam as saídas com valores publicados. Os organismos de normalização e o Cryptographic Algorithm Validation Program do NIST publicam vetores; para o ML-KEM, modos de teste determinísticos permitem fixar a aleatoriedade para que as saídas possam ser comparadas byte a byte.
Os modos determinísticos existem apenas para testes; o código de produção precisa usar aleatoriedade nova, e uma verificação de build garante que os ganchos de teste não sejam alcançáveis nas versões de produção. A BPA executa a suíte de vetores a cada atualização de biblioteca e bloqueia a atualização se algum vetor falhar, o que detecta regressões como as mudanças da codificação do ML-KEM entre o rascunho e a versão final.
30.2 Atividade prática — Laboratório V
# Lab V (ch 30): known-answer and negative tests - the habit behind validating PQC libraries.
import hashlib
KATS = [ # (function, input, expected hex prefix) - published test values for SHA-3 / SHAKE on empty input
("sha3_256", b"", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"),
("shake_128/32", b"", "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26"),
]
def run(name, data):
if name == "sha3_256": return hashlib.sha3_256(data).hexdigest()
return hashlib.shake_128(data).hexdigest(32)
for name, data, want in KATS:
print(f"KAT {name:13s}", "PASS" if run(name, data) == want else "FAIL")
SIZES = {"ML-KEM-512": 800, "ML-KEM-768": 1184, "ML-KEM-1024": 1568} # encapsulation-key bytes, FIPS 203
def validate_ek(param, ek):
if len(ek) != SIZES[param]: raise ValueError(f"{param}: expected {SIZES[param]} bytes, got {len(ek)}")
return True
for param, n in [("ML-KEM-768", 1184), ("ML-KEM-768", 1183), ("ML-KEM-512", 1184)]:
try: validate_ek(param, bytes(n)); print(f"negative/positive test {param} len {n}: accepted")
except ValueError as e: print(f"negative/positive test {param} len {n}: rejected ({e})")
Saída esperada:
KAT sha3_256 PASS
KAT shake_128/32 PASS
negative/positive test ML-KEM-768 len 1184: accepted
negative/positive test ML-KEM-768 len 1183: rejected (ML-KEM-768: expected 1184 bytes, got 1183)
negative/positive test ML-KEM-512 len 1184: rejected (ML-KEM-512: expected 800 bytes, got 1184)
O validador de comprimento é só a primeira verificação: a FIPS 203 também exige verificar que os coeficientes codificados de uma chave de encapsulamento estão abaixo de q (a verificação de módulo) e uma verificação de hash nas chaves de desencapsulamento. As bibliotecas reais implementam isso; os seus testes devem confirmar que elas rejeitam chaves ruins.
O terceiro caso de teste é o importante: uma chave ML-KEM-768 de tamanho correto apresentada como ML-KEM-512 precisa ser rejeitada, porque um interpretador que confia no comprimento da chave para escolher o conjunto de parâmetros pode ser conduzido por um atacante.
30.3 Interoperabilidade
Execute handshakes entre cada par de implementações de cliente e servidor no escopo; encapsule com uma biblioteca e desencapsule com outra; assine com o HSM e verifique no software dos parceiros. Registre a matriz. As falhas de interoperabilidade no início do programa são baratas; em produção, são interrupções.
Testar uma biblioteca apenas contra ela mesma prova pouco, já que um bug de codificação de um lado é espelhado do outro e se anula. Pares de implementações diferentes expõem essas incompatibilidades. A matriz também registra as versões, então, quando uma biblioteca é atualizada, apenas as linhas afetadas são refeitas.
30.4 Evidências
Cada execução de teste registra: implementação e versão, vetores de teste usados, resultado, data, operador. As evidências alimentam a coluna de verificação da matriz de rastreabilidade (Capítulo 21).
As evidências precisam ser reprodutíveis: outro engenheiro deve conseguir refazer o mesmo teste com as mesmas versões e vetores e obter o mesmo resultado. A BPA guarda a configuração do teste junto com o resultado, então um auditor que pergunta como o REQ-KE-01 foi verificado recebe a consulta, a sua saída e a data, e não uma afirmação de que os testes foram feitos. Resultados mais antigos que a versão atual da biblioteca são marcados como vencidos e refeitos antes da versão.
30.5 Exemplo resolvido
A matriz de interoperabilidade da BPA para o TLS de borda: três pilhas de servidor × cinco famílias de clientes. Duas falhas: uma biblioteca antiga de um parceiro oferecia o codepoint obsoleto de antes da norma e não conseguia concluir handshakes híbridos; um balanceador de carga removia grupos desconhecidos. As duas recebem itens de trabalho; nenhuma bloqueia a implantação, porque o fallback para o X25519 funciona e é registrado.
O codepoint obsoleto pertence a uma implementação de rascunho do Kyber, e é por isso que os pares com o ML-KEM final não conseguem concluir o handshake; o parceiro precisa atualizar a biblioteca. O problema do balanceador de carga é mais sério, porque afeta todo o tráfego que passa por ele, então a sua correção é agendada antes que a implantação avance por esse caminho.
30.6 Erros comuns e limites
- Apenas testes positivos.
- Testar uma biblioteca contra ela mesma.
- Resultados não registrados.
Testes positivos sozinhos aprovariam um validador que aceita qualquer chave, enquanto os casos de rejeição do Laboratório V mostram que o validador realmente discrimina. Testar uma biblioteca contra ela mesma esconde incompatibilidades de codificação, que só aparecem quando há uma implementação diferente do outro lado, como mostrou a falha do codepoint obsoleto. Resultados não registrados não podem sustentar a matriz de rastreabilidade, então um teste aprovado que ninguém anotou não vale nada na revisão. O pipeline da BPA guarda cada execução com versões e vetores.
Nota de engenharia
As evidências de verificação devem poder ser reproduzidas por outra pessoa. Guarde os vetores de teste exatos, as versões das ferramentas e as linhas de comando junto com os resultados e refaça a suíte automaticamente sempre que mudar uma biblioteca, um provedor ou o firmware de um HSM. Quando um fornecedor publicar um alerta de segurança, a equipe poderá então responder em horas se a versão afetada está implantada e se os seus testes ainda passam, em vez de reconstruir a verificação original de memória e por capturas de tela.
Exercícios
- EX059 — Testes negativos. Liste cinco testes negativos para uma função de desencapsulamento ML-KEM. Rubrica: 3 = comprimento errado, texto cifrado modificado, chave errada, chave malformada, coerência de chamadas repetidas.
- EX060 — Matriz de interoperabilidade. Projete a matriz de interoperabilidade para as assinaturas dos conhecimentos de embarque da BPA. Rubrica: 3 = assinantes, verificadores, formatos, resultados esperados.
Síntese
A verificação combina testes de resposta conhecida, testes negativos e interoperabilidade entre implementações, tudo registrado como evidência rastreada até os requisitos.
Continue estudando — capítulo 30 de 50
← Capítulo 29 · Índice de capítulos do curso · Capítulo 31 →
Siga para a próxima lição escrita.