From 56aaa5efbc95e01f08a9489cd64f7ea52978095c Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Mon, 14 Mar 2022 03:25:01 +0200 Subject: [PATCH] implement Katie's hash algorithm as class and split input data in two chunks benchmark result: ********* Start testing of tst_qcryptographichash ********* Config: Using QTest library 4.12.0, Katie 4.12.0 PASS : tst_qcryptographichash::initTestCase() RESULT : tst_qcryptographichash::append():"10 (Md5)": 2,847.12983 CPU ticks per iteration (total: 569,425,966, iterations: 200000) RESULT : tst_qcryptographichash::append():"10 (Sha1)": 3,370.50678 CPU ticks per iteration (total: 674,101,357, iterations: 200000) RESULT : tst_qcryptographichash::append():"10 (Sha256)": 4,718.83796 CPU ticks per iteration (total: 943,767,592, iterations: 200000) RESULT : tst_qcryptographichash::append():"10 (Sha512)": 3,636.39393 CPU ticks per iteration (total: 727,278,787, iterations: 200000) RESULT : tst_qcryptographichash::append():"10 (KAT)": 1,424.54430 CPU ticks per iteration (total: 284,908,860, iterations: 200000) RESULT : tst_qcryptographichash::append():"100 (Md5)": 674.086020 CPU ticks per iteration (total: 134,817,204, iterations: 200000) RESULT : tst_qcryptographichash::append():"100 (Sha1)": 1,133.63370 CPU ticks per iteration (total: 226,726,740, iterations: 200000) RESULT : tst_qcryptographichash::append():"100 (Sha256)": 940.656270 CPU ticks per iteration (total: 188,131,254, iterations: 200000) RESULT : tst_qcryptographichash::append():"100 (Sha512)": 1,092.76190 CPU ticks per iteration (total: 218,552,381, iterations: 200000) RESULT : tst_qcryptographichash::append():"100 (KAT)": 752.884775 CPU ticks per iteration (total: 150,576,955, iterations: 200000) RESULT : tst_qcryptographichash::append():"250 (Md5)": 635.722665 CPU ticks per iteration (total: 127,144,533, iterations: 200000) RESULT : tst_qcryptographichash::append():"250 (Sha1)": 1,365.40317 CPU ticks per iteration (total: 273,080,634, iterations: 200000) RESULT : tst_qcryptographichash::append():"250 (Sha256)": 893.019390 CPU ticks per iteration (total: 178,603,878, iterations: 200000) RESULT : tst_qcryptographichash::append():"250 (Sha512)": 1,042.41434 CPU ticks per iteration (total: 208,482,868, iterations: 200000) RESULT : tst_qcryptographichash::append():"250 (KAT)": 647.685440 CPU ticks per iteration (total: 129,537,088, iterations: 200000) RESULT : tst_qcryptographichash::append():"500 (Md5)": 613.694575 CPU ticks per iteration (total: 122,738,915, iterations: 200000) RESULT : tst_qcryptographichash::append():"500 (Sha1)": 1,385.37680 CPU ticks per iteration (total: 277,075,361, iterations: 200000) RESULT : tst_qcryptographichash::append():"500 (Sha256)": 875.499705 CPU ticks per iteration (total: 175,099,941, iterations: 200000) RESULT : tst_qcryptographichash::append():"500 (Sha512)": 1,026.35629 CPU ticks per iteration (total: 205,271,259, iterations: 200000) RESULT : tst_qcryptographichash::append():"500 (KAT)": 613.024700 CPU ticks per iteration (total: 122,604,940, iterations: 200000) PASS : tst_qcryptographichash::append() RESULT : tst_qcryptographichash::append_once():"Md5": 1,575.48784 CPU ticks per iteration (total: 315,097,569, iterations: 200000) RESULT : tst_qcryptographichash::append_once():"Sha1": 2,189.54088 CPU ticks per iteration (total: 437,908,176, iterations: 200000) RESULT : tst_qcryptographichash::append_once():"Sha256": 4,181.71968 CPU ticks per iteration (total: 836,343,936, iterations: 200000) RESULT : tst_qcryptographichash::append_once():"Sha512": 3,171.89449 CPU ticks per iteration (total: 634,378,899, iterations: 200000) RESULT : tst_qcryptographichash::append_once():"KAT": 783.837000 CPU ticks per iteration (total: 156,767,400, iterations: 200000) PASS : tst_qcryptographichash::append_once() RESULT : tst_qcryptographichash::statichash():"Md5": 1,491.84898 CPU ticks per iteration (total: 298,369,796, iterations: 200000) RESULT : tst_qcryptographichash::statichash():"Sha1": 2,074.73995 CPU ticks per iteration (total: 414,947,990, iterations: 200000) RESULT : tst_qcryptographichash::statichash():"Sha256": 4,098.37431 CPU ticks per iteration (total: 819,674,863, iterations: 200000) RESULT : tst_qcryptographichash::statichash():"Sha512": 3,075.87383 CPU ticks per iteration (total: 615,174,767, iterations: 200000) RESULT : tst_qcryptographichash::statichash():"KAT": 745.386400 CPU ticks per iteration (total: 149,077,280, iterations: 200000) PASS : tst_qcryptographichash::statichash() PASS : tst_qcryptographichash::cleanupTestCase() Totals: 5 passed, 0 failed, 0 skipped ********* Finished testing of tst_qcryptographichash ********* Signed-off-by: Ivailo Monev --- src/network/kernel/qcryptographichash.cpp | 109 +++++++++++++-------- .../qcryptographichash/tst_qcryptographichash.cpp | 6 +- 2 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/network/kernel/qcryptographichash.cpp b/src/network/kernel/qcryptographichash.cpp index ecf58575d..0338a19f3 100644 --- a/src/network/kernel/qcryptographichash.cpp +++ b/src/network/kernel/qcryptographichash.cpp @@ -32,6 +32,66 @@ QT_BEGIN_NAMESPACE +static const int xxh3len = sizeof(XXH128_hash_t); + +class QKatHash +{ +public: + QKatHash(); + ~QKatHash(); + + void reset(); + void update(const char *data, const int length); + QByteArray result() const; + +private: + XXH3_state_t* m_xxh3; + XXH3_state_t* m_xxh32; +}; + +QKatHash::QKatHash() + : m_xxh3(nullptr), + m_xxh32(nullptr) +{ + m_xxh3 = XXH3_createState(); + m_xxh32 = XXH3_createState(); +} + +QKatHash::~QKatHash() +{ + XXH3_freeState(m_xxh3); + XXH3_freeState(m_xxh32); +} + +void QKatHash::reset() +{ + XXH3_128bits_reset(m_xxh3); + XXH3_128bits_reset(m_xxh32); +} + +void QKatHash::update(const char *data, const int length) +{ + if (Q_UNLIKELY(length == 1)) { + XXH3_128bits_update(m_xxh3, data, length); + XXH3_128bits_update(m_xxh32, "K", 1); + } else if (Q_LIKELY(length > 1)) { + const size_t halflenght = (length / 2); + XXH3_128bits_update(m_xxh3, data, halflenght); + XXH3_128bits_update(m_xxh32, data + halflenght, halflenght); + } +} + +QByteArray QKatHash::result() const +{ + XXH128_canonical_t xxh3canonical; + XXH128_canonicalFromHash(&xxh3canonical, XXH3_128bits_digest(m_xxh3)); + + XXH128_canonical_t xxh3canonical2; + XXH128_canonicalFromHash(&xxh3canonical2, XXH3_128bits_digest(m_xxh32)); + + return (QByteArray(reinterpret_cast(xxh3canonical.digest), xxh3len) + QByteArray(reinterpret_cast(xxh3canonical2.digest), xxh3len)); +} + class QCryptographicHashPrivate { public: @@ -42,24 +102,19 @@ public: SHA1_CTX sha1Context; SHA256_CTX sha256Context; SHA512_CTX sha512Context; - XXH3_state_t* xxh3Context; - XXH3_state_t* xxh3Context2; + QKatHash katContext; bool rehash; const QCryptographicHash::Algorithm method; }; QCryptographicHashPrivate::QCryptographicHashPrivate(const QCryptographicHash::Algorithm amethod) - : xxh3Context(nullptr), - xxh3Context2(nullptr), - rehash(false), + : rehash(false), method(amethod) { } QCryptographicHashPrivate::~QCryptographicHashPrivate() { - XXH3_freeState(xxh3Context); - XXH3_freeState(xxh3Context2); } /*! @@ -81,7 +136,8 @@ QCryptographicHashPrivate::~QCryptographicHashPrivate() \warning The custom algorithm will not produce same result from the static and the incremental methods. Use either to compute hash sums with this - algorithm. + algorithm. Do not feed QCryptographicHash with chunks of data that have + different sizes either - the chunks size must be fixed, i.e. BUFFSIZE. */ /*! @@ -136,14 +192,7 @@ void QCryptographicHash::reset() break; } case QCryptographicHash::KAT: { - if (!d->xxh3Context) { - d->xxh3Context = XXH3_createState(); - } - if (!d->xxh3Context2) { - d->xxh3Context2 = XXH3_createState(); - } - XXH3_128bits_reset(d->xxh3Context); - XXH3_128bits_reset(d->xxh3Context2); + d->katContext.reset(); break; } } @@ -173,10 +222,7 @@ void QCryptographicHash::addData(const char *data, int length) break; } case QCryptographicHash::KAT: { - XXH3_128bits_update(d->xxh3Context, data, length); - if (Q_LIKELY(length > 1)) { - XXH3_128bits_update(d->xxh3Context2, data, length / 2); - } + d->katContext.update(data, length); break; } } @@ -241,13 +287,7 @@ QByteArray QCryptographicHash::result() const return QByteArray(reinterpret_cast(result), SHA512_DIGEST_LENGTH); } case QCryptographicHash::KAT: { - const XXH128_hash_t xxresult = XXH3_128bits_digest(d->xxh3Context); - XXH128_canonical_t xxcanonical; - XXH128_canonicalFromHash(&xxcanonical, xxresult); - const XXH128_hash_t xxresult2 = XXH3_128bits_digest(d->xxh3Context2); - XXH128_canonical_t xxcanonical2; - XXH128_canonicalFromHash(&xxcanonical2, xxresult2); - return (QByteArray(reinterpret_cast(xxcanonical.digest), sizeof(XXH128_hash_t)) + QByteArray(reinterpret_cast(xxcanonical2.digest), sizeof(XXH128_hash_t))); + return d->katContext.result(); } } @@ -293,18 +333,9 @@ QByteArray QCryptographicHash::hash(const QByteArray &data, QCryptographicHash:: return QByteArray(reinterpret_cast(result), SHA512_DIGEST_LENGTH); } case QCryptographicHash::KAT: { - const XXH128_hash_t xxresult = XXH3_128bits(data.constData(), data.length()); - XXH128_canonical_t xxcanonical; - XXH128_canonicalFromHash(&xxcanonical, xxresult); - XXH128_hash_t xxresult2; - if (Q_LIKELY(data.length() > 1)) { - xxresult2 = XXH3_128bits(data.constData(), data.length() / 2); - } else { - xxresult2 = XXH3_128bits("KATIE", 5); - } - XXH128_canonical_t xxcanonical2; - XXH128_canonicalFromHash(&xxcanonical2, xxresult2); - return (QByteArray(reinterpret_cast(xxcanonical.digest), sizeof(XXH128_hash_t)) + QByteArray(reinterpret_cast(xxcanonical2.digest), sizeof(XXH128_hash_t))); + QKatHash kathash; + kathash.update(data.constData(), data.length()); + return kathash.result(); } } diff --git a/tests/auto/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/qcryptographichash/tst_qcryptographichash.cpp index 54dcb2f47..a3b1ca045 100644 --- a/tests/auto/qcryptographichash/tst_qcryptographichash.cpp +++ b/tests/auto/qcryptographichash/tst_qcryptographichash.cpp @@ -91,8 +91,8 @@ void tst_QCryptographicHash::intermediary_result_data() << QByteArray::fromHex("F3C41E7B63EE869596FC28BAD64120612C520F65928AB4D126C72C6998B551B8FF1CEDDFED4373E6717554DC89D1EEE6F0AB22FD3675E561ABA9AE26A3EEC53B"); QTest::newRow("KAT") << QCryptographicHash::KAT << QByteArray("abc") << QByteArray("abc") - << QByteArray::fromHex("06b05ab6733a618578af5f94892f3950a96faf705af16834e6c632b61e964e1f") - << QByteArray::fromHex("3b3faa148c5f05f1b441a07dd428557bb9fe94d346d39b20369242a646a19333"); + << QByteArray::fromHex("a96faf705af16834e6c632b61e964e1f4b2212e31ac97fd4575a0b1c44d8843f") + << QByteArray::fromHex("b9fe94d346d39b20369242a646a19333db1de4b3da6c7871b776d5cb968aa5a4"); } void tst_QCryptographicHash::intermediary_result() @@ -117,8 +117,6 @@ void tst_QCryptographicHash::intermediary_result() result = hash.result(); // qDebug() << result.toHex(); QCOMPARE(result, hash_firstsecond); - - hash.reset(); } void tst_QCryptographicHash::static_vs_incremental_result_data() -- 2.11.0