08-12-2024, 11:58 AM
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?
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;
}