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

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

fixed keysearcher bug

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.