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

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

Fixed Ticket #131 - but in AES and SDES the new Decrypt-Method isn't implemented yet. Do be done by the specific Engineers.
Also fixed the other KeySearcher-Samples (DES, SDES and AES).
Still a bug: After reloading the Sample all In- and Outputs are visible event though the second Encryption-PlugIn is slave-connected

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