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

Last change on this file since 1244 was 1244, checked in by arnold, 12 years ago

For evaluation issues added a DateTime information to every LogMessage from P2P- and KeySearcher-PlugIns, because the LogMessages seems to be inaccurate and/or delayed in some cases

Additionally added a Begin- and End-Message into the KeySearcher with an TimeSpan information, how long the bruteforce process had taken

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