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

Last change on this file since 2010 was 2010, checked in by Sven Rech, 11 years ago

new key finding algorithm for KeySearcher

This update is really huge.

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