Как компьютер генерирует случайное число
Как компьютер генерирует случайные числа
Что такое случайность в компьютере? Как происходит генерация случайных чисел? В этой статье мы постарались дать простые ответы на эти вопросы.
В программном обеспечении, да и в технике в целом существует необходимость в воспроизводимой случайности: числа и картинки, которые кажутся случайными, на самом деле сгенерированы определённым алгоритмом. Это называется псевдослучайностью, и мы рассмотрим простые способы создания псевдослучайных чисел. В конце статьи мы сформулируем простую теорему для создания этих, казалось бы, случайных чисел.
Определение того, что именно является случайностью, может быть довольно сложной задачей. Существуют тесты (например, колмогоровская сложность), которые могут дать вам точное значение того, насколько случайна та или иная последовательность. Но мы не будем заморачиваться, а просто попробуем создать последовательность чисел, которые будут казаться несвязанными между собой.
Часто требуется не просто одно число, а несколько случайных чисел, генерируюемых непрерывно. Следовательно, учитывая начальное значение, нам нужно создать другие случайные числа. Это начальное значение называется семенем, и позже мы увидим, как его получить. А пока давайте сконцентрируемся на создании других случайных значений.
Создание случайных чисел из семени
Один из подходов может заключаться в том, чтобы применить какую-то безумную математическую формулу к семени, а затем исказить её настолько, что число на выходе будет казаться непредсказуемым, а после взять его как семя для следующей итерации. Вопрос только в том, как должна выглядеть эта функция искажения.
Давайте поэкспериментируем с этой идеей и посмотрим, куда она нас приведёт.
Функция искажения будет принимать одно значение, а возвращать другое. Назовём её R.
Числовой круг
Посмотрим на циферблат часов: наш ряд начинается с 1 и идёт по кругу до 12. Но поскольку мы работаем с компьютером, пусть вместо 12 будет 0.
Теперь начиная с 1 снова будем прибавлять 7. Прогресс! Мы видим, что после 12 наш ряд начинает повторяться, независимо от того, с какого числа начать.
Здесь мы получаем очень важно свойство: если наш цикл состоит из n элементов, то максимальное число элементов, которые мы можем получить перед тем, как они начнут повторяться это n.
Теперь давайте переделаем функцию R так, чтобы она соответствовала нашей логике. Ограничить длину цикла можно с помощью оператора модуля или оператора остатка от деления.
Если вы попробуете несколько разных значений, то сможете увидеть одно свойство: m и с должны быть взаимно простыми.
До сих пор мы делали «прыжки» за счёт добавления, но что если использовать умножение? Умножим х на константу a.
Свойства, которым должно подчиняться а, чтобы образовался полный цикл, немного более специфичны. Чтобы создать верный цикл:
Эти свойства вместе с правилом, что m и с должны быть взаимно простыми составляют теорему Халла-Добелла. Мы не будем рассматривать её доказательство, но если бы вы взяли кучу разных значений для разных констант, то могли бы прийти к тому же выводу.
Выбор семени
Настало время поговорить о самом интересном: выборе первоначального семени. Мы могли бы сделать его константой. Это может пригодиться в тех случаях, когда вам нужны случайные числа, но при этом нужно, чтобы при каждом запуске программы они были одинаковые. Например, создание одинаковой карты для каждой игры.
Конечный результат
Когда мы применяем функцию к её результату несколько раз, мы получаем рекуррентное соотношение. Давайте запишем нашу формулу с использованием рекурсии:
То, что мы сделали, называется линейным конгруэнтным методом. Он очень часто используется, потому что он прост в реализации и вычисления выполняются быстро.
В разных языках программирования реализация линейного конгруэнтного метода отличается, то есть меняются значения констант. Например, функция случайных чисел в libc (стандартная библиотека С для Linux) использует m = 2 ^ 32, a = 1664525 и c = 1013904223. Такие компиляторы, как gcc, обычно используют эти значения.
Заключительные замечания
Существуют и другие алгоритмы генерации случайных чисел, но линейный конгруэнтный метод считается классическим и лёгким для понимания. Если вы хотите глубже изучить данную тему, то обратите внимание на книгу Random Numbers Generators, в которой приведены элегантные доказательства линейного конгруэнтного метода.
Генерация случайных чисел имеет множество приложений в области информатики и особенно важна для криптографии.
Генерировать случайные числа гораздо сложнее, чем вы думаете
Что общего у любителей проходить видеоигры на скорость, азартных игроков и криптографов? Они зависят от случайных чисел. От перетасовки музыки до шифрования интернета, случайные числа — важнейшая часть современной жизни. И мы, как правило, полагаемся на компьютеры, которые генерируют их.
На первый взгляд, создание случайных чисел может показаться простым. В конце концов, числа на компьютере — это набор единиц и нулей. Компьютеру просто нужно случайным образом выбрать 1 или 0 и повторить это столько раз, сколько необходимо.
Человеку не составит труда сделать это:
Примечание: ведутся споры о том, может ли человек демонстрировать по-настоящему случайное поведение. Но это выходит за рамки данной статьи.
Тем не менее, все еще остается вопрос: как компьютер случайно выбирает между нулем и единицей? Ответ оказывается довольно сложным. Он коренится в таких темах, как рекурсивные алгоритмы, компьютерное оборудование и немного — теория хаоса.
Если это звучит для вас интересно, тогда погрузимся глубже.
Как компьютеры генерируют случайные числа?
Простой ответ на этот вопрос заключается в том, что они не могут. По крайней мере, не сами по себе.
Люди создали компьютеры, чтобы они были тем, чем не являемся мы, — полностью логическими машинами. Случайность не в их природе. В конце концов, вы же не хотите, чтобы сервер спонтанно решил не следовать логике приложения.
По своей сути компьютеры — простые машины, которые принимают данные и выдают их обратно. Чтобы компьютеры могли генерировать случайные числа, им нужен внешний источник случайности. И этот источник будет варьироваться в зависимости от того, каким генератором случайных чисел вы решите воспользоваться.
Вероятно, последнее предложение вызвало несколько растерянных взглядов. Что подразумевается под “своего рода генератором случайных чисел”? Разве они не все одинаковы?
Не совсем. Существует два основных типа генераторов случайных чисел.
Примечание: далее названия генераторов случайных чисел будут использоваться в сокращении.
Генератор псевдослучайных чисел (ГПСЧ)
Наиболее распространенный тип — генератор псевдослучайных чисел. Он называется псевдослучайным, потому что не создает “по-настоящему” случайных чисел.
“ГПСЧ — это алгоритмы, которые могут автоматически создавать длинные ряды чисел с хорошими случайными свойствами, но в конечном итоге последовательность повторяется”.
Несмотря на то, что ГПСЧ следуют определенной схеме, эта схема не прослеживается людьми. Поэтому они “достаточно хороши” для большинства случаев, к примеру для видеоигр.
Генераторам псевдослучайных чисел для работы необходимы две составляющие:
Первоначально в качестве алгоритмов ГПСЧ применялись линейные конгруэнтные генераторы. Это рекурсивные алгоритмы, которые генерируют следующую величину на основе предыдущей. Вот почему этим алгоритмам требуется “семя” (seed) или начальное значение. О семени можно думать как о фрагменте случайности.
Однако со временем на смену линейным конгруэнтным генераторам пришел вихрь Мерсенна, и он по сей день остается самым популярным алгоритмом ГПСЧ.
Хотя псевдослучайные числа на самом деле не случайные, есть множество причин ими пользоваться. Во-первых, они быстры и дешевы в создании. Кроме того, поскольку ГПСЧ — всего лишь алгоритмы, их можно протестировать и убедиться, что они всегда будут работать правильно.
Вот почему в большинстве, если не во всех, языках программирования случайные числа по умолчанию генерируются именно через ГПСЧ.
Но у генерации псевдослучайных чисел есть и свои недостатки. ГСПЧ работают, потому что случайны для неподготовленного глаза. Однако, если бы вы знали начальное значение для определенной последовательности ГПСЧ, то могли бы предсказать, какие числа будут следующими.
Этой уязвимостью часто пользуются любители ускоренного прохождения видеоигр — они называют это манипулированием ГСЧ. Они заставляют игру работать предсказуемо, чтобы пройти ее как можно быстрее. К счастью, если семя видеоигры будет скомпрометировано, ничего особенного не случится. В этом нет ни вреда, ни зла.
Но бывают случаи, когда предсказание случайных чисел имеет гораздо большее значение. Например, создание ключей безопасности.
Если злоумышленник выяснит исходное значение, используемое для создания ключей RSA в сертификатах TLS, он потенциально может расшифровать сетевой трафик. Это означает, что он сможет получать пароли и другую личную информацию, передаваемую через интернет.
В таких ситуациях нужен более безопасный способ получения случайных чисел.
Генератор истинно случайных чисел (ГИСЧ)
Как вы можете догадаться, истинно случайные числа непредсказуемы и не следуют шаблону.
Но как компьютер может достичь этого? Как было указано ранее, компьютерам требуется внешний источник случайности. В случае ГПСЧ, это было семя. В случае ГИСЧ, это энтропия.
Теория хаоса и термодинамика выходят далеко за рамки данной статьи. Достаточно сказать, что энтропия — это чистый нефильтрованный хаос. И лучший источник этого хаоса — сам компьютер.
Компьютер не может функционировать случайным образом, но составляющие его части — могут. Компьютер — это сложная система со множеством движущихся частей и изменчивостью. Тепловой шум, фотоэффект и другие квантовые явления происходят постоянно.
Компьютерное оборудование — не единственный источник энтропии. Также можно использовать движения мыши и клавиатуры пользователя.
Но хаос был бы бесполезен, если бы его нельзя было обуздать. К счастью, инженеры-аппаратчики придумали, как это сделать. Посредством сложной схемы аппаратных микросхем и компонентов, компьютеры могут преобразовывать этот физический шум в цифровые нули и единицы.
Примерная схема генератора истинно случайных чисел
Один из наиболее очевидных вариантов применения ГИСЧ — цифровые азартные игры. Бросание костей, перетасовка карт и вращение колеса рулетки — все это зависит от того, чтобы быть неопределимым. Хотя он часто используется при опросах общественного мнения, призыве на военную службу и отборе присяжных, а также там, где случайность используется как метод справедливости.
В действительности сферы применения ГИСЧ довольно ограничены, поскольку у них есть свой набор недостатков. Во-первых, они медлительны. Хотя это варьируется, ГИСЧ может выдавать только небольшое количество бит в секунду.
Кроме того, ГИСЧ не всегда надежны. Компьютерам требуется достаточное количество энтропии для производства истинно случайных чисел. Но суть случайности в том, что она возникает случайным образом. Простаивающий или новый сервер не сможет генерировать числа настолько же качественно, как активный.
Эта ненадежность создает угрозу безопасности при использовании ГИСЧ для создания криптографических ключей. В 2012 году в исследовательской работе под названием Ron was Wrong, Whit is Right обнаружилось, что тысячи SSL-ключей небезопасны. Хотя основная причина неизвестна, обычно считается, что это результат ошибочной генерации случайных чисел.
Криптографически стойкий генератор псевдослучайных чисел (КСГПЧ)
Из-за недостатков ГИСЧ и ГПСЧ криптографы разработали гибридный подход, называемый криптографически защищенной генерацией псевдослучайных чисел. Этот метод направлен на обеспечение скорости ГПСЧ с гарантией безопасности ГИСЧ.
КСГПЧ прост в теории. В нем применяется высококачественный источник энтропии для получения начального значения, которое дальше вводится в алгоритм, а тот затем выдает безопасные случайные числа.
Проще говоря, он задействует ГИСЧ при создании начального значения для ГПСЧ. Если все сделано правильно, КСГПЧ гарантирует, что начальное значение действительно случайное, и ГПСЧ не может быть скомпрометирован или изменен.
Пример этому — /dev/random в системах Unix и Linux.
Несмотря на преимущества КСГПЧ, здесь, как и везде в технологической отрасли, нельзя гарантировать полную безопасность.
Завершающие мысли
Многие разработчики программного обеспечения не понимают сложности, связанной с генерацией случайных чисел. Это свидетельствует в пользу архитекторов, которые создали существующую систему. От инженеров-аппаратчиков, которые разрабатывали чипы для преобразования шума в данные, до разработчиков ядра и языков программирования, которые преобразовали эти данные в простые для использования API.
Возможно, в следующий раз, когда вы будете играть в видеоигру, слушать музыку в случайном порядке или просто генерировать произвольное число у себя в коде, вы лучше станете понимать волшебство, которое происходит под капотом.
Как компьютеры выбирают случайные числа – псевдослучайные числа
Компьютеры могут генерировать поистине случайные числа, наблюдая за некоторыми внешними данными, такими как движения мыши или шум вентилятора, который не предсказуем и создают данные из него. Это называется энтропией. В других случаях они генерируют «псевдослучайные» числа, используя алгоритм, поэтому результаты кажутся случайными, хотя таковыми не являются.
Эта тема становится всё более спорной в последнее время, и вызывает сомнение у большого количества людей. Чтобы понять, почему это может быть ненадежным, вам нужно понять, как используются случайные числа и для чего они нужны.
Как используют случайные числа
Случайные числа использовались в течение многих тысяч лет. Независимо от того, подкидывали ли монету или бросали кости, цель заключалась в том, чтобы получить случайный результат. Генераторы случайных чисел на компьютерах похожи – они пытаются достичь непредсказуемого случайного результата.
Генераторы случайных чисел полезны для разных целей. Помимо очевидных приложений, таких как генерация случайных чисел для азартных игр или создания непредсказуемых результатов в компьютерной игре, случайность важна для криптографии.
Криптография требует использования чисел, о которых не смогут догадаться третьи лица. Мы не можем просто использовать одни и те же числа снова и снова. Мы хотим генерировать эти цифры очень непредсказуемым образом, чтобы злоумышленники не могли их угадать. Эти случайные числа необходимы для безопасного шифрования, независимо от того, шифруете ли вы свои собственные файлы или подключаетесь к веб-сайту по HTTPS.
Истинные случайные числа
Возможно, вам интересно, как компьютер может генерировать случайное число. Откуда возникает эта «случайность». Если это всего лишь фрагмент компьютерного кода, возможно ли, что числа, которые генерирует компьютер, могут быть непредсказуемыми?
Обычно мы группируем случайные числа, создаваемые компьютером, в два типа, в зависимости от того, как они генерируются: «истинные» случайные числа и псевдослучайные числа.
Для генерации «истинного» случайного числа компьютер измеряет некоторый тип физического явления, которое происходит за пределами компьютера. Например, компьютер может измерять радиоактивный распад атома. Согласно квантовой теории, нет никакого способа точно знать, когда произойдет радиоактивный распад, так что это «чистая случайность». Злоумышленник не сможет предсказать, когда произойдет радиоактивный распад, поэтому они не будут знать случайное значение.
В бытовом случае компьютер может опираться на атмосферный шум или просто использовать точное время нажатия клавиш на клавиатуре в качестве источника непредсказуемых данных или энтропии. Например, ваш компьютер может заметить, что вы нажали клавишу ровно в 0,23423523 секунды после 2 часов дня. Это достаточный источник энтропии, который можно использовать для создания «истинного» случайного числа. Вы не предсказуемая машина, поэтому злоумышленник не сможет угадать точный момент, когда вы нажимаете эти клавиши.
Псевдослучайные числа
Псевдослучайные числа являются альтернативой «истинным» случайным числам. Компьютер может использовать начальное значение и алгоритм для генерации чисел, которые кажутся случайными, но которые, на самом деле, предсказуемы. Компьютер не собирает никаких случайных данных из среды.
Это не обязательно плохо. Например, если вы играете в видеоигру, не имеет значения, связаны ли события, происходящие в этой игре, с «истинными» случайными числами или псевдослучайными числами. С другой стороны, если вы используете шифрование, вряд ли Вам захочется использовать псевдослучайные числа, которые может угадать злоумышленник.
Например, злоумышленник знает алгоритм и начальное значение, которое использует генератор псевдослучайных чисел. Предположим, что алгоритм шифрования получает псевдослучайное число из этого алгоритма и использует его для генерации ключа шифрования без добавления дополнительной случайности. Если злоумышленник знает достаточно, он сможет «повернуть процесс вспять» и определять псевдослучайное число, вмешавшись в шифрование.
NSA и аппаратный генератор случайных чисел Intel
Чтобы упростить работу разработчиков и помочь генерировать безопасные случайные числа, чипы Intel включают аппаратный генератор случайных чисел, известный как RdRand. Этот чип использует источник энтропии на процессоре и предоставляет случайные числа для программного обеспечения, когда программное обеспечение запрашивает их.
Проблема здесь в том, что генератор случайных чисел – это, по сути, «черный ящик», и мы не знаем, что происходит внутри него. Если RdRand содержит бэкдор NSA, правительство сможет получить ключи шифрования, которые были сгенерированы с данными, предоставленными этим генератором случайных чисел.
Случайности не случайны, Или как компьютеры генерируют случайные числа
Генератор случайных чисел — это намного сложнее, чем кажется.
Как думаете, что общего в компьютерных гонках, азартных играх и криптографии? На первый взгляд кажется, что ничего. Но на самом деле все они зависят от случайных чисел. От прослушивания музыки до шифрования всего Интернета — случайные числа являются важной частью жизни современного человека. И чаще всего мы полагаемся на компьютеры, которые генерируют их для нас.
Это заставляет задуматься: а как именно компьютеры генерируют случайные числа?
Если вы занимались программированием, то наверняка использовали в своем коде генератор случайных чисел. Для этого в Ruby достаточно вызвать «rand», а в Python — «random ()». Создание ряда случайных чисел может показаться простым. В конце концов числа на компьютере — это набор единиц и нулей. Машине просто нужно случайным образом выбрать 1 или 0 и повторить это столько раз, сколько нужно. Даже мы, люди, можем сделать это легко и просто на листе бумаги.
Однако если копнуть глубже, то мы создали компьютеры, чтобы стать теми, кем не являемся — полностью логическими устройствами. Получается, случайность противоречит их природе. Ну кто захочет, чтобы сервер спонтанно решил не следовать логике приложения?
По своей сути компьютеры — это простые машины, которые принимают данные и выводят их обратно. И чтобы эти машины могли генерировать случайные числа, им нужен внешний источник случайности. Этот источник будет зависеть от того, какой генератор случайных чисел вы захотите использовать. Таких генераторов два — конечно, если говорить об основных.
Первый и самый распространенный тип называется «генератор псевдослучайных чисел (ГПСЧ)». Как следует из названия, он не создает «истинных» случайных чисел. Чтобы сгенерировать с помощью него число, понадобится единственное начальное значение, откуда последует псевдослучайность. Алгоритмы генерации, используемые для ГПСЧ, включают в себя «метод извлечения квадратов», «линейный конгруэнтный метод», «регистр сдвига с линейной обратной связью» и «вихрь Мерсенна».
ГПСЧ автоматически создает длинные серии чисел с хорошими случайными свойствами и делает это быстро и дешево — в этом его преимущества. Но есть и очевидный минус: с ограниченными ресурсами любой ГПСЧ рано или поздно зацикливается и начинает повторять одну и ту же последовательность чисел. Однако чаще всего этот шаблон не воспринимается людьми, что делает ГПСЧ подходящим для использования в видеоиграх и программировании.
Нельзя не сказать о том, что слабым местом ГПСЧ все-таки пользуются: например, любители гонок, которые манипулируют ГСЧ и заставляют игру работать предсказуемо, чтобы пройти ее как можно скорее. Есть случаи, когда предсказание случайных чисел имеет более серьезные последствия. Зная начальное значение, злоумышленник может угадать сгенерированный пароль и получить доступ к личным данным пользователя.
Второй тип генератора — генератор «истинно» случайных чисел (ГИСЧ или TRNG). В качестве внешнего источника случайности он использует энтропию. Не углубляясь в теорию хаоса и термодинамику, отметим, что энтропия — это чистый нефильтрованный хаос. И лучший источник этого хаоса — сам компьютер. Компьютер не может работать случайным образом, чего не скажешь о его составляющих.
Компьютер — это сложная система со множеством движущихся частей и непостоянством, где регулярно возникают тепловой шум, фотоэффект и другие квантовые явления. В конце концов инженеры по аппаратному обеспечению выяснили, что, используя сложную схему аппаратных микросхем и компонентов, компьютеры могут преобразовывать физический шум в цифровые единицы и нули.
Чаще всего ГИСЧ используют в цифровых азартных играх: бросание костей, тасование карт, рулетка — все это завязано на неопределенности. А еще в общественных вопросах, военных призывах и выборе присяжных, где случайность выступает в качестве метода справедливости.
Однако на самом деле спектр использования ГИСЧ тоже ограничен, ведь у него есть свои недостатки. Во-первых, для генерации чисел требуется много времени. А еще ГИСЧ не всегда надежны. Компьютерам требуется достаточное количество энтропии для создания истинных случайных чисел, но случайность заключается в том, что она возникает… случайно! Неактивный или новый сервер не сможет создавать номера такого же высокого качества, как активный.
Поскольку и ГПСЧ, и ГИСЧ имеют свои недостатки, их можно без проблем использовать в гейм-сфере и азартных играх, но нельзя — в криптографии, которая требует высокой безопасности. По этой причине появился гибридный тип — «криптографически стойкий генератор псевдослучайных чисел (КСГПЧ или CSPRNG)», который обладает скоростью ГПСЧ и безопасностью ГИСЧ.
КСГПЧ — это генератор, использующий высококачественный источник энтропии для создания начального числа. Затем оно вводится в алгоритм, который производит случайные и безопасные числа. Проще говоря, он использует ГИСЧ для создания начального числа для ГПСЧ. Если все сделано правильно, КСГПЧ гарантирует, что начальное число действительно случайно, а полученный результат нельзя взломать или реконструировать. Обычно его используют в операционных системах вроде Unix и Linux.
Тем не менее, даже несмотря на преимущества КСГПЧ, как и всего остального в технологической индустрии, абсолютная безопасность недостижима.
Теперь, когда в следующий раз вы будете играть в видеоигру, слушать музыку в случайном порядке или просто генерировать случайное число в своем коде, вы осознаете всю магию, которая творится «под капотом».
Подробно о генераторах случайных и псевдослучайных чисел
Введение
Как отличить случайную последовательность чисел от неслучайной?
Чуть более сложный пример или число Пи
Последовательность цифры в числе Пи считается случайной. Пусть генератор основывается на выводе бит представления числа Пи, начиная с какой-то неизвестной точки. Такой генератор, возможно и пройдет «тест на следующий бит», так как ПИ, видимо, является случайной последовательностью. Однако этот подход не является критографически надежным — если криптоаналитик определит, какой бит числа Пи используется в данный момент, он сможет вычислить и все предшествующие и последующие биты.
Данный пример накладывает ещё одно ограничение на генераторы случайных чисел. Криптоаналитик не должен иметь возможности предсказать работу генератора случайных чисел.
Отличие генератора псевдослучайных чисел (ГПСЧ) от генератора случайных чисел (ГСЧ)
Источники энтропии используются для накопления энтропии с последующим получением из неё начального значения (initial value, seed), необходимого генераторам случайных чисел (ГСЧ) для формирования случайных чисел. ГПСЧ использует единственное начальное значение, откуда и следует его псевдослучайность, а ГСЧ всегда формирует случайное число, имея в начале высококачественную случайную величину, предоставленную различными источниками энтропии.
Энтропия – это мера беспорядка. Информационная энтропия — мера неопределённости или непредсказуемости информации.
Можно сказать, что ГСЧ = ГПСЧ + источник энтропии.
Уязвимости ГПСЧ
Линейный конгруэнтный ГПСЧ (LCPRNG)
Распространённый метод для генерации псевдослучайных чисел, не обладающий криптографической стойкостью. Линейный конгруэнтный метод заключается в вычислении членов линейной рекуррентной последовательности по модулю некоторого натурального числа m, задаваемой следующей формулой:
где a (multiplier), c (addend), m (mask) — некоторые целочисленные коэффициенты. Получаемая последовательность зависит от выбора стартового числа (seed) X0 и при разных его значениях получаются различные последовательности случайных чисел.
Для выбора коэффициентов имеются свойства позволяющие максимизировать длину периода(максимальная длина равна m), то есть момент, с которого генератор зациклится [1].
Пусть генератор выдал несколько случайных чисел X0, X1, X2, X3. Получается система уравнений
Решив эту систему, можно определить коэффициенты a, c, m. Как утверждает википедия [8], эта система имеет решение, но решить самостоятельно или найти решение не получилось. Буду очень признателен за любую помощь в этом направлении.
Предсказание результатов линейно-конгруэнтного метода
Основным алгоритмом предсказания чисел для линейно-конгруэнтного метода является Plumstead’s — алгоритм, реализацию, которого можно найти здесь [4](есть онлайн запуск) и здесь [5]. Описание алгоритма можно найти в [9].
Простая реализация конгруэнтного метода на Java.
Отправив 20 чисел на сайт [4], можно с большой вероятностью получить следующие. Чем больше чисел, тем больше вероятность.
Взлом встроенного генератора случайных чисел в Java
Многие языки программирования, например C(rand), C++(rand) и Java используют LСPRNG. Рассмотрим, как можно провести взлом на примере java.utils.Random. Зайдя в исходный код (jdk1.7) данного класса можно увидеть используемые константы
Метод java.utils.Randon.nextInt() выглядит следующим образом (здесь bits == 32)
Результатом является nextseed сдвинутый вправо на 48-32=16 бит. Данный метод называется truncated-bits, особенно неприятен при black-box, приходится добавлять ещё один цикл в brute-force. Взлом будет происходить методом грубой силы(brute-force).
Пусть мы знаем два подряд сгенерированных числа x1 и x2. Тогда необходимо перебрать 2^16 = 65536 вариантов oldseed и применять к x1 формулу:
до тех пор, пока она не станет равной x2. Код для brute-force может выглядеть так
Вывод данной программы будет примерно таким:
Несложно понять, что мы нашли не самый первый seed, а seed, используемый при генерации второго числа. Для нахождения первоначального seed необходимо провести несколько операций, которые Java использовала для преобразования seed, в обратном порядке.
И теперь в исходном коде заменим
crackingSeed.set(seed);
на
crackingSeed.set(getPreviousSeed(seed));
И всё, мы успешно взломали ГПСЧ в Java.
Взлом ГПСЧ Mersenne twister в PHP
Рассмотрим ещё один не криптостойкий алгоритм генерации псевдослучайных чисел Mersenne Twister. Основные преимущества алгоритма — это скорость генерации и огромный период 2^19937 − 1, На этот раз будем анализировать реализацию алгоритма mt_srand() и mt_rand() в исходном коде php версии 5.4.6.
Можно заметить, что php_mt_reload вызывается при инициализации и после вызова php_mt_rand 624 раза. Начнем взлом с конца, обратим трансформации в конце функции php_mt_rand(). Рассмотрим (s1 ^ (s1 >> 18)). В бинарном представление операция выглядит так:
10110111010111100111111001110010 s1
00000000000000000010110111010111100111111001110010 s1 >> 18
10110111010111100101001110100101 s1 ^ (s1 >> 18)
Видно, что первые 18 бит (выделены жирным) остались без изменений.
Напишем две функции для инвертирования битового сдвига и xor
Тогда код для инвертирования последних строк функции php_mt_rand() будет выглядеть так
Если у нас есть 624 последовательных числа сгенерированных Mersenne Twister, то применив этот алгоритм для этих последовательных чисел, мы получим полное состояние Mersenne Twister, и сможем легко определить каждое последующее значение, запустив php_mt_reload для известного набора значений.
Область для взлома
Если вы думаете, что уже нечего ломать, то Вы глубоко заблуждаетесь. Одним из интересных направлений является генератор случайных чисел Adobe Flash(Action Script 3.0). Его особенностью является закрытость исходного кода и отсутствие задания seed’а. Основной интерес к нему, это использование во многих онлайн-казино и онлайн-покере.
Есть много последовательностей чисел, начиная от курса доллара и заканчивая количеством времени проведенным в пробке каждый день. И найти закономерность в таких данных очень не простая задача.
Задание распределения для генератора псевдослучайных чисел
Для любой случайной величины можно задать распределение. Перенося на пример с картами, можно сделать так, чтобы тузы выпадали чаще, чем девятки. Далее представлены несколько примеров для треугольного распределения и экспоненциального распределения.
Треугольное распределение
Приведем пример генерации случайной величины с треугольным распределением [7] на языке C99.
Экспоненциальное распределение
Тесты ГПСЧ
Некоторые разработчики считают, что если они скроют используемый ими метод генерации или придумают свой, то этого достаточно для защиты. Это очень распространённое заблуждение. Следует помнить, что есть специальные методы и приемы для поиска зависимостей в последовательности чисел.
Одним из известных тестов является тест на следующий бит — тест, служащий для проверки генераторов псевдослучайных чисел на криптостойкость. Тест гласит, что не должно существовать полиномиального алгоритма, который, зная первые k битов случайной последовательности, сможет предсказать k+1 бит с вероятностью большей ½.
В теории криптографии отдельной проблемой является определение того, насколько последовательность чисел или бит, сгенерированных генератором, является случайной. Как правило, для этой цели используются различные статистические тесты, такие как DIEHARD или NIST. Эндрю Яо в 1982 году доказал, что генератор, прошедший «тест на следующий бит», пройдет и любые другие статистические тесты на случайность, выполнимые за полиномиальное время.
В интернете [10] можно пройти тесты DIEHARD и множество других, чтобы определить критостойкость алгоритма.