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

Last change on this file since 2476 was 2476, checked in by Sven Rech, 10 years ago

keysearcher speed fix

File size: 69.0 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                    EnhanceUserName(valueKey);
586                    valuequeue.Enqueue(valueKey);
587                }
588            }
589        }
590
591        private bool BruteforceCPU(IKeyTranslator keyTranslator, IControlEncryption sender, int bytesToUse)
592        {
593            bool finish = false;
594            for (int count = 0; count < 256 * 256; count++)
595            {
596                byte[] keya = keyTranslator.GetKey();
597
598                if (!decryptAndCalculate(sender, bytesToUse, keya, keyTranslator))
599                    throw new Exception("Bruteforcing not possible!");
600
601                finish = !keyTranslator.NextKey();
602                if (finish)
603                    break;
604            }
605            return finish;
606        }
607
608        private IKeyTranslator ShareKeys(KeyPattern.KeyPattern[] patterns, int threadid, BigInteger[] keysLeft, IKeyTranslator keyTranslator, Stack threadStack)
609        {
610            BigInteger size;
611            if (maxThread == threadid && threadStack.Count != 0)
612            {
613                try
614                {
615                    maxThreadMutex.WaitOne();
616                    if (maxThread == threadid && threadStack.Count != 0)
617                    {
618                        KeyPattern.KeyPattern[] split = patterns[threadid].split();
619                        if (split != null)
620                        {
621                            patterns[threadid] = split[0];
622                            keyTranslator = ControlMaster.getKeyTranslator();
623                            keyTranslator.SetKeys(patterns[threadid]);
624
625                            ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
626                            patterns[elem.threadid] = split[1];
627                            elem.ev.Set();    //wake the other thread up                                   
628                            size = patterns[threadid].size();
629                            keysLeft[threadid] = size;
630                        }
631                        maxThread = -1;
632                    }
633                }
634                finally
635                {
636                    maxThreadMutex.ReleaseMutex();
637                }
638            }
639            return keyTranslator;
640        }
641
642        private void WaitForNewPattern(KeyPattern.KeyPattern[] patterns, int threadid, Stack threadStack)
643        {
644            ThreadStackElement el = new ThreadStackElement();
645            el.ev = new AutoResetEvent(false);
646            el.threadid = threadid;
647            patterns[threadid] = null;
648            threadStack.Push(el);
649            GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
650            el.ev.WaitOne();
651            if (!stop)
652            {
653                GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
654            }
655        }
656
657        #region bruteforce methods
658
659        private bool decryptAndCalculate(IControlEncryption sender, int bytesToUse, byte[] keya, IKeyTranslator keyTranslator)
660        {
661            ValueKey valueKey = new ValueKey();
662
663            try
664            {
665                if (this.encryptedData != null && this.encryptedData.Length > 0)
666                {
667                    valueKey.decryption = sender.Decrypt(this.encryptedData, keya, InitVector, bytesToUse);
668                }
669                else
670                {
671                    GuiLogMessage("Can't bruteforce empty input!", NotificationLevel.Error);
672                    return false;
673                }
674            }
675            catch (Exception ex)
676            {
677                GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
678                GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
679                return false;
680            }
681
682            try
683            {
684                valueKey.value = CostMaster.calculateCost(valueKey.decryption);
685            }
686            catch (Exception ex)
687            {
688                GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
689                return false;
690            }
691
692            if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
693            {
694                if (valueKey.value > value_threshold)
695                {
696                    valueKey.key = keyTranslator.GetKeyRepresentation();
697                    valueKey.keya = (byte[])keya.Clone();
698                    EnhanceUserName(valueKey);
699                    valuequeue.Enqueue(valueKey);
700                }
701            }
702            else
703            {
704                if (valueKey.value < value_threshold)
705                {
706                    valueKey.key = keyTranslator.GetKeyRepresentation();
707                    valueKey.keya = (byte[])keya.Clone();
708                    EnhanceUserName(valueKey);
709                    valuequeue.Enqueue(valueKey);
710                }
711            }
712            return true;
713        }
714
715        #endregion
716
717        #endregion
718
719        public void process(IControlEncryption sender)
720        {
721            if (sender == null || costMaster == null)
722                return;
723            if (!Pattern.testWildcardKey(settings.Key))
724            {
725                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
726                return;
727            }
728            Pattern.WildcardKey = settings.Key;
729            this.sender = sender;
730
731            bruteforcePattern(Pattern);
732        }
733
734        internal LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
735        private int bytesToUse;
736        private IControlEncryption sender;
737        private DateTime beginBruteforcing;
738        private DistributedBruteForceManager distributedBruteForceManager;
739        private BigInteger keysInThisChunk;
740
741        // main entry point to the KeySearcher
742        private LinkedList<ValueKey> bruteforcePattern(KeyPattern.KeyPattern pattern)
743        {
744            beginBruteforcing = DateTime.Now;
745            GuiLogMessage(Resources.Start_bruteforcing_pattern__ + pattern.getKey() + "'", NotificationLevel.Debug);
746                       
747            int maxInList = 10;
748            costList = new LinkedList<ValueKey>();
749            fillListWithDummies(maxInList, costList);
750            valuequeue = Queue.Synchronized(new Queue());
751
752            statistic = new Dictionary<string, Dictionary<long, Information>>();
753            maschinehierarchie = new Dictionary<long, Maschinfo>();
754            initialized = false;
755
756            stop = false;
757            if (!pattern.testWildcardKey(settings.Key))
758            {
759                GuiLogMessage(Resources.Wrong_key_pattern_, NotificationLevel.Error);
760                return null;
761            }
762
763            // bytesToUse = 0;
764
765            try
766            {
767                bytesToUse = CostMaster.getBytesToUse();
768            }
769            catch (Exception ex)
770            {
771                GuiLogMessage(Resources.Bytes_used_not_valid__ + ex.Message, NotificationLevel.Error);
772                return null;
773            }
774
775            Thread serverThread = null;
776            try
777            {
778                if (settings.UseExternalClient)
779                {
780                    GuiLogMessage(Resources.Waiting_for_external_client_, NotificationLevel.Info);
781                    if (cryptoolServer != null)
782                    {
783
784                    }
785                    cryptoolServer = new CryptoolServer();
786                    waitingExternalClients.Clear();
787                    cryptoolServer.Port = settings.Port;
788                    cryptoolServer.OnJobCompleted += cryptoolServer_OnJobCompleted;
789                    cryptoolServer.OnClientAuth = cryptoolServer_OnClientAuth;
790                    cryptoolServer.OnClientDisconnected += cryptoolServer_OnClientDisconnected;
791                    cryptoolServer.OnClientRequestedJob += cryptoolServer_OnClientRequestedJob;
792                    cryptoolServer.OnErrorLog += cryptoolServer_OnErrorLog;
793                    serverThread = new Thread(new ThreadStart(delegate
794                                                                      {
795                                                                          cryptoolServer.Run();
796                                                                      }));
797                    serverThread.Start();
798                }
799
800                if (settings.UsePeerToPeer)
801                {
802                    BruteForceWithPeerToPeerSystem();
803                    return null;
804                }
805
806                return BruteForceWithLocalSystem(pattern);
807            }
808            finally
809            {
810                if (serverThread != null)
811                {
812                    //stop server here!
813                    cryptoolServer.Shutdown();
814                    cryptoolServer.OnJobCompleted -= cryptoolServer_OnJobCompleted;
815                    cryptoolServer.OnClientAuth = null;
816                    cryptoolServer.OnClientDisconnected -= cryptoolServer_OnClientDisconnected;
817                    cryptoolServer.OnClientRequestedJob -= cryptoolServer_OnClientRequestedJob;
818                    cryptoolServer.OnErrorLog -= cryptoolServer_OnErrorLog;
819                }
820            }
821        }
822
823        private void BruteForceWithPeerToPeerSystem()
824        {
825            if (!update)
826            {
827                GuiLogMessage(Resources.Launching_p2p_based_bruteforce_logic___, NotificationLevel.Info);
828
829                try
830                {
831                    distributedBruteForceManager = new DistributedBruteForceManager(this, pattern, settings,
832                                                                                    keyQualityHelper,
833                                                                                    p2PQuickWatchPresentation);
834                    distributedBruteForceManager.Execute();
835                }
836                catch (NotConnectedException)
837                {
838                    GuiLogMessage(Resources.P2P_not_connected_, NotificationLevel.Error);
839                }
840                catch (KeySearcherStopException)
841                {
842                    update = true;
843                    return;
844                }
845            }
846            else
847            {
848                GuiLogMessage(Resources.Keysearcher_Fullstop__Please_Update_your_Version_, NotificationLevel.Error);
849                Thread.Sleep(3000);
850            }
851        }
852
853        internal LinkedList<ValueKey> BruteForceWithLocalSystem(KeyPattern.KeyPattern pattern, bool redirectResultsToStatisticsGenerator = false)
854        {
855            ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
856            {
857                openCLPresentationMutex.WaitOne();
858                ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices = 0;
859                openCLPresentationMutex.ReleaseMutex();
860            }, null);
861
862            if (!redirectResultsToStatisticsGenerator)
863            {
864                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(SetStartDate));
865                localBruteForceStopwatch.Start();
866            }
867
868            keysInThisChunk = pattern.size();
869
870            if (settings.UseExternalClient)
871            {
872                GuiLogMessage(Resources.Only_using_external_client_to_bruteforce_, NotificationLevel.Info);
873                lock (this)
874                {
875                    externalKeySearcherOpenCLCode = new KeySearcherOpenCLCode(this, encryptedData, sender, CostMaster,
876                                                                              256*256*256*64);
877                    externalKeysProcessed = 0;
878                    externalKeyTranslator = ControlMaster.getKeyTranslator();
879                    externalKeyTranslator.SetKeys(pattern);
880                    currentExternalJobGuid = Guid.NewGuid();
881                    foreach (var client in waitingExternalClients)
882                    {
883                        AssignJobToClient(client, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
884                    }
885                    waitingExternalClients.Clear();
886                    externalClientJobsAvailable = true;
887                }
888                waitForExternalClientToFinish.Reset();
889                waitForExternalClientToFinish.WaitOne();
890                lock (this)
891                {
892                    externalClientJobsAvailable = false;
893                }
894            }
895            else
896            {
897                KeyPattern.KeyPattern[] patterns = splitPatternForThreads(pattern);
898                if (patterns == null || patterns.Length == 0)
899                {
900                    GuiLogMessage(Resources.No_ressources_to_BruteForce_available__Check_the_KeySearcher_settings_, NotificationLevel.Error);
901                    throw new Exception("No ressources to BruteForce available. Check the KeySearcher settings!");
902                }
903
904                BigInteger[] doneKeysA = new BigInteger[patterns.Length];
905                BigInteger[] openCLDoneKeysA = new BigInteger[patterns.Length];
906                BigInteger[] keycounters = new BigInteger[patterns.Length];
907                BigInteger[] keysleft = new BigInteger[patterns.Length];
908                Stack threadStack = Stack.Synchronized(new Stack());
909                threadsStopEvents = ArrayList.Synchronized(new ArrayList());
910                StartThreads(sender, bytesToUse, patterns, doneKeysA, openCLDoneKeysA, keycounters, keysleft, threadStack);
911
912                DateTime lastTime = DateTime.Now;
913
914                //update message:
915                while (!stop)
916                {
917                    Thread.Sleep(2000);
918
919                    updateToplist();
920
921                    #region calculate global counters from local counters
922                    BigInteger keycounter = 0;
923                    BigInteger doneKeys = 0;
924                    BigInteger openCLdoneKeys = 0;
925                    foreach (BigInteger dk in doneKeysA)
926                        doneKeys += dk;
927                    foreach (BigInteger dk in openCLDoneKeysA)
928                        openCLdoneKeys += dk;
929                    foreach (BigInteger kc in keycounters)
930                        keycounter += kc;
931                    #endregion
932
933                    if (keycounter > keysInThisChunk)
934                        GuiLogMessage(Resources.There_must_be_an_error__because_we_bruteforced_too_much_keys___, NotificationLevel.Error);
935
936                    #region determination of the thread with most keys
937                    if (keysInThisChunk - keycounter > 1000)
938                    {
939                        try
940                        {
941                            maxThreadMutex.WaitOne();
942                            BigInteger max = 0;
943                            int id = -1;
944                            for (int i = 0; i < patterns.Length; i++)
945                                if (keysleft[i] != null && keysleft[i] > max)
946                                {
947                                    max = keysleft[i];
948                                    id = i;
949                                }
950                            maxThread = id;
951                        }
952                        finally
953                        {
954                            maxThreadMutex.ReleaseMutex();
955                        }
956                    }
957                    #endregion
958
959                    long keysPerSecond = (long)((long)doneKeys / (DateTime.Now - lastTime).TotalSeconds);
960                    long openCLKeysPerSecond = (long)((long)openCLdoneKeys / (DateTime.Now - lastTime).TotalSeconds);
961                    lastTime = DateTime.Now;
962                    if (redirectResultsToStatisticsGenerator)
963                    {
964                        distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList, keysInThisChunk, keycounter, keysPerSecond);
965                    }
966                    else
967                    {
968                        showProgress(costList, keysInThisChunk, keycounter, keysPerSecond);
969                    }
970
971                    //show OpenCL keys/sec:
972                    var ratio = (double)openCLdoneKeys / (double)doneKeys;
973                    ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
974                    {
975                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondOpenCL.Content = String.Format("{0:N}", openCLKeysPerSecond);
976                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondCPU.Content = String.Format("{0:N}", (keysPerSecond - openCLKeysPerSecond));
977                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.ratio.Content = String.Format("{0:P}", ratio);
978                    }, null);
979
980
981                    #region set doneKeys to 0
982                    doneKeys = 0;
983                    for (int i = 0; i < doneKeysA.Length; i++)
984                        doneKeysA[i] = 0;
985                    openCLdoneKeys = 0;
986                    for (int i = 0; i < openCLDoneKeysA.Length; i++)
987                        openCLDoneKeysA[i] = 0;
988                    #endregion
989
990                    if (keycounter >= keysInThisChunk)
991                        break;
992                }//end while
993
994                showProgress(costList, 1, 1, 1);
995
996                //wake up all sleeping threads, so they can stop:
997                while (threadStack.Count != 0)
998                    ((ThreadStackElement)threadStack.Pop()).ev.Set();
999
1000                //wait until all threads finished:
1001                foreach (AutoResetEvent stopEvent in threadsStopEvents)
1002                {
1003                    stopEvent.WaitOne();
1004                }
1005
1006                if (!stop && !redirectResultsToStatisticsGenerator)
1007                    ProgressChanged(1, 1);
1008
1009            }
1010
1011            /* BEGIN: For evaluation issues - added by Arnold 2010.03.17 */
1012            TimeSpan bruteforcingTime = DateTime.Now.Subtract(beginBruteforcing);
1013            StringBuilder sbBFTime = new StringBuilder();
1014            if (bruteforcingTime.Days > 0)
1015                sbBFTime.Append(bruteforcingTime.Days.ToString() + Resources._days_);
1016            if (bruteforcingTime.Hours > 0)
1017            {
1018                if (bruteforcingTime.Hours <= 9)
1019                    sbBFTime.Append("0");
1020                sbBFTime.Append(bruteforcingTime.Hours.ToString() + ":");
1021            }
1022            if (bruteforcingTime.Minutes <= 9)
1023                sbBFTime.Append("0");
1024            sbBFTime.Append(bruteforcingTime.Minutes.ToString() + ":");
1025            if (bruteforcingTime.Seconds <= 9)
1026                sbBFTime.Append("0");
1027            sbBFTime.Append(bruteforcingTime.Seconds.ToString() + "-");
1028            if (bruteforcingTime.Milliseconds <= 9)
1029                sbBFTime.Append("00");
1030            if (bruteforcingTime.Milliseconds <= 99)
1031                sbBFTime.Append("0");
1032            sbBFTime.Append(bruteforcingTime.Milliseconds.ToString());
1033
1034            GuiLogMessage(Resources.Ended_bruteforcing_pattern__ + pattern.getKey() + Resources.___Bruteforcing_TimeSpan__ + sbBFTime.ToString(), NotificationLevel.Debug);
1035            /* END: For evaluation issues - added by Arnold 2010.03.17 */
1036
1037            return costList;
1038        }
1039
1040        #region External Client
1041
1042        void cryptoolServer_OnClientDisconnected(EndPoint client)
1043        {
1044            GuiLogMessage(Resources.Client_disconnected_, NotificationLevel.Info);
1045            lock (this)
1046            {
1047                waitingExternalClients.Remove(client);
1048            }
1049        }
1050
1051        bool cryptoolServer_OnClientAuth(System.Net.EndPoint client, string name, string password)
1052        {
1053            if(settings.ExternalClientPassword.Length == 0 ||
1054                settings.ExternalClientPassword == password)
1055            {
1056                GuiLogMessage(string.Format(Resources.Client__0__connected_, name), NotificationLevel.Info);
1057                return true;
1058            }
1059            GuiLogMessage(string.Format(Resources.Client__0__tried_to_auth_with_invalid_password, name), NotificationLevel.Info);
1060            return false;
1061        }
1062
1063        private void AssignJobToClient(EndPoint client, string src)
1064        {
1065            JobInput j = new JobInput();
1066            j.Guid = currentExternalJobGuid.ToString();
1067            j.Src = src;
1068            var key = externalKeyTranslator.GetKey();
1069            j.Key = key;
1070            j.LargerThen = (costMaster.getRelationOperator() == RelationOperator.LargerThen);
1071            j.Size = externalKeyTranslator.GetOpenCLBatchSize();
1072            j.ResultSize = 10;
1073            GuiLogMessage(string.Format(Resources.Assigning_new_job_with_Guid__0__to_client_, j.Guid), NotificationLevel.Info);
1074            cryptoolServer.SendJob(j, client);
1075            assignTime = DateTime.Now;
1076        }
1077
1078        void cryptoolServer_OnJobCompleted(System.Net.EndPoint client, JobResult jr)
1079        {
1080            GuiLogMessage(string.Format(Resources.Client_returned_result_of_job_with_Guid__0__, jr.Guid), NotificationLevel.Info);
1081            lock (this)
1082            {
1083                if (!jr.Guid.Equals(currentExternalJobGuid.ToString()))
1084                {
1085                    GuiLogMessage(string.Format(Resources.Received_late_job_result_0_from_client_1, jr.Guid, client), NotificationLevel.Warning);
1086                    return;
1087                }
1088
1089                // Set new guid. Will prevent concurrent clients
1090                // from supplying old results for new chunks.
1091                currentExternalJobGuid = Guid.NewGuid();
1092            }
1093            //check:
1094            var op = this.costMaster.getRelationOperator();
1095            foreach (var res in jr.ResultList)
1096            {
1097                float cost = res.Key;
1098                if (((op == RelationOperator.LargerThen) && (cost > value_threshold))
1099                    || (op == RelationOperator.LessThen) && (cost < value_threshold))
1100                {
1101                    ValueKey valueKey = new ValueKey { value = cost, key = externalKeyTranslator.GetKeyRepresentation(res.Value) };
1102                    valueKey.keya = externalKeyTranslator.GetKeyFromRepresentation(valueKey.key);
1103                    valueKey.decryption = sender.Decrypt(this.encryptedData, valueKey.keya, InitVector, bytesToUse);
1104
1105                    EnhanceUserName(valueKey);
1106                    valuequeue.Enqueue(valueKey);
1107                }
1108            }
1109            updateToplist();
1110
1111            //progress:
1112            externalKeyTranslator.NextOpenCLBatch();
1113            int progress = externalKeyTranslator.GetProgress();
1114            externalKeysProcessed += progress;
1115            int keysPerSec = (int)(progress / (DateTime.Now - assignTime).TotalSeconds);
1116
1117            QuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1118                                                                                    {
1119                                                                                        if (!((QuickWatch)QuickWatchPresentation).IsP2PEnabled)
1120                                                                                            showProgress(costList, keysInThisChunk, externalKeysProcessed, keysPerSec);
1121                                                                                        else
1122                                                                                            distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList,
1123                                                                                                             keysInThisChunk, externalKeysProcessed, keysPerSec);
1124                                                                                    }, null);
1125
1126            if (externalKeysProcessed == keysInThisChunk)
1127            {
1128                waitForExternalClientToFinish.Set();
1129                lock (this)
1130                {
1131                    externalClientJobsAvailable = false;
1132                }
1133            }
1134        }
1135
1136        void cryptoolServer_OnErrorLog(string str)
1137        {
1138            GuiLogMessage(str, NotificationLevel.Error);
1139        }
1140
1141        void cryptoolServer_OnClientRequestedJob(EndPoint ipep)
1142        {
1143            lock (this)
1144            {
1145                if(externalClientJobsAvailable)
1146                {
1147                    AssignJobToClient(ipep, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
1148                }
1149                else
1150                {
1151                    waitingExternalClients.Add(ipep);
1152                }
1153            }
1154       
1155        }
1156
1157        #endregion
1158
1159        private void SetStartDate()
1160        {
1161            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
1162        }
1163
1164        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, long keysPerSecond)
1165        {
1166            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
1167
1168            LinkedListNode<ValueKey> linkedListNode;
1169            ProgressChanged((double)keycounter / (double)size, 1.0);
1170
1171            if (localQuickWatchPresentation.IsVisible && keysPerSecond != 0 && !stop)
1172            {
1173                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - Math.Log10(keysPerSecond)));
1174                TimeSpan timeleft = new TimeSpan(-1);
1175
1176                try
1177                {
1178                    if (time / (24 * 60 * 60) <= int.MaxValue)
1179                    {
1180                        int days = (int)(time / (24 * 60 * 60));
1181                        time = time - (days * 24 * 60 * 60);
1182                        int hours = (int)(time / (60 * 60));
1183                        time = time - (hours * 60 * 60);
1184                        int minutes = (int)(time / 60);
1185                        time = time - (minutes * 60);
1186                        int seconds = (int)time;
1187
1188                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
1189                    }
1190                }
1191                catch
1192                {
1193                    //can not calculate time span
1194                }
1195
1196                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1197                {
1198                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
1199                    localQuickWatchPresentation.keysPerSecond.Content = String.Format("{0:0,0}", keysPerSecond);
1200                    if (timeleft != new TimeSpan(-1))
1201                    {
1202                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
1203                        try
1204                        {
1205                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
1206                        }
1207                        catch
1208                        {
1209                            localQuickWatchPresentation.endTime.Content = Resources.in_a_galaxy_far__far_away___;
1210                        }
1211                    }
1212                    else
1213                    {
1214                        localQuickWatchPresentation.timeLeft.Content = Resources.incalculable____;
1215                        localQuickWatchPresentation.endTime.Content = Resources.in_a_galaxy_far__far_away___;
1216                    }
1217
1218                    localQuickWatchPresentation.entries.Clear();
1219                    linkedListNode = costList.First;
1220
1221                    int i = 0;
1222                    while (linkedListNode != null)
1223                    {
1224                        i++;
1225
1226                        ResultEntry entry = new ResultEntry();
1227                        entry.Ranking = "" + i;
1228                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1229                        entry.Key = linkedListNode.Value.key;
1230                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1231
1232                        localQuickWatchPresentation.entries.Add(entry);
1233                        linkedListNode = linkedListNode.Next;
1234                    }
1235                }
1236                , null);
1237            }//end if
1238            else if (!stop && localQuickWatchPresentation.IsVisible)
1239            {
1240
1241                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1242                {
1243                    localQuickWatchPresentation.entries.Clear();
1244                    linkedListNode = costList.First;
1245                    int i = 0;
1246
1247                    while (linkedListNode != null)
1248                    {
1249                        i++;
1250
1251                        ResultEntry entry = new ResultEntry();
1252                        entry.Ranking = "" + i;
1253                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1254                        entry.Key = linkedListNode.Value.key;
1255                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1256
1257                        localQuickWatchPresentation.entries.Add(entry);
1258                        linkedListNode = linkedListNode.Next;
1259                    }
1260                }
1261                , null);
1262            }
1263        }
1264
1265        #region For TopList
1266
1267        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
1268        {
1269            ValueKey valueKey = new ValueKey();
1270            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
1271                valueKey.value = double.MaxValue;
1272            else
1273                valueKey.value = double.MinValue;
1274            valueKey.key = Resources.dummykey;
1275            valueKey.decryption = new byte[0];
1276            value_threshold = valueKey.value;
1277            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
1278            for (int i = 1; i < maxInList; i++)
1279            {
1280                node = costList.AddAfter(node, valueKey);
1281            }
1282        }
1283
1284        public void SetInitialized(bool ini)
1285        {
1286            this.initialized = ini;
1287        }
1288
1289        public Dictionary<string, Dictionary<long, Information>> GetStatistics()
1290        {
1291            return statistic;
1292        }
1293
1294        public void ResetStatistics()
1295        {
1296            statistic = null;
1297            statistic = new Dictionary<string, Dictionary<long, Information>>();
1298            maschinehierarchie = null;
1299            maschinehierarchie = new Dictionary<long, Maschinfo>();
1300        }
1301
1302        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList, Dictionary<string, Dictionary<long, Information>> updatedStatistics, string dataIdentifier)
1303        {
1304            foreach (var valueKey in updatedCostList)
1305            {
1306                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
1307                {
1308                    valuequeue.Enqueue(valueKey);
1309                }
1310            }
1311
1312            foreach (string avname in updatedStatistics.Keys)
1313            {
1314                //taking the dictionary in this avatarname
1315                Dictionary<long, Information> MaschCount = updatedStatistics[avname];
1316               
1317                //if the avatarname already exists in the statistics
1318                if (statistic.ContainsKey(avname))
1319                {
1320                    foreach (long id in MaschCount.Keys)
1321                    {
1322                        //get the statistic maschcount for this avatarname
1323                        Dictionary<long, Information> statMaschCount = statistic[avname];
1324
1325                        //if the id of the Maschine already exists for this avatarname
1326                        if (statMaschCount.ContainsKey(id))
1327                        {
1328                            if (!initialized || ((MaschCount[id].Count == 1) && (MaschCount.Keys.Count == 1)))
1329                            {
1330                                statMaschCount[id].Count = statMaschCount[id].Count + MaschCount[id].Count;
1331                                statMaschCount[id].Hostname = MaschCount[id].Hostname;
1332                                statMaschCount[id].Date = MaschCount[id].Date;
1333                                statistic[avname] = statMaschCount;
1334                            }
1335                        }
1336                        else
1337                        {
1338                            //add a new id,information value for this avatarname
1339                            statistic[avname].Add(id, MaschCount[id]);
1340                        }
1341                    }
1342                }
1343                else
1344                {
1345                    //add the maschinecount dictionary to this avatarname
1346                    statistic[avname] = MaschCount;
1347                }
1348                statistic[avname] = statistic[avname].OrderByDescending((x) => x.Value.Count).ToDictionary(x => x.Key, y => y.Value);
1349            }
1350            GenerateMaschineStats();
1351            WriteStatistics(dataIdentifier);
1352
1353            ((QuickWatch)QuickWatchPresentation).StatisticsPresentation.Statistics = statistic;
1354            ((QuickWatch)QuickWatchPresentation).StatisticsPresentation.MachineHierarchy = maschinehierarchie;
1355
1356            updateToplist();
1357        }
1358
1359        //Write the User Statistics to an external csv-document
1360        internal void WriteStatistics(String dataIdentifier)
1361        {
1362            //using the chosen csv file
1363            String path = settings.CsvPath;
1364
1365            if (path == "")
1366            {
1367                //using the default save folder %APPDATA%\Local\Cryptool2
1368                path = string.Format("{0}\\UserRanking{1}.csv", DirectoryHelper.DirectoryLocal, dataIdentifier);
1369            }
1370
1371            try
1372            {
1373                using (StreamWriter sw = new StreamWriter(path))
1374                {
1375                    sw.WriteLine("Avatarname" + ";" + "MaschineID" + ";" + "Hostname" + ";" + "Pattern Count" + ";" + "Last Update");
1376                    foreach (string avatar in statistic.Keys)
1377                    {
1378                        foreach (long mID in statistic[avatar].Keys)
1379                        {
1380                            sw.WriteLine(avatar + ";" + mID.ToString() + ";" + statistic[avatar][mID].Hostname + ";" + statistic[avatar][mID].Count + ";" + statistic[avatar][mID].Date);
1381                        }
1382                    }
1383                }
1384            }
1385            catch (Exception)
1386            {
1387                GuiLogMessage(string.Format("Failed to write statistics to {0}", path), NotificationLevel.Debug);
1388            }
1389
1390
1391            /*
1392            //For testing purpose. This writes the Maschinestatistics to the main folder if no different path was chosen--------
1393            if (settings.CsvPath == "")
1394            {
1395                //using the default save folder %APPDATA%\Local\Cryptool2
1396                using (StreamWriter sw = new StreamWriter(string.Format("{0}\\Maschine{1}.csv", DirectoryHelper.DirectoryLocal, dataIdentifier)))
1397                {
1398                    sw.WriteLine("Maschineid" + ";" + "Name" + ";" + "Sum" + ";" + "Users");
1399
1400                        foreach (long mID in maschinehierarchie.Keys)
1401                        {
1402                            sw.WriteLine(mID + ";" + maschinehierarchie[mID].Hostname + ";" + maschinehierarchie[mID].Sum + ";" + maschinehierarchie[mID].Users);
1403                        }
1404                   
1405                }
1406            }
1407            //-------------
1408            */
1409             
1410        }
1411
1412        internal void GenerateMaschineStats()
1413        {
1414            maschinehierarchie = null;
1415            maschinehierarchie = new Dictionary<long, Maschinfo>();
1416
1417            foreach (string avatar in statistic.Keys)
1418            {
1419                Dictionary<long, Information> Maschines = statistic[avatar];
1420
1421                //add the maschine count to the maschinestatistics
1422                foreach (long mid in Maschines.Keys)
1423                {
1424                    //if the maschine exists in maschinestatistic add it to the sum
1425                    if (maschinehierarchie.ContainsKey(mid))
1426                    {
1427
1428                        maschinehierarchie[mid].Sum = maschinehierarchie[mid].Sum + Maschines[mid].Count;
1429                        maschinehierarchie[mid].Hostname = Maschines[mid].Hostname;
1430                        maschinehierarchie[mid].Users = maschinehierarchie[mid].Users + avatar + " | ";
1431                    }
1432                    else
1433                    {
1434                        //else make a new entry
1435                        maschinehierarchie.Add(mid, new Maschinfo() { Sum = Maschines[mid].Count , Hostname = Maschines[mid].Hostname , Users = "| " + avatar + " | "});
1436                    }
1437                }
1438            }
1439
1440            maschinehierarchie = maschinehierarchie.OrderByDescending((x) => x.Value.Sum).ToDictionary(x => x.Key, y => y.Value);
1441        }
1442
1443        private static DateTime defaultstart = DateTime.MinValue;
1444        private static string username = P2PSettings.Default.PeerName;
1445        private static long maschineid = Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
1446        private static string maschinename = Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetHostName();
1447
1448        private static void EnhanceUserName(ValueKey vk)
1449        {
1450            DateTime chunkstart = DateTime.UtcNow;
1451
1452            //enhance our userdata:
1453            if ((username != null) && (!username.Equals("")))
1454            {
1455                vk.user = username;
1456                vk.time = chunkstart;
1457                vk.maschid = maschineid;
1458                vk.maschname = maschinename;
1459            }
1460            else
1461            {
1462                vk.user = "Unknown";
1463                vk.time = defaultstart;
1464                vk.maschid = 666;
1465                vk.maschname = "Devil";
1466            }
1467        }
1468
1469        internal void updateToplist()
1470        {
1471            LinkedListNode<ValueKey> node;
1472            while (valuequeue.Count != 0)
1473            {
1474                ValueKey vk = (ValueKey)valuequeue.Dequeue();
1475
1476                //if (costList.Contains(vk)) continue;
1477                var result = costList.Where(valueKey => valueKey.key == vk.key);
1478                if (result.Count() > 0)
1479                {
1480                    continue;
1481                }
1482
1483                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
1484                {
1485                    if (vk.value > costList.Last().value)
1486                    {
1487                        node = costList.First;
1488                        while (node != null)
1489                        {
1490                            if (vk.value > node.Value.value)
1491                            {
1492                                if (node == costList.First)
1493                                    Top1 = vk;
1494                                costList.AddBefore(node, vk);
1495                                costList.RemoveLast();
1496                                value_threshold = costList.Last.Value.value;
1497                                break;
1498                            }
1499                            node = node.Next;
1500                        }//end while
1501                    }//end if
1502                }
1503                else
1504                {
1505                    if (vk.value < costList.Last().value)
1506                    {
1507                        node = costList.First;
1508                        while (node != null)
1509                        {
1510                            if (vk.value < node.Value.value)
1511                            {
1512                                if (node == costList.First)
1513                                    Top1 = vk;
1514                                costList.AddBefore(node, vk);
1515                                costList.RemoveLast();
1516                                value_threshold = costList.Last.Value.value;
1517                                break;
1518                            }
1519                            node = node.Next;
1520                        }//end while
1521                    }//end if
1522                }
1523            }
1524        }
1525
1526        #endregion
1527
1528        private void StartThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] openCLDoneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
1529        {
1530            //First start the opencl threads:
1531            int i = 0;
1532            foreach (var ds in settings.DeviceSettings)
1533            {
1534                if (ds.useDevice)
1535                {
1536                    WaitCallback worker = new WaitCallback(KeySearcherJob);
1537                    doneKeysA[i] = new BigInteger();
1538                    openCLDoneKeysA[i] = new BigInteger();
1539                    keycounters[i] = new BigInteger();
1540
1541                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, ds });
1542                    i++;
1543                }
1544            }
1545
1546            //Then the CPU threads:
1547            for (; i < patterns.Length; i++)
1548            {
1549                WaitCallback worker = new WaitCallback(KeySearcherJob);
1550                doneKeysA[i] = new BigInteger();
1551                openCLDoneKeysA[i] = new BigInteger();
1552                keycounters[i] = new BigInteger();
1553
1554                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, null });
1555            }
1556        }
1557
1558        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
1559        {
1560            int threads = settings.CoresUsed;
1561            threads += settings.DeviceSettings.Count(x => x.useDevice); 
1562
1563            if (threads < 1)
1564                return null;
1565
1566            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[threads];
1567            if (threads > 1)
1568            {
1569                KeyPattern.KeyPattern[] patterns2 = pattern.split();
1570                if (patterns2 == null)
1571                {
1572                    patterns2 = new KeyPattern.KeyPattern[1];
1573                    patterns2[0] = pattern;
1574                    return patterns2;
1575                }
1576                patterns[0] = patterns2[0];
1577                patterns[1] = patterns2[1];
1578                int p = 1;
1579                threads -= 2;
1580
1581                while (threads > 0)
1582                {
1583                    int maxPattern = -1;
1584                    BigInteger max = 0;
1585                    for (int i = 0; i <= p; i++)
1586                        if (patterns[i].size() > max)
1587                        {
1588                            max = patterns[i].size();
1589                            maxPattern = i;
1590                        }
1591                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
1592                    if (patterns3 == null)
1593                    {
1594                        patterns3 = new KeyPattern.KeyPattern[p+1];
1595                        for (int i = 0; i <= p; i++)
1596                            patterns3[i] = patterns[i];
1597                        return patterns3;
1598                    }
1599                    patterns[maxPattern] = patterns3[0];
1600                    patterns[++p] = patterns3[1];
1601                    threads--;
1602                }
1603            }
1604            else
1605                patterns[0] = pattern;
1606            return patterns;
1607        }
1608
1609        private void keyPatternChanged()
1610        {
1611            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
1612        }
1613
1614        #endregion
1615
1616        public void GuiLogMessage(string message, NotificationLevel loglevel)
1617        {
1618            if (OnGuiLogNotificationOccured != null)
1619                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
1620        }
1621
1622        public void ProgressChanged(double value, double max)
1623        {
1624            if (OnPluginProgressChanged != null)
1625            {
1626                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1627
1628            }
1629        }
1630
1631        /// <summary>
1632        /// used for delivering the results from the worker threads to the main thread:
1633        /// </summary>
1634        public struct ValueKey
1635        {
1636            public override bool Equals(object obj)
1637            {
1638                if (obj != null && obj is ValueKey && keya != null && ((ValueKey)obj).keya != null)
1639                    return (keya.SequenceEqual(((ValueKey)obj).keya));
1640                else
1641                    return false;
1642            }
1643
1644            public double value;
1645            public String key;
1646            public byte[] decryption;
1647            public byte[] keya;
1648            //---------------------
1649            public string user { get; set; }
1650            public DateTime time { get; set; }
1651            public long maschid { get; set; }
1652            public string maschname { get; set; }
1653            //---------------------
1654        };
1655    }
1656
1657    /// <summary>
1658    /// Represents one entry in our result list
1659    /// </summary>
1660    public class ResultEntry
1661    {
1662        public string Ranking { get; set; }
1663        public string Value { get; set; }
1664        public string Key { get; set; }
1665        public string Text { get; set; }
1666        //-------
1667        public string User { get; set; }
1668        public DateTime Time { get; set; }
1669        public long Maschid { get; set; }
1670        public string Maschname { get; set; }
1671        //-------
1672    }
1673    /// <summary>
1674    /// Represents one entry in our statistic list
1675    /// </summary>
1676    public class Information
1677    {
1678        public int Count { get; set; }
1679        public string Hostname { get; set; }
1680        public DateTime Date { get; set; }
1681    }
1682    /// <summary>
1683    /// Represents one entry in our maschine statistic list
1684    /// </summary>
1685    public class Maschinfo
1686    {
1687        public int Sum { get; set; }
1688        public string Hostname { get; set; }
1689        public string Users { get; set; }
1690    } 
1691}
Note: See TracBrowser for help on using the repository browser.