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

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

removed an optimization in keysearcher plugin, that didn't worked anymore and wasn't used anymore.
code is now more readable.

I will replace this by a much better optimization approach later (master project)

File size: 38.2 KB
Line 
1using System;
2using System.Diagnostics;
3using System.Linq;
4using System.Text;
5using Cryptool.P2P;
6using Cryptool.P2P.Internal;
7using Cryptool.PluginBase.Analysis;
8using Cryptool.PluginBase;
9using System.Windows.Controls;
10using System.ComponentModel;
11using Cryptool.PluginBase.Control;
12using System.Collections;
13using System.Collections.Generic;
14using System.Threading;
15using System.Windows.Threading;
16using Cryptool.PluginBase.IO;
17using System.Numerics;
18using KeySearcher.Helper;
19using KeySearcher.P2P;
20using KeySearcherPresentation;
21using KeySearcherPresentation.Controls;
22
23namespace KeySearcher
24{   
25    [Author("Sven Rech, Nils Kopal, Raoul Falk, Dennis Nolte", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
26    [PluginInfo(false, "KeySearcher", "Bruteforces a decryption algorithm.", "KeySearcher/DetailedDescription/Description.xaml", "KeySearcher/Images/icon.png")]
27    public class KeySearcher : IAnalysisMisc
28    {
29        /// <summary>
30        /// used for creating the TopList
31        /// </summary>
32        private Queue valuequeue;
33        private double value_threshold;
34        /// <summary>
35        /// the thread with the most keys left
36        /// </summary>
37        private int maxThread;
38        private readonly Mutex maxThreadMutex = new Mutex();
39
40        public bool IsKeySearcherRunning;
41        private KeyQualityHelper keyQualityHelper;
42        private readonly P2PQuickWatchPresentation p2PQuickWatchPresentation;
43        private readonly LocalQuickWatchPresentation localQuickWatchPresentation;
44
45        private readonly Stopwatch localBruteForceStopwatch;
46
47        private KeyPattern.KeyPattern pattern;
48        public KeyPattern.KeyPattern Pattern
49        {
50            get
51            {
52                return pattern;
53            }
54            set
55            {
56                pattern = value;
57                if ((settings.Key == null) || ((settings.Key != null) && !pattern.testWildcardKey(settings.Key)))
58                    settings.Key = pattern.giveInputPattern();
59            }
60        }
61
62        internal bool stop;
63
64        #region IControlEncryption + IControlCost + InputFields
65
66        #region IControlEncryption Members
67
68        private IControlEncryption controlMaster;
69        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
70        public IControlEncryption ControlMaster
71        {
72            get { return controlMaster; }
73            set
74            {
75                if (controlMaster != null)
76                {
77                    controlMaster.keyPatternChanged -= keyPatternChanged;
78                }
79                if (value != null)
80                {
81                    Pattern = new KeyPattern.KeyPattern(value.getKeyPattern());
82                    value.keyPatternChanged += keyPatternChanged;
83                    controlMaster = value;
84                    OnPropertyChanged("ControlMaster");
85
86                }
87                else
88                    controlMaster = null;
89            }
90        }
91
92        #endregion
93
94        #region IControlCost Members
95
96        private IControlCost costMaster;
97        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
98        public IControlCost CostMaster
99        {
100            get { return costMaster; }
101            set
102            {
103                costMaster = value;
104                keyQualityHelper = new KeyQualityHelper(costMaster);
105            }
106        }
107
108        #endregion
109
110        /* BEGIN: following lines are from Arnie - 2010.01.12 */
111        CryptoolStream csEncryptedData;
112        [PropertyInfo(Direction.InputData, "CS Encrypted Data", "Encrypted data out of an Encryption PlugIn", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, "")]
113        public virtual CryptoolStream CSEncryptedData
114        {
115            get { return this.csEncryptedData; }
116            set
117            {
118                if (value != this.csEncryptedData)
119                {
120                    this.csEncryptedData = value;
121                    this.encryptedData = GetByteFromCryptoolStream(value);
122                    OnPropertyChanged("CSEncryptedData");
123                }
124            }
125        }
126
127        byte[] encryptedData;
128        [PropertyInfo(Direction.InputData,"Encrypted Data","Encrypted data out of an Encryption PlugIn","",false,false,DisplayLevel.Beginner,QuickWatchFormat.Hex,"")]
129        public virtual byte[] EncryptedData
130        {
131            get { return this.encryptedData; }
132            set
133            {
134                if (value != this.encryptedData)
135                {
136                    this.encryptedData = value;
137                    OnPropertyChanged("EncryptedData");
138                }
139            }
140        }
141
142        /// <summary>
143        /// When the Input-Slot changed, set this variable to true, so the new Stream will be transformed to byte[]
144        /// </summary>
145        private byte[] GetByteFromCryptoolStream(CryptoolStream cryptoolStream)
146        {
147            byte[] encryptedByteData = null;
148
149            if (cryptoolStream != null)
150            {
151                CryptoolStream cs = new CryptoolStream();
152                cs.OpenRead(cryptoolStream.FileName);
153                encryptedByteData = new byte[cs.Length];
154                if(cs.Length > Int32.MaxValue)
155                    throw(new Exception("CryptoolStream length is longer than the Int32.MaxValue"));
156                cs.Read(encryptedByteData, 0, (int)cs.Length);
157            }
158            return encryptedByteData;
159        }
160
161        byte[] initVector;
162        [PropertyInfo(Direction.InputData, "Initialization Vector", "Initialization vector with which the data were encrypted", "", DisplayLevel.Beginner)]
163        public virtual byte[] InitVector
164        {
165            get { return this.initVector; }
166            set
167            {
168                if (value != this.initVector)
169                {
170                    this.initVector = value;
171                    OnPropertyChanged("InitVector");
172                }
173            }
174        }
175        /* END: Lines above are from Arnie - 2010.01.12 */
176
177        private ValueKey top1ValueKey;
178        public virtual ValueKey Top1
179        {
180            set { top1ValueKey = value; OnPropertyChanged("Top1Message"); OnPropertyChanged("Top1Key"); }
181        }
182
183        [PropertyInfo(Direction.OutputData, "Top1 Message", "The best message found", "", DisplayLevel.Beginner)]
184        public virtual byte[] Top1Message
185        {
186            get { return top1ValueKey.decryption; }
187        }
188        [PropertyInfo(Direction.OutputData, "Top1 Key", "The best key found", "", DisplayLevel.Beginner)]
189        public virtual byte[] Top1Key
190        {
191            get
192            {
193                if (top1ValueKey.key != null) //added by Arnold - 2010.02.22
194                {
195                    return ControlMaster.getKeyFromString(top1ValueKey.key);
196                }
197                else
198                    return null;
199            }
200        }
201
202        #endregion
203
204        #region IPlugin Members
205
206        public event StatusChangedEventHandler OnPluginStatusChanged;
207
208        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
209
210        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
211
212        private KeySearcherSettings settings;
213        private AutoResetEvent connectResetEvent;
214
215        public KeySearcher()
216        {
217            IsKeySearcherRunning = false;
218            settings = new KeySearcherSettings(this);
219            QuickWatchPresentation = new QuickWatch();
220            localQuickWatchPresentation = ((QuickWatch) QuickWatchPresentation).LocalQuickWatchPresentation;
221            p2PQuickWatchPresentation = ((QuickWatch)QuickWatchPresentation).P2PQuickWatchPresentation;
222            p2PQuickWatchPresentation.UpdateSettings(this, settings);
223
224            settings.PropertyChanged += SettingsPropertyChanged;
225
226            localBruteForceStopwatch = new Stopwatch();
227        }
228
229        void SettingsPropertyChanged(object sender, PropertyChangedEventArgs e)
230        {
231            p2PQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
232                                                             new Action(UpdateIsP2PEnabledSetting));
233        }
234
235        void UpdateIsP2PEnabledSetting()
236        {
237            ((QuickWatch)QuickWatchPresentation).IsP2PEnabled = settings.UsePeerToPeer;
238            p2PQuickWatchPresentation.UpdateSettings(this, settings);
239        }
240
241        public ISettings Settings
242        {
243            get { return settings; }
244        }
245
246        public UserControl Presentation
247        {
248            get { return QuickWatchPresentation; }
249        }
250
251        public UserControl QuickWatchPresentation
252        {
253            get;
254            private set;
255        }
256
257        public void PreExecution()
258        {
259        }
260
261        // because Encryption PlugIns were changed radical, the new StartPoint is here - Arnie 2010.01.12
262        public virtual void Execute()
263        {
264            IsKeySearcherRunning = true;
265
266            //either byte[] CStream input or CryptoolStream Object input
267            if (encryptedData != null || csEncryptedData != null) //to prevent execution on initialization
268            {
269                if (ControlMaster != null)
270                    process(ControlMaster);
271                else
272                {
273                    GuiLogMessage("You have to connect the KeySearcher with the Decryption Control!", NotificationLevel.Warning);
274                }
275            }
276        }
277
278        public void PostExecution()
279        {
280        }
281
282        public void Pause()
283        {
284        }
285
286        public void Stop()
287        {
288            IsKeySearcherRunning = false;
289            stop = true;
290        }
291
292        public void Initialize()
293        {
294        }
295
296        public void Dispose()
297        {
298        }
299
300        #endregion
301
302        #region INotifyPropertyChanged Members
303
304        public event PropertyChangedEventHandler PropertyChanged;
305
306        public void OnPropertyChanged(string name)
307        {
308            if (PropertyChanged != null)
309            {
310                PropertyChanged(this, new PropertyChangedEventArgs(name));
311            }
312        }
313
314        #endregion
315
316        #region whole KeySearcher functionality
317
318        private class ThreadStackElement
319        {
320            public AutoResetEvent ev;
321            public int threadid;
322        }
323
324        #region code for the worker threads
325
326        private void KeySearcherJob(object param)
327        {
328            object[] parameters = (object[])param;
329            KeyPattern.KeyPattern[] patterns = (KeyPattern.KeyPattern[])parameters[0];
330            int threadid = (int)parameters[1];
331            BigInteger[] doneKeysArray = (BigInteger[])parameters[2];
332            BigInteger[] keycounterArray = (BigInteger[])parameters[3];
333            BigInteger[] keysLeft = (BigInteger[])parameters[4];
334            IControlEncryption sender = (IControlEncryption)parameters[5];
335            int bytesToUse = (int)parameters[6];
336            Stack threadStack = (Stack)parameters[7];
337
338            KeyPattern.KeyPattern pattern = patterns[threadid];
339           
340            try
341            {
342                while (pattern != null)
343                {
344                    BigInteger size = pattern.size();
345                    keysLeft[threadid] = size;
346
347                    do
348                    {
349                        //if we are the thread with most keys left, we have to share them:
350                        if (maxThread == threadid && threadStack.Count != 0)
351                        {
352                            try
353                            {
354                                maxThreadMutex.WaitOne();
355                                if (maxThread == threadid && threadStack.Count != 0)
356                                {
357                                    KeyPattern.KeyPattern[] split = pattern.split();
358                                    if (split != null)
359                                    {
360                                        patterns[threadid] = split[0];
361                                        pattern = split[0];
362                                        ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
363                                        patterns[elem.threadid] = split[1];
364                                        elem.ev.Set();    //wake the other thread up                                   
365                                        size = pattern.size();
366                                        keysLeft[threadid] = size;
367                                    }
368                                    maxThread = -1;
369                                }
370                            }
371                            finally
372                            {
373                                maxThreadMutex.ReleaseMutex();
374                            }
375                        }
376
377                        ValueKey valueKey = new ValueKey();
378                        try
379                        {
380                            valueKey.key = pattern.getKey();
381                        }
382                        catch (Exception ex)
383                        {
384                            GuiLogMessage("Could not get next key: " + ex.Message, NotificationLevel.Error);
385                            return;
386                        }
387
388                        byte[] keya = ControlMaster.getKeyFromString(valueKey.key);
389
390                        if (!decryptAndCalculate(sender, bytesToUse, ref valueKey, keya, 0, null))
391                            return;
392
393                        doneKeysArray[threadid]++;
394                        keycounterArray[threadid]++;
395                        keysLeft[threadid]--;
396
397                    } while (pattern.nextKey() && !stop);
398
399                    if (stop)
400                        return;
401
402                    //Let's wait until another thread is willing to share with us:
403                    pattern = null;
404                    ThreadStackElement el = new ThreadStackElement();
405                    el.ev = new AutoResetEvent(false);
406                    el.threadid = threadid;
407                    patterns[threadid] = null;
408                    threadStack.Push(el);
409                    GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
410                    el.ev.WaitOne();
411                    GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
412                    pattern = patterns[threadid];
413                }
414            }
415            finally
416            {
417                sender.Dispose();
418            }
419        }
420
421        #region bruteforce methods
422
423        private bool decryptAndCalculate(IControlEncryption sender, int bytesToUse, ref ValueKey valueKey, byte[] keya, int counter, KeyPattern.KeyPattern pattern)
424        {
425            try
426            {
427                if (this.encryptedData != null && this.encryptedData.Length > 0)
428                {
429                    valueKey.decryption = sender.Decrypt(this.encryptedData, keya, InitVector, bytesToUse);
430                }
431                else
432                {
433                    GuiLogMessage("Can't bruteforce empty input!", NotificationLevel.Error);
434                    return false;
435                }
436                //CryptoolStream cs = new CryptoolStream();
437                //if (this.CSEncryptedData == null)
438                //{
439                //    cs.OpenRead(this.EncryptedData);
440                //    valueKey.decryption = sender.Decrypt(this.EncryptedData, keya);
441                //}
442                //else
443                //{
444                //    cs.OpenRead(this.CSEncryptedData.FileName);
445                //    byte[] byteCS = new byte[cs.Length];
446                //    cs.Read(byteCS, 0, byteCS.Length);
447                //    //this.CSEncryptedData.Read(byteCS, 0, byteCS.Length);
448                //    valueKey.decryption = sender.Decrypt(byteCS, keya);
449                //}
450
451                //valueKey.decryption = sender.Decrypt(keya, bytesToUse);
452            }
453            catch (Exception ex)
454            {
455                GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
456                GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
457                return false;
458            }
459
460            try
461            {
462                valueKey.value = CostMaster.calculateCost(valueKey.decryption);
463            }
464            catch (Exception ex)
465            {
466                GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
467                return false;
468            }
469
470            if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
471            {
472                if (valueKey.value > value_threshold)
473                {
474                    if (pattern != null)
475                        valueKey.key = pattern.getKey(counter);
476                    valuequeue.Enqueue(valueKey);
477                }
478            }
479            else
480            {
481                if (valueKey.value < value_threshold)
482                {
483                    if (pattern != null)
484                        valueKey.key = pattern.getKey(counter);
485                    valuequeue.Enqueue(valueKey);
486                }
487            }
488            return true;
489        }
490
491        #endregion
492
493        #endregion
494
495        public void process(IControlEncryption sender)
496        {
497            if (sender == null || costMaster == null)
498                return;
499            if (!Pattern.testWildcardKey(settings.Key))
500            {
501                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
502                return;
503            }
504            Pattern.WildcardKey = settings.Key;
505            this.sender = sender;
506
507            bruteforcePattern(Pattern);
508        }
509
510        internal LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
511        private int bytesToUse;
512        private IControlEncryption sender;
513        private DateTime beginBruteforcing;
514        private DistributedBruteForceManager distributedBruteForceManager;
515
516        // modified by Christian Arnold 2009.12.07 - return type LinkedList (top10List)
517        // main entry point to the KeySearcher
518        private LinkedList<ValueKey> bruteforcePattern(KeyPattern.KeyPattern pattern)
519        {
520            //For evaluation issues - added by Arnold 2010.03.17
521            beginBruteforcing = DateTime.Now;
522            GuiLogMessage("Start bruteforcing pattern '" + pattern.getKey() + "'", NotificationLevel.Debug);
523
524
525                       
526            int maxInList = 10;
527            costList = new LinkedList<ValueKey>();
528            fillListWithDummies(maxInList, costList);
529            valuequeue = Queue.Synchronized(new Queue());
530
531            stop = false;
532            if (!pattern.testWildcardKey(settings.Key))
533            {
534                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
535                return null;
536            }
537
538            // bytesToUse = 0;
539
540            try
541            {
542                bytesToUse = CostMaster.getBytesToUse();
543            }
544            catch (Exception ex)
545            {
546                GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
547                return null;
548            }
549
550            if (settings.UsePeerToPeer)
551            {
552                BruteForceWithPeerToPeerSystem();
553                return null;
554            }
555
556            return BruteForceWithLocalSystem(pattern);
557        }
558
559        private void BruteForceWithPeerToPeerSystem()
560        {
561            GuiLogMessage("Launching p2p based bruteforce logic...", NotificationLevel.Info);
562
563            try
564            {
565                distributedBruteForceManager = new DistributedBruteForceManager(this, pattern, settings,
566                                                                                keyQualityHelper,
567                                                                                p2PQuickWatchPresentation);
568                distributedBruteForceManager.Execute();
569            }
570            catch (NotConnectedException)
571            {
572                GuiLogMessage("P2P not connected.", NotificationLevel.Error);
573            }
574        }
575
576        internal LinkedList<ValueKey> BruteForceWithLocalSystem(KeyPattern.KeyPattern pattern, bool redirectResultsToStatisticsGenerator = false)
577        {
578            if (!redirectResultsToStatisticsGenerator)
579            {
580                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(SetStartDate));
581                localBruteForceStopwatch.Start();
582            }
583
584            BigInteger size = pattern.size();
585            KeyPattern.KeyPattern[] patterns = splitPatternForThreads(pattern);
586
587            BigInteger[] doneKeysA = new BigInteger[patterns.Length];
588            BigInteger[] keycounters = new BigInteger[patterns.Length];
589            BigInteger[] keysleft = new BigInteger[patterns.Length];
590            Stack threadStack = Stack.Synchronized(new Stack());
591            startThreads(sender, bytesToUse, patterns, doneKeysA, keycounters, keysleft, threadStack);
592
593            //update message:
594            while (!stop)
595            {
596                Thread.Sleep(1000);
597
598                updateToplist();
599
600                #region calculate global counters from local counters
601                BigInteger keycounter = 0;
602                BigInteger doneKeys = 0;
603                foreach (BigInteger dk in doneKeysA)
604                    doneKeys += dk;
605                foreach (BigInteger kc in keycounters)
606                    keycounter += kc;
607                #endregion
608
609                if (keycounter > size)
610                    GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
611
612                #region determination of the thread with most keys
613                if (size - keycounter > 1000)
614                {
615                    try
616                    {
617                        maxThreadMutex.WaitOne();
618                        BigInteger max = 0;
619                        int id = -1;
620                        for (int i = 0; i < patterns.Length; i++)
621                            if (keysleft[i] != null && keysleft[i] > max)
622                            {
623                                max = keysleft[i];
624                                id = i;
625                            }
626                        maxThread = id;
627                    }
628                    finally
629                    {
630                        maxThreadMutex.ReleaseMutex();
631                    }
632                }
633                #endregion
634
635                if (redirectResultsToStatisticsGenerator)
636                {
637                    distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList, size, keycounter, doneKeys);
638                }
639                else
640                {
641                    showProgress(costList, size, keycounter, doneKeys);
642                }
643               
644
645                #region set doneKeys to 0
646                doneKeys = 0;
647                for (int i = 0; i < doneKeysA.Length; i++)
648                    doneKeysA[i] = 0;
649                #endregion
650
651                if (keycounter >= size)
652                    break;
653            }//end while
654
655            //wake up all sleeping threads, so they can stop:
656            while (threadStack.Count != 0)
657                ((ThreadStackElement)threadStack.Pop()).ev.Set();
658
659            if (!stop && !redirectResultsToStatisticsGenerator)
660                ProgressChanged(1, 1);
661
662            /* BEGIN: For evaluation issues - added by Arnold 2010.03.17 */
663            TimeSpan bruteforcingTime = DateTime.Now.Subtract(beginBruteforcing);
664            StringBuilder sbBFTime = new StringBuilder();
665            if (bruteforcingTime.Days > 0)
666                sbBFTime.Append(bruteforcingTime.Days.ToString() + " days ");
667            if (bruteforcingTime.Hours > 0)
668            {
669                if (bruteforcingTime.Hours <= 9)
670                    sbBFTime.Append("0");
671                sbBFTime.Append(bruteforcingTime.Hours.ToString() + ":");
672            }
673            if (bruteforcingTime.Minutes <= 9)
674                sbBFTime.Append("0");
675            sbBFTime.Append(bruteforcingTime.Minutes.ToString() + ":");
676            if (bruteforcingTime.Seconds <= 9)
677                sbBFTime.Append("0");
678            sbBFTime.Append(bruteforcingTime.Seconds.ToString() + "-");
679            if (bruteforcingTime.Milliseconds <= 9)
680                sbBFTime.Append("00");
681            if (bruteforcingTime.Milliseconds <= 99)
682                sbBFTime.Append("0");
683            sbBFTime.Append(bruteforcingTime.Milliseconds.ToString());
684
685            GuiLogMessage("Ended bruteforcing pattern '" + pattern.getKey() + "'. Bruteforcing TimeSpan: " + sbBFTime.ToString(), NotificationLevel.Debug);
686            /* END: For evaluation issues - added by Arnold 2010.03.17 */
687
688            return costList;
689        }
690
691        private void SetStartDate()
692        {
693            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
694        }
695
696        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, BigInteger doneKeys)
697        {
698            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
699
700            LinkedListNode<ValueKey> linkedListNode;
701            ProgressChanged((double)keycounter / (double) size, 1.0);
702
703            if (localQuickWatchPresentation.IsVisible && doneKeys != 0 && !stop)
704            {
705                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - BigInteger.Log(doneKeys, 10)));
706                TimeSpan timeleft = new TimeSpan(-1);
707
708                try
709                {
710                    if (time / (24 * 60 * 60) <= int.MaxValue)
711                    {
712                        int days = (int)(time / (24 * 60 * 60));
713                        time = time - (days * 24 * 60 * 60);
714                        int hours = (int)(time / (60 * 60));
715                        time = time - (hours * 60 * 60);
716                        int minutes = (int)(time / 60);
717                        time = time - (minutes * 60);
718                        int seconds = (int)time;
719
720                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
721                    }
722                }
723                catch
724                {
725                    //can not calculate time span
726                }
727
728                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
729                {
730                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
731
732                    localQuickWatchPresentation.keysPerSecond.Content = "" + doneKeys;
733                    if (timeleft != new TimeSpan(-1))
734                    {
735                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
736                        try
737                        {
738                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
739                        }
740                        catch
741                        {
742                            localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
743                        }
744                    }
745                    else
746                    {
747                        localQuickWatchPresentation.timeLeft.Content = "incalculable :-)";
748                        localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
749                    }
750
751                    localQuickWatchPresentation.entries.Clear();
752                    linkedListNode = costList.First;
753                   
754                    int i = 0;
755                    while (linkedListNode != null)
756                    {
757                        i++;
758
759                        ResultEntry entry = new ResultEntry();
760                        entry.Ranking = "" + i;
761                        entry.Value = "" + Math.Round(linkedListNode.Value.value,3);
762                        entry.Key = linkedListNode.Value.key;
763                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
764
765                        localQuickWatchPresentation.entries.Add(entry);
766                        linkedListNode = linkedListNode.Next;
767                    }
768                }
769                , null);
770            }//end if
771
772
773            else if (!stop && localQuickWatchPresentation.IsVisible)
774            {
775
776                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
777                {
778                    localQuickWatchPresentation.entries.Clear();
779                    linkedListNode = costList.First;                   
780                    int i = 0;
781
782                    while (linkedListNode != null)
783                    {
784                        i++;
785
786                        ResultEntry entry = new ResultEntry();
787                        entry.Ranking = "" + i;
788                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
789                        entry.Key = linkedListNode.Value.key;
790                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
791
792                        localQuickWatchPresentation.entries.Add(entry);
793                        linkedListNode = linkedListNode.Next;
794                    }
795                }
796                , null);
797            }
798        }
799
800        #region For TopList
801
802        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
803        {
804            ValueKey valueKey = new ValueKey();
805            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
806                valueKey.value = double.MaxValue;
807            else
808                valueKey.value = double.MinValue;
809            valueKey.key = "dummykey";
810            valueKey.decryption = new byte[0];
811            value_threshold = valueKey.value;
812            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
813            for (int i = 1; i < maxInList; i++)
814            {
815                node = costList.AddAfter(node, valueKey);
816            }
817        }
818
819        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList)
820        {
821            foreach (var valueKey in updatedCostList)
822            {
823                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
824                {
825                    valuequeue.Enqueue(valueKey);
826                }
827            }
828
829            updateToplist();
830        }
831
832        internal void updateToplist()
833        {
834            LinkedListNode<ValueKey> node;
835            while (valuequeue.Count != 0)
836            {
837                ValueKey vk = (ValueKey)valuequeue.Dequeue();
838
839                //if (costList.Contains(vk)) continue;
840                var result = costList.Where(valueKey => valueKey.key == vk.key);
841                if (result.Count() > 0)
842                {
843                    continue;
844                }
845
846                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
847                {
848                    if (vk.value > costList.Last().value)
849                    {
850                        node = costList.First;
851                        while (node != null)
852                        {
853                            if (vk.value > node.Value.value)
854                            {
855                                if (node == costList.First)
856                                    Top1 = vk;
857                                costList.AddBefore(node, vk);
858                                costList.RemoveLast();
859                                value_threshold = costList.Last.Value.value;
860                                break;
861                            }
862                            node = node.Next;
863                        }//end while
864                    }//end if
865                }
866                else
867                {
868                    if (vk.value < costList.Last().value)
869                    {
870                        node = costList.First;
871                        while (node != null)
872                        {
873                            if (vk.value < node.Value.value)
874                            {
875                                if (node == costList.First)
876                                    Top1 = vk;
877                                costList.AddBefore(node, vk);
878                                costList.RemoveLast();
879                                value_threshold = costList.Last.Value.value;
880                                break;
881                            }
882                            node = node.Next;
883                        }//end while
884                    }//end if
885                }
886            }
887        }
888
889        #endregion
890
891        private void startThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
892        {
893            for (int i = 0; i < patterns.Length; i++)
894            {
895                WaitCallback worker = new WaitCallback(KeySearcherJob);
896                doneKeysA[i] = new BigInteger();
897                keycounters[i] = new BigInteger();
898                //ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
899                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack });
900            }
901        }
902
903        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
904        {
905            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[settings.CoresUsed + 1];
906            if (settings.CoresUsed > 0)
907            {
908                KeyPattern.KeyPattern[] patterns2 = pattern.split();
909                if (patterns2 == null)
910                {
911                    patterns2 = new KeyPattern.KeyPattern[1];
912                    patterns2[0] = pattern;
913                    return patterns2;
914                }
915                patterns[0] = patterns2[0];
916                patterns[1] = patterns2[1];
917                int p = 1;
918                int threads = settings.CoresUsed - 1;
919                while (threads > 0)
920                {
921                    int maxPattern = -1;
922                    BigInteger max = 0;
923                    for (int i = 0; i <= p; i++)
924                        if (patterns[i].size() > max)
925                        {
926                            max = patterns[i].size();
927                            maxPattern = i;
928                        }
929                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
930                    if (patterns3 == null)
931                    {
932                        patterns3 = new KeyPattern.KeyPattern[p+1];
933                        for (int i = 0; i <= p; i++)
934                            patterns3[i] = patterns[i];
935                        return patterns3;
936                    }
937                    patterns[maxPattern] = patterns3[0];
938                    patterns[++p] = patterns3[1];
939                    threads--;
940                }
941            }
942            else
943                patterns[0] = Pattern;
944            return patterns;
945        }
946
947        private void keyPatternChanged()
948        {
949            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
950        }
951
952        // added by Arnie - 2009.12.07
953        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
954        /// <summary>
955        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
956        /// But when the returned List is filled, we have (at least a part) of the possible best keys
957        /// </summary>
958        public event BruteforcingEnded OnBruteforcingEnded;
959
960        // added by Arnie -2009.12.02
961        // for inheritance reasons
962        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
963        {
964            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
965            this.encryptedData = encryptedData;
966            this.initVector = initVector;
967            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
968
969            this.sender = encryptControl;
970            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
971            if(OnBruteforcingEnded != null)
972                OnBruteforcingEnded(lstRet);
973        }
974
975        #endregion
976
977        public void GuiLogMessage(string message, NotificationLevel loglevel)
978        {
979            if (OnGuiLogNotificationOccured != null)
980                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
981        }
982
983        public void ProgressChanged(double value, double max)
984        {
985            if (OnPluginProgressChanged != null)
986            {
987                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
988
989            }
990        }
991
992        /// <summary>
993        /// used for delivering the results from the worker threads to the main thread:
994        /// </summary>
995        public struct ValueKey
996        {
997            public double value;
998            public String key;
999            public byte[] decryption;
1000        };
1001    }
1002
1003    /// <summary>
1004    /// Represents one entry in our result list
1005    /// </summary>
1006    public class ResultEntry
1007    {
1008        public string Ranking { get; set; }
1009        public string Value { get; set; }
1010        public string Key { get; set; }
1011        public string Text { get; set; }
1012
1013    }
1014}
Note: See TracBrowser for help on using the repository browser.