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

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

machine statistics

File size: 67.1 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            ((QuickWatch)QuickWatchPresentation).StatisticsPresentation.MachineHierarchy = maschinehierarchie;
1296//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1297//TODO "maschinehierarchie" in Quickwatch einfügen. Bereits sortiert ;-) Sum = Anzahl Chunks total ; Hostname = Computername ; Users = String mit Avatarnamen der User dieses Rechners
1298//Anmerkung: Dictionaries lassen sich nicht sortieren.
1299//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1300
1301            updateToplist();
1302        }
1303
1304        //Write the User Statistics to an external csv-document
1305        internal void WriteStatistics(String dataIdentifier)
1306        {
1307            if (settings.CsvPath == "")
1308            {
1309                //using the default save folder %APPDATA%\Local\Cryptool2
1310                using (StreamWriter sw = new StreamWriter(string.Format("{0}\\UserRanking{1}.csv", DirectoryHelper.DirectoryLocal, dataIdentifier)))
1311                {
1312                    sw.WriteLine("Avatarname" + ";" + "MaschineID" + ";" + "Hostname" + ";" + "Pattern Count" + ";" + "Last Update");
1313                    foreach (string avatar in statistic.Keys)
1314                    {
1315                        foreach (long mID in statistic[avatar].Keys)
1316                        {
1317                            sw.WriteLine(avatar + ";" + mID.ToString() + ";" + statistic[avatar][mID].Hostname + ";" + statistic[avatar][mID].Count + ";" + statistic[avatar][mID].Date);
1318                        }
1319                    }
1320                }
1321            }
1322            else 
1323            {
1324                //using the chosen csv file
1325                using (StreamWriter sw = new StreamWriter(settings.CsvPath))
1326                {
1327                    sw.WriteLine("Avatarname" + ";" + "MaschineID" + ";" + "Hostname" + ";" + "Pattern Count" + ";" + "Last Update");
1328                    foreach (string avatar in statistic.Keys)
1329                    {
1330                        foreach (long mID in statistic[avatar].Keys)
1331                        {
1332                            sw.WriteLine(avatar + ";" + mID.ToString() + ";" + statistic[avatar][mID].Hostname + ";" + statistic[avatar][mID].Count + ";" + statistic[avatar][mID].Date);
1333                        }
1334                    }
1335                }
1336            }
1337
1338            /*
1339            //For testing purpose. This writes the Maschinestatistics to the main folder if no different path was chosen--------
1340            if (settings.CsvPath == "")
1341            {
1342                //using the default save folder %APPDATA%\Local\Cryptool2
1343                using (StreamWriter sw = new StreamWriter(string.Format("{0}\\Maschine{1}.csv", DirectoryHelper.DirectoryLocal, dataIdentifier)))
1344                {
1345                    sw.WriteLine("Maschineid" + ";" + "Name" + ";" + "Sum" + ";" + "Users");
1346
1347                        foreach (long mID in maschinehierarchie.Keys)
1348                        {
1349                            sw.WriteLine(mID + ";" + maschinehierarchie[mID].Hostname + ";" + maschinehierarchie[mID].Sum + ";" + maschinehierarchie[mID].Users);
1350                        }
1351                   
1352                }
1353            }
1354            //-------------
1355            */
1356             
1357        }
1358
1359        internal void GenerateMaschineStats()
1360        {
1361            maschinehierarchie = null;
1362            maschinehierarchie = new Dictionary<long, Maschinfo>();
1363
1364            foreach (string avatar in statistic.Keys)
1365            {
1366                Dictionary<long, Information> Maschines = statistic[avatar];
1367
1368                //add the maschine count to the maschinestatistics
1369                foreach (long mid in Maschines.Keys)
1370                {
1371                    //if the maschine exists in maschinestatistic add it to the sum
1372                    if (maschinehierarchie.ContainsKey(mid))
1373                    {
1374
1375                        maschinehierarchie[mid].Sum = maschinehierarchie[mid].Sum + Maschines[mid].Count;
1376                        maschinehierarchie[mid].Hostname = Maschines[mid].Hostname;
1377                        maschinehierarchie[mid].Users = maschinehierarchie[mid].Users + avatar + ", ";
1378                    }
1379                    else
1380                    {
1381                        //else make a new entry
1382                        maschinehierarchie.Add(mid, new Maschinfo() { Sum = Maschines[mid].Count , Hostname = Maschines[mid].Hostname , Users = "" + avatar + ", "});
1383                    }
1384                }
1385            }
1386
1387            maschinehierarchie = maschinehierarchie.OrderByDescending((x) => x.Value.Sum).ToDictionary(x => x.Key, y => y.Value);
1388        }
1389
1390        internal void updateToplist()
1391        {
1392            LinkedListNode<ValueKey> node;
1393            while (valuequeue.Count != 0)
1394            {
1395                ValueKey vk = (ValueKey)valuequeue.Dequeue();
1396
1397                //if (costList.Contains(vk)) continue;
1398                var result = costList.Where(valueKey => valueKey.key == vk.key);
1399                if (result.Count() > 0)
1400                {
1401                    continue;
1402                }
1403
1404                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
1405                {
1406                    if (vk.value > costList.Last().value)
1407                    {
1408                        node = costList.First;
1409                        while (node != null)
1410                        {
1411                            if (vk.value > node.Value.value)
1412                            {
1413                                if (node == costList.First)
1414                                    Top1 = vk;
1415                                costList.AddBefore(node, vk);
1416                                costList.RemoveLast();
1417                                value_threshold = costList.Last.Value.value;
1418                                break;
1419                            }
1420                            node = node.Next;
1421                        }//end while
1422                    }//end if
1423                }
1424                else
1425                {
1426                    if (vk.value < costList.Last().value)
1427                    {
1428                        node = costList.First;
1429                        while (node != null)
1430                        {
1431                            if (vk.value < node.Value.value)
1432                            {
1433                                if (node == costList.First)
1434                                    Top1 = vk;
1435                                costList.AddBefore(node, vk);
1436                                costList.RemoveLast();
1437                                value_threshold = costList.Last.Value.value;
1438                                break;
1439                            }
1440                            node = node.Next;
1441                        }//end while
1442                    }//end if
1443                }
1444            }
1445        }
1446
1447        #endregion
1448
1449        private void StartThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] openCLDoneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
1450        {
1451            //First start the opencl threads:
1452            int i = 0;
1453            foreach (var ds in settings.DeviceSettings)
1454            {
1455                if (ds.useDevice)
1456                {
1457                    WaitCallback worker = new WaitCallback(KeySearcherJob);
1458                    doneKeysA[i] = new BigInteger();
1459                    openCLDoneKeysA[i] = new BigInteger();
1460                    keycounters[i] = new BigInteger();
1461
1462                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, ds });
1463                    i++;
1464                }
1465            }
1466
1467            //Then the CPU threads:
1468            for (; i < patterns.Length; i++)
1469            {
1470                WaitCallback worker = new WaitCallback(KeySearcherJob);
1471                doneKeysA[i] = new BigInteger();
1472                openCLDoneKeysA[i] = new BigInteger();
1473                keycounters[i] = new BigInteger();
1474
1475                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, null });
1476            }
1477        }
1478
1479        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
1480        {
1481            int threads = settings.CoresUsed;
1482            threads += settings.DeviceSettings.Count(x => x.useDevice); 
1483
1484            if (threads < 1)
1485                return null;
1486
1487            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[threads];
1488            if (threads > 1)
1489            {
1490                KeyPattern.KeyPattern[] patterns2 = pattern.split();
1491                if (patterns2 == null)
1492                {
1493                    patterns2 = new KeyPattern.KeyPattern[1];
1494                    patterns2[0] = pattern;
1495                    return patterns2;
1496                }
1497                patterns[0] = patterns2[0];
1498                patterns[1] = patterns2[1];
1499                int p = 1;
1500                threads -= 2;
1501
1502                while (threads > 0)
1503                {
1504                    int maxPattern = -1;
1505                    BigInteger max = 0;
1506                    for (int i = 0; i <= p; i++)
1507                        if (patterns[i].size() > max)
1508                        {
1509                            max = patterns[i].size();
1510                            maxPattern = i;
1511                        }
1512                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
1513                    if (patterns3 == null)
1514                    {
1515                        patterns3 = new KeyPattern.KeyPattern[p+1];
1516                        for (int i = 0; i <= p; i++)
1517                            patterns3[i] = patterns[i];
1518                        return patterns3;
1519                    }
1520                    patterns[maxPattern] = patterns3[0];
1521                    patterns[++p] = patterns3[1];
1522                    threads--;
1523                }
1524            }
1525            else
1526                patterns[0] = pattern;
1527            return patterns;
1528        }
1529
1530        private void keyPatternChanged()
1531        {
1532            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
1533        }
1534
1535        // added by Arnie - 2009.12.07
1536        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
1537        /// <summary>
1538        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
1539        /// But when the returned List is filled, we have (at least a part) of the possible best keys
1540        /// </summary>
1541        public event BruteforcingEnded OnBruteforcingEnded;
1542
1543        // added by Arnie -2009.12.02
1544        // for inheritance reasons
1545        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
1546        {
1547            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1548            this.encryptedData = encryptedData;
1549            this.initVector = initVector;
1550            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1551
1552            this.sender = encryptControl;
1553            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
1554            if(OnBruteforcingEnded != null)
1555                OnBruteforcingEnded(lstRet);
1556        }
1557
1558        #endregion
1559
1560        public void GuiLogMessage(string message, NotificationLevel loglevel)
1561        {
1562            if (OnGuiLogNotificationOccured != null)
1563                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
1564        }
1565
1566        public void ProgressChanged(double value, double max)
1567        {
1568            if (OnPluginProgressChanged != null)
1569            {
1570                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1571
1572            }
1573        }
1574
1575        /// <summary>
1576        /// used for delivering the results from the worker threads to the main thread:
1577        /// </summary>
1578        public struct ValueKey
1579        {
1580            public double value;
1581            public String key;
1582            public byte[] decryption;
1583            public byte[] keya;
1584        };
1585    }
1586
1587    /// <summary>
1588    /// Represents one entry in our result list
1589    /// </summary>
1590    public class ResultEntry
1591    {
1592        public string Ranking { get; set; }
1593        public string Value { get; set; }
1594        public string Key { get; set; }
1595        public string Text { get; set; }
1596    }
1597    /// <summary>
1598    /// Represents one entry in our statistic list
1599    /// </summary>
1600    public class Information
1601    {
1602        public int Count { get; set; }
1603        public string Hostname { get; set; }
1604        public DateTime Date { get; set; }
1605    }
1606    /// <summary>
1607    /// Represents one entry in our maschine statistic list
1608    /// </summary>
1609    public class Maschinfo
1610    {
1611        public int Sum { get; set; }
1612        public string Hostname { get; set; }
1613        public string Users { get; set; }
1614    } 
1615}
Note: See TracBrowser for help on using the repository browser.