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

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

+ P2PEditor can display the status of jobs, if available; Participating displays overlay while loading workspace data
+ KeySearcher can upload status for P2PEditor display

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