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

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

Several ExternalClient improvements:

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