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

ML-DSA или SLH-DSA: подписи на решётках или на хешах

ML-DSA — постквантовая подпись общего назначения: подписи в несколько килобайт и быстрое подписание. Стойкость SLH-DSA опирается только на хеш-функции, а платить за это приходится подписями от 8 до 50 КБ и медленным подписанием.
Что сравниваетсяML-DSA (FIPS 204)SLH-DSA (FIPS 205)

Выбор между ML-DSA и SLH-DSA — главный выбор среди постквантовых подписей, которые стандартизировал NIST; оба стандарта опубликованы 13 августа 2024 года. ML-DSA (FIPS 204, происходит от CRYSTALS-Dilithium) опирается на структурированные решётки, а SLH-DSA (FIPS 205, происходит от SPHINCS+) — только на стойкость своей хеш-функции. Их размеры и скорость различаются настолько, что большинство систем будет использовать ML-DSA, а SLH-DSA — там, где её консервативные предположения о стойкости оправдывают затраты.

Коротко о главном

ML-DSA (FIPS 204)SLH-DSA (FIPS 205)
Основа стойкостиЗадачи на решётках Module-LWE и Module-SISТолько свойства SHA-2 или SHAKE
Наборы параметровML-DSA-44, -65, -8712 наборов: SHA2 или SHAKE × 128/192/256 × s (small, компактные) или f (fast, быстрые)
Категории стойкости2, 3, 51, 3, 5
Открытый ключ1 312 / 1 952 / 2 592 байта32 / 48 / 64 байта
Подпись2 420 / 3 309 / 4 627 байтот 7 856 (128s) до 49 856 байт (256f)
Закрытый ключ2 560–4 896 байт в развёрнутом виде или 32-байтный seed64 / 96 / 128 байт
Подписей в секунду (OpenSSL 3.6.5)около 3 900 (44), 2 400 (65), 2 050 (87)около 7 (SHA2-128s), 144 (SHA2-128f), 3,5 (SHA2-192s)
Проверок в секундуоколо 20 800 (44), 13 600 (65), 8 500 (87)около 7 400 (SHA2-128s), 2 400 (SHA2-128f)
Генераций ключей в секундуоколо 22 000 (44)около 55 (128s), 3 400 (128f)
Случайность при подписанииПо умолчанию хеджированное подписание, допускается детерминированный вариантПо умолчанию хеджированное подписание, допускается детерминированный вариант
Строка контекстаДо 255 байтДо 255 байт
Вариант с предварительным хешированиемHashML-DSA (§ 5.4)HashSLH-DSA (§ 10.2.2)
X.509RFC 9881 (id-ml-dsa-44 = 2.16.840.1.101.3.4.3.17 …)RFC 9909 (id-slh-dsa-sha2-128s = …3.4.3.20 …)

Скорость измерялась с помощью openssl speed на одном ядре Apple M4 Max; ML-DSA в OpenSSL написана на переносимом C, а оптимизированные реализации подписывают в несколько раз быстрее.

На чём основана стойкость

ML-DSA — схема подписи на основе решёток, построенная по принципу Фиата — Шамира с прерываниями (Fiat–Shamir with aborts). Её стойкость опирается на модульные варианты задачи обучения с ошибками (Module Learning With Errors) и задачи о коротком целочисленном решении (Module Short Integer Solution). Эти задачи изучают около двух десятилетий, и они выдержали как классические, так и квантовые атаки, но конкретные оценки их стойкости всё ещё меняются по мере того, как совершенствуются методы редукции решёток. NIST выбрал наборы параметров с запасом относительно этих оценок.

SLH-DSA строит подписи из одноразовых и малоразовых (few-time) подписей на основе хеш-функций, организованных в гипердерево. Пока SHA-256 или SHAKE256 сохраняют стойкость к нахождению прообраза и связанные с ней свойства, SLH-DSA остаётся стойкой: алгебраической структуры, которую можно было бы атаковать, у неё нет. Поэтому это самая консервативная подпись из стандартизированных NIST и естественная страховка на случай, если когда-нибудь произойдёт прорыв в атаках на решётки. В отличие от схем на основе хеш-функций с сохранением состояния LMS и XMSS, ей не нужно хранить состояние: каждый ключ может подписать до 2⁶⁴ сообщений.

Размеры и скорость на практике

Скрипт ниже подписывает одно и то же сообщение каждым из алгоритмов с помощью OpenSSL 3.6.5.

OpenSSL 3.6: размеры постквантовых и классических подписей
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
printf 'firmware-2026.10.bin digest' > msg
for alg in ML-DSA-44 ML-DSA-65 SLH-DSA-SHA2-128s SLH-DSA-SHA2-128f ED25519; do
  openssl genpkey -algorithm "$alg" -out key.pem 2>/dev/null
  openssl pkeyutl -sign -rawin -inkey key.pem -in msg -out sig.bin 2>/dev/null
  openssl pkey -in key.pem -pubout -outform DER -out pub.der 2>/dev/null
  openssl pkey -in key.pem -pubout -out pub.pem 2>/dev/null
  if openssl pkeyutl -verify -rawin -pubin -inkey pub.pem -in msg -sigfile sig.bin >/dev/null 2>&1; then ok=yes; else ok=no; fi
  printf '%-18s public key (SPKI DER) %5s bytes, signature %6s bytes, verifies: %s\n' "$alg" \
    "$(wc -c < pub.der | tr -d ' ')" "$(wc -c < sig.bin | tr -d ' ')" "$ok"
done
cd / && rm -rf "$dir"
Результат
ML-DSA-44          public key (SPKI DER)  1334 bytes, signature   2420 bytes, verifies: yes
ML-DSA-65          public key (SPKI DER)  1974 bytes, signature   3309 bytes, verifies: yes
SLH-DSA-SHA2-128s  public key (SPKI DER)    50 bytes, signature   7856 bytes, verifies: yes
SLH-DSA-SHA2-128f  public key (SPKI DER)    50 bytes, signature  17088 bytes, verifies: yes
ED25519            public key (SPKI DER)    44 bytes, signature     64 bytes, verifies: yes

Профили у схем зеркально противоположны. У ML-DSA открытые ключи и подписи занимают килобайты, а подписывает она тысячи раз в секунду. У SLH-DSA крошечные открытые ключи (такого же размера, как у Ed25519), но подписи от 8 до 50 КБ, а компактные наборы s тратят на одну подпись около 137 миллисекунд на этой машине (наборы f вдвое увеличивают размер подписи, зато подписывают примерно в 20 раз быстрее). Проверка у обеих схем быстрая. Для цепочки сертификатов или TLS-рукопожатия ML-DSA пригодна, а SLH-DSA нет; для образа прошивки, который подписывают один раз на релиз и проверяют при каждой загрузке, затраты SLH-DSA не имеют значения, а её крошечный открытый ключ помещается в загрузочное ПЗУ.

Детали применения

  • Хеджированное подписание. Оба стандарта по умолчанию смешивают свежие случайные данные со значениями, выведенными из ключа, и допускают детерминированный вариант для платформ без генератора случайных чисел; проверяющая сторона не может отличить один вариант от другого.
  • Контексты. Обе схемы включают в каждую подпись строку контекста длиной до 255 байт; протоколам следует использовать её, чтобы разделять назначения подписей.
  • Чистый вариант и вариант с предварительным хешированием. HashML-DSA и HashSLH-DSA подписывают дайджест, к которому привязан OID хеш-функции; это отдельные алгоритмы с отдельными OID, и FIPS 204 рекомендует использовать ключ только для одного из двух вариантов.
  • Форматы закрытых ключей. Ключи ML-DSA можно хранить в виде 32-байтного seed, что RFC 9881 допускает в кодировках seed и both; проблемы совместимости возникают, когда одна из сторон ожидает развёрнутый ключ.
  • Оборудование и валидация FIPS. Модули с ML-DSA и SLH-DSA, прошедшие валидацию, начали появляться в 2024 году; точные наборы параметров смотрите в сертификате модуля.

Что когда выбирать

  • Частная PKI, внутренний mTLS, подпись документов и кода: ML-DSA-65 (или 44).
  • Прошивки, безопасная загрузка, аппаратные корни доверия: SLH-DSA-128s или 192s либо схемы с сохранением состояния LMS и XMSS, которые CNSA 2.0 предписывает для этого случая, если вы можете управлять состоянием подписанта.
  • Долгосрочные архивы и корневые сертификаты, рассчитанные на десятилетия: SLH-DSA, возможно вместе с ML-DSA в виде двойной подписи.
  • Массовое подписание (токены, транзакции, журналы): ML-DSA; SLH-DSA не справится с такой нагрузкой.
  • Протоколы с ограниченной пропускной способностью: ни одна из схем не компактна; сегодня ML-DSA-44 — самый компактный из стандартизированных вариантов, а FN-DSA (проект FIPS 206) нацелена на ещё меньший размер.
  • Публичный TLS в WebPKI: сегодня браузеры не принимают ни одну из этих схем; о том, как идёт переход, читайте в статье ML-DSA или ECDSA.

Заметки о миграции

  1. Проведите инвентаризацию применений подписей по сроку жизни и объёму: долгоживущие и редко подписываемые артефакты — кандидаты на SLH-DSA, всё остальное — на ML-DSA.
  2. Выбирайте версии библиотек, которые реализуют окончательные стандарты: OpenSSL 3.5 и новее (апрель 2025 года), Bouncy Castle для Java 1.79 и новее (1.81 — для стандартизированной кодировки закрытого ключа), crypto/mldsa из Go 1.27 для ML-DSA. Выходные данные Dilithium и SPHINCS+ в версиях до стандартизации с ними несовместимы.
  3. Заложите запас по размеру: увеличьте ограничения для полей сертификатов, токенов и подписей; сертификаты ML-DSA-65 занимают около 5,5 КБ (см. соседнее сравнение), а подписи SLH-DSA могут превышать обычные ограничения на размер заголовков или записей.
  4. Рассмотрите гибриды на переходный период: составные сертификаты ML-DSA плюс ECDSA или EdDSA (проект IETF) или двойные подписи позволяют классическим проверяющим сторонам продолжать работу.
  5. Зафиксируйте строку контекста и вариант (чистый или с предварительным хешированием) в спецификации протокола, чтобы все реализации работали одинаково.

Источники

Все сравнения