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

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

KeySearcher:

  • Removed creation of CryptoolStream for each trial key -> performance boost
  • Re-integrated the usage of only the partial encrypted message for trial decryption (byteToUse). Now the value set in the costFunction will determine how many bytes will be used. This value shall be moved in the future to the KeySearcher settings.

IControlEncryption

  • Added an extended method for Decrypt to IControlEncryption for usage with bytesToUse

AES/DES/SDES

  • Updated for compatibility with IControlEncryption-changes (the new parameter is also used by all three)

Samples

  • Updated KeySearcher-Sample-DES to use only 128 bytes for bruteforcing instead of 256 (increase performance a little)

Note: providing a value for bytesToUse smaller than the blocksize of the algorithm used is an error case - not sure if every case is already covered.

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