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

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

Added code to generate openCL bruteforce code in KeySearcher.
Not used yet, so don't try it

File size: 40.3 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                    IKeyTranslator 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, IKeyTranslator 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 string CreateOpenCLBruteForceCode(KeyPattern.KeyPattern keyPattern)
714        {
715            try
716            {
717                string code = sender.GetOpenCLCode(CostMaster.getBytesToUse());
718                if (code == null)
719                    throw new Exception("OpenCL not supported in this configuration!");
720
721                //put cost function stuff into code:
722                code = costMaster.ModifyOpenCLCode(code);
723
724                //put input to be bruteforced into code:
725                string inputarray = string.Format("__constant unsigned char inn[{0}] = {{ \n", CostMaster.getBytesToUse());
726                for (int i = 0; i < CostMaster.getBytesToUse(); i++)
727                {
728                    inputarray += String.Format("0x{0:X2}, ", this.encryptedData[i]);
729                }
730                inputarray = inputarray.Substring(0, inputarray.Length - 2);
731                inputarray += "}; \n";
732                code = code.Replace("$$INPUTARRAY$$", inputarray);
733
734                //put key movement of pattern into code:
735                IKeyTranslator keyTranslator = ControlMaster.getKeyTranslator();
736                keyTranslator.SetKeys(pattern);
737                code = keyTranslator.ModifyOpenCLCode(code, 256*256);
738
739                return code;
740            }
741            catch (Exception ex)
742            {
743                GuiLogMessage("Error trying to generate OpenCL code: " + ex.Message, NotificationLevel.Error);
744                return null;
745            }
746        }
747
748        private void SetStartDate()
749        {
750            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
751        }
752
753        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, long keysPerSecond)
754        {
755            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
756
757            LinkedListNode<ValueKey> linkedListNode;
758            ProgressChanged((double)keycounter / (double) size, 1.0);
759
760            if (localQuickWatchPresentation.IsVisible && keysPerSecond != 0 && !stop)
761            {
762                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - Math.Log10(keysPerSecond)));
763                TimeSpan timeleft = new TimeSpan(-1);
764
765                try
766                {
767                    if (time / (24 * 60 * 60) <= int.MaxValue)
768                    {
769                        int days = (int)(time / (24 * 60 * 60));
770                        time = time - (days * 24 * 60 * 60);
771                        int hours = (int)(time / (60 * 60));
772                        time = time - (hours * 60 * 60);
773                        int minutes = (int)(time / 60);
774                        time = time - (minutes * 60);
775                        int seconds = (int)time;
776
777                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
778                    }
779                }
780                catch
781                {
782                    //can not calculate time span
783                }
784
785                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
786                {
787                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
788                    localQuickWatchPresentation.keysPerSecond.Content = "" + keysPerSecond;
789                    if (timeleft != new TimeSpan(-1))
790                    {
791                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
792                        try
793                        {
794                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
795                        }
796                        catch
797                        {
798                            localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
799                        }
800                    }
801                    else
802                    {
803                        localQuickWatchPresentation.timeLeft.Content = "incalculable :-)";
804                        localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
805                    }
806
807                    localQuickWatchPresentation.entries.Clear();
808                    linkedListNode = costList.First;
809                   
810                    int i = 0;
811                    while (linkedListNode != null)
812                    {
813                        i++;
814
815                        ResultEntry entry = new ResultEntry();
816                        entry.Ranking = "" + i;
817                        entry.Value = "" + Math.Round(linkedListNode.Value.value,3);
818                        entry.Key = linkedListNode.Value.key;
819                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
820
821                        localQuickWatchPresentation.entries.Add(entry);
822                        linkedListNode = linkedListNode.Next;
823                    }
824                }
825                , null);
826            }//end if
827
828
829            else if (!stop && localQuickWatchPresentation.IsVisible)
830            {
831
832                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
833                {
834                    localQuickWatchPresentation.entries.Clear();
835                    linkedListNode = costList.First;                   
836                    int i = 0;
837
838                    while (linkedListNode != null)
839                    {
840                        i++;
841
842                        ResultEntry entry = new ResultEntry();
843                        entry.Ranking = "" + i;
844                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
845                        entry.Key = linkedListNode.Value.key;
846                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
847
848                        localQuickWatchPresentation.entries.Add(entry);
849                        linkedListNode = linkedListNode.Next;
850                    }
851                }
852                , null);
853            }
854        }
855
856        #region For TopList
857
858        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
859        {
860            ValueKey valueKey = new ValueKey();
861            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
862                valueKey.value = double.MaxValue;
863            else
864                valueKey.value = double.MinValue;
865            valueKey.key = "dummykey";
866            valueKey.decryption = new byte[0];
867            value_threshold = valueKey.value;
868            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
869            for (int i = 1; i < maxInList; i++)
870            {
871                node = costList.AddAfter(node, valueKey);
872            }
873        }
874
875        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList)
876        {
877            foreach (var valueKey in updatedCostList)
878            {
879                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
880                {
881                    valuequeue.Enqueue(valueKey);
882                }
883            }
884
885            updateToplist();
886        }
887
888        internal void updateToplist()
889        {
890            LinkedListNode<ValueKey> node;
891            while (valuequeue.Count != 0)
892            {
893                ValueKey vk = (ValueKey)valuequeue.Dequeue();
894
895                //if (costList.Contains(vk)) continue;
896                var result = costList.Where(valueKey => valueKey.key == vk.key);
897                if (result.Count() > 0)
898                {
899                    continue;
900                }
901
902                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
903                {
904                    if (vk.value > costList.Last().value)
905                    {
906                        node = costList.First;
907                        while (node != null)
908                        {
909                            if (vk.value > node.Value.value)
910                            {
911                                if (node == costList.First)
912                                    Top1 = vk;
913                                costList.AddBefore(node, vk);
914                                costList.RemoveLast();
915                                value_threshold = costList.Last.Value.value;
916                                break;
917                            }
918                            node = node.Next;
919                        }//end while
920                    }//end if
921                }
922                else
923                {
924                    if (vk.value < costList.Last().value)
925                    {
926                        node = costList.First;
927                        while (node != null)
928                        {
929                            if (vk.value < node.Value.value)
930                            {
931                                if (node == costList.First)
932                                    Top1 = vk;
933                                costList.AddBefore(node, vk);
934                                costList.RemoveLast();
935                                value_threshold = costList.Last.Value.value;
936                                break;
937                            }
938                            node = node.Next;
939                        }//end while
940                    }//end if
941                }
942            }
943        }
944
945        #endregion
946
947        private void startThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
948        {
949            for (int i = 0; i < patterns.Length; i++)
950            {
951                WaitCallback worker = new WaitCallback(KeySearcherJob);
952                doneKeysA[i] = new BigInteger();
953                keycounters[i] = new BigInteger();
954                //ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
955                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack });
956            }
957        }
958
959        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
960        {
961            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[settings.CoresUsed + 1];
962            if (settings.CoresUsed > 0)
963            {
964                KeyPattern.KeyPattern[] patterns2 = pattern.split();
965                if (patterns2 == null)
966                {
967                    patterns2 = new KeyPattern.KeyPattern[1];
968                    patterns2[0] = pattern;
969                    return patterns2;
970                }
971                patterns[0] = patterns2[0];
972                patterns[1] = patterns2[1];
973                int p = 1;
974                int threads = settings.CoresUsed - 1;
975                while (threads > 0)
976                {
977                    int maxPattern = -1;
978                    BigInteger max = 0;
979                    for (int i = 0; i <= p; i++)
980                        if (patterns[i].size() > max)
981                        {
982                            max = patterns[i].size();
983                            maxPattern = i;
984                        }
985                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
986                    if (patterns3 == null)
987                    {
988                        patterns3 = new KeyPattern.KeyPattern[p+1];
989                        for (int i = 0; i <= p; i++)
990                            patterns3[i] = patterns[i];
991                        return patterns3;
992                    }
993                    patterns[maxPattern] = patterns3[0];
994                    patterns[++p] = patterns3[1];
995                    threads--;
996                }
997            }
998            else
999                patterns[0] = pattern;
1000            return patterns;
1001        }
1002
1003        private void keyPatternChanged()
1004        {
1005            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
1006        }
1007
1008        // added by Arnie - 2009.12.07
1009        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
1010        /// <summary>
1011        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
1012        /// But when the returned List is filled, we have (at least a part) of the possible best keys
1013        /// </summary>
1014        public event BruteforcingEnded OnBruteforcingEnded;
1015
1016        // added by Arnie -2009.12.02
1017        // for inheritance reasons
1018        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
1019        {
1020            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1021            this.encryptedData = encryptedData;
1022            this.initVector = initVector;
1023            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1024
1025            this.sender = encryptControl;
1026            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
1027            if(OnBruteforcingEnded != null)
1028                OnBruteforcingEnded(lstRet);
1029        }
1030
1031        #endregion
1032
1033        public void GuiLogMessage(string message, NotificationLevel loglevel)
1034        {
1035            if (OnGuiLogNotificationOccured != null)
1036                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
1037        }
1038
1039        public void ProgressChanged(double value, double max)
1040        {
1041            if (OnPluginProgressChanged != null)
1042            {
1043                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1044
1045            }
1046        }
1047
1048        /// <summary>
1049        /// used for delivering the results from the worker threads to the main thread:
1050        /// </summary>
1051        public struct ValueKey
1052        {
1053            public double value;
1054            public String key;
1055            public byte[] decryption;
1056            public byte[] keya;
1057        };
1058    }
1059
1060    /// <summary>
1061    /// Represents one entry in our result list
1062    /// </summary>
1063    public class ResultEntry
1064    {
1065        public string Ranking { get; set; }
1066        public string Value { get; set; }
1067        public string Key { get; set; }
1068        public string Text { get; set; }
1069
1070    }
1071}
Note: See TracBrowser for help on using the repository browser.