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

Last change on this file since 1216 was 1216, checked in by Arno Wacker, 12 years ago

Deadlock hunting...

File size: 35.4 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            int maxInList = 10;
542            LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
543            fillListWithDummies(maxInList, costList);
544
545            stop = false;
546            if (!pattern.testWildcardKey(settings.Key))
547            {
548                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
549                return null;
550            }
551
552            int bytesToUse = 0;
553
554            try
555            {
556                bytesToUse = CostMaster.getBytesToUse();
557            }
558            catch (Exception ex)
559            {
560                GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
561                return null;
562            }
563
564            BigInteger size = pattern.size();
565            KeyPattern[] patterns = splitPatternForThreads(pattern);
566
567            valuequeue = Queue.Synchronized(new Queue());
568
569            BigInteger[] doneKeysA = new BigInteger[patterns.Length];
570            BigInteger[] keycounters = new BigInteger[patterns.Length];
571            BigInteger[] keysleft = new BigInteger[patterns.Length];
572            Stack threadStack = Stack.Synchronized(new Stack());
573            startThreads(sender, bytesToUse, patterns, doneKeysA, keycounters, keysleft, threadStack);
574
575            //update message:
576            while (!stop)
577            {
578                Thread.Sleep(1000);
579
580                updateToplist(costList);
581
582                #region calculate global counters from local counters
583                BigInteger keycounter = 0;
584                BigInteger doneKeys = 0;
585                foreach (BigInteger dk in doneKeysA)
586                    doneKeys += dk;
587                foreach (BigInteger kc in keycounters)
588                    keycounter += kc;
589                #endregion
590
591                if (keycounter > size)
592                    GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
593
594                #region determination of the thread with most keys
595                if (size - keycounter > 1000)
596                {
597                    try
598                    {
599                        maxThreadMutex.WaitOne();
600                        BigInteger max = 0;
601                        int id = -1;
602                        for (int i = 0; i < patterns.Length; i++)
603                            if (keysleft[i] != null && keysleft[i] > max)
604                            {
605                                max = keysleft[i];
606                                id = i;
607                            }
608                        maxThread = id;
609                    }
610                    finally
611                    {
612                        maxThreadMutex.ReleaseMutex();
613                    }
614                }
615                #endregion
616
617                showProgress(costList, size, keycounter, doneKeys);
618
619                #region set doneKeys to 0
620                doneKeys = 0;
621                for (int i = 0; i < doneKeysA.Length; i++)
622                    doneKeysA[i] = 0;
623                #endregion
624
625                if (keycounter >= size)
626                    break;
627            }//end while
628
629            //wake up all sleeping threads, so they can stop:
630            while (threadStack.Count != 0)
631                ((ThreadStackElement)threadStack.Pop()).ev.Set();
632
633            if (!stop)
634                ProgressChanged(1, 1);
635
636            return costList;
637        }
638
639        private void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, BigInteger doneKeys)
640        {
641            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
642
643            LinkedListNode<ValueKey> linkedListNode;
644            ProgressChanged(Math.Pow(10, keycounter.log(10) - size.log(10)), 1.0);
645
646            if (QuickWatchPresentation.IsVisible && doneKeys != 0 && !stop)
647            {
648                double time = (Math.Pow(10, (size - keycounter).log(10) - doneKeys.log(10)));
649                TimeSpan timeleft = new TimeSpan(-1);
650
651                try
652                {
653                    if (time / (24 * 60 * 60) <= int.MaxValue)
654                    {
655                        int days = (int)(time / (24 * 60 * 60));
656                        time = time - (days * 24 * 60 * 60);
657                        int hours = (int)(time / (60 * 60));
658                        time = time - (hours * 60 * 60);
659                        int minutes = (int)(time / 60);
660                        time = time - (minutes * 60);
661                        int seconds = (int)time;
662
663                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
664                    }
665                }
666                catch
667                {
668                    //can not calculate time span
669                }
670
671                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
672                {
673                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Text = "" + doneKeys;
674                    if (timeleft != new TimeSpan(-1))
675                    {
676                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "" + timeleft;
677                        try
678                        {
679                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "" + DateTime.Now.Add(timeleft);
680                        }
681                        catch
682                        {
683                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
684                        }
685                    }
686                    else
687                    {
688                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "incalculable :-)";
689                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
690                    }
691
692                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Clear();
693                    linkedListNode = costList.First;
694                   
695                    int i = 0;
696                    while (linkedListNode != null)
697                    {
698                        i++;
699
700                        ResultEntry entry = new ResultEntry();
701                        entry.Ranking = "" + i;
702                        entry.Value = "" + Math.Round(linkedListNode.Value.value,3);
703                        entry.Key = linkedListNode.Value.key;
704                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
705
706                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Add(entry);
707                        linkedListNode = linkedListNode.Next;
708                    }
709                }
710                , null);
711            }//end if
712
713
714            else if (!stop && QuickWatchPresentation.IsVisible)
715            {
716
717                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
718                {
719                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Clear();
720                    linkedListNode = costList.First;                   
721                    int i = 0;
722
723                    while (linkedListNode != null)
724                    {
725                        i++;
726
727                        ResultEntry entry = new ResultEntry();
728                        entry.Ranking = "" + i;
729                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
730                        entry.Key = linkedListNode.Value.key;
731                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
732
733                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Add(entry);
734                        linkedListNode = linkedListNode.Next;
735                    }
736                }
737                , null);
738            }
739        }
740
741        #region For TopList
742
743        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
744        {
745            ValueKey valueKey = new ValueKey();
746            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
747                valueKey.value = double.MaxValue;
748            else
749                valueKey.value = double.MinValue;
750            valueKey.key = "dummykey";
751            valueKey.decryption = new byte[0];
752            value_threshold = valueKey.value;
753            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
754            for (int i = 1; i < maxInList; i++)
755            {
756                node = costList.AddAfter(node, valueKey);
757            }
758        }
759
760        private void updateToplist(LinkedList<ValueKey> costList)
761        {
762            LinkedListNode<ValueKey> node;
763            while (valuequeue.Count != 0)
764            {
765                ValueKey vk = (ValueKey)valuequeue.Dequeue();
766                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
767                {
768                    if (vk.value > costList.Last().value)
769                    {
770                        node = costList.First;
771                        while (node != null)
772                        {
773                            if (vk.value > node.Value.value)
774                            {
775                                if (node == costList.First)
776                                    Top1 = vk;
777                                costList.AddBefore(node, vk);
778                                costList.RemoveLast();
779                                value_threshold = costList.Last.Value.value;
780                                break;
781                            }
782                            node = node.Next;
783                        }//end while
784                    }//end if
785                }
786                else
787                {
788                    if (vk.value < costList.Last().value)
789                    {
790                        node = costList.First;
791                        while (node != null)
792                        {
793                            if (vk.value < node.Value.value)
794                            {
795                                if (node == costList.First)
796                                    Top1 = vk;
797                                costList.AddBefore(node, vk);
798                                costList.RemoveLast();
799                                value_threshold = costList.Last.Value.value;
800                                break;
801                            }
802                            node = node.Next;
803                        }//end while
804                    }//end if
805                }
806            }
807        }
808
809        #endregion
810
811        private void startThreads(IControlEncryption sender, int bytesToUse, KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
812        {
813            for (int i = 0; i < patterns.Length; i++)
814            {
815                WaitCallback worker = new WaitCallback(KeySearcherJob);
816                doneKeysA[i] = new BigInteger();
817                keycounters[i] = new BigInteger();
818                //ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
819                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack });
820            }
821        }
822
823        private KeyPattern[] splitPatternForThreads(KeyPattern pattern)
824        {
825            KeyPattern[] patterns = new KeyPattern[settings.CoresUsed + 1];
826            if (settings.CoresUsed > 0)
827            {
828                KeyPattern[] patterns2 = pattern.split();
829                if (patterns2 == null)
830                {
831                    patterns2 = new KeyPattern[1];
832                    patterns2[0] = pattern;
833                    return patterns2;
834                }
835                patterns[0] = patterns2[0];
836                patterns[1] = patterns2[1];
837                int p = 1;
838                int threads = settings.CoresUsed - 1;
839                while (threads > 0)
840                {
841                    int maxPattern = -1;
842                    BigInteger max = 0;
843                    for (int i = 0; i <= p; i++)
844                        if (patterns[i].size() > max)
845                        {
846                            max = patterns[i].size();
847                            maxPattern = i;
848                        }
849                    KeyPattern[] patterns3 = patterns[maxPattern].split();
850                    if (patterns3 == null)
851                    {
852                        patterns3 = new KeyPattern[p+1];
853                        for (int i = 0; i <= p; i++)
854                            patterns3[i] = patterns[i];
855                        return patterns3;
856                    }
857                    patterns[maxPattern] = patterns3[0];
858                    patterns[++p] = patterns3[1];
859                    threads--;
860                }
861            }
862            else
863                patterns[0] = Pattern;
864            return patterns;
865        }
866
867        private void keyPatternChanged()
868        {
869            Pattern = new KeyPattern(controlMaster.getKeyPattern());
870        }
871
872        // added by Arnie - 2009.12.07
873        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
874        /// <summary>
875        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
876        /// But when the returned List is filled, we have (at least a part) of the possible best keys
877        /// </summary>
878        public event BruteforcingEnded OnBruteforcingEnded;
879
880        // added by Arnie -2009.12.02
881        // for inheritance reasons
882        public void BruteforcePattern(KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
883        {
884            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
885            this.encryptedData = encryptedData;
886            this.initVector = initVector;
887            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
888           
889            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern, encryptControl);
890            if(OnBruteforcingEnded != null)
891                OnBruteforcingEnded(lstRet);
892        }
893
894        #endregion
895
896        public void GuiLogMessage(string message, NotificationLevel loglevel)
897        {
898            if (OnGuiLogNotificationOccured != null)
899                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
900        }
901
902        public void ProgressChanged(double value, double max)
903        {
904            if (OnPluginProgressChanged != null)
905            {
906                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
907
908            }
909        }
910
911        /// <summary>
912        /// used for delivering the results from the worker threads to the main thread:
913        /// </summary>
914        public struct ValueKey
915        {
916            public double value;
917            public String key;
918            public byte[] decryption;
919        };
920    }
921
922    /// <summary>
923    /// Represents one entry in our result list
924    /// </summary>
925    public class ResultEntry
926    {
927        public string Ranking { get; set; }
928        public string Value { get; set; }
929        public string Key { get; set; }
930        public string Text { get; set; }
931
932    }
933}
Note: See TracBrowser for help on using the repository browser.