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

Last change on this file since 2040 was 2040, checked in by Sven Rech, 11 years ago
  • added OpenCL.Net project
  • added OpenCL settings in KeySearcher
  • changed rereservation status message behavior
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            //wake up all sleeping threads, so they can stop:
676            while (threadStack.Count != 0)
677                ((ThreadStackElement)threadStack.Pop()).ev.Set();
678
679            if (!stop && !redirectResultsToStatisticsGenerator)
680                ProgressChanged(1, 1);
681
682            /* BEGIN: For evaluation issues - added by Arnold 2010.03.17 */
683            TimeSpan bruteforcingTime = DateTime.Now.Subtract(beginBruteforcing);
684            StringBuilder sbBFTime = new StringBuilder();
685            if (bruteforcingTime.Days > 0)
686                sbBFTime.Append(bruteforcingTime.Days.ToString() + " days ");
687            if (bruteforcingTime.Hours > 0)
688            {
689                if (bruteforcingTime.Hours <= 9)
690                    sbBFTime.Append("0");
691                sbBFTime.Append(bruteforcingTime.Hours.ToString() + ":");
692            }
693            if (bruteforcingTime.Minutes <= 9)
694                sbBFTime.Append("0");
695            sbBFTime.Append(bruteforcingTime.Minutes.ToString() + ":");
696            if (bruteforcingTime.Seconds <= 9)
697                sbBFTime.Append("0");
698            sbBFTime.Append(bruteforcingTime.Seconds.ToString() + "-");
699            if (bruteforcingTime.Milliseconds <= 9)
700                sbBFTime.Append("00");
701            if (bruteforcingTime.Milliseconds <= 99)
702                sbBFTime.Append("0");
703            sbBFTime.Append(bruteforcingTime.Milliseconds.ToString());
704
705            GuiLogMessage("Ended bruteforcing pattern '" + pattern.getKey() + "'. Bruteforcing TimeSpan: " + sbBFTime.ToString(), NotificationLevel.Debug);
706            /* END: For evaluation issues - added by Arnold 2010.03.17 */
707
708            return costList;
709        }
710
711        private void SetStartDate()
712        {
713            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
714        }
715
716        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, long keysPerSecond)
717        {
718            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
719
720            LinkedListNode<ValueKey> linkedListNode;
721            ProgressChanged((double)keycounter / (double) size, 1.0);
722
723            if (localQuickWatchPresentation.IsVisible && keysPerSecond != 0 && !stop)
724            {
725                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - Math.Log10(keysPerSecond)));
726                TimeSpan timeleft = new TimeSpan(-1);
727
728                try
729                {
730                    if (time / (24 * 60 * 60) <= int.MaxValue)
731                    {
732                        int days = (int)(time / (24 * 60 * 60));
733                        time = time - (days * 24 * 60 * 60);
734                        int hours = (int)(time / (60 * 60));
735                        time = time - (hours * 60 * 60);
736                        int minutes = (int)(time / 60);
737                        time = time - (minutes * 60);
738                        int seconds = (int)time;
739
740                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
741                    }
742                }
743                catch
744                {
745                    //can not calculate time span
746                }
747
748                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
749                {
750                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
751                    localQuickWatchPresentation.keysPerSecond.Content = "" + keysPerSecond;
752                    if (timeleft != new TimeSpan(-1))
753                    {
754                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
755                        try
756                        {
757                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
758                        }
759                        catch
760                        {
761                            localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
762                        }
763                    }
764                    else
765                    {
766                        localQuickWatchPresentation.timeLeft.Content = "incalculable :-)";
767                        localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
768                    }
769
770                    localQuickWatchPresentation.entries.Clear();
771                    linkedListNode = costList.First;
772                   
773                    int i = 0;
774                    while (linkedListNode != null)
775                    {
776                        i++;
777
778                        ResultEntry entry = new ResultEntry();
779                        entry.Ranking = "" + i;
780                        entry.Value = "" + Math.Round(linkedListNode.Value.value,3);
781                        entry.Key = linkedListNode.Value.key;
782                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
783
784                        localQuickWatchPresentation.entries.Add(entry);
785                        linkedListNode = linkedListNode.Next;
786                    }
787                }
788                , null);
789            }//end if
790
791
792            else if (!stop && localQuickWatchPresentation.IsVisible)
793            {
794
795                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
796                {
797                    localQuickWatchPresentation.entries.Clear();
798                    linkedListNode = costList.First;                   
799                    int i = 0;
800
801                    while (linkedListNode != null)
802                    {
803                        i++;
804
805                        ResultEntry entry = new ResultEntry();
806                        entry.Ranking = "" + i;
807                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
808                        entry.Key = linkedListNode.Value.key;
809                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
810
811                        localQuickWatchPresentation.entries.Add(entry);
812                        linkedListNode = linkedListNode.Next;
813                    }
814                }
815                , null);
816            }
817        }
818
819        #region For TopList
820
821        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
822        {
823            ValueKey valueKey = new ValueKey();
824            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
825                valueKey.value = double.MaxValue;
826            else
827                valueKey.value = double.MinValue;
828            valueKey.key = "dummykey";
829            valueKey.decryption = new byte[0];
830            value_threshold = valueKey.value;
831            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
832            for (int i = 1; i < maxInList; i++)
833            {
834                node = costList.AddAfter(node, valueKey);
835            }
836        }
837
838        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList)
839        {
840            foreach (var valueKey in updatedCostList)
841            {
842                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
843                {
844                    valuequeue.Enqueue(valueKey);
845                }
846            }
847
848            updateToplist();
849        }
850
851        internal void updateToplist()
852        {
853            LinkedListNode<ValueKey> node;
854            while (valuequeue.Count != 0)
855            {
856                ValueKey vk = (ValueKey)valuequeue.Dequeue();
857
858                //if (costList.Contains(vk)) continue;
859                var result = costList.Where(valueKey => valueKey.key == vk.key);
860                if (result.Count() > 0)
861                {
862                    continue;
863                }
864
865                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
866                {
867                    if (vk.value > costList.Last().value)
868                    {
869                        node = costList.First;
870                        while (node != null)
871                        {
872                            if (vk.value > node.Value.value)
873                            {
874                                if (node == costList.First)
875                                    Top1 = vk;
876                                costList.AddBefore(node, vk);
877                                costList.RemoveLast();
878                                value_threshold = costList.Last.Value.value;
879                                break;
880                            }
881                            node = node.Next;
882                        }//end while
883                    }//end if
884                }
885                else
886                {
887                    if (vk.value < costList.Last().value)
888                    {
889                        node = costList.First;
890                        while (node != null)
891                        {
892                            if (vk.value < node.Value.value)
893                            {
894                                if (node == costList.First)
895                                    Top1 = vk;
896                                costList.AddBefore(node, vk);
897                                costList.RemoveLast();
898                                value_threshold = costList.Last.Value.value;
899                                break;
900                            }
901                            node = node.Next;
902                        }//end while
903                    }//end if
904                }
905            }
906        }
907
908        #endregion
909
910        private void startThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
911        {
912            for (int i = 0; i < patterns.Length; i++)
913            {
914                WaitCallback worker = new WaitCallback(KeySearcherJob);
915                doneKeysA[i] = new BigInteger();
916                keycounters[i] = new BigInteger();
917                //ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
918                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack });
919            }
920        }
921
922        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
923        {
924            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[settings.CoresUsed + 1];
925            if (settings.CoresUsed > 0)
926            {
927                KeyPattern.KeyPattern[] patterns2 = pattern.split();
928                if (patterns2 == null)
929                {
930                    patterns2 = new KeyPattern.KeyPattern[1];
931                    patterns2[0] = pattern;
932                    return patterns2;
933                }
934                patterns[0] = patterns2[0];
935                patterns[1] = patterns2[1];
936                int p = 1;
937                int threads = settings.CoresUsed - 1;
938                while (threads > 0)
939                {
940                    int maxPattern = -1;
941                    BigInteger max = 0;
942                    for (int i = 0; i <= p; i++)
943                        if (patterns[i].size() > max)
944                        {
945                            max = patterns[i].size();
946                            maxPattern = i;
947                        }
948                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
949                    if (patterns3 == null)
950                    {
951                        patterns3 = new KeyPattern.KeyPattern[p+1];
952                        for (int i = 0; i <= p; i++)
953                            patterns3[i] = patterns[i];
954                        return patterns3;
955                    }
956                    patterns[maxPattern] = patterns3[0];
957                    patterns[++p] = patterns3[1];
958                    threads--;
959                }
960            }
961            else
962                patterns[0] = pattern;
963            return patterns;
964        }
965
966        private void keyPatternChanged()
967        {
968            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
969        }
970
971        // added by Arnie - 2009.12.07
972        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
973        /// <summary>
974        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
975        /// But when the returned List is filled, we have (at least a part) of the possible best keys
976        /// </summary>
977        public event BruteforcingEnded OnBruteforcingEnded;
978
979        // added by Arnie -2009.12.02
980        // for inheritance reasons
981        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
982        {
983            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
984            this.encryptedData = encryptedData;
985            this.initVector = initVector;
986            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
987
988            this.sender = encryptControl;
989            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
990            if(OnBruteforcingEnded != null)
991                OnBruteforcingEnded(lstRet);
992        }
993
994        #endregion
995
996        public void GuiLogMessage(string message, NotificationLevel loglevel)
997        {
998            if (OnGuiLogNotificationOccured != null)
999                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
1000        }
1001
1002        public void ProgressChanged(double value, double max)
1003        {
1004            if (OnPluginProgressChanged != null)
1005            {
1006                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1007
1008            }
1009        }
1010
1011        /// <summary>
1012        /// used for delivering the results from the worker threads to the main thread:
1013        /// </summary>
1014        public struct ValueKey
1015        {
1016            public double value;
1017            public String key;
1018            public byte[] decryption;
1019            public byte[] keya;
1020        };
1021    }
1022
1023    /// <summary>
1024    /// Represents one entry in our result list
1025    /// </summary>
1026    public class ResultEntry
1027    {
1028        public string Ranking { get; set; }
1029        public string Value { get; set; }
1030        public string Key { get; set; }
1031        public string Text { get; set; }
1032
1033    }
1034}
Note: See TracBrowser for help on using the repository browser.