1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 19:08:26 -06:00

Linux/MacOSX/FreeBSD: Implement benchmarking for Hash and PKCS-5 PRF algorithms.

This commit is contained in:
Mounir IDRASSI
2018-08-09 19:18:18 +02:00
parent 1b59879411
commit c84bcd4b47
5 changed files with 733 additions and 130 deletions

View File

@@ -38,38 +38,125 @@ namespace VeraCrypt
BufferSizeChoice->Append (Gui->SizeToString (size), (void *) size);
}
BenchmarkChoice->Select (0);
BufferSizeChoice->Select (1);
list <int> colPermilles;
BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1);
colPermilles.push_back (322);
BenchmarkListCtrl->InsertColumn (ColumnEncryption, LangString["ENCRYPTION"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
BenchmarkListCtrl->InsertColumn (ColumnDecryption, LangString["DECRYPTION"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
BenchmarkListCtrl->InsertColumn (ColumnMean, LangString["MEAN"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false);
Gui->SetListCtrlHeight (BenchmarkListCtrl, 14);
Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles);
UpdateBenchmarkList ();
wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST); // wxFILTER_NUMERIC does not exclude - . , etc.
const wxChar *valArr[] = { L"0", L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9" };
validator.SetIncludes (wxArrayString (array_capacity (valArr), (const wxChar **) &valArr));
VolumePimText->SetValidator (validator);
Layout();
Fit();
Center();
}
void BenchmarkDialog::UpdateBenchmarkList ()
{
int index = BenchmarkChoice->GetSelection ();
if (index == 1)
{
// PRF case
m_volumePimLabel->Show ();
VolumePimText->Show ();
BufferSizeChoice->Hide ();
m_bufferSizeLabel->Hide ();
}
else
{
m_volumePimLabel->Hide ();
VolumePimText->Hide ();
BufferSizeChoice->Show ();
m_bufferSizeLabel->Show ();
}
BenchmarkListCtrl->DeleteAllItems();
BenchmarkListCtrl->DeleteAllColumns();
if (index == 0)
{
// encryption case
list <int> colPermilles;
BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1);
colPermilles.push_back (322);
BenchmarkListCtrl->InsertColumn (ColumnEncryption, LangString["ENCRYPTION"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
BenchmarkListCtrl->InsertColumn (ColumnDecryption, LangString["DECRYPTION"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
BenchmarkListCtrl->InsertColumn (ColumnMean, LangString["MEAN"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false);
Gui->SetListCtrlHeight (BenchmarkListCtrl, 14);
Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles);
}
else if (index == 1)
{
// PRF case
list <int> colPermilles;
BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1);
colPermilles.push_back (322);
BenchmarkListCtrl->InsertColumn (ColumnTime, LangString["TIME"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
BenchmarkListCtrl->InsertColumn (ColumnIterations, LangString["ITERATIONS"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false);
Gui->SetListCtrlHeight (BenchmarkListCtrl, 14);
Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles);
}
else
{
// Hash case
list <int> colPermilles;
BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1);
colPermilles.push_back (322);
BenchmarkListCtrl->InsertColumn (ColumnEncryption, LangString["MEAN"], wxLIST_FORMAT_RIGHT, 1);
colPermilles.push_back (226);
Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false);
Gui->SetListCtrlHeight (BenchmarkListCtrl, 14);
Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles);
}
}
void BenchmarkDialog::OnBenchmarkChoiceSelected (wxCommandEvent& event)
{
UpdateBenchmarkList ();
Layout();
Fit();
}
void BenchmarkDialog::OnBenchmarkButtonClick (wxCommandEvent& event)
{
list <BenchmarkResult> results;
wxBusyCursor busy;
Buffer buffer ((size_t) Gui->GetSelectedData <size_t> (BufferSizeChoice));
int opIndex = BenchmarkChoice->GetSelection ();
Buffer buffer ((opIndex == 1)? sizeof (unsigned long) : (size_t) Gui->GetSelectedData <size_t> (BufferSizeChoice));
if (opIndex == 1)
{
unsigned long pim = 0;
if (!VolumePimText->GetValue().ToULong (&pim))
pim = 0;
memcpy (buffer.Ptr (), &pim, sizeof (unsigned long));
}
BenchmarkThreadRoutine routine(this, results, buffer);
BenchmarkThreadRoutine routine(this, results, buffer, opIndex);
Gui->ExecuteWaitThreadRoutine (this, &routine);
BenchmarkListCtrl->DeleteAllItems();
@@ -79,9 +166,21 @@ namespace VeraCrypt
vector <wstring> fields (BenchmarkListCtrl->GetColumnCount());
fields[ColumnAlgorithm] = result.AlgorithmName;
fields[ColumnEncryption] = Gui->SpeedToString (result.EncryptionSpeed);
fields[ColumnDecryption] = Gui->SpeedToString (result.DecryptionSpeed);
fields[ColumnMean] = Gui->SpeedToString (result.MeanSpeed);
if (opIndex == 0)
{
fields[ColumnEncryption] = Gui->SpeedToString (result.EncryptionSpeed);
fields[ColumnDecryption] = Gui->SpeedToString (result.DecryptionSpeed);
fields[ColumnMean] = Gui->SpeedToString (result.MeanSpeed);
}
else if (opIndex == 1)
{
fields[ColumnTime] = wxString::Format (wxT("%llu ms"), (unsigned long long) result.Time);
fields[ColumnIterations] = wxString::Format (wxT("%llu"), (unsigned long long) result.Iterations);
}
else
{
fields[ColumnHashMean] = Gui->SpeedToString (result.MeanSpeed);
}
Gui->AppendToListCtrl (BenchmarkListCtrl, fields);
}
@@ -94,78 +193,184 @@ namespace VeraCrypt
Fit();
}
void BenchmarkDialog::DoBenchmark (list<BenchmarkResult>& results, Buffer& buffer)
void BenchmarkDialog::DoBenchmark (list<BenchmarkResult>& results, Buffer& buffer, int opIndex)
{
try
{
EncryptionAlgorithmList encryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms();
foreach (shared_ptr <EncryptionAlgorithm> ea, encryptionAlgorithms)
if (opIndex == 0)
{
if (!ea->IsDeprecated())
EncryptionAlgorithmList encryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms();
foreach (shared_ptr <EncryptionAlgorithm> ea, encryptionAlgorithms)
{
BenchmarkResult result;
result.AlgorithmName = ea->GetName(true);
Buffer key (ea->GetKeySize());
ea->SetKey (key);
shared_ptr <EncryptionMode> xts (new EncryptionModeXTS);
xts->SetKey (key);
ea->SetMode (xts);
wxLongLong startTime = wxGetLocalTimeMillis();
// CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency gradually changes depending on CPU load).
do
if (!ea->IsDeprecated())
{
ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
}
while (wxGetLocalTimeMillis().GetValue() - startTime.GetValue() < 20);
BenchmarkResult result;
result.AlgorithmName = ea->GetName(true);
uint64 size = 0;
uint64 time;
startTime = wxGetLocalTimeMillis();
Buffer key (ea->GetKeySize());
ea->SetKey (key);
do
{
ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
size += buffer.Size();
time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue());
}
while (time < 100);
shared_ptr <EncryptionMode> xts (new EncryptionModeXTS);
xts->SetKey (key);
ea->SetMode (xts);
result.EncryptionSpeed = size * 1000 / time;
wxLongLong startTime = wxGetLocalTimeMillis();
startTime = wxGetLocalTimeMillis();
size = 0;
do
{
ea->DecryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
size += buffer.Size();
time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue());
}
while (time < 100);
result.DecryptionSpeed = size * 1000 / time;
result.MeanSpeed = (result.EncryptionSpeed + result.DecryptionSpeed) / 2;
bool inserted = false;
for (list <BenchmarkResult>::iterator i = results.begin(); i != results.end(); ++i)
{
if (i->MeanSpeed < result.MeanSpeed)
// CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency gradually changes depending on CPU load).
do
{
results.insert (i, result);
inserted = true;
break;
ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
}
}
while (wxGetLocalTimeMillis().GetValue() - startTime.GetValue() < 20);
if (!inserted)
results.push_back (result);
uint64 size = 0;
uint64 time;
startTime = wxGetLocalTimeMillis();
do
{
ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
size += buffer.Size();
time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue());
}
while (time < 100);
result.EncryptionSpeed = size * 1000 / time;
startTime = wxGetLocalTimeMillis();
size = 0;
do
{
ea->DecryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
size += buffer.Size();
time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue());
}
while (time < 100);
result.DecryptionSpeed = size * 1000 / time;
result.MeanSpeed = (result.EncryptionSpeed + result.DecryptionSpeed) / 2;
bool inserted = false;
for (list <BenchmarkResult>::iterator i = results.begin(); i != results.end(); ++i)
{
if (i->MeanSpeed < result.MeanSpeed)
{
results.insert (i, result);
inserted = true;
break;
}
}
if (!inserted)
results.push_back (result);
}
}
}
else if (opIndex == 1)
{
Buffer dk(MASTER_KEYDATA_SIZE);
Buffer salt(64);
const char *tmp_salt = {"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"};
unsigned long pim;
Pkcs5KdfList prfList = Pkcs5Kdf::GetAvailableAlgorithms (false);
VolumePassword password ((const byte*) "passphrase-1234567890", 21);
memcpy (&pim, buffer.Ptr (), sizeof (unsigned long));
memcpy (salt.Ptr(), tmp_salt, 64);
foreach (shared_ptr <Pkcs5Kdf> prf, prfList)
{
if (!prf->IsDeprecated())
{
BenchmarkResult result;
result.AlgorithmName = prf->GetName ();
result.Iterations = (uint64) prf->GetIterationCount (pim);
uint64 time;
wxLongLong startTime = wxGetLocalTimeMillis();
for (int i = 1; i <= 2; i++)
{
prf->DeriveKey (dk, password, pim, salt);
}
time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue());
result.Time = time / 2;
bool inserted = false;
for (list <BenchmarkResult>::iterator i = results.begin(); i != results.end(); ++i)
{
if (i->Time > result.Time)
{
results.insert (i, result);
inserted = true;
break;
}
}
if (!inserted)
results.push_back (result);
}
}
}
else
{
Buffer digest (1024);
HashList hashAlgorithms = Hash::GetAvailableAlgorithms ();
foreach (shared_ptr <Hash> hash, hashAlgorithms)
{
if (!hash->IsDeprecated())
{
BenchmarkResult result;
result.AlgorithmName = hash->GetName ();
uint64 size = 0;
uint64 time;
wxLongLong startTime = wxGetLocalTimeMillis();
// CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency gradually changes depending on CPU load).
do
{
hash->Init ();
hash->ProcessData (digest);
hash->GetDigest (digest);
}
while (wxGetLocalTimeMillis().GetValue() - startTime.GetValue() < 100);
startTime = wxGetLocalTimeMillis();
do
{
hash->Init ();
hash->ProcessData (buffer);
hash->GetDigest (digest);
time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue());
size += buffer.Size ();
}
while (time < 2000);
result.MeanSpeed = size * 1000 / time;
bool inserted = false;
for (list <BenchmarkResult>::iterator i = results.begin(); i != results.end(); ++i)
{
if (i->MeanSpeed < result.MeanSpeed)
{
results.insert (i, result);
inserted = true;
break;
}
}
if (!inserted)
results.push_back (result);
}
}
}
}
catch (exception &e)
{