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

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

Added extension for the key values.
(Commited as comments. Needs to be tested before release)
Still using Version 4 -> No DHT changes yet.

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