summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/benchmark/bench_crypto.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/benchmark/bench_crypto.cpp')
-rw-r--r--protocols/Telegram/tdlib/td/benchmark/bench_crypto.cpp392
1 files changed, 352 insertions, 40 deletions
diff --git a/protocols/Telegram/tdlib/td/benchmark/bench_crypto.cpp b/protocols/Telegram/tdlib/td/benchmark/bench_crypto.cpp
index 44d309ef11..40d7602d2e 100644
--- a/protocols/Telegram/tdlib/td/benchmark/bench_crypto.cpp
+++ b/protocols/Telegram/tdlib/td/benchmark/bench_crypto.cpp
@@ -1,75 +1,374 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include "td/utils/benchmark.h"
+#include "td/utils/common.h"
#include "td/utils/crypto.h"
-#include "td/utils/int_types.h"
-#include "td/utils/logging.h"
#include "td/utils/port/thread.h"
#include "td/utils/Random.h"
#include "td/utils/Slice.h"
+#include "td/utils/SliceBuilder.h"
+#include "td/utils/UInt.h"
+#include <openssl/evp.h>
#include <openssl/sha.h>
+#include <algorithm>
#include <array>
#include <atomic>
#include <cstdint>
#include <cstdlib>
+#include <iterator>
#include <random>
#include <string>
#include <vector>
static constexpr int DATA_SIZE = 8 << 10;
+static constexpr int SHORT_DATA_SIZE = 64;
-class SHA1Bench : public td::Benchmark {
+#if OPENSSL_VERSION_NUMBER <= 0x10100000L
+class SHA1Bench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
- std::string get_description() const override {
+ std::string get_description() const final {
return PSTRING() << "SHA1 OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
}
- void start_up() override {
- for (int i = 0; i < DATA_SIZE; i++) {
- data[i] = 123;
- data[i] = 0;
- }
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
}
- void run(int n) override {
+ void run(int n) final {
for (int i = 0; i < n; i++) {
unsigned char md[20];
SHA1(data, DATA_SIZE, md);
}
}
};
+#endif
+
+class SHA1ShortBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[SHORT_DATA_SIZE];
+
+ std::string get_description() const final {
+ return PSTRING() << "SHA1 [" << SHORT_DATA_SIZE << "B]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ }
+
+ void run(int n) final {
+ unsigned char md[20];
+ for (int i = 0; i < n; i++) {
+ td::sha1(td::Slice(data, SHORT_DATA_SIZE), md);
+ }
+ }
+};
+
+class SHA256ShortBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[SHORT_DATA_SIZE];
+
+ std::string get_description() const final {
+ return PSTRING() << "SHA256 [" << SHORT_DATA_SIZE << "B]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ }
+
+ void run(int n) final {
+ unsigned char md[32];
+ for (int i = 0; i < n; i++) {
+ td::sha256(td::Slice(data, SHORT_DATA_SIZE), td::MutableSlice(md, 32));
+ }
+ }
+};
+
+class SHA512ShortBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[SHORT_DATA_SIZE];
+
+ std::string get_description() const final {
+ return PSTRING() << "SHA512 [" << SHORT_DATA_SIZE << "B]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ }
+
+ void run(int n) final {
+ unsigned char md[64];
+ for (int i = 0; i < n; i++) {
+ td::sha512(td::Slice(data, SHORT_DATA_SIZE), td::MutableSlice(md, 64));
+ }
+ }
+};
-class AESBench : public td::Benchmark {
+class HmacSha256ShortBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[SHORT_DATA_SIZE];
+
+ std::string get_description() const final {
+ return PSTRING() << "HMAC-SHA256 [" << SHORT_DATA_SIZE << "B]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ }
+
+ void run(int n) final {
+ unsigned char md[32];
+ for (int i = 0; i < n; i++) {
+ td::hmac_sha256(td::Slice(data, SHORT_DATA_SIZE), td::Slice(data, SHORT_DATA_SIZE), td::MutableSlice(md, 32));
+ }
+ }
+};
+
+class HmacSha512ShortBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[SHORT_DATA_SIZE];
+
+ std::string get_description() const final {
+ return PSTRING() << "HMAC-SHA512 [" << SHORT_DATA_SIZE << "B]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ }
+
+ void run(int n) final {
+ unsigned char md[32];
+ for (int i = 0; i < n; i++) {
+ td::hmac_sha256(td::Slice(data, SHORT_DATA_SIZE), td::Slice(data, SHORT_DATA_SIZE), td::MutableSlice(md, 32));
+ }
+ }
+};
+
+class AesEcbBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt256 iv;
- std::string get_description() const override {
- return PSTRING() << "AES OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
+ std::string get_description() const final {
+ return PSTRING() << "AES ECB OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ td::Random::secure_bytes(key.raw, sizeof(key));
+ td::Random::secure_bytes(iv.raw, sizeof(iv));
}
- void start_up() override {
- for (int i = 0; i < DATA_SIZE; i++) {
- data[i] = 123;
+ void run(int n) final {
+ td::AesState state;
+ state.init(td::as_slice(key), true);
+ td::MutableSlice data_slice(data, DATA_SIZE);
+ for (int i = 0; i <= n; i++) {
+ size_t step = 16;
+ for (size_t offset = 0; offset + step <= data_slice.size(); offset += step) {
+ state.encrypt(data_slice.ubegin() + offset, data_slice.ubegin() + offset, static_cast<int>(step));
+ }
}
+ }
+};
+
+class AesIgeEncryptBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[DATA_SIZE];
+ td::UInt256 key;
+ td::UInt256 iv;
+
+ std::string get_description() const final {
+ return PSTRING() << "AES IGE OpenSSL encrypt [" << (DATA_SIZE >> 10) << "KB]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
td::Random::secure_bytes(key.raw, sizeof(key));
td::Random::secure_bytes(iv.raw, sizeof(iv));
}
- void run(int n) override {
+ void run(int n) final {
td::MutableSlice data_slice(data, DATA_SIZE);
+ td::AesIgeState state;
+ state.init(as_slice(key), as_slice(iv), true);
for (int i = 0; i < n; i++) {
- td::aes_ige_encrypt(key, &iv, data_slice, data_slice);
+ state.encrypt(data_slice, data_slice);
+ }
+ }
+};
+
+class AesIgeDecryptBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[DATA_SIZE];
+ td::UInt256 key;
+ td::UInt256 iv;
+
+ std::string get_description() const final {
+ return PSTRING() << "AES IGE OpenSSL decrypt [" << (DATA_SIZE >> 10) << "KB]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ td::Random::secure_bytes(key.raw, sizeof(key));
+ td::Random::secure_bytes(iv.raw, sizeof(iv));
+ }
+
+ void run(int n) final {
+ td::MutableSlice data_slice(data, DATA_SIZE);
+ td::AesIgeState state;
+ state.init(as_slice(key), as_slice(iv), false);
+ for (int i = 0; i < n; i++) {
+ state.decrypt(data_slice, data_slice);
+ }
+ }
+};
+
+class AesCtrBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[DATA_SIZE];
+ td::UInt256 key;
+ td::UInt128 iv;
+
+ std::string get_description() const final {
+ return PSTRING() << "AES CTR OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ td::Random::secure_bytes(key.raw, sizeof(key));
+ td::Random::secure_bytes(iv.raw, sizeof(iv));
+ }
+
+ void run(int n) final {
+ td::MutableSlice data_slice(data, DATA_SIZE);
+ td::AesCtrState state;
+ state.init(as_slice(key), as_slice(iv));
+ for (int i = 0; i < n; i++) {
+ state.encrypt(data_slice, data_slice);
+ }
+ }
+};
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+class AesCtrOpenSSLBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[DATA_SIZE];
+ td::UInt256 key;
+ td::UInt128 iv;
+
+ std::string get_description() const final {
+ return PSTRING() << "AES CTR RAW OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ td::Random::secure_bytes(key.raw, sizeof(key));
+ td::Random::secure_bytes(iv.raw, sizeof(iv));
+ }
+
+ void run(int n) final {
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+ EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, key.raw, iv.raw);
+
+ td::MutableSlice data_slice(data, DATA_SIZE);
+ td::AesCtrState state;
+ state.init(as_slice(key), as_slice(iv));
+ for (int i = 0; i < n; i++) {
+ int len = 0;
+ EVP_EncryptUpdate(ctx, data_slice.ubegin(), &len, data_slice.ubegin(), DATA_SIZE);
+ CHECK(len == DATA_SIZE);
+ }
+
+ EVP_CIPHER_CTX_free(ctx);
+ }
+};
+#endif
+
+class AesCbcDecryptBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[DATA_SIZE];
+ td::UInt256 key;
+ td::UInt128 iv;
+
+ std::string get_description() const final {
+ return PSTRING() << "AES CBC Decrypt OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ td::Random::secure_bytes(as_slice(key));
+ td::Random::secure_bytes(as_slice(iv));
+ }
+
+ void run(int n) final {
+ td::MutableSlice data_slice(data, DATA_SIZE);
+ for (int i = 0; i < n; i++) {
+ td::aes_cbc_decrypt(as_slice(key), as_slice(iv), data_slice, data_slice);
+ }
+ }
+};
+
+class AesCbcEncryptBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[DATA_SIZE];
+ td::UInt256 key;
+ td::UInt128 iv;
+
+ std::string get_description() const final {
+ return PSTRING() << "AES CBC Encrypt OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ td::Random::secure_bytes(as_slice(key));
+ td::Random::secure_bytes(as_slice(iv));
+ }
+
+ void run(int n) final {
+ td::MutableSlice data_slice(data, DATA_SIZE);
+ for (int i = 0; i < n; i++) {
+ td::aes_cbc_encrypt(as_slice(key), as_slice(iv), data_slice, data_slice);
+ }
+ }
+};
+
+template <bool use_state>
+class AesIgeShortBench final : public td::Benchmark {
+ public:
+ alignas(64) unsigned char data[SHORT_DATA_SIZE];
+ td::UInt256 key;
+ td::UInt256 iv;
+
+ std::string get_description() const final {
+ return PSTRING() << "AES IGE OpenSSL " << (use_state ? "EVP" : "C ") << "[" << SHORT_DATA_SIZE << "B]";
+ }
+
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
+ td::Random::secure_bytes(as_slice(key));
+ td::Random::secure_bytes(as_slice(iv));
+ }
+
+ void run(int n) final {
+ td::MutableSlice data_slice(data, SHORT_DATA_SIZE);
+ for (int i = 0; i < n; i++) {
+ if (use_state) {
+ td::AesIgeState ige;
+ ige.init(as_slice(key), as_slice(iv), false);
+ ige.decrypt(data_slice, data_slice);
+ } else {
+ td::aes_ige_decrypt(as_slice(key), as_slice(iv), data_slice, data_slice);
+ }
}
}
};
@@ -110,15 +409,15 @@ BENCH(TdRandFast, "td_rand_fast") {
#if !TD_THREAD_UNSUPPORTED
BENCH(SslRand, "ssl_rand_int32") {
std::vector<td::thread> v;
- std::atomic<td::uint32> sum;
+ std::atomic<td::uint32> sum{0};
for (int i = 0; i < 3; i++) {
- v.push_back(td::thread([&] {
+ v.emplace_back([&sum, n] {
td::int32 res = 0;
for (int j = 0; j < n; j++) {
res ^= td::Random::secure_int32();
}
sum += res;
- }));
+ });
}
for (auto &x : v) {
x.join();
@@ -147,22 +446,19 @@ BENCH(Pbkdf2, "pbkdf2") {
td::pbkdf2_sha256(password, salt, n, key);
}
-class Crc32Bench : public td::Benchmark {
+class Crc32Bench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
- std::string get_description() const override {
+ std::string get_description() const final {
return PSTRING() << "Crc32 zlib [" << (DATA_SIZE >> 10) << "KB]";
}
- void start_up() override {
- for (int i = 0; i < DATA_SIZE; i++) {
- data[i] = 123;
- data[i] = 0;
- }
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
}
- void run(int n) override {
+ void run(int n) final {
td::uint64 res = 0;
for (int i = 0; i < n; i++) {
res += td::crc32(td::Slice(data, DATA_SIZE));
@@ -171,22 +467,19 @@ class Crc32Bench : public td::Benchmark {
}
};
-class Crc64Bench : public td::Benchmark {
+class Crc64Bench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
- std::string get_description() const override {
+ std::string get_description() const final {
return PSTRING() << "Crc64 Anton [" << (DATA_SIZE >> 10) << "KB]";
}
- void start_up() override {
- for (int i = 0; i < DATA_SIZE; i++) {
- data[i] = 123;
- data[i] = 0;
- }
+ void start_up() final {
+ std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(123));
}
- void run(int n) override {
+ void run(int n) final {
td::uint64 res = 0;
for (int i = 0; i < n; i++) {
res += td::crc64(td::Slice(data, DATA_SIZE));
@@ -196,6 +489,20 @@ class Crc64Bench : public td::Benchmark {
};
int main() {
+ td::init_openssl_threads();
+ td::bench(AesCtrBench());
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ td::bench(AesCtrOpenSSLBench());
+#endif
+
+ td::bench(AesCbcDecryptBench());
+ td::bench(AesCbcEncryptBench());
+ td::bench(AesIgeShortBench<true>());
+ td::bench(AesIgeShortBench<false>());
+ td::bench(AesIgeEncryptBench());
+ td::bench(AesIgeDecryptBench());
+ td::bench(AesEcbBench());
+
td::bench(Pbkdf2Bench());
td::bench(RandBench());
td::bench(CppRandBench());
@@ -205,9 +512,14 @@ int main() {
td::bench(SslRandBench());
#endif
td::bench(SslRandBufBench());
+#if OPENSSL_VERSION_NUMBER <= 0x10100000L
td::bench(SHA1Bench());
- td::bench(AESBench());
+#endif
+ td::bench(SHA1ShortBench());
+ td::bench(SHA256ShortBench());
+ td::bench(SHA512ShortBench());
+ td::bench(HmacSha256ShortBench());
+ td::bench(HmacSha512ShortBench());
td::bench(Crc32Bench());
td::bench(Crc64Bench());
- return 0;
}