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

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

keysearcher:

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