Existe algum uso legítimo para o RDRAND da Intel?
Hoje pensei: bem, mesmo que haja grande suspeita sobre a implementação do RDRAND noNIST SP 800-90A, ainda é uma implementação de hardware do gerador de números pseudo-aleatórios (PRNG) que deve ser bom o suficiente para aplicativos não sensíveis. Então, pensei em usá-lo no meu jogo em vez de Mersenne Twister.
Portanto, para verificar se houve algum ganho de desempenho ao usar a instrução, comparei o tempo dos dois códigos a seguir:
// 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);
}
e
//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);
}
e executando os dois eu recebo:
$ time ./test
d230449a
real 0m0.361s
user 0m0.358s
sys 0m0.002s
$ time ./test2
bfc4e472
real 0m0.051s
user 0m0.050s
sys 0m0.002s
Portanto, Mersenne Twister é muito mais rápido que RDRAND no meu CPU. Bem, fiquei desapontado, excluído do meu jogo. Mas o RDRAND é um PRNG criptograficamente seguro (CSPRNG), por isso faz muito nos bastidores ... mais justo seria compará-lo com outro CSPRNG. Então eu peguei minhaCoelho implementação (tradução simples da RFC para C, sem truques sofisticados de desempenho) e escreveu o seguinte teste:
// 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]);
}
E para minha surpresa, gerando o dobro de dados pseudo-aleatórios que os dois primeiros, tive um tempo melhor que o RDRAND:
$ time ./test3
8ef9772277b70aba
real 0m0.344s
user 0m0.341s
sys 0m0.002s
Todos os três foram compilados com a otimização ativada.
Portanto, temos uma paranóia generalizada de que o RDRAND foi criado para incorporar backdoors da NSA na criptografia de software de todos. Também temos pelo menos um software CSPRNG mais rápido que o RDRAND, e o PRNG decente mais amplamente usado, Mersenne Twister, éMuito de mais rápido que RDRAND. Por fim, temos pools de entropia de software auditável de código aberto, como/dev/random
e/dev/urandom
, que não estão ocultos atrás das duas camadas de AES, como RDRAND.
Então, a pergunta: as pessoas deveriam estar usando o RDRAND? Existe algum uso legítimo para isso? Ou devemos parar de usá-lo completamente?