diff --git a/BitcoinExprCracker.sln b/BitcoinExprCracker.sln
new file mode 100644
index 0000000..ff2fe94
--- /dev/null
+++ b/BitcoinExprCracker.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.902
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitcoinExprCracker", "BitcoinExprCracker\BitcoinExprCracker.csproj", "{EFA130F7-552B-46D9-8558-B8C6DEFB5F54}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EFA130F7-552B-46D9-8558-B8C6DEFB5F54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EFA130F7-552B-46D9-8558-B8C6DEFB5F54}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EFA130F7-552B-46D9-8558-B8C6DEFB5F54}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EFA130F7-552B-46D9-8558-B8C6DEFB5F54}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A9088E96-7B3F-4F0E-B420-60E5B6323DB5}
+ EndGlobalSection
+EndGlobal
diff --git a/BitcoinExprCracker/App.config b/BitcoinExprCracker/App.config
new file mode 100644
index 0000000..88fa402
--- /dev/null
+++ b/BitcoinExprCracker/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BitcoinExprCracker/BitcoinExprCracker.csproj b/BitcoinExprCracker/BitcoinExprCracker.csproj
new file mode 100644
index 0000000..056ed91
--- /dev/null
+++ b/BitcoinExprCracker/BitcoinExprCracker.csproj
@@ -0,0 +1,74 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {EFA130F7-552B-46D9-8558-B8C6DEFB5F54}
+ Exe
+ BitcoinExprCracker
+ BitcoinExprCracker
+ v4.5.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\BigInteger.1.0.7\lib\net20\BigInteger.dll
+
+
+ ..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll
+
+
+ ..\packages\NBitcoin.4.2.16\lib\net452\NBitcoin.dll
+
+
+ ..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+
+ ..\packages\System.Buffers.4.5.0\lib\netstandard1.1\System.Buffers.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BitcoinExprCracker/Generator/Estrutura.cs b/BitcoinExprCracker/Generator/Estrutura.cs
new file mode 100644
index 0000000..deb741e
--- /dev/null
+++ b/BitcoinExprCracker/Generator/Estrutura.cs
@@ -0,0 +1,35 @@
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
+namespace BitcoinExprCracker.Generator
+{
+ public struct Operação
+ {
+ public Variável A;
+ public Variável B;
+ public char Operador;
+ public byte Resultado;
+ }
+
+ public struct Variável
+ {
+ public byte Value; // Valor
+ public int Index; // Index em X ou Y
+ public char X_Y; // Se pertence a x ou Y
+
+ public override string ToString()
+ {
+ return Value.ToString();
+ }
+ }
+
+ public struct ParsedPubKey
+ {
+ public byte[] X;
+ public byte[] Y;
+ public ulong[] xU;
+ public ulong[] yU;
+ public byte[] PublicKey;
+ }
+}
\ No newline at end of file
diff --git a/BitcoinExprCracker/Generator/ExprGenerator.cs b/BitcoinExprCracker/Generator/ExprGenerator.cs
new file mode 100644
index 0000000..aaf69b0
--- /dev/null
+++ b/BitcoinExprCracker/Generator/ExprGenerator.cs
@@ -0,0 +1,400 @@
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace BitcoinExprCracker.Generator
+{
+ internal class ExprGenerator
+ {
+ ///
+ ///
+ ///
+ /// X[i]
+ /// Y[i]
+ ///
+ ///
+
+ public static int Generate(ref ulong Hash, ref ulong Seed, ref ulong limitDeOperações, ref byte[] X, ref byte[] Y, out string expression)
+ {
+ string stringOperation = string.Empty;
+ List Operações = new List();
+
+ ulong elementsAdded = 0;
+ ulong insideTry = 0;
+
+ for (ulong operações = 0; operações < limitDeOperações; operações++)
+ {
+ Operação op = new Operação();
+ char Operador = GetOperand(true, Seed, ref insideTry, ref elementsAdded);
+
+ stringOperation += "(";
+
+ op.A = GenerateVariável(Seed, ref insideTry, ref elementsAdded, ref X, ref Y);
+
+ if (Operador == Operands[6]) // ~ NOT
+ {
+ op.A.Value = (byte)((~op.A.Value) & 255);
+
+ stringOperation += Operador + VariáveltoExpression(op.A) + " ";
+ Operador = GetOperand(false, Seed, ref insideTry, ref elementsAdded);
+ }
+ else
+ stringOperation += VariáveltoExpression(op.A) + " ";
+
+ op.B = GenerateVariável(Seed, ref insideTry, ref elementsAdded, ref X, ref Y);
+
+ stringOperation += Operador + " " + VariáveltoExpression(op.B) + " ";
+
+ // op.Resultado = (byte)(operators[Operador](op.A.Value, op.B.Value) % 256);
+ op.Resultado = (byte)(CalcularOperação(Operador, new int[] { op.A.Value, op.B.Value }) % 256);
+ op.Operador = Operador;
+ Operações.Add(op);
+
+ stringOperation += ") ";
+
+ if (operações + 1 < limitDeOperações)
+ {
+ Operações.Add(new Operação() { Operador = GetOperand(false, Seed, ref insideTry, ref elementsAdded) });
+ stringOperation += Operações[Operações.Count - 1].Operador + " ";
+ }
+ }
+
+ // Agora calcular o resultado da expressão
+
+ int resultado = CalcularResultadoOperações(Operações);
+ expression = stringOperation;
+
+ return resultado;
+ }
+
+ public static int Calculate(byte[] pubkey, ref string expression)
+ {
+ byte[] compareX = new byte[32];
+ byte[] compareY = new byte[32];
+ Utils.ParseXYfromPub(pubkey, out compareX, out compareY);
+
+ return Calculate(compareX, compareY, ref expression);
+ }
+
+ public static int Calculate(ParsedPubKey pubkey, ref string expression)
+ {
+ return Calculate(pubkey.X, pubkey.Y, ref expression);
+ }
+
+ public static int Calculate(byte[] compareX, byte[] compareY, ref string expression)
+ {
+ List Operações = new List();
+ // Vars = new List();
+
+ StringReader Reader = new StringReader(expression.Replace(" ", ""));
+ bool B = false;
+
+ char c = (char)Reader.Peek();
+
+ while (Reader.Peek() != -1)
+ {
+ c = (char)Reader.Peek();
+
+ if (c == '(')
+ {
+ Operação op = new Operação(); // (~X[10] ^ ~Y[21] ) ^ (~Y[9] & ~X[24] )
+ Reader.Read();
+
+ VOLTA:
+
+ c = (char)Reader.Peek();
+
+ if (c == '~')
+ {
+ Reader.Read();
+
+ char Letra = (char)Reader.Peek();
+ Reader.Read(); // [
+ Reader.Read(); // index
+
+ string numero = string.Empty;
+ int index = 0;
+
+ while (char.IsNumber((char)Reader.Peek()))
+ {
+ numero += (char)Reader.Peek();
+ Reader.Read();
+ }
+ index = int.Parse(numero);
+
+ Reader.Read(); // ]
+
+ if (!B)
+ {
+ op.A = GetVariável(ref compareX, ref compareY, Letra, index, true);
+ // if(Vars != null)
+ // Vars.Add(op.A);
+ B = true;
+ goto VOLTA;
+ }
+ else // A já foi prenchido, agora B
+ {
+ op.B = GetVariável(ref compareX, ref compareY, Letra, index, true);
+ // if (Vars != null)
+ // Vars.Add(op.B);
+ }
+
+ Reader.Read(); // )
+
+ if (B)
+ {
+ Operações.Add(op);
+ // op.Resultado = (byte)(operators[op.Operador](op.A.Value, op.B.Value) % 256);
+ op.Resultado = (byte)(CalcularOperação(op.Operador, new int[] { op.A.Value, op.B.Value }) % 256);
+ B = false;
+ continue;
+ }
+ }
+ else if (IsOperand(c))
+ {
+ op.Operador = c;
+ Reader.Read();
+ goto VOLTA;
+ }
+ else
+ {
+ char Letra = (char)Reader.Peek();
+ Reader.Read(); // [
+ Reader.Read(); // index
+
+ string numero = string.Empty;
+ int index = 0;
+
+ while (char.IsNumber((char)Reader.Peek()))
+ {
+ numero += (char)Reader.Peek();
+ Reader.Read();
+ }
+
+ index = int.Parse(numero);
+
+ Reader.Read(); // ]
+
+ if (!B)
+ {
+ op.A = GetVariável(ref compareX, ref compareY, Letra, index);
+ // if (Vars != null)
+ // Vars.Add(op.A);
+ B = true;
+ goto VOLTA; ;
+ }
+ else // A já foi prenchido, agora B
+ {
+ op.B = GetVariável(ref compareX, ref compareY, Letra, index);
+ // if (Vars != null)
+ // Vars.Add(op.B);
+ }
+
+ Reader.Read(); // )
+
+ if (B)
+ {
+ //op.Resultado = (byte)(operators[op.Operador](op.A.Value, op.B.Value) % 256);
+ op.Resultado = (byte)(CalcularOperação(op.Operador, new int[] { op.A.Value, op.B.Value }) % 256);
+ Operações.Add(op);
+ B = false;
+ continue;
+ }
+ }
+ }
+ else if (IsOperand(c))
+ {
+ Operações.Add(new Operação() { Operador = c });
+ Reader.Read(); // (
+ }
+ }
+
+ return CalcularResultadoOperações(Operações);
+ }
+
+ private static int CalcularResultadoOperações(List Operações)
+ {
+ // Agora calcular o resultado da expressão
+
+ aindaHáOperações:
+ List temp = new List();
+
+ for (int i = 0; i < Operações.Count; i++)
+ {
+ Operação a = Operações[i];
+ i++;
+ char operador = Operações[i].Operador;
+ i++;
+ Operação b = Operações[i];
+
+ Operação resultado = new Operação();
+ // resultado.Resultado = (byte)(operators[operador](a.Resultado, b.Resultado) % 256);
+ resultado.Resultado = (byte)(CalcularOperação(operador, new int[] { a.Resultado, b.Resultado }) % 256);
+ temp.Add(resultado);
+
+ if (i == Operações.Count - 1)
+ break;
+ i++;
+ temp.Add(Operações[i]);
+ }
+
+ if (temp.Count != 1)
+ {
+ Operações = temp;
+ goto aindaHáOperações;
+ }
+
+ return (byte)temp[0].Resultado;
+ }
+
+ private static Variável GetVariável(ref byte[] x, ref byte[] y, char x_y, int index, bool NOT = false)
+ {
+ Variável v = new Variável();
+ if (x_y == 'X')
+ {
+ if (!NOT)
+ v.Value = x[index];
+ else
+ v.Value = (byte)((~x[index]) & 255);
+ }
+ else // 'Y'
+ {
+ if (!NOT)
+ v.Value = y[index];
+ else
+ v.Value = (byte)((~y[index]) & 255);
+ }
+
+ v.X_Y = x_y;
+ v.Index = index;
+ return v;
+ }
+
+ private static readonly char[] Operands = { '+', '-', '*', '%', '&', '|', '~', '^' };
+
+ private static bool IsOperand(char c)
+ {
+ if (Operands[0] == c || Operands[1] == c || Operands[2] == c || Operands[3] == c || Operands[4] == c ||
+ Operands[5] == c || Operands[6] == c || Operands[7] == c)
+ return true;
+
+ return false;
+ }
+
+ private static int CalcularOperação(char op, int[] values)
+ {
+ switch (op)
+ {
+ case '+':
+ return values[0] + values[1];
+
+ case '-':
+ return values[0] - values[1];
+
+ case '*':
+ return values[0] * values[1];
+
+ case '%':
+ if (values[0] == 0)
+ {
+ if (values[1] != 0)
+ return values[1];
+ else
+ return 0;
+ }
+ else if (values[1] == 0)
+ {
+ return 0;
+ }
+ else
+ return values[0] % values[1];
+
+ case '&':
+ return values[0] & values[1];
+
+ case '|':
+ return values[0] | values[1];
+
+ case '~':
+ return ~values[0];
+
+ case '^':
+ return values[0] ^ values[1];
+
+ default:
+ throw new Exception();
+ }
+ }
+
+ private static string VariáveltoExpression(Variável v)
+ {
+ string ret = v.X_Y + "[" + v.Index + "]";
+ return ret;
+ }
+
+ public static ulong Hash(byte[] bytes)
+ {
+ ulong x = 1;
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ x ^= bytes[i];
+ x ^= x * (x >> 3);
+ x += (x >> 3) ^ (x << 1);
+ }
+ return x;
+ }
+
+ private static Variável GenerateVariável(ulong seed, ref ulong insideTry, ref ulong elementsAdded, ref byte[] X, ref byte[] Y)
+ {
+ Variável variável = new Variável();
+ byte[] indexSeed = BitConverter.GetBytes(seed + insideTry + elementsAdded);
+ Array.Reverse(indexSeed);
+
+ int Index = (int)(Hash(indexSeed) % 32);
+ ulong X_Y = ((ulong)Index + insideTry) % 2;
+
+ if (X_Y == 0)
+ {
+ variável.Index = Index;
+ variável.Value = X[Index];
+ variável.X_Y = 'X';
+ }
+ else // X_Y == 1
+ {
+ variável.Index = Index;
+ variável.Value = Y[Index];
+ variável.X_Y = 'Y';
+ }
+
+ elementsAdded++;
+ return variável;
+ }
+
+ public static char GetOperand(bool podeNot, ulong seed, ref ulong insideTry, ref ulong elementsAdded)
+ {
+ volta:
+ byte[] indexSeed = BitConverter.GetBytes(seed + insideTry + elementsAdded);
+ Array.Reverse(indexSeed);
+ int result = (int)(Hash(indexSeed) % 8);
+
+ if (!podeNot && result == 6)
+ {
+ insideTry += 1;
+ goto volta;
+ }
+ elementsAdded++;
+
+ return Operands[result];
+ }
+ }
+}
+
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
diff --git a/BitcoinExprCracker/Generator/GeneratorMethods.cs b/BitcoinExprCracker/Generator/GeneratorMethods.cs
new file mode 100644
index 0000000..ee28885
--- /dev/null
+++ b/BitcoinExprCracker/Generator/GeneratorMethods.cs
@@ -0,0 +1,96 @@
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
+
+using NBitcoin;
+using System;
+
+namespace BitcoinExprCracker.Generator
+{
+ class GeneratorMethods
+ {
+
+ public static byte[] ConvertTryesToPrivateKey(byte[] publicKey, ulong[] tryes)
+ {
+ ulong UintMax = 4294967296;
+ ParsedPubKey pubKey = Utils.ParseXYfromPub(publicKey, true);
+ byte[] prv = new byte[32];
+
+ for (int indexPrv = 0; indexPrv < 32; indexPrv++)
+ {
+ ulong targetX = pubKey.xU[Utils.GetPubUIndex(indexPrv)];
+ ulong targetY = pubKey.yU[Utils.GetPubUIndex(indexPrv)];
+ ulong Mult = targetX * targetY;
+ ulong SeedSum = (ulong)((new BigInteger(pubKey.X) % UintMax).LongValue() + (new BigInteger(pubKey.Y) % UintMax).LongValue());
+
+ ulong Try = tryes[indexPrv];
+
+ ulong Hash = Try + (Mult * ((ulong)indexPrv + Try)) % UintMax;
+ ulong limitDeOperações = (uint)Math.Pow(2d, (double)(Hash % 2) + 1d);
+ ulong SeedC = Try + Mult;
+ ulong Seed = ((Hash + SeedSum + SeedC) + Try) % UintMax;
+
+ string Expr = string.Empty;
+ byte result = (byte)ExprGenerator.Generate(ref Hash, ref Seed, ref limitDeOperações, ref pubKey.X, ref pubKey.Y, out Expr);
+
+ prv[indexPrv] = result;
+ }
+
+ return prv;
+ }
+
+ public static ulong[] GetPubKeyCorrectTryes(Key key, int limitPrvIndex = 32, bool PrintCorrectExpr = false)
+ {
+ ulong UintMax = 4294967296;
+ ParsedPubKey pubKey = Utils.ParseXYfromPub(key.PubKey.Decompress().ToBytes(), true);
+ byte[] prv = key.ToBytes();
+ ulong[] CorrectTryes = new ulong[32];
+
+ for (int indexPrv = 0; indexPrv < limitPrvIndex; indexPrv++)
+ {
+ ulong targetX = pubKey.xU[Utils.GetPubUIndex(indexPrv)];
+ ulong targetY = pubKey.yU[Utils.GetPubUIndex(indexPrv)];
+ ulong Mult = targetX * targetY;
+ ulong SeedSum = (ulong)((new BigInteger(pubKey.X) % UintMax).LongValue() + (new BigInteger(pubKey.Y) % UintMax).LongValue());
+
+ for (ulong Try = 0; Try < ulong.MaxValue; Try++)
+ {
+ ulong Hash = Try + (Mult * ((ulong)indexPrv + Try)) % UintMax;
+ ulong limitDeOperações = (uint)Math.Pow(2d, (double)(Hash % 2) + 1d);
+ ulong SeedC = Try + Mult;
+ ulong Seed = ((Hash + SeedSum + SeedC) + Try) % UintMax;
+
+ string Expr = string.Empty;
+ byte result = (byte)ExprGenerator.Generate(ref Hash, ref Seed, ref limitDeOperações, ref pubKey.X, ref pubKey.Y, out Expr);
+
+ if (prv[indexPrv] == result)
+ {
+ CorrectTryes[indexPrv] = Try;
+ if (PrintCorrectExpr)
+ Console.WriteLine("Correct expression for index "+indexPrv + " = " +Expr);
+ break;
+ }
+ }
+ }
+
+ return CorrectTryes;
+ }
+
+ public static string TryesToString(ulong[] CorrectTryes)
+ {
+ string rett = "";
+ for (int i = 0; i < CorrectTryes.Length; i++)
+ {
+ rett += (CorrectTryes[i] + ", ");
+ }
+ return rett;
+ }
+
+ }
+}
+
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
diff --git a/BitcoinExprCracker/Program.cs b/BitcoinExprCracker/Program.cs
new file mode 100644
index 0000000..28eb5a8
--- /dev/null
+++ b/BitcoinExprCracker/Program.cs
@@ -0,0 +1,37 @@
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
+
+using NBitcoin;
+using System;
+
+namespace BitcoinExprCracker
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+
+ for (BigInteger priv = 1; priv < 2; priv++)
+ {
+ Key k = new Key(Utils.BigInt2Key(priv));
+ byte[] PubKey = k.PubKey.Decompress().ToBytes();
+
+ ulong[] CorrectTryes = Generator.GeneratorMethods.GetPubKeyCorrectTryes(k, 32, true);
+ Console.WriteLine("PubKey = " + NBitcoin.DataEncoders.Encoders.Hex.EncodeData(PubKey));
+ Console.WriteLine("PrvKey = " + NBitcoin.DataEncoders.Encoders.Hex.EncodeData(k.ToBytes()));
+ Console.WriteLine("Generated Tryes = " + Generator.GeneratorMethods.TryesToString(CorrectTryes));
+ Console.WriteLine("Converted Tryes to PrvKey = " + NBitcoin.DataEncoders.Encoders.Hex.EncodeData(Generator.GeneratorMethods.ConvertTryesToPrivateKey(PubKey, CorrectTryes)));
+ Console.WriteLine();
+ }
+
+ Console.ReadKey();
+ }
+ }
+}
+
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
diff --git a/BitcoinExprCracker/Properties/AssemblyInfo.cs b/BitcoinExprCracker/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d2800c7
--- /dev/null
+++ b/BitcoinExprCracker/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// As informações gerais sobre um assembly são controladas por
+// conjunto de atributos. Altere estes valores de atributo para modificar as informações
+// associada a um assembly.
+[assembly: AssemblyTitle("BitcoinExprCracker")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BitcoinExprCracker")]
+[assembly: AssemblyCopyright("Copyright © Jairo Paiva 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Definir ComVisible como false torna os tipos neste assembly invisíveis
+// para componentes COM. Caso precise acessar um tipo neste assembly de
+// COM, defina o atributo ComVisible como true nesse tipo.
+[assembly: ComVisible(false)]
+
+// O GUID a seguir será destinado à ID de typelib se este projeto for exposto para COM
+[assembly: Guid("efa130f7-552b-46d9-8558-b8c6defb5f54")]
+
+// As informações da versão de um assembly consistem nos quatro valores a seguir:
+//
+// Versão Principal
+// Versão Secundária
+// Número da Versão
+// Revisão
+//
+// É possível especificar todos os valores ou usar como padrão os Números de Build e da Revisão
+// utilizando o "*" como mostrado abaixo:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BitcoinExprCracker/Utils.cs b/BitcoinExprCracker/Utils.cs
new file mode 100644
index 0000000..7002119
--- /dev/null
+++ b/BitcoinExprCracker/Utils.cs
@@ -0,0 +1,116 @@
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
+
+using BitcoinExprCracker.Generator;
+using System;
+
+namespace BitcoinExprCracker
+{
+ class Utils
+ {
+
+ public static ParsedPubKey ParseXYfromPub(byte[] pub, bool AssignULong = false)
+ {
+ byte[] X = new byte[32];
+ byte[] Y = new byte[32];
+ ParsedPubKey result = new ParsedPubKey();
+
+ for (int i = 1; i < 33; i++)
+ {
+ X[i - 1] = pub[i];
+ }
+
+ for (int i = 0; i < 32; i++)
+ {
+ Y[i] = pub[i + 33];
+ }
+
+ result.X = X;
+ result.Y = Y;
+
+ if (AssignULong)
+ {
+ result.xU = Utils.ByteArrayToULong32Bits(X);
+ result.yU = Utils.ByteArrayToULong32Bits(Y);
+ }
+
+ result.PublicKey = pub;
+
+ return result;
+ }
+
+ public static void Resize(ref byte[] data, int lenght)
+ {
+ byte[] newdata = new byte[lenght];
+
+ int e = data.Length - 1;
+ int i = lenght - 1;
+ while (e != -1)
+ {
+ if (i != -1)
+ {
+ newdata[i] = data[e];
+ i--;
+ e--;
+ }
+ }
+ data = newdata;
+
+ }
+
+ public static ulong[] ByteArrayToULong32Bits(byte[] array)
+ {
+ int total = array.Length / 4;
+ ulong[] result = new ulong[total];
+
+ for (int i = 0; i < total; i++)
+ {
+ byte[] arr = new byte[4];
+ Buffer.BlockCopy(array, (i * 4), arr, 0, arr.Length);
+ Array.Reverse(arr);
+ result[i] = BitConverter.ToUInt32(arr, 0);
+ }
+ return result;
+ }
+
+ public static byte[] BigInt2Key(BigInteger privatekey)
+ {
+ byte[] prv = privatekey.getBytes();
+ if (prv.Length != 32)
+ Resize(ref prv, 32);
+ return prv;
+ }
+
+ public static void ParseXYfromPub(byte[] pub, out byte[] x, out byte[] y)
+ {
+ byte[] X = new byte[32];
+ byte[] Y = new byte[32];
+
+ for (int i = 1; i < 33; i++)
+ {
+ X[i - 1] = pub[i];
+ }
+
+ for (int i = 0; i < 32; i++)
+ {
+ Y[i] = pub[i + 33];
+ }
+
+ x = X;
+ y = Y;
+ }
+
+ public static int GetPubUIndex(int prvIndex)
+ {
+ return (int)(prvIndex / 4);
+ }
+
+ }
+}
+
+/* Criado por Jairo Paiva
+ * https://github.com/jairopaiva
+ * GNU GPLv3
+ * */
diff --git a/BitcoinExprCracker/packages.config b/BitcoinExprCracker/packages.config
new file mode 100644
index 0000000..e8223f9
--- /dev/null
+++ b/BitcoinExprCracker/packages.config
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Main.PNG b/Main.PNG
new file mode 100644
index 0000000..afd1024
Binary files /dev/null and b/Main.PNG differ
diff --git a/Main_MostrarExprs.PNG b/Main_MostrarExprs.PNG
new file mode 100644
index 0000000..bafebaf
Binary files /dev/null and b/Main_MostrarExprs.PNG differ