mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
initial commit
This commit is contained in:
commit
c2da007f40
1610 changed files with 398047 additions and 0 deletions
368
crypto/openssl/bignum.h
Normal file
368
crypto/openssl/bignum.h
Normal file
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include "td/utils/bits.h"
|
||||
|
||||
namespace arith {
|
||||
struct dec_string {
|
||||
std::string str;
|
||||
explicit dec_string(const std::string& s) : str(s) {
|
||||
}
|
||||
};
|
||||
|
||||
struct hex_string {
|
||||
std::string str;
|
||||
explicit hex_string(const std::string& s) : str(s) {
|
||||
}
|
||||
};
|
||||
} // namespace arith
|
||||
|
||||
namespace arith {
|
||||
|
||||
inline void bn_assert(int cond);
|
||||
BN_CTX* get_ctx();
|
||||
|
||||
class BignumBitref {
|
||||
BIGNUM* ptr;
|
||||
int n;
|
||||
|
||||
public:
|
||||
BignumBitref(BIGNUM* x, int _n) : ptr(x), n(_n){};
|
||||
operator bool() const {
|
||||
return BN_is_bit_set(ptr, n);
|
||||
}
|
||||
BignumBitref& operator=(bool val);
|
||||
};
|
||||
|
||||
class Bignum {
|
||||
BIGNUM* val;
|
||||
|
||||
public:
|
||||
class bignum_error {};
|
||||
Bignum() {
|
||||
val = BN_new();
|
||||
}
|
||||
Bignum(long x) {
|
||||
val = BN_new();
|
||||
set_long(x);
|
||||
}
|
||||
~Bignum() {
|
||||
BN_free(val);
|
||||
}
|
||||
Bignum(const dec_string& ds) {
|
||||
val = BN_new();
|
||||
set_dec_str(ds.str);
|
||||
}
|
||||
Bignum(const hex_string& hs) {
|
||||
val = BN_new();
|
||||
set_hex_str(hs.str);
|
||||
}
|
||||
Bignum(const Bignum& x) {
|
||||
val = BN_new();
|
||||
BN_copy(val, x.val);
|
||||
}
|
||||
//Bignum (Bignum&& x) { val = x.val; }
|
||||
void clear() {
|
||||
BN_clear(val);
|
||||
} // use this for sensitive data
|
||||
Bignum& operator=(const Bignum& x) {
|
||||
BN_copy(val, x.val);
|
||||
return *this;
|
||||
}
|
||||
Bignum& operator=(Bignum&& x) {
|
||||
swap(x);
|
||||
return *this;
|
||||
}
|
||||
Bignum& operator=(long x) {
|
||||
return set_long(x);
|
||||
}
|
||||
Bignum& operator=(const dec_string& ds) {
|
||||
return set_dec_str(ds.str);
|
||||
}
|
||||
Bignum& operator=(const hex_string& hs) {
|
||||
return set_hex_str(hs.str);
|
||||
}
|
||||
Bignum& swap(Bignum& x) {
|
||||
BN_swap(val, x.val);
|
||||
return *this;
|
||||
}
|
||||
BIGNUM* bn_ptr() {
|
||||
return val;
|
||||
}
|
||||
const BIGNUM* bn_ptr() const {
|
||||
return val;
|
||||
}
|
||||
bool is_zero() const {
|
||||
return BN_is_zero(val);
|
||||
}
|
||||
int sign() const {
|
||||
return BN_is_zero(val) ? 0 : (BN_is_negative(val) ? -1 : 1);
|
||||
}
|
||||
bool odd() const {
|
||||
return BN_is_odd(val);
|
||||
}
|
||||
int num_bits() const {
|
||||
return BN_num_bits(val);
|
||||
}
|
||||
int num_bytes() const {
|
||||
return BN_num_bytes(val);
|
||||
}
|
||||
bool operator[](int n) const {
|
||||
return BN_is_bit_set(val, n);
|
||||
}
|
||||
BignumBitref operator[](int n) {
|
||||
return BignumBitref(val, n);
|
||||
}
|
||||
void export_msb(unsigned char* buffer, std::size_t size) const;
|
||||
Bignum& import_msb(const unsigned char* buffer, std::size_t size);
|
||||
Bignum& import_msb(const std::string& s) {
|
||||
return import_msb((const unsigned char*)s.c_str(), s.size());
|
||||
}
|
||||
void export_lsb(unsigned char* buffer, std::size_t size) const;
|
||||
Bignum& import_lsb(const unsigned char* buffer, std::size_t size);
|
||||
Bignum& import_lsb(const std::string& s) {
|
||||
return import_lsb((const unsigned char*)s.c_str(), s.size());
|
||||
}
|
||||
|
||||
Bignum& set_dec_str(std::string s) {
|
||||
bn_assert(BN_dec2bn(&val, s.c_str()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& set_hex_str(std::string s) {
|
||||
bn_assert(BN_hex2bn(&val, s.c_str()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& set_ulong(unsigned long x) {
|
||||
bn_assert(BN_set_word(val, x));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& set_long(long x) {
|
||||
set_ulong(std::abs(x));
|
||||
return x < 0 ? negate() : *this;
|
||||
}
|
||||
|
||||
Bignum& negate() {
|
||||
BN_set_negative(val, !BN_is_negative(val));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator+=(const Bignum& y) {
|
||||
bn_assert(BN_add(val, val, y.val));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator+=(long y) {
|
||||
bn_assert((y >= 0 ? BN_add_word : BN_sub_word)(val, std::abs(y)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator-=(long y) {
|
||||
bn_assert((y >= 0 ? BN_sub_word : BN_add_word)(val, std::abs(y)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator*=(const Bignum& y) {
|
||||
bn_assert(BN_mul(val, val, y.val, get_ctx()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator*=(long y) {
|
||||
if (y < 0) {
|
||||
negate();
|
||||
}
|
||||
bn_assert(BN_mul_word(val, std::abs(y)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator<<=(int r) {
|
||||
bn_assert(BN_lshift(val, val, r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator>>=(int r) {
|
||||
bn_assert(BN_rshift(val, val, r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator/=(const Bignum& y) {
|
||||
Bignum w;
|
||||
bn_assert(BN_div(val, w.val, val, y.val, get_ctx()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator/=(long y) {
|
||||
bn_assert(BN_div_word(val, std::abs(y)) != (BN_ULONG)(-1));
|
||||
return y < 0 ? negate() : *this;
|
||||
}
|
||||
|
||||
Bignum& operator%=(const Bignum& y) {
|
||||
bn_assert(BN_mod(val, val, y.val, get_ctx()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bignum& operator%=(long y) {
|
||||
BN_ULONG rem = BN_mod_word(val, std::abs(y));
|
||||
bn_assert(rem != (BN_ULONG)(-1));
|
||||
return set_long(static_cast<long>(y < 0 ? td::bits_negate64(rem) : rem));
|
||||
}
|
||||
|
||||
unsigned long divmod(unsigned long y) {
|
||||
BN_ULONG rem = BN_div_word(val, y);
|
||||
bn_assert(rem != (BN_ULONG)(-1));
|
||||
return static_cast<unsigned long>(rem);
|
||||
}
|
||||
|
||||
const Bignum divmod(const Bignum& y);
|
||||
|
||||
std::string to_str() const;
|
||||
std::string to_hex() const;
|
||||
};
|
||||
|
||||
inline void bn_assert(int cond) {
|
||||
if (!cond) {
|
||||
throw Bignum::bignum_error();
|
||||
}
|
||||
}
|
||||
|
||||
BN_CTX* get_ctx(void);
|
||||
|
||||
const Bignum operator+(const Bignum& x, const Bignum& y);
|
||||
const Bignum operator+(const Bignum& x, long y);
|
||||
|
||||
/*
|
||||
const Bignum operator+ (Bignum&& x, long y) {
|
||||
if (y > 0) {
|
||||
bn_assert (BN_add_word (x.bn_ptr(), y));
|
||||
} else if (y < 0) {
|
||||
bn_assert (BN_sub_word (x.bn_ptr(), -y));
|
||||
}
|
||||
return std::move (x);
|
||||
}
|
||||
*/
|
||||
|
||||
inline const Bignum operator+(long y, const Bignum& x) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
/*
|
||||
const Bignum operator+ (long y, Bignum&& x) {
|
||||
return x + y;
|
||||
}
|
||||
*/
|
||||
|
||||
const Bignum operator-(const Bignum& x, const Bignum& y);
|
||||
inline const Bignum operator-(const Bignum& x, long y) {
|
||||
return x + (-y);
|
||||
}
|
||||
|
||||
/*
|
||||
const Bignum operator- (Bignum&& x, long y) {
|
||||
return x + (-y);
|
||||
}
|
||||
*/
|
||||
|
||||
const Bignum operator*(const Bignum& x, const Bignum& y);
|
||||
const Bignum operator*(const Bignum& x, long y);
|
||||
|
||||
/*
|
||||
const Bignum operator* (Bignum&& x, long y) {
|
||||
if (y > 0) {
|
||||
bn_assert (BN_mul_word (x.bn_ptr(), y));
|
||||
} else if (y < 0) {
|
||||
x.negate();
|
||||
bn_assert (BN_mul_word (x.bn_ptr(), -y));
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
return std::move (x);
|
||||
}
|
||||
*/
|
||||
|
||||
inline const Bignum operator*(long y, const Bignum& x) {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
const Bignum operator/(const Bignum& x, const Bignum& y);
|
||||
const Bignum operator%(const Bignum& x, const Bignum& y);
|
||||
unsigned long operator%(const Bignum& x, unsigned long y);
|
||||
|
||||
const Bignum operator<<(const Bignum& x, int r);
|
||||
const Bignum operator>>(const Bignum& x, int r);
|
||||
|
||||
const Bignum abs(const Bignum& x);
|
||||
const Bignum sqr(const Bignum& x);
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Bignum& x);
|
||||
std::istream& operator>>(std::istream& is, Bignum& x);
|
||||
|
||||
bool is_prime(const Bignum& p, int nchecks = 64, bool trial_div = true);
|
||||
|
||||
inline int cmp(const Bignum& x, const Bignum& y) {
|
||||
return BN_cmp(x.bn_ptr(), y.bn_ptr());
|
||||
}
|
||||
|
||||
inline bool operator==(const Bignum& x, const Bignum& y) {
|
||||
return cmp(x, y) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const Bignum& x, const Bignum& y) {
|
||||
return cmp(x, y) != 0;
|
||||
}
|
||||
|
||||
inline bool operator<(const Bignum& x, const Bignum& y) {
|
||||
return cmp(x, y) < 0;
|
||||
}
|
||||
|
||||
inline bool operator<=(const Bignum& x, const Bignum& y) {
|
||||
return cmp(x, y) <= 0;
|
||||
}
|
||||
|
||||
inline bool operator>(const Bignum& x, const Bignum& y) {
|
||||
return cmp(x, y) > 0;
|
||||
}
|
||||
|
||||
inline bool operator>=(const Bignum& x, const Bignum& y) {
|
||||
return cmp(x, y) >= 0;
|
||||
}
|
||||
|
||||
inline bool operator==(const Bignum& x, long y) {
|
||||
if (y >= 0) {
|
||||
return BN_is_word(x.bn_ptr(), y);
|
||||
} else {
|
||||
return x == Bignum(y);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool operator!=(const Bignum& x, long y) {
|
||||
if (y >= 0) {
|
||||
return !BN_is_word(x.bn_ptr(), y);
|
||||
} else {
|
||||
return x != Bignum(y);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace arith
|
Loading…
Add table
Add a link
Reference in a new issue