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

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

Prepared KeySearcher for Localization

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