Истинные случайные числа с C++11 и RDRAND
Я видел, что Intel, похоже, включила новую функцию сборки для получения реальных случайных чисел, полученных из аппаратного обеспечения. Название инструкции RdRand
, но в Интернете доступно лишь небольшое количество деталей: http://en.wikipedia.org/wiki/RdRand
Мои вопросы относительно этой новой инструкции и ее использования в C++11 следующие:
Случайные числа, сгенерированные с
RdRand
действительно случайно? (каждый бит генерируется некоррелированным белым шумом или квантовыми процессами?)Это особенность процессоров Ivy Bridge, и будет ли Intel продолжать реализовывать эту функцию в процессорах следующего поколения?
Как использовать это через C++11? Может быть с
std::random_device
но компиляторы уже вызываютRdRand
если инструкция доступна?Как проверить,
RdRand
действительно вызывается, когда я компилирую программу?
5 ответов
- Это, безусловно, зависит от вашего взгляда на детерминизм вселенной, поэтому это скорее философский вопрос, но многие люди считают его случайным.
- Только Intel узнает, но поскольку было требование добавить его, вероятно, будет спрос на его сохранение.
std::random_device
не требуется аппаратное управление, и даже если это так, его не требуется использоватьrdrand
, Вы можете спросить егоdouble entropy() const noexcept
функция-член, независимо от того, аппаратно она или нет. С помощьюrdrand
это проблема QoI, но я ожидаю, что каждая здравомыслящая реализация, у которой она есть, сделает это (я видел, например, gcc, делающий это). Если вы не уверены, вы всегда можете проверить сборку, но и другие средства аппаратной случайности должны быть достаточно хороши (доступно другое выделенное оборудование).- Смотрите выше, если вас интересует, является ли это только аппаратным, используйте
entropy
Если вы заинтересованы в rdrand, отсканируйте сгенерированный машинный код.
Я разработал генератор случайных чисел, который подает случайные числа в инструкцию RdRand. Так что для разнообразия я действительно знаю ответы.
1) Случайные числа генерируются из PRNG, совместимого с AES-CTR DRBG SP800-90. AES использует 128-битный ключ, поэтому числа имеют устойчивость к мультипликативному предсказанию до 128 бит и суммируются за пределами 128.
Однако PRNG часто повторяется из полного источника энтропии. Для изолированных инструкций RdRand они будут заново заполнены. Для 8 потоков на 4 ядрах, тянущих как можно быстрее, он будет повторяться всегда чаще, чем один раз на 14 RdRands.
Семена происходят из генератора случайных чисел. Это касается источника энтропии 2,5 Гбит / с, который подается в энтропийный экстрактор со степенью сжатия 3:1 с использованием AES-CBC-MAC.
Таким образом, в действительности это TRNG, но тот, который прибегает к свойствам криптографически безопасного PRNG для коротких последовательностей при большой загрузке.
Это именно семантическая разница между /dev/random и /dev/urandom в Linux, только намного быстрее.
В конечном итоге энтропия получается из квантового процесса, поскольку это единственный фундаментальный случайный процесс, который мы знаем в природе. В DRNG именно тепловые шумы в затворах 4 транзисторов определяют состояние разрешения метастабильной защелки, 2,5 миллиарда раз в секунду.
Источник энтропии и кондиционер предназначены для соответствия SP800-90B и SP800-90C, но эти спецификации все еще находятся в черновом варианте.
2) RdRand является частью стандартного набора команд Intel. Это будет поддерживаться во всех процессорных продуктах в будущем.
3) Вам нужно либо использовать встроенную сборку, либо библиотеку (например, openssl), которая использует RdRand. Если вы используете библиотеку, библиотека реализует встроенный ассемблер, который вы можете реализовать напрямую. Intel дает примеры кода на своем веб-сайте.
Кто-то еще упомянул librdrand.a. Я написал это. Это довольно просто.
4) Просто найдите коды операций RdRand в двоичном файле.
Со времени открытия PRISM и Сноудена я бы очень осторожно использовал аппаратные генераторы случайных чисел или полагался на одну единственную библиотеку в приложении с вопросами безопасности. Я предпочитаю использовать комбинацию независимых криптографических генераторов случайных чисел с открытым исходным кодом. Под комбинацией я имею в виду, например: ra
, rb
, rc
быть тремя независимыми криптографическими генераторами случайных чисел, r
случайное значение, возвращаемое в приложение. Давайте sa
, sb
, sc
быть их семенем, ta
, tb
, tc
периоды повторной посадки rb
каждый tb
розыгрыши. Независимым: принадлежность, насколько это возможно, независимым библиотекам и использование различных шифров или алгоритмов.
Псевдо-код:
// init
seed std rand with time (at least millisec, preferably microsec)
sa = std rand xor time // of course, not the same time evaluation
// loop
sb = ra every tb
sc = rb every tc
r = rb xor rc
sa = rc every ta
Конечно, каждый розыгрыш должен быть использован только один раз.
Вероятно, достаточно двух источников:
// init
seed std rand with time (at least millisec, preferably microsec)
sa = std rand xor time // of course, not the same time evaluation
// loop
sb = ra every tb
sa = rb every ta
r = rb xor ra
Выберите разные значения для ta, tb, tc. Их диапазон зависит от силы случайного источника, который вы используете.
РЕДАКТИРОВАТЬ: я запустил новую библиотеку ABaDooRand для этой цели.
1) Нет, числа из RdRand не являются действительно случайными, так как они поступают из криптографически безопасного генератора псевдослучайных чисел. Однако технологии RdRand, RdSeed и Intel Secure Key, вероятно, наиболее близки к случайным.
2) Да, эта функция доступна во всех процессорах Intel, которые появляются на ноутбуках, настольных компьютерах и серверах, начиная с процессоров Ivy Bridge, о которых вы упомянули. В наши дни эти функции также реализованы в чипах AMD.
3 и 4) Руководство по разработке программного обеспечения Intel - это место, где можно найти ответы на эти вопросы. Здесь интересно обсудить, как Intel Secure Key применяется к астрофизической проблеме ( http://iopscience.iop.org/article/10.3847/1538-4357/aa7ede/meta;jsessionid=A9DA9DDB925E6522D058F3CEEC7D0B21.ip-10-40-2-120) и неоплаченная версия здесь ( https://arxiv.org/abs/1707.02212). В этом документе описывается, как работает технология, как ее реализовать, и описывается ее производительность (разделы 2.2.1 и 5). Пришлось читать это для класса.
- Я думаю, что они, как говорят, "случайные"... Так как это для шифрования. Я бы не слишком беспокоился о качестве случайных чисел.
- Я думаю, что Intel продолжит делать это, поскольку они всегда считают обратную совместимость важной, даже если эта инструкция может оказаться бесполезной в будущем.
- Извините, я не могу ответить на этот вопрос, потому что я не использую C++11.
- Вы можете попробовать librdrand.a, если не хотите копаться в ассемблерном коде. Intel предоставила библиотеку для бесплатного скачивания на своем сайте. Я проверил это, это довольно удобно и имеет механизм сообщения об ошибках (так как генератор случайных чисел имеет небольшую вероятность не сгенерировать случайное число). Так что если вы используете эту библиотеку, вам нужно только проверить возвращаемое значение функции в librdrand
Пожалуйста, дайте мне знать, если что-то не так в моем ответе. Спасибо
Удачи
xiangpisaiMM