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

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

o Work on the distributed KeySearcher presentation

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