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

Last change on this file since 1448 was 1448, checked in by Sven Rech, 12 years ago

replaced all BigInteger stuff with the new BigInteger class from .net 4.0

But there are still problems with some plugins (Keysearcher, BigInteger Operations...)

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