diff options
Diffstat (limited to 'tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp')
-rw-r--r-- | tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp | 190 |
1 files changed, 125 insertions, 65 deletions
diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp index 719ba7a8c1..9f2d1c57f2 100644 --- a/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp +++ b/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp @@ -1,13 +1,19 @@ +// Copyright (C) 2023 The Qt Company Ltd. // Copyright (C) 2017 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// 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 @@ -15,6 +21,8 @@ class tst_QCryptographicHash : public QObject Q_OBJECT QByteArray blockOfData; + using Algorithm = QCryptographicHash::Algorithm; + public: tst_QCryptographicHash(); @@ -25,63 +33,24 @@ private Q_SLOTS: 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 MaxCryptoAlgorithm = QCryptographicHash::Sha3_512; const int MaxBlockSize = 65536; -const char *algoname(int i) +static void for_each_algorithm(qxp::function_ref<void(QCryptographicHash::Algorithm, const char*) const> f) { - 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; + 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() @@ -101,7 +70,7 @@ tst_QCryptographicHash::tst_QCryptographicHash() void tst_QCryptographicHash::hash_data() { - QTest::addColumn<int>("algorithm"); + QTest::addColumn<Algorithm>("algo"); QTest::addColumn<QByteArray>("data"); static const int datasizes[] = { 0, 1, 64, 65, 512, 4095, 4096, 4097, 65536 }; @@ -109,42 +78,56 @@ void tst_QCryptographicHash::hash_data() 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; + 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(int, algorithm); + QFETCH(const Algorithm, algo); QFETCH(QByteArray, data); - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); + SKIP_IF_NOT_SUPPORTED(algo); + QBENCHMARK { - QCryptographicHash::hash(data, algo); + [[maybe_unused]] + auto r = QCryptographicHash::hash(data, algo); } } void tst_QCryptographicHash::addData() { - QFETCH(int, algorithm); + QFETCH(const Algorithm, algo); QFETCH(QByteArray, data); - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); + SKIP_IF_NOT_SUPPORTED(algo); + QCryptographicHash hash(algo); QBENCHMARK { hash.reset(); hash.addData(data); - hash.result(); + [[maybe_unused]] + auto r = hash.resultView(); } } void tst_QCryptographicHash::addDataChunked() { - QFETCH(int, algorithm); + QFETCH(const Algorithm, algo); QFETCH(QByteArray, data); - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); + SKIP_IF_NOT_SUPPORTED(algo); + QCryptographicHash hash(algo); QBENCHMARK { hash.reset(); @@ -154,10 +137,87 @@ void tst_QCryptographicHash::addDataChunked() hash.addData({data.constData() + 64 * i, 64}); hash.addData({data.constData() + data.size() / 64 * 64, data.size() % 64}); - hash.result(); + [[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" |