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

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