Влияние длины ключа на скорость

Криптографическая стойкость алгоритмов симметричного шифрования напрямую связана с длиной ключа, однако влияние этого параметра на производительность часто оказывается менее интуитивным, чем принято считать. В контексте Stanford JavaScript Crypto Library (SJCL) ключевой вопрос заключается в том, как увеличение длины ключа AES с 128 до 192 и 256 бит отражается на скорости операций шифрования и расшифрования.

SJCL реализует AES как блочный шифр с фиксированным размером блока 128 бит, независимо от длины ключа. Поддерживаются три основных варианта:

  • AES-128 (128-битный ключ)
  • AES-192 (192-битный ключ)
  • AES-256 (256-битный ключ)

Важно понимать, что размер блока остаётся неизменным, а различие затрагивает исключительно процедуру расширения ключа (key schedule) и количество раундов шифрования.

  • AES-128 использует 10 раундов
  • AES-192 использует 12 раундов
  • AES-256 использует 14 раундов

Именно число раундов является ключевым фактором, влияющим на производительность.

Ключевое расширение и его стоимость

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

Увеличение длины ключа приводит к следующим изменениям:

  • увеличивается объём предварительных вычислений
  • растёт количество операций XOR, сдвигов и подстановок
  • возрастает размер таблицы раундовых ключей

Пример создания AES-контекста в SJCL:

import sjcl from 'sjcl';

const key128 = sjcl.codec.hex.toBits('00112233445566778899aabbccddeeff');
const key256 = sjcl.codec.hex.toBits('00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff');

const aes128 = new sjcl.cipher.aes(key128);
const aes256 = new sjcl.cipher.aes(key256);

На этапе new sjcl.cipher.aes(...) происходит основная разница в стоимости между вариантами.

Сравнение стоимости ключевого расписания

С точки зрения вычислительной сложности:

  • AES-128: минимальная нагрузка на key schedule
  • AES-192: умеренное увеличение затрат
  • AES-256: заметно более тяжёлый key schedule

Однако важно учитывать, что key schedule выполняется один раз при инициализации объекта шифра. При многократном шифровании данных одним и тем же ключом эта стоимость становится пренебрежимой.

Основная нагрузка: раундовые преобразования

После инициализации ключа основная работа приходится на сами раунды AES. Каждый раунд включает:

  • SubBytes (нелинейная замена байтов)
  • ShiftRows (циклические сдвиги)
  • MixColumns (линейное смешивание)
  • AddRoundKey (XOR с раундовым ключом)

Количество раундов напрямую зависит от длины ключа, поэтому влияние на производительность проявляется линейно.

Если обозначить стоимость одного раунда как T, то:

  • AES-128 ≈ 10T
  • AES-192 ≈ 12T
  • AES-256 ≈ 14T

Разница между AES-128 и AES-256 составляет примерно 40% по количеству раундовых операций, что теоретически должно отражаться на скорости.

Особенности реализации SJCL в JavaScript

SJCL оптимизирован под JavaScript-окружение и использует следующие подходы:

  • битовые массивы (bitArray) вместо сырых байтов
  • заранее вычисленные S-box таблицы
  • минимизацию аллокаций в горячих циклах

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

Причины сглаживания различий:

  • операции над массивами битов оптимизированы движком JS
  • доступ к памяти и кэширование играют большую роль, чем арифметика
  • AES-раунды доминируют над стоимостью key schedule

Практическое влияние на throughput

При массовом шифровании данных (например, потоковые операции) наблюдается следующая картина:

  • AES-128 обеспечивает максимальную пропускную способность
  • AES-192 снижает скорость умеренно
  • AES-256 даёт заметное, но не критическое падение производительности

Разница чаще всего находится в диапазоне:

  • 5–15% между AES-128 и AES-192
  • 10–25% между AES-128 и AES-256

Эти значения зависят от:

  • JavaScript-движка (V8, SpiderMonkey, JavaScriptCore)
  • объёма данных
  • режима работы (CBC, CTR, GCM-подобные реализации поверх SJCL)

Режимы шифрования и влияние ключа

В SJCL часто используются режимы:

  • CBC (Cipher Block Chaining)
  • CTR (Counter Mode)

CTR обычно быстрее CBC, потому что:

  • не требует цепочки зависимостей между блоками
  • лучше параллелизуется

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

Пример измерения производительности

const plaintext = sjcl.codec.utf8String.toBits("A".repeat(1024));

function benchmark(cipher, iterations = 1000) {
    const start = performance.now();
    for (let i = 0; i < iterations; i++) {
        cipher.encrypt(plaintext);
    }
    return performance.now() - start;
}

const aes128 = new sjcl.cipher.aes(key128);
const aes256 = new sjcl.cipher.aes(key256);

console.log(benchmark(aes128));
console.log(benchmark(aes256));

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

Баланс безопасности и производительности

Увеличение длины ключа даёт экспоненциальный рост стойкости к перебору, но линейное ухудшение производительности.

Ключевые соотношения:

  • 128 бит: достаточен для большинства прикладных задач
  • 192 бит: компромиссный уровень для повышенной устойчивости
  • 256 бит: максимальный уровень стойкости в AES-стандарте

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

Низкоуровневые эффекты в JS-движках

На практике производительность дополнительно зависит от:

  • оптимизации циклов в JIT-компиляторе
  • работы с 32-битными операциями
  • эффективности кэширования массивов
  • инлайнинга функций SJCL

Иногда AES-256 может выполняться почти так же быстро, как AES-128, если движок хорошо оптимизирует циклы раундов, однако это скорее исключение, чем правило.

Итоговая техническая картина

Увеличение длины ключа в SJCL влияет на производительность по двум направлениям:

  • стоимость инициализации (key schedule)
  • количество раундов шифрования

Первый фактор важен при редком создании объектов шифра, второй — при массовой обработке данных и является определяющим.

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