Last active
May 11, 2020 20:38
-
-
Save neolit123/a23fbccba2298fe4bf939fc64e514812 to your computer and use it in GitHub Desktop.
compare-RtlGenRando-BCryptGenRandom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// performance comparison between RtlGenRandom and BCryptGenRandom | |
// with BCRYPT_USE_SYSTEM_PREFERRED_RNG. | |
// | |
// gcc -O3 -std=c99 -Wall test.c -lbcrypt && a | |
#include <windows.h> | |
#include <stdio.h> | |
#include <bcrypt.h> | |
BOOLEAN(APIENTRY *RtlGenRandom) | |
(void *, ULONG); | |
HANDLE BCryptoProvider = NULL; | |
DOUBLE GetTime() | |
{ | |
LARGE_INTEGER t, f; | |
QueryPerformanceCounter(&t); | |
QueryPerformanceFrequency(&f); | |
return (DOUBLE) t.QuadPart / (DOUBLE) f.QuadPart; | |
} | |
int PrepareRtlGenRandom() | |
{ | |
LoadLibrary("advapi32.dll"); | |
HMODULE advapi = GetModuleHandle("advapi32.dll"); | |
if (!advapi) { | |
puts("advapi32 load error"); | |
return 1; | |
} | |
RtlGenRandom = (BOOLEAN(APIENTRY*)(void *, ULONG)) GetProcAddress(advapi, "SystemFunction036"); | |
if (!RtlGenRandom) { | |
puts("RtlGenRandom proc error"); | |
return 1; | |
} | |
return 0; | |
} | |
int RunSingleTest(PBYTE Buffer, DWORD BufferSize, DWORD TestIterations) | |
{ | |
DOUBLE StartTime; | |
printf("\nBufferSize: %lu\n", BufferSize); | |
// test BCryptGenRandom | |
StartTime = GetTime(); | |
for (int i = 0; i < TestIterations; i++) { | |
if (BCryptGenRandom( | |
BCryptoProvider, | |
Buffer, | |
BufferSize, | |
0)) { // BCRYPT_USE_SYSTEM_PREFERRED_RNG | |
puts("BCryptGenRandom failed"); | |
return 1; | |
} | |
} | |
printf("BCryptGenRandom: %fs\n", GetTime() - StartTime); | |
// ------------------------------------------------------------------------- | |
// test RtlGenRandom | |
StartTime = GetTime(); | |
for (int i = 0; i < TestIterations; i++) { | |
if (!RtlGenRandom(Buffer, BufferSize)) { | |
puts("RtlGenRandom failed"); | |
return 1; | |
} | |
} | |
printf("RtlGenRandom: %fs\n", GetTime() - StartTime); | |
return 0; | |
} | |
int main(void) | |
{ | |
const DWORD TestIterations = 100000; | |
BYTE Buffer[16384]; | |
DWORD MaxBufferSize = sizeof(Buffer); | |
memset(Buffer, 0, MaxBufferSize); | |
// ------------------------------------------------------------------------- | |
// verify the timer | |
DOUBLE StartTime = GetTime(); | |
Sleep(1000); | |
printf("Veryfing timer precision; result should be close to 1.0, got %f\n", GetTime() - StartTime); | |
// ------------------------------------------------------------------------- | |
// prepare RtlGenRandom | |
if (PrepareRtlGenRandom()) { | |
return 1; | |
} | |
// ------------------------------------------------------------------------- | |
// prepare BCryptGenRandom | |
if (BCryptOpenAlgorithmProvider( | |
&BCryptoProvider, | |
BCRYPT_RNG_ALGORITHM, | |
NULL, | |
0)) { | |
puts("BCryptOpenAlgorithmProvider failed"); | |
return 1; | |
} | |
// ------------------------------------------------------------------------- | |
// test various buffer sizes | |
printf("TestIterations: %lu\n", TestIterations); | |
for (DWORD BufferSize = 1; BufferSize <= MaxBufferSize; BufferSize *= 2) { | |
if (RunSingleTest(Buffer, BufferSize, TestIterations)) { | |
return 1; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Veryfing timer precision; result should be close to 1.0, got 0.999352 | |
TestIterations: 100000 | |
BufferSize: 1 | |
BCryptGenRandom: 0.097258s | |
RtlGenRandom: 0.100814s | |
BufferSize: 2 | |
BCryptGenRandom: 0.095720s | |
RtlGenRandom: 0.100624s | |
BufferSize: 4 | |
BCryptGenRandom: 0.095737s | |
RtlGenRandom: 0.100634s | |
BufferSize: 8 | |
BCryptGenRandom: 0.095641s | |
RtlGenRandom: 0.100441s | |
BufferSize: 16 | |
BCryptGenRandom: 0.095755s | |
RtlGenRandom: 0.100434s | |
BufferSize: 32 | |
BCryptGenRandom: 0.108264s | |
RtlGenRandom: 0.113315s | |
BufferSize: 64 | |
BCryptGenRandom: 0.133766s | |
RtlGenRandom: 0.139911s | |
BufferSize: 128 | |
BCryptGenRandom: 0.183334s | |
RtlGenRandom: 0.190524s | |
BufferSize: 256 | |
BCryptGenRandom: 0.284192s | |
RtlGenRandom: 0.292344s | |
BufferSize: 512 | |
BCryptGenRandom: 0.482821s | |
RtlGenRandom: 0.495196s | |
BufferSize: 1024 | |
BCryptGenRandom: 0.879791s | |
RtlGenRandom: 0.902300s | |
BufferSize: 2048 | |
BCryptGenRandom: 1.673630s | |
RtlGenRandom: 1.714524s | |
BufferSize: 4096 | |
BCryptGenRandom: 3.260548s | |
RtlGenRandom: 3.340992s | |
BufferSize: 8192 | |
BCryptGenRandom: 6.437690s | |
RtlGenRandom: 6.626667s | |
BufferSize: 16384 | |
BCryptGenRandom: 12.841288s | |
RtlGenRandom: 13.214990s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment