Funções de CPU RDRAND e RDSEED agora disponíveis

Olá pessoal!

Eu próprio não faço criptografia, mas minha pequena pesquisa pode muito bem ser útil. Decidi lidar com as funções internas do processador RDRAND e RDSEED. O compilador Delphi disse um identificador não declarado. Hmm O IMC, o IMC2, o AVX, o AVX2 e até o AVX-512 já existem há muito tempo e os Delphians adotaram o SSE4.2. Isso não importa. Nós mesmos compilamos o código.

Primeiro, verifiquei o suporte dessas funções pelo processador. Claro, CPUID. Você pode usar o CPUID começando com os primeiros processadores Pentium. Espero que ninguém pense em executar o CPUID em uma máquina 486, porque ela ainda não existe. A propósito, RDRAND e RDSEED antes dos processadores IvyBridge também não existem.

function CPU_support_RDRAND: Boolean; asm mov rax, $01 cpuid test ecx, 40000000h // 30-  setne al end; function CPU_support_RDSEED: Boolean; asm mov rcx, 0 mov rax, $07 // №7 cpuid test ebx, 40000h // 18-  setne al end; 

Acontece que o meu Core i7 G6950X Extreme suporta esses recursos. Então, eu decidi compilar o bytecode manualmente. Para experientes, darei os prefixos de código REX e REX.W. Você pode escrever o resultado em um registro diferente:

 const REX_RDRAND32: Byte = $F0; //(11b:REG, 110b:OPCODE, 000b:EAX) REX_RDSEED32: Byte = $F8; //(11b:REG, 111b:OPCODE, 000b:EAX) REX_W_RDRAND64: Byte = $48; //(11b:REG, 110b:OPCODE, 000b:RAX) REX_W_RDSEED64: Byte = $48; //(11b:REG, 111b:OPCODE, 000b:RAX) 

As funções podem funcionar no modo de 32 bits e no modo de 64 bits. Portanto, eu fiz os dois, e até em duas versões. O resultado são 4 funções:

 function RDRand32: DWord; asm @Retry: db $0F, $C7, $F0 //RDRAND EAX (CF = 1    ) jnc @Retry end; function RDSeed32: DWord; asm @Retry: db $0F, $C7, $F8 //RDSEED EAX (CF = 1    ) jnc @Retry end; function RDRand64: QWord; asm .NOFRAME @Retry: db $48, $0F, $C7, $F0 //RDRAND RAX (CF = 1    ) jnc @Retry end; function RDSeed64: QWord; asm .NOFRAME @Retry: db $48, $0F, $C7, $F8 //RDSEED RAX (CF = 1    ) jnc @Retry end; 

Eles são mais lentos que a função de biblioteca Random. O RDRand é de cerca de 35% e o RDSeed é de 50% ou mais, mas a qualidade da exclusividade dos valores gerados é muito maior. Existem alguns bons artigos sobre esse assunto neste recurso, mas minha missão (disponibilizar funções no Delphi) foi concluída. Não testei em Lázaro, mas provavelmente funcionará sem nenhuma alteração. No final da declaração da função, você só precisa adicionar a palavra de backup assembler.

Aqui está o código fonte do aplicativo do console de teste. Lá você pode encontrar um protótipo das funções Random32 e Random64 com base no processador embutido. Talvez seja isso que você estava procurando. Tchau pessoal!

Source: https://habr.com/ru/post/pt441392/


All Articles