Pular para o conteúdo
ecdsa.com
Rust

aws-lc-rs

O aws-lc-rs da AWS, uma API Rust compatível com o ring sobre a biblioteca C AWS-LC: as mesmas constantes de codificação FIXED/ASN1 do ring, mais P-521, secp256k1, ML-KEM e ML-DSA na API estável e um build FIPS 140-3 opcional.
Licença
ISC AND (Apache-2.0 OR ISC)
Versão verificada
1.18.2 ·
Código-fonte
github.com/aws/aws-lc-rs
Documentação
docs.rs/aws-lc-rs/1.18.2/aws_lc_rs/

Visão geral da compatibilidade

ECDSAEdDSAPós-quântica

Curvas ECDSA
P-256P-384P-521secp256k1
EdDSA
Ed25519
Formatos de chave pública
spki-dersec1-uncompressedsec1-compressed
Formatos de chave privada
pkcs8-dersec1-derraw-scalar

O aws-lc-rs expõe o AWS-LC — o fork do BoringSSL mantido pela Amazon — por meio de uma API inspirada no ring, de modo que a maior parte do código escrito para o ring compila depois de trocar o nome do crate. Ele é o provedor de criptografia padrão do rustls e é a opção dos serviços Rust que precisam de validação FIPS 140-3 (a feature fips) ou de algoritmos pós-quânticos. A biblioteca C é compilada durante o build; o teste compilou a versão 1.18.2 com as features padrão na imagem rust simples.

As codificações de assinatura funcionam exatamente como no ring: as constantes *_FIXED produzem e aceitam r‖s bruto de 64 bytes, as constantes *_ASN1, DER, e uma assinatura bruta falhou com a constante de verificação ASN1. Os nonces são aleatórios, o s não é normalizado e a verificação aceita as duas metades. Além das curvas P-256 e P-384 do ring, ele assina e verifica na P-521 e na secp256k1, com variantes SHA-2 e SHA-3.

Os algoritmos pós-quânticos fazem parte da API estável na versão 1.18.2 — o teste compilou sem a feature unstable: ML-KEM-512, ML-KEM-768 e ML-KEM-1024 em aws_lc_rs::kem, e ML-DSA-44, ML-DSA-65 e ML-DSA-87 em aws_lc_rs::signature, que o exemplo usa. Os tamanhos que ele imprime — uma chave pública de 1952 bytes e uma assinatura de 3309 bytes no ML-DSA-65, um texto cifrado de 1088 bytes no ML-KEM-768 — são o que certificados, tokens e handshakes precisam transportar; o playground de assinaturas pós-quânticas e o playground de KEM os comparam com algoritmos clássicos.

O carregamento de chaves é mais amplo que o do ring: chaves ECDSA são carregadas de PKCS#8 e SEC1 (RFC 5915) em DER e de um escalar bruto acompanhado da chave pública; chaves públicas, de SPKI DER e de pontos SEC1, comprimidos ou não. Ao contrário do ring, Ed25519KeyPair::from_pkcs8 aceitou a forma PKCS#8 v1 de 48 bytes que o OpenSSL grava.

Use o conversor DER ⇄ bruto quando suspeitar de uma incompatibilidade entre FIXED e ASN1, e o gerador de configurações TLS para as configurações de troca de chaves híbrida pós-quântica.

Os fatos e as verificações por trás deles

Nada abaixo foi copiado da documentação. A verificação content/libraries/verify/aws-lc-rs/run.sh executou aws-lc-rs 1.18.2 na imagem de contêiner rust:1.99.1-trixie em 20 de outubro de 2026; a página precisa corresponder ao que a verificação imprimiu, e cada fato lista essas linhas.

  • Codificação da assinatura ECDSA

    der-or-raw

    As constantes *_FIXED assinam em r‖s bruto de 64 bytes, e as constantes *_ASN1, em DER; uma assinatura bruta não passou na verificação com a constante ASN1.

    Registrado pela verificação
    fact ecdsa-signature-encoding = der-or-raw
    evidence ecdsa-signature-encoding: FIXED signs 64 bytes; the same bytes verify under the ASN1 constant: false
  • Nonce do ECDSA

    random

    Nonce aleatório: duas assinaturas da mesma mensagem são diferentes.

    Registrado pela verificação
    fact ecdsa-nonce = random
  • Low-S ao assinar

    either

    O s não é normalizado: valores high-S apareceram entre 64 assinaturas.

    Registrado pela verificação
    fact ecdsa-low-s-sign = either
  • High-S ao verificar

    accepts-high-s

    O verificador FIXED aceitou a assinatura com s substituído por n − s.

    Registrado pela verificação
    fact ecdsa-low-s-verify = accepts-high-s
  • Entrada do hash na chamada de assinatura

    hashes-message

    O hash da mensagem é calculado com o algoritmo indicado na constante (variantes SHA-2 ou SHA-3).

    Registrado pela verificação
    fact ecdsa-prehash = hashes-message
  • Assinatura ECDSA malformada

    returns-error

    A verificação retorna um valor de erro para assinaturas malformadas ou incorretas.

    Registrado pela verificação
    fact ecdsa-malformed-signature = returns-error
  • Curvas ECDSA

    P-256P-384P-521secp256k1

    Assinatura e verificação funcionaram com P-256, P-384, P-521 e secp256k1.

    Registrado pela verificação
    fact ecdsa-curves = P-256, P-384, P-521, secp256k1
  • EdDSA

    Ed25519

    Ed25519.

    Registrado pela verificação
    fact eddsa = Ed25519
  • Chaves Ed25519 PKCS #8 v1

    accepted

    Ed25519KeyPair::from_pkcs8 aceitou uma chave Ed25519 PKCS#8 v1 de 48 bytes, que o ring rejeita.

    Registrado pela verificação
    fact ed25519-pkcs8-v1 = accepted
    evidence ed25519-pkcs8-v1: 48-byte PKCS#8 v1 Ed25519 key with from_pkcs8: Ok("ok")
  • Algoritmos pós-quânticos

    ML-KEMML-DSA

    O encapsulamento e o desencapsulamento com ML-KEM-512/768/1024 e a assinatura e a verificação com ML-DSA-44/65/87 funcionaram em um build sem a feature unstable.

    Registrado pela verificação
    fact pqc = ML-KEM, ML-DSA
    evidence pqc: ML-KEM-512/768/1024 via aws_lc_rs::kem; ML-DSA-44/65/87 via aws_lc_rs::signature
  • Formatos de chave pública

    spki-dersec1-uncompressedsec1-compressed

    SPKI DER por meio de ParsedPublicKey e pontos SEC1 comprimidos ou não comprimidos.

    Registrado pela verificação
    fact public-key-formats = spki-der, sec1-uncompressed, sec1-compressed
  • Formatos de chave privada

    pkcs8-dersec1-derraw-scalar

    PKCS#8 DER, SEC1 (RFC 5915) DER e um escalar bruto junto com a chave pública correspondente.

    Registrado pela verificação
    fact private-key-formats = pkcs8-der, sec1-der, raw-scalar

Uso

Assine e verifique com ML-DSA-65 e execute um encapsulamento ML-KEM-768, imprimindo os tamanhos da chave, da assinatura e do texto cifrado.
use aws_lc_rs::kem::{DecapsulationKey, ML_KEM_768};
use aws_lc_rs::signature::{self, KeyPair, PqdsaKeyPair, UnparsedPublicKey};

fn main() {
    // ML-DSA-65 (FIPS 204) through the stable signature API.
    let key = PqdsaKeyPair::generate(&signature::ML_DSA_65_SIGNING).unwrap();
    let message = b"release v2.0 manifest";
    let mut sig = vec![0u8; signature::ML_DSA_65_SIGNING.signature_len()];
    let len = key.sign(message, &mut sig).unwrap();
    let ok = UnparsedPublicKey::new(&signature::ML_DSA_65, key.public_key().as_ref()).verify(message, &sig[..len]);
    println!("ML-DSA-65: public key {} bytes, signature {len} bytes, verified {}", key.public_key().as_ref().len(), ok.is_ok());

    // ML-KEM-768 (FIPS 203): the receiver publishes the encapsulation key.
    let receiver = DecapsulationKey::generate(&ML_KEM_768).unwrap();
    let (ciphertext, sender_secret) = receiver.encapsulation_key().unwrap().encapsulate().unwrap();
    let receiver_secret = receiver.decapsulate(ciphertext.as_ref().into()).unwrap();
    println!("ML-KEM-768: ciphertext {} bytes, shared secrets match {}", ciphertext.as_ref().len(), sender_secret.as_ref() == receiver_secret.as_ref());
}

O executor de trechos de código roda cada exemplo literalmente na imagem de contêiner rust:1.99.1-trixie, e a execução falha se a saída não corresponder.

Comando
cargo run --quiet --release
A saída deve corresponder a (expressão regular)
ML-DSA-65: public key 1952 bytes, signature 3309 bytes, verified true\nML-KEM-768: ciphertext 1088 bytes, shared secrets match true

Bibliotecas