|
@@ -0,0 +1,61 @@
|
|
|
+#include "big_integer.h"
|
|
|
+
|
|
|
+#include <util/generic/yexception.h>
|
|
|
+#include <util/generic/scope.h>
|
|
|
+#include <util/stream/output.h>
|
|
|
+
|
|
|
+#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();
|
|
|
+}
|