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