//https://redd.it/8rx5zi
using System;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
namespace SHAPrefix
{
class Program
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int memcmp(byte[] b1, byte[] b2, int count);
private struct ThreadConfig
{
public byte[] Prefix;
}
private static volatile bool Cont = true;
private static long Hashes = 0;
private static object Lockable = new object();
private static byte[] FoundKey;
private static byte[] FoundHash;
static void Main(string[] args)
{
Console.Error.Write("Enter prefix as hexadecimal number [0-9,A-F]: ");
var Input = Console.ReadLine();
if (Input.Length % 2 == 0)
{
byte[] Prefix = new byte[Input.Length / 2];
for (var i = 0; i < Prefix.Length; i++)
{
Cont &= byte.TryParse(Input.Substring(i * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out Prefix[i]);
}
if (Cont)
{
if (Prefix.Length > 0 && Prefix.Length < 33)
{
Thread[] TList = new Thread[1/*Environment.ProcessorCount*/];
for (var i = 0; i < TList.Length; i++)
{
var T = new Thread(FindPrefix);
T.IsBackground = true;
T.Priority = ThreadPriority.BelowNormal;
T.Name = $"Hash Finder #{i + 1}";
TList[i] = T;
T.Start(new ThreadConfig() { Prefix = Prefix });
Console.Error.WriteLine("Started {0}", T.Name);
}
while (Cont)
{
if (TList.Any(m => !m.IsAlive))
{
Cont = false;
}
else
{
lock (Lockable)
{
Console.SetCursorPosition(0, TList.Length + 1);
Console.Error.WriteLine("Hashes generated so far: {0}", Hashes);
}
Thread.Sleep(500);
}
}
foreach (var T in TList)
{
T.Join();
}
if (FoundKey != null && FoundHash != null)
{
Console.Clear();
Console.WriteLine("Key : {0}", Encoding.ASCII.GetString(FoundKey));
Console.WriteLine("Prefix: {0}", BitConverter.ToString(Prefix).Replace("-", ""));
Console.WriteLine("Hash : {0}", BitConverter.ToString(FoundHash).Replace("-", ""));
Console.WriteLine("Check : {0}", Validate(FoundKey, FoundHash));
}
Console.Error.WriteLine("Process ended");
}
else
{
Console.Error.WriteLine("Prefix length is invalid");
}
}
else
{
Console.Error.WriteLine("Invalid hexadecimal number");
}
}
else
{
Console.Error.WriteLine("Invalid Prefix. Hexadecimal numbers have an even number of digits");
}
Console.ReadKey(true);
}
static bool Validate(byte[] Key, byte[] Hash)
{
using (var Gen = HashAlgorithm.Create("SHA256"))
{
return Hash != null && Hash.Length == 32 && memcmp(Gen.ComputeHash(Key), Hash, Hash.Length) == 0;
}
}
static void FindPrefix(object o)
{
var RND = new byte[20];
int StepSize = Environment.ProcessorCount;
var Config = (ThreadConfig)o;
var Hash = new byte[32];
using (var RNG = RandomNumberGenerator.Create())
{
RNG.GetBytes(RND);
for (var i = 0; i < RND.Length; i += 2)
{
var S = RND[i].ToString("X2");
RND[i] = (byte)S[0];
RND[i + 1] = (byte)S[1];
}
}
using (var Gen = HashAlgorithm.Create("SHA256"))
{
while (Cont)
{
Hash = Gen.ComputeHash(RND);
++Hashes;
if (memcmp(Hash, Config.Prefix, Config.Prefix.Length) != 0)
{
for (int i = 19; i >= 0; --i)
{
++RND[i];
//Roll over Hexadecimal number
if (RND[i] == 0x47 /*G*/)
{
RND[i] = 0x30 /*0*/;
}
else
{
//Skip ASCII Gap between digits and letters
if (RND[i] == 0x3A /*:*/)
{
RND[i] = 0x41 /*A*/;
}
//Stop incrementing this number
break;
}
}
}
else
{
break;
}
}
if (memcmp(Hash, Config.Prefix, Config.Prefix.Length) == 0)
{
FoundKey = RND;
FoundHash = Hash;
}
}
}
}
}
Comments
0 B
|👍
/👎