1 module dcrypt.random.fortuna.sources.systemtick; 2 3 import core.time; 4 5 6 import dcrypt.random.fortuna.entropysource; 7 import dcrypt.random.fortuna.fortuna: addEntropy; 8 9 /// Generate entropy data with the system clock. 10 @safe 11 public class SystemTickEntropySource: EntropySource 12 { 13 14 override void collectEntropy() nothrow { 15 ubyte[64] buf; 16 17 getTimingEntropy(buf); 18 19 sendEntropyEvent(buf); 20 } 21 22 @nogc @property nothrow 23 override public string name() { 24 return "SystemTickSource"; 25 } 26 27 @safe @nogc nothrow 28 override uint scheduleNext() { 29 return 250; 30 } 31 32 } 33 34 /// Fill the buffer with timing measurements. 35 /// Params: 36 /// buf = The buffer to fill. 37 @safe @nogc nothrow 38 static void getTimingEntropy(ubyte[] buf) { 39 foreach(ref b; buf) { 40 ulong ticks = MonoTime.currTime.ticks; 41 b = cast(ubyte) (ticks^(ticks>>8)^(ticks>>16)); // Combine three bytes for the case if the system clock has low resolution. 42 } 43 } 44 45 unittest { 46 ubyte[32] buf1, buf2; 47 48 getTimingEntropy(buf1); 49 getTimingEntropy(buf2); 50 51 assert(buf1 != buf2, "Measurements are not at all random!"); 52 }