Esempio n. 1
0
        public static void OutputKey(RSAWrapper rsa)
        {
            ProgramParameters parms = ProgramParameters.Instance;

            Console.WriteLine();
            Console.WriteLine("Ding!! Delicious scallions for you!!");
            Console.WriteLine();

            if (parms.KeyOutputPath != null)
            {
                System.IO.File.AppendAllText(parms.KeyOutputPath, "Generated at: " + System.DateTime.Now.ToString("G") + "\n");
                System.IO.File.AppendAllText(parms.KeyOutputPath, "Address/Hash: " + rsa.OnionHash + ".onion\n");
                System.IO.File.AppendAllText(parms.KeyOutputPath, "Public Modulus: " + rsa.Rsa.PublicModulus.ToDecimalString() + "\n");
                System.IO.File.AppendAllText(parms.KeyOutputPath, "Public Exponent: " + rsa.Rsa.PublicExponent.ToDecimalString() + "\n");
                if (rsa.HasPrivateKey)
                {
                    System.IO.File.AppendAllText(parms.KeyOutputPath, "RSA key: \n" + rsa.Rsa.PrivateKeyAsPEM + "\n");
                }
                System.IO.File.AppendAllText(parms.KeyOutputPath, "\n\n");
            }

            Console.WriteLine("Public Modulus:  {0}", rsa.Rsa.PublicModulus.ToDecimalString());
            Console.WriteLine("Public Exponent: {0}", rsa.Rsa.PublicExponent.ToDecimalString());
            Console.WriteLine("Address/Hash: " + rsa.OnionHash + ".onion");

            Console.WriteLine();
            if (rsa.HasPrivateKey)
            {
                Console.WriteLine(rsa.Rsa.PrivateKeyAsPEM);
                Console.WriteLine();
            }
        }
Esempio n. 2
0
        public static void WriteModuli()
        {
            ProgramParameters parms = ProgramParameters.Instance;

            var   rp             = new RegexPattern(parms.Regex);
            ulong hashes_per_win = (ulong)(0.5 / rp.GenerateAllOnionPatternsForRegex().Select(t => Math.Pow(2, -5 * t.Count(q => q != '.'))).Sum());
            ulong hashes_per_key = (CLRuntime.EXP_MAX - CLRuntime.EXP_MIN) / 2;
            ulong keys_needed    = hashes_per_win / hashes_per_key;
            uint  SF             = 5;

            Console.WriteLine("Generating that pattern will require approximately {0:0.000} gigahashes.", hashes_per_win / 1e9);
            Console.WriteLine("That will require on average {0} public keys.", keys_needed);
            Console.WriteLine("Generating {0} keys (for safety's sake).", keys_needed * SF);

            RSAWrapper rsa = new RSAWrapper();

            StreamWriter priv_sw = new StreamWriter(parms.RSAModuliPath + ".priv");
            StreamWriter pub_sw  = new StreamWriter(parms.RSAModuliPath);

            for (ulong i = 0; i < keys_needed * SF; i++)
            {
                if (i % 100 == 0)
                {
                    Console.WriteLine("Generating key {0} of {1}...", i, keys_needed * SF);
                }
                rsa.GenerateKey((int)parms.KeySize);
                pub_sw.WriteLine(rsa.Rsa.PublicModulus.ToDecimalString());
                priv_sw.WriteLine("Public Modulus: " + rsa.Rsa.PublicModulus.ToDecimalString());
                priv_sw.WriteLine(rsa.Rsa.PrivateKeyAsPEM);
                priv_sw.WriteLine("");
            }
            pub_sw.Close();
            priv_sw.Close();
        }
		public static string GenerateKernel(ProgramParameters programParameters, int numberOfMasks, int numberOfHashesPerKey, uint[] Bitmask, uint[] Pattern, int numberOfPatterns)
		{
			//Read kernel.cl
			StringBuilder builder = new StringBuilder();
			string kernelFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar + "kernel.cl";
			builder.Append(File.ReadAllText(kernelFile));
			//Replace program parms
			builder.Replace("GENERATED__CONSTANTS", programParameters.CreateDefinesString());
			//replace checking code
			builder.Replace("GENERATED__CHECKING_CODE", GenerateCheckingCode(numberOfMasks, numberOfHashesPerKey, Bitmask, Pattern, numberOfPatterns));
			//Return generated kernel
			return builder.ToString();
		}
Esempio n. 4
0
        public static string GenerateKernel(ProgramParameters programParameters, int numberOfMasks, int numberOfHashesPerKey, uint[] Bitmask, uint[] Pattern, int numberOfPatterns)
        {
            //Read kernel.cl
            StringBuilder builder    = new StringBuilder();
            string        kernelFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar + "kernel.cl";

            builder.Append(File.ReadAllText(kernelFile));
            //Replace program parms
            builder.Replace("GENERATED__CONSTANTS", programParameters.CreateDefinesString());
            //replace checking code
            builder.Replace("GENERATED__CHECKING_CODE", GenerateCheckingCode(numberOfMasks, numberOfHashesPerKey, Bitmask, Pattern, numberOfPatterns));
            //Return generated kernel
            return(builder.ToString());
        }
Esempio n. 5
0
        static void Shutdown()
        {
            ProgramParameters parms = ProgramParameters.Instance;

            if (parms.UsedModuliFile != null)
            {
                parms.UsedModuliFile.Close();
            }
            if (parms.PIDFile != null && File.Exists(parms.PIDFile))
            {
                File.Delete(parms.PIDFile);
            }
            Console.WriteLine();
            Console.WriteLine("Stopping the GPU and shutting down...");
            Console.WriteLine();
            lock (_runtime) { _runtime.Abort = true; }
        }
Esempio n. 6
0
        static void Main(string[] args)
        {
            ProgramParameters             parms     = ProgramParameters.Instance;
            Func <Mode, Action <string> > parseMode = (m) => (s) => { if (!string.IsNullOrEmpty(s))
                                                                      {
                                                                          parms.ProgramMode = m;
                                                                      }
            };
            OptionSet p = new OptionSet()
                          .Add <uint>("k|keysize=", "Specifies keysize for the RSA key", (i) => parms.KeySize = i)
                          .Add("n|nonoptimized", "Runs non-optimized kernel", parseMode(Mode.NonOptimized))
                          .Add("l|listdevices", "Lists the devices that can be used.", parseMode(Mode.ListDevices))
                          .Add("h|?|help", "Displays command line usage help.", parseMode(Mode.Help))
                          .Add <uint>("d|device=", "Specifies the opencl device that should be used.", (i) => parms.DeviceId        = i)
                          .Add <uint>("g|groupsize=", "Specifies the number of threads in a workgroup.", (i) => parms.WorkGroupSize = i)
                          .Add <uint>("w|worksize=", "Specifies the number of hashes preformed at one time.", (i) => parms.WorkSize = i)
                          .Add <uint>("t|cputhreads=", "Specifies the number of CPU threads to use when creating work. (EXPERIMENTAL - OpenSSL not thread-safe)", (i) => parms.CpuThreads = i)
                          .Add <string>("p|save-kernel=", "Saves the generated kernel to this path.", (i) => parms.SaveGeneratedKernelPath  = i)
                          .Add <string>("o|output=", "Saves the generated key(s) and address(es) to this path.", (i) => parms.KeyOutputPath = i)
                          .Add("c|continue", "Continue to search for keys rather than exiting when a key is found.", (i) => { if (!string.IsNullOrEmpty(i))
                                                                                                                              {
                                                                                                                                  parms.ContinueGeneration = true;
                                                                                                                              }
                               })
            ;



            List <string> extra = p.Parse(args);

            if (parms.ProgramMode == Mode.NonOptimized || parms.ProgramMode == Mode.Normal)
            {
                if (extra.Count < 1)
                {
                    parms.ProgramMode = Mode.Help;
                }
                else
                {
                    parms.Regex = extra.ToDelimitedString("|");
                }
            }

            //_runtime.Run(ProgramParameters.Instance,"prefix[abcdef]");
            switch (parms.ProgramMode)
            {
            case Mode.Help:
                Help(p);
                break;

            case Mode.ListDevices:
                ListDevices();
                break;

            case Mode.Normal:
            case Mode.NonOptimized:
            {
                // If no Work Group Size provided, then query the selected device for preferred, if not found set to 32.
                if (parms.WorkGroupSize == 0)
                {
                    ulong preferredWorkGroupSize = 32;
                    uint  deviceId = 0;
                    foreach (CLDeviceInfo device in CLRuntime.GetDevices())
                    {
                        if (!device.CompilerAvailable)
                        {
                            continue;
                        }
                        if (deviceId == parms.DeviceId)
                        {
                            preferredWorkGroupSize = getPreferredWorkGroupSize(device.DeviceId);
                            break;
                        }
                        deviceId++;
                    }

                    parms.WorkGroupSize = (uint)preferredWorkGroupSize;
                }

                Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
                _runtime.Run(ProgramParameters.Instance);
            }
            break;
            }
        }
Esempio n. 7
0
        public void Run(ProgramParameters parms)
        //int deviceId, int workGroupSize, int workSize, int numThreadsCreateWork, KernelType kernelt, int keysize, IEnumerable<string> patterns)
        {
            int        deviceId             = (int)parms.DeviceId;
            int        workGroupSize        = (int)parms.WorkGroupSize;
            int        workSize             = (int)parms.WorkSize;
            int        numThreadsCreateWork = (int)parms.CpuThreads;
            KernelType kernelt = parms.KernelType;
            int        keysize = (int)parms.KeySize;

            Console.WriteLine("Cooking up some delicions scallions...");
            this.workSize = (uint)workSize;
            profiler      = new Profiler();
            #region init
            profiler.StartRegion("init");

            // Combine patterns into a single regexp and build one of Richard's objects
            var rp = new RegexPattern(parms.Regex);

            // Create bitmasks array for the GPU
            var gpu_bitmasks = rp.GenerateOnionPatternBitmasksForGpu(MIN_CHARS)
                               .Select(t => TorBase32.ToUIntArray(TorBase32.CreateBase32Mask(t)))
                               .SelectMany(t => t).ToArray();
            //Create Hash Table
            uint[]   dataArray;
            ushort[] hashTable;
            uint[][] all_patterns;
            int      max_items_per_key = 0;
            {
                Func <uint[], ushort> fnv =
                    (pattern_arr) =>
                {
                    uint f = Util.FNVHash(pattern_arr[0], pattern_arr[1], pattern_arr[2]);
                    f = ((f >> 10) ^ f) & (uint)1023;
                    return((ushort)f);
                };
                all_patterns = rp.GenerateOnionPatternsForGpu(7)
                               .Select(i => TorBase32.ToUIntArray(TorBase32.FromBase32Str(i.Replace('.', 'a'))))
                               .ToArray();
                var gpu_dict_list = all_patterns
                                    .Select(i => new KeyValuePair <ushort, uint>(fnv(i), Util.FNVHash(i[0], i[1], i[2])))
                                    .GroupBy(i => i.Key)
                                    .OrderBy(i => i.Key)
                                    .ToList();

                dataArray = gpu_dict_list.SelectMany(i => i.Select(j => j.Value)).ToArray();
                hashTable = new ushort[1024];                 //item 1 index, item 2 length
                int currIndex = 0;
                foreach (var item in gpu_dict_list)
                {
                    int len = item.Count();
                    hashTable[item.Key] = (ushort)currIndex;
                    currIndex          += len;
                    if (len > max_items_per_key)
                    {
                        max_items_per_key = len;
                    }
                }

                Console.WriteLine("Putting {0} patterns into {1} buckets.", currIndex, gpu_dict_list.Count);
            }

            // Set the key size
            keySize = keysize;

            // Find kernel name and check key size
            kernel_type = kernelt;
            string kernelFileName = null, kernelName = null;
            switch (kernel_type)
            {
            case KernelType.Normal:
                kernelFileName = "kernel.cl";
                kernelName     = "normal";
                break;

            case KernelType.Optimized4_9:
                if (keySize != 1024)
                {
                    throw new ArgumentException("Kernel only works with keysize 1024.");
                }
                kernelFileName = "kernel.cl";
                kernelName     = "optimized";
                break;

            case KernelType.Optimized4_11:
                if (keySize != 2048 && keySize != 4096)
                {
                    throw new ArgumentException("Kernel only works with keysize 2048 or 4096.");
                }
                kernelFileName = "kernel.cl";
                kernelName     = "optimized";
                break;

            default:
                throw new ArgumentException("Pick a supported kernel.");
            }

            Console.WriteLine("Using kernel {0} from file {1} ({2})", kernelName, kernelFileName, kernel_type);

            //create device context and kernel
            CLDeviceInfo device = GetDevices()[deviceId];
            if ((uint)workGroupSize > device.MaxWorkGroupSize)
            {
                workGroupSize = (int)device.MaxWorkGroupSize;
            }
            Console.WriteLine("Using work group size {0}", workGroupSize);
            CLContext context = new CLContext(device.DeviceId);

            Console.Write("Compiling kernel... ");
            string kernel_text = KernelGenerator.GenerateKernel(parms, gpu_bitmasks.Length / 3, max_items_per_key, gpu_bitmasks.Take(3).ToArray(), all_patterns[0], all_patterns.Length);
            if (parms.SaveGeneratedKernelPath != null)
            {
                System.IO.File.WriteAllText(parms.SaveGeneratedKernelPath, kernel_text);
            }
            IntPtr program = context.CreateAndCompileProgram(kernel_text);

            var hashes_per_win = 0.5 / rp.GenerateAllOnionPatternsForRegex().Select(t => Math.Pow(2, -5 * t.Count(q => q != '.'))).Sum();
            Console.WriteLine("done.");

            CLKernel kernel = context.CreateKernel(program, kernelName);
            //Create buffers
            CLBuffer <uint> bufLastWs;
            CLBuffer <uint> bufMidstates;
            CLBuffer <int>  bufExpIndexes;
            CLBuffer <uint> bufResults;
            {
                int    num_exps   = (get_der_len(EXP_MAX) - get_der_len(EXP_MIN) + 1);
                uint[] LastWs     = new uint[num_exps * 16];
                uint[] Midstates  = new uint[num_exps * 5];
                int[]  ExpIndexes = new int[num_exps];
                uint[] Results    = new uint[128];

                bufLastWs     = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, LastWs);
                bufMidstates  = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, Midstates);
                bufExpIndexes = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, ExpIndexes);
                bufResults    = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadWrite | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, Results);
            }
            //Create pattern buffers
            CLBuffer <ushort> bufHashTable;
            CLBuffer <uint>   bufDataArray;
            CLBuffer <uint>   bufBitmasks;
            {
                bufHashTable = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, hashTable);
                bufDataArray = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, dataArray);
                bufBitmasks  = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, gpu_bitmasks);
            }
            //Set kernel arguments
            lock (new object()) { }             // Empty lock, resolves (or maybe hides) a race condition in SetKernelArg
            kernel.SetKernelArg(0, bufLastWs);
            kernel.SetKernelArg(1, bufMidstates);
            kernel.SetKernelArg(2, bufResults);
            kernel.SetKernelArg(3, (uint)EXP_MIN);
            kernel.SetKernelArg(4, (byte)get_der_len(EXP_MIN));
            kernel.SetKernelArg(5, bufExpIndexes);
            kernel.SetKernelArg(6, bufBitmasks);
            kernel.SetKernelArg(7, bufHashTable);
            kernel.SetKernelArg(8, bufDataArray);
            profiler.EndRegion("init");

            bufBitmasks.EnqueueWrite(true);
            bufHashTable.EnqueueWrite(true);
            bufDataArray.EnqueueWrite(true);

            //start the thread to generate input data
            for (int i = 0; i < numThreadsCreateWork; i++)
            {
                Thread inputThread = new Thread(CreateInput);
                inputThread.Start();
                inputThreads.Add(inputThread);
            }
            Thread.Sleep(3000);            //wait just a bit so some work is available
            #endregion

            int loop = 0;

            var gpu_runtime_sw = System.Diagnostics.Stopwatch.StartNew();

            profiler.StartRegion("total without init");
            bool success = false;
            while (!success)
            {
                lock (this) { if (this.Abort)
                              {
                                  break;
                              }
                }                                                      //abort flag was set.... bail
                KernelInput input = null;
                lock (_kernelInput)
                {
                    if (_kernelInput.Count > 0)
                    {
                        input = _kernelInput.Pop();
                    }
                }
                if (input == null)                 //If we have run out of work sleep for a bit
                {
                    Console.WriteLine("Lack of work for the GPU!! Taking a nap!!");
                    Thread.Sleep(250);
                    continue;
                }

                profiler.StartRegion("set buffers");
                bufLastWs.Data     = input.LastWs;
                bufMidstates.Data  = input.Midstates;
                bufExpIndexes.Data = input.ExpIndexes;
                bufResults.Data    = input.Results;
                kernel.SetKernelArg(3, input.BaseExp);
                profiler.EndRegion("set buffers");

                profiler.StartRegion("write buffers");
                bufLastWs.EnqueueWrite(true);
                bufMidstates.EnqueueWrite(true);
                bufExpIndexes.EnqueueWrite(true);
                Array.Clear(bufResults.Data, 0, bufResults.Data.Length);
                bufResults.EnqueueWrite(true);
                profiler.EndRegion("write buffers");

                kernel.EnqueueNDRangeKernel(workSize, workGroupSize);

                profiler.StartRegion("read results");
                bufResults.EnqueueRead(false);
                profiler.EndRegion("read results");

                loop++;
                Console.Write("\r");
                long hashes = (long)workSize * (long)loop;

                Console.Write("LoopIteration:{0}  HashCount:{1:0.00}MH  Speed:{2:0.0}MH/s  Runtime:{3}  Predicted:{4}  ",
                              loop, hashes / 1000000.0d, hashes / gpu_runtime_sw.ElapsedMilliseconds / 1000.0d,
                              gpu_runtime_sw.Elapsed.ToString().Split('.')[0],
                              PredictedRuntime(hashes_per_win, hashes * 1000 / gpu_runtime_sw.ElapsedMilliseconds));

                profiler.StartRegion("check results");
                foreach (var result in input.Results)
                {
                    if (result != 0)
                    {
                        try
                        {
                            input.Rsa.ChangePublicExponent((BigNumber)result);

                            string onion_hash = input.Rsa.OnionHash;
                            Console.WriteLine("CPU checking hash: {0}", onion_hash);

                            if (rp.DoesOnionHashMatchPattern(onion_hash))
                            {
                                Console.WriteLine();
                                Console.WriteLine("Ding!! Delicious scallions for you!!");
                                Console.WriteLine();

                                string key = input.Rsa.Rsa.PrivateKeyAsPEM;

                                if (parms.KeyOutputPath != null)
                                {
                                    System.IO.File.AppendAllText(parms.KeyOutputPath, "Generated at: " + System.DateTime.Now.ToString("G") + "\n");
                                    System.IO.File.AppendAllText(parms.KeyOutputPath, "Address/Hash: " + onion_hash + ".onion\n");
                                    System.IO.File.AppendAllText(parms.KeyOutputPath, "RSA key: \n" + key + "\n\n");
                                }

                                Console.WriteLine("Exponent: {0}", result);
                                input.Rsa.ChangePublicExponent((BigNumber)result);
                                Console.WriteLine("Address/Hash: " + onion_hash + ".onion");
                                Console.WriteLine();
                                Console.WriteLine(key);
                                Console.WriteLine();
                                if (!parms.ContinueGeneration)
                                {
                                    success = true;
                                }
                            }
                        }
                        catch (OpenSslException /*ex*/) { }
                    }
                }
                profiler.EndRegion("check results");
            }

            foreach (var thread in inputThreads)
            {
                thread.Abort();
            }
            profiler.EndRegion("total without init");
            Console.WriteLine(profiler.GetSummaryString());
            Console.WriteLine("{0:0.00} million hashes per second", ((long)loop * (long)workSize * (long)1000) / (double)profiler.GetTotalMS("total without init") / (double)1000000);
        }
Esempio n. 8
0
        public void Run(ProgramParameters parms)
        //int deviceId, int workGroupSize, int workSize, int numThreadsCreateWork, KernelType kernelt, int keysize, IEnumerable<string> patterns)
        {
            int        deviceId             = (int)parms.DeviceId;
            int        workGroupSize        = (int)parms.WorkGroupSize;
            int        workSize             = (int)parms.WorkSize;
            int        numThreadsCreateWork = (int)parms.CpuThreads;
            KernelType kernelt = parms.KernelType;
            int        keysize = (int)parms.KeySize;

            Console.WriteLine("Cooking up some delicions scallions...");
            this.workSize = (uint)workSize;
            profiler      = new Profiler();
            #region init
            profiler.StartRegion("init");

            // Combine patterns into a single regexp and build one of Richard's objects
            var rp = new RegexPattern(parms.Regex);

            // Create bitmasks array for the GPU
            var gpu_bitmasks = rp.GenerateOnionPatternBitmasksForGpu(MIN_CHARS)
                               .Select(t => TorBase32.ToUIntArray(TorBase32.CreateBase32Mask(t)))
                               .SelectMany(t => t).ToArray();
            //Create Hash Table
            uint[]   dataArray;
            ushort[] hashTable;
            uint[][] all_patterns;
            int      max_items_per_key = 0;
            {
                Func <uint[], ushort> fnv =
                    (pattern_arr) =>
                {
                    uint f = Util.FNVHash(pattern_arr[0], pattern_arr[1], pattern_arr[2]);
                    f = ((f >> 10) ^ f) & (uint)1023;
                    return((ushort)f);
                };
                all_patterns = rp.GenerateOnionPatternsForGpu(7)
                               .Select(i => TorBase32.ToUIntArray(TorBase32.FromBase32Str(i.Replace('.', 'a'))))
                               .ToArray();
                var gpu_dict_list = all_patterns
                                    .Select(i => new KeyValuePair <ushort, uint>(fnv(i), Util.FNVHash(i[0], i[1], i[2])))
                                    .GroupBy(i => i.Key)
                                    .OrderBy(i => i.Key)
                                    .ToList();

                dataArray = gpu_dict_list.SelectMany(i => i.Select(j => j.Value)).ToArray();
                hashTable = new ushort[1024];                 //item 1 index, item 2 length
                int currIndex = 0;
                foreach (var item in gpu_dict_list)
                {
                    int len = item.Count();
                    hashTable[item.Key] = (ushort)currIndex;
                    currIndex          += len;
                    if (len > max_items_per_key)
                    {
                        max_items_per_key = len;
                    }
                }

                Console.WriteLine("Putting {0} patterns into {1} buckets.", currIndex, gpu_dict_list.Count);
            }

            // Set the key size
            keySize = keysize;

            // Find kernel name and check key size
            kernel_type = kernelt;
            string kernelFileName = null, kernelName = null;
            switch (kernel_type)
            {
            case KernelType.Normal:
                kernelFileName = "kernel.cl";
                kernelName     = "normal";
                break;

            case KernelType.Optimized4:
                kernelFileName = "kernel.cl";
                kernelName     = "optimized";
                break;

            default:
                throw new ArgumentException("Pick a supported kernel.");
            }

            Console.WriteLine("Using kernel {0} from file {1} ({2})", kernelName, kernelFileName, kernel_type);

            //create device context and kernel
            CLDeviceInfo device = GetDevices()[deviceId];
            if ((uint)workGroupSize > device.MaxWorkGroupSize)
            {
                workGroupSize = (int)device.MaxWorkGroupSize;
            }
            Console.WriteLine("Using work group size {0}", workGroupSize);
            CLContext context = new CLContext(device.DeviceId);

            Console.Write("Compiling kernel... ");
            string kernel_text = KernelGenerator.GenerateKernel(parms, gpu_bitmasks.Length / 3, max_items_per_key, gpu_bitmasks.Take(3).ToArray(), all_patterns[0], all_patterns.Length, parms.ExponentIndex);
            if (parms.SaveGeneratedKernelPath != null)
            {
                System.IO.File.WriteAllText(parms.SaveGeneratedKernelPath, kernel_text);
            }
            IntPtr program = context.CreateAndCompileProgram(kernel_text);

            var hashes_per_win = 0.5 / rp.GenerateAllOnionPatternsForRegex().Select(t => Math.Pow(2, -5 * t.Count(q => q != '.'))).Sum();
            Console.WriteLine("done.");

            //
            // Test SHA1 algo
            //
            {
                Console.WriteLine("Testing SHA1 hash...");

                CLKernel        shaTestKern = context.CreateKernel(program, "shaTest");
                CLBuffer <uint> bufSuccess  = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadWrite | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, new uint[5]);
                shaTestKern.SetKernelArg(0, bufSuccess);

                shaTestKern.EnqueueNDRangeKernel(workSize, workGroupSize);

                bufSuccess.EnqueueRead(false);

                // Calculate the SHA1 CPU-side
                System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();

                String        testdata = "Hello world!";
                byte[]        cpuhash  = sha.ComputeHash(Encoding.ASCII.GetBytes(testdata));
                StringBuilder cpuhex   = new StringBuilder(cpuhash.Length * 2);
                foreach (byte b in cpuhash)
                {
                    cpuhex.AppendFormat("{0:x2}", b);
                }
                Console.WriteLine("CPU SHA-1: {0}", cpuhex.ToString());

                // Convert the SHA1 GPU-side to hex
                String gpuhex = String.Format("{0:x8}{1:x8}{2:x8}{3:x8}{4:x8}", bufSuccess.Data[0], bufSuccess.Data[1], bufSuccess.Data[2], bufSuccess.Data[3], bufSuccess.Data[4]);

                Console.WriteLine("GPU SHA-1: {0}", gpuhex);

                if (gpuhex != cpuhex.ToString())
                {
                    Console.WriteLine();
                    Console.WriteLine("******************************* ERROR ERROR ERROR *******************************");
                    Console.WriteLine("*                                                                               *");
                    Console.WriteLine("* GPU and CPU SHA-1 calculations do NOT match.                                  *");
                    Console.WriteLine("* Hashing will NOT work until this is resolved.                                 *");
                    Console.WriteLine("* The program will continue, but WILL NOT find a valid match.                   *");
                    Console.WriteLine("*                                                                               *");
                    Console.WriteLine("* See https://github.com/lachesis/scallion/issues/11#issuecomment-29046835      *");
                    Console.WriteLine("*                                                                               *");
                    Console.WriteLine("*********************************************************************************");
                    Console.WriteLine();
                }
                else
                {
                    Console.WriteLine("Looks good!");
                }
            }

            CLKernel kernel = context.CreateKernel(program, kernelName);
            //Create buffers
            CLBuffer <uint> bufLastWs;
            CLBuffer <uint> bufMidstates;
            CLBuffer <int>  bufExpIndexes;
            CLBuffer <uint> bufResults;
            {
                int    num_exps   = (get_der_len(EXP_MAX) - get_der_len(EXP_MIN) + 1);
                uint[] LastWs     = new uint[num_exps * 16];
                uint[] Midstates  = new uint[num_exps * 5];
                int[]  ExpIndexes = new int[num_exps];
                uint[] Results    = new uint[128];

                bufLastWs     = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, LastWs);
                bufMidstates  = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, Midstates);
                bufExpIndexes = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, ExpIndexes);
                bufResults    = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadWrite | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, Results);
            }
            //Create pattern buffers
            CLBuffer <ushort> bufHashTable;
            CLBuffer <uint>   bufDataArray;
            CLBuffer <uint>   bufBitmasks;
            {
                bufHashTable = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, hashTable);
                bufDataArray = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, dataArray);
                bufBitmasks  = context.CreateBuffer(OpenTK.Compute.CL10.MemFlags.MemReadOnly | OpenTK.Compute.CL10.MemFlags.MemCopyHostPtr, gpu_bitmasks);
            }
            //Set kernel arguments
            lock (new object()) { }             // Empty lock, resolves (or maybe hides) a race condition in SetKernelArg
            kernel.SetKernelArg(0, bufLastWs);
            kernel.SetKernelArg(1, bufMidstates);
            kernel.SetKernelArg(2, bufResults);
            kernel.SetKernelArg(3, (uint)EXP_MIN);
            kernel.SetKernelArg(4, (byte)get_der_len(EXP_MIN));
            kernel.SetKernelArg(5, bufExpIndexes);
            kernel.SetKernelArg(6, bufBitmasks);
            kernel.SetKernelArg(7, bufHashTable);
            kernel.SetKernelArg(8, bufDataArray);
            profiler.EndRegion("init");

            bufBitmasks.EnqueueWrite(true);
            bufHashTable.EnqueueWrite(true);
            bufDataArray.EnqueueWrite(true);

            //start the thread to generate input data
            for (int i = 0; i < numThreadsCreateWork; i++)
            {
                Thread inputThread = new Thread(CreateInput);
                inputThread.Start();
                inputThreads.Add(inputThread);
            }
            Thread.Sleep(3000);            //wait just a bit so some work is available
            #endregion

            int loop = 0;

            var gpu_runtime_sw = System.Diagnostics.Stopwatch.StartNew();

            profiler.StartRegion("total without init");
            bool success = false;
            while (!success)
            {
                lock (this) { if (this.Abort)
                              {
                                  break;
                              }
                }                                                      //abort flag was set.... bail
                KernelInput input = null;
                lock (_kernelInput)
                {
                    if (_kernelInput.Count > 0)
                    {
                        input = _kernelInput.Pop();
                    }
                }
                if (input == null)                 //If we have run out of work sleep for a bit
                {
                    Console.WriteLine("Lack of work for the GPU!! Taking a nap!!");
                    Thread.Sleep(250);
                    continue;
                }

                profiler.StartRegion("set buffers");
                bufLastWs.Data     = input.LastWs;
                bufMidstates.Data  = input.Midstates;
                bufExpIndexes.Data = input.ExpIndexes;
                bufResults.Data    = input.Results;
                kernel.SetKernelArg(3, input.BaseExp);
                profiler.EndRegion("set buffers");

                profiler.StartRegion("write buffers");
                bufLastWs.EnqueueWrite(true);
                bufMidstates.EnqueueWrite(true);
                bufExpIndexes.EnqueueWrite(true);
                Array.Clear(bufResults.Data, 0, bufResults.Data.Length);
                bufResults.EnqueueWrite(true);
                profiler.EndRegion("write buffers");

                kernel.EnqueueNDRangeKernel(workSize, workGroupSize);

                profiler.StartRegion("read results");
                bufResults.EnqueueRead(false);
                profiler.EndRegion("read results");

                loop++;
                Console.Write("\r");
                long hashes = (long)workSize * (long)loop;

                Console.Write("LoopIteration:{0}  HashCount:{1:0.00}MH  Speed:{2:0.0}MH/s  Runtime:{3}  Predicted:{4}  ",
                              loop, hashes / 1000000.0d, hashes / gpu_runtime_sw.ElapsedMilliseconds / 1000.0d,
                              gpu_runtime_sw.Elapsed.ToString().Split('.')[0],
                              PredictedRuntime(hashes_per_win, hashes * 1000 / gpu_runtime_sw.ElapsedMilliseconds));

                profiler.StartRegion("check results");
                foreach (var result in input.Results)
                {
                    if (result != 0)
                    {
                        try
                        {
                            input.Rsa.Rsa.PublicExponent = (BigNumber)result;

                            string onion_hash = input.Rsa.OnionHash;
                            Console.WriteLine("CPU checking hash: {0}", onion_hash);

                            if (rp.DoesOnionHashMatchPattern(onion_hash))
                            {
                                input.Rsa.ChangePublicExponent(result);
                                OutputKey(input.Rsa);

                                if (!parms.ContinueGeneration)
                                {
                                    success = true;
                                }
                            }
                        }
                        catch (OpenSslException /*ex*/) { }
                    }
                }
                profiler.EndRegion("check results");

                // Mark key as used (if configured)
                if (parms.UsedModuliFile != null)
                {
                    parms.UsedModuliFile.WriteLine(input.Rsa.Rsa.PublicModulus.ToDecimalString());
                }
            }

            foreach (var thread in inputThreads)
            {
                thread.Abort();
            }
            profiler.EndRegion("total without init");
            Console.WriteLine(profiler.GetSummaryString());
            Console.WriteLine("{0:0.00} million hashes per second", ((long)loop * (long)workSize * (long)1000) / (double)profiler.GetTotalMS("total without init") / (double)1000000);
        }
Esempio n. 9
0
        private void CreateInput()
        {
            ProgramParameters parms = ProgramParameters.Instance;

            while (true)
            {
                bool inputQueueIsLow = false;
                lock (_kernelInput)     { inputQueueIsLow = _kernelInput.Count < 300; }
                if (inputQueueIsLow)
                {
                    int         num_exps = (get_der_len(EXP_MAX) - get_der_len(EXP_MIN) + 1);
                    KernelInput input    = new KernelInput(num_exps);

                    // Read moduli from file or generate them if possible
                    if (parms.RSAPublicModuli != null)
                    {
                        if (parms.RSAPublicModuli.Count > 0)
                        {
                            input.Rsa.Rsa.PublicModulus = parms.RSAPublicModuli.Dequeue();
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        profiler.StartRegion("generate key");
                        input.Rsa.GenerateKey(keySize);                         // Generate a key
                        profiler.EndRegion("generate key");
                    }

                    // Build DERs and calculate midstates for exponents of representitive lengths
                    profiler.StartRegion("cpu precompute");
                    int         cur_exp_num = 0;
                    BigNumber[] Exps        = new BigNumber[num_exps];
                    bool        skip_flag   = false;

                    // With EXP_MIN = 0x01010001 and EXP_MAX = 0x7FFFFFFF, only one iteration (i = 4)
                    for (int i = get_der_len(EXP_MIN); i <= get_der_len(EXP_MAX); i++)
                    {
                        // With i = 4, exp = 0x01000000 (just a placeholder in the DER)
                        ulong exp = (ulong)0x01 << (int)((i - 1) * 8);

                        // Set the exponent in the RSA key
                        // NO SANITY CHECK - just for building a DER
                        input.Rsa.Rsa.PublicExponent = (BigNumber)exp;
                        Exps[cur_exp_num]            = (BigNumber)exp;

                        // Get the DER
                        byte[] der       = input.Rsa.DER;
                        int    exp_index = der.Length % 64 - i;
                        if (exp_index != parms.ExponentIndex)
                        {
                            Console.WriteLine("Exponent index doesn't match - skipping key");
                            skip_flag = true;
                            break;
                        }
                        if (i != 4)                          // exponent length assumed to be 4 in the kernel
                        {
                            Console.WriteLine("Exponent length doesn't match - skipping key");
                            skip_flag = true;
                            break;
                        }

                        // Put the DER into Ws
                        SHA1          Sha1 = new SHA1();
                        List <uint[]> Ws   = Sha1.DataToPaddedBlocks(der);

                        // Put all but the last block through the hash
                        Ws.Take(Ws.Count - 1).Select((t) =>
                        {
                            Sha1.SHA1_Block(t);
                            return(t);
                        }).ToArray();

                        // Put the midstate, the last W block, and the byte index of the exponent into the CL buffers
                        Sha1.H.CopyTo(input.Midstates, 5 * cur_exp_num);
                        Ws.Last().Take(16).ToArray().CopyTo(input.LastWs, 16 * cur_exp_num);
                        input.ExpIndexes[cur_exp_num] = exp_index;

                        // Increment the current exponent size
                        cur_exp_num++;
                        break;
                    }
                    profiler.EndRegion("cpu precompute");

                    if (skip_flag)
                    {
                        continue;                               // we got a bad key - don't enqueue it
                    }
                    List <KernelInput> inputs = new List <KernelInput>();
                    inputs.Add(input);
                    for (uint i = 1; i < (EXP_MAX - EXP_MIN) / 2 / workSize - 1; i++)
                    {
                        //profiler.StartRegion("generate key");
                        if (EXP_MIN + workSize * 2 * i >= EXP_MAX)
                        {
                            throw new ArgumentException("base_exp > EXP_MAX");
                        }
                        inputs.Add(new KernelInput(input, EXP_MIN + workSize * 2 * i));
                        //profiler.EndRegion("generate key");
                    }
                    lock (_kernelInput)                    //put input on queue
                    {
                        foreach (KernelInput i in inputs)
                        {
                            _kernelInput.Push(i);
                        }
                    }
                    continue;                    //skip the sleep cause we might be really low
                }
                Thread.Sleep(50);
            }
        }
Esempio n. 10
0
        static void Main(string[] args)
        {
            ProgramParameters             parms     = ProgramParameters.Instance;
            Func <Mode, Action <string> > parseMode = (m) => (s) => { if (!string.IsNullOrEmpty(s))
                                                                      {
                                                                          parms.ProgramMode = m;
                                                                      }
            };
            OptionSet p = new OptionSet()
                          .Add <uint>("k|keysize=", "Specifies keysize for the RSA key", (i) => parms.KeySize = i)
                          .Add("n|nonoptimized", "Runs non-optimized kernel", parseMode(Mode.NonOptimized))
                          .Add("l|listdevices", "Lists the devices that can be used.", parseMode(Mode.ListDevices))
                          .Add("h|?|help", "Displays command line usage help.", parseMode(Mode.Help))
                          .Add <uint>("d|device=", "Specifies the opencl device that should be used.", (i) => parms.DeviceId        = i)
                          .Add <uint>("g|groupsize=", "Specifies the number of threads in a workgroup.", (i) => parms.WorkGroupSize = i)
                          .Add <uint>("w|worksize=", "Specifies the number of hashes preformed at one time.", (i) => parms.WorkSize = i)
                          .Add <uint>("t|cputhreads=", "Specifies the number of CPU threads to use when creating work. (EXPERIMENTAL - OpenSSL not thread-safe)", (i) => parms.CpuThreads = i)
                          .Add <string>("pidfile=", "Specifies a file where the process id will be written; file will be deleted at exit", (i) => parms.PIDFile = i)
                          .Add <string>("m|modulifile=", "Specifies a file containing public key moduli", (i) => parms.RSAModuliPath = i)
                          .Add("s|write-moduli", "Writes moduli and private keys for a given pattern to the file specified with -m", (i) => { if (parms.ProgramMode != Mode.Help)
                                                                                                                                              {
                                                                                                                                                  parms.ProgramMode = Mode.WriteModuli;
                                                                                                                                              }
                               })
                          .Add("r|read-results=", "Reads a results file (generated by a remote miner) and output the winning key (-m must be specified)", (i) => parms.InputResultsPath = i)
                          .Add <string>("p|save-kernel=", "Saves the generated kernel to this path.", (i) => parms.SaveGeneratedKernelPath  = i)
                          .Add <string>("o|output=", "Saves the generated key(s) and address(es) to this path.", (i) => parms.KeyOutputPath = i)
                          .Add("c|continue", "Continue to search for keys rather than exiting when a key is found.", (i) => { if (!string.IsNullOrEmpty(i))
                                                                                                                              {
                                                                                                                                  parms.ContinueGeneration = true;
                                                                                                                              }
                               })
            ;

            List <string> extra = p.Parse(args);

            if (parms.InputResultsPath != null && parms.ProgramMode != Mode.Help)
            {
                parms.ProgramMode = Mode.ReadResults;
            }

            if (parms.ProgramMode == Mode.NonOptimized || parms.ProgramMode == Mode.Normal || parms.ProgramMode == Mode.WriteModuli)
            {
                if (extra.Count < 1)
                {
                    parms.ProgramMode = Mode.Help;
                }
                else
                {
                    parms.Regex = extra.ToDelimitedString("|");
                }
            }

            if (parms.PIDFile != null)
            {
                File.WriteAllText(parms.PIDFile, System.Diagnostics.Process.GetCurrentProcess().Id.ToString());
            }

            //_runtime.Run(ProgramParameters.Instance,"prefix[abcdef]");
            switch (parms.ProgramMode)
            {
            case Mode.Help:
                Help(p);
                break;

            case Mode.ListDevices:
                ListDevices();
                break;

            case Mode.WriteModuli:
                WriteModuli();
                break;

            case Mode.ReadResults:
                ReadResults();
                break;

            case Mode.Normal:
            case Mode.NonOptimized:
            {
                // If no Work Group Size provided, then query the selected device for preferred, if not found set to 32.
                if (parms.WorkGroupSize == 0)
                {
                    ulong preferredWorkGroupSize = 32;
                    uint  deviceId = 0;
                    foreach (CLDeviceInfo device in CLRuntime.GetDevices())
                    {
                        if (!device.CompilerAvailable)
                        {
                            continue;
                        }
                        if (deviceId == parms.DeviceId)
                        {
                            preferredWorkGroupSize = getPreferredWorkGroupSize(device.DeviceId);
                            break;
                        }
                        deviceId++;
                    }

                    parms.WorkGroupSize = (uint)preferredWorkGroupSize;
                }

                // If a moduli file is specified, read it and create or read a .used file
                if (parms.RSAModuliPath != null)
                {
                    if (File.Exists(parms.RSAModuliPath))
                    {
                        // Read and/or create used file
                        string           usedPath = parms.RSAModuliPath + ".used";
                        HashSet <string> used     = null;
                        if (File.Exists(usedPath))
                        {
                            used = new HashSet <string>();
                            foreach (var line in File.ReadAllLines(usedPath))
                            {
                                used.Add(line.Trim());
                            }
                        }
                        else
                        {
                            File.WriteAllText(usedPath, "");
                        }

                        // Set up used file to be written later
                        parms.UsedModuliFile = new StreamWriter(usedPath, true);

                        // Read moduli file
                        parms.RSAPublicModuli = new Queue <BigNumber>();
                        foreach (var line in File.ReadAllLines(parms.RSAModuliPath))
                        {
                            if (used == null || !used.Contains(line.Trim()))
                            {
                                parms.RSAPublicModuli.Enqueue(BigNumber.FromDecimalString(line.Trim()));
                            }
                        }
                    }
                }

                Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
                try {
                    _runtime.Run(ProgramParameters.Instance);
                }
                finally {
                    Shutdown();
                }
            }
            break;
            }
        }
Esempio n. 11
0
        public static void ReadResults()
        {
            ProgramParameters parms = ProgramParameters.Instance;

            string rsaPrivFn = parms.RSAModuliPath + ".priv";

            if (!File.Exists(rsaPrivFn))
            {
                Console.WriteLine("Error: expecting private key file at {0}.", rsaPrivFn);
                return;
            }
            if (!File.Exists(parms.InputResultsPath))
            {
                Console.WriteLine("Error: expecting results from miner at {0}.", parms.InputResultsPath);
                return;
            }

            // Create a map to hold (public modulus as decimal string) -> (private key as pem)
            IDictionary <string, string> modulusKeyMap = new Dictionary <string, string>();

            // Read the priv key list file
            string currentModulus = null, currentPEM = null;

            foreach (string l in File.ReadAllLines(rsaPrivFn))
            {
                string line = l.Trim();
                if (line.StartsWith("Public Modulus: "))
                {
                    currentModulus = line.Replace("Public Modulus: ", "");
                }

                if (line.StartsWith("-----BEGIN RSA PRIVATE KEY-----"))
                {
                    currentPEM = "";
                }
                currentPEM += line + "\n";
                if (line.StartsWith("-----END RSA PRIVATE KEY-----"))
                {
                    modulusKeyMap.Add(currentModulus, currentPEM);
                }
            }

            // Read the results file
            string modulus = null, exponent = null, address = null;

            foreach (string l in File.ReadAllLines(parms.InputResultsPath))
            {
                //string[] split = l.Trim().Split(":".ToCharArray(), 2);
                string line = l.Trim();
                if (line.StartsWith("Public Modulus: "))
                {
                    modulus = line.Replace("Public Modulus: ", "");
                }
                if (line.StartsWith("Public Exponent: "))
                {
                    exponent = line.Replace("Public Exponent: ", "");
                }
                if (line.StartsWith("Address/Hash: "))
                {
                    address = line.Replace("Address/Hash: ", "");
                }

                if (modulus != null && exponent != null && address != null)
                {
                    // Find the modulus in the private key map
                    string pem;
                    if (!modulusKeyMap.TryGetValue(modulus, out pem))
                    {
                        throw new InvalidDataException(String.Format("Modulus {0} is missing from the private key data file.", modulus));
                    }

                    // Load the PEM into the RSA
                    RSAWrapper rsa = new RSAWrapper();
                    rsa.FromPrivateKeyPEM(pem);

                    // Verify that modulus matches
                    if (rsa.Rsa.PublicModulus != BigNumber.FromDecimalString(modulus))
                    {
                        throw new InvalidDataException("Modulus of PEM does not match declared value.");
                    }

                    // Change the public exponent
                    rsa.ChangePublicExponent(BigNumber.FromDecimalString(exponent));

                    // Check the key's sanity
                    rsa.CheckSanity();

                    // Verify the hash
                    if (rsa.OnionHash + ".onion" != address)
                    {
                        throw new InvalidDataException("Onion hash of key does not match declared value.");
                    }

                    // Yay the key is good! Output it as required
                    CLRuntime.OutputKey(rsa);

                    modulus  = null;
                    exponent = null;
                    address  = null;
                }
            }
        }