diff options
Diffstat (limited to 'tests/benchmarks/corelib/tools/qcryptographichash')
3 files changed, 227 insertions, 191 deletions
diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt b/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt index 2ca8e683e1..b69b884f7d 100644 --- a/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from qcryptographichash.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_qcryptographichash Binary: @@ -6,7 +7,7 @@ qt_internal_add_benchmark(tst_bench_qcryptographichash SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qcryptographichash.cpp + LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp deleted file mode 100644 index 1f0a7373bb..0000000000 --- a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QByteArray> -#include <QCryptographicHash> -#include <QFile> -#include <QRandomGenerator> -#include <QString> -#include <QTest> - -#include <time.h> - -class tst_bench_QCryptographicHash : public QObject -{ - Q_OBJECT - QByteArray blockOfData; - -public: - tst_bench_QCryptographicHash(); - -private Q_SLOTS: - void hash_data(); - void hash(); - void addData_data() { hash_data(); } - void addData(); - void addDataChunked_data() { hash_data(); } - void addDataChunked(); -}; - -const int MaxCryptoAlgorithm = QCryptographicHash::Sha3_512; -const int MaxBlockSize = 65536; - -const char *algoname(int i) -{ - switch (QCryptographicHash::Algorithm(i)) { - case QCryptographicHash::Md4: - return "md4-"; - case QCryptographicHash::Md5: - return "md5-"; - case QCryptographicHash::Sha1: - return "sha1-"; - case QCryptographicHash::Sha224: - return "sha2_224-"; - case QCryptographicHash::Sha256: - return "sha2_256-"; - case QCryptographicHash::Sha384: - return "sha2_384-"; - case QCryptographicHash::Sha512: - return "sha2_512-"; - case QCryptographicHash::Sha3_224: - return "sha3_224-"; - case QCryptographicHash::Sha3_256: - return "sha3_256-"; - case QCryptographicHash::Sha3_384: - return "sha3_384-"; - case QCryptographicHash::Sha3_512: - return "sha3_512-"; - case QCryptographicHash::Keccak_224: - return "keccak_224-"; - case QCryptographicHash::Keccak_256: - return "keccak_256-"; - case QCryptographicHash::Keccak_384: - return "keccak_384-"; - case QCryptographicHash::Keccak_512: - return "keccak_512-"; - case QCryptographicHash::Blake2b_160: - return "blake2b_160-"; - case QCryptographicHash::Blake2b_256: - return "blake2b_256-"; - case QCryptographicHash::Blake2b_384: - return "blake2b_384-"; - case QCryptographicHash::Blake2b_512: - return "blake2b_512-"; - case QCryptographicHash::Blake2s_128: - return "blake2s_128-"; - case QCryptographicHash::Blake2s_160: - return "blake2s_160-"; - case QCryptographicHash::Blake2s_224: - return "blake2s_224-"; - case QCryptographicHash::Blake2s_256: - return "blake2s_256-"; - } - Q_UNREACHABLE(); - return nullptr; -} - -tst_bench_QCryptographicHash::tst_bench_QCryptographicHash() - : blockOfData(MaxBlockSize, Qt::Uninitialized) -{ -#ifdef Q_OS_UNIX - QFile urandom("/dev/urandom"); - if (urandom.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) { - QCOMPARE(urandom.read(blockOfData.data(), blockOfData.size()), qint64(MaxBlockSize)); - } else -#endif - { - for (int i = 0; i < MaxBlockSize; ++i) - blockOfData[i] = QRandomGenerator::global()->generate(); - } -} - -void tst_bench_QCryptographicHash::hash_data() -{ - QTest::addColumn<int>("algorithm"); - QTest::addColumn<QByteArray>("data"); - - static const int datasizes[] = { 0, 1, 64, 65, 512, 4095, 4096, 4097, 65536 }; - for (uint i = 0; i < sizeof(datasizes)/sizeof(datasizes[0]); ++i) { - Q_ASSERT(datasizes[i] < MaxBlockSize); - QByteArray data = QByteArray::fromRawData(blockOfData.constData(), datasizes[i]); - - for (int algo = QCryptographicHash::Md4; algo <= MaxCryptoAlgorithm; ++algo) - QTest::newRow(algoname(algo) + QByteArray::number(datasizes[i])) << algo << data; - } -} - -void tst_bench_QCryptographicHash::hash() -{ - QFETCH(int, algorithm); - QFETCH(QByteArray, data); - - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); - QBENCHMARK { - QCryptographicHash::hash(data, algo); - } -} - -void tst_bench_QCryptographicHash::addData() -{ - QFETCH(int, algorithm); - QFETCH(QByteArray, data); - - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); - QCryptographicHash hash(algo); - QBENCHMARK { - hash.reset(); - hash.addData(data); - hash.result(); - } -} - -void tst_bench_QCryptographicHash::addDataChunked() -{ - QFETCH(int, algorithm); - QFETCH(QByteArray, data); - - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); - QCryptographicHash hash(algo); - QBENCHMARK { - hash.reset(); - - // add the data in chunks of 64 bytes - for (int i = 0; i < data.size() / 64; ++i) - hash.addData(data.constData() + 64 * i, 64); - hash.addData(data.constData() + data.size() / 64 * 64, data.size() % 64); - - hash.result(); - } -} - -QTEST_APPLESS_MAIN(tst_bench_QCryptographicHash) - -#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp new file mode 100644 index 0000000000..9f2d1c57f2 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp @@ -0,0 +1,223 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// Copyright (C) 2017 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QByteArray> +#include <QCryptographicHash> +#include <QFile> +#include <QMetaEnum> +#include <QMessageAuthenticationCode> +#include <QRandomGenerator> +#include <QString> +#include <QTest> + +#include <qxpfunctional.h> +#include <numeric> + +#include <time.h> + +class tst_QCryptographicHash : public QObject +{ + Q_OBJECT + QByteArray blockOfData; + + using Algorithm = QCryptographicHash::Algorithm; + +public: + tst_QCryptographicHash(); + +private Q_SLOTS: + void hash_data(); + void hash(); + void addData_data() { hash_data(); } + void addData(); + void addDataChunked_data() { hash_data(); } + void addDataChunked(); + + // QMessageAuthenticationCode: + void hmac_hash_data() { hash_data(); } + void hmac_hash(); + void hmac_addData_data() { hash_data(); } + void hmac_addData(); + void hmac_setKey_data(); + void hmac_setKey(); +}; + +const int MaxBlockSize = 65536; + +static void for_each_algorithm(qxp::function_ref<void(QCryptographicHash::Algorithm, const char*) const> f) +{ + using A = QCryptographicHash::Algorithm; + static const auto metaEnum = QMetaEnum::fromType<A>(); + for (int i = 0, value = metaEnum.value(i); value != -1; value = metaEnum.value(++i)) + f(A(value), metaEnum.key(i)); +} + +tst_QCryptographicHash::tst_QCryptographicHash() + : blockOfData(MaxBlockSize, Qt::Uninitialized) +{ +#ifdef Q_OS_UNIX + QFile urandom("/dev/urandom"); + if (urandom.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) { + QCOMPARE(urandom.read(blockOfData.data(), blockOfData.size()), qint64(MaxBlockSize)); + } else +#endif + { + for (int i = 0; i < MaxBlockSize; ++i) + blockOfData[i] = QRandomGenerator::global()->generate(); + } +} + +void tst_QCryptographicHash::hash_data() +{ + QTest::addColumn<Algorithm>("algo"); + QTest::addColumn<QByteArray>("data"); + + static const int datasizes[] = { 0, 1, 64, 65, 512, 4095, 4096, 4097, 65536 }; + for (uint i = 0; i < sizeof(datasizes)/sizeof(datasizes[0]); ++i) { + Q_ASSERT(datasizes[i] < MaxBlockSize); + QByteArray data = QByteArray::fromRawData(blockOfData.constData(), datasizes[i]); + + for_each_algorithm([&] (Algorithm algo, const char *name) { + if (algo == Algorithm::NumAlgorithms) + return; + QTest::addRow("%s-%d", name, datasizes[i]) << algo << data; + }); + } +} + +#define SKIP_IF_NOT_SUPPORTED(algo) do { \ + if (!QCryptographicHash::supportsAlgorithm(algo)) \ + QSKIP("This algorithm is not supported in this configuration"); \ + } while (false) \ + /* end */ + +void tst_QCryptographicHash::hash() +{ + QFETCH(const Algorithm, algo); + QFETCH(QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + QBENCHMARK { + [[maybe_unused]] + auto r = QCryptographicHash::hash(data, algo); + } +} + +void tst_QCryptographicHash::addData() +{ + QFETCH(const Algorithm, algo); + QFETCH(QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + QCryptographicHash hash(algo); + QBENCHMARK { + hash.reset(); + hash.addData(data); + [[maybe_unused]] + auto r = hash.resultView(); + } +} + +void tst_QCryptographicHash::addDataChunked() +{ + QFETCH(const Algorithm, algo); + QFETCH(QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + QCryptographicHash hash(algo); + QBENCHMARK { + hash.reset(); + + // add the data in chunks of 64 bytes + for (int i = 0; i < data.size() / 64; ++i) + hash.addData({data.constData() + 64 * i, 64}); + hash.addData({data.constData() + data.size() / 64 * 64, data.size() % 64}); + + [[maybe_unused]] + auto r = hash.resultView(); + } +} + +static QByteArray hmacKey() { + static QByteArray key = [] { + QByteArray result(277, Qt::Uninitialized); + std::iota(result.begin(), result.end(), uchar(0)); // uchar so wraps after UCHAR_MAX + return result; + }(); + return key; +} + +void tst_QCryptographicHash::hmac_hash() +{ + QFETCH(const Algorithm, algo); + QFETCH(const QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + const auto key = hmacKey(); + QBENCHMARK { + [[maybe_unused]] + auto r = QMessageAuthenticationCode::hash(data, key, algo); + } +} + +void tst_QCryptographicHash::hmac_addData() +{ + QFETCH(const Algorithm, algo); + QFETCH(const QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + const auto key = hmacKey(); + QMessageAuthenticationCode mac(algo, key); + QBENCHMARK { + mac.reset(); + mac.addData(data); + [[maybe_unused]] + auto r = mac.resultView(); + } +} + +void tst_QCryptographicHash::hmac_setKey_data() +{ + QTest::addColumn<Algorithm>("algo"); + for_each_algorithm([] (Algorithm algo, const char *name) { + if (algo == Algorithm::NumAlgorithms) + return; + QTest::addRow("%s", name) << algo; + }); +} + +void tst_QCryptographicHash::hmac_setKey() +{ + QFETCH(const Algorithm, algo); + + SKIP_IF_NOT_SUPPORTED(algo); + + const QByteArrayList keys = [] { + QByteArrayList result; + const auto fullKey = hmacKey(); + result.reserve(fullKey.size()); + for (auto i = fullKey.size(); i > 0; --i) + result.push_back(fullKey.sliced(i)); + return result; + }(); + + QMessageAuthenticationCode mac(algo); + QBENCHMARK { + for (const auto &key : keys) { + mac.setKey(key); + mac.addData("abc", 3); // avoid lazy setKey() + } + } +} + +#undef SKIP_IF_NOT_SUPPORTED + +QTEST_APPLESS_MAIN(tst_QCryptographicHash) + +#include "tst_bench_qcryptographichash.moc" |