source: trunk/CrypPlugins/KeySearcher/KeySearcher.cs @ 2214

Last change on this file since 2214 was 2214, checked in by Sven Rech, 11 years ago

keysearcher

File size: 57.7 KB
Line 
1/*                             
2   Copyright 2009 Sven Rech, Nils Kopal, Uni Duisburg-Essen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Diagnostics;
19using System.IO;
20using System.Linq;
21using System.Net;
22using System.Text;
23using Cryptool.P2P;
24using Cryptool.P2P.Internal;
25using Cryptool.PluginBase.Analysis;
26using Cryptool.PluginBase;
27using System.Windows.Controls;
28using System.ComponentModel;
29using Cryptool.PluginBase.Control;
30using System.Collections;
31using System.Collections.Generic;
32using System.Threading;
33using System.Windows.Threading;
34using Cryptool.PluginBase.IO;
35using System.Numerics;
36using KeySearcher.Helper;
37using KeySearcher.KeyPattern;
38using KeySearcher.P2P;
39using KeySearcher.P2P.Exceptions;
40using KeySearcherPresentation;
41using KeySearcherPresentation.Controls;
42using OpenCLNet;
43
44namespace KeySearcher
45{   
46    [Author("Sven Rech, Nils Kopal, Raoul Falk, Dennis Nolte", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
47    [PluginInfo(false, "KeySearcher", "Bruteforces a decryption algorithm.", "KeySearcher/DetailedDescription/Description.xaml", "KeySearcher/Images/icon.png")]
48    public class KeySearcher : IAnalysisMisc
49    {
50        /// <summary>
51        /// used for creating the TopList
52        /// </summary>
53        private Queue valuequeue;
54        private double value_threshold;
55        /// <summary>
56        /// the thread with the most keys left
57        /// </summary>
58        private int maxThread;
59        private readonly Mutex maxThreadMutex = new Mutex();
60        private ArrayList threadsStopEvents;
61
62        public bool IsKeySearcherRunning;
63        private KeyQualityHelper keyQualityHelper;
64        private readonly P2PQuickWatchPresentation p2PQuickWatchPresentation;
65        private readonly LocalQuickWatchPresentation localQuickWatchPresentation;
66
67        private OpenCLManager oclManager = null;
68        private Mutex openCLPresentationMutex = new Mutex();
69
70        private readonly Stopwatch localBruteForceStopwatch;
71
72        private KeyPattern.KeyPattern pattern;
73        public KeyPattern.KeyPattern Pattern
74        {
75            get
76            {
77                return pattern;
78            }
79            set
80            {
81                pattern = value;
82                if ((settings.Key == null) || ((settings.Key != null) && !pattern.testWildcardKey(settings.Key)))
83                    settings.Key = pattern.giveInputPattern();
84            }
85        }
86
87        internal bool stop;
88
89        internal bool update;
90
91        #region IControlEncryption + IControlCost + InputFields
92
93        #region IControlEncryption Members
94
95        private IControlEncryption controlMaster;
96        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
97        public IControlEncryption ControlMaster
98        {
99            get { return controlMaster; }
100            set
101            {
102                if (controlMaster != null)
103                {
104                    controlMaster.keyPatternChanged -= keyPatternChanged;
105                }
106                if (value != null)
107                {
108                    Pattern = new KeyPattern.KeyPattern(value.getKeyPattern());
109                    value.keyPatternChanged += keyPatternChanged;
110                    controlMaster = value;
111                    OnPropertyChanged("ControlMaster");
112
113                }
114                else
115                    controlMaster = null;
116            }
117        }
118
119        #endregion
120
121        #region IControlCost Members
122
123        private IControlCost costMaster;
124        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
125        public IControlCost CostMaster
126        {
127            get { return costMaster; }
128            set
129            {
130                costMaster = value;
131                keyQualityHelper = new KeyQualityHelper(costMaster);
132            }
133        }
134
135        #endregion
136
137        /* BEGIN: following lines are from Arnie - 2010.01.12 */
138        CryptoolStream csEncryptedData;
139        [PropertyInfo(Direction.InputData, "CS Encrypted Data", "Encrypted data out of an Encryption PlugIn", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, "")]
140        public virtual CryptoolStream CSEncryptedData
141        {
142            get { return this.csEncryptedData; }
143            set
144            {
145                if (value != this.csEncryptedData)
146                {
147                    this.csEncryptedData = value;
148                    this.encryptedData = GetByteFromCryptoolStream(value);
149                    OnPropertyChanged("CSEncryptedData");
150                }
151            }
152        }
153
154        byte[] encryptedData;
155        [PropertyInfo(Direction.InputData,"Encrypted Data","Encrypted data out of an Encryption PlugIn","",false,false,DisplayLevel.Beginner,QuickWatchFormat.Hex,"")]
156        public virtual byte[] EncryptedData
157        {
158            get { return this.encryptedData; }
159            set
160            {
161                if (value != this.encryptedData)
162                {
163                    this.encryptedData = value;
164                    OnPropertyChanged("EncryptedData");
165                }
166            }
167        }
168
169        /// <summary>
170        /// When the Input-Slot changed, set this variable to true, so the new Stream will be transformed to byte[]
171        /// </summary>
172        private byte[] GetByteFromCryptoolStream(CryptoolStream cryptoolStream)
173        {
174            byte[] encryptedByteData = null;
175
176            if (cryptoolStream != null)
177            {
178                CryptoolStream cs = new CryptoolStream();
179                cs.OpenRead(cryptoolStream.FileName);
180                encryptedByteData = new byte[cs.Length];
181                if(cs.Length > Int32.MaxValue)
182                    throw(new Exception("CryptoolStream length is longer than the Int32.MaxValue"));
183                cs.Read(encryptedByteData, 0, (int)cs.Length);
184            }
185            return encryptedByteData;
186        }
187
188        byte[] initVector;
189        [PropertyInfo(Direction.InputData, "Initialization Vector", "Initialization vector with which the data were encrypted", "", DisplayLevel.Beginner)]
190        public virtual byte[] InitVector
191        {
192            get { return this.initVector; }
193            set
194            {
195                if (value != this.initVector)
196                {
197                    this.initVector = value;
198                    OnPropertyChanged("InitVector");
199                }
200            }
201        }
202        /* END: Lines above are from Arnie - 2010.01.12 */
203
204        private ValueKey top1ValueKey;
205        public virtual ValueKey Top1
206        {
207            set { top1ValueKey = value; OnPropertyChanged("Top1Message"); OnPropertyChanged("Top1Key"); }
208        }
209
210        [PropertyInfo(Direction.OutputData, "Top1 Message", "The best message found", "", DisplayLevel.Beginner)]
211        public virtual byte[] Top1Message
212        {
213            get { return top1ValueKey.decryption; }
214        }
215        [PropertyInfo(Direction.OutputData, "Top1 Key", "The best key found", "", DisplayLevel.Beginner)]
216        public virtual byte[] Top1Key
217        {
218            get
219            {
220                if (top1ValueKey.key != null)
221                {
222                    return top1ValueKey.keya;
223                }
224                else
225                    return null;
226            }
227        }
228
229        #endregion
230
231        #region IPlugin Members
232
233        public event StatusChangedEventHandler OnPluginStatusChanged;
234
235        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
236
237        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
238
239        private KeySearcherSettings settings;
240        private AutoResetEvent connectResetEvent;
241
242        #region external client variables
243        private CryptoolServer cryptoolServer;
244        private KeySearcherOpenCLCode externalKeySearcherOpenCLCode;
245        private IKeyTranslator externalKeyTranslator;
246        private int externalKeysProcessed;
247        private EndPoint externalClientConnected;
248        private AutoResetEvent waitForExternalClientToFinish = new AutoResetEvent(false);
249        private DateTime assignTime;
250        #endregion
251
252        public KeySearcher()
253        {
254            IsKeySearcherRunning = false;
255           
256            if (OpenCL.NumberOfPlatforms > 0)
257            {
258                oclManager = new OpenCLManager();
259                oclManager.AttemptUseBinaries = false;
260                oclManager.AttemptUseSource = true;
261                oclManager.RequireImageSupport = false;
262                var directoryName = Path.Combine(DirectoryHelper.DirectoryLocalTemp, "KeySearcher");
263                oclManager.BinaryPath = Path.Combine(directoryName, "openclbin");
264                oclManager.BuildOptions = "";
265                oclManager.CreateDefaultContext(0, DeviceType.ALL);
266            }
267
268            settings = new KeySearcherSettings(this, oclManager);
269           
270            QuickWatchPresentation = new QuickWatch();
271            localQuickWatchPresentation = ((QuickWatch) QuickWatchPresentation).LocalQuickWatchPresentation;
272            p2PQuickWatchPresentation = ((QuickWatch)QuickWatchPresentation).P2PQuickWatchPresentation;
273            p2PQuickWatchPresentation.UpdateSettings(this, settings);
274
275            settings.PropertyChanged += SettingsPropertyChanged;
276            ((QuickWatch)QuickWatchPresentation).IsOpenCLEnabled = (settings.DeviceSettings.Count(x => x.useDevice) > 0);
277
278            localBruteForceStopwatch = new Stopwatch();
279        }
280
281        void SettingsPropertyChanged(object sender, PropertyChangedEventArgs e)
282        {
283            p2PQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
284                                                             new Action(UpdateQuickwatchSettings));
285        }
286
287        void UpdateQuickwatchSettings()
288        {
289            ((QuickWatch)QuickWatchPresentation).IsP2PEnabled = settings.UsePeerToPeer;
290            ((QuickWatch)QuickWatchPresentation).IsOpenCLEnabled = (settings.DeviceSettings.Count(x => x.useDevice) > 0);
291            p2PQuickWatchPresentation.UpdateSettings(this, settings);
292        }
293
294        public ISettings Settings
295        {
296            get { return settings; }
297        }
298
299        public UserControl Presentation
300        {
301            get { return QuickWatchPresentation; }
302        }
303
304        public UserControl QuickWatchPresentation
305        {
306            get;
307            private set;
308        }
309
310        public void PreExecution()
311        {
312            update = false;
313        }
314
315        // because Encryption PlugIns were changed radical, the new StartPoint is here - Arnie 2010.01.12
316        public virtual void Execute()
317        {
318            IsKeySearcherRunning = true;
319            localBruteForceStopwatch.Reset();
320
321            //either byte[] CStream input or CryptoolStream Object input
322            if (encryptedData != null || csEncryptedData != null) //to prevent execution on initialization
323            {
324                if (ControlMaster != null)
325                    process(ControlMaster);
326                else
327                {
328                    GuiLogMessage("You have to connect the KeySearcher with the Decryption Control!", NotificationLevel.Warning);
329                }
330            }
331        }
332
333        public void PostExecution()
334        {
335        }
336
337        public void Pause()
338        {
339        }
340
341        public void Stop()
342        {
343            IsKeySearcherRunning = false;
344            stop = true;
345            waitForExternalClientToFinish.Set();
346        }
347
348        public void Initialize()
349        {
350            settings.Initialize();
351        }
352
353        public void Dispose()
354        {
355        }
356
357        #endregion
358
359        #region INotifyPropertyChanged Members
360
361        public event PropertyChangedEventHandler PropertyChanged;
362
363        public void OnPropertyChanged(string name)
364        {
365            if (PropertyChanged != null)
366            {
367                PropertyChanged(this, new PropertyChangedEventArgs(name));
368            }
369        }
370
371        #endregion
372
373        #region whole KeySearcher functionality
374
375        private class ThreadStackElement
376        {
377            public AutoResetEvent ev;
378            public int threadid;
379        }
380
381        #region code for the worker threads
382
383        private void KeySearcherJob(object param)
384        {
385            AutoResetEvent stopEvent = new AutoResetEvent(false);
386            threadsStopEvents.Add(stopEvent);
387
388            object[] parameters = (object[])param;
389            KeyPattern.KeyPattern[] patterns = (KeyPattern.KeyPattern[])parameters[0];
390            int threadid = (int)parameters[1];
391            BigInteger[] doneKeysArray = (BigInteger[])parameters[2];
392            BigInteger[] openCLDoneKeysArray = (BigInteger[])parameters[3];
393            BigInteger[] keycounterArray = (BigInteger[])parameters[4];
394            BigInteger[] keysLeft = (BigInteger[])parameters[5];
395            IControlEncryption sender = (IControlEncryption)parameters[6];
396            int bytesToUse = (int)parameters[7];
397            Stack threadStack = (Stack)parameters[8];
398            var openCLDeviceSettings = (KeySearcherSettings.OpenCLDeviceSettings)parameters[9];
399
400            KeySearcherOpenCLCode keySearcherOpenCLCode = null;
401            KeySearcherOpenCLSubbatchOptimizer keySearcherOpenCLSubbatchOptimizer = null;
402            if (openCLDeviceSettings != null)
403            {
404                keySearcherOpenCLCode = new KeySearcherOpenCLCode(this, encryptedData, sender, CostMaster, 256 * 256 * 256 * 16);
405                keySearcherOpenCLSubbatchOptimizer = new KeySearcherOpenCLSubbatchOptimizer(openCLDeviceSettings.mode, 
406                        oclManager.CQ[openCLDeviceSettings.index].Device.MaxWorkItemSizes.Aggregate(1, (x, y) => (x * (int)y)) / 8);
407
408                ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
409                {
410                    openCLPresentationMutex.WaitOne();
411                    ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices++;
412                    openCLPresentationMutex.ReleaseMutex();
413                }, null);
414                Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
415            }
416
417            try
418            {
419                while (patterns[threadid] != null)
420                {
421                    BigInteger size = patterns[threadid].size();
422                    keysLeft[threadid] = size;
423                   
424                    IKeyTranslator keyTranslator = ControlMaster.getKeyTranslator();
425                    keyTranslator.SetKeys(patterns[threadid]);
426
427                    bool finish = false;
428
429                    do
430                    {
431                        //if we are the thread with most keys left, we have to share them:
432                        keyTranslator = ShareKeys(patterns, threadid, keysLeft, keyTranslator, threadStack);
433
434                        if (openCLDeviceSettings == null)         //CPU
435                        {
436                            finish = BruteforceCPU(keyTranslator, sender, bytesToUse);
437                        }
438                        else                    //OpenCL
439                        {
440                            try
441                            {
442                                finish = BruteforceOpenCL(keySearcherOpenCLCode, keySearcherOpenCLSubbatchOptimizer, keyTranslator, sender, bytesToUse, parameters);
443                            }
444                            catch (Exception)
445                            {
446                                openCLDeviceSettings.useDevice = false;
447                                ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
448                                {
449                                    openCLPresentationMutex.WaitOne();
450                                    ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices--;
451                                    openCLPresentationMutex.ReleaseMutex();
452                                }, null);
453                                continue;
454                            }
455                        }
456                       
457                        int progress = keyTranslator.GetProgress();
458
459                        if (openCLDeviceSettings == null)
460                        {
461                            doneKeysArray[threadid] += progress;
462                            keycounterArray[threadid] += progress;
463                            keysLeft[threadid] -= progress;
464                        }
465
466                    } while (!finish && !stop);
467
468                    if (stop)
469                        return;
470
471                    //Let's wait until another thread is willing to share with us:
472                    WaitForNewPattern(patterns, threadid, threadStack);
473                }
474            }
475            finally
476            {
477                sender.Dispose();
478                stopEvent.Set();
479            }
480        }
481
482        private unsafe bool BruteforceOpenCL(KeySearcherOpenCLCode keySearcherOpenCLCode, KeySearcherOpenCLSubbatchOptimizer keySearcherOpenCLSubbatchOptimizer, IKeyTranslator keyTranslator, IControlEncryption sender, int bytesToUse, object[] parameters)
483        {
484            int threadid = (int)parameters[1];
485            BigInteger[] doneKeysArray = (BigInteger[])parameters[2];
486            BigInteger[] openCLDoneKeysArray = (BigInteger[])parameters[3];
487            BigInteger[] keycounterArray = (BigInteger[])parameters[4];
488            BigInteger[] keysLeft = (BigInteger[])parameters[5];
489            var openCLDeviceSettings = (KeySearcherSettings.OpenCLDeviceSettings)parameters[9];
490            try
491            {
492                Kernel bruteforceKernel = keySearcherOpenCLCode.GetBruteforceKernel(oclManager, keyTranslator);
493
494                int deviceIndex = openCLDeviceSettings.index;
495               
496                Mem userKey;
497                var key = keyTranslator.GetKey();
498                fixed (byte* ukp = key)
499                    userKey = oclManager.Context.CreateBuffer(MemFlags.USE_HOST_PTR, key.Length, new IntPtr((void*)ukp));
500
501                int subbatches = keySearcherOpenCLSubbatchOptimizer.GetAmountOfSubbatches(keyTranslator);
502                int subbatchSize = keyTranslator.GetOpenCLBatchSize() / subbatches;
503                ((QuickWatch) QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate
504                                                                    {
505                                                                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.workItems.Content = subbatchSize;
506                                                                    }, null);
507                //GuiLogMessage(string.Format("Now using {0} subbatches", subbatches), NotificationLevel.Info);
508               
509                float[] costArray = new float[subbatchSize];
510                Mem costs = oclManager.Context.CreateBuffer(MemFlags.READ_WRITE, costArray.Length * 4);
511
512                IntPtr[] globalWorkSize = { (IntPtr)subbatchSize };
513
514                keySearcherOpenCLSubbatchOptimizer.BeginMeasurement();
515
516                try
517                {
518                    for (int i = 0; i < subbatches; i++)
519                    {
520                        bruteforceKernel.SetArg(0, userKey);
521                        bruteforceKernel.SetArg(1, costs);
522                        bruteforceKernel.SetArg(2, i * subbatchSize);
523                        oclManager.CQ[deviceIndex].EnqueueNDRangeKernel(bruteforceKernel, 1, null, globalWorkSize, null);
524                        oclManager.CQ[deviceIndex].EnqueueBarrier();
525
526                        Event e;
527                        fixed (float* costa = costArray)
528                            oclManager.CQ[deviceIndex].EnqueueReadBuffer(costs, true, 0, costArray.Length * 4, new IntPtr((void*)costa), 0, null, out e);
529
530                        e.Wait();
531
532                        checkOpenCLResults(keyTranslator, costArray, sender, bytesToUse, i * subbatchSize);
533
534                        doneKeysArray[threadid] += subbatchSize;
535                        openCLDoneKeysArray[threadid] += subbatchSize;
536                        keycounterArray[threadid] += subbatchSize;
537                        keysLeft[threadid] -= subbatchSize;
538
539                        if (stop)
540                            return false;
541                    }
542
543                    keySearcherOpenCLSubbatchOptimizer.EndMeasurement();
544                }
545                finally
546                {
547                    costs.Dispose();
548                }
549            }
550            catch (Exception ex)
551            {
552                GuiLogMessage(ex.Message, NotificationLevel.Error);
553                GuiLogMessage("Bruteforcing with OpenCL failed! Using CPU instead.", NotificationLevel.Error);
554                throw new Exception("Bruteforcing with OpenCL failed!");
555            }
556
557            return !keyTranslator.NextOpenCLBatch();
558        }
559
560        private void checkOpenCLResults(IKeyTranslator keyTranslator, float[] costArray, IControlEncryption sender, int bytesToUse, int add)
561        {
562            var op = this.costMaster.getRelationOperator();
563            for (int i = 0; i < costArray.Length; i++)
564            {
565                float cost = costArray[i];
566                if (((op == RelationOperator.LargerThen) && (cost > value_threshold))
567                    || (op == RelationOperator.LessThen) && (cost < value_threshold))
568                {
569                    ValueKey valueKey = new ValueKey { value = cost, key = keyTranslator.GetKeyRepresentation(i + add) };
570                    valueKey.keya = keyTranslator.GetKeyFromRepresentation(valueKey.key);
571                    valueKey.decryption = sender.Decrypt(this.encryptedData, valueKey.keya, InitVector, bytesToUse);
572                    valuequeue.Enqueue(valueKey);
573                }
574            }
575        }
576
577        private bool BruteforceCPU(IKeyTranslator keyTranslator, IControlEncryption sender, int bytesToUse)
578        {
579            bool finish = false;
580            for (int count = 0; count < 256 * 256; count++)
581            {
582                byte[] keya = keyTranslator.GetKey();
583
584                if (!decryptAndCalculate(sender, bytesToUse, keya, keyTranslator))
585                    throw new Exception("Bruteforcing not possible!");
586
587                finish = !keyTranslator.NextKey();
588                if (finish)
589                    break;
590            }
591            return finish;
592        }
593
594        private IKeyTranslator ShareKeys(KeyPattern.KeyPattern[] patterns, int threadid, BigInteger[] keysLeft, IKeyTranslator keyTranslator, Stack threadStack)
595        {
596            BigInteger size;
597            if (maxThread == threadid && threadStack.Count != 0)
598            {
599                try
600                {
601                    maxThreadMutex.WaitOne();
602                    if (maxThread == threadid && threadStack.Count != 0)
603                    {
604                        KeyPattern.KeyPattern[] split = patterns[threadid].split();
605                        if (split != null)
606                        {
607                            patterns[threadid] = split[0];
608                            keyTranslator = ControlMaster.getKeyTranslator();
609                            keyTranslator.SetKeys(patterns[threadid]);
610
611                            ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
612                            patterns[elem.threadid] = split[1];
613                            elem.ev.Set();    //wake the other thread up                                   
614                            size = patterns[threadid].size();
615                            keysLeft[threadid] = size;
616                        }
617                        maxThread = -1;
618                    }
619                }
620                finally
621                {
622                    maxThreadMutex.ReleaseMutex();
623                }
624            }
625            return keyTranslator;
626        }
627
628        private void WaitForNewPattern(KeyPattern.KeyPattern[] patterns, int threadid, Stack threadStack)
629        {
630            ThreadStackElement el = new ThreadStackElement();
631            el.ev = new AutoResetEvent(false);
632            el.threadid = threadid;
633            patterns[threadid] = null;
634            threadStack.Push(el);
635            GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
636            el.ev.WaitOne();
637            if (!stop)
638            {
639                GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
640            }
641        }
642
643        #region bruteforce methods
644
645        private bool decryptAndCalculate(IControlEncryption sender, int bytesToUse, byte[] keya, IKeyTranslator keyTranslator)
646        {
647            ValueKey valueKey;
648
649            try
650            {
651                if (this.encryptedData != null && this.encryptedData.Length > 0)
652                {
653                    valueKey.decryption = sender.Decrypt(this.encryptedData, keya, InitVector, bytesToUse);
654                }
655                else
656                {
657                    GuiLogMessage("Can't bruteforce empty input!", NotificationLevel.Error);
658                    return false;
659                }
660            }
661            catch (Exception ex)
662            {
663                GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
664                GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
665                return false;
666            }
667
668            try
669            {
670                valueKey.value = CostMaster.calculateCost(valueKey.decryption);
671            }
672            catch (Exception ex)
673            {
674                GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
675                return false;
676            }
677
678            if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
679            {
680                if (valueKey.value > value_threshold)
681                {
682                    valueKey.key = keyTranslator.GetKeyRepresentation();
683                    valueKey.keya = (byte[])keya.Clone();
684                    valuequeue.Enqueue(valueKey);                   
685                }
686            }
687            else
688            {
689                if (valueKey.value < value_threshold)
690                {
691                    valueKey.key = keyTranslator.GetKeyRepresentation();
692                    valueKey.keya = (byte[])keya.Clone();                 
693                    valuequeue.Enqueue(valueKey);
694                }
695            }
696            return true;
697        }
698
699        #endregion
700
701        #endregion
702
703        public void process(IControlEncryption sender)
704        {
705            if (sender == null || costMaster == null)
706                return;
707            if (!Pattern.testWildcardKey(settings.Key))
708            {
709                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
710                return;
711            }
712            Pattern.WildcardKey = settings.Key;
713            this.sender = sender;
714
715            bruteforcePattern(Pattern);
716        }
717
718        internal LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
719        private int bytesToUse;
720        private IControlEncryption sender;
721        private DateTime beginBruteforcing;
722        private DistributedBruteForceManager distributedBruteForceManager;
723
724        // main entry point to the KeySearcher
725        private LinkedList<ValueKey> bruteforcePattern(KeyPattern.KeyPattern pattern)
726        {
727            beginBruteforcing = DateTime.Now;
728            GuiLogMessage("Start bruteforcing pattern '" + pattern.getKey() + "'", NotificationLevel.Debug);
729                       
730            int maxInList = 10;
731            costList = new LinkedList<ValueKey>();
732            fillListWithDummies(maxInList, costList);
733            valuequeue = Queue.Synchronized(new Queue());
734
735            stop = false;
736            if (!pattern.testWildcardKey(settings.Key))
737            {
738                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
739                return null;
740            }
741
742            // bytesToUse = 0;
743
744            try
745            {
746                bytesToUse = CostMaster.getBytesToUse();
747            }
748            catch (Exception ex)
749            {
750                GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
751                return null;
752            }
753
754            Thread serverThread = null;
755            try
756            {
757                if (settings.UseExternalClient)
758                {
759                    GuiLogMessage("Waiting for external client!", NotificationLevel.Info);
760                    cryptoolServer = new CryptoolServer();
761                    externalClientConnected = null;
762                    cryptoolServer.Port = settings.Port;
763                    cryptoolServer.OnJobCompleted += server_OnJobCompleted;
764                    cryptoolServer.OnClientConnected += server_OnClientConnected;
765                    cryptoolServer.OnClientDisconnected += cryptoolServer_OnClientDisconnected;
766                    serverThread = new Thread(new ThreadStart(delegate
767                                                                      {
768                                                                          cryptoolServer.Run();
769                                                                      }));
770                    serverThread.Start();
771                }
772
773                if (settings.UsePeerToPeer)
774                {
775                    BruteForceWithPeerToPeerSystem();
776                    return null;
777                }
778
779                return BruteForceWithLocalSystem(pattern);
780            }
781            finally
782            {
783                if (stop && serverThread != null)
784                {
785                    //stop server here!
786                    serverThread.Interrupt();
787                    cryptoolServer.OnJobCompleted -= server_OnJobCompleted;
788                    cryptoolServer.OnClientConnected -= server_OnClientConnected;
789                    cryptoolServer.OnClientDisconnected -= cryptoolServer_OnClientDisconnected;
790                }
791            }
792        }
793
794        private void BruteForceWithPeerToPeerSystem()
795        {
796            if (!update)
797            {
798                GuiLogMessage("Launching p2p based bruteforce logic...", NotificationLevel.Info);
799
800                try
801                {
802                    distributedBruteForceManager = new DistributedBruteForceManager(this, pattern, settings,
803                                                                                    keyQualityHelper,
804                                                                                    p2PQuickWatchPresentation);
805                    distributedBruteForceManager.Execute();
806                }
807                catch (NotConnectedException)
808                {
809                    GuiLogMessage("P2P not connected.", NotificationLevel.Error);
810                }
811                catch (KeySearcherStopException)
812                {
813                    update = true;
814                    return;
815                }
816            }
817            else
818            {
819                GuiLogMessage("Keysearcher Fullstop.Please Update your Version.", NotificationLevel.Error);
820                Thread.Sleep(3000);
821            }
822        }
823
824        internal LinkedList<ValueKey> BruteForceWithLocalSystem(KeyPattern.KeyPattern pattern, bool redirectResultsToStatisticsGenerator = false)
825        {
826            ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
827            {
828                openCLPresentationMutex.WaitOne();
829                ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices = 0;
830                openCLPresentationMutex.ReleaseMutex();
831            }, null);
832
833            if (!redirectResultsToStatisticsGenerator)
834            {
835                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(SetStartDate));
836                localBruteForceStopwatch.Start();
837            }
838
839            if (settings.UseExternalClient)
840            {
841                GuiLogMessage("Only using external client to bruteforce!", NotificationLevel.Info);
842                lock (this)
843                {
844                    externalKeySearcherOpenCLCode = new KeySearcherOpenCLCode(this, encryptedData, sender, CostMaster,
845                                                                              256*256*256*64);
846                    externalKeysProcessed = 0;
847                    externalKeyTranslator = ControlMaster.getKeyTranslator();
848                    externalKeyTranslator.SetKeys(pattern);
849                    if (externalClientConnected != null)
850                        AssignJobToClient(externalClientConnected, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
851                }
852                waitForExternalClientToFinish.Reset();
853                waitForExternalClientToFinish.WaitOne();
854            }
855            else
856            {
857                BigInteger size = pattern.size();
858                KeyPattern.KeyPattern[] patterns = splitPatternForThreads(pattern);
859                if (patterns == null || patterns.Length == 0)
860                {
861                    GuiLogMessage("No ressources to BruteForce available. Check the KeySearcher settings!", NotificationLevel.Error);
862                    throw new Exception("No ressources to BruteForce available. Check the KeySearcher settings!");
863                }
864
865                BigInteger[] doneKeysA = new BigInteger[patterns.Length];
866                BigInteger[] openCLDoneKeysA = new BigInteger[patterns.Length];
867                BigInteger[] keycounters = new BigInteger[patterns.Length];
868                BigInteger[] keysleft = new BigInteger[patterns.Length];
869                Stack threadStack = Stack.Synchronized(new Stack());
870                threadsStopEvents = ArrayList.Synchronized(new ArrayList());
871                StartThreads(sender, bytesToUse, patterns, doneKeysA, openCLDoneKeysA, keycounters, keysleft, threadStack);
872
873                DateTime lastTime = DateTime.Now;
874
875                //update message:
876                while (!stop)
877                {
878                    Thread.Sleep(2000);
879
880                    updateToplist();
881
882                    #region calculate global counters from local counters
883                    BigInteger keycounter = 0;
884                    BigInteger doneKeys = 0;
885                    BigInteger openCLdoneKeys = 0;
886                    foreach (BigInteger dk in doneKeysA)
887                        doneKeys += dk;
888                    foreach (BigInteger dk in openCLDoneKeysA)
889                        openCLdoneKeys += dk;
890                    foreach (BigInteger kc in keycounters)
891                        keycounter += kc;
892                    #endregion
893
894                    if (keycounter > size)
895                        GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
896
897                    #region determination of the thread with most keys
898                    if (size - keycounter > 1000)
899                    {
900                        try
901                        {
902                            maxThreadMutex.WaitOne();
903                            BigInteger max = 0;
904                            int id = -1;
905                            for (int i = 0; i < patterns.Length; i++)
906                                if (keysleft[i] != null && keysleft[i] > max)
907                                {
908                                    max = keysleft[i];
909                                    id = i;
910                                }
911                            maxThread = id;
912                        }
913                        finally
914                        {
915                            maxThreadMutex.ReleaseMutex();
916                        }
917                    }
918                    #endregion
919
920                    long keysPerSecond = (long)((long)doneKeys / (DateTime.Now - lastTime).TotalSeconds);
921                    long openCLKeysPerSecond = (long)((long)openCLdoneKeys / (DateTime.Now - lastTime).TotalSeconds);
922                    lastTime = DateTime.Now;
923                    if (redirectResultsToStatisticsGenerator)
924                    {
925                        distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList, size, keycounter, keysPerSecond);
926                    }
927                    else
928                    {
929                        showProgress(costList, size, keycounter, keysPerSecond);
930                    }
931
932                    //show OpenCL keys/sec:
933                    var ratio = (double)openCLdoneKeys / (double)doneKeys;
934                    ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
935                    {
936                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondOpenCL.Content = String.Format("{0:N}", openCLKeysPerSecond);
937                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondCPU.Content = String.Format("{0:N}", (keysPerSecond - openCLKeysPerSecond));
938                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.ratio.Content = String.Format("{0:P}", ratio);
939                    }, null);
940
941
942                    #region set doneKeys to 0
943                    doneKeys = 0;
944                    for (int i = 0; i < doneKeysA.Length; i++)
945                        doneKeysA[i] = 0;
946                    openCLdoneKeys = 0;
947                    for (int i = 0; i < openCLDoneKeysA.Length; i++)
948                        openCLDoneKeysA[i] = 0;
949                    #endregion
950
951                    if (keycounter >= size)
952                        break;
953                }//end while
954
955                showProgress(costList, 1, 1, 1);
956
957                //wake up all sleeping threads, so they can stop:
958                while (threadStack.Count != 0)
959                    ((ThreadStackElement)threadStack.Pop()).ev.Set();
960
961                //wait until all threads finished:
962                foreach (AutoResetEvent stopEvent in threadsStopEvents)
963                {
964                    stopEvent.WaitOne();
965                }
966
967                if (!stop && !redirectResultsToStatisticsGenerator)
968                    ProgressChanged(1, 1);
969
970            }
971
972            /* BEGIN: For evaluation issues - added by Arnold 2010.03.17 */
973            TimeSpan bruteforcingTime = DateTime.Now.Subtract(beginBruteforcing);
974            StringBuilder sbBFTime = new StringBuilder();
975            if (bruteforcingTime.Days > 0)
976                sbBFTime.Append(bruteforcingTime.Days.ToString() + " days ");
977            if (bruteforcingTime.Hours > 0)
978            {
979                if (bruteforcingTime.Hours <= 9)
980                    sbBFTime.Append("0");
981                sbBFTime.Append(bruteforcingTime.Hours.ToString() + ":");
982            }
983            if (bruteforcingTime.Minutes <= 9)
984                sbBFTime.Append("0");
985            sbBFTime.Append(bruteforcingTime.Minutes.ToString() + ":");
986            if (bruteforcingTime.Seconds <= 9)
987                sbBFTime.Append("0");
988            sbBFTime.Append(bruteforcingTime.Seconds.ToString() + "-");
989            if (bruteforcingTime.Milliseconds <= 9)
990                sbBFTime.Append("00");
991            if (bruteforcingTime.Milliseconds <= 99)
992                sbBFTime.Append("0");
993            sbBFTime.Append(bruteforcingTime.Milliseconds.ToString());
994
995            GuiLogMessage("Ended bruteforcing pattern '" + pattern.getKey() + "'. Bruteforcing TimeSpan: " + sbBFTime.ToString(), NotificationLevel.Debug);
996            /* END: For evaluation issues - added by Arnold 2010.03.17 */
997
998            return costList;
999        }
1000
1001        #region External Client
1002
1003        void cryptoolServer_OnClientDisconnected(EndPoint client)
1004        {
1005            GuiLogMessage("Client disconnected!", NotificationLevel.Info);
1006            externalClientConnected = null;
1007        }
1008
1009        void server_OnClientConnected(System.Net.EndPoint client, string identification)
1010        {
1011            lock (this)
1012            {
1013                if (externalClientConnected == null)
1014                {
1015                    externalClientConnected = client;
1016                    GuiLogMessage(string.Format("Client {0} connected!", identification), NotificationLevel.Info);
1017                    AssignJobToClient(client, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
1018                }
1019                else
1020                {
1021                    GuiLogMessage("Client tried to connect, but only one client allowed!", NotificationLevel.Info);
1022                }
1023            }
1024        }
1025
1026        private void AssignJobToClient(EndPoint client, string src)
1027        {
1028            JobInput j = new JobInput();
1029            j.Guid = Guid.NewGuid().ToString();
1030            j.Src = src;
1031            var key = externalKeyTranslator.GetKey();
1032            j.Key = key;
1033            j.LargerThen = (costMaster.getRelationOperator() == RelationOperator.LargerThen);
1034            j.Size = externalKeyTranslator.GetOpenCLBatchSize();
1035            j.ResultSize = 10;
1036            GuiLogMessage(string.Format("Assigning new job with Guid {0} to client!", j.Guid), NotificationLevel.Info);
1037            cryptoolServer.SendJob(j, client);
1038            assignTime = DateTime.Now;
1039        }
1040
1041        void server_OnJobCompleted(System.Net.EndPoint client, JobResult jr)
1042        {
1043            GuiLogMessage(string.Format("Client returned result of job with Guid {0}!", jr.Guid), NotificationLevel.Info);
1044            //check:
1045            var op = this.costMaster.getRelationOperator();
1046            foreach (var res in jr.ResultList)
1047            {
1048                float cost = res.Key;
1049                if (((op == RelationOperator.LargerThen) && (cost > value_threshold))
1050                    || (op == RelationOperator.LessThen) && (cost < value_threshold))
1051                {
1052                    ValueKey valueKey = new ValueKey { value = cost, key = externalKeyTranslator.GetKeyRepresentation(res.Value) };
1053                    valueKey.keya = externalKeyTranslator.GetKeyFromRepresentation(valueKey.key);
1054                    valueKey.decryption = sender.Decrypt(this.encryptedData, valueKey.keya, InitVector, bytesToUse);
1055                    valuequeue.Enqueue(valueKey);
1056                }
1057            }
1058            updateToplist();
1059
1060            //progress:
1061            externalKeyTranslator.NextOpenCLBatch();
1062            int progress = externalKeyTranslator.GetProgress();
1063            externalKeysProcessed += progress;
1064            int keysPerSec = (int)(progress / (DateTime.Now - assignTime).TotalSeconds);
1065            showProgress(costList, pattern.size(), externalKeysProcessed, keysPerSec);
1066
1067            if (externalKeysProcessed != pattern.size())
1068            {
1069                AssignJobToClient(client, null);
1070            }
1071            else
1072            {
1073                waitForExternalClientToFinish.Set();
1074            }
1075        }
1076
1077        #endregion
1078
1079        private void SetStartDate()
1080        {
1081            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
1082        }
1083
1084        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, long keysPerSecond)
1085        {
1086            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
1087
1088            LinkedListNode<ValueKey> linkedListNode;
1089            ProgressChanged((double)keycounter / (double)size, 1.0);
1090
1091            if (localQuickWatchPresentation.IsVisible && keysPerSecond != 0 && !stop)
1092            {
1093                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - Math.Log10(keysPerSecond)));
1094                TimeSpan timeleft = new TimeSpan(-1);
1095
1096                try
1097                {
1098                    if (time / (24 * 60 * 60) <= int.MaxValue)
1099                    {
1100                        int days = (int)(time / (24 * 60 * 60));
1101                        time = time - (days * 24 * 60 * 60);
1102                        int hours = (int)(time / (60 * 60));
1103                        time = time - (hours * 60 * 60);
1104                        int minutes = (int)(time / 60);
1105                        time = time - (minutes * 60);
1106                        int seconds = (int)time;
1107
1108                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
1109                    }
1110                }
1111                catch
1112                {
1113                    //can not calculate time span
1114                }
1115
1116                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1117                {
1118                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
1119                    localQuickWatchPresentation.keysPerSecond.Content = String.Format("{0:0,0}", keysPerSecond);
1120                    if (timeleft != new TimeSpan(-1))
1121                    {
1122                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
1123                        try
1124                        {
1125                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
1126                        }
1127                        catch
1128                        {
1129                            localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
1130                        }
1131                    }
1132                    else
1133                    {
1134                        localQuickWatchPresentation.timeLeft.Content = "incalculable :-)";
1135                        localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
1136                    }
1137
1138                    localQuickWatchPresentation.entries.Clear();
1139                    linkedListNode = costList.First;
1140
1141                    int i = 0;
1142                    while (linkedListNode != null)
1143                    {
1144                        i++;
1145
1146                        ResultEntry entry = new ResultEntry();
1147                        entry.Ranking = "" + i;
1148                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1149                        entry.Key = linkedListNode.Value.key;
1150                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1151
1152                        localQuickWatchPresentation.entries.Add(entry);
1153                        linkedListNode = linkedListNode.Next;
1154                    }
1155                }
1156                , null);
1157            }//end if
1158            else if (!stop && localQuickWatchPresentation.IsVisible)
1159            {
1160
1161                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1162                {
1163                    localQuickWatchPresentation.entries.Clear();
1164                    linkedListNode = costList.First;
1165                    int i = 0;
1166
1167                    while (linkedListNode != null)
1168                    {
1169                        i++;
1170
1171                        ResultEntry entry = new ResultEntry();
1172                        entry.Ranking = "" + i;
1173                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1174                        entry.Key = linkedListNode.Value.key;
1175                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1176
1177                        localQuickWatchPresentation.entries.Add(entry);
1178                        linkedListNode = linkedListNode.Next;
1179                    }
1180                }
1181                , null);
1182            }
1183        }
1184
1185        #region For TopList
1186
1187        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
1188        {
1189            ValueKey valueKey = new ValueKey();
1190            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
1191                valueKey.value = double.MaxValue;
1192            else
1193                valueKey.value = double.MinValue;
1194            valueKey.key = "dummykey";
1195            valueKey.decryption = new byte[0];
1196            value_threshold = valueKey.value;
1197            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
1198            for (int i = 1; i < maxInList; i++)
1199            {
1200                node = costList.AddAfter(node, valueKey);
1201            }
1202        }
1203
1204        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList)
1205        {
1206            foreach (var valueKey in updatedCostList)
1207            {
1208                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
1209                {
1210                    valuequeue.Enqueue(valueKey);
1211                }
1212            }
1213
1214            updateToplist();
1215        }
1216
1217        internal void updateToplist()
1218        {
1219            LinkedListNode<ValueKey> node;
1220            while (valuequeue.Count != 0)
1221            {
1222                ValueKey vk = (ValueKey)valuequeue.Dequeue();
1223
1224                //if (costList.Contains(vk)) continue;
1225                var result = costList.Where(valueKey => valueKey.key == vk.key);
1226                if (result.Count() > 0)
1227                {
1228                    continue;
1229                }
1230
1231                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
1232                {
1233                    if (vk.value > costList.Last().value)
1234                    {
1235                        node = costList.First;
1236                        while (node != null)
1237                        {
1238                            if (vk.value > node.Value.value)
1239                            {
1240                                if (node == costList.First)
1241                                    Top1 = vk;
1242                                costList.AddBefore(node, vk);
1243                                costList.RemoveLast();
1244                                value_threshold = costList.Last.Value.value;
1245                                break;
1246                            }
1247                            node = node.Next;
1248                        }//end while
1249                    }//end if
1250                }
1251                else
1252                {
1253                    if (vk.value < costList.Last().value)
1254                    {
1255                        node = costList.First;
1256                        while (node != null)
1257                        {
1258                            if (vk.value < node.Value.value)
1259                            {
1260                                if (node == costList.First)
1261                                    Top1 = vk;
1262                                costList.AddBefore(node, vk);
1263                                costList.RemoveLast();
1264                                value_threshold = costList.Last.Value.value;
1265                                break;
1266                            }
1267                            node = node.Next;
1268                        }//end while
1269                    }//end if
1270                }
1271            }
1272        }
1273
1274        #endregion
1275
1276        private void StartThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] openCLDoneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
1277        {
1278            //First start the opencl threads:
1279            int i = 0;
1280            foreach (var ds in settings.DeviceSettings)
1281            {
1282                if (ds.useDevice)
1283                {
1284                    WaitCallback worker = new WaitCallback(KeySearcherJob);
1285                    doneKeysA[i] = new BigInteger();
1286                    openCLDoneKeysA[i] = new BigInteger();
1287                    keycounters[i] = new BigInteger();
1288
1289                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, ds });
1290                    i++;
1291                }
1292            }
1293
1294            //Then the CPU threads:
1295            for (; i < patterns.Length; i++)
1296            {
1297                WaitCallback worker = new WaitCallback(KeySearcherJob);
1298                doneKeysA[i] = new BigInteger();
1299                openCLDoneKeysA[i] = new BigInteger();
1300                keycounters[i] = new BigInteger();
1301
1302                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, null });
1303            }
1304        }
1305
1306        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
1307        {
1308            int threads = settings.CoresUsed;
1309            threads += settings.DeviceSettings.Count(x => x.useDevice); 
1310
1311            if (threads < 1)
1312                return null;
1313
1314            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[threads];
1315            if (threads > 1)
1316            {
1317                KeyPattern.KeyPattern[] patterns2 = pattern.split();
1318                if (patterns2 == null)
1319                {
1320                    patterns2 = new KeyPattern.KeyPattern[1];
1321                    patterns2[0] = pattern;
1322                    return patterns2;
1323                }
1324                patterns[0] = patterns2[0];
1325                patterns[1] = patterns2[1];
1326                int p = 1;
1327                threads -= 2;
1328
1329                while (threads > 0)
1330                {
1331                    int maxPattern = -1;
1332                    BigInteger max = 0;
1333                    for (int i = 0; i <= p; i++)
1334                        if (patterns[i].size() > max)
1335                        {
1336                            max = patterns[i].size();
1337                            maxPattern = i;
1338                        }
1339                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
1340                    if (patterns3 == null)
1341                    {
1342                        patterns3 = new KeyPattern.KeyPattern[p+1];
1343                        for (int i = 0; i <= p; i++)
1344                            patterns3[i] = patterns[i];
1345                        return patterns3;
1346                    }
1347                    patterns[maxPattern] = patterns3[0];
1348                    patterns[++p] = patterns3[1];
1349                    threads--;
1350                }
1351            }
1352            else
1353                patterns[0] = pattern;
1354            return patterns;
1355        }
1356
1357        private void keyPatternChanged()
1358        {
1359            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
1360        }
1361
1362        // added by Arnie - 2009.12.07
1363        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
1364        /// <summary>
1365        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
1366        /// But when the returned List is filled, we have (at least a part) of the possible best keys
1367        /// </summary>
1368        public event BruteforcingEnded OnBruteforcingEnded;
1369
1370        // added by Arnie -2009.12.02
1371        // for inheritance reasons
1372        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
1373        {
1374            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1375            this.encryptedData = encryptedData;
1376            this.initVector = initVector;
1377            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1378
1379            this.sender = encryptControl;
1380            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
1381            if(OnBruteforcingEnded != null)
1382                OnBruteforcingEnded(lstRet);
1383        }
1384
1385        #endregion
1386
1387        public void GuiLogMessage(string message, NotificationLevel loglevel)
1388        {
1389            if (OnGuiLogNotificationOccured != null)
1390                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
1391        }
1392
1393        public void ProgressChanged(double value, double max)
1394        {
1395            if (OnPluginProgressChanged != null)
1396            {
1397                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1398
1399            }
1400        }
1401
1402        /// <summary>
1403        /// used for delivering the results from the worker threads to the main thread:
1404        /// </summary>
1405        public struct ValueKey
1406        {
1407            public double value;
1408            public String key;
1409            public byte[] decryption;
1410            public byte[] keya;
1411        };
1412    }
1413
1414    /// <summary>
1415    /// Represents one entry in our result list
1416    /// </summary>
1417    public class ResultEntry
1418    {
1419        public string Ranking { get; set; }
1420        public string Value { get; set; }
1421        public string Key { get; set; }
1422        public string Text { get; set; }
1423
1424    }
1425}
Note: See TracBrowser for help on using the repository browser.