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

Last change on this file since 2233 was 2233, checked in by nolte, 11 years ago

Statistic update. The CSV additionally shows the name of the host and the last time this computer gained a pattern point (PP)

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