Случайность - это вообще весьма важная штука в криптографии. Например, в том же RSA некоторые параметры при генерации ключевой пары выбираются случайно. Или, к примеру, в ECC мы можем задать количество "прыжков" до финальной точки случайным образом. Но дело в том, что нельзя сказать компьютеру "загадай какое-нибудь число", в отличие от людей, которые могут легко выдать нечто в указанном диапазоне (хотя и там наверняка есть какой-то алгоритм).
Так вот, процесс создания случайных, точнее псевдослучайных, чисел в компьютере - это довольно любопытная тема. Самый простой пример генератора случайных чисел (RNG) - это линейный конгруэнтный генератор, который выражается формулой
f(x) = a * x + c (mod m). Казалось бы, звучит сложно, но по факту алгоритм следующий:- Берём изначальное "сообщение", которое может быть числом, словом, строкой. Это сообщение называется seed.
- Хэшируем его по заданному алгоритму, хотя бы с помощью keccak256. Получаем на выходе число в диапазоне до 2 ** 256 - 1 (ну, или в другом, зависит от алгоритма). Это и будет нашим первым случайным числом.
- Проблема, однако, в том, что это число лежит в очень большом диапазоне, а нам, к примеру, нужно получить число от 0 до 10. Ну, это не беда - мы можем просто использовать остаток от деления на 10, то есть нормировать изначальное число.
- Дальше, если нам нужно ещё одно случайное число, мы просто увеличиваем seed на единицу и опять хэшируем - у нас получится другое число, которое также можно нормировать.
- Эту операцию можно повторять сколько угодно раз. Естественно, процесс может быть сложнее, чем просто увеличение на 1, но суть остаётся прежней.
Из всего этого можно сделать очень простой вывод: если кто-то знает изначальный seed, то этот некто сумеет предсказать последующие случайные числа, то есть восстановить последовательность, что, в ряде случаев, может привести к очень серьёзным проблемам. Ну, грубо говоря, хакер может понять, какое случайное число использовалось при создании закрытого ключа и просто его взломать.
Поэтому чрезвычайно важно, чтобы в таких случаях использовались безопасные случайные числа (CSPRNG, то есть криптографически надёжные). Для таких чисел seed выбирается с помощью отслеживания множества происходящих в системе событий, которые сложно предсказать и восстановить. К примеру, сетевая активность, движения мышкой, ввод с клавиатуры - в таком духе. Все эти события вносят так называемую энтропию, то есть размытие, которая сильно затрудняет попытку как-то воссоздать seed.
Другая особенность CSPRNG заключается в том, что даже если кто-то знает несколько случайных чисел последовательности, он не сможет предсказать, каким будет следующее число или понять, какие числа шли до этого. В большинстве языков программирования уже есть встроенные инструменты для генерации надёжных случайных чисел.
Впрочем, далеко не всегда это нужно - если вы просто хотите вытащить случайный элемент из массива в учебной программе, то вам подойдут обычные генераторы случайных чисел в духе
rand() в Ruby.Случайные числа можно использовать для создания потоковых шифров, а пример такого шифра можно посмотреть в видео-уроке (в общем, он несложный). https://youtu.be/q9PWljGSpKY