Перейти к содержимому
ecdsa.com
Rust

aws-lc-rs

aws-lc-rs от AWS — совместимый с ring API для Rust поверх C-библиотеки AWS-LC: те же константы кодирования FIXED/ASN1, что и в ring, а также P-521, secp256k1, ML-KEM и ML-DSA в стабильном API и необязательная сборка FIPS 140-3.
Лицензия
ISC AND (Apache-2.0 OR ISC)
Проверенная версия
1.18.2 ·
Исходный код
github.com/aws/aws-lc-rs
Документация
docs.rs/aws-lc-rs/1.18.2/aws_lc_rs/

Совместимость вкратце

ECDSAEdDSAПостквантовая криптография

Кривые ECDSA
P-256P-384P-521secp256k1
EdDSA
Ed25519
Форматы открытых ключей
spki-dersec1-uncompressedsec1-compressed

aws-lc-rs открывает доступ к AWS-LC — форку BoringSSL от Amazon — через API по образцу ring, поэтому большая часть кода для ring компилируется после замены имени крейта. Это криптопровайдер rustls по умолчанию, и именно его выбирают сервисы на Rust, когда им нужна сертификация FIPS 140-3 (feature-флаг fips) или постквантовые алгоритмы. C-библиотека компилируется во время сборки; для проверки версию 1.18.2 собрали с feature-флагами по умолчанию в обычном образе rust.

Кодировки подписей работают точно так же, как в ring: константы *_FIXED создают и принимают 64-байтовые подписи raw r‖s, константы *_ASN1 — DER, а подпись raw не прошла проверку с константой ASN1. Nonce случайные, s не нормализуется, а проверка принимает s из обеих половин диапазона. Помимо P-256 и P-384, которые есть в ring, библиотека подписывает и проверяет на P-521 и secp256k1, с вариантами SHA-2 и SHA-3.

В версии 1.18.2 постквантовые алгоритмы входят в стабильный API (для проверки библиотеку собрали без feature-флага unstable): ML-KEM-512, ML-KEM-768 и ML-KEM-1024 в aws_lc_rs::kem и ML-DSA-44, ML-DSA-65 и ML-DSA-87 в aws_lc_rs::signature, которые использует пример. Размеры, которые он выводит, — открытый ключ 1952 байта и подпись 3309 байт для ML-DSA-65, шифртекст 1088 байт для ML-KEM-768 — это то, что придётся передавать в сертификатах, токенах и рукопожатиях; песочница постквантовых подписей и песочница KEM сравнивают их с классическими алгоритмами.

Загрузка ключей поддерживает больше форматов, чем в ring: ключи ECDSA загружаются из PKCS#8, SEC1 (RFC 5915) DER и из скаляра в формате raw вместе с его открытым ключом, открытые ключи — из SPKI DER и из точек SEC1, сжатых или несжатых. В отличие от ring, Ed25519KeyPair::from_pkcs8 принял 48-байтовую форму PKCS#8 v1, которую записывает OpenSSL.

Если подозреваете путаницу FIXED и ASN1, воспользуйтесь конвертером DER ⇄ raw, а настройки гибридного постквантового обмена ключами подготовит генератор конфигурации TLS.

Факты и проверки, на которых они основаны

Ничего из приведённого ниже не скопировано из документации. 20 октября 2026 г. проверка content/libraries/verify/aws-lc-rs/run.sh запустила aws-lc-rs 1.18.2 в образе контейнера rust:1.99.1-trixie; содержимое страницы должно совпадать с выводом проверки, а у каждого факта приведены соответствующие строки вывода.

  • Кодировка подписи ECDSA

    der-or-raw

    Константы *_FIXED дают 64-байтовую подпись raw r‖s, константы *_ASN1 — DER; подпись raw не прошла проверку с константой ASN1.

    Что записала проверка
    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: две подписи одного сообщения различаются.

    Что записала проверка
    fact ecdsa-nonce = random
  • Low-S при подписи

    either

    s не нормализуется: среди 64 подписей встретились значения high-S.

    Что записала проверка
    fact ecdsa-low-s-sign = either
  • High-S при проверке

    accepts-high-s

    Проверка с константой FIXED приняла подпись, в которой s заменили на n − s.

    Что записала проверка
    fact ecdsa-low-s-verify = accepts-high-s
  • Что хеширует вызов подписи

    hashes-message

    Сообщение хешируется алгоритмом, указанным в константе (варианты SHA-2 или SHA-3).

    Что записала проверка
    fact ecdsa-prehash = hashes-message
  • Некорректная подпись ECDSA

    returns-error

    Для некорректных или неверных подписей проверка возвращает значение ошибки.

    Что записала проверка
    fact ecdsa-malformed-signature = returns-error
  • Кривые ECDSA

    P-256P-384P-521secp256k1

    P-256, P-384, P-521 и secp256k1: подпись и проверка прошли успешно.

    Что записала проверка
    fact ecdsa-curves = P-256, P-384, P-521, secp256k1
  • EdDSA

    Ed25519

    Ed25519.

    Что записала проверка
    fact eddsa = Ed25519
  • Ключи Ed25519 в PKCS #8 v1

    accepted

    Ed25519KeyPair::from_pkcs8 принял 48-байтовый ключ Ed25519 в формате PKCS#8 v1, а в ring такой ключ отклоняется.

    Что записала проверка
    fact ed25519-pkcs8-v1 = accepted
    evidence ed25519-pkcs8-v1: 48-byte PKCS#8 v1 Ed25519 key with from_pkcs8: Ok("ok")
  • Постквантовые алгоритмы

    ML-KEMML-DSA

    В сборке без feature-флага unstable ML-KEM-512/768/1024 прошли инкапсуляцию и декапсуляцию, а для ML-DSA-44/65/87 подпись и проверка прошли успешно.

    Что записала проверка
    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
  • Форматы открытых ключей

    spki-dersec1-uncompressedsec1-compressed

    SPKI DER через ParsedPublicKey, а также сжатые и несжатые точки SEC1.

    Что записала проверка
    fact public-key-formats = spki-der, sec1-uncompressed, sec1-compressed
  • Форматы закрытых ключей

    pkcs8-dersec1-derraw-scalar

    PKCS#8 DER, SEC1 (RFC 5915) DER и скаляр в формате raw вместе с соответствующим открытым ключом.

    Что записала проверка
    fact private-key-formats = pkcs8-der, sec1-der, raw-scalar

Использование

Подпишите и проверьте подпись с ML-DSA-65 и выполните инкапсуляцию ML-KEM-768, выводя размеры ключа, подписи и шифртекста.
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());
}

Тестовый стенд для фрагментов кода запускает каждый пример без изменений в образе контейнера rust:1.99.1-trixie, и запуск завершается ошибкой, если вывод не совпадает.

Команда
cargo run --quiet --release
Вывод должен совпадать (регулярное выражение)
ML-DSA-65: public key 1952 bytes, signature 3309 bytes, verified true\nML-KEM-768: ciphertext 1088 bytes, shared secrets match true

Библиотеки