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

Last change on this file since 2285 was 2285, checked in by matkovic, 11 years ago

-added sort for the statistics
-arranged position for the chunk display
-added ProgressBar color alternations
-fixed size
-added Chunk sum
-minor Design choices

By Viktor Matkovic, Dennis Nolte

File size: 63.7 KB
Line 
1/*                             
2   Copyright 2009 Sven Rech, Nils Kopal, Uni Duisburg-Essen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Diagnostics;
19using System.IO;
20using System.Linq;
21using System.Net;
22using System.Text;
23using Cryptool.P2P;
24using Cryptool.P2P.Internal;
25using Cryptool.PluginBase.Analysis;
26using Cryptool.PluginBase;
27using System.Windows.Controls;
28using System.ComponentModel;
29using Cryptool.PluginBase.Control;
30using System.Collections;
31using System.Collections.Generic;
32using System.Threading;
33using System.Windows.Threading;
34using Cryptool.PluginBase.IO;
35using System.Numerics;
36using KeySearcher.Helper;
37using KeySearcher.KeyPattern;
38using KeySearcher.P2P;
39using KeySearcher.P2P.Exceptions;
40using KeySearcherPresentation;
41using KeySearcherPresentation.Controls;
42using OpenCLNet;
43
44namespace KeySearcher
45{
46    [Author("Sven Rech, Nils Kopal, Raoul Falk, Dennis Nolte", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
47    [PluginInfo(false, "KeySearcher", "Bruteforces a decryption algorithm.", "KeySearcher/DetailedDescription/Description.xaml", "KeySearcher/Images/icon.png")]
48    public class KeySearcher : IAnalysisMisc
49    {
50        /// <summary>
51        /// used for creating the 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 BigInteger 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        private BigInteger keysInThisChunk;
729
730        // main entry point to the KeySearcher
731        private LinkedList<ValueKey> bruteforcePattern(KeyPattern.KeyPattern pattern)
732        {
733            beginBruteforcing = DateTime.Now;
734            GuiLogMessage("Start bruteforcing pattern '" + pattern.getKey() + "'", NotificationLevel.Debug);
735                       
736            int maxInList = 10;
737            costList = new LinkedList<ValueKey>();
738            fillListWithDummies(maxInList, costList);
739            valuequeue = Queue.Synchronized(new Queue());
740
741            statistic = new Dictionary<string, Dictionary<long, Information>>();
742            initialized = false;
743
744            stop = false;
745            if (!pattern.testWildcardKey(settings.Key))
746            {
747                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
748                return null;
749            }
750
751            // bytesToUse = 0;
752
753            try
754            {
755                bytesToUse = CostMaster.getBytesToUse();
756            }
757            catch (Exception ex)
758            {
759                GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
760                return null;
761            }
762
763            Thread serverThread = null;
764            try
765            {
766                if (settings.UseExternalClient)
767                {
768                    GuiLogMessage("Waiting for external client!", NotificationLevel.Info);
769                    cryptoolServer = new CryptoolServer();
770                    externalClientConnected = null;
771                    cryptoolServer.Port = settings.Port;
772                    cryptoolServer.OnJobCompleted += server_OnJobCompleted;
773                    cryptoolServer.OnClientConnected += server_OnClientConnected;
774                    cryptoolServer.OnClientDisconnected += cryptoolServer_OnClientDisconnected;
775                    serverThread = new Thread(new ThreadStart(delegate
776                                                                      {
777                                                                          cryptoolServer.Run();
778                                                                      }));
779                    serverThread.Start();
780                }
781
782                if (settings.UsePeerToPeer)
783                {
784                    BruteForceWithPeerToPeerSystem();
785                    return null;
786                }
787
788                return BruteForceWithLocalSystem(pattern);
789            }
790            finally
791            {
792                if (stop && serverThread != null)
793                {
794                    //stop server here!
795                    serverThread.Interrupt();
796                    cryptoolServer.OnJobCompleted -= server_OnJobCompleted;
797                    cryptoolServer.OnClientConnected -= server_OnClientConnected;
798                    cryptoolServer.OnClientDisconnected -= cryptoolServer_OnClientDisconnected;
799                }
800            }
801        }
802
803        private void BruteForceWithPeerToPeerSystem()
804        {
805            if (!update)
806            {
807                GuiLogMessage("Launching p2p based bruteforce logic...", NotificationLevel.Info);
808
809                try
810                {
811                    distributedBruteForceManager = new DistributedBruteForceManager(this, pattern, settings,
812                                                                                    keyQualityHelper,
813                                                                                    p2PQuickWatchPresentation);
814                    distributedBruteForceManager.Execute();
815                }
816                catch (NotConnectedException)
817                {
818                    GuiLogMessage("P2P not connected.", NotificationLevel.Error);
819                }
820                catch (KeySearcherStopException)
821                {
822                    update = true;
823                    return;
824                }
825            }
826            else
827            {
828                GuiLogMessage("Keysearcher Fullstop.Please Update your Version.", NotificationLevel.Error);
829                Thread.Sleep(3000);
830            }
831        }
832
833        internal LinkedList<ValueKey> BruteForceWithLocalSystem(KeyPattern.KeyPattern pattern, bool redirectResultsToStatisticsGenerator = false)
834        {
835            ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
836            {
837                openCLPresentationMutex.WaitOne();
838                ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices = 0;
839                openCLPresentationMutex.ReleaseMutex();
840            }, null);
841
842            if (!redirectResultsToStatisticsGenerator)
843            {
844                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(SetStartDate));
845                localBruteForceStopwatch.Start();
846            }
847
848            keysInThisChunk = pattern.size();
849
850            if (settings.UseExternalClient)
851            {
852                GuiLogMessage("Only using external client to bruteforce!", NotificationLevel.Info);
853                lock (this)
854                {
855                    externalKeySearcherOpenCLCode = new KeySearcherOpenCLCode(this, encryptedData, sender, CostMaster,
856                                                                              256*256*256*64);
857                    externalKeysProcessed = 0;
858                    externalKeyTranslator = ControlMaster.getKeyTranslator();
859                    externalKeyTranslator.SetKeys(pattern);
860                    if (externalClientConnected != null)
861                        AssignJobToClient(externalClientConnected, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
862                }
863                waitForExternalClientToFinish.Reset();
864                waitForExternalClientToFinish.WaitOne();
865            }
866            else
867            {
868                KeyPattern.KeyPattern[] patterns = splitPatternForThreads(pattern);
869                if (patterns == null || patterns.Length == 0)
870                {
871                    GuiLogMessage("No ressources to BruteForce available. Check the KeySearcher settings!", NotificationLevel.Error);
872                    throw new Exception("No ressources to BruteForce available. Check the KeySearcher settings!");
873                }
874
875                BigInteger[] doneKeysA = new BigInteger[patterns.Length];
876                BigInteger[] openCLDoneKeysA = new BigInteger[patterns.Length];
877                BigInteger[] keycounters = new BigInteger[patterns.Length];
878                BigInteger[] keysleft = new BigInteger[patterns.Length];
879                Stack threadStack = Stack.Synchronized(new Stack());
880                threadsStopEvents = ArrayList.Synchronized(new ArrayList());
881                StartThreads(sender, bytesToUse, patterns, doneKeysA, openCLDoneKeysA, keycounters, keysleft, threadStack);
882
883                DateTime lastTime = DateTime.Now;
884
885                //update message:
886                while (!stop)
887                {
888                    Thread.Sleep(2000);
889
890                    updateToplist();
891
892                    #region calculate global counters from local counters
893                    BigInteger keycounter = 0;
894                    BigInteger doneKeys = 0;
895                    BigInteger openCLdoneKeys = 0;
896                    foreach (BigInteger dk in doneKeysA)
897                        doneKeys += dk;
898                    foreach (BigInteger dk in openCLDoneKeysA)
899                        openCLdoneKeys += dk;
900                    foreach (BigInteger kc in keycounters)
901                        keycounter += kc;
902                    #endregion
903
904                    if (keycounter > keysInThisChunk)
905                        GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
906
907                    #region determination of the thread with most keys
908                    if (keysInThisChunk - keycounter > 1000)
909                    {
910                        try
911                        {
912                            maxThreadMutex.WaitOne();
913                            BigInteger max = 0;
914                            int id = -1;
915                            for (int i = 0; i < patterns.Length; i++)
916                                if (keysleft[i] != null && keysleft[i] > max)
917                                {
918                                    max = keysleft[i];
919                                    id = i;
920                                }
921                            maxThread = id;
922                        }
923                        finally
924                        {
925                            maxThreadMutex.ReleaseMutex();
926                        }
927                    }
928                    #endregion
929
930                    long keysPerSecond = (long)((long)doneKeys / (DateTime.Now - lastTime).TotalSeconds);
931                    long openCLKeysPerSecond = (long)((long)openCLdoneKeys / (DateTime.Now - lastTime).TotalSeconds);
932                    lastTime = DateTime.Now;
933                    if (redirectResultsToStatisticsGenerator)
934                    {
935                        distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList, keysInThisChunk, keycounter, keysPerSecond);
936                    }
937                    else
938                    {
939                        showProgress(costList, keysInThisChunk, keycounter, keysPerSecond);
940                    }
941
942                    //show OpenCL keys/sec:
943                    var ratio = (double)openCLdoneKeys / (double)doneKeys;
944                    ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
945                    {
946                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondOpenCL.Content = String.Format("{0:N}", openCLKeysPerSecond);
947                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondCPU.Content = String.Format("{0:N}", (keysPerSecond - openCLKeysPerSecond));
948                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.ratio.Content = String.Format("{0:P}", ratio);
949                    }, null);
950
951
952                    #region set doneKeys to 0
953                    doneKeys = 0;
954                    for (int i = 0; i < doneKeysA.Length; i++)
955                        doneKeysA[i] = 0;
956                    openCLdoneKeys = 0;
957                    for (int i = 0; i < openCLDoneKeysA.Length; i++)
958                        openCLDoneKeysA[i] = 0;
959                    #endregion
960
961                    if (keycounter >= keysInThisChunk)
962                        break;
963                }//end while
964
965                showProgress(costList, 1, 1, 1);
966
967                //wake up all sleeping threads, so they can stop:
968                while (threadStack.Count != 0)
969                    ((ThreadStackElement)threadStack.Pop()).ev.Set();
970
971                //wait until all threads finished:
972                foreach (AutoResetEvent stopEvent in threadsStopEvents)
973                {
974                    stopEvent.WaitOne();
975                }
976
977                if (!stop && !redirectResultsToStatisticsGenerator)
978                    ProgressChanged(1, 1);
979
980            }
981
982            /* BEGIN: For evaluation issues - added by Arnold 2010.03.17 */
983            TimeSpan bruteforcingTime = DateTime.Now.Subtract(beginBruteforcing);
984            StringBuilder sbBFTime = new StringBuilder();
985            if (bruteforcingTime.Days > 0)
986                sbBFTime.Append(bruteforcingTime.Days.ToString() + " days ");
987            if (bruteforcingTime.Hours > 0)
988            {
989                if (bruteforcingTime.Hours <= 9)
990                    sbBFTime.Append("0");
991                sbBFTime.Append(bruteforcingTime.Hours.ToString() + ":");
992            }
993            if (bruteforcingTime.Minutes <= 9)
994                sbBFTime.Append("0");
995            sbBFTime.Append(bruteforcingTime.Minutes.ToString() + ":");
996            if (bruteforcingTime.Seconds <= 9)
997                sbBFTime.Append("0");
998            sbBFTime.Append(bruteforcingTime.Seconds.ToString() + "-");
999            if (bruteforcingTime.Milliseconds <= 9)
1000                sbBFTime.Append("00");
1001            if (bruteforcingTime.Milliseconds <= 99)
1002                sbBFTime.Append("0");
1003            sbBFTime.Append(bruteforcingTime.Milliseconds.ToString());
1004
1005            GuiLogMessage("Ended bruteforcing pattern '" + pattern.getKey() + "'. Bruteforcing TimeSpan: " + sbBFTime.ToString(), NotificationLevel.Debug);
1006            /* END: For evaluation issues - added by Arnold 2010.03.17 */
1007
1008            return costList;
1009        }
1010
1011        #region External Client
1012
1013        void cryptoolServer_OnClientDisconnected(EndPoint client)
1014        {
1015            GuiLogMessage("Client disconnected!", NotificationLevel.Info);
1016            externalClientConnected = null;
1017        }
1018
1019        void server_OnClientConnected(System.Net.EndPoint client, string identification)
1020        {
1021            lock (this)
1022            {
1023                if (externalClientConnected == null)
1024                {
1025                    externalClientConnected = client;
1026                    GuiLogMessage(string.Format("Client {0} connected!", identification), NotificationLevel.Info);
1027                    AssignJobToClient(client, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
1028                }
1029                else
1030                {
1031                    GuiLogMessage("Client tried to connect, but only one client allowed!", NotificationLevel.Info);
1032                }
1033            }
1034        }
1035
1036        private void AssignJobToClient(EndPoint client, string src)
1037        {
1038            JobInput j = new JobInput();
1039            j.Guid = Guid.NewGuid().ToString();
1040            j.Src = src;
1041            var key = externalKeyTranslator.GetKey();
1042            j.Key = key;
1043            j.LargerThen = (costMaster.getRelationOperator() == RelationOperator.LargerThen);
1044            j.Size = externalKeyTranslator.GetOpenCLBatchSize();
1045            j.ResultSize = 10;
1046            GuiLogMessage(string.Format("Assigning new job with Guid {0} to client!", j.Guid), NotificationLevel.Info);
1047            cryptoolServer.SendJob(j, client);
1048            assignTime = DateTime.Now;
1049        }
1050
1051        void server_OnJobCompleted(System.Net.EndPoint client, JobResult jr)
1052        {
1053            GuiLogMessage(string.Format("Client returned result of job with Guid {0}!", jr.Guid), NotificationLevel.Info);
1054            //check:
1055            var op = this.costMaster.getRelationOperator();
1056            foreach (var res in jr.ResultList)
1057            {
1058                float cost = res.Key;
1059                if (((op == RelationOperator.LargerThen) && (cost > value_threshold))
1060                    || (op == RelationOperator.LessThen) && (cost < value_threshold))
1061                {
1062                    ValueKey valueKey = new ValueKey { value = cost, key = externalKeyTranslator.GetKeyRepresentation(res.Value) };
1063                    valueKey.keya = externalKeyTranslator.GetKeyFromRepresentation(valueKey.key);
1064                    valueKey.decryption = sender.Decrypt(this.encryptedData, valueKey.keya, InitVector, bytesToUse);
1065                    valuequeue.Enqueue(valueKey);
1066                }
1067            }
1068            updateToplist();
1069
1070            //progress:
1071            externalKeyTranslator.NextOpenCLBatch();
1072            int progress = externalKeyTranslator.GetProgress();
1073            externalKeysProcessed += progress;
1074            int keysPerSec = (int)(progress / (DateTime.Now - assignTime).TotalSeconds);
1075
1076            QuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1077                                                                                    {
1078                                                                                        if (!((QuickWatch)QuickWatchPresentation).IsP2PEnabled)
1079                                                                                            showProgress(costList, keysInThisChunk, externalKeysProcessed, keysPerSec);
1080                                                                                        else
1081                                                                                            distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList,
1082                                                                                                             keysInThisChunk, externalKeysProcessed, keysPerSec);
1083                                                                                    }, null);
1084
1085
1086            if (externalKeysProcessed != keysInThisChunk)
1087            {
1088                AssignJobToClient(client, null);
1089            }
1090            else
1091            {
1092                waitForExternalClientToFinish.Set();
1093            }
1094        }
1095
1096        #endregion
1097
1098        private void SetStartDate()
1099        {
1100            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
1101        }
1102
1103        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, long keysPerSecond)
1104        {
1105            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
1106
1107            LinkedListNode<ValueKey> linkedListNode;
1108            ProgressChanged((double)keycounter / (double)size, 1.0);
1109
1110            if (localQuickWatchPresentation.IsVisible && keysPerSecond != 0 && !stop)
1111            {
1112                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - Math.Log10(keysPerSecond)));
1113                TimeSpan timeleft = new TimeSpan(-1);
1114
1115                try
1116                {
1117                    if (time / (24 * 60 * 60) <= int.MaxValue)
1118                    {
1119                        int days = (int)(time / (24 * 60 * 60));
1120                        time = time - (days * 24 * 60 * 60);
1121                        int hours = (int)(time / (60 * 60));
1122                        time = time - (hours * 60 * 60);
1123                        int minutes = (int)(time / 60);
1124                        time = time - (minutes * 60);
1125                        int seconds = (int)time;
1126
1127                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
1128                    }
1129                }
1130                catch
1131                {
1132                    //can not calculate time span
1133                }
1134
1135                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1136                {
1137                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
1138                    localQuickWatchPresentation.keysPerSecond.Content = String.Format("{0:0,0}", keysPerSecond);
1139                    if (timeleft != new TimeSpan(-1))
1140                    {
1141                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
1142                        try
1143                        {
1144                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
1145                        }
1146                        catch
1147                        {
1148                            localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
1149                        }
1150                    }
1151                    else
1152                    {
1153                        localQuickWatchPresentation.timeLeft.Content = "incalculable :-)";
1154                        localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
1155                    }
1156
1157                    localQuickWatchPresentation.entries.Clear();
1158                    linkedListNode = costList.First;
1159
1160                    int i = 0;
1161                    while (linkedListNode != null)
1162                    {
1163                        i++;
1164
1165                        ResultEntry entry = new ResultEntry();
1166                        entry.Ranking = "" + i;
1167                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1168                        entry.Key = linkedListNode.Value.key;
1169                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1170
1171                        localQuickWatchPresentation.entries.Add(entry);
1172                        linkedListNode = linkedListNode.Next;
1173                    }
1174                }
1175                , null);
1176            }//end if
1177            else if (!stop && localQuickWatchPresentation.IsVisible)
1178            {
1179
1180                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1181                {
1182                    localQuickWatchPresentation.entries.Clear();
1183                    linkedListNode = costList.First;
1184                    int i = 0;
1185
1186                    while (linkedListNode != null)
1187                    {
1188                        i++;
1189
1190                        ResultEntry entry = new ResultEntry();
1191                        entry.Ranking = "" + i;
1192                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1193                        entry.Key = linkedListNode.Value.key;
1194                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1195
1196                        localQuickWatchPresentation.entries.Add(entry);
1197                        linkedListNode = linkedListNode.Next;
1198                    }
1199                }
1200                , null);
1201            }
1202        }
1203
1204        #region For TopList
1205
1206        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
1207        {
1208            ValueKey valueKey = new ValueKey();
1209            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
1210                valueKey.value = double.MaxValue;
1211            else
1212                valueKey.value = double.MinValue;
1213            valueKey.key = "dummykey";
1214            valueKey.decryption = new byte[0];
1215            value_threshold = valueKey.value;
1216            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
1217            for (int i = 1; i < maxInList; i++)
1218            {
1219                node = costList.AddAfter(node, valueKey);
1220            }
1221        }
1222
1223        public void SetInitialized(bool ini)
1224        {
1225            this.initialized = ini;
1226        }
1227        public Dictionary<string, Dictionary<long, Information>> GetStatistics()
1228        {
1229            return statistic;
1230        }
1231        public void ResetStatistics()
1232        {
1233            statistic = null;
1234            statistic = new Dictionary<string, Dictionary<long, Information>>();
1235        }
1236
1237        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList, Dictionary<string, Dictionary<long, Information>> updatedStatistics, string dataIdentifier)
1238        {
1239            foreach (var valueKey in updatedCostList)
1240            {
1241                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
1242                {
1243                    valuequeue.Enqueue(valueKey);
1244                }
1245            }
1246
1247            foreach (string avname in updatedStatistics.Keys)
1248            {
1249                //taking the dictionary in this avatarname
1250                Dictionary<long, Information> MaschCount = updatedStatistics[avname];
1251               
1252                //if the avatarname already exists in the statistics
1253                if (statistic.ContainsKey(avname))
1254                {
1255                    foreach (long id in MaschCount.Keys)
1256                    {
1257                        //get the statistic maschcount for this avatarname
1258                        Dictionary<long, Information> statMaschCount = statistic[avname];
1259
1260                        //if the id of the Maschine already exists for this avatarname
1261                        if (statMaschCount.ContainsKey(id))
1262                        {
1263                            if (!initialized || ((MaschCount[id].Count == 1) && (MaschCount.Keys.Count == 1)))
1264                            {
1265                                statMaschCount[id].Count = statMaschCount[id].Count + MaschCount[id].Count;
1266                                statMaschCount[id].Hostname = MaschCount[id].Hostname;
1267                                statMaschCount[id].Date = MaschCount[id].Date;
1268                                statistic[avname] = statMaschCount;
1269                            }
1270                        }
1271                        else
1272                        {
1273                            //add a new id,information value for this avatarname
1274                            statistic[avname].Add(id, MaschCount[id]);
1275                        }
1276                    }
1277                }
1278                else
1279                {
1280                    //add the maschinecount dictionary to this avatarname
1281                    statistic[avname] = MaschCount;
1282                }
1283
1284                statistic[avname] = statistic[avname].OrderByDescending((x) => x.Value.Count).ToDictionary(x => x.Key, y => y.Value);
1285            }         
1286            WriteStatistics(dataIdentifier);
1287
1288            ((QuickWatch) QuickWatchPresentation).StatisticsPresentation.Statistics = statistic;
1289            updateToplist();
1290        }
1291
1292        //Write the User Statistics to an external csv-document
1293        internal void WriteStatistics(String dataIdentifier)
1294        {
1295            if (settings.CsvPath == "")
1296            {
1297                //using the default save folder %APPDATA%\Local\Cryptool2
1298                using (StreamWriter sw = new StreamWriter(string.Format("{0}\\UserRanking{1}.csv", DirectoryHelper.DirectoryLocal, dataIdentifier)))
1299                {
1300                    sw.WriteLine("Avatarname" + ";" + "MaschineID" + ";" + "Hostname" + ";" + "Pattern Count" + ";" + "Last Update");
1301                    foreach (string avatar in statistic.Keys)
1302                    {
1303                        foreach (long mID in statistic[avatar].Keys)
1304                        {
1305                            sw.WriteLine(avatar + ";" + mID.ToString() + ";" + statistic[avatar][mID].Hostname + ";" + statistic[avatar][mID].Count + ";" + statistic[avatar][mID].Date);
1306                        }
1307                    }
1308                }
1309            }
1310            else 
1311            {
1312                //using the chosen csv file
1313                using (StreamWriter sw = new StreamWriter(settings.CsvPath))
1314                {
1315                    sw.WriteLine("Avatarname" + ";" + "MaschineID" + ";" + "Hostname" + ";" + "Pattern Count" + ";" + "Last Update");
1316                    foreach (string avatar in statistic.Keys)
1317                    {
1318                        foreach (long mID in statistic[avatar].Keys)
1319                        {
1320                            sw.WriteLine(avatar + ";" + mID.ToString() + ";" + statistic[avatar][mID].Hostname + ";" + statistic[avatar][mID].Count + ";" + statistic[avatar][mID].Date);
1321                        }
1322                    }
1323                }
1324            }
1325        }
1326
1327        internal void updateToplist()
1328        {
1329            LinkedListNode<ValueKey> node;
1330            while (valuequeue.Count != 0)
1331            {
1332                ValueKey vk = (ValueKey)valuequeue.Dequeue();
1333
1334                //if (costList.Contains(vk)) continue;
1335                var result = costList.Where(valueKey => valueKey.key == vk.key);
1336                if (result.Count() > 0)
1337                {
1338                    continue;
1339                }
1340
1341                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
1342                {
1343                    if (vk.value > costList.Last().value)
1344                    {
1345                        node = costList.First;
1346                        while (node != null)
1347                        {
1348                            if (vk.value > node.Value.value)
1349                            {
1350                                if (node == costList.First)
1351                                    Top1 = vk;
1352                                costList.AddBefore(node, vk);
1353                                costList.RemoveLast();
1354                                value_threshold = costList.Last.Value.value;
1355                                break;
1356                            }
1357                            node = node.Next;
1358                        }//end while
1359                    }//end if
1360                }
1361                else
1362                {
1363                    if (vk.value < costList.Last().value)
1364                    {
1365                        node = costList.First;
1366                        while (node != null)
1367                        {
1368                            if (vk.value < node.Value.value)
1369                            {
1370                                if (node == costList.First)
1371                                    Top1 = vk;
1372                                costList.AddBefore(node, vk);
1373                                costList.RemoveLast();
1374                                value_threshold = costList.Last.Value.value;
1375                                break;
1376                            }
1377                            node = node.Next;
1378                        }//end while
1379                    }//end if
1380                }
1381            }
1382        }
1383
1384        #endregion
1385
1386        private void StartThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] openCLDoneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
1387        {
1388            //First start the opencl threads:
1389            int i = 0;
1390            foreach (var ds in settings.DeviceSettings)
1391            {
1392                if (ds.useDevice)
1393                {
1394                    WaitCallback worker = new WaitCallback(KeySearcherJob);
1395                    doneKeysA[i] = new BigInteger();
1396                    openCLDoneKeysA[i] = new BigInteger();
1397                    keycounters[i] = new BigInteger();
1398
1399                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, ds });
1400                    i++;
1401                }
1402            }
1403
1404            //Then the CPU threads:
1405            for (; i < patterns.Length; i++)
1406            {
1407                WaitCallback worker = new WaitCallback(KeySearcherJob);
1408                doneKeysA[i] = new BigInteger();
1409                openCLDoneKeysA[i] = new BigInteger();
1410                keycounters[i] = new BigInteger();
1411
1412                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, null });
1413            }
1414        }
1415
1416        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
1417        {
1418            int threads = settings.CoresUsed;
1419            threads += settings.DeviceSettings.Count(x => x.useDevice); 
1420
1421            if (threads < 1)
1422                return null;
1423
1424            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[threads];
1425            if (threads > 1)
1426            {
1427                KeyPattern.KeyPattern[] patterns2 = pattern.split();
1428                if (patterns2 == null)
1429                {
1430                    patterns2 = new KeyPattern.KeyPattern[1];
1431                    patterns2[0] = pattern;
1432                    return patterns2;
1433                }
1434                patterns[0] = patterns2[0];
1435                patterns[1] = patterns2[1];
1436                int p = 1;
1437                threads -= 2;
1438
1439                while (threads > 0)
1440                {
1441                    int maxPattern = -1;
1442                    BigInteger max = 0;
1443                    for (int i = 0; i <= p; i++)
1444                        if (patterns[i].size() > max)
1445                        {
1446                            max = patterns[i].size();
1447                            maxPattern = i;
1448                        }
1449                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
1450                    if (patterns3 == null)
1451                    {
1452                        patterns3 = new KeyPattern.KeyPattern[p+1];
1453                        for (int i = 0; i <= p; i++)
1454                            patterns3[i] = patterns[i];
1455                        return patterns3;
1456                    }
1457                    patterns[maxPattern] = patterns3[0];
1458                    patterns[++p] = patterns3[1];
1459                    threads--;
1460                }
1461            }
1462            else
1463                patterns[0] = pattern;
1464            return patterns;
1465        }
1466
1467        private void keyPatternChanged()
1468        {
1469            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
1470        }
1471
1472        // added by Arnie - 2009.12.07
1473        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
1474        /// <summary>
1475        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
1476        /// But when the returned List is filled, we have (at least a part) of the possible best keys
1477        /// </summary>
1478        public event BruteforcingEnded OnBruteforcingEnded;
1479
1480        // added by Arnie -2009.12.02
1481        // for inheritance reasons
1482        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
1483        {
1484            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1485            this.encryptedData = encryptedData;
1486            this.initVector = initVector;
1487            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1488
1489            this.sender = encryptControl;
1490            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
1491            if(OnBruteforcingEnded != null)
1492                OnBruteforcingEnded(lstRet);
1493        }
1494
1495        #endregion
1496
1497        public void GuiLogMessage(string message, NotificationLevel loglevel)
1498        {
1499            if (OnGuiLogNotificationOccured != null)
1500                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
1501        }
1502
1503        public void ProgressChanged(double value, double max)
1504        {
1505            if (OnPluginProgressChanged != null)
1506            {
1507                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1508
1509            }
1510        }
1511
1512        /// <summary>
1513        /// used for delivering the results from the worker threads to the main thread:
1514        /// </summary>
1515        public struct ValueKey
1516        {
1517            public double value;
1518            public String key;
1519            public byte[] decryption;
1520            public byte[] keya;
1521        };
1522    }
1523
1524    /// <summary>
1525    /// Represents one entry in our result list
1526    /// </summary>
1527    public class ResultEntry
1528    {
1529        public string Ranking { get; set; }
1530        public string Value { get; set; }
1531        public string Key { get; set; }
1532        public string Text { get; set; }
1533    }
1534    /// <summary>
1535    /// Represents one entry in our statistic list
1536    /// </summary>
1537    public class Information
1538    {
1539        public int Count { get; set; }
1540        public string Hostname { get; set; }
1541        public DateTime Date { get; set; }
1542    } 
1543}
Note: See TracBrowser for help on using the repository browser.