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

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

added top1 outputs to keysearcher

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