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

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

o Refactoring in CrypP2P
o AES: NullReference in AES-Plugin fixed
o Small fixes in KeySearcher, StorageKeyGenerator uses IV and truncates input data

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