Случайности не случайны, особенно когда они реализованы исключительно программными методами и подчиняются распознаваемому детерминизму. А тем временем мы нуждаемся в генерации настоящих, случайных чисел — от криптографии с защитой наших банковских данных, до компьютерных игр.
Может показаться что эта проблема была решена уже давно, но те же процессоры обзавелись модулями энтропии только в 2012-2014 годах. И на этом прогресс не останавливается: всё доступнее становятся квантовые генераторы энтропии, полностью лишённые изъяна детерминизма. Давайте посмотрим, как от ложного рандома мы пришли к недетерминированному.
Миллион случайных цифр
В мае 1947 года пока ещё коммерческая компания RAND, созданная как «Think Tank» для нужд ВВС США, занялась решением нетривиальной для тех лет задачи: генерацией большого массива случайных чисел. На Random.org тогда было не зайти, человеческой способности к генерации случайных чисел не доверяли уже тогда, но источники случайности для криптографии, исследований и ряда других задач уже надо было откуда-то брать.
Для этого инженеры RAND сделали то, чего до них почти никто не пробовал — прибегли к компьютерам. Пока ещё аналоговым: их генератор представлял из себя электрическую рулетку в форме колеса на 32 разряда. На колесо поступал импульсный сигнал с частотой 0,1 мегагерца, за раз колесо совершало 3000 оборотов и производило 1 случайное число в секунду, которое передавалось на компьютер. Для этого использовался двоично-десятичный преобразователь, который преобразовывал 20 из 32 чисел (оставшиеся 12 не использовались). Далее на перфоратор IBM поступала только пара из двух двузначных чисел, из которых на перфокарту переносилась последняя цифра. И так процесс повторяли, пока не накопили необходимое количество случайных чисел, перенесённых на перфокарты. Всего было сделано 20 000 перфокарт по 50 цифр на каждой. Далее, чтобы дополнительно перерандомизировать, к каждой цифре добавили по модулю 10, взятому из соответствующей по расположению цифры на предшествовавшей карте.
Полученный массив чисел подобным образом несколько раз переделывали, пока не добились частоты случайности для каждого отдельного числа в 2 %. Для этого вычисляли отдельные массивы на 125 тысяч цифр с такими вводными:
В конечном итоге, после ещё ряда тестов и перепроверок в 1951 году, в ставшей к тому времени некоммерческой компанией RAND написали книгу под названием «A Million Random Digits with 100,000 Normal Deviates», которая на долгие годы станет настольной для тысяч специалистов и исследователей в самых различных областях и дисциплинах.
Её содержимое выглядело подобным образом:
Страшно представить, что происходило, если номер случайного числа терялся и его приходилось искать самостоятельно, вручную. Ctrl+F и удобных читалок для файлов ведь тоже не было, а закладку легко забыть сделать, да и вкладыш легко мог потеряться.
Какое число вы загадали, мистер Тьюринг?
Физики и математики часто любят шутить, что всё было придумано Гауссом либо Эйлером. В случае же компьютерных наук, куда бы мы ни пошли, везде мы встретим Алана Тьюринга и Джона фон Неймана. Конечно же, без них не могло обойтись и тут.
В 1951 году начались работы над первым в мире коммерчески доступным компьютером общего назначения, Ferranti Mark I. Хотя сам Тьюрин называл этот компьютер Mark II, так как ранее он уже работал вместе с Манчестерским Университетом над созданием схожего компьютера. Помимо прочего, это также был первый компьютер, обладавший аппаратным модулем и поддержкой инструкций для создания энтропии для случайных чисел. Всего с помощью инструкции /W он мог помещать 20 случайных битов в младшие половины регистра, беря в качестве источника энтропии «шум», создаваемый сопротивлением в резисторе.
Однако идея Тьюринга по созданию случайных чисел аппаратным методом слишком опережала своё время. Для программистов той эпохи, не имевших привычных нам инструментов разработки и отладки, это была настоящая головная боль. Из-за своей недетерминированной природы аппаратный метод генерации случайных чисел внёс слишком много неопределённости в ранее непредсказуемую среду. Надёжность и предсказуемость в тот исторический период были в приоритете у разработчиков программного обеспечения, а программы, использующие эту инструкцию /W, по своей природе не могли быть запущены так, чтобы можно было пошагово повторить их исполнение.
Новая, случайная надежда
Прошло почти полвека с создания Тьюрингом инструкций и аппаратной поддержки генерации случайных чисел для компьютеров. И вот, неожиданно для всех, в 1999 году Intel добавляет в свой чипсет i810 аппаратный генератор случайных чисел.
Компания не стала изобретать велосипед: как и в Ferranti Mark I, модуль Intel RNG в качестве источника энтропии использовал шум, получаемый с резистора, измеряя, как под воздействием тепла меняется сопротивление резистора, а с ним и напряжение.
Однако в Intel также зачем-то решили применить фон Неймановский экстрактор случайности, разработанный им в 1951 году и по сей день активно использующийся, но предназначенный для псевдослучайных чисел. Зачем же его использовать для равномерного распределения вывода с аппаратного генератора, и не делает ли это медвежью услугу?
В Intel отмечают, что одно из последствий использования корректора — нестабильный битрейт на выходе, с примерным уровнем преобразования 6 бит на входе и 1 на выходе, и общей пропускной способностью чуть выше 75 Кбит/с.
И зачем всё это нужно? Более 50 лет ведь как-то жили же без таких модулей. Верно, но тут есть нюанс: более детерминированные механизмы генерации случайных чисел более чем реально предсказуемы и взламываемы, нет даже нужды ждать, когда наконец-то выйдут квантовые компьютеры. Одной из наиболее известных уязвимостей детерминированных генераторов было открытие в 1994 году механизма подбора ключа шифрования к SSL-сертификату веб-сервера Netscape. Для его реверс-инжиниринга требовалось знать всего лишь три переменные: время суток, идентификатор процесса и идентификатор родительского процесса. Но и позднее, из более безобидного: в 2009 у энтузиастов получалось взломать HackerNews. С учётом того, что культура безопасности — это то, что в ИТ традиционно находится под постоянным давлением, требующим постоянного развития. При должном внимании подобных уязвимостей и сейчас можно найти немало в современном софте. И как не трудно догадаться, нововведение Intel с 1999 года особой популярности не обрело.
Настоящая случайность
В 2012 году на рынок выходит новое поколение процессоров Intel из линейки Ivy Bridge. Конца света не случилось, но зато появились две новые процессорные инструкции: RDSEED и RDRAND. Последняя истинно случайная, работает на аппаратном уровне, но более медленная, а вторая использует первую как ключ для генерации. Реализовали это с помощью изменений на архитектурном уровне, вместо использования аналогового терморезистора генератор стал цифровым.
Теперь он состоит из пары инверторов — логических вентилей, меняющих входное значение на противоположное. Выход одного инвертора подключён на вход другого. Если на выходе у одного 0, то другой инвертор получает его на входе и, соответственно, выдаёт 1. Если же первый инвертор выдаёт 1, то второй инвертор будет выдавать 0. Дополнительно в цепь к ним добавлены два транзистора, подающих на входе и на выходе обоих инверторов 1.
И откуда же тут взяться случайности, если логические схемы детерминированней некуда? В сферическо-вакуумном пространстве математической логики это возможно. Однако в реальном мире логические вентили материальны и имеют физические свойства. Когда тактовый генератор отключает транзисторы, у инверторов на выходах оказывается одинаковое состояние, а они по своей природе стремятся принять противоположное. И какой инвертор поменяется на 0? Неизвестно. В теории, одинаковое состояние обоих инверторов может сохраняться вечно, но в реальности любое воздействие — от теплового шума до случайных колебаний в атомах — приводит цепь в одно из двух возможных устойчивых состояний.
Без дополнительного запаса прочности, как и в аналоговом генераторе, не обошлось, но вместо экстрактора фон Неймана используется уже более продвинутый нормализатор на основе алгоритма AES.
В 2015 поддержку инструкций RDRAND и RDSEED добавила в свои процессоры и AMD.
Примерно в это же время аналогичные инструкции и аппаратные модули появляются для ARM-процессоров. Ядро Linux получает поддержку этих инструкций, однако для генерации рандома в /dev/urandom им не доверяет, сомневаясь в их безопасности и оставаясь верным своим генераторам случайных чисел на основе иных источников.
По сей день RDRAND и RDSEED остаются основными инструкциями в тех случаях, когда требуется генерация случайных чисел на аппаратной основе. Несмотря на сложность их принципов работы и того, что на слуху они достаточно редко, применение их в коде под Linux не является затруднительным. Вот пример кода на C++ с их использованием:
#include <iostream>
#include <cstdint>
#include <random>
// rdseed
void rdseed() {
uint64_t result;
asm volatile("rdseed %0" : "=r" (result));
std::cout << "Random value by rdseed: " << result << std::endl;
}
//rdrand
void rdrand(){
std::random_device rd;
unsigned long long randomValue = rd();
std::cout << "Random value by rdrand: " << randomValue << std::endl;
}
int main() {
rdseed();
rdrand();
return 0;
}
В квантовый мир
Генераторы случайных чисел на основе квантовых эффектов (QRNG) представляют собой устройства, которые используют явления квантовой физики для создания истинно случайных последовательностей чисел. По крайней мере, есть интерпретации квантовой механики, утверждающие, что квантовые явления полностью недетерминированы.
Однако, не будучи по специализации физиком я в этом не до конца уверен. Поэтому приглашаю в комментарию тех кто более компетентен подтвердить или опровергнуть мои рассуждения.
Один из наиболее популярных методов получения энтропии на основе квантовых явлений — это анализ скорости прибытия фотона на детектор, в определённый отрезок времени.
Впрочем, никто не запрещает использовать известную, наверное, всем особенность света, обнаруженную в знаменитом эксперименте с двойной щелью: корпускулярно-волновой дуализм. То есть поведение света и как частицы, и как волны. Что и сделал один энтузиаст в своём простом генераторе, с поправкой на то, что выдавать он может либо 0, либо 1, наравне с подбросом монетки. Но от того менее занимательной идея не становится.
Ну или ещё экзотичнее — можно использовать радиоактивность. Если вы сейчас подумали про кота Шрёдингера, то вы отчасти правы: в этом проекте энтузиаст генерирует энтропию исходя из времени обнаружения альфа-распада америция-241.
Заключение
Криптография, шифрование и случайность используются везде, буквально. От генерации миров в Minecraft до веб-сертификатов и ключей безопасности, обеспечивающих надёжность ваших транзакций в банке. Но многие даже не задумываются, чем это всё обеспечено, как не задумывались и 30 лет назад. К счастью, современные тенденции идут наоборот в сторону большего внимания к этим вопросам и улучшения состояния информационной безопасности ИТ-систем. Пусть тот же проект Linux не особо доверяет аппаратным генераторам случайных чисел, всё по тем же причинам, что и во времена Тьюринга, недетерминированность — это обоюдоострый меч. Полезный для конечного результата, но больно бьющий по пытающемуся отлаживать проект разработчику. Но теория и историческая практика уже не раз показали, что закрыть глаза и надеяться на «и так сойдёт» — не вариант. В лучшем случае проверку на прочность устроит белый хакер, в худшем — злонамеренный взломщик.
Как и в прошлом веке, конечное решение только за индустрией. Поэтому интересно услышать ваше мнение на этот счёт в комментариях. – Достаточен ли текущий уровень внимания к информационной безопасности в ИТ-индустрии, возможно он наоборот избыточен? Или, быть может, для большей части проектов с избытком хватит и справочника с заранее расписанными вариантами ключей шифрования, которые остаётся только захардкодить в проект?
Комментарии (10)
diakin
03.05.2024 08:02Да взять последовательность знаков числа Пи, она же случайная )
avost
03.05.2024 08:02Она настолько же "случайная", как последовательность цифр десятичного представления числа одна третья. Разве что повторения случаются пореже.
diakin
03.05.2024 08:02Ну конечно.
Математики утверждают {но это не точно}, что число Пи состоит из бесконечного числа цифр, последовательность которых нельзя отличить от случайных. Под случайностью подразумевают, что если мы возьмём любой достаточно длинный кусок числа Пи, то в нём будет одинаковое количество единиц, двоек, ..., девяток. Более того, в нём будет одинаковое количество пар (00, 01,...,10, 11, ...,99), троек и дальше со всеми остановками.
avost
03.05.2024 08:02Математики утверждают {но это не точно}, что число Пи состоит из бесконечного числа цифр
Это правда.
последовательность которых нельзя отличить от случайных
А это - нет. Последовательность неслучайна и фиксирована. Любая цифра последовательности с тем или иным трудом однозначно вычисляется.
Под случайностью подразумевают
В любом учебнике по теорверу написано что НА САМОМ ДЕЛЕ подразумевают под случайностью. А не вот этот бред.
если мы возьмём любой достаточно длинный кусок числа Пи, то в нём будет одинаковое количество единиц, двоек, ..., девяток.
Ровно наоборот. Если мы возьмём любое "достаточно длинное" конечное число эН, то в последовательности цифр представления числа пи существует кусок, состоящий целиком из эН нулей. Или эН девяток. Или эН повторов последовательности "123".
Ну конечно
Не знаю откуда вы взяли процитированный вами бред, но положите его на место и возьмите обычный вузовский учебник по теории вероятностей. И ещё по матанализу.
diakin
03.05.2024 08:02Случайная величина — переменная, значения которой представляют собой численные исходы некоторого случайного феномена или эксперимента. Другими словами, это численное выражение результата случайного события.
...
Последовательность цифры в числе Пи считается случайной. Пусть генератор основывается на выводе бит представления числа Пи, начиная с какой-то неизвестной точки. Такой генератор, возможно и пройдет «тест на следующий бит», так как ПИ, видимо, является случайной последовательностью.https://habr.com/ru/articles/151187/
Норма́льное число́ по основанию n - всякое действительное число, в записи которого в n-ричной системе счисления произвольная группа из k последовательных цифр встречается с одной и той же асимптотической частотой, равной n-k для каждого k = 1, 2, ….
на 2024 год неизвестно, является ли π нормальным числом)
Любая цифра последовательности с тем или иным трудом однозначно вычисляется.
Если вы знаете, что вычислять.
Есть источник случайных случайных чисел, а есть их мат. свойства. Имеются ли у числа ПИ требуемые свойства? "Видимо" имеются, {но это не точно}.
avost
03.05.2024 08:02Ну, вот цитата из приведённой вами ссылки: Случайная величина — это величина, которая принимает в результате опыта одно из множества значений, причём появление того или иного значения этой величины до её измерения нельзя точно предсказать.
Для числа пи выделенное условие не выполняется.на 2024 год неизвестно, является ли π нормальным числом)
Ну, вот видите, и это ваше первоеачальное утверждение не подтверждается.
Любая цифра последовательности с тем или иным трудом однозначно вычисляется.
Если вы знаете, что вычислять.
Если мы всё ещё говорим о числе пи, то я знаю что вычислять.
Есть источник случайных случайных чисел, а есть их мат. свойства. Имеются ли у числа ПИ требуемые свойства?
Как мы только что выяснили, последовательность цифр в числе пи не обладает основным свойством случайных величин - непредсказуемостью появления очередной цифры. Дополнительно вы опровергли тезис об ассимптотической равномерности распределения цифр в последовательности (вернее, дали информацию о его недоказанности).
"Видимо" имеются
Без выполнения условия непредсказуемости они ничего не стоят, увы.
diakin
03.05.2024 08:02Непредсказуемость.. это такая вещь.. Давайте я буду называть числа, а вы их предсказывать? Ведь не получится предсказать.
И не доказано на равно - опровергнуто.
Вообще мне непонятногенераторы псевдослучайных чисел (PRNGS), которые генерируют числа, которые выглядят случайными, но на самом деле являются детерминированными и могут быть воспроизведены, если известна модель (шаблон), на основании которой работает генератор псевдослучайных чисел.
Какой шаблон-мавлон?
Берем число ПИ и какой-нибудь генератор (псевдо)случайных чисел.
Генератор генерит число, которое будет являться номером десятичной цифры числа ПИ. Ну и? Какое тут предсказание может быть?
Если мало - возьмем 2\100502 генератора и будем из использовать по очереди. Все что угодно можно придумать.
SADKO
03.05.2024 08:02Что-то как-то, надо было назвать "эволюция генераторов случайных чисел от intel", да и в ней многое осталось за кадром, например чем кроме теории и практики заговоров обусловленны именно такие решения, и какие проблемы они решают... Или на сколько они были пригодны для тех или иных задач, и почему рынок ГСЧ не ограничен поделками энтузиастов, да и последние бывают очень разные...
...а без физики тут вообще никак, ибо она сильно влияет на распределение у наивных аппаратных генераторов, по этому к ним и прикручивают тот или иной математический костыль для гарантии тех или иных качеств последовательности, и иногда это даже может статься хорошей идеей, но дьявол как всегда в деталях реализации
sidorovmax
Отечественные банки по закону обязаны использовать для криптографических нужд сертифицированные в ФСБ генераторы случайных чисел.
Shaman_RSHU
Да и по PCI DSS тоже всякие HSM с аппаратными генераторами... но скорее всего PCI DSS сейчас не актуален