Как настроить смартфоны и ПК. Информационный портал

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

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

ГПСЧ (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 и хэш функции такие как

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

Последовательность случайных чисел {X n } получается с помощью следующего итерационного равенства:

X n +1 = (a X n + c) mod m

Если m, а и с являются целыми, то создается последовательность целых чисел в диапазоне 0 X n < m.

Выбор значений для а, с и m является критичным для разработки хорошего генератора случайных чисел.

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

Существует три критерия, используемые при выборе генератора случайных чисел:

1. Функция должна создавать полный период, т.е. все числа между 0 и m до того, как создаваемые числа начнут повторяться.

2. Создаваемая последовательность должна появляться случайно. Последовательность не является случайной, так как она создается детерминированно, но различные статистические тесты, которые могут применяться, должны показывать, что последовательность случайна.

3. Функция должна эффективно реализовываться на 32-битных процессорах.

Значения а, с и m должны быть выбраны таким образом, чтобы эти три критерия выполнялись. В соответствии с первым критерием можно показать, что если m является простым и с = 0, то при определенном значении а период, создаваемый функцией, будет равен m-1. Для 32-битной арифметики соответствующее простое значение m = 2 31 - 1. Таким образом, функция создания псевдослучайных чисел имеет вид:

X n +1 = (a X n) mod (2 31 - 1)

Только небольшое число значений а удовлетворяет всем трем критериям. Одно из таких значений есть а = 7 5 = 16807, которое использовалось в семействе компьютеров IBM 360. Этот генератор широко применяется и прошел более тысячи тестов, больше, чем все другие генераторы псевдослучайных чисел.

Сила алгоритма линейного конгруента в том, что если сомножитель и модуль (основание) соответствующим образом подобраны, то результирующая последовательность чисел будет статистически неотличима от последовательности, являющейся случайной из набора 1, 2, ..., m-1. Но не может быть случайности в последовательности, полученной с использованием алгоритма, независимо от выбора начального значения Х 0 . Если значение выбрано, то оставшиеся числа в последовательности будут предопределены. Это всегда учитывается при криптоанализе.



Если противник знает, что используется алгоритм линейного конгруента, и если известны его параметры (а = 7 5 , с = 0, m = 2 31 - 1), то, если раскрыто одно число, вся последовательность чисел становится известна. Даже если противник знает только, что используется алгоритм линейного конгруента, знания небольшой части последовательности достаточно для определения параметров алгоритма и всех последующих чисел. Предположим, что противник может определить значения Х 0 , Х 1 , Х 2 , Х 3 . Тогда:

Х 1 = (а Х 0 + с) mod mХ 2 = (а Х 1 + с) mod mХ 3 = (а Х 2 + с) mod m

Эти равенства позволяют найти а, с и m.

Таким образом, хотя алгоритм и является хорошим генератором псевдослучайной последовательности чисел, желательно, чтобы реально используемая последовательность была непредсказуемой, поскольку в этом случае знание части последовательности не позволит определить будущие ее элементы. Эта цель может быть достигнута несколькими способами. Например, использование внутренних системных часов для модификации потока случайных чисел. Один из способов применения часов состоит в перезапуске последовательности после N чисел, используя текущее значение часов по модулю m в качестве нового начального значения. Другой способ состоит в простом добавлении значения текущего времени к каждому случайному числу по модулю m.

алгоритм генерации псевдослучайных чисел, называемый алгоритмом 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 - предыдущее псевдослучайное число .

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

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

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

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

В компьютерных программах нередко требуется эмуляция случайности. Например, при разработке игр. Если в программе имеется некий генератор, т. е. производитель, случайного числа, то, используя полученное таким образом число, можно выбирать ту или иную ветку выполнения программы, или произвольный объект из коллекции. Другими словами, главное – сгенерировать число. Эмуляция случайности иного рода основывается на нем.

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

"Зерно" – это исходные данные для формулы. Им может быть, например, системное время в миллисекундах, которое постоянно меняется. Следовательно, "зерно" будет постоянно разным. Или программист может задавать его самостоятельно.

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

В этом уроке будут рассмотрены функции random(), randrange() и randint() из модуля random. Обратите внимание, что модуль random содержит одноименную функцию random(). Так бывает.

Чтобы обращаться к функциям, надо импортировать модуль random:

>>> import random

Или импортировать отдельные функции из него:

>>> from random import random , randrange, randint

Функции для получения целых "случайных" чисел – randint() и randrange()

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

>>> random .randint (0 , 10 ) 6

или (если импортировались отдельные функции):

>>> randint(100 , 200 ) 110

В случае randint() обе границы включаются в диапазон, т. е. на языке математики отрезок описывается как .

Числа могут быть отрицательными:

>>> random .randint (-100 , 10 ) -83 >>> random .randint (-100 , -10 ) -38

Но первое число всегда должно быть меньше или, по-крайней мере, равно второму. То есть a <= b.

Функция randrange() сложнее. Она может принимать один аргумент, два или даже три. Если указан только один, то она возвращает случайное число от 0 до указанного аргумента. Причем сам аргумент в диапазон не входит. На языке математики – это }

Лучшие статьи по теме