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

Last change on this file since 1707 was 1707, checked in by Paul Lelgemann, 11 years ago

o KeySearcher: more precise statistics in the new visualization of distributed search

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