sha256 OpenSSL vs 7z
#1
Hi.
I wrote two programs, one using sha256 from LZMA-SDK, the other using OpenSSL. I noticed that there is a significant speed improvement when using OpenSSL, especially when the processor does not have sha256 instructions. Also, when using LZMA-SDK, there is a decrease in hashing performance over time. Both programs are based on the same algorithm taken from LZMA-SDK, but using the appropriate instructions SHA256_Update(&sha, buf, unrollSize); //from OpenSSL and Sha256_Update((CSha256*)(void*)(Byte*)sha, buf, unrollSize); //from 7z. Could implementing OpenSSL into Hashcat give similar results?


Code:
unsigned char* GetSHA256_7zD(string PassStringUTF16) //OpenSSL
{
    const int len = PassStringUTF16.length();
    CByteBuffer_Wipe PassBuffer(len * 2);
    for (size_t k = 0; k < len; k++)
    {
        wchar_t c = PassStringUTF16[k];
        ((Byte*)PassBuffer)[k * 2] = (Byte)c;
        ((Byte*)PassBuffer)[k * 2 + 1] = (Byte)(c >> 8);
    }
    const unsigned kUnrPow = 6;
    const UInt32 numUnroll = (UInt32)1 << (*g_Cost <= kUnrPow ? (unsigned)*g_Cost : kUnrPow);

    const size_t bufSize = 8 + 0 + PassBuffer.Size();
    const size_t unrollSize = bufSize * numUnroll;
    CAlignedBuffer sha2(sizeof(CSha256) + unrollSize + bufSize * 2); //From 7z to set buf
    Byte* buf = sha2 + sizeof(CSha256); //From 7z
    SHA256_CTX sha; //From OpenSSL
    SHA256_Init(&sha); //From OpenSSL

    //memcpy(buf, "", 0); //for salt, but no salt
    memcpy(buf + 0, PassBuffer, PassBuffer.Size());
    memset(buf + bufSize - 8, 0, 8);

    {
        {
            Byte* dest = buf;
            for (UInt32 i = 1; i < numUnroll; i++)
            {
                dest += bufSize;
                memcpy(dest, buf, bufSize);
            }
        }

        const UInt32 numRounds = (UInt32)1 << *g_Cost;
        UInt32 r = 0;
        do
        {
            Byte* dest = buf + bufSize - 8;
            UInt32 i = r;
            r += numUnroll;
            do
            {
                SetUi32(dest, i)  i++; dest += bufSize;
            } while (i < r);
            SHA256_Update(&sha, buf, unrollSize); //from OpenSSL
        } while (r < numRounds);
    }

    unsigned char* Key = (unsigned char*)malloc(32);
    SHA256_Final(Key, &sha); //from OpenSSL
    return Key;
}


////////////////////////////

unsigned char* GetSHA256_7zZ(string PassStringUTF16) //7z
{
    //From 7z only ->
    const int len = PassStringUTF16.length();
    CByteBuffer_Wipe PassBuffer(len * 2);
    for (size_t k = 0; k < len; k++)
    {
        wchar_t c = PassStringUTF16[k];
        ((Byte*)PassBuffer)[k * 2] = (Byte)c;
        ((Byte*)PassBuffer)[k * 2 + 1] = (Byte)(c >> 8);
    }
    const unsigned kUnrPow = 6;
    const UInt32 numUnroll = (UInt32)1 << (*g_Cost <= kUnrPow ? (unsigned)*g_Cost : kUnrPow);

    const size_t bufSize = 8 + 0 + PassBuffer.Size();
    const size_t unrollSize = bufSize * numUnroll;
    CAlignedBuffer sha(sizeof(CSha256) + unrollSize + bufSize * 2);
    Byte* buf = sha + sizeof(CSha256);

    //memcpy(buf, "", 0); //no salt
    memcpy(buf + 0, PassBuffer, PassBuffer.Size());
    memset(buf + bufSize - 8, 0, 8);

    Sha256_Init((CSha256*)(void*)(Byte*)sha);

    {
        {
            Byte* dest = buf;
            for (UInt32 i = 1; i < numUnroll; i++)
            {
                dest += bufSize;
                memcpy(dest, buf, bufSize);
            }
        }

        const UInt32 numRounds = (UInt32)1 << *g_Cost;
        UInt32 r = 0;
        do
        {
            Byte* dest = buf + bufSize - 8;
            UInt32 i = r;
            r += numUnroll;
            do
            {
                SetUi32(dest, i)  i++; dest += bufSize;
            } while (i < r);
            Sha256_Update((CSha256*)(void*)(Byte*)sha, buf, unrollSize);
        } while (r < numRounds);
    }

    unsigned char* Key = (unsigned char*)malloc(32);
    Sha256_Final((CSha256*)(void*)(Byte*)sha, Key);
    memset(&sha, 0, sizeof(sha));
    return Key;
}
Reply