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

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

Prepared the data for the "Maschine -> Sum of Patterns"-View for the Keysearcher.

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