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

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

Added code for using keysearcher with external client.

External client not available yet.

File size: 57.1 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.IO;
20using System.Linq;
21using System.Net;
22using System.Text;
23using Cryptool.P2P;
24using Cryptool.P2P.Internal;
25using Cryptool.PluginBase.Analysis;
26using Cryptool.PluginBase;
27using System.Windows.Controls;
28using System.ComponentModel;
29using Cryptool.PluginBase.Control;
30using System.Collections;
31using System.Collections.Generic;
32using System.Threading;
33using System.Windows.Threading;
34using Cryptool.PluginBase.IO;
35using System.Numerics;
36using KeySearcher.Helper;
37using KeySearcher.KeyPattern;
38using KeySearcher.P2P;
39using KeySearcher.P2P.Exceptions;
40using KeySearcherPresentation;
41using KeySearcherPresentation.Controls;
42using OpenCLNet;
43
44namespace KeySearcher
45{   
46    [Author("Sven Rech, Nils Kopal, Raoul Falk, Dennis Nolte", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
47    [PluginInfo(false, "KeySearcher", "Bruteforces a decryption algorithm.", "KeySearcher/DetailedDescription/Description.xaml", "KeySearcher/Images/icon.png")]
48    public class KeySearcher : IAnalysisMisc
49    {
50        /// <summary>
51        /// used for creating the TopList
52        /// </summary>
53        private Queue valuequeue;
54        private double value_threshold;
55        /// <summary>
56        /// the thread with the most keys left
57        /// </summary>
58        private int maxThread;
59        private readonly Mutex maxThreadMutex = new Mutex();
60        private ArrayList threadsStopEvents;
61
62        public bool IsKeySearcherRunning;
63        private KeyQualityHelper keyQualityHelper;
64        private readonly P2PQuickWatchPresentation p2PQuickWatchPresentation;
65        private readonly LocalQuickWatchPresentation localQuickWatchPresentation;
66
67        private OpenCLManager oclManager = null;
68        private Mutex openCLPresentationMutex = new Mutex();
69
70        private readonly Stopwatch localBruteForceStopwatch;
71
72        private KeyPattern.KeyPattern pattern;
73        public KeyPattern.KeyPattern Pattern
74        {
75            get
76            {
77                return pattern;
78            }
79            set
80            {
81                pattern = value;
82                if ((settings.Key == null) || ((settings.Key != null) && !pattern.testWildcardKey(settings.Key)))
83                    settings.Key = pattern.giveInputPattern();
84            }
85        }
86
87        internal bool stop;
88
89        internal bool update;
90
91        #region IControlEncryption + IControlCost + InputFields
92
93        #region IControlEncryption Members
94
95        private IControlEncryption controlMaster;
96        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
97        public IControlEncryption ControlMaster
98        {
99            get { return controlMaster; }
100            set
101            {
102                if (controlMaster != null)
103                {
104                    controlMaster.keyPatternChanged -= keyPatternChanged;
105                }
106                if (value != null)
107                {
108                    Pattern = new KeyPattern.KeyPattern(value.getKeyPattern());
109                    value.keyPatternChanged += keyPatternChanged;
110                    controlMaster = value;
111                    OnPropertyChanged("ControlMaster");
112
113                }
114                else
115                    controlMaster = null;
116            }
117        }
118
119        #endregion
120
121        #region IControlCost Members
122
123        private IControlCost costMaster;
124        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
125        public IControlCost CostMaster
126        {
127            get { return costMaster; }
128            set
129            {
130                costMaster = value;
131                keyQualityHelper = new KeyQualityHelper(costMaster);
132            }
133        }
134
135        #endregion
136
137        /* BEGIN: following lines are from Arnie - 2010.01.12 */
138        CryptoolStream csEncryptedData;
139        [PropertyInfo(Direction.InputData, "CS Encrypted Data", "Encrypted data out of an Encryption PlugIn", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, "")]
140        public virtual CryptoolStream CSEncryptedData
141        {
142            get { return this.csEncryptedData; }
143            set
144            {
145                if (value != this.csEncryptedData)
146                {
147                    this.csEncryptedData = value;
148                    this.encryptedData = GetByteFromCryptoolStream(value);
149                    OnPropertyChanged("CSEncryptedData");
150                }
151            }
152        }
153
154        byte[] encryptedData;
155        [PropertyInfo(Direction.InputData,"Encrypted Data","Encrypted data out of an Encryption PlugIn","",false,false,DisplayLevel.Beginner,QuickWatchFormat.Hex,"")]
156        public virtual byte[] EncryptedData
157        {
158            get { return this.encryptedData; }
159            set
160            {
161                if (value != this.encryptedData)
162                {
163                    this.encryptedData = value;
164                    OnPropertyChanged("EncryptedData");
165                }
166            }
167        }
168
169        /// <summary>
170        /// When the Input-Slot changed, set this variable to true, so the new Stream will be transformed to byte[]
171        /// </summary>
172        private byte[] GetByteFromCryptoolStream(CryptoolStream cryptoolStream)
173        {
174            byte[] encryptedByteData = null;
175
176            if (cryptoolStream != null)
177            {
178                CryptoolStream cs = new CryptoolStream();
179                cs.OpenRead(cryptoolStream.FileName);
180                encryptedByteData = new byte[cs.Length];
181                if(cs.Length > Int32.MaxValue)
182                    throw(new Exception("CryptoolStream length is longer than the Int32.MaxValue"));
183                cs.Read(encryptedByteData, 0, (int)cs.Length);
184            }
185            return encryptedByteData;
186        }
187
188        byte[] initVector;
189        [PropertyInfo(Direction.InputData, "Initialization Vector", "Initialization vector with which the data were encrypted", "", DisplayLevel.Beginner)]
190        public virtual byte[] InitVector
191        {
192            get { return this.initVector; }
193            set
194            {
195                if (value != this.initVector)
196                {
197                    this.initVector = value;
198                    OnPropertyChanged("InitVector");
199                }
200            }
201        }
202        /* END: Lines above are from Arnie - 2010.01.12 */
203
204        private ValueKey top1ValueKey;
205        public virtual ValueKey Top1
206        {
207            set { top1ValueKey = value; OnPropertyChanged("Top1Message"); OnPropertyChanged("Top1Key"); }
208        }
209
210        [PropertyInfo(Direction.OutputData, "Top1 Message", "The best message found", "", DisplayLevel.Beginner)]
211        public virtual byte[] Top1Message
212        {
213            get { return top1ValueKey.decryption; }
214        }
215        [PropertyInfo(Direction.OutputData, "Top1 Key", "The best key found", "", DisplayLevel.Beginner)]
216        public virtual byte[] Top1Key
217        {
218            get
219            {
220                if (top1ValueKey.key != null)
221                {
222                    return top1ValueKey.keya;
223                }
224                else
225                    return null;
226            }
227        }
228
229        #endregion
230
231        #region IPlugin Members
232
233        public event StatusChangedEventHandler OnPluginStatusChanged;
234
235        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
236
237        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
238
239        private KeySearcherSettings settings;
240        private AutoResetEvent connectResetEvent;
241
242        #region external client variables
243        private CryptoolServer cryptoolServer;
244        private KeySearcherOpenCLCode externalKeySearcherOpenCLCode;
245        private IKeyTranslator externalKeyTranslator;
246        private int externalKeysProcessed;
247        private EndPoint externalClientConnected;
248        private AutoResetEvent waitForExternalClientToFinish = new AutoResetEvent(false);
249        #endregion
250
251        public KeySearcher()
252        {
253            IsKeySearcherRunning = false;
254           
255            if (OpenCL.NumberOfPlatforms > 0)
256            {
257                oclManager = new OpenCLManager();
258                oclManager.AttemptUseBinaries = false;
259                oclManager.AttemptUseSource = true;
260                oclManager.RequireImageSupport = false;
261                var directoryName = Path.Combine(DirectoryHelper.DirectoryLocalTemp, "KeySearcher");
262                oclManager.BinaryPath = Path.Combine(directoryName, "openclbin");
263                oclManager.BuildOptions = "";
264                oclManager.CreateDefaultContext(0, DeviceType.ALL);
265            }
266
267            settings = new KeySearcherSettings(this, oclManager);
268           
269            QuickWatchPresentation = new QuickWatch();
270            localQuickWatchPresentation = ((QuickWatch) QuickWatchPresentation).LocalQuickWatchPresentation;
271            p2PQuickWatchPresentation = ((QuickWatch)QuickWatchPresentation).P2PQuickWatchPresentation;
272            p2PQuickWatchPresentation.UpdateSettings(this, settings);
273
274            settings.PropertyChanged += SettingsPropertyChanged;
275            ((QuickWatch)QuickWatchPresentation).IsOpenCLEnabled = (settings.DeviceSettings.Count(x => x.useDevice) > 0);
276
277            localBruteForceStopwatch = new Stopwatch();
278        }
279
280        void SettingsPropertyChanged(object sender, PropertyChangedEventArgs e)
281        {
282            p2PQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
283                                                             new Action(UpdateQuickwatchSettings));
284        }
285
286        void UpdateQuickwatchSettings()
287        {
288            ((QuickWatch)QuickWatchPresentation).IsP2PEnabled = settings.UsePeerToPeer;
289            ((QuickWatch)QuickWatchPresentation).IsOpenCLEnabled = (settings.DeviceSettings.Count(x => x.useDevice) > 0);
290            p2PQuickWatchPresentation.UpdateSettings(this, settings);
291        }
292
293        public ISettings Settings
294        {
295            get { return settings; }
296        }
297
298        public UserControl Presentation
299        {
300            get { return QuickWatchPresentation; }
301        }
302
303        public UserControl QuickWatchPresentation
304        {
305            get;
306            private set;
307        }
308
309        public void PreExecution()
310        {
311            update = false;
312        }
313
314        // because Encryption PlugIns were changed radical, the new StartPoint is here - Arnie 2010.01.12
315        public virtual void Execute()
316        {
317            IsKeySearcherRunning = true;
318            localBruteForceStopwatch.Reset();
319
320            //either byte[] CStream input or CryptoolStream Object input
321            if (encryptedData != null || csEncryptedData != null) //to prevent execution on initialization
322            {
323                if (ControlMaster != null)
324                    process(ControlMaster);
325                else
326                {
327                    GuiLogMessage("You have to connect the KeySearcher with the Decryption Control!", NotificationLevel.Warning);
328                }
329            }
330        }
331
332        public void PostExecution()
333        {
334        }
335
336        public void Pause()
337        {
338        }
339
340        public void Stop()
341        {
342            IsKeySearcherRunning = false;
343            stop = true;
344            waitForExternalClientToFinish.Set();
345        }
346
347        public void Initialize()
348        {
349            settings.Initialize();
350        }
351
352        public void Dispose()
353        {
354        }
355
356        #endregion
357
358        #region INotifyPropertyChanged Members
359
360        public event PropertyChangedEventHandler PropertyChanged;
361
362        public void OnPropertyChanged(string name)
363        {
364            if (PropertyChanged != null)
365            {
366                PropertyChanged(this, new PropertyChangedEventArgs(name));
367            }
368        }
369
370        #endregion
371
372        #region whole KeySearcher functionality
373
374        private class ThreadStackElement
375        {
376            public AutoResetEvent ev;
377            public int threadid;
378        }
379
380        #region code for the worker threads
381
382        private void KeySearcherJob(object param)
383        {
384            AutoResetEvent stopEvent = new AutoResetEvent(false);
385            threadsStopEvents.Add(stopEvent);
386
387            object[] parameters = (object[])param;
388            KeyPattern.KeyPattern[] patterns = (KeyPattern.KeyPattern[])parameters[0];
389            int threadid = (int)parameters[1];
390            BigInteger[] doneKeysArray = (BigInteger[])parameters[2];
391            BigInteger[] openCLDoneKeysArray = (BigInteger[])parameters[3];
392            BigInteger[] keycounterArray = (BigInteger[])parameters[4];
393            BigInteger[] keysLeft = (BigInteger[])parameters[5];
394            IControlEncryption sender = (IControlEncryption)parameters[6];
395            int bytesToUse = (int)parameters[7];
396            Stack threadStack = (Stack)parameters[8];
397            var openCLDeviceSettings = (KeySearcherSettings.OpenCLDeviceSettings)parameters[9];
398
399            KeySearcherOpenCLCode keySearcherOpenCLCode = null;
400            KeySearcherOpenCLSubbatchOptimizer keySearcherOpenCLSubbatchOptimizer = null;
401            if (openCLDeviceSettings != null)
402            {
403                keySearcherOpenCLCode = new KeySearcherOpenCLCode(this, encryptedData, sender, CostMaster, 256 * 256 * 256 * 16);
404                keySearcherOpenCLSubbatchOptimizer = new KeySearcherOpenCLSubbatchOptimizer(openCLDeviceSettings.mode, 
405                        oclManager.CQ[openCLDeviceSettings.index].Device.MaxWorkItemSizes.Aggregate(1, (x, y) => (x * (int)y)) / 8);
406
407                ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
408                {
409                    openCLPresentationMutex.WaitOne();
410                    ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices++;
411                    openCLPresentationMutex.ReleaseMutex();
412                }, null);
413                Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
414            }
415
416            try
417            {
418                while (patterns[threadid] != null)
419                {
420                    BigInteger size = patterns[threadid].size();
421                    keysLeft[threadid] = size;
422                   
423                    IKeyTranslator keyTranslator = ControlMaster.getKeyTranslator();
424                    keyTranslator.SetKeys(patterns[threadid]);
425
426                    bool finish = false;
427
428                    do
429                    {
430                        //if we are the thread with most keys left, we have to share them:
431                        keyTranslator = ShareKeys(patterns, threadid, keysLeft, keyTranslator, threadStack);
432
433                        if (openCLDeviceSettings == null)         //CPU
434                        {
435                            finish = BruteforceCPU(keyTranslator, sender, bytesToUse);
436                        }
437                        else                    //OpenCL
438                        {
439                            try
440                            {
441                                finish = BruteforceOpenCL(keySearcherOpenCLCode, keySearcherOpenCLSubbatchOptimizer, keyTranslator, sender, bytesToUse, parameters);
442                            }
443                            catch (Exception)
444                            {
445                                openCLDeviceSettings.useDevice = false;
446                                ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
447                                {
448                                    openCLPresentationMutex.WaitOne();
449                                    ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices--;
450                                    openCLPresentationMutex.ReleaseMutex();
451                                }, null);
452                                continue;
453                            }
454                        }
455                       
456                        int progress = keyTranslator.GetProgress();
457
458                        if (openCLDeviceSettings == null)
459                        {
460                            doneKeysArray[threadid] += progress;
461                            keycounterArray[threadid] += progress;
462                            keysLeft[threadid] -= progress;
463                        }
464
465                    } while (!finish && !stop);
466
467                    if (stop)
468                        return;
469
470                    //Let's wait until another thread is willing to share with us:
471                    WaitForNewPattern(patterns, threadid, threadStack);
472                }
473            }
474            finally
475            {
476                sender.Dispose();
477                stopEvent.Set();
478            }
479        }
480
481        private unsafe bool BruteforceOpenCL(KeySearcherOpenCLCode keySearcherOpenCLCode, KeySearcherOpenCLSubbatchOptimizer keySearcherOpenCLSubbatchOptimizer, IKeyTranslator keyTranslator, IControlEncryption sender, int bytesToUse, object[] parameters)
482        {
483            int threadid = (int)parameters[1];
484            BigInteger[] doneKeysArray = (BigInteger[])parameters[2];
485            BigInteger[] openCLDoneKeysArray = (BigInteger[])parameters[3];
486            BigInteger[] keycounterArray = (BigInteger[])parameters[4];
487            BigInteger[] keysLeft = (BigInteger[])parameters[5];
488            var openCLDeviceSettings = (KeySearcherSettings.OpenCLDeviceSettings)parameters[9];
489            try
490            {
491                Kernel bruteforceKernel = keySearcherOpenCLCode.GetBruteforceKernel(oclManager, keyTranslator);
492
493                int deviceIndex = openCLDeviceSettings.index;
494               
495                Mem userKey;
496                var key = keyTranslator.GetKey();
497                fixed (byte* ukp = key)
498                    userKey = oclManager.Context.CreateBuffer(MemFlags.USE_HOST_PTR, key.Length, new IntPtr((void*)ukp));
499
500                int subbatches = keySearcherOpenCLSubbatchOptimizer.GetAmountOfSubbatches(keyTranslator);
501                int subbatchSize = keyTranslator.GetOpenCLBatchSize() / subbatches;
502                ((QuickWatch) QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate
503                                                                    {
504                                                                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.workItems.Content = subbatchSize;
505                                                                    }, null);
506                //GuiLogMessage(string.Format("Now using {0} subbatches", subbatches), NotificationLevel.Info);
507               
508                float[] costArray = new float[subbatchSize];
509                Mem costs = oclManager.Context.CreateBuffer(MemFlags.READ_WRITE, costArray.Length * 4);
510
511                IntPtr[] globalWorkSize = { (IntPtr)subbatchSize };
512
513                keySearcherOpenCLSubbatchOptimizer.BeginMeasurement();
514
515                try
516                {
517                    for (int i = 0; i < subbatches; i++)
518                    {
519                        bruteforceKernel.SetArg(0, userKey);
520                        bruteforceKernel.SetArg(1, costs);
521                        bruteforceKernel.SetArg(2, i * subbatchSize);
522                        oclManager.CQ[deviceIndex].EnqueueNDRangeKernel(bruteforceKernel, 1, null, globalWorkSize, null);
523                        oclManager.CQ[deviceIndex].EnqueueBarrier();
524
525                        Event e;
526                        fixed (float* costa = costArray)
527                            oclManager.CQ[deviceIndex].EnqueueReadBuffer(costs, true, 0, costArray.Length * 4, new IntPtr((void*)costa), 0, null, out e);
528
529                        e.Wait();
530
531                        checkOpenCLResults(keyTranslator, costArray, sender, bytesToUse, i * subbatchSize);
532
533                        doneKeysArray[threadid] += subbatchSize;
534                        openCLDoneKeysArray[threadid] += subbatchSize;
535                        keycounterArray[threadid] += subbatchSize;
536                        keysLeft[threadid] -= subbatchSize;
537
538                        if (stop)
539                            return false;
540                    }
541
542                    keySearcherOpenCLSubbatchOptimizer.EndMeasurement();
543                }
544                finally
545                {
546                    costs.Dispose();
547                }
548            }
549            catch (Exception ex)
550            {
551                GuiLogMessage(ex.Message, NotificationLevel.Error);
552                GuiLogMessage("Bruteforcing with OpenCL failed! Using CPU instead.", NotificationLevel.Error);
553                throw new Exception("Bruteforcing with OpenCL failed!");
554            }
555
556            return !keyTranslator.NextOpenCLBatch();
557        }
558
559        private void checkOpenCLResults(IKeyTranslator keyTranslator, float[] costArray, IControlEncryption sender, int bytesToUse, int add)
560        {
561            var op = this.costMaster.getRelationOperator();
562            for (int i = 0; i < costArray.Length; i++)
563            {
564                float cost = costArray[i];
565                if (((op == RelationOperator.LargerThen) && (cost > value_threshold))
566                    || (op == RelationOperator.LessThen) && (cost < value_threshold))
567                {
568                    ValueKey valueKey = new ValueKey { value = cost, key = keyTranslator.GetKeyRepresentation(i + add) };
569                    valueKey.keya = keyTranslator.GetKeyFromRepresentation(valueKey.key);
570                    valueKey.decryption = sender.Decrypt(this.encryptedData, valueKey.keya, InitVector, bytesToUse);
571                    valuequeue.Enqueue(valueKey);
572                }
573            }
574        }
575
576        private bool BruteforceCPU(IKeyTranslator keyTranslator, IControlEncryption sender, int bytesToUse)
577        {
578            bool finish = false;
579            for (int count = 0; count < 256 * 256; count++)
580            {
581                byte[] keya = keyTranslator.GetKey();
582
583                if (!decryptAndCalculate(sender, bytesToUse, keya, keyTranslator))
584                    throw new Exception("Bruteforcing not possible!");
585
586                finish = !keyTranslator.NextKey();
587                if (finish)
588                    break;
589            }
590            return finish;
591        }
592
593        private IKeyTranslator ShareKeys(KeyPattern.KeyPattern[] patterns, int threadid, BigInteger[] keysLeft, IKeyTranslator keyTranslator, Stack threadStack)
594        {
595            BigInteger size;
596            if (maxThread == threadid && threadStack.Count != 0)
597            {
598                try
599                {
600                    maxThreadMutex.WaitOne();
601                    if (maxThread == threadid && threadStack.Count != 0)
602                    {
603                        KeyPattern.KeyPattern[] split = patterns[threadid].split();
604                        if (split != null)
605                        {
606                            patterns[threadid] = split[0];
607                            keyTranslator = ControlMaster.getKeyTranslator();
608                            keyTranslator.SetKeys(patterns[threadid]);
609
610                            ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
611                            patterns[elem.threadid] = split[1];
612                            elem.ev.Set();    //wake the other thread up                                   
613                            size = patterns[threadid].size();
614                            keysLeft[threadid] = size;
615                        }
616                        maxThread = -1;
617                    }
618                }
619                finally
620                {
621                    maxThreadMutex.ReleaseMutex();
622                }
623            }
624            return keyTranslator;
625        }
626
627        private void WaitForNewPattern(KeyPattern.KeyPattern[] patterns, int threadid, Stack threadStack)
628        {
629            ThreadStackElement el = new ThreadStackElement();
630            el.ev = new AutoResetEvent(false);
631            el.threadid = threadid;
632            patterns[threadid] = null;
633            threadStack.Push(el);
634            GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
635            el.ev.WaitOne();
636            if (!stop)
637            {
638                GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
639            }
640        }
641
642        #region bruteforce methods
643
644        private bool decryptAndCalculate(IControlEncryption sender, int bytesToUse, byte[] keya, IKeyTranslator keyTranslator)
645        {
646            ValueKey valueKey;
647
648            try
649            {
650                if (this.encryptedData != null && this.encryptedData.Length > 0)
651                {
652                    valueKey.decryption = sender.Decrypt(this.encryptedData, keya, InitVector, bytesToUse);
653                }
654                else
655                {
656                    GuiLogMessage("Can't bruteforce empty input!", NotificationLevel.Error);
657                    return false;
658                }
659            }
660            catch (Exception ex)
661            {
662                GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
663                GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
664                return false;
665            }
666
667            try
668            {
669                valueKey.value = CostMaster.calculateCost(valueKey.decryption);
670            }
671            catch (Exception ex)
672            {
673                GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
674                return false;
675            }
676
677            if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
678            {
679                if (valueKey.value > value_threshold)
680                {
681                    valueKey.key = keyTranslator.GetKeyRepresentation();
682                    valueKey.keya = (byte[])keya.Clone();
683                    valuequeue.Enqueue(valueKey);                   
684                }
685            }
686            else
687            {
688                if (valueKey.value < value_threshold)
689                {
690                    valueKey.key = keyTranslator.GetKeyRepresentation();
691                    valueKey.keya = (byte[])keya.Clone();                 
692                    valuequeue.Enqueue(valueKey);
693                }
694            }
695            return true;
696        }
697
698        #endregion
699
700        #endregion
701
702        public void process(IControlEncryption sender)
703        {
704            if (sender == null || costMaster == null)
705                return;
706            if (!Pattern.testWildcardKey(settings.Key))
707            {
708                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
709                return;
710            }
711            Pattern.WildcardKey = settings.Key;
712            this.sender = sender;
713
714            bruteforcePattern(Pattern);
715        }
716
717        internal LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
718        private int bytesToUse;
719        private IControlEncryption sender;
720        private DateTime beginBruteforcing;
721        private DistributedBruteForceManager distributedBruteForceManager;
722
723        // main entry point to the KeySearcher
724        private LinkedList<ValueKey> bruteforcePattern(KeyPattern.KeyPattern pattern)
725        {
726            beginBruteforcing = DateTime.Now;
727            GuiLogMessage("Start bruteforcing pattern '" + pattern.getKey() + "'", NotificationLevel.Debug);
728                       
729            int maxInList = 10;
730            costList = new LinkedList<ValueKey>();
731            fillListWithDummies(maxInList, costList);
732            valuequeue = Queue.Synchronized(new Queue());
733
734            stop = false;
735            if (!pattern.testWildcardKey(settings.Key))
736            {
737                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
738                return null;
739            }
740
741            // bytesToUse = 0;
742
743            try
744            {
745                bytesToUse = CostMaster.getBytesToUse();
746            }
747            catch (Exception ex)
748            {
749                GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
750                return null;
751            }
752
753            Thread serverThread = null;
754            try
755            {
756                if (settings.UseExternalClient)
757                {
758                    GuiLogMessage("Waiting for external client!", NotificationLevel.Info);
759                    cryptoolServer = new CryptoolServer();
760                    externalClientConnected = null;
761                    cryptoolServer.Port = settings.Port;
762                    cryptoolServer.OnJobCompleted += new CryptoolServer.JobCompletedDelegate(server_OnJobCompleted);
763                    cryptoolServer.OnClientConnected += new CryptoolServer.ClientConnectedDelegate(server_OnClientConnected);
764                    cryptoolServer.OnClientDisconnected += new CryptoolServer.ClientDisconnectedDelegate(cryptoolServer_OnClientDisconnected);
765                    serverThread = new Thread(new ThreadStart(delegate
766                                                                      {
767                                                                          cryptoolServer.Run();
768                                                                      }));
769                    serverThread.Start();
770                }
771
772                if (settings.UsePeerToPeer)
773                {
774                    BruteForceWithPeerToPeerSystem();
775                    return null;
776                }
777
778                return BruteForceWithLocalSystem(pattern);
779            }
780            finally
781            {
782                if (stop && serverThread != null)
783                {
784                    //stop server here!
785                }
786            }
787        }
788
789        private void BruteForceWithPeerToPeerSystem()
790        {
791            if (!update)
792            {
793                GuiLogMessage("Launching p2p based bruteforce logic...", NotificationLevel.Info);
794
795                try
796                {
797                    distributedBruteForceManager = new DistributedBruteForceManager(this, pattern, settings,
798                                                                                    keyQualityHelper,
799                                                                                    p2PQuickWatchPresentation);
800                    distributedBruteForceManager.Execute();
801                }
802                catch (NotConnectedException)
803                {
804                    GuiLogMessage("P2P not connected.", NotificationLevel.Error);
805                }
806                catch (KeySearcherStopException)
807                {
808                    update = true;
809                    return;
810                }
811            }
812            else
813            {
814                GuiLogMessage("Keysearcher Fullstop.Please Update your Version.", NotificationLevel.Error);
815                Thread.Sleep(3000);
816            }
817        }
818
819        internal LinkedList<ValueKey> BruteForceWithLocalSystem(KeyPattern.KeyPattern pattern, bool redirectResultsToStatisticsGenerator = false)
820        {
821            ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
822            {
823                openCLPresentationMutex.WaitOne();
824                ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.AmountOfDevices = 0;
825                openCLPresentationMutex.ReleaseMutex();
826            }, null);
827
828            if (!redirectResultsToStatisticsGenerator)
829            {
830                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(SetStartDate));
831                localBruteForceStopwatch.Start();
832            }
833
834            if (settings.UseExternalClient)
835            {
836                GuiLogMessage("Only using external client to bruteforce!", NotificationLevel.Info);
837                lock (this)
838                {
839                    externalKeySearcherOpenCLCode = new KeySearcherOpenCLCode(this, encryptedData, sender, CostMaster,
840                                                                              256*256*256*64);
841                    externalKeysProcessed = 0;
842                    externalKeyTranslator = ControlMaster.getKeyTranslator();
843                    externalKeyTranslator.SetKeys(pattern);
844                    if (externalClientConnected != null)
845                        AssignJobToClient(externalClientConnected, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
846                }
847                waitForExternalClientToFinish.Reset();
848                waitForExternalClientToFinish.WaitOne();
849            }
850            else
851            {
852                BigInteger size = pattern.size();
853                KeyPattern.KeyPattern[] patterns = splitPatternForThreads(pattern);
854                if (patterns == null || patterns.Length == 0)
855                {
856                    GuiLogMessage("No ressources to BruteForce available. Check the KeySearcher settings!", NotificationLevel.Error);
857                    throw new Exception("No ressources to BruteForce available. Check the KeySearcher settings!");
858                }
859
860                BigInteger[] doneKeysA = new BigInteger[patterns.Length];
861                BigInteger[] openCLDoneKeysA = new BigInteger[patterns.Length];
862                BigInteger[] keycounters = new BigInteger[patterns.Length];
863                BigInteger[] keysleft = new BigInteger[patterns.Length];
864                Stack threadStack = Stack.Synchronized(new Stack());
865                threadsStopEvents = ArrayList.Synchronized(new ArrayList());
866                StartThreads(sender, bytesToUse, patterns, doneKeysA, openCLDoneKeysA, keycounters, keysleft, threadStack);
867
868                DateTime lastTime = DateTime.Now;
869
870                //update message:
871                while (!stop)
872                {
873                    Thread.Sleep(2000);
874
875                    updateToplist();
876
877                    #region calculate global counters from local counters
878                    BigInteger keycounter = 0;
879                    BigInteger doneKeys = 0;
880                    BigInteger openCLdoneKeys = 0;
881                    foreach (BigInteger dk in doneKeysA)
882                        doneKeys += dk;
883                    foreach (BigInteger dk in openCLDoneKeysA)
884                        openCLdoneKeys += dk;
885                    foreach (BigInteger kc in keycounters)
886                        keycounter += kc;
887                    #endregion
888
889                    if (keycounter > size)
890                        GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
891
892                    #region determination of the thread with most keys
893                    if (size - keycounter > 1000)
894                    {
895                        try
896                        {
897                            maxThreadMutex.WaitOne();
898                            BigInteger max = 0;
899                            int id = -1;
900                            for (int i = 0; i < patterns.Length; i++)
901                                if (keysleft[i] != null && keysleft[i] > max)
902                                {
903                                    max = keysleft[i];
904                                    id = i;
905                                }
906                            maxThread = id;
907                        }
908                        finally
909                        {
910                            maxThreadMutex.ReleaseMutex();
911                        }
912                    }
913                    #endregion
914
915                    long keysPerSecond = (long)((long)doneKeys / (DateTime.Now - lastTime).TotalSeconds);
916                    long openCLKeysPerSecond = (long)((long)openCLdoneKeys / (DateTime.Now - lastTime).TotalSeconds);
917                    lastTime = DateTime.Now;
918                    if (redirectResultsToStatisticsGenerator)
919                    {
920                        distributedBruteForceManager.StatisticsGenerator.ShowProgress(costList, size, keycounter, keysPerSecond);
921                    }
922                    else
923                    {
924                        showProgress(costList, size, keycounter, keysPerSecond);
925                    }
926
927                    //show OpenCL keys/sec:
928                    var ratio = (double)openCLdoneKeys / (double)doneKeys;
929                    ((QuickWatch)QuickWatchPresentation).Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
930                    {
931                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondOpenCL.Content = String.Format("{0:N}", openCLKeysPerSecond);
932                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.keysPerSecondCPU.Content = String.Format("{0:N}", (keysPerSecond - openCLKeysPerSecond));
933                        ((QuickWatch)QuickWatchPresentation).OpenCLPresentation.ratio.Content = String.Format("{0:P}", ratio);
934                    }, null);
935
936
937                    #region set doneKeys to 0
938                    doneKeys = 0;
939                    for (int i = 0; i < doneKeysA.Length; i++)
940                        doneKeysA[i] = 0;
941                    openCLdoneKeys = 0;
942                    for (int i = 0; i < openCLDoneKeysA.Length; i++)
943                        openCLDoneKeysA[i] = 0;
944                    #endregion
945
946                    if (keycounter >= size)
947                        break;
948                }//end while
949
950                showProgress(costList, 1, 1, 1);
951
952                //wake up all sleeping threads, so they can stop:
953                while (threadStack.Count != 0)
954                    ((ThreadStackElement)threadStack.Pop()).ev.Set();
955
956                //wait until all threads finished:
957                foreach (AutoResetEvent stopEvent in threadsStopEvents)
958                {
959                    stopEvent.WaitOne();
960                }
961
962                if (!stop && !redirectResultsToStatisticsGenerator)
963                    ProgressChanged(1, 1);
964
965            }
966
967            /* BEGIN: For evaluation issues - added by Arnold 2010.03.17 */
968            TimeSpan bruteforcingTime = DateTime.Now.Subtract(beginBruteforcing);
969            StringBuilder sbBFTime = new StringBuilder();
970            if (bruteforcingTime.Days > 0)
971                sbBFTime.Append(bruteforcingTime.Days.ToString() + " days ");
972            if (bruteforcingTime.Hours > 0)
973            {
974                if (bruteforcingTime.Hours <= 9)
975                    sbBFTime.Append("0");
976                sbBFTime.Append(bruteforcingTime.Hours.ToString() + ":");
977            }
978            if (bruteforcingTime.Minutes <= 9)
979                sbBFTime.Append("0");
980            sbBFTime.Append(bruteforcingTime.Minutes.ToString() + ":");
981            if (bruteforcingTime.Seconds <= 9)
982                sbBFTime.Append("0");
983            sbBFTime.Append(bruteforcingTime.Seconds.ToString() + "-");
984            if (bruteforcingTime.Milliseconds <= 9)
985                sbBFTime.Append("00");
986            if (bruteforcingTime.Milliseconds <= 99)
987                sbBFTime.Append("0");
988            sbBFTime.Append(bruteforcingTime.Milliseconds.ToString());
989
990            GuiLogMessage("Ended bruteforcing pattern '" + pattern.getKey() + "'. Bruteforcing TimeSpan: " + sbBFTime.ToString(), NotificationLevel.Debug);
991            /* END: For evaluation issues - added by Arnold 2010.03.17 */
992
993            return costList;
994        }
995
996        #region External Client
997
998        void cryptoolServer_OnClientDisconnected(EndPoint client)
999        {
1000            GuiLogMessage("Client disconnected!", NotificationLevel.Info);
1001            externalClientConnected = null;
1002        }
1003
1004        void server_OnClientConnected(System.Net.EndPoint client, string identification)
1005        {
1006            lock (this)
1007            {
1008                if (externalClientConnected == null)
1009                {
1010                    externalClientConnected = client;
1011                    GuiLogMessage(string.Format("Client {0} connected!", identification), NotificationLevel.Info);
1012                    AssignJobToClient(client, externalKeySearcherOpenCLCode.CreateOpenCLBruteForceCode(externalKeyTranslator));
1013                }
1014                else
1015                {
1016                    GuiLogMessage("Client tried to connect, but only one client allowed!", NotificationLevel.Info);
1017                }
1018            }
1019        }
1020
1021        private void AssignJobToClient(EndPoint client, string src)
1022        {
1023            JobInput j = new JobInput();
1024            j.Guid = Guid.NewGuid().ToString();
1025            j.Src = src;
1026            var key = externalKeyTranslator.GetKey();
1027            j.Key = key;
1028            j.LargerThen = (costMaster.getRelationOperator() == RelationOperator.LargerThen);
1029            j.Size = externalKeyTranslator.GetOpenCLBatchSize();
1030            j.ResultSize = 10;
1031            cryptoolServer.SendJob(j, client);
1032        }
1033
1034        void server_OnJobCompleted(System.Net.EndPoint client, JobResult jr)
1035        {
1036            //check:
1037            var op = this.costMaster.getRelationOperator();
1038            foreach (var res in jr.ResultList)
1039            {
1040                float cost = res.Key;
1041                if (((op == RelationOperator.LargerThen) && (cost > value_threshold))
1042                    || (op == RelationOperator.LessThen) && (cost < value_threshold))
1043                {
1044                    ValueKey valueKey = new ValueKey { value = cost, key = externalKeyTranslator.GetKeyRepresentation(res.Value) };
1045                    valueKey.keya = externalKeyTranslator.GetKeyFromRepresentation(valueKey.key);
1046                    valueKey.decryption = sender.Decrypt(this.encryptedData, valueKey.keya, InitVector, bytesToUse);
1047                    valuequeue.Enqueue(valueKey);
1048                }
1049            }
1050            updateToplist();
1051
1052            //progress:
1053            externalKeysProcessed += externalKeyTranslator.GetProgress();
1054            showProgress(costList, pattern.size(), externalKeysProcessed, 1);
1055
1056            if (externalKeysProcessed != pattern.size())
1057            {
1058                AssignJobToClient(client, null);
1059            }
1060            else
1061            {
1062                waitForExternalClientToFinish.Set();
1063            }
1064        }
1065
1066        #endregion
1067
1068        private void SetStartDate()
1069        {
1070            localQuickWatchPresentation.startTime.Content = DateTime.Now.ToString("g", Thread.CurrentThread.CurrentCulture); ;
1071        }
1072
1073        internal void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, long keysPerSecond)
1074        {
1075            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
1076
1077            LinkedListNode<ValueKey> linkedListNode;
1078            ProgressChanged((double)keycounter / (double)size, 1.0);
1079
1080            if (localQuickWatchPresentation.IsVisible && keysPerSecond != 0 && !stop)
1081            {
1082                double time = (Math.Pow(10, BigInteger.Log((size - keycounter), 10) - Math.Log10(keysPerSecond)));
1083                TimeSpan timeleft = new TimeSpan(-1);
1084
1085                try
1086                {
1087                    if (time / (24 * 60 * 60) <= int.MaxValue)
1088                    {
1089                        int days = (int)(time / (24 * 60 * 60));
1090                        time = time - (days * 24 * 60 * 60);
1091                        int hours = (int)(time / (60 * 60));
1092                        time = time - (hours * 60 * 60);
1093                        int minutes = (int)(time / 60);
1094                        time = time - (minutes * 60);
1095                        int seconds = (int)time;
1096
1097                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
1098                    }
1099                }
1100                catch
1101                {
1102                    //can not calculate time span
1103                }
1104
1105                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1106                {
1107                    localQuickWatchPresentation.elapsedTime.Content = localBruteForceStopwatch.Elapsed;
1108                    localQuickWatchPresentation.keysPerSecond.Content = String.Format("{0:0,0}", keysPerSecond);
1109                    if (timeleft != new TimeSpan(-1))
1110                    {
1111                        localQuickWatchPresentation.timeLeft.Content = "" + timeleft;
1112                        try
1113                        {
1114                            localQuickWatchPresentation.endTime.Content = "" + DateTime.Now.Add(timeleft);
1115                        }
1116                        catch
1117                        {
1118                            localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
1119                        }
1120                    }
1121                    else
1122                    {
1123                        localQuickWatchPresentation.timeLeft.Content = "incalculable :-)";
1124                        localQuickWatchPresentation.endTime.Content = "in a galaxy far, far away...";
1125                    }
1126
1127                    localQuickWatchPresentation.entries.Clear();
1128                    linkedListNode = costList.First;
1129
1130                    int i = 0;
1131                    while (linkedListNode != null)
1132                    {
1133                        i++;
1134
1135                        ResultEntry entry = new ResultEntry();
1136                        entry.Ranking = "" + i;
1137                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1138                        entry.Key = linkedListNode.Value.key;
1139                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1140
1141                        localQuickWatchPresentation.entries.Add(entry);
1142                        linkedListNode = linkedListNode.Next;
1143                    }
1144                }
1145                , null);
1146            }//end if
1147            else if (!stop && localQuickWatchPresentation.IsVisible)
1148            {
1149
1150                localQuickWatchPresentation.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1151                {
1152                    localQuickWatchPresentation.entries.Clear();
1153                    linkedListNode = costList.First;
1154                    int i = 0;
1155
1156                    while (linkedListNode != null)
1157                    {
1158                        i++;
1159
1160                        ResultEntry entry = new ResultEntry();
1161                        entry.Ranking = "" + i;
1162                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
1163                        entry.Key = linkedListNode.Value.key;
1164                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
1165
1166                        localQuickWatchPresentation.entries.Add(entry);
1167                        linkedListNode = linkedListNode.Next;
1168                    }
1169                }
1170                , null);
1171            }
1172        }
1173
1174        #region For TopList
1175
1176        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
1177        {
1178            ValueKey valueKey = new ValueKey();
1179            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
1180                valueKey.value = double.MaxValue;
1181            else
1182                valueKey.value = double.MinValue;
1183            valueKey.key = "dummykey";
1184            valueKey.decryption = new byte[0];
1185            value_threshold = valueKey.value;
1186            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
1187            for (int i = 1; i < maxInList; i++)
1188            {
1189                node = costList.AddAfter(node, valueKey);
1190            }
1191        }
1192
1193        internal void IntegrateNewResults(LinkedList<ValueKey> updatedCostList)
1194        {
1195            foreach (var valueKey in updatedCostList)
1196            {
1197                if (keyQualityHelper.IsBetter(valueKey.value, value_threshold))
1198                {
1199                    valuequeue.Enqueue(valueKey);
1200                }
1201            }
1202
1203            updateToplist();
1204        }
1205
1206        internal void updateToplist()
1207        {
1208            LinkedListNode<ValueKey> node;
1209            while (valuequeue.Count != 0)
1210            {
1211                ValueKey vk = (ValueKey)valuequeue.Dequeue();
1212
1213                //if (costList.Contains(vk)) continue;
1214                var result = costList.Where(valueKey => valueKey.key == vk.key);
1215                if (result.Count() > 0)
1216                {
1217                    continue;
1218                }
1219
1220                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
1221                {
1222                    if (vk.value > costList.Last().value)
1223                    {
1224                        node = costList.First;
1225                        while (node != null)
1226                        {
1227                            if (vk.value > node.Value.value)
1228                            {
1229                                if (node == costList.First)
1230                                    Top1 = vk;
1231                                costList.AddBefore(node, vk);
1232                                costList.RemoveLast();
1233                                value_threshold = costList.Last.Value.value;
1234                                break;
1235                            }
1236                            node = node.Next;
1237                        }//end while
1238                    }//end if
1239                }
1240                else
1241                {
1242                    if (vk.value < costList.Last().value)
1243                    {
1244                        node = costList.First;
1245                        while (node != null)
1246                        {
1247                            if (vk.value < node.Value.value)
1248                            {
1249                                if (node == costList.First)
1250                                    Top1 = vk;
1251                                costList.AddBefore(node, vk);
1252                                costList.RemoveLast();
1253                                value_threshold = costList.Last.Value.value;
1254                                break;
1255                            }
1256                            node = node.Next;
1257                        }//end while
1258                    }//end if
1259                }
1260            }
1261        }
1262
1263        #endregion
1264
1265        private void StartThreads(IControlEncryption sender, int bytesToUse, KeyPattern.KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] openCLDoneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
1266        {
1267            //First start the opencl threads:
1268            int i = 0;
1269            foreach (var ds in settings.DeviceSettings)
1270            {
1271                if (ds.useDevice)
1272                {
1273                    WaitCallback worker = new WaitCallback(KeySearcherJob);
1274                    doneKeysA[i] = new BigInteger();
1275                    openCLDoneKeysA[i] = new BigInteger();
1276                    keycounters[i] = new BigInteger();
1277
1278                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, ds });
1279                    i++;
1280                }
1281            }
1282
1283            //Then the CPU threads:
1284            for (; i < patterns.Length; i++)
1285            {
1286                WaitCallback worker = new WaitCallback(KeySearcherJob);
1287                doneKeysA[i] = new BigInteger();
1288                openCLDoneKeysA[i] = new BigInteger();
1289                keycounters[i] = new BigInteger();
1290
1291                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, openCLDoneKeysA, keycounters, keysleft, sender, bytesToUse, threadStack, null });
1292            }
1293        }
1294
1295        private KeyPattern.KeyPattern[] splitPatternForThreads(KeyPattern.KeyPattern pattern)
1296        {
1297            int threads = settings.CoresUsed;
1298            threads += settings.DeviceSettings.Count(x => x.useDevice); 
1299
1300            if (threads < 1)
1301                return null;
1302
1303            KeyPattern.KeyPattern[] patterns = new KeyPattern.KeyPattern[threads];
1304            if (threads > 1)
1305            {
1306                KeyPattern.KeyPattern[] patterns2 = pattern.split();
1307                if (patterns2 == null)
1308                {
1309                    patterns2 = new KeyPattern.KeyPattern[1];
1310                    patterns2[0] = pattern;
1311                    return patterns2;
1312                }
1313                patterns[0] = patterns2[0];
1314                patterns[1] = patterns2[1];
1315                int p = 1;
1316                threads -= 2;
1317
1318                while (threads > 0)
1319                {
1320                    int maxPattern = -1;
1321                    BigInteger max = 0;
1322                    for (int i = 0; i <= p; i++)
1323                        if (patterns[i].size() > max)
1324                        {
1325                            max = patterns[i].size();
1326                            maxPattern = i;
1327                        }
1328                    KeyPattern.KeyPattern[] patterns3 = patterns[maxPattern].split();
1329                    if (patterns3 == null)
1330                    {
1331                        patterns3 = new KeyPattern.KeyPattern[p+1];
1332                        for (int i = 0; i <= p; i++)
1333                            patterns3[i] = patterns[i];
1334                        return patterns3;
1335                    }
1336                    patterns[maxPattern] = patterns3[0];
1337                    patterns[++p] = patterns3[1];
1338                    threads--;
1339                }
1340            }
1341            else
1342                patterns[0] = pattern;
1343            return patterns;
1344        }
1345
1346        private void keyPatternChanged()
1347        {
1348            Pattern = new KeyPattern.KeyPattern(controlMaster.getKeyPattern());
1349        }
1350
1351        // added by Arnie - 2009.12.07
1352        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
1353        /// <summary>
1354        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
1355        /// But when the returned List is filled, we have (at least a part) of the possible best keys
1356        /// </summary>
1357        public event BruteforcingEnded OnBruteforcingEnded;
1358
1359        // added by Arnie -2009.12.02
1360        // for inheritance reasons
1361        public void BruteforcePattern(KeyPattern.KeyPattern pattern, byte[] encryptedData, byte[] initVector, IControlEncryption encryptControl, IControlCost costControl)
1362        {
1363            /* Begin: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1364            this.encryptedData = encryptedData;
1365            this.initVector = initVector;
1366            /* End: New stuff because of changing the IControl data flow - Arnie 2010.01.18 */
1367
1368            this.sender = encryptControl;
1369            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern);
1370            if(OnBruteforcingEnded != null)
1371                OnBruteforcingEnded(lstRet);
1372        }
1373
1374        #endregion
1375
1376        public void GuiLogMessage(string message, NotificationLevel loglevel)
1377        {
1378            if (OnGuiLogNotificationOccured != null)
1379                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
1380        }
1381
1382        public void ProgressChanged(double value, double max)
1383        {
1384            if (OnPluginProgressChanged != null)
1385            {
1386                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1387
1388            }
1389        }
1390
1391        /// <summary>
1392        /// used for delivering the results from the worker threads to the main thread:
1393        /// </summary>
1394        public struct ValueKey
1395        {
1396            public double value;
1397            public String key;
1398            public byte[] decryption;
1399            public byte[] keya;
1400        };
1401    }
1402
1403    /// <summary>
1404    /// Represents one entry in our result list
1405    /// </summary>
1406    public class ResultEntry
1407    {
1408        public string Ranking { get; set; }
1409        public string Value { get; set; }
1410        public string Key { get; set; }
1411        public string Text { get; set; }
1412
1413    }
1414}
Note: See TracBrowser for help on using the repository browser.