Funciones de CPU RDRAND y RDSEED ahora disponibles

Hola a todos!

Yo mismo no hago criptografía, pero mi pequeña investigación puede ser muy útil. Decidí ocuparme de las funciones de procesador integradas RDRAND y RDSEED. El compilador de Delphi dijo un identificador no declarado. Hmm BMI, BMI2, AVX, AVX2 e incluso AVX-512 han existido durante mucho tiempo, y Delphians se decidió por SSE4.2. No importa Compilamos el código nosotros mismos.

Primero hice una verificación para el soporte de estas funciones por parte del procesador. Por supuesto, CPUID. Puede usar CPUID comenzando con los primeros procesadores Pentium. Espero que nadie piense en ejecutar CPUID en una máquina 486, porque todavía no ha estado allí. Por cierto, RDRAND y RDSEED antes de los procesadores IvyBridge tampoco existen.

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; 

Resultó que mi Core i7 G6950X Extreme es compatible con estas características. Entonces decidí compilar el bytecode manualmente. Para los experimentados le daré los prefijos de código REX y REX.W. Es posible que desee escribir el resultado en un 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) 

Las funciones pueden funcionar tanto en modo de 32 bits como en modo de 64 bits. Por lo tanto, hice ambas cosas, e incluso en dos versiones. El resultado son 4 funciones:

 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; 

Son más lentos en velocidad que la función de biblioteca Random. RDRand es aproximadamente del 35% y RDSeed es del 50% o más, pero la calidad de la unicidad de los valores generados es mucho mayor. Hay algunos buenos artículos sobre este tema en este recurso, pero mi misión (hacer que las funciones estén disponibles en Delphi) se ha completado. No lo probé en Lazarus, pero lo más probable es que funcione sin ningún cambio. Al final de la declaración de función, solo necesita agregar el ensamblador de palabras de respaldo.

Aquí está el código fuente de la aplicación de consola de prueba. Allí puede encontrar un prototipo de las funciones Random32 y Random64 basadas en el procesador incorporado. Quizás esto es lo que estabas buscando. ¡Adiós a todos!

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


All Articles