Есть ли законное использование RDRAND Intel?

сегодня я подумал: ну, даже если есть большие подозрения на реализацию RDRAND NIST SP 800-90A, это все еще аппаратная реализация генератора псевдослучайных чисел (PRNG), которая должна быть достаточно хороша для нечувствительных приложений. Поэтому я подумал использовать его в своей игре вместо Mersenne Twister.

Итак, чтобы увидеть, был ли какой-либо прирост производительности при использовании инструкции, я сравнил время двух следующих коды:

// test.cpp
#include <cstdio>

int main()
{
    unsigned int rnd = 0;
    for(int i = 0; i < 10000000; ++i) {
        __builtin_ia32_rdrand32_step(&rnd);
    }
    printf("%xn", rnd);
}

и

//test2.cpp
#include <cstdio>
#include <random>

int main()
{
    unsigned int rnd = 0;
    __builtin_ia32_rdrand32_step(&rnd);
    std::mt19937 gen(rnd);
    for(int i = 0; i < 10000000; ++i) {
        rnd ^= gen();
    }
    printf("%xn", rnd);
}

и, запустив два я:

$ time ./test
d230449a

real    0m0.361s
user    0m0.358s
sys     0m0.002s

$ time ./test2 
bfc4e472

real    0m0.051s
user    0m0.050s
sys     0m0.002s

Итак, Mersenne Twister намного быстрее, чем RDRAND на моем процессоре. Ну, я был разочарован, исключен из игры. Но RDRAND-это криптографически безопасный PRNG (CSPRNG), поэтому он многое делает за кулисами... более справедливым было бы сравнить его с другими CSPRNG. Поэтому я взял свой Кролик реализация (простой перевод RFC на C, никаких причудливых трюков для производительности), и написал следующий тест:

// test3.cpp
#include <cstdio>

extern "C"
{
#include "rabbit.h"
}

int main()
{
    rabbit_state s;
    unsigned long long buf[2];
    __builtin_ia32_rdrand64_step(&buf[0]);
    __builtin_ia32_rdrand64_step(&buf[1]);
    rabbit_init_key(&s, (uint8_t*)&buf[0]);

    for(int i = 0; i < 10000000; ++i) {
        rabbit_extract(&s, (uint8_t*)&buf[0]);
    }
    printf("%llxn", buf[0]);
}

и к моему удивлению, генерируя вдвое больше псевдослучайных данных, чем первые два из них, я получил лучшее время, чем RDRAND:

$ time ./test3 
8ef9772277b70aba

real    0m0.344s
user    0m0.341s
sys     0m0.002s

все три были скомпилированы с включенной оптимизацией.

Итак, у нас широко распространенная паранойя, что RDRAND был сделан, чтобы встроить бэкдоры АНБ в криптографию программного обеспечения каждого. Также у нас есть по крайней мере одно программное обеспечение CSPRNG быстрее, чем RDRAND, и наиболее широко используемый достойный PRNG, Мерсен Твистер, это много быстрее, чем RDRAND. Наконец, у нас есть пулы энтропии с открытым исходным кодом, такие как /dev/random и /dev/urandom, которые не скрыты за двойными слоями скремблеров AES, такими как RDRAND.

Итак, вопрос: Должны ли люди использовать RDRAND? Есть ли для него законное применение? Или нам вообще перестать его использовать?

4 ответов


Как owlstead указал, RDRAND высевают с истинной случайности. В частности, он часто пересаживает свой внутренний CSPRNG с 128 битами аппаратно-генерируемой случайности, гарантируя пересаживание по крайней мере один раз каждые 511 * 128 бит. См. раздел 4.2.5 этого документа:

https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide

Итак, в ваших примерах вы использовали одно 128-битное семя для генерации 10 миллионов случайных ничьих от rabbit_extract. В версии RDRAND у вас был эквивалент 2,5 миллиона 128-битных ничьих, что означает, что CSPRING был пересажен по крайней мере 2,500,000/511 = 4,892 раз.

таким образом, вместо 128 бит энтропии, идущих в ваш пример кролика, было по крайней мере 4,892*128 = 626,176 бит энтропии переход к примеру RDRAND.

Это намного, намного больше энтропии, чем вы получите за 0,361 секунды без аппаратная поддержка. Это может иметь значение, если вы делаете вещи, где много реальной случайности важно. Один из примеров-секрет Шамира обмена больших объемов данных-не уверен, что есть и другие.

Итак, в заключение -- это не для скорости, это для высокой безопасности. Вопрос о том, является ли это backdoored беспокоит, конечно, но вы всегда можете XOR его с другими источниками, и, по крайней мере, это не вредит вам.


RDRAND Это не просто PRNG. Это отбеленный TRNG, который соответствует FIPS. Разница в том, что вы можете положиться на RDRAND чтобы содержать довольно много фактической энтропии, непосредственно извлеченной из процессора. Так что основное использование RDRAND должен поставлять энтропию в ОС / библиотеки / приложения.

единственный другой хороший способ для приложений для извлечения энтропии обычно использует источник энтропии, поставляемый ОС, такой как /dev/random или /dev/urandom (который обычно рисует энтропии от /dev/random). Однако, эта ОС также требует найти где-то энтропию. Обычно для этого используются крошечные различия во времени доступа к диску и сети (+ другой полуслучайный вход). Эти устройства не всегда присутствуют и не предназначены в качестве источников энтропии; они часто не очень хорошие источники и не очень быстрые. Так что на системах, которые его поддерживают,RDRAND часто используется в качестве источника энтропии для криптографически безопасный генератор случайных чисел операционной системы.

относительно скорости, специально для игр, вполне допустимо использовать (небезопасный) PRNG. Если вы хотите иметь разумное случайное семя, то посев его с результатом RDRAND может быть хорошей идеей, хотя посев его из поставляемой ОС RNG может быть более портативным и даже более безопасным вариантом (в случае, если вы не полностью доверяете Intel или США).


обратите внимание, что в настоящее время RDRAND реализован с использованием (AES) CTR_DRBG вместо (менее хорошо проанализированного) потокового шифра, который был создан для скорости как кролик, так что это не должно удивлять, что Кролик быстрее.


есть ли законное использование RDRAND Intel?

да.

рассмотрим Монте-Карло. У него нет криптографических потребностей, поэтому не имеет значения, поддерживает ли его АНБ.


или мы должны прекратить использовать его?

мы не можем ответить. Это слияние вариантов использования, требований и личных предпочтений.


... Также мы имейте хотя бы одно программное обеспечение CSPRNG быстрее, чем RDRAND, и наиболее широко используемый приличный PRNG..."

Mersenne Twister может быть быстрее для Слова в момент времени после инициализации и без поворотов, потому что он возвращает слово из массива состояний. Но я сомневаюсь, что это так же быстро, как RDRAND для непрерывного потока. Я знаю, что RDRAND может достичь теоретических пределов, основанных на ширине шины в непрерывном потоке.

согласно Дэвиду Джонстону из Intel (который разработал схему), это что-то вроде 800+ MB/s. См. ответ DJ в какова задержка и пропускная способность инструкции RDRAND на Ivy Bridge?.


у параноиков есть по крайней мере два варианта. Во-первых, они могут отказаться от использования RDRAND и RDSEED. Во-вторых, они могут использовать выход RDRAND и RDSEED для посева другого генератора, а затем используйте выход второго генератора. Я считаю, что ядро Linux использует второй подход.


здесь есть исследование астрофизики (http://iopscience.iop.org/article/10.3847/1538-4357/aa7ede/meta;jsessionid=A9DA9DDB925E6522D058F3CEEC7D0B21.ip-10-40-2-120), (non-paywalled) версия здесь (https://arxiv.org/abs/1707.02212), что дает законное использование для RdRand.

он рассматривает эффекты RdRand на симуляторе Монте-Карло, как советовал более ранний пост. Но автор не нашел никакой статистической разницы в результатах, которые используйте или не используйте RdRand. С точки зрения производительности, похоже, что Mersenne Twister намного быстрее. Я думаю, что разделы 2.2.1 и 5 содержат все детали.