Проверка соответствия стандартным тест-векторам NIST

Проверка криптографических примитивов на соответствие стандартным тест-векторам NIST является обязательным этапом валидации любой реализации, включая Stanford JavaScript Crypto Library. Тест-векторы представляют собой заранее известные входные данные и ожидаемые выходные результаты для конкретных алгоритмов, что позволяет выявлять ошибки в реализации на уровне битовой совместимости.

В контексте SJCL ключевая сложность заключается в том, что библиотека использует собственное представление данных через bitArray, а не стандартные JS-строки или Uint8Array. Это требует аккуратной адаптации тестов, предоставляемых NIST, к внутреннему формату библиотеки.


Особенности представления данных в SJCL

Перед тем как переходить к тест-векторам, необходимо учитывать ключевую архитектурную особенность:

  • SJCL оперирует типом sjcl.bitArray
  • Один элемент массива представляет 32-битное слово
  • Старшие биты хранятся первыми (big-endian логика внутри слова)
  • Большинство входных данных из NIST представлено в hex или byte-строках

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


Подготовка NIST тест-векторов для SJCL

Обычно NIST предоставляет тесты в формате:

  • HEX ключи
  • HEX plaintext/ciphertext
  • HEX IV
  • ожидаемый HEX результат

Для использования в SJCL требуется преобразование:

var keyBits = sjcl.codec.hex.toBits("000102030405060708090a0b0c0d0e0f");
var dataBits = sjcl.codec.hex.toBits("00112233445566778899aabbccddeeff");

После этого результаты также сравниваются через hex:

var resultHex = sjcl.codec.hex.fromBits(resultBits);

Проверка AES на тест-векторах NIST

AES-128 ECB (Known Answer Test)

Типичный NIST-вектор:

  • Key: 000102030405060708090a0b0c0d0e0f
  • Plaintext: 00112233445566778899aabbccddeeff
  • Ciphertext: 69c4e0d86a7b0430d8cdb78070b4c55a

Реализация проверки в SJCL

var aes = new sjcl.cipher.aes(sjcl.codec.hex.toBits("000102030405060708090a0b0c0d0e0f"));

var pt = sjcl.codec.hex.toBits("00112233445566778899aabbccddeeff");
var ct = aes.encrypt(pt);

var ctHex = sjcl.codec.hex.fromBits(ct);

Сравнение:

ctHex === "69c4e0d86a7b0430d8cdb78070b4c55a";

AES-CBC тестирование с NIST векторами

Для CBC режима дополнительно используется IV:

  • IV: 000102030405060708090a0b0c0d0e0f
var aes = new sjcl.cipher.aes(keyBits);

var cipher = sjcl.mode.cbc.encrypt(aes, ptBits, ivBits);

Особенность проверки CBC:

  • важно учитывать паддинг (если используется PKCS#5/7)
  • SJCL не всегда автоматически применяет padding, поэтому тесты NIST должны быть адаптированы

AES-CTR и потоковые тесты

CTR режим наиболее чувствителен к ошибкам счётчика.

var aes = new sjcl.cipher.aes(keyBits);

var ctr = new sjcl.mode.ctr(aes, ivBits, 128);
var out = ctr.encrypt(ptBits);

NIST тест-векторы для CTR обычно проверяют:

  • корректность генерации keystream
  • отсутствие смещения битов в счётчике
  • соответствие побайтовой последовательности

SHA-256 и тест-векторы NIST

Пример базового теста SHA-256

Вход:

  • пустая строка

Ожидаемый результат:

e3b0c44298fc1c149afbf4c8996fb924...

Проверка в SJCL

var hash = sjcl.hash.sha256.hash("");
var hex = sjcl.codec.hex.fromBits(hash);

Тестирование промежуточных сообщений

NIST SHA-256 test suite включает:

  • “abc”
  • длинные повторяющиеся строки
  • инкрементальные данные

Пример:

sjcl.codec.hex.fromBits(
  sjcl.hash.sha256.hash("abc")
);

Ожидаемое значение:

ba7816bf8f01cfea414140de5dae2223...

HMAC-SHA256 тестирование

NIST предоставляет HMAC тест-векторы с разными ключами:

var hmac = new sjcl.misc.hmac(keyBits, sjcl.hash.sha256);
var result = hmac.encrypt(messageBits);

Проверяются:

  • корректность обработки ключей > block size
  • корректность inner/outer padding (ipad/opad)
  • совпадение digest с эталоном

PBKDF2 и NIST-like проверки

Хотя PBKDF2 не всегда входит в классические NIST KAT наборы для всех конфигураций, он широко используется в валидации.

sjcl.misc.pbkdf2(password, salt, iterations, keyLength);

Ключевые параметры проверки:

  • корректная работа итераций
  • стабильность результата при повторном запуске
  • совпадение derived key с эталонным значением

Типичные ошибки при сравнении с NIST векторами

1. Ошибки преобразования bitArray

Наиболее частая проблема:

  • неправильная интерпретация байтов
  • потеря ведущих нулей

2. Неверная работа с IV

Особенно критично для CBC и CTR:

  • IV должен быть той же длины, что и block size (128 бит для AES)

3. Несовпадение encoding

NIST использует:

  • raw bytes
  • hex

SJCL требует явного преобразования через codec


4. Padding discrepancies

AES-CBC тесты могут не совпадать из-за:

  • отсутствия padding в реализации
  • различий PKCS7 vs PKCS5 интерпретации

Автоматизация тестирования NIST векторов

Для крупных наборов тестов удобно строить runner:

function runTest(vector) {
  var key = sjcl.codec.hex.toBits(vector.key);
  var pt  = sjcl.codec.hex.toBits(vector.pt);

  var aes = new sjcl.cipher.aes(key);
  var ct = aes.encrypt(pt);

  var out = sjcl.codec.hex.fromBits(ct);

  return out === vector.ct;
}

Структура набора тестов

Обычно NIST набор организован как:

  • key
  • plaintext
  • ciphertext
  • IV (optional)
  • mode
  • algorithm version

Для SJCL удобно преобразовать в JSON:

{
  "key": "...",
  "pt": "...",
  "ct": "...",
  "iv": "...",
  "mode": "CBC"
}

Контроль корректности реализации через cross-check

Дополнительный уровень проверки:

  • сравнение с OpenSSL
  • сравнение с WebCrypto API
  • сравнение с эталонными C-реализациями NIST

Несовпадение только с SJCL обычно указывает на ошибку в адаптации bitArray, а не в алгоритме.


Особенности интерпретации NIST спецификаций

Некоторые тонкости:

  • NIST описывает операции на уровне байтов
  • SJCL оперирует 32-битными словами
  • требуется аккуратная работа с выравниванием

Это критично при:

  • SHA padding
  • AES key expansion
  • HMAC block processing

Практика построения regression suite

В реальных проектах проверка NIST-векторов интегрируется как:

  • unit tests (QUnit, Mocha)
  • CI pipeline
  • nightly crypto regression tests

Каждый алгоритм имеет собственный набор:

  • aes_ecb_kat.json
  • aes_cbc_kat.json
  • sha256_kat.json
  • hmac_kat.json

Интерпретация расхождений

Если результат не совпадает:

  1. Проверяется преобразование входных данных
  2. Проверяется порядок битов
  3. Проверяется режим шифрования
  4. Проверяется соответствие NIST спецификации версии

Даже один неверный байт в IV или ключе приводит к полностью отличающемуся выходу, что характерно для криптографических примитивов.