Using PC Data Creates a Strong Entropy Source
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Threading; public class EntropySource { private const int Sha3BitSize = 256; private const int Sha3BitBufferMoveSize = Sha3BitSize >> 3; private const int CpuDataLength = 256; private const int JitterDataSize = 256; [DllImport("kernel32.dll")] private static extern int GetTickCount(); [DllImport("kernel32.dll")] internal static extern bool QueryPerformanceCounter(out long lpPerformanceCount); [DllImport("kernel32.dll")] internal static extern bool QueryPerformanceFrequency(out long lpFrequency); public static byte[] GetBuffer(int bufferSize) { var rhb = new byte[0]; var rho = new byte[bufferSize]; var EntropyThread = new Thread(() => { var el = new List<string>(); var hashBytes = new HashSet<byte[]>(new ArrayComparer()); var sw = new Stopwatch(); sw.Start(); AddLocalUserData(hashBytes); AddProcessInformation(hashBytes, el); AddJitterInformation(hashBytes); GetWmiInfor("Win32_PerfRawData_PerfOS_Processor", hashBytes); GetWmiInfor("Win32_PerfRawData_PerfOS_System", hashBytes); GetWmiInfor("Win32_PerfRawData_Counters_ProcessorInformation", hashBytes); GetWmiInfor("Win32_PerfRawData_Counters_Synchronization", hashBytes); GetWmiInfor("Win32_PerfRawData_PerfDisk_LogicalDisk", hashBytes); GetWmiInfor("Win32_PerfRawData_PerfDisk_PhysicalDisk", hashBytes); GetWmiInfor("Win32_PerfFormattedData_PerfOS_Cache", hashBytes); GetWmiInfor("Win32_PerfFormattedData_PerfOS_Memory", hashBytes); GetWmiInfor("Win32_PerfFormattedData_PerfOS_Objects", hashBytes); CpuInfo(hashBytes); sw.Stop(); hashBytes.Add(sw.Elapsed.Ticks.GetBytes()); rhb = HashBytesToArray(hashBytes); AddHistogramInforamation(rhb, hashBytes); rhb = HashBytesToArray(hashBytes); hashBytes.Clear(); var div = bufferSize / Sha3BitBufferMoveSize; if (div * Sha3BitBufferMoveSize < bufferSize) div++; var segSize = rhb.Length / div; var aseg = new byte[segSize]; for (var i = 0; i < div; ++i) { Buffer.BlockCopy(rhb, i * segSize, aseg, 0, segSize); Buffer.BlockCopy(new SHA3Managed(Sha3BitSize).ComputeHash(aseg), 0, rho, i * Sha3BitBufferMoveSize, Sha3BitBufferMoveSize); } }) {Priority = ThreadPriority.Highest}; EntropyThread.Start(); EntropyThread.Join(); return rho; } private static void GetWmiInfor(string key, HashSet<byte[]> hashBytes) { var wmi = new WMIServices(); wmi.GetProperties(key); foreach (var v in wmi.EntriesList) foreach (var p in v.Value) hashBytes.Add(p.GetBytesObject()); } private static void CpuInfo(HashSet<byte[]> hashBytes) { var lhashBytes = new HashSet<byte[]>(); var dump = CpuTotalPc.CPULoad; do { var l = (byte) CpuTotalPc.CPULoad; if (l != 0) lhashBytes.Add(new[] {l}); Thread.Sleep(1); } while (lhashBytes.Count < CpuDataLength); foreach (var b in lhashBytes) hashBytes.Add(b); } private static void AddHistogramInforamation(byte[] rhb, HashSet<byte[]> hashBytes) { var FFTArray = Histogram(rhb); for (var i = 0; i < FFTArray.Length; ++i) hashBytes.Add(FFTArray[i].GetBytes()); } private static void AddJitterInformation(HashSet<byte[]> hashBytes) { hashBytes.Add(new JitterEx(JitterDataSize).GetBuffer()); } private static void AddProcessInformation(HashSet<byte[]> hashBytes, List<string> el) { foreach (var p in Process.GetProcesses()) { try { hashBytes.Add(p.Id.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.Id.GetBytes())"); } try { hashBytes.Add(p.HandleCount.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.HandleCount.GetBytes())"); } try { hashBytes.Add(p.NonpagedSystemMemorySize64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.NonpagedSystemMemorySize64.GetBytes())"); } try { hashBytes.Add(p.PagedMemorySize64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.PagedMemorySize64.GetBytes())"); } try { hashBytes.Add(p.PagedSystemMemorySize64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.PagedSystemMemorySize64.GetBytes())"); } try { hashBytes.Add(p.PeakPagedMemorySize64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.PeakPagedMemorySize64.GetBytes())"); } try { hashBytes.Add(p.PeakVirtualMemorySize64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.PeakVirtualMemorySize64.GetBytes())"); } try { hashBytes.Add(p.PeakWorkingSet64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.PeakWorkingSet64.GetBytes()"); } try { hashBytes.Add(p.PrivateMemorySize64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.PrivateMemorySize64.GetBytes())"); } try { hashBytes.Add(p.ProcessName.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.ProcessName.GetBytes())"); } try { hashBytes.Add(p.Threads.Count.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.Threads.Count.GetBytes())"); } try { hashBytes.Add(p.SessionId.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.SessionId.GetBytes())"); } for (var i = 0; i < p.Threads.Count; i++) { try { hashBytes.Add(p.Threads[i].CurrentPriority.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.Threads[i].CurrentPriority.GetBytes())"); } try { hashBytes.Add(p.Threads[i].Id.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.Threads[i].Id.GetBytes())"); } try { hashBytes.Add(p.Threads[i].StartAddress.ToString().GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.Threads[i].StartAddress.ToString().GetBytes())"); } } try { hashBytes.Add(p.VirtualMemorySize64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.VirtualMemorySize64.GetBytes()))"); } try { hashBytes.Add(p.WorkingSet64.GetBytes()); } catch (Exception ex) { el.Add($"{ex.Message} hashBytes.Add(p.WorkingSet64.GetBytes()))"); } } } private static void AddLocalUserData(HashSet<byte[]> hashBytes) { hashBytes.Add(Process.GetCurrentProcess().Id.GetBytes()); hashBytes.Add(Thread.CurrentThread.ManagedThreadId.GetBytes()); hashBytes.Add(GetTickCount().GetBytes()); hashBytes.Add(Process.GetProcesses().Length.GetBytes()); QueryPerformanceFrequency(out var freq); hashBytes.Add(freq.GetBytes()); for (var i = 0; i < 128; i++) { QueryPerformanceCounter(out var query); hashBytes.Add(query.GetBytes()); } hashBytes.Add(DateTime.Now.Ticks.GetBytes()); hashBytes.Add(Environment.UserName.GetBytes()); hashBytes.Add(Environment.MachineName.GetBytes()); hashBytes.Add(Environment.OSVersion.ToString().GetBytes()); hashBytes.Add(Environment.ProcessorCount.GetBytes()); hashBytes.Add(Environment.UserDomainName.GetBytes()); hashBytes.Add(Environment.StackTrace.GetBytes()); hashBytes.Add(Environment.GetLogicalDrives().GetBytes()); hashBytes.Add(MemoryInfo.GetValues().GetBytesObjectSerial()); hashBytes.Add(MemoryInfo.GetSystemPerformanceInformation().GetBytesObjectSerial()); } private static byte[] HashBytesToArray(HashSet<byte[]> hashBytes) { byte[] rhb; var ptr = 0; var count = 0; var arr = hashBytes.ToArray(); foreach (var hba in arr) count += hba.Length; hashBytes.Add(count.GetBytes()); arr = hashBytes.ToArray(); count += arr.Last().Length; rhb = new byte[count]; foreach (var hba in arr) { Buffer.BlockCopy(hba, 0, rhb, ptr, hba.Length); ptr += hba.Length; } return rhb; } private static int[] Histogram(IEnumerable<byte> ba) { var map = new int[256]; foreach (var i in ba) map[i]++; return map; } }