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

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

small keysearcher "keys/sec" fix

File size: 38.4 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            DateTime lastTime = DateTime.Now;
594
595            //update message:
596            while (!stop)
597            {
598                Thread.Sleep(1000);
599
600                updateToplist();
601
602                #region calculate global counters from local counters
603                BigInteger keycounter = 0;
604                BigInteger doneKeys = 0;
605                foreach (BigInteger dk in doneKeysA)
606                    doneKeys += dk;
607                foreach (BigInteger kc in keycounters)
608                    keycounter += kc;
609                #endregion
610
611                if (keycounter > size)
612                    GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
613
614                #region determination of the thread with most keys
615                if (size - keycounter > 1000)
616                {
617                    try
618                    {
619                        maxThreadMutex.WaitOne();
620                        BigInteger max = 0;
621                        int id = -1;
622                        for (int i = 0; i < patterns.Length; i++)
623                            if (keysleft[i] != null && keysleft[i] > max)
624                            {
625                                max = keysleft[i];
626                                id = i;
627                            }
628                        maxThread = id;
629                    }
630                    finally
631                    {
632                        maxThreadMutex.ReleaseMutex();
633                    }
634                }
635                #endregion
636
637                long keysPerSecond = (long)((long)doneKeys/(DateTime.Now - lastTime).TotalSeconds);
638                lastTime = DateTime.Now;
639                if (redirectResultsToStatisticsGenerator)
640                {
641                    distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList, size, keycounter, keysPerSecond);
642                }
643                else
644                {
645                    showProgress(costList, size, keycounter, keysPerSecond);                   
646                }
647               
648
649                #region set doneKeys to 0
650                doneKeys = 0;
651                for (int i = 0; i < doneKeysA.Length; i++)
652                    doneKeysA[i] = 0;
653                #endregion
654
655                if (keycounter >= size)
656                    break;
657            }//end while
658
659            //wake up all sleeping threads, so they can stop:
660            while (threadStack.Count != 0)
661                ((ThreadStackElement)threadStack.Pop()).ev.Set();
662
663            if (!stop && !redirectResultsToStatisticsGenerator)
664                ProgressChanged(1, 1);
665
666            /* BEGIN: For evaluation issues - added by Arnold 2010.03.17 */
667            TimeSpan bruteforcingTime = DateTime.Now.Subtract(beginBruteforcing);
668            StringBuilder sbBFTime = new StringBuilder();
669            if (bruteforcingTime.Days > 0)
670                sbBFTime.Append(bruteforcingTime.Days.ToString() + " days ");
671            if (bruteforcingTime.Hours > 0)
672            {
673                if (bruteforcingTime.Hours <= 9)
674                    sbBFTime.Append("0");
675                sbBFTime.Append(bruteforcingTime.Hours.ToString() + ":");
676            }
677            if (bruteforcingTime.Minutes <= 9)
678                sbBFTime.Append("0");
679            sbBFTime.Append(bruteforcingTime.Minutes.ToString() + ":");
680            if (bruteforcingTime.Seconds <= 9)
681                sbBFTime.Append("0");
682            sbBFTime.Append(bruteforcingTime.Seconds.ToString() + "-");
683            if (bruteforcingTime.Milliseconds <= 9)
684                sbBFTime.Append("00");
685            if (bruteforcingTime.Milliseconds <= 99)
686                sbBFTime.Append("0");
687            sbBFTime.Append(bruteforcingTime.Milliseconds.ToString());
688
689            GuiLogMessage("Ended bruteforcing pattern '" + pattern.getKey() + "'. Bruteforcing TimeSpan: " + sbBFTime.ToString(), NotificationLevel.Debug);
690            /* END: For evaluation issues - added by Arnold 2010.03.17 */
691
692            return costList;
693        }
694
695        private void SetStartDate()
696        {
697            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
698        }
699
700        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, long keysPerSecond)
701        {
702            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
703
704            LinkedListNode<ValueKey> linkedListNode;
705            ProgressChanged((double)keycounter / (double) size, 1.0);
706
707            if (localQuickWatchPresentation.IsVisible && keysPerSecond != 0 && !stop)
708            {
709                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - Math.Log10(keysPerSecond)));
710                TimeSpan timeleft = new TimeSpan(-1);
711
712                try
713                {
714                    if (time / (24 * 60 * 60) <= int.MaxValue)
715                    {
716                        int days = (int)(time / (24 * 60 * 60));
717                        time = time - (days * 24 * 60 * 60);
718                        int hours = (int)(time / (60 * 60));
719                        time = time - (hours * 60 * 60);
720                        int minutes = (int)(time / 60);
721                        time = time - (minutes * 60);
722                        int seconds = (int)time;
723
724                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
725                    }
726                }
727                catch
728                {
729                    //can not calculate time span
730                }
731
732                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
733                {
734                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
735                    localQuickWatchPresentation.keysPerSecond.Content = "" + keysPerSecond;
736                    if (timeleft != new TimeSpan(-1))
737                    {
738                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
739                        try
740                        {
741                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
742                        }
743                        catch
744                        {
745                            localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
746                        }
747                    }
748                    else
749                    {
750                        localQuickWatchPresentation.timeLeft.Content = "incalculable :-)";
751                        localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
752                    }
753
754                    localQuickWatchPresentation.entries.Clear();
755                    linkedListNode = costList.First;
756                   
757                    int i = 0;
758                    while (linkedListNode != null)
759                    {
760                        i++;
761
762                        ResultEntry entry = new ResultEntry();
763                        entry.Ranking = "" + i;
764                        entry.Value = "" + Math.Round(linkedListNode.Value.value,3);
765                        entry.Key = linkedListNode.Value.key;
766                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
767
768                        localQuickWatchPresentation.entries.Add(entry);
769                        linkedListNode = linkedListNode.Next;
770                    }
771                }
772                , null);
773            }//end if
774
775
776            else if (!stop && localQuickWatchPresentation.IsVisible)
777            {
778
779                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
780                {
781                    localQuickWatchPresentation.entries.Clear();
782                    linkedListNode = costList.First;                   
783                    int i = 0;
784
785                    while (linkedListNode != null)
786                    {
787                        i++;
788
789                        ResultEntry entry = new ResultEntry();
790                        entry.Ranking = "" + i;
791                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
792                        entry.Key = linkedListNode.Value.key;
793                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
794
795                        localQuickWatchPresentation.entries.Add(entry);
796                        linkedListNode = linkedListNode.Next;
797                    }
798                }
799                , null);
800            }
801        }
802
803        #region For TopList
804
805        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
806        {
807            ValueKey valueKey = new ValueKey();
808            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
809                valueKey.value = double.MaxValue;
810            else
811                valueKey.value = double.MinValue;
812            valueKey.key = "dummykey";
813            valueKey.decryption = new byte[0];
814            value_threshold = valueKey.value;
815            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
816            for (int i = 1; i < maxInList; i++)
817            {
818                node = costList.AddAfter(node, valueKey);
819            }
820        }
821
822        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList)
823        {
824            foreach (var valueKey in updatedCostList)
825            {
826                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
827                {
828                    valuequeue.Enqueue(valueKey);
829                }
830            }
831
832            updateToplist();
833        }
834
835        internal void updateToplist()
836        {
837            LinkedListNode<ValueKey> node;
838            while (valuequeue.Count != 0)
839            {
840                ValueKey vk = (ValueKey)valuequeue.Dequeue();
841
842                //if (costList.Contains(vk)) continue;
843                var result = costList.Where(valueKey => valueKey.key == vk.key);
844                if (result.Count() > 0)
845                {
846                    continue;
847                }
848
849                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
850                {
851                    if (vk.value > costList.Last().value)
852                    {
853                        node = costList.First;
854                        while (node != null)
855                        {
856                            if (vk.value > node.Value.value)
857                            {
858                                if (node == costList.First)
859                                    Top1 = vk;
860                                costList.AddBefore(node, vk);
861                                costList.RemoveLast();
862                                value_threshold = costList.Last.Value.value;
863                                break;
864                            }
865                            node = node.Next;
866                        }//end while
867                    }//end if
868                }
869                else
870                {
871                    if (vk.value < costList.Last().value)
872                    {
873                        node = costList.First;
874                        while (node != null)
875                        {
876                            if (vk.value < node.Value.value)
877                            {
878                                if (node == costList.First)
879                                    Top1 = vk;
880                                costList.AddBefore(node, vk);
881                                costList.RemoveLast();
882                                value_threshold = costList.Last.Value.value;
883                                break;
884                            }
885                            node = node.Next;
886                        }//end while
887                    }//end if
888                }
889            }
890        }
891
892        #endregion
893
894        private void startThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
895        {
896            for (int i = 0; i < patterns.Length; i++)
897            {
898                WaitCallback worker = new WaitCallback(KeySearcherJob);
899                doneKeysA[i] = new BigInteger();
900                keycounters[i] = new BigInteger();
901                //ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
902                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack });
903            }
904        }
905
906        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
907        {
908            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[settings.CoresUsed + 1];
909            if (settings.CoresUsed > 0)
910            {
911                KeyPattern.KeyPattern[] patterns2 = pattern.split();
912                if (patterns2 == null)
913                {
914                    patterns2 = new KeyPattern.KeyPattern[1];
915                    patterns2[0] = pattern;
916                    return patterns2;
917                }
918                patterns[0] = patterns2[0];
919                patterns[1] = patterns2[1];
920                int p = 1;
921                int threads = settings.CoresUsed - 1;
922                while (threads > 0)
923                {
924                    int maxPattern = -1;
925                    BigInteger max = 0;
926                    for (int i = 0; i <= p; i++)
927                        if (patterns[i].size() > max)
928                        {
929                            max = patterns[i].size();
930                            maxPattern = i;
931                        }
932                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
933                    if (patterns3 == null)
934                    {
935                        patterns3 = new KeyPattern.KeyPattern[p+1];
936                        for (int i = 0; i <= p; i++)
937                            patterns3[i] = patterns[i];
938                        return patterns3;
939                    }
940                    patterns[maxPattern] = patterns3[0];
941                    patterns[++p] = patterns3[1];
942                    threads--;
943                }
944            }
945            else
946                patterns[0] = pattern;
947            return patterns;
948        }
949
950        private void keyPatternChanged()
951        {
952            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
953        }
954
955        // added by Arnie - 2009.12.07
956        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
957        /// <summary>
958        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
959        /// But when the returned List is filled, we have (at least a part) of the possible best keys
960        /// </summary>
961        public event BruteforcingEnded OnBruteforcingEnded;
962
963        // added by Arnie -2009.12.02
964        // for inheritance reasons
965        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
966        {
967            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
968            this.encryptedData = encryptedData;
969            this.initVector = initVector;
970            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
971
972            this.sender = encryptControl;
973            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
974            if(OnBruteforcingEnded != null)
975                OnBruteforcingEnded(lstRet);
976        }
977
978        #endregion
979
980        public void GuiLogMessage(string message, NotificationLevel loglevel)
981        {
982            if (OnGuiLogNotificationOccured != null)
983                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
984        }
985
986        public void ProgressChanged(double value, double max)
987        {
988            if (OnPluginProgressChanged != null)
989            {
990                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
991
992            }
993        }
994
995        /// <summary>
996        /// used for delivering the results from the worker threads to the main thread:
997        /// </summary>
998        public struct ValueKey
999        {
1000            public double value;
1001            public String key;
1002            public byte[] decryption;
1003        };
1004    }
1005
1006    /// <summary>
1007    /// Represents one entry in our result list
1008    /// </summary>
1009    public class ResultEntry
1010    {
1011        public string Ranking { get; set; }
1012        public string Value { get; set; }
1013        public string Key { get; set; }
1014        public string Text { get; set; }
1015
1016    }
1017}
Note: See TracBrowser for help on using the repository browser.