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;
}
}