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

Last change on this file since 2411 was 2411, checked in by schwittmann, 11 years ago

Shutdown external client server gracefully

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