Created
March 4, 2019 15:22
-
-
Save mjs3339/bc538e78821671ee0e983190ee7fdbfb to your computer and use it in GitHub Desktop.
C# CryptoEntropySourceExperimental
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define TESTING | |
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
using System.Security.Cryptography; | |
using System.Threading; | |
public class CryptoEntropySourceExperimental | |
{ | |
public static byte[] Entropy => GetEntropy(); | |
public static double EntropyLevel{get; private set;} | |
~CryptoEntropySourceExperimental() | |
{ | |
GC.SuppressFinalize(this); | |
} | |
[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); | |
private static byte[] GetEntropy() | |
{ | |
var rhb = new byte[0]; | |
var EntropyThread = new Thread(() => | |
{ | |
var el = new List<string>(); | |
var hashBytes = new TinySet<byte[]>(new ArrayComparer()); | |
var sw = new Stopwatch(); | |
sw.Start(); | |
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); | |
QueryPerformanceCounter(out var query); | |
hashBytes.Add(freq.GetBytes()); | |
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()); | |
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.MainWindowTitle.GetBytes()); | |
} | |
catch(Exception ex) | |
{ | |
el.Add($"{ex.Message} hashBytes.Add(p.MainWindowTitle.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()))"); | |
} | |
} | |
var csb = new JitterEntropySource(); | |
hashBytes.Add(csb.SeedBuffer); | |
sw.Stop(); | |
hashBytes.Add(sw.Elapsed.Ticks.GetBytes()); | |
var ptr = 0; | |
var count = 0; | |
foreach(var hba in hashBytes.Items) | |
count += hba.Length; | |
hashBytes.Add(count.GetBytes()); | |
count += hashBytes.Items.Last().Length; | |
rhb = new byte[count]; | |
foreach(var hba in hashBytes.Items) | |
{ | |
Buffer.BlockCopy(hba, 0, rhb, ptr, hba.Length); | |
ptr += hba.Length; | |
} | |
EntropyLevel = GetEntropyLevel(rhb); | |
}) | |
{Priority = ThreadPriority.Highest}; | |
EntropyThread.Start(); | |
EntropyThread.Join(); | |
var rvh = new SHA512CryptoServiceProvider().ComputeHash(rhb); | |
#if TESTING | |
SetsTesting.TestArrayDuplication("EntropySourceList", rvh); | |
#endif | |
return rvh; | |
} | |
private static double GetEntropyLevel(byte[] ba) | |
{ | |
var map = new int[256]; | |
foreach(var i in ba) | |
map[i]++; | |
var lot = Math.Log(2); | |
return(from item in map | |
where item > 0 | |
select item / (double) ba.Length).Aggregate(0.0, (current, frequency) => current - frequency * (Math.Log(frequency) / lot)); | |
} | |
private static unsafe bool Compare(byte[] a1, byte[] a2) | |
{ | |
if(a1 == null && a2 == null) | |
return true; | |
if(a1 == null || a2 == null || a1.Length != a2.Length) | |
return false; | |
fixed(byte* p1 = a1, p2 = a2) | |
{ | |
var Len = a1.Length; | |
byte* x1 = p1, x2 = p2; | |
while(Len > 7) | |
{ | |
if(*(long*) x2 != *(long*) x1) | |
return false; | |
x1 += 8; | |
x2 += 8; | |
Len -= 8; | |
} | |
switch(Len % 8) | |
{ | |
case 0: | |
break; | |
case 7: | |
if(*(int*) x2 != *(int*) x1) | |
return false; | |
x1 += 4; | |
x2 += 4; | |
if(*(short*) x2 != *(short*) x1) | |
return false; | |
x1 += 2; | |
x2 += 2; | |
if(*x2 != *x1) | |
return false; | |
break; | |
case 6: | |
if(*(int*) x2 != *(int*) x1) | |
return false; | |
x1 += 4; | |
x2 += 4; | |
if(*(short*) x2 != *(short*) x1) | |
return false; | |
break; | |
case 5: | |
if(*(int*) x2 != *(int*) x1) | |
return false; | |
x1 += 4; | |
x2 += 4; | |
if(*x2 != *x1) | |
return false; | |
break; | |
case 4: | |
if(*(int*) x2 != *(int*) x1) | |
return false; | |
break; | |
case 3: | |
if(*(short*) x2 != *(short*) x1) | |
return false; | |
x1 += 2; | |
x2 += 2; | |
if(*x2 != *x1) | |
return false; | |
break; | |
case 2: | |
if(*(short*) x2 != *(short*) x1) | |
return false; | |
break; | |
case 1: | |
if(*x2 != *x1) | |
return false; | |
break; | |
} | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment