Did I implement clock drift properly?
- by David Titarenco
I couldn't find any clock drift RNG code for Windows anywhere so I attempted to implement it myself. I haven't run the numbers through ent or DIEHARD yet, and I'm just wondering if this is even remotely correct...
void QueryRDTSC(__int64* tick) {
__asm {
xor eax, eax
cpuid
rdtsc
mov edi, dword ptr tick
mov dword ptr [edi], eax
mov dword ptr [edi+4], edx
}
}
__int64 clockDriftRNG() {
__int64 CPU_start, CPU_end, OS_start, OS_end;
// get CPU ticks -- uses RDTSC on the Processor
QueryRDTSC(&CPU_start);
Sleep(1);
QueryRDTSC(&CPU_end);
// get OS ticks -- uses the Motherboard clock
QueryPerformanceCounter((LARGE_INTEGER*)&OS_start);
Sleep(1);
QueryPerformanceCounter((LARGE_INTEGER*)&OS_end);
// CPU clock is ~1000x faster than mobo clock
// return raw
return ((CPU_end - CPU_start)/(OS_end - OS_start));
// or
// return a random number from 0 to 9
// return ((CPU_end - CPU_start)/(OS_end - OS_start)%10);
}
If you're wondering why I Sleep(1), it's because if I don't, OS_end - OS_start returns 0 consistently (because of the bad timer resolution, I presume).
Basically, (CPU_end - CPU_start)/(OS_end - OS_start) always returns around 1000 with a slight variation based on the entropy of CPU load, maybe temperature, quartz crystal vibration imperfections, etc.
Anyway, the numbers have a pretty decent distribution, but this could be totally wrong. I have no idea.