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

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

fixed KeyPattern stuff

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