diff options
author | komels <komels@yandex-team.ru> | 2022-04-14 13:10:53 +0300 |
---|---|---|
committer | komels <komels@yandex-team.ru> | 2022-04-14 13:10:53 +0300 |
commit | 21c9b0e6b039e9765eb414c406c2b86e8cea6850 (patch) | |
tree | f40ebc18ff8958dfbd189954ad024043ca983ea5 /library/cpp/openssl/big_integer | |
parent | 9a4effa852abe489707139c2b260dccc6f4f9aa9 (diff) | |
download | ydb-21c9b0e6b039e9765eb414c406c2b86e8cea6850.tar.gz |
Final part on compatibility layer: LOGBROKER-7215
ref:777c67aadbf705d19034a09a792b2df61ba53697
Diffstat (limited to 'library/cpp/openssl/big_integer')
-rw-r--r-- | library/cpp/openssl/big_integer/CMakeLists.txt | 19 | ||||
-rw-r--r-- | library/cpp/openssl/big_integer/big_integer.cpp | 61 | ||||
-rw-r--r-- | library/cpp/openssl/big_integer/big_integer.h | 57 | ||||
-rw-r--r-- | library/cpp/openssl/big_integer/ut/big_integer_ut.cpp | 43 |
4 files changed, 180 insertions, 0 deletions
diff --git a/library/cpp/openssl/big_integer/CMakeLists.txt b/library/cpp/openssl/big_integer/CMakeLists.txt new file mode 100644 index 0000000000..55d94de253 --- /dev/null +++ b/library/cpp/openssl/big_integer/CMakeLists.txt @@ -0,0 +1,19 @@ + +# This file was gererated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +find_package(OpenSSL REQUIRED) + +add_library(cpp-openssl-big_integer) +target_link_libraries(cpp-openssl-big_integer PUBLIC + contrib-libs-cxxsupp + yutil + OpenSSL::OpenSSL +) +target_sources(cpp-openssl-big_integer PRIVATE + ${CMAKE_SOURCE_DIR}/library/cpp/openssl/big_integer/big_integer.cpp +) diff --git a/library/cpp/openssl/big_integer/big_integer.cpp b/library/cpp/openssl/big_integer/big_integer.cpp new file mode 100644 index 0000000000..de59f84499 --- /dev/null +++ b/library/cpp/openssl/big_integer/big_integer.cpp @@ -0,0 +1,61 @@ +#include "big_integer.h" + +#include <util/generic/yexception.h> +#include <util/generic/scope.h> +#include <util/stream/output.h> + +#include <contrib/libs/openssl/include/openssl/bn.h> + +using namespace NOpenSsl; + +TBigInteger::~TBigInteger() noexcept { + BN_free(Impl_); +} + +TBigInteger TBigInteger::FromULong(ui64 value) { + TBigInteger result(BN_new()); + + Y_ENSURE(result.Impl(), "BN_new() failed"); + Y_ENSURE(BN_set_word(result.Impl(), value) == 1, "BN_set_word() failed"); + + return result; +} + +TBigInteger TBigInteger::FromRegion(const void* ptr, size_t len) { + auto result = BN_bin2bn((ui8*)(ptr), len, nullptr); + + Y_ENSURE(result, "BN_bin2bn() failed"); + + return result; +} + +int TBigInteger::Compare(const TBigInteger& a, const TBigInteger& b) noexcept { + return BN_cmp(a.Impl(), b.Impl()); +} + +size_t TBigInteger::NumBytes() const noexcept { + return BN_num_bytes(Impl_); +} + +size_t TBigInteger::ToRegion(void* to) const noexcept { + const auto ret = BN_bn2bin(Impl_, (unsigned char*)to); + + Y_VERIFY(ret >= 0, "it happens"); + + return ret; +} + +TString TBigInteger::ToDecimalString() const { + auto res = BN_bn2dec(Impl_); + + Y_DEFER { + OPENSSL_free(res); + }; + + return res; +} + +template <> +void Out<TBigInteger>(IOutputStream& out, const TBigInteger& bi) { + out << bi.ToDecimalString(); +} diff --git a/library/cpp/openssl/big_integer/big_integer.h b/library/cpp/openssl/big_integer/big_integer.h new file mode 100644 index 0000000000..07763c5e13 --- /dev/null +++ b/library/cpp/openssl/big_integer/big_integer.h @@ -0,0 +1,57 @@ +#pragma once + +#include <util/generic/ptr.h> +#include <util/generic/strbuf.h> +#include <util/generic/utility.h> +#include <util/generic/string.h> + +struct bignum_st; + +namespace NOpenSsl { + class TBigInteger { + inline TBigInteger(bignum_st* impl) noexcept + : Impl_(impl) + { + } + + static int Compare(const TBigInteger& a, const TBigInteger& b) noexcept; + + public: + inline TBigInteger(TBigInteger&& other) noexcept { + Swap(other); + } + + ~TBigInteger() noexcept; + + static TBigInteger FromULong(ui64 value); + static TBigInteger FromRegion(const void* ptr, size_t len); + + inline const bignum_st* Impl() const noexcept { + return Impl_; + } + + inline bignum_st* Impl() noexcept { + return Impl_; + } + + inline void Swap(TBigInteger& other) noexcept { + DoSwap(Impl_, other.Impl_); + } + + inline friend bool operator==(const TBigInteger& a, const TBigInteger& b) noexcept { + return Compare(a, b) == 0; + } + + inline friend bool operator!=(const TBigInteger& a, const TBigInteger& b) noexcept { + return !(a == b); + } + + size_t NumBytes() const noexcept; + size_t ToRegion(void* to) const noexcept; + + TString ToDecimalString() const; + + private: + bignum_st* Impl_ = nullptr; + }; +} diff --git a/library/cpp/openssl/big_integer/ut/big_integer_ut.cpp b/library/cpp/openssl/big_integer/ut/big_integer_ut.cpp new file mode 100644 index 0000000000..8a0050f531 --- /dev/null +++ b/library/cpp/openssl/big_integer/ut/big_integer_ut.cpp @@ -0,0 +1,43 @@ +#include "big_integer.h" + +#include <library/cpp/testing/unittest/registar.h> + +#include <util/system/byteorder.h> +#include <util/stream/str.h> + +Y_UNIT_TEST_SUITE(BigInteger) { + using NOpenSsl::TBigInteger; + + Y_UNIT_TEST(Initialization) { + constexpr ui64 testVal = 12345678900; + const auto fromULong = TBigInteger::FromULong(testVal); + + const ui64 testArea = HostToInet(testVal); // transform to big-endian + const auto fromRegion = TBigInteger::FromRegion(&testArea, sizeof(testArea)); + UNIT_ASSERT(fromULong == fromRegion); + UNIT_ASSERT_VALUES_EQUAL(fromULong, fromRegion); + + const auto fromULongOther = TBigInteger::FromULong(22345678900); + UNIT_ASSERT(fromULong != fromULongOther); + } + + Y_UNIT_TEST(Decimal) { + UNIT_ASSERT_VALUES_EQUAL(TBigInteger::FromULong(123456789).ToDecimalString(), "123456789"); + } + + Y_UNIT_TEST(Region) { + const auto v1 = TBigInteger::FromULong(1234567890); + char buf[1024]; + const auto v2 = TBigInteger::FromRegion(buf, v1.ToRegion(buf)); + + UNIT_ASSERT_VALUES_EQUAL(v1, v2); + } + + Y_UNIT_TEST(Output) { + TStringStream ss; + + ss << TBigInteger::FromULong(123456789); + + UNIT_ASSERT_VALUES_EQUAL(ss.Str(), "123456789"); + } +} |