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

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

fixed top1 in keysearcher

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