πŸ“œ ⬆️ ⬇️

CPU functions RDRAND and RDSEED become more accessible

Hello!

I myself am not engaged in cryptography, but for someone, my small research may be useful. I decided to deal with the RDRAND and RDSEED functions built into the processor. The Delphi compiler said Undeclared identifier. Hmm BMI, BMI2, AVX, AVX2, and even AVX-512 have been around for a long time, and the Delphi stopped at SSE4.2. No problem. Compile the code yourself.

First I made a check on the support of these functions by the processor. Of course CPUID. You can use CPUID starting with the first Pentium processors. I hope no one thinks of running CPUID on a 486 machine, because it has not been there yet. By the way, RDRAND and RDSEED before the IvyBridge processors also do not exist.
')
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; 

It turned out that my Core i7 G6950X Extreme supports these functions. Therefore, I decided to compile the byte-code manually. For experienced cite the REX and REX.W prefixes. You may want to write the result in another register:

 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) 

Functions can work both in 32-bit mode, and in 64-bit mode. Therefore, I made both and even in two versions. The result was 4 functions:

 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; 

For speed, they are slower than the library function Random. RDRand by about 35%, and RDSeed by 50% or even more, but the quality of the uniqueness of the generated values ​​is much higher. This resource has quite good articles on this topic, but my mission (to make the functions available in Delphi) is completed. I haven't tested it in Lazarus, but it will most likely work without any changes. At the end of the function declaration, you only need to add the reserve word assembler.

Here are the source texts of the test console application. There you can find a prototype of the functions Random32 and Random64 based on the built-in processor. Perhaps this is what you were looking for. Bye everyone!

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


All Articles