Aller au contenu
ecdsa.com
Rust

aws-lc-rs

aws-lc-rs d’AWS, une API Rust compatible avec ring au-dessus de la bibliothèque C AWS-LC : les mêmes constantes d’encodage FIXED/ASN1 que ring, avec en plus P-521, secp256k1, ML-KEM et ML-DSA dans l’API stable, et un build FIPS 140-3 optionnel.
Licence
ISC AND (Apache-2.0 OR ISC)
Version vérifiée
1.18.2 ·
Code source
github.com/aws/aws-lc-rs
Documentation
docs.rs/aws-lc-rs/1.18.2/aws_lc_rs/

Compatibilité en un coup d’œil

ECDSAEdDSAPost-quantique

Courbes ECDSA
P-256P-384P-521secp256k1
EdDSA
Ed25519
Formats de clé publique
spki-dersec1-uncompressedsec1-compressed
Formats de clé privée
pkcs8-dersec1-derraw-scalar

aws-lc-rs expose AWS-LC, le fork de BoringSSL maintenu par Amazon, à travers une API calquée sur ring, si bien que la plupart du code ring compile après un simple changement de nom de crate. C’est le fournisseur cryptographique par défaut de rustls, et c’est vers lui que se tournent les services Rust qui ont besoin d’une validation FIPS 140-3 (la fonctionnalité fips) ou d’algorithmes post-quantiques. La bibliothèque C est compilée pendant le build ; les essais ont compilé la 1.18.2 avec les fonctionnalités par défaut dans l’image rust standard.

Les encodages de signature fonctionnent exactement comme dans ring : les constantes *_FIXED produisent et acceptent du r‖s brut de 64 octets, les constantes *_ASN1 du DER, et une signature brute a échoué sous la constante de vérification ASN1. Les nonces sont aléatoires, s n’est pas normalisé et la vérification accepte les deux moitiés. Au-delà des courbes P-256 et P-384 de ring, aws-lc-rs signe et vérifie sur P-521 et secp256k1, avec des variantes SHA-2 et SHA-3.

Les algorithmes post-quantiques font partie de l’API stable dans la 1.18.2 (les essais ont compilé sans la fonctionnalité unstable) : ML-KEM-512, ML-KEM-768 et ML-KEM-1024 dans aws_lc_rs::kem, et ML-DSA-44, ML-DSA-65 et ML-DSA-87 dans aws_lc_rs::signature, qu’utilise l’exemple. Les tailles qu’il affiche (une clé publique de 1952 octets et une signature de 3309 octets pour ML-DSA-65, un texte chiffré de 1088 octets pour ML-KEM-768) sont ce que les certificats, les jetons et les handshakes doivent transporter ; le bac à sable des signatures post-quantiques et le bac à sable KEM les comparent aux algorithmes classiques.

Le chargement des clés est plus large que dans ring : les clés ECDSA se chargent depuis PKCS#8, SEC1 (RFC 5915) DER et un scalaire brut accompagné de sa clé publique ; les clés publiques, depuis SPKI DER et des points SEC1, compressés ou non. Contrairement à ring, Ed25519KeyPair::from_pkcs8 a accepté la forme PKCS#8 v1 de 48 octets qu’écrit OpenSSL.

Utilisez le convertisseur DER ⇄ brut lorsque vous soupçonnez une confusion entre FIXED et ASN1, et le générateur de configurations TLS pour les paramètres d’échange de clés hybride post-quantique.

Les faits et les vérifications qui les fondent

Rien de ce qui suit n’est copié d’une documentation. La vérification content/libraries/verify/aws-lc-rs/run.sh a exécuté aws-lc-rs 1.18.2 dans l’image de conteneur rust:1.99.1-trixie le 20 octobre 2026 ; la page doit correspondre à ce que la vérification a affiché, et chaque fait cite les lignes en question.

  • Encodage des signatures ECDSA

    der-or-raw

    Les constantes *_FIXED signent en r‖s brut de 64 octets, les constantes *_ASN1 en DER ; une signature brute n’a pas passé la vérification sous la constante ASN1.

    Relevé par la vérification
    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 ECDSA

    random

    Nonce aléatoire : deux signatures du même message diffèrent.

    Relevé par la vérification
    fact ecdsa-nonce = random
  • Low-S à la signature

    either

    s n’est pas normalisé : des valeurs high-S sont apparues parmi 64 signatures.

    Relevé par la vérification
    fact ecdsa-low-s-sign = either
  • High-S à la vérification

    accepts-high-s

    Le vérificateur FIXED a accepté la signature dont s a été remplacé par n − s.

    Relevé par la vérification
    fact ecdsa-low-s-verify = accepts-high-s
  • Ce que l’appel de signature hache

    hashes-message

    Le message est haché par l’algorithme que nomme la constante (variantes SHA-2 ou SHA-3).

    Relevé par la vérification
    fact ecdsa-prehash = hashes-message
  • Signature ECDSA mal formée

    returns-error

    La vérification renvoie une valeur d’erreur pour les signatures mal formées ou incorrectes.

    Relevé par la vérification
    fact ecdsa-malformed-signature = returns-error
  • Courbes ECDSA

    P-256P-384P-521secp256k1

    Signature et vérification réussies avec P-256, P-384, P-521 et secp256k1.

    Relevé par la vérification
    fact ecdsa-curves = P-256, P-384, P-521, secp256k1
  • EdDSA

    Ed25519

    Ed25519.

    Relevé par la vérification
    fact eddsa = Ed25519
  • Clés Ed25519 PKCS #8 v1

    accepted

    Ed25519KeyPair::from_pkcs8 a accepté une clé Ed25519 PKCS#8 v1 de 48 octets, que ring rejette.

    Relevé par la vérification
    fact ed25519-pkcs8-v1 = accepted
    evidence ed25519-pkcs8-v1: 48-byte PKCS#8 v1 Ed25519 key with from_pkcs8: Ok("ok")
  • Algorithmes post-quantiques

    ML-KEMML-DSA

    Encapsulation et décapsulation réussies avec ML-KEM-512/768/1024, signature et vérification avec ML-DSA-44/65/87, dans un build sans la fonctionnalité unstable.

    Relevé par la vérification
    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
  • Formats de clé publique

    spki-dersec1-uncompressedsec1-compressed

    SPKI DER via ParsedPublicKey, et points SEC1 compressés ou non compressés.

    Relevé par la vérification
    fact public-key-formats = spki-der, sec1-uncompressed, sec1-compressed
  • Formats de clé privée

    pkcs8-dersec1-derraw-scalar

    PKCS#8 DER, SEC1 (RFC 5915) DER et un scalaire brut accompagné de sa clé publique.

    Relevé par la vérification
    fact private-key-formats = pkcs8-der, sec1-der, raw-scalar

Utilisation

Signer et vérifier avec ML-DSA-65, et effectuer une encapsulation ML-KEM-768, en affichant les tailles de la clé, de la signature et du texte chiffré.
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());
}

Le banc de test des extraits de code exécute chaque exemple tel quel dans l’image de conteneur rust:1.99.1-trixie, et l’exécution échoue si la sortie ne correspond pas.

Commande
cargo run --quiet --release
La sortie doit correspondre à cette expression régulière
ML-DSA-65: public key 1952 bytes, signature 3309 bytes, verified true\nML-KEM-768: ciphertext 1088 bytes, shared secrets match true

Bibliothèques