¿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?

Respuestas a la pregunta(4)

Su respuesta a la pregunta