#include #include #include #include #include namespace fc { bigint::bigint( const char* bige, uint32_t l ) { n = BN_bin2bn( (const unsigned char*)bige, l, NULL ); } bigint::bigint( const std::vector& bige ) { n = BN_bin2bn( (const unsigned char*)bige.data(), bige.size(), NULL ); } bigint::bigint( BIGNUM* in ) { n = BN_dup(in); } bigint::bigint( ) :n(BN_new()) { } BIGNUM* bigint::dup()const { return BN_dup( n ); } bigint::bigint( unsigned long i ) :n(BN_new()) { BN_set_word( n, i ); } bigint::bigint( const bigint& c ) { n = BN_dup( c.n ); } bigint::bigint( bigint&& b ) { n = b.n; b.n = 0; } bigint::~bigint() { if(n!=0) BN_free(n); } bool bigint::is_negative()const { return BN_is_negative(n); } int64_t bigint::to_int64()const { return BN_get_word(n); } int64_t bigint::log2()const { return BN_num_bits(n); } bool bigint::operator < ( const bigint& c )const { return BN_cmp( n, c.n ) < 0; } bool bigint::operator > ( const bigint& c )const { return BN_cmp( n, c.n ) > 0; } bool bigint::operator >= ( const bigint& c )const { return BN_cmp( n, c.n ) >= 0; } bool bigint::operator == ( const bigint& c )const { return BN_cmp( n, c.n ) == 0; } bool bigint::operator != ( const bigint& c )const { return BN_cmp( n, c.n ) == 0; } bigint::operator bool()const { return !BN_is_zero( n ); } bigint bigint::operator++(int) { bigint tmp = *this; *this = *this + bigint(1); return tmp; } bigint& bigint::operator++() { return *this = *this + bigint(1); } bigint bigint::operator--(int) { bigint tmp = *this; *this = *this - bigint(1); return tmp; } bigint& bigint::operator--() { return *this = *this - bigint(1); } bigint bigint::operator + ( const bigint& a )const { bigint tmp(*this); BN_add( tmp.n, n, a.n ); return tmp; } bigint& bigint::operator += ( const bigint& a ){ bigint tmp(*this); BN_add( tmp.n, n, a.n ); std::swap(*this,tmp); return *this; } bigint bigint::operator * ( const bigint& a )const { BN_CTX* ctx = BN_CTX_new(); bigint tmp(*this); BN_mul( tmp.n, n, a.n, ctx ); BN_CTX_free(ctx); return tmp; } bigint bigint::operator / ( const bigint& a ) const { BN_CTX* ctx = BN_CTX_new(); bigint tmp;//(*this); BN_div( tmp.n, NULL, n, a.n, ctx ); BN_CTX_free(ctx); return tmp; } bigint bigint::operator % ( const bigint& a ) const { BN_CTX* ctx = BN_CTX_new(); bigint tmp;//(*this); BN_mod( tmp.n, n, a.n, ctx ); BN_CTX_free(ctx); return tmp; } bigint bigint::operator /= ( const bigint& a ) { BN_CTX* ctx = BN_CTX_new(); bigint tmp;//*this); BN_div( tmp.n, NULL, n, a.n, ctx ); fc_swap( tmp.n, n ); BN_CTX_free(ctx); return tmp; } bigint bigint::operator *= ( const bigint& a ) { auto tmp = *this * a; *this = std::move(tmp); return *this; } bigint& bigint::operator <<= ( uint32_t i ) { bigint tmp; BN_lshift( tmp.n, n, i ); std::swap(*this,tmp); return *this; } bigint bigint::operator - ( const bigint& a )const { bigint tmp; BN_sub( tmp.n, n, a.n ); return tmp; } bigint bigint::exp( const bigint& a )const { BN_CTX* ctx = BN_CTX_new(); bigint tmp; BN_exp( tmp.n, n, a.n, ctx ); BN_CTX_free(ctx); return tmp; } bigint& bigint::operator = ( bigint&& a ) { fc_swap( a.n, n ); return *this; } bigint& bigint::operator = ( const bigint& a ) { if( &a == this ) return *this; BN_copy( n, a.n ); return *this; } bigint::operator fc::string()const { return BN_bn2dec(n); } bigint::operator std::vector()const { std::vector to(BN_num_bytes(n)); BN_bn2bin(n,(unsigned char*)to.data()); return to; } /** encodes the big int as base64 string, or a number */ void to_variant( const bigint& bi, variant& v ) { std::vector ve = bi; v = fc::variant(base64_encode((unsigned char*)ve.data(),ve.size())); } /** decodes the big int as base64 string, or a number */ void from_variant( const variant& v, bigint& bi ) { if( v.is_numeric() ) bi = bigint( static_cast(v.as_uint64()) ); else { std::string b64 = v.as_string(); std::string bin = base64_decode(b64); bi = bigint(bin.c_str(), bin.size() ); } } } // namespace fc