¿Hay algún uso legítimo para el RDRAND de Intel?
Hoy pensé: bueno, incluso si hay una gran sospecha sobre la implementación de RDRANDNIST SP 800-90A, sigue siendo una implementación de hardware del generador de números pseudoaleatorios (PRNG) que debe ser lo suficientemente bueno para aplicaciones no sensibles. Así que pensé en usarlo en mi juego en lugar de Mersenne Twister.
Entonces, para ver si hubo alguna ganancia de rendimiento al usar la instrucción, comparé el tiempo de los dos códigos siguientes:
// 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);
}
y
//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);
}
y al ejecutar los dos obtengo:
$ time ./test
d230449a
real 0m0.361s
user 0m0.358s
sys 0m0.002s
$ time ./test2
bfc4e472
real 0m0.051s
user 0m0.050s
sys 0m0.002s
Entonces, Mersenne Twister es mucho más rápido que RDRAND en mi CPU. Bueno, estaba decepcionado, descartado de mi juego. Pero RDRAND es un PRNG criptográficamente seguro (CSPRNG), por lo que hace mucho entre bastidores ... más justo sería compararlo con otros CSPRNG. Entonces tomé miConejo implementación (traducción simple de RFC a C, sin trucos sofisticados para el rendimiento), y escribió la siguiente prueba:
// 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]);
}
Y para mi sorpresa, al generar el doble de datos pseudoaleatorios que los dos primeros, obtuve un mejor momento que RDRAND:
$ time ./test3
8ef9772277b70aba
real 0m0.344s
user 0m0.341s
sys 0m0.002s
Los tres fueron compilados con la optimización habilitada.
Entonces, tenemos una paranoia generalizada de que RDRAND se hizo para incrustar puertas traseras de la NSA en la criptografía de software de todos. También tenemos al menos un software CSPRNG más rápido que RDRAND, y el PRNG decente más utilizado, Mersenne Twister, esmucho más rápido que RDRAND. Finalmente, tenemos grupos de entropía de software auditables de código abierto, como/dev/random
y/dev/urandom
, que no están ocultos detrás de dos capas de codificador de AES, como RDRAND.
Entonces, la pregunta: ¿deberían las personas estar usando RDRAND? ¿Hay algún uso legítimo para ello? ¿O deberíamos dejar de usarlo por completo?