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

  • Tutorial

Вы когда-нибудь задумывались, как работает Math.random()? Что такое случайное число и как оно получается? А представьте вопрос на собеседовании - напишите свой генератор случайных чисел в пару строк кода. И так, что же это такое, случайность и возможно ли ее предсказать?

Меня очень увлекают различные IT головоломки и задачки и генератор случайных чисел - одна из таких задачек. Обычно в своем телеграм канале я разбираю всякие головоломки и разные задачи с собеседований. Задача про генератор случайных чисел набрала большую популярность и мне захотелось увековечить ее в недрах одного из авторитетных источников информации - то бишь здесь, на Хабре.

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

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

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

Этот источник используется для накопления энтропии с последующим получением из неё начального значения (initial value, seed), которое необходимо генераторам случайных чисел (ГСЧ) для формирования случайных чисел.

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

Энтропия - это мера беспорядка. Информационная энтропия - мера неопределённости или непредсказуемости информации.
Выходит, что чтобы создать псевдослучайную последовательность нам нужен алгоритм, который будет генерить некоторую последовательность на основании определенной формулы. Но такую последовательность можно будет предсказать. Тем не менее, давайте пофантазируем, как бы могли написать свой генератор случайных чисел, если бы у нас не было Math.random()

ГПСЧ имеет некоторый алгоритм, который можно воспроизвести.
ГСЧ - это получение чисел полностью из какого либо шума, возможность просчитать который стремится к нулю. При этом в ГСЧ есть определенные алгоритмы для выравнивания распределения.

Придумываем свой алгоритм ГПСЧ

Генератор псевдослучайных чисел (ГПСЧ, англ. pseudorandom number generator, PRNG) - алгоритм, порождающий последовательность чисел, элементы которой почти независимы друг от друга и подчиняются заданному распределению (обычно равномерному).
Мы можем взять последовательность каких-то чисел и брать от них модуль числа. Самый простой пример, который приходит в голову. Нам нужно подумать, какую последовательность взять и модуль от чего. Если просто в лоб от 0 до N и модуль 2, то получится генератор 1 и 0:

Function* rand() { const n = 100; const mod = 2; let i = 0; while (true) { yield i % mod; if (i++ > n) i = 0; } } let i = 0; for (let x of rand()) { if (i++ > 100) break; console.log(x); }
Эта функция генерит нам последовательность 01010101010101… и назвать ее даже псевдослучайной никак нельзя. Чтобы генератор был случайным, он должен проходить тест на следующий бит. Но у нас не стоит такой задачи. Тем не менее даже без всяких тестов мы можем предсказать следующую последовательность, значит такой алгоритм в лоб не подходит, но мы в нужном направлении.

А что если взять какую-то известную, но нелинейную последовательность, например число PI. А в качестве значения для модуля будем брать не 2, а что-то другое. Можно даже подумать на тему меняющегося значения модуля. Последовательность цифр в числе Pi считается случайной. Генератор может работать, используя числа Пи, начиная с какой-то неизвестной точки. Пример такого алгоритма, с последовательностью на базе PI и с изменяемым модулем:

Const vector = [...Math.PI.toFixed(48).replace(".","")]; function* rand() { for (let i=3; i<1000; i++) { if (i > 99) i = 2; for (let n=0; n Но в JS число PI можно вывести только до 48 знака и не более. Поэтому предсказать такую последовательность все так же легко и каждый запуск такого генератора будет выдавать всегда одни и те же числа. Но наш генератор уже стал показывать числа от 0 до 9.

Мы получили генератор чисел от 0 до 9, но распределение очень неравномерное и каждый раз он будет генерировать одну и ту же последовательность.

Мы можем взять не число Pi, а время в числовом представлении и это число рассматривать как последовательность цифр, причем для того, чтобы каждый раз последовательность не повторялась, мы будем считывать ее с конца. Итого наш алгоритм нашего ГПСЧ будет выглядеть так:

Function* rand() { let newNumVector = () => [...(+new Date)+""].reverse(); let vector = newNumVector(); let i=2; while (true) { if (i++ > 99) i = 2; let n=-1; while (++n < vector.length) yield (vector[n] % i); vector = newNumVector(); } } // TEST: let i = 0; for (let x of rand()) { if (i++ > 100) break; console.log(x) }
Вот это уже похоже на генератор псевдослучайных чисел. И тот же Math.random() - это ГПСЧ, про него мы поговорим чуть позже. При этом у нас каждый раз первое число получается разным.

Собственно на этих простых примерах можно понять как работают более сложные генераторы случайных числе. И есть даже готовые алгоритмы. Для примера разберем один из них - это Линейный конгруэнтный ГПСЧ(LCPRNG).

Линейный конгруэнтный ГПСЧ

Линейный конгруэнтный ГПСЧ(LCPRNG) - это распространённый метод для генерации псевдослучайных чисел. Он не обладает криптографической стойкостью. Этот метод заключается в вычислении членов линейной рекуррентной последовательности по модулю некоторого натурального числа m, задаваемой формулой. Получаемая последовательность зависит от выбора стартового числа - т.е. seed. При разных значениях seed получаются различные последовательности случайных чисел. Пример реализации такого алгоритма на JavaScript:

Const a = 45; const c = 21; const m = 67; var seed = 2; const rand = () => seed = (a * seed + c) % m; for(let i=0; i<30; i++) console.log(rand())
Многие языки программирования используют LСPRNG (но не именно такой алгоритм(!)).

Как говорилось выше, такую последовательность можно предсказать. Так зачем нам ГПСЧ? Если говорить про безопасность, то ГПСЧ - это проблема. Если говорить про другие задачи, то эти свойства - могут сыграть в плюс. Например для различных спец эффектов и анимаций графики может понадобиться частый вызов random. И вот тут важны распределение значений и перформанс! Секурные алгоритмы не могут похвастать скоростью работы.

Еще одно свойство - воспроизводимость. Некоторые реализации позволяют задать seed, и это очень полезно, если последовательность должна повторяться. Воспроизведение нужно в тестах, например. И еще много других вещей существует, для которых не нужен безопасный ГСЧ.

Как устроен Math.random()

Метод Math.random() возвращает псевдослучайное число с плавающей запятой из диапазона = crypto.getRandomValues(new Uint8Array(1)); console.log(rvalue)
Но, в отличие от ГПСЧ Math.random(), этот метод очень ресурсоемкий. Дело в том, что данный генератор использует системные вызовы в ОС, чтобы получить доступ к источникам энтропии (мак адрес, цпу, температуре, etc…).

(англ.) русск. : «генерация случайных чисел слишком важна, чтобы оставлять её на волю случая ».

Энциклопедичный YouTube

    1 / 5

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

    ✪ Генератор псевдослучайных чисел | Криптография | Программирование (часть 8)

    ✪ Уроки C++ с нуля / Урок #5 - Генератор чисел + строки в C++

    ✪ rand. srand. rand задать диапазон. srand time null. Генератора случайных чисел. randomize. Урок #29.

    ✪ Случайные числа, линейный конгруэнтный метод - LNG (Linear Congruential Generator)

    Субтитры

    Когда мы наблюдаем за физическим миром, мы находим случайные отклонения везде. Мы можем генерировать настоящие случайные величины, измеряя случайные отклонения, называемые шумом. При измерении этого шума (выборке) можно получать числа. Например, если измерить электрический ток статики от телевизора в течении некоторого времени, то получится идеальная случайная последовательность. Можно визуализировать эту случайную последовательность, изобразив путь, направление которого изменяется в зависимости от каждого числа. Это называется случайным блужданием. Нужно отметить отсутствие шаблона любого масштаба в каждой точке последовательности -- следующий шаг всегда непредсказуем. Говорят, что случайные процессы недетерминированные, так как невозможно предсказать их развитие заранее. Машины, с другой стороны, детерминированные. Их операции предсказуемы и повторяемые. В 1946 году Джон фон Нейман был приглашен для проведения вычислений для военных. Особенно активно он участвовал при проектировании водородной бомбы. Используя компьютер ENIAC, он планировал повторяющиеся вычисления приближенных процессов, задействованных при ядерном синтезе. Как бы то ни было, это требовало быстрого доступа к случайно сгенерированным числам, которые возможно воспроизвести при необходимости. Однако, ENIAC имел очень ограниченную внутреннюю память, и хранить длинные случайные последовательности не представлялось возможным. Поэтому Нейман разработал алгоритм для механической симуляции перестановочного аспекта случайности таким образом: Сначала выбирается настоящее случайное число, называемое зерном. Это число можно получить при измерении шумов или взять текущее время в миллисекундах. Далее, выбранное зерно передается на вход для простых вычислений. Зерно умножается само на себя и на выход подаются средние цифры в результирующем числе. Затем, выход итерации передается в качестве зерна на вход для следующей. Этот процесс повторяется так долго, сколько нужно. Этот метод известен как метод серединных квадратов, и это только первый из большого набора генераторов псевдослучайных чисел известных сегодня. Случайность последовательности зависит только от случайности изначального зерна. Одно зерно -- одна последовательность. Итак, какая же разница между случайно сгенерированной и псевдослучайно сгенерированной последовательностями? Представим каждую последовательность в виде случайного блуждания. Они выглядят схожим образом до тех пор, пока мы не ускорим представление. Псевдослучайная последовательность в конечном счете повторяется. Это происходит, когда алгоритм доходит до зерна, которое уже было использовано ранее, и круг замыкается. Длина последовательности до повторения называется периодом. Период четко ограничен длиной изначального зерна. Например, для двузначного зерна алгоритм может породить последовательность длиной до 100 элементов, прежде чем вернется к использованному ранее зерну и начнет циклически повторяться. Трехзначное зерно позволяет растянуть период до 1000 чисел до начала повторений. Четырехзначное зерно расширяет последовательность до 10 000 чисел до начала повторений. Однако, если использовать достаточно большое зерно, можно получать последовательности из триллионов и триллионов элементов до начала повторений. Ключевым же отличием является то, что генерируя последовательность псевдослучайно, из нее исключаются очень многие подпоследовательности, которые просто не могут быть включены в нее. Например, если Алиса генерирует настоящую случайную последовательность из 20 элементов, это эквивалентно произвольной выборке из стопки всех возможных последовательностей этой длины. Эта стопка содержит 26 в степени 20 страниц, что является числом астрономического масштаба. Если встать внизу стопки и посветить фонариком вверх, то человек, стоящий на вершине стопки, не увидит этого света примерно 200 миллионов лет. Сравним это с генерацией 20-элементной псевдослучайной последовательности с использованием 4-значного зерна. Это эквивалентно произвольной выборке из 10 000 возможных начальных зерен. То есть можно сгенерировать лишь 10 000 различных последовательностей, что является исчезающе малой частью всех возможных вариантов последовательностей. Меняя случайные смещения на псевдослучайные, мы сужаем пространство ключей до намного меньшего пространства зерен. Для того, чтобы псевдослучайная последовательность была неотличима от случайно сгенерированной последовательности, нужно, чтобы при помощи компьютера было невозможно перебрать все зерна для нахождения совпадения. Это приводит нас к важному отличию в компьютерной науке между тем, что возможно и тем, что возможно в разумные сроки. Мы применяем ту же логику, когда покупаем замок для велосипеда. Мы знаем, что кто угодно может просто перебрать все возможные комбинации, чтобы найти ту, которая подойдет и откроет замок. Но это займет несколько дней. Поэтому мы предполагаем, что на 8 часов он практически защищен. При использовании генераторов псевдослучайных чисел безопасность возрастает с повышением длины зерна. Самый мощный компьютер будет перебирать все возможные зерна на протяжении многих лет, поэтому мы может спокойно предполагать практическую безопасность вместо идеальной безопасности. При увеличении скорости вычислений длина зерна должна пропорционально увеличиваться. Псевдослучайность освобождает Алису и Боба от необходимости обмениваться полной случайной последовательностью смещений заранее. Вместо этого они обмениваются относительно небольшим случайным зерном и растягивают его в одинаковые подобные случайным последовательности, которые требуются. Но что случится, если они никогда не встретятся для обмена этим случайным зерном.

Источники случайных чисел

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

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

Генератор псевдослучайных чисел включён в состав многих современных процессоров , например, RdRand входит в набор инструкций IA-32.

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

Детерминированные ГПСЧ

Из современных ГПСЧ широкое распространение также получил «вихрь Мерсенна », предложенный в 1997 году Мацумото и Нисимурой. Его достоинствами являются колоссальный период (2 19937 −1), равномерное распределение в 623 измерениях (линейный конгруэнтный метод даёт более или менее равномерное распределение максимум в 5 измерениях), быстрая генерация случайных чисел (в 2-3 раза быстрее, чем стандартные ГПСЧ, использующие линейный конгруэнтный метод). Однако существуют алгоритмы, распознающие последовательность, порождаемую вихрем Мерсенна, как неслучайную.

ГПСЧ с источником энтропии или ГСЧ

Наравне с существующей необходимостью генерировать легко воспроизводимые последовательности случайных чисел, также существует необходимость генерировать совершенно непредсказуемые или попросту абсолютно случайные числа. Такие генераторы называются генераторами случайных чисел (ГСЧ - англ. random number generator, RNG ). Так как такие генераторы чаще всего применяются для генерации уникальных симметричных и асимметричных ключей для шифрования, они чаще всего строятся из комбинации криптостойкого ГПСЧ и внешнего источника энтропии (и именно такую комбинацию теперь и принято понимать под ГСЧ).

Почти все крупные производители микрочипов поставляют аппаратные ГСЧ с различными источниками энтропии, используя различные методы для их очистки от неизбежной предсказуемости. Однако на данный момент скорость сбора случайных чисел всеми существующими микрочипами (несколько тысяч бит в секунду) не соответствует быстродействию современных процессоров.

В современных исследованиях осуществляются попытки использования измерения физических свойств объектов (например, температуры) или даже квантовых флуктуаций вакуума в качестве источника энтропии для ГСЧ.

В персональных компьютерах авторы программных ГСЧ используют гораздо более быстрые источники энтропии, такие, как шум звуковой карты или счётчик тактов процессора . Сбор энтропии являлся наиболее уязвимым местом ГСЧ. Эта проблема до сих пор полностью не разрешена во многих устройствах (например, смарт-картах), которые таким образом остаются уязвимыми. Многие ГСЧ используют традиционные испытанные, хотя и медленные, методы сбора энтропии вроде измерения реакции пользователя (движение мыши и т. п.), как, например, в PGP и Yarrow , или взаимодействия между потоками , как, например, в Java SecureRandom.

Пример простейшего ГСЧ с источником энтропии

Если в качестве источника энтропии использовать текущее время, то для получения целого числа от 0 до N достаточно вычислить остаток от деления текущего времени в миллисекундах на число N +1. Недостатком этого ГСЧ является то, что в течение одной миллисекунды он выдает одно и то же число.

Примеры ГСЧ и источников энтропии

ГПСЧ Достоинства Недостатки
/dev/random в UNIX /Linux Счётчик тактов процессора, однако собирается только во время аппаратных прерываний LFSR , с хешированием выхода через SHA-1 Есть во всех Unix, надёжный источник энтропии Очень долго «нагревается», может надолго «застревать», либо работает как ГПСЧ (/dev/urandom )
Yarrow от Брюса Шнайера Традиционные методы AES -256 и SHA-1 маленького внутреннего состояния Гибкий криптостойкий дизайн Медленный
Microsoft CryptoAPI Текущее время, размер жёсткого диска, размер свободной памяти, номер процесса и NETBIOS-имя компьютера MD5 -хеш внутреннего состояния размером в 128 бит Встроен в Windows, не «застревает» Сильно зависит от используемого криптопровайдера (CSP).
Java SecureRandom Взаимодействие между потоками SHA-1 -хеш внутреннего состояния (1024 бит) Большое внутреннее состояние Медленный сбор энтропии
Chaos от Ruptor Счётчик тактов процессора, собирается непрерывно Хеширование 4096-битового внутреннего состояния на основе нелинейного варианта Marsaglia -генератора Пока самый быстрый из всех, большое внутреннее состояние, не «застревает» Оригинальная разработка, свойства приведены только по утверждению автора
RRAND от Ruptor Счётчик тактов процессора Зашифровывание внутреннего состояния поточным шифром EnRUPT в authenticated encryption режиме (aeRUPT) Очень быстр, внутреннее состояние произвольного размера по выбору, не «застревает» Оригинальная разработка, свойства приведены только по утверждению автора. Шифр EnRUPT не является криптостойким.
RdRand от intel Шумы токов Построение ПСЧ на основе "случайного" битового считывания значений от токов Очень быстр, не «застревает» Оригинальная разработка, свойства приведены только по утверждению статьи из habrahabr - уточнить.
ГПСЧ Stratosphera от ORION Счетчик тактов процессора, собирается непрерывно (также используется соль в виде случайно выбранного целого числа) Построение ПСЧ на основе алгоритма от Intel с многоразовой инициализацией и сдвигом Достаточно быстр, не «застревает», проходит все тесты DIEHARD Оригинальная разработка, свойства приведены только исходя из информации на сайте oriondevteam.com - (уточнение от 23-10-2013).

ГПСЧ в криптографии

Разновидностью ГПСЧ являются ГПСБ (PRBG) - генераторы псевдо-случайных бит, а также различных поточных шифров . ГПСЧ, как и поточные шифры, состоят из внутреннего состояния (обычно размером от 16 бит до нескольких мегабайт), функции инициализации внутреннего состояния ключом или зерном (англ. seed ), функции обновления внутреннего состояния и функции вывода. ГПСЧ подразделяются на простые арифметические, сломанные криптографические и криптостойкие . Их общее предназначение - генерация последовательностей чисел, которые невозможно отличить от случайных вычислительными методами.

Хотя многие криптостойкие ГПСЧ или поточные шифры предлагают гораздо более «случайные» числа, такие генераторы гораздо медленнее обычных арифметических и могут быть непригодны во всякого рода исследованиях, требующих, чтобы процессор был свободен для более полезных вычислений.

В военных целях и в полевых условиях применяются только засекреченные синхронные криптостойкие ГПСЧ (поточные шифры), блочные шифры не используются. Примерами известных криптостойких ГПСЧ являются RC4 , ISAAC , SEAL , Snow , совсем медленный теоретический алгоритм Блюм - Блюма - Шуба , а также счётчики с криптографическими хеш-функциями или криптостойкими блочными шифрами вместо функции вывода.

Примеры криптостойких ГПСЧ

Циклическое шифрование

В данном случае используется способ генерации ключа сессии из мастер-ключа. Счетчик с периодом N используется в качестве входа в шифрующее устройство. Например, в случае использования 56-битного ключа DES может использоваться счетчик с периодом 256. После каждого созданного ключа значение счетчика повышается на 1. Таким образом, псевдослучайная последовательность, полученная по данной схеме, имеет полный период: каждое выходное значение Х0, Х1,…XN-1 основано на разных значениях счетчика, поэтому Х0 ≠ X1 ≠ XN-1. Так как мастер-ключ является секретным, легко показать, что любой секретный ключ не зависит от знания одного или более предыдущих секретных ключей.

ANSI X9.17

ГПСЧ из стандарта ANSI X9.17 используется во многих приложениях финансовой безопасности и PGP . В основе этого ГПСЧ лежит тройной DES . Генератор ANSI X9.17 состоит из следующих частей:

  1. Вход: генератором управляют два псевдослучайных входа. Один является 64-битным представлением текущих даты и времени, которые меняются каждый раз при создании числа. Другой является 64-битным исходным значением. Оно инициализируется некоторым произвольным значением и изменяется в ходе генерации последовательности псевдослучайных чисел.
  2. Ключи: генератор использует три модуля тройного DES. Все три используют одну и ту же пару 56-битных ключей, которая держится в секрете и применяется только при генерации псевдослучайного числа.
  3. Выход: выход состоит из 64-битного псевдослучайного числа и 64-битного значения, которое будет использоваться в качестве начального значения при создании следующего числа.
  • DTi - значение даты и времени на начало i-ой стадии генерации.
  • Vi - начальное значение для i-ой стадии генерации.
  • Ri - псевдослучайное число, созданное на i-ой стадии генерации.
  • K1, K2 - ключи, используемые на каждой стадии.

1 Ri = EDEK1,K2 [ EDEK1,K2 [ DTi] Vi ] 2 Vi+1 = EDEK1,K2 [ EDEK1,K2 [ DTi] Ri]

Схема включает использование 112-битного ключа и трех EDE-шифрований. На вход даются два псевдослучайных значения: значение даты и времени и начальное значение текущей итерации, на выходе получаются начальное значение для следующей итерации и очередное псевдослучайное значение. Даже если псевдослучайное число Ri будет скомпрометировано, вычислить Vi+1 из Ri не является возможным за разумное время, и, следовательно, следующее псевдослучайное значение Ri+1, так как для получения Vi+1 дополнительно выполняются три операции EDE.

Аппаратные ГПСЧ

Кроме устаревших, хорошо известных LFSR-генераторов, широко применявшихся в качестве аппаратных ГПСЧ в XX веке, к сожалению, очень мало известно о современных аппаратных ГПСЧ (поточных шифрах), так как большинство из них разработано для военных целей и держатся в секрете. Почти все существующие коммерческие аппаратные ГПСЧ запатентованы или держатся в секрете . Аппаратные ГПСЧ ограничены строгими требованиями к расходуемой памяти (чаще всего использование памяти запрещено), быстродействию (1-2 такта) и площади (несколько сотен FPGA - или ASIC -ячеек). Из-за таких строгих требований к аппаратным ГПСЧ очень трудно создать криптостойкий генератор, поэтому до сих пор все известные аппаратные ГПСЧ были взломаны. Примерами таких генераторов являются Toyocrypt и LILI-128, которые оба являются LFSR-генераторами, и оба были взломаны с помощью алгебраических атак.

Из-за недостатка хороших аппаратных ГПСЧ производители вынуждены применять имеющиеся под рукой гораздо более медленные, но широко известные блочные шифры (DES , AES) и хеш-функции (SHA-1) в поточных режимах.

Детерминированные ГПСЧ

ГПСЧ (PRNG) это генераторы псевдо-случайных чисел. Этот же термин часто используется для описания ГПСБ (PRBG) - генераторов псевдо-случайных бит, а так же различных поточных шифров. ГПСЧ как и поточные шифры состоят из внутреннего состояния (размером от 16 бит до нескольких мегабайт), функции инициализации внутреннего состояния ключом или семенами, функции обновления внутреннего состояния и функции вывода. ГПСЧ подразделяются на простые арифметические, сломанные криптографические и криптостойкие. Их общее предназначение - генерация последовательностей чисел, которые невозможно отличить от случайных.

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

Любой ГПСЧ с ограниченными ресурсами рано или поздно зацикливается. Длина циклов ГПСЧ зависит от самого генератора и в среднем составляет около 2 (n/2) где n это размер внутреннего состояния в битах, хотя линейные-конгруэнтные генераторы и РЛСО (LFSR) генераторы обладают максимальными циклами порядка 2 n . Если ГПСЧ может сходиться к слишком коротким циклам, такой ГПСЧ становится предсказуемым и является непригодным.

Большинство простых арифметических генераторов хотя и обладают большой скоростью, но страдают от многих серьёзных недостатков:

  • Слишком короткий период/периоды
  • Последовательные значения не являются независимыми
  • Некоторые биты «менее случайны», чем другие
  • Неравномерное одномерное распределение
  • Обратимость

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

ГПСЧ с источником энтропии или ГСЧ

Наравне с существующей необходимостью генерировать легко воспроизводимые последовательности случайных чисел, также существует необходимость генерировать совершенно непредсказуемые или попросту абсолютно случайные числа. Такие генераторы называются «генераторами случайных чисел» («random number generator» ) или сокращённо ГСЧ (RNG). Так как такие генераторы чаще всего применяются для генерации уникальных симметричных и асимметричных ключей для шифрования, они чаще всего строятся из комбинации криптостойкого ГПСЧ и внешнего источника . Таким образом, под ГСЧ теперь принято подразумевать именно криптостойкие ГПСЧ с внешним источником энтропии.

Почти все крупные производители микрочипов поставляют аппаратные ГСЧ с различными источниками энтропии, используя различные методы для их очистки от неизбежных предсказуемостей. Однако на данный момент скорость сбора случайных чисел всеми существующими микрочипами (несколько тысяч бит в секунду) не соответствует быстродействию современных процессоров.

В персональных компьютерах авторы программных ГСЧ используют гораздо более быстрые источники энтропии, такие как шум звуковой карты или значения (processor clock counter) которые легко считываются, например, при помощи инструкции в процессорах Intel. До появления в процессорах возможности считывать значение самого чувствительного к малейшим изменениям окружающей среды счётчика тактов процессора, сбор энтропии являлся наиболее уязвимым местом ГСЧ. Эта проблема до сих пор полностью не разрешена во многих устройствах (например smart-карты), которые таким образом остаются уязвимыми. Многие ГСЧ до сих пор используют традиционные (устаревшие) методы сбора энтропии такие как действия пользователя (движения мыши и т. п.), как например в и Yarrow , или взаимодействие между нитями (threads), как например в Java secure random.

Вот несколько примеров ГСЧ с их источниками энтропии и генераторами:

  • /dev/random в / - источник энтропии: , однако собирается только во время аппаратных прерываний; ГПСЧ: LFSR, с хэшированием выхода через ; достоинства: есть во всех Unix-ах, надёжный источник энтропии; недостатки: очень долго «нагревается», может надолго «застревать», либо работает как ГПСЧ (/dev/urandom );
  • Yarrow от - источник энтропии: традиционные (устаревшие) методы; ГПСЧ: AES-256 и маленького внутреннего состояния; достоинства: гибкий криптостойкий дизайн; недостатки - долго «нагревается», очень маленькое внутреннее состояние, слишком сильно зависит от криптостойкости выбранных алгоритмов, медленный, применим исключительно для генерации ключей;
  • генератор от Леонида Юрьева (Leo Yuriev) - источник энтропии: шум звуковой карты; ГПСЧ: пока не известен; достоинства: скорее всего хороший и быстрый источник энтропии; недостатки - нет независимого, заведомо криптостойкого ГПСЧ, доступен исключительно в виде DLL под Windows;
  • Microsoft CryptoAPI - источник энтропии: текущее время, размер hard drive, размер свободной памяти, id процесса и NETBIOS имя компьютера; ГПСЧ: хэш внутреннего состояния размером в 128 бит (хэш присутствует только в 128-битовых версиях Windows); достоинства - встроен в Windows, не «застревает»; недостатки - маленькое внутреннее состояние, легко предсказуем;
  • Java SecureRandom - источник энтропии: взаимодействие между нитями (threads); ГПСЧ: хэш внутреннего состояния (1024 бит); достоинства - в Java другого выбора пока нет, большое внутреннее состояние; недостатки: медленный сбор энтропии, хотя в Java другого выбора пока всё равно нет;
  • Chaos от Ruptor - источник энтропии: , собирается непрерывно; ГПСЧ: хэширование 4096-битового внутреннего состояния на основе нелинейного варианта Marsaglia генератора; достоинства: пока самый быстрый из всех, большое внутреннее состояние, не «застревает».

Аппаратные ГПСЧ

Кроме устаревших хорошо известных LFSR генераторов широко применявшихся в качестве аппаратных ГПСЧ в прошлом веке к сожалению очень мало известно о современных аппаратных ГПСЧ (поточных шифрах), так как большинство из них разработано для военных целей и держатся в секрете. Почти все существующие коммерческие аппаратные ГПСЧ запатентованы и так же держатся в секрете. Аппаратные ГПСЧ ограничены строгими требованиями к расходуемой памяти (чаще всего использование памяти запрещено), быстродействию (1-2 такта) и площади (несколько сотен FPGA или ASIC ячеек). Из-за таких строгих требований к аппаратным ГПСЧ очень трудно создать криптостойкий генератор, по этому до сих пор все известные аппаратные ГПСЧ были сломаны. Примерами таких генераторов являются Toyocrypt и LILI-128, которые оба являются LFSR генераторами и оба были сломаны с помощью алгебраических атак.

Из-за недостатка хороших аппаратных ГПСЧ производители вынуждены применять имеющиеся под рукой гораздо более медленные, но широко известные блочные шифры как и AES и хэш функции такие как

алгоритм генерации псевдослучайных чисел, называемый алгоритмом BBS (от фамилий авторов - L. Blum, M. Blum, M. Shub) или генератором с квадратичным остатком . Для целей криптографии этот метод предложен в 1986 году.

Он заключается в следующем. Вначале выбираются два больших простых 1 Целое положительное число большее единицы называется простым , если оно не делится ни на какое другое число, кроме самого себя и единицы. Подробнее о простых числах см. в "Основные положения теории чисел, используемые в криптографии с открытым ключом" . числа p и q . Числа p и q должны быть оба сравнимы с 3 по модулю 4, то есть при делении p и q на 4 должен получаться одинаковый остаток 3. Далее вычисляется число M = p* q , называемое целым числом Блюма. Затем выбирается другое случайное целое число х , взаимно простое (то есть не имеющее общих делителей, кроме единицы) с М . Вычисляем х0= х 2 mod M . х 0 называется стартовым числом генератора.

На каждом n-м шаге работы генератора вычисляется х n+1 = х n 2 mod M . Результатом n-го шага является один (обычно младший) бит числа х n+1 . Иногда в качестве результата принимают бит чётности, то есть количество единиц в двоичном представлении элемента. Если количество единиц в записи числа четное – бит четности принимается равным 0 , нечетное – бит четности принимается равным 1 .

Например , пусть p = 11, q = 19 (убеждаемся, что 11 mod 4 = 3, 19 mod 4 = 3 ). Тогда M = p* q = 11*19=209 . Выберем х , взаимно простое с М : пусть х = 3 . Вычислим стартовое число генератора х 0 :

х 0 = х 2 mod M = 3 2 mod 209 = 9 mod 209 = 9.

Вычислим первые десять чисел х i по алгоритму BBS . В качестве случайных бит будем брать младший бит в двоичной записи числа х i :

х 1 =9 2 mod 209= 81 mod 209= 81 младший бит: 1
х 2 =81 2 mod 209= 6561 mod 209= 82 младший бит: 0
х 3 =82 2 mod 209= 6724 mod 209= 36 младший бит: 0
х 4 =36 2 mod 209= 1296 mod 209= 42 младший бит: 0
х 5 =42 2 mod 209= 1764 mod 209= 92 младший бит: 0
х 6 =92 2 mod 209= 8464 mod 209= 104 младший бит: 0
х 7 =104 2 mod 209= 10816 mod 209= 157 младший бит: 1
х 8 =157 2 mod 209= 24649 mod 209= 196 младший бит: 0
х 9 =196 2 mod 209= 38416 mod 209= 169 младший бит: 1
х 10 =169 2 mod 209= 28561 mod 209= 137 младший бит: 1

Самым интересным для практических целей свойством этого метода является то, что для получения n-го числа последовательности не нужно вычислять все предыдущие n чисел х i . Оказывается х n можно сразу получить по формуле

Например, вычислим х 10 сразу из х 0 :


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

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

Безопасность алгоритма BBS основана на сложности разложения большого числа М на множители. Утверждается, что если М достаточно велико, его можно даже не держать в секрете; до тех пор, пока М не разложено на множители, никто не сможет предсказать выход генератора ПСЧ. Это связано с тем, что задача разложения чисел вида n = pq (р и q - простые числа) на множители является вычислительно очень трудной, если мы знаем только n , а р и q - большие числа, состоящие из нескольких десятков или сотен бит (это так называемая задача факторизации ).

Кроме того, можно доказать, что злоумышленник , зная некоторую последовательность, сгенерированную генератором BBS , не сможет определить ни предыдущие до нее биты, ни следующие. Генератор BBS непредсказуем в левом направлении и в правом направлении . Это свойство очень полезно для целей криптографии и оно также связано с особенностями разложения числа М на множители.

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

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

Ключевые термины

Stream cipher – поточный шифр .

Алгоритм BBS – один из методов генерации псевдослучайных чисел. Название алгоритма происходит от фамилий авторов - L. Blum, M. Blum, M. Shub. Алгоритм может использоваться в криптографии. Для вычислений очередного числа x n+1 по алгоритму BBS используется формула х n+1 = х n 2 mod M , где M = pq является произведением двух больших простых p и q .

Генератор псевдослучайных чисел (ГПСЧ) – некоторый алгоритм или устройство, которые создают последовательность битов, внешне похожую на случайную.

Линейный конгруэнтный генератор псевдослучайных чисел – один из простейших ГПСЧ, который для вычисления очередного числа k i использует формулу k i =(a*k i-1 +b)mod c , где а, b, с - некоторые константы , a k i-1 - предыдущее псевдослучайное число .

Метод Фибоначчи с запаздываниями – один из методов генерации псевдослучайных чисел. Может использоваться в криптографии.

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

Краткие итоги

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