Есть ли законное использование для Intel RDRAND?
Сегодня я подумал: хорошо, даже если есть большие подозрения на реализацию RDRANDНИСТ СП 800-90Аэто все еще аппаратная реализация генератора псевдослучайных чисел (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("%x\n", 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("%x\n", 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("%llx\n", buf[0]);
}
И к моему удивлению, генерируя вдвое больше псевдослучайных данных, чем первые два, я получил лучшее время, чем RDRAND:
$ time ./test3
8ef9772277b70aba
real 0m0.344s
user 0m0.341s
sys 0m0.002s
Все три были скомпилированы с включенной оптимизацией.
Итак, у нас широко распространена паранойя о том, что RDRAND была создана для того, чтобы встраивать бэкдоры АНБ в криптографию программного обеспечения для всех. Также у нас есть по крайней мере один программный CSPRNG быстрее, чем RDRAND, и наиболее широко используемый приличный PRNG, Mersenne Twister, являетсямного быстрее чем RDRAND. Наконец, у нас есть пулы энтропии программного обеспечения с открытым исходным кодом, такие как/dev/random
а также/dev/urandom
, которые не спрятаны за двумя слоями скремблера AES, как RDRAND.
Итак, вопрос: должны ли люди использовать RDRAND? Есть ли законное использование для этого? Или мы должны перестать использовать его вообще?