Changeset 1198


Ignore:
Timestamp:
Feb 26, 2010, 1:12:45 PM (12 years ago)
Author:
Sven Rech
Message:

speed optimization for CFB

Location:
trunk/NativeCryptography
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/NativeCryptography/NativeCryptography.cpp

    r1197 r1198  
    4747        array<unsigned char>^ Crypto::decryptAESorDES(array<unsigned char>^ Input, array<unsigned char>^ Key, array<unsigned char>^ IV, const int bits, const int length, const int mode, const int blockSize, const cryptMethod method)
    4848        {
     49                static unsigned char lastIVencrypted[16];       //optimization
     50
    4951                int numBlocks = length / blockSize;
    5052                if (length % blockSize != 0)
    5153                        numBlocks++;
    5254
     55                bool noIV = false;
     56
    5357                if (IV == nullptr)
    54                         IV = gcnew array<unsigned char>(blockSize);
     58                {
     59                        noIV = true;
     60                        if (blockSize == 8)
     61                                IV = zeroIV8;
     62                        else if (blockSize == 16)
     63                                IV = zeroIV16;
     64                        else
     65                                return nullptr;
     66                }
    5567
    5668                pin_ptr<unsigned char> input = &Input[0];
     
    6476                DES_key_schedule deskey;
    6577                if (mode == 2)  //CFB
    66                 {
    67                         array<unsigned char>^ ShiftRegister = (array<unsigned char>^)IV->Clone();
    68                         pin_ptr<unsigned char> shiftregister = &ShiftRegister[0];                       
     78                {                       
    6979                        unsigned char block[16];        //16 is enough for AES and DES
     80                        unsigned char shiftregister[16];
     81                        //works only for little endian architectures:
     82                        if (blockSize == 8)
     83                        {
     84                                *((unsigned int*)shiftregister) = *((unsigned int*)&iv[1]);
     85                                *((unsigned int*)&shiftregister[4]) = (*((unsigned int*)&iv[4]) >> 8) | ((unsigned int)(input[0]) << 24);
     86                        }
     87                        else if (blockSize == 16)
     88                        {
     89                                *((unsigned int*)shiftregister) = *((unsigned int*)&iv[1]);
     90                                *((unsigned int*)&shiftregister[4]) = (*((unsigned int*)&iv[4]) >> 8) | ((unsigned int)iv[8] << 24);
     91                                *((unsigned int*)&shiftregister[8]) = (*((unsigned int*)&iv[8]) >> 8) | ((unsigned int)iv[12] << 24);
     92                                *((unsigned int*)&shiftregister[12]) = (*((unsigned int*)&iv[12]) >> 8) | ((unsigned int)input[0] << 24);
     93                        }
     94                        else
     95                                return nullptr;
    7096
    71                         if (method == cryptMethod::methodAES) 
     97                        if (method == cryptMethod::methodAES)
    7298                                AES_set_encrypt_key(key, bits, &aeskey);
    73                         else 
     99                        else
    74100                                DES_set_key_unchecked((const_DES_cblock*)key, &deskey);
     101                       
     102                        if (IV != lastIV)
     103                        {
     104                                try{
     105                                        lastivmutex->WaitOne();
     106                                        if (IV != lastIV)
     107                                        {
     108                                                encrypt(iv, lastIVencrypted, method, &aeskey, &deskey);
     109                                                lastIV = IV;
     110                                        }
     111                                } finally
     112                                {
     113                                        lastivmutex->ReleaseMutex();
     114                                }
     115                        }
     116                       
     117                        unsigned char leftmost = lastIVencrypted[0];
     118                        outp[0] = leftmost ^ input[0];
    75119
    76                         for (int i = 0; i < length; i++)
     120                        for (int i = 1; i < length; i++)
    77121                        {
    78122                                encrypt(shiftregister, block, method, &aeskey, &deskey);
    79                                 unsigned char leftmost = block[0];
     123                                leftmost = block[0];
    80124                                outp[i] = leftmost ^ input[i];
    81125                               
    82126                                //shift input[i] in register:
    83                                 for (int c = 0; c < blockSize - 1; c++)
    84                                         shiftregister[c] = shiftregister[c+1];
    85                                 shiftregister[blockSize-1] = input[i];
     127                                if (blockSize == 8)
     128                                {
     129                                        *((unsigned int*)shiftregister) = *((unsigned int*)&shiftregister[1]);
     130                                        *((unsigned int*)&shiftregister[4]) = (*((unsigned int*)&shiftregister[4]) >> 8) | ((unsigned int)input[i] << 24);
     131                                }
     132                                else if (blockSize == 16)
     133                                {
     134                                        *((unsigned int*)shiftregister) = *((unsigned int*)&shiftregister[1]);
     135                                        *((unsigned int*)&shiftregister[4]) = (*((unsigned int*)&shiftregister[4]) >> 8) | ((unsigned int)shiftregister[8] << 24);
     136                                        *((unsigned int*)&shiftregister[8]) = (*((unsigned int*)&shiftregister[8]) >> 8) | ((unsigned int)shiftregister[12] << 24);
     137                                        *((unsigned int*)&shiftregister[12]) = (*((unsigned int*)&shiftregister[12]) >> 8) | ((unsigned int)input[i] << 24);
     138                                }
    86139                        }
    87140                }
     
    94147
    95148                        decrypt(input, outp, method, &aeskey, &deskey);                         
    96                         if (mode == 1)          //CBC
     149                        if (mode == 1 && !noIV)         //CBC
    97150                                xorblock(outp, iv, method);     
    98151                        for (int c = 1; c < numBlocks; c++)
  • trunk/NativeCryptography/NativeCryptography.h

    r1196 r1198  
    44#include <stdlib.h>
    55
     6using namespace System::Threading;
    67using namespace System;
    78
     
    1213        private:
    1314                enum class cryptMethod {methodAES, methodDES};
    14                
     15
     16                //for optimization:
     17                static array<unsigned char>^ lastIV = nullptr;         
     18                static array<unsigned char>^ zeroIV8 = gcnew array<unsigned char>(8);
     19                static array<unsigned char>^ zeroIV16 = gcnew array<unsigned char>(16);
     20                static Mutex^ lastivmutex = gcnew Mutex();
     21
    1522                static void xorBlockAES(int *t1, int *t2);
    1623                static void xorBlockDES(int *t1, int *t2);
Note: See TracChangeset for help on using the changeset viewer.