Ignore:
Timestamp:
Nov 13, 2009, 12:48:50 AM (12 years ago)
Author:
Sven Rech
Message:

much better thread support for keysearcher now

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/KeySearcher/KeySearcher.cs

    r838 r843  
    136136                    patterns[0].wildcardList.Add(new Wildcard(wc));
    137137                    Wildcard copy = new Wildcard(wc);
    138                     copy.resetCounter();
     138                    if (s)
     139                        copy.resetCounter();
    139140                    patterns[1].wildcardList.Add(copy);
    140141                }
     
    231232        public long size()
    232233        {
     234            if (wildcardList == null)
     235                return 0;
    233236            long counter = 1;
    234237            foreach (Wildcard wc in wildcardList)
     
    273276        private double value_threshold;
    274277        private int maxThread;  //the thread with the most keys left
     278        private Mutex maxThreadMutex = new Mutex();
    275279
    276280        private KeyPattern pattern = null;
     
    331335        }
    332336
     337        private class ThreadStackElement
     338        {
     339            public AutoResetEvent ev;
     340            public int threadid;
     341        }
     342
    333343        private void KeySearcherJob(object param)
    334344        {
    335345            object[] parameters = (object[])param;
    336             KeyPattern pattern = (KeyPattern)parameters[0];
     346            KeyPattern[] patterns = (KeyPattern[])parameters[0];
    337347            int threadid = (int)parameters[1];
    338348            Int64[] doneKeysArray = (Int64[])parameters[2];
    339349            Int64[] keycounterArray = (Int64[])parameters[3];
    340350            Int64[] keysLeft = (Int64[])parameters[4];
    341             IControlEncryption sender = (IControlEncryption)parameters[5];
     351            IControlEncryption sender = (IControlEncryption)parameters[5];           
    342352            int bytesToUse = (int)parameters[6];
     353            Stack threadStack = (Stack)parameters[7];
     354
     355            KeyPattern pattern = patterns[threadid];
    343356
    344357            try
    345358            {
    346                 long size = pattern.size();
    347                 keysLeft[threadid] = size;
    348 
    349                 do
    350                 {
    351                     ValueKey valueKey = new ValueKey();
    352                     try
     359                while (pattern != null)
     360                {
     361                    long size = pattern.size();
     362                    keysLeft[threadid] = size;
     363
     364                    do
    353365                    {
    354                         valueKey.key = pattern.getKey();
    355                     }
    356                     catch (Exception ex)
    357                     {
    358                         GuiLogMessage("Could not get next Key: " + ex.Message, NotificationLevel.Error);
    359                         return;
    360                     }
    361 
    362                     try
    363                     {
    364                         valueKey.decryption = sender.Decrypt(ControlMaster.getKeyFromString(valueKey.key), bytesToUse);
    365                     }
    366                     catch (Exception ex)
    367                     {
    368                         GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
    369                         GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
    370                         return;
    371                     }
    372 
    373                     try
    374                     {
    375                         valueKey.value = CostMaster.calculateCost(valueKey.decryption);
    376                     }
    377                     catch (Exception ex)
    378                     {
    379                         GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
    380                         return;
    381                     }
    382 
    383                     if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
    384                     {
    385                         if (valueKey.value > value_threshold)
    386                             valuequeue.Enqueue(valueKey);
    387                     }
    388                     else
    389                     {
    390                         if (valueKey.value < value_threshold)
    391                             valuequeue.Enqueue(valueKey);
    392                     }
    393 
    394                     doneKeysArray[threadid]++;
    395                     keycounterArray[threadid]++;
    396                     keysLeft[threadid]--;
    397 
    398                     //if (maxThread == threadid)
    399                    
    400                 } while (pattern.nextKey() && !stop);
    401 
     366                        ValueKey valueKey = new ValueKey();
     367                        try
     368                        {
     369                            valueKey.key = pattern.getKey();
     370                        }
     371                        catch (Exception ex)
     372                        {
     373                            GuiLogMessage("Could not get next Key: " + ex.Message, NotificationLevel.Error);
     374                            return;
     375                        }
     376
     377                        try
     378                        {
     379                            valueKey.decryption = sender.Decrypt(ControlMaster.getKeyFromString(valueKey.key), bytesToUse);
     380                        }
     381                        catch (Exception ex)
     382                        {
     383                            GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
     384                            GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
     385                            return;
     386                        }
     387
     388                        try
     389                        {
     390                            valueKey.value = CostMaster.calculateCost(valueKey.decryption);
     391                        }
     392                        catch (Exception ex)
     393                        {
     394                            GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
     395                            return;
     396                        }
     397
     398                        if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
     399                        {
     400                            if (valueKey.value > value_threshold)
     401                                valuequeue.Enqueue(valueKey);
     402                        }
     403                        else
     404                        {
     405                            if (valueKey.value < value_threshold)
     406                                valuequeue.Enqueue(valueKey);
     407                        }
     408
     409                        doneKeysArray[threadid]++;
     410                        keycounterArray[threadid]++;
     411                        keysLeft[threadid]--;
     412
     413                        //if we are the thread with most keys left, we have to share them:
     414                        if (maxThread == threadid && threadStack.Count != 0)
     415                        {
     416                            maxThreadMutex.WaitOne();
     417                            if (maxThread == threadid && threadStack.Count != 0)
     418                            {
     419                                KeyPattern[] split = pattern.split();
     420                                patterns[threadid] = split[0];
     421                                pattern = split[0];
     422                                ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
     423                                patterns[elem.threadid] = split[1];
     424                                elem.ev.Set();    //wake the other thread up
     425                                maxThread = -1;
     426                                size = pattern.size();
     427                                keysLeft[threadid] = size;
     428                            }
     429                            maxThreadMutex.ReleaseMutex();
     430                        }
     431
     432                    } while (pattern.nextKey() && !stop);
     433
     434                    //Let's wait until another thread is willing to share with us:
     435                    pattern = null;
     436                    ThreadStackElement el = new ThreadStackElement();
     437                    el.ev = new AutoResetEvent(false);
     438                    el.threadid = threadid;
     439                    patterns[threadid] = null;
     440                    threadStack.Push(el);
     441                    GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
     442                    el.ev.WaitOne();
     443                    GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
     444                    pattern = patterns[threadid];
     445                }
    402446            }
    403447            finally
     
    448492                LinkedListNode<ValueKey> linkedListNode;
    449493
    450                 KeyPattern[] patterns;
     494                KeyPattern[] patterns = new KeyPattern[settings.CoresUsed+1];
    451495                long size = Pattern.initKeyIteration(settings.Key);
    452 
     496               
    453497                if (settings.CoresUsed > 0)
    454                     patterns = Pattern.split();
     498                {
     499                    KeyPattern[] patterns2 = Pattern.split();                   
     500                    patterns[0] = patterns2[0];
     501                    patterns[1] = patterns2[1];
     502                    int p = 1;
     503                    int threads = settings.CoresUsed - 1;
     504                    while (threads > 0)
     505                    {
     506                        int maxPattern = -1;
     507                        long max = 0;
     508                        for (int i = 0; i <= p; i++)
     509                            if (patterns[i].size() > max)
     510                            {
     511                                max = patterns[i].size();
     512                                maxPattern = i;
     513                            }
     514                        KeyPattern[] patterns3 = patterns[maxPattern].split();
     515                        patterns[maxPattern] = patterns3[0];
     516                        patterns[++p] = patterns3[1];
     517                        threads--;
     518                    }
     519                }
    455520                else
    456                 {
    457                     patterns = new KeyPattern[1];
    458521                    patterns[0] = Pattern;
    459                 }
    460522
    461523                valuequeue = Queue.Synchronized(new Queue());
     
    464526                Int64[] keycounters = new Int64[patterns.Length];
    465527                Int64[] keysleft = new Int64[patterns.Length];
     528                Stack threadStack = Stack.Synchronized(new Stack());
    466529                for (int i = 0; i < patterns.Length; i++)
    467530                {
     
    469532                    doneKeysA[i] = new Int64();
    470533                    keycounters[i] = new Int64();
    471                     ThreadPool.QueueUserWorkItem(worker, new object[] { patterns[i], i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse });
     534                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
    472535                }
    473536               
     
    476539                {
    477540                    Thread.Sleep(1000);
    478 
    479                     long max = 0;
    480                     int id = -1;
    481                     for (int i = 0; i < patterns.Length; i++)
    482                         if (keysleft[i] > max)
    483                         {
    484                             max = keysleft[i];
    485                             id = i;
    486                         }
    487                     maxThread = id;
    488541
    489542                    //update toplist:
     
    537590                    foreach (Int64 kc in keycounters)
    538591                        keycounter += kc;
     592
     593                    if (keycounter > size)
     594                        GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
     595
     596                    //Let's determine which thread has the most keys to share:
     597                    if (size - keycounter > 1000)
     598                    {
     599                        maxThreadMutex.WaitOne();
     600                        long max = 0;
     601                        int id = -1;
     602                        for (int i = 0; i < patterns.Length; i++)
     603                            if (keysleft[i] > max)
     604                            {
     605                                max = keysleft[i];
     606                                id = i;
     607                            }
     608                        maxThread = id;
     609                        maxThreadMutex.ReleaseMutex();
     610                    }
    539611
    540612                    ProgressChanged(keycounter, size);
     
    626698                    if (keycounter >= size)
    627699                        break;
    628                 }//end while 
     700                }//end while
     701
     702                //wake up all sleeping threads:
     703                while (threadStack.Count != 0)
     704                    ((ThreadStackElement)threadStack.Pop()).ev.Set();
    629705            }//end if
    630706
    631707            if (!stop)
    632708                ProgressChanged(1, 1);
    633  
    634709        }
    635710
     
    752827    }
    753828}
    754 
Note: See TracChangeset for help on using the changeset viewer.