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

Last change on this file since 1166 was 1166, checked in by arnold, 12 years ago

P2PManager: Design embellished and added an "estimated end time" information.
Samples: Output Boxes for KeySearcher Outputs

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