Генератор псевдослучайных чисел и его инициализация

В библиотеке SJCL (Stanford JavaScript Crypto Library) генератор псевдослучайных чисел построен вокруг объекта sjcl.random, который реализует криптографически стойкий PRNG с накоплением энтропии из различных источников среды выполнения JavaScript. Основная идея заключается не в прямом использовании детерминированного алгоритма, а в постоянном сборе случайности из событий системы и её последующем преобразовании в ключевой материал через хэш-функции.

Базовый объект sjcl.random

Центральный элемент генерации случайных чисел — глобальный экземпляр:

sjcl.random

Он представляет собой состояние генератора, включающее:

  • пул энтропии
  • внутренний PRNG (основанный на AES-CTR)
  • очередь источников энтропии
  • статус готовности генератора

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


Энтропийная модель

Источники энтропии

Энтропия поступает из событий браузера и окружения:

  • движения мыши
  • нажатия клавиш
  • события сенсора (на мобильных устройствах)
  • временные метки
  • особенности окружения (например, тайминги выполнения)

Каждое событие преобразуется в числовое представление и добавляется в общий пул.

sjcl.random.addEventListener("mousemove");
sjcl.random.addEventListener("keypress");

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


Добавление энтропии вручную

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

sjcl.random.addEntropy(data, bits, source)

Параметры:

  • data — исходные данные (число, массив или строка)
  • bits — оценка количества энтропии
  • source — идентификатор источника

Пример:

sjcl.random.addEntropy([123456, 987654], 32, "custom-source");

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


Пул энтропии

Внутренне используется структура пула, в которую складываются данные от разных источников. Эти данные затем смешиваются через хэш-функции (обычно SHA-256 или SHA-512 в зависимости от конфигурации).

Пул не является прямым источником случайных чисел. Он лишь накопитель состояния, которое затем «переплавляется» в ключевой материал.


Состояние готовности генератора

Генератор SJCL не считается готовым сразу после загрузки. Его состояние определяется уровнем накопленной энтропии:

sjcl.random.isReady()

Возвращаемые значения:

  • 0 — недостаточно энтропии
  • 1 — частично готов (можно использовать с ограничениями)
  • 2 — полностью готов

Дополнительно можно получить уровень:

sjcl.random.getProgress()

Он возвращает число от 0 до 1, отражающее относительный прогресс накопления энтропии.


Инициализация генератора

Автоматическая инициализация

При загрузке SJCL автоматически подключает стандартные источники энтропии (если включены соответствующие модули). В браузере это обычно:

  • mousemove
  • keydown
  • touchstart
  • device orientation

После накопления минимального объёма данных PRNG переключается в рабочий режим.


Ручная инициализация состояния

В некоторых сценариях требуется форсированная инициализация:

sjcl.random.startCollectors()

Этот метод активирует сборщики энтропии.

Также можно завершить сбор:

sjcl.random.stopCollectors()

Это полезно в средах, где события не предполагаются (например, серверные окружения).


Генерация псевдослучайных чисел

Основной метод

sjcl.random.randomWords(n, paranoia)
  • n — количество 32-битных слов
  • paranoia — уровень требуемой уверенности

Пример:

var words = sjcl.random.randomWords(4);

Результат — массив из 32-битных чисел.


Уровень паранойи

Параметр paranoia определяет, сколько энтропии требуется:

  • 0 — минимальные требования
  • 10 — максимальная криптографическая строгость

Если энтропии недостаточно, вызов может блокироваться до её накопления.


Внутренний PRNG: AES-CTR

После накопления энтропии SJCL преобразует её в ключ AES, который используется в режиме CTR (Counter Mode).

Схема:

  1. Энтропийный пул хэшируется
  2. Получается 256-битный ключ
  3. AES используется как генератор псевдослучайного потока
  4. Счётчик увеличивается на каждом блоке

Это обеспечивает:

  • детерминированность при одинаковом состоянии
  • криптостойкость при достаточной энтропии
  • невозможность предсказания выходных значений

Перемешивание энтропии

Каждое добавление данных в пул приводит к ре-микшированию:

  • данные хэшируются
  • объединяются с текущим состоянием
  • применяется повторное хэширование

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


Сброс состояния генератора

Возможен полный сброс:

sjcl.random.reset()

При этом:

  • очищается пул энтропии
  • сбрасывается PRNG
  • удаляются временные состояния

После сброса генератор снова требует накопления энтропии.


Проблемы и ограничения модели

Недостаток энтропии в серверных средах

Node.js или headless-среды не предоставляют естественных источников событий. В этом случае:

  • генератор может оставаться в состоянии isReady() === 0
  • требуется внешняя инициализация

Псевдослучайность до полной готовности

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


Зависимость от поведения пользователя

В браузерных условиях качество случайности напрямую связано с активностью пользователя. Без взаимодействия с интерфейсом накопление энтропии замедляется или останавливается.


Использование в криптографических операциях

Генератор SJCL применяется в:

  • генерации ключей AES
  • создании nonce и IV
  • формировании соли для PBKDF2
  • криптографических токенах

Пример генерации соли:

var salt = sjcl.random.randomWords(4);

Связь с PBKDF2 и ключевой деривацией

PRNG часто используется как источник начальной соли:

var salt = sjcl.random.randomWords(2);
var key = sjcl.misc.pbkdf2(password, salt, 10000, 256);

Здесь качество случайности напрямую влияет на стойкость всей схемы.


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

Типичный контроль состояния:

if (sjcl.random.isReady() < 2) {
    // ожидание накопления энтропии
}

или с прогрессом:

console.log(sjcl.random.getProgress());

Архитектурная роль PRNG в SJCL

Генератор случайных чисел в SJCL не является вспомогательным модулем. Он выполняет фундаментальную роль:

  • начальный источник ключевого материала
  • основа всех симметричных операций
  • механизм защиты от предсказуемости криптографических параметров

Его безопасность определяет устойчивость всей криптосистемы библиотеки.