Skip to content

Instantly share code, notes, and snippets.

@neolit123
Last active May 11, 2020 20:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neolit123/a23fbccba2298fe4bf939fc64e514812 to your computer and use it in GitHub Desktop.
Save neolit123/a23fbccba2298fe4bf939fc64e514812 to your computer and use it in GitHub Desktop.
compare-RtlGenRando-BCryptGenRandom
// 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;
}
}
}
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