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

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

Modified the bonus feature (Still testing)

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