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

liboqs (Open Quantum Safe)

liboqs — библиотека проекта Open Quantum Safe на C с постквантовыми KEM и подписями: ML-KEM, ML-DSA и SLH-DSA рядом с длинным списком алгоритмов-кандидатов за единым API — по словам авторов, она предназначена для исследований и прототипирования.
Лицензия
MIT
Проверенная версия
0.16.0 ·
Исходный код
github.com/open-quantum-safe/liboqs
Документация
openquantumsafe.org/liboqs/

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

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

EdDSA
none
Постквантовые алгоритмы
ML-KEMML-DSASLH-DSAFalconHQCClassic-McElieceFrodoKEMBIKENTRUsntrup761KyberMAYOCROSSUOVSNOVAMQOM

liboqs собирает реализации постквантовых механизмов инкапсуляции ключа (OQS_KEM) и схем подписи (OQS_SIG) за единым API на C и служит движком провайдера Open Quantum Safe для OpenSSL 3. Факты на этой странице проверены на релизе 0.16.0 (коммит 5a1a854b0dc9), собранном с параметрами CMake по умолчанию, при которых симметричные примитивы берутся из OpenSSL. В README прописными буквами сказано: «МЫ ПОКА НЕ РЕКОМЕНДУЕМ ПОЛАГАТЬСЯ НА ЭТУ БИБЛИОТЕКУ В РАБОЧЕЙ СРЕДЕ ИЛИ ДЛЯ ЗАЩИТЫ КАКИХ-ЛИБО КОНФИДЕНЦИАЛЬНЫХ ДАННЫХ». Для ML-KEM и ML-DSA в рабочей среде смотрите страницы OpenSSL, BoringSSL, AWS-LC и Bouncy Castle: на них перечислено, что входит в основные API этих библиотек.

В сборке по умолчанию включены 41 KEM и 221 набор параметров подписи, и для одного набора параметров каждого семейства полный цикл прошёл успешно: стандарты NIST ML-KEM, ML-DSA и SLH-DSA (156 вариантов SLH-DSA, чистых и с предварительным хешированием), Falcon, KEM-кандидаты HQC, Classic McEliece, FrodoKEM, BIKE, NTRU и sntrup761, предстандартный Kyber и дополнительные кандидаты в схемы подписи MAYO, CROSS, UOV, SNOVA и MQOM. В новом коде указывайте ML-KEM-768, а не Kyber768. Ни один набор параметров XMSS или LMS в сборке по умолчанию не включён.

Подписание ML-DSA рандомизировано (hedged): две подписи одного и того же сообщения одним и тем же ключом различались, поэтому тесты должны проверять подписи, а не сравнивать байты. Строки контекста FIPS 204 поддерживаются через OQS_SIG_sign_with_ctx_str; подпись, созданная с контекстом invoice-v1, не прошла проверку с invoice-v2 и с обычной OQS_SIG_verify, которая использует пустой контекст, поэтому обе стороны должны согласовать контекст. Обрезанная подпись, 3-байтовый блок данных и верная подпись других данных вернули одну и ту же ошибку OQS_ERROR.

Декапсуляция ML-KEM не сообщает о повреждённом шифртексте: после инверсии одного бита OQS_KEM_decaps вернула OQS_SUCCESS и другой общий секрет, как того требует неявное отклонение (implicit rejection) из FIPS 203. Несовпадение проявляется только при использовании выведенных ключей, например как ошибка расшифрования AEAD. Кроме того, функция не принимает длину шифртекста и читает ровно length_ciphertext байт (1088 байт для ML-KEM-768). Попробуйте обе схемы в инструменте ML-KEM и инструменте постквантовых подписей.

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

Ничего из приведённого ниже не скопировано из документации. 20 октября 2026 г. проверка content/libraries/verify/liboqs/run.sh запустила liboqs (Open Quantum Safe) 0.16.0 в образе контейнера debian:trixie-20261005-slim; содержимое страницы должно совпадать с выводом проверки, а у каждого факта приведены соответствующие строки вывода.

  • Кривые ECDSA

    none

    ECDSA нет: все включённые идентификаторы алгоритмов относятся к постквантовым семействам.

    Что записала проверка
    fact ecdsa-curves = none
  • EdDSA

    none

    EdDSA нет: liboqs реализует только постквантовые схемы.

    Что записала проверка
    fact eddsa = none
  • Постквантовые алгоритмы

    ML-KEMML-DSASLH-DSAFalconHQCClassic-McElieceFrodoKEMBIKENTRUsntrup761KyberMAYOCROSSUOVSNOVAMQOM

    В сборке по умолчанию для одного набора параметров каждого из перечисленных семейств успешно прошли генерация ключей, инкапсуляция или подпись и декапсуляция или проверка.

    Что записала проверка
    fact pqc = ML-KEM, ML-DSA, SLH-DSA, Falcon, HQC, Classic-McEliece, FrodoKEM, BIKE, NTRU, sntrup761, Kyber, MAYO, CROSS, UOV, SNOVA, MQOM
    evidence pqc: enabled: 41 KEMs, 221 signature schemes, 0 stateful signature schemes
    evidence pqc: enabled parameter sets by identifier prefix: ML-KEM- 3, ML-DSA- 3, SLH_DSA 156, Falcon- 4, HQC- 3, Classic-McEliece- 10, FrodoKEM- 6, eFrodoKEM- 6, BIKE- 3, NTRU- 6, sntrup 1, Kyber 3, MAYO- 4, cross- 18, OV- 12, SNOVA 12, mqom2 12
    evidence pqc: first parameter set of each family run end to end; failures: none
  • Подписи с состоянием на основе хеш-функций

    not-built

    В сборке по умолчанию не включён ни один набор параметров XMSS или LMS.

    Что записала проверка
    fact stateful-signatures = not-built
    evidence stateful-signatures: no XMSS or LMS parameter set is enabled in this build
  • Режим подписи ML-DSA

    hedged

    Две подписи ML-DSA-65 одного сообщения одним ключом различались (рандомизированное подписание, hedged).

    Что записала проверка
    fact ml-dsa-signing = hedged
    evidence ml-dsa-signing: ML-DSA-65: public key 1952 bytes, signature 3309 bytes; two signatures of one message are different
  • Строка контекста ML-DSA

    supported

    Подпись с контекстом invoice-v1 прошла проверку с этим контекстом и не прошла с invoice-v2 и с пустым контекстом.

    Что записала проверка
    fact ml-dsa-context-string = supported
    evidence ml-dsa-context-string: signed with context "invoice-v1": verifies with it yes, with "invoice-v2" no, with OQS_SIG_verify no
    evidence ml-dsa-context-string: an OQS_SIG_sign signature verifies with a zero-length context: yes
  • Некорректная подпись ML-DSA

    returns-false

    Обрезанная подпись, 3 байта данных и неверное сообщение вернули OQS_ERROR (-1).

    Что записала проверка
    fact ml-dsa-malformed-signature = returns-false
    evidence ml-dsa-malformed-signature: OQS_SIG_verify: truncated signature -1, 3 bytes -1, wrong message -1 (OQS_SUCCESS = 0, OQS_ERROR = -1)
  • Изменённый шифртекст ML-KEM

    implicit-rejection

    После инверсии одного бита шифртекста OQS_KEM_decaps вернула OQS_SUCCESS и другой общий секрет.

    Что записала проверка
    fact ml-kem-modified-ciphertext = implicit-rejection
    evidence ml-kem-modified-ciphertext: ML-KEM-768 (public key 1184, ciphertext 1088 bytes): one flipped bit, OQS_KEM_decaps returned 0 and the secrets differ
    evidence ml-kem-modified-ciphertext: kem.h: OQS_API OQS_STATUS OQS_KEM_decaps(const OQS_KEM *kem, uint8_t *shared_secret, const uint8_t *ciphertext, const uint8_t *secret_key)

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

Выполните обмен ключами ML-KEM-768, а затем подпишите и проверьте подпись ML-DSA-65 со строкой контекста.
#include <oqs/oqs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    OQS_init();
    /* ML-KEM-768: the receiver publishes pk, the sender encapsulates a fresh secret to it. */
    OQS_KEM *kem = OQS_KEM_new(OQS_KEM_alg_ml_kem_768);
    uint8_t *pk = malloc(kem->length_public_key), *sk = malloc(kem->length_secret_key);
    uint8_t *ct = malloc(kem->length_ciphertext), sent[32], received[32];
    OQS_KEM_keypair(kem, pk, sk);
    OQS_KEM_encaps(kem, ct, sent, pk);
    /* Decapsulation never reports a damaged ciphertext: it yields a different secret instead. */
    OQS_KEM_decaps(kem, received, ct, sk);
    printf("ML-KEM-768 secrets match: %d\n", memcmp(sent, received, 32) == 0);

    /* ML-DSA-65 with a FIPS 204 context string that ties the signature to one purpose. */
    OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_ml_dsa_65);
    uint8_t *vk = malloc(sig->length_public_key), *dk = malloc(sig->length_secret_key);
    uint8_t *s = malloc(sig->length_signature);
    const uint8_t msg[] = "order #1042 approved", ctx[] = "invoice-v1";
    size_t len = 0;
    OQS_SIG_keypair(sig, vk, dk);
    OQS_SIG_sign_with_ctx_str(sig, s, &len, msg, sizeof msg - 1, ctx, sizeof ctx - 1, dk);
    OQS_STATUS rc = OQS_SIG_verify_with_ctx_str(sig, msg, sizeof msg - 1, s, len, ctx, sizeof ctx - 1, vk);
    printf("ML-DSA-65 verified: %d (%zu-byte signature)\n", rc == OQS_SUCCESS, len);

    OQS_MEM_secure_free(sk, kem->length_secret_key);
    OQS_MEM_secure_free(dk, sig->length_secret_key);
    free(pk), free(ct), free(vk), free(s);
    OQS_KEM_free(kem), OQS_SIG_free(sig);
    OQS_destroy();
    return 0;
}

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

Подготовка
apt-get -qq update >/dev/null && apt-get -qq install -y --no-install-recommends build-essential cmake ninja-build git ca-certificates libssl-dev >/dev/null 2>&1 && git clone -q --depth 1 --branch 0.16.0 https://github.com/open-quantum-safe/liboqs /oqs 2>/dev/null && test "$(git -C /oqs rev-parse HEAD)" = 5a1a854b0dc9f2141bdc771c555ee60c37950183 && cmake -S /oqs -B /oqs/build -G Ninja -DOQS_BUILD_ONLY_LIB=ON >/dev/null 2>&1 && ninja -C /oqs/build install >/dev/null
Команда
cc -o usage usage.c -loqs -lcrypto && ./usage
Вывод должен совпадать (регулярное выражение)
ML-KEM-768 secrets match: 1\nML-DSA-65 verified: 1 \(3309-byte signature\)

Библиотеки