This commit is contained in:
Daniel Larimer 2015-09-11 08:55:02 -04:00
commit 483b348878
50 changed files with 1453 additions and 346 deletions

2
.gitmodules vendored
View file

@ -1,6 +1,6 @@
[submodule "vendor/secp256k1-zkp"]
path = vendor/secp256k1-zkp
url = https://github.com/ElementsProject/secp256k1-zkp.git
url = https://github.com/cryptonomex/secp256k1-zkp.git
[submodule "vendor/websocketpp"]
path = vendor/websocketpp
url = https://github.com/zaphoyd/websocketpp.git

View file

@ -189,6 +189,7 @@ set( fc_sources
src/log/file_appender.cpp
src/log/gelf_appender.cpp
src/log/logger_config.cpp
src/crypto/_digest_common.cpp
src/crypto/openssl.cpp
src/crypto/aes.cpp
src/crypto/crc.cpp
@ -322,23 +323,23 @@ add_executable( api tests/api.cpp )
target_link_libraries( api fc )
if( ECC_IMPL STREQUAL secp256k1 )
add_executable( blind tests/blind.cpp )
add_executable( blind tests/all_tests.cpp tests/crypto/blind.cpp )
target_link_libraries( blind fc )
endif()
include_directories( vendor/websocketpp )
add_executable( ntp_test ntp_test.cpp )
add_executable( ntp_test tests/all_tests.cpp tests/network/ntp_test.cpp )
target_link_libraries( ntp_test fc )
add_executable( task_cancel_test tests/task_cancel.cpp )
add_executable( task_cancel_test tests/all_tests.cpp tests/thread/task_cancel.cpp )
target_link_libraries( task_cancel_test fc )
add_executable( bloom_test tests/bloom_test.cpp )
add_executable( bloom_test tests/all_tests.cpp tests/bloom_test.cpp )
target_link_libraries( bloom_test fc )
add_executable( real128_test tests/real128_test.cpp )
add_executable( real128_test tests/all_tests.cpp tests/real128_test.cpp )
target_link_libraries( real128_test fc )
@ -348,11 +349,9 @@ target_link_libraries( udt_server fc udt )
add_executable( udt_client tests/udtc.cpp )
target_link_libraries( udt_client fc udt )
add_executable( ecc_test tests/ecc_test.cpp )
add_executable( ecc_test tests/crypto/ecc_test.cpp )
target_link_libraries( ecc_test fc )
#add_executable( test_compress tests/compress.cpp )
#target_link_libraries( test_compress fc )
#add_executable( test_aes tests/aes_test.cpp )
#target_link_libraries( test_aes fc ${rt_library} ${pthread_library} )
#add_executable( test_sleep tests/sleep.cpp )
@ -360,6 +359,25 @@ target_link_libraries( ecc_test fc )
#add_executable( test_rate_limiting tests/rate_limiting.cpp )
#target_link_libraries( test_rate_limiting fc )
add_executable( all_tests tests/all_tests.cpp
tests/compress/compress.cpp
tests/crypto/aes_test.cpp
tests/crypto/base_n_tests.cpp
tests/crypto/bigint_test.cpp
tests/crypto/blind.cpp
tests/crypto/blowfish_test.cpp
tests/crypto/dh_test.cpp
tests/crypto/rand_test.cpp
tests/crypto/sha_tests.cpp
tests/network/ntp_test.cpp
tests/network/http/websocket_test.cpp
tests/thread/task_cancel.cpp
tests/bloom_test.cpp
tests/real128_test.cpp
tests/utf8_test.cpp
)
target_link_libraries( all_tests fc )
if(WIN32)
# add addtional import library on windows platform
target_link_libraries( fc PUBLIC crypt32.lib)

View file

@ -22,8 +22,8 @@ your system.
Testing
-------
Type "make ecc_test" to build the ecc_test executable from tests/ecc_test.cpp
with the currently configured ECC implementation.
Type "make ecc_test" to build the ecc_test executable from
tests/crypto/ecc_test.cpp with the currently configured ECC implementation.
ecc_test expects two arguments:
@ -38,6 +38,6 @@ If the file does exist, intermediate results from the current ECC backend
are compared with the file contents.
For a full round of interoperability testing, you can use the script
tests/ecc-interop.sh .
tests/crypto/ecc-interop.sh .
None of the test runs should produce any output.

View file

@ -1,11 +1,12 @@
#pragma once
#include <fc/crypto/openssl.hpp>
#include <vector>
#include <stdint.h>
namespace fc {
struct diffie_hellman {
diffie_hellman():valid(0),g(5){}
diffie_hellman():valid(0),g(5){ fc::init_openssl(); }
bool generate_params( int s, uint8_t g );
bool generate_pub_key();
bool compute_shared_key( const char* buf, uint32_t s );

View file

@ -22,11 +22,10 @@ namespace fc
{
ssl_wrapper(ssl_type* obj):obj(obj) {}
operator ssl_type*()
{
return obj;
}
operator ssl_type*() { return obj; }
operator const ssl_type*() const { return obj; }
ssl_type* operator->() { return obj; }
const ssl_type* operator->() const { return obj; }
ssl_type* obj;
};

View file

@ -70,6 +70,10 @@ namespace fc
exception( log_messages&&, int64_t code = unspecified_exception_code,
const std::string& name_value = "exception",
const std::string& what_value = "unspecified");
exception( const log_messages&,
int64_t code = unspecified_exception_code,
const std::string& name_value = "exception",
const std::string& what_value = "unspecified");
exception( const exception& e );
exception( exception&& e );
~exception();
@ -232,6 +236,10 @@ namespace fc
:BASE( std::move(m), code, name_value, what_value ){} \
explicit TYPE( fc::log_messages&& m, int64_t code, const std::string& name_value, const std::string& what_value )\
:BASE( std::move(m), code, name_value, what_value ){}\
explicit TYPE( const fc::log_messages& m, int64_t code, const std::string& name_value, const std::string& what_value )\
:BASE( m, code, name_value, what_value ){}\
TYPE( const std::string& what_value, const fc::log_messages& m ) \
:BASE( m, CODE, BOOST_PP_STRINGIZE(TYPE), what_value ){} \
TYPE( fc::log_message&& m ) \
:BASE( fc::move(m), CODE, BOOST_PP_STRINGIZE(TYPE), WHAT ){}\
TYPE( fc::log_messages msgs ) \

View file

@ -47,4 +47,11 @@ namespace fc {
fc::shared_ptr<impl> my;
};
/**
* Grab the full contents of a file into a string object.
* NB reading a full file into memory is a poor choice
* if the file may be very large.
*/
void read_file_contents( const fc::path& filename, std::string& result );
} // namespace fc

View file

@ -22,15 +22,15 @@ namespace fc {
public:
typedef typename std::function<Signature>::result_type result_type;
callback_functor( fc::api_connection& con, uint64_t id )
callback_functor( std::weak_ptr< fc::api_connection > con, uint64_t id )
:_callback_id(id),_api_connection(con){}
template<typename... Args>
result_type operator()( Args... args )const;
private:
uint64_t _callback_id;
fc::api_connection& _api_connection;
uint64_t _callback_id;
std::weak_ptr< fc::api_connection > _api_connection;
};
template<typename R, typename Arg0, typename ... Args>
@ -91,8 +91,18 @@ namespace fc {
return _methods[method_id](args);
}
fc::api_connection& get_connection(){ auto tmp = _api_connection.lock(); FC_ASSERT( tmp, "connection closed"); return *tmp; }
std::weak_ptr< fc::api_connection > get_connection()
{
return _api_connection;
}
std::vector<std::string> get_method_names()const
{
std::vector<std::string> result;
result.reserve( _by_name.size() );
for( auto& m : _by_name ) result.push_back(m.first);
return result;
}
private:
friend struct api_visitor;
@ -221,9 +231,11 @@ namespace fc {
return _local_callbacks.size() - 1;
}
std::vector<std::string> get_method_names( api_id_type local_api_id = 0 )const { return _local_apis[local_api_id]->get_method_names(); }
fc::signal<void()> closed;
private:
std::vector< std::unique_ptr<generic_api> > _local_apis;
std::vector< std::unique_ptr<generic_api> > _local_apis;
std::map< uint64_t, api_id_type > _handle_to_id;
std::vector< std::function<variant(const variants&)> > _local_callbacks;
@ -382,7 +394,11 @@ namespace fc {
template<typename... Args>
typename callback_functor<Signature>::result_type callback_functor<Signature>::operator()( Args... args )const
{
_api_connection.send_callback( _callback_id, fc::variants{ args... } ).template as< result_type >();
std::shared_ptr< fc::api_connection > locked = _api_connection.lock();
// TODO: make new exception type for this instead of recycling eof_exception
if( !locked )
throw fc::eof_exception();
locked->send_callback( _callback_id, fc::variants{ args... } ).template as< result_type >();
}
@ -392,17 +408,21 @@ namespace fc {
public:
typedef void result_type;
callback_functor( fc::api_connection& con, uint64_t id )
callback_functor( std::weak_ptr< fc::api_connection > con, uint64_t id )
:_callback_id(id),_api_connection(con){}
void operator()( Args... args )const
{
_api_connection.send_notice( _callback_id, fc::variants{ args... } );
std::shared_ptr< fc::api_connection > locked = _api_connection.lock();
// TODO: make new exception type for this instead of recycling eof_exception
if( !locked )
throw fc::eof_exception();
locked->send_notice( _callback_id, fc::variants{ args... } );
}
private:
uint64_t _callback_id;
fc::api_connection& _api_connection;
uint64_t _callback_id;
std::weak_ptr< fc::api_connection > _api_connection;
};
} // namespace detail

View file

@ -176,6 +176,14 @@ namespace fc
set(std::move(key), variant( fc::forward<T>(var) ) );
return *this;
}
/**
* Copy a variant_object into this mutable_variant_object.
*/
mutable_variant_object& operator()( const variant_object& vo );
/**
* Copy another mutable_variant_object into this mutable_variant_object.
*/
mutable_variant_object& operator()( const mutable_variant_object& mvo );
///@}

View file

@ -1,28 +0,0 @@
#include <fc/network/ntp.hpp>
#include <fc/log/logger.hpp>
#include <fc/thread/thread.hpp>
int main( int argc, char** argv )
{
fc::ntp ntp_service;
ntp_service.set_request_interval(5);
fc::usleep(fc::seconds(4) );
auto time = ntp_service.get_time();
if( time )
{
auto ntp_time = *time;
auto delta = ntp_time - fc::time_point::now();
auto minutes = delta.count() / 1000000 / 60;
auto hours = delta.count() / 1000000 / 60 / 60;
auto seconds = delta.count() / 1000000;
auto msec= delta.count() / 1000;
idump( (fc::time_point::now() ) );
idump( (ntp_time)(delta)(msec)(seconds)(minutes)(hours) );
}
else
{
elog( "no response" );
}
return 0;
}

View file

@ -0,0 +1,29 @@
#include <fc/exception/exception.hpp>
#include "_digest_common.hpp"
namespace fc { namespace detail {
static void shift_l( const uint8_t* in, uint8_t* out, std::size_t n, unsigned int i) {
if (i < n) {
memcpy( out, in + i, n-i );
} else {
i = n;
}
memset( out + (n-i), 0, i );
}
void shift_l( const char* in, char* out, std::size_t n, unsigned int i) {
const uint8_t* in8 = (uint8_t*) in;
uint8_t* out8 = (uint8_t*) out;
if (i >= 8) {
shift_l( in8, out8, n, i >> 3 );
i &= 7;
in8 = out8;
}
std::size_t p;
for( p = 0; p < n-1; ++p )
out8[p] = (in8[p] << i) | (in8[p+1]>>(8-i));
out8[p] = in8[p] << i;
}
}}

View file

@ -0,0 +1,7 @@
#pragma once
/* Common stuff for cryptographic hashes
*/
namespace fc { namespace detail {
void shift_l( const char* in, char* out, std::size_t n, unsigned int i);
}}

View file

@ -7,16 +7,17 @@ namespace fc
{
auto len = cyoBase32DecodeGetLength( b32.size() );
std::vector<char> v(len);
cyoBase32Decode( v.data(), b32.c_str(), b32.size() );
len = cyoBase32Decode( v.data(), b32.c_str(), b32.size() );
v.resize( len );
return v;
}
std::string to_base32( const char* data, size_t len )
{
auto s = cyoBase16EncodeGetLength(len);
auto s = cyoBase32EncodeGetLength(len);
std::vector<char> b32;
b32.resize(s);
cyoBase16Encode( b32.data(), data, len );
cyoBase32Encode( b32.data(), data, len );
b32.resize( b32.size()-1); // strip the nullterm
return std::string(b32.begin(),b32.end());
}

View file

@ -1,3 +1,4 @@
#include <memory>
#include <fc/crypto/bigint.hpp>
#include <fc/io/sstream.hpp>
#include <fc/log/logger.hpp>
@ -7,9 +8,20 @@ namespace fc
fc::string to_base36( const char* data, size_t len )
{
if( len == 0 ) return fc::string();
fc::bigint value( data, len );
const char* src = data;
int src_len = len;
std::unique_ptr<char[]> buffer(new char[len+1]);
if (*data & 0x80) {
buffer[0] = 0;
memcpy( buffer.get() + 1, data, len );
src = buffer.get();
src_len++;
}
fc::bigint value( src, src_len );
auto base36 = "0123456789abcdefghijklmnopqrstuvwxyz";
std::vector<char> out( static_cast<size_t>(len * 1.6) + 1 );
std::vector<char> out( static_cast<size_t>(len * 1.6) + 2 );
int pos = out.size() - 1;
out[pos] = '\0';
fc::bigint _36(36);
@ -19,7 +31,9 @@ namespace fc
out[pos] = base36[(value % _36).to_int64()];
}
} while (value /= _36);
while (len-- > 0 && *data++ == 0) {
out[--pos] = '0';
}
return &out[pos]; //fc::string( &out[pos], out.size() - pos);
}
@ -30,21 +44,39 @@ namespace fc
std::vector<char> from_base36( const fc::string& b36 )
{
if ( b36.empty() ) {
std::vector<char> empty;
return empty;
}
fc::bigint value;
fc::bigint pos = 0;
fc::bigint _36(36);
for( auto itr = b36.begin(); itr != b36.end(); ++itr )
for( auto itr = b36.rbegin(); itr != b36.rend(); ++itr )
{
if( *itr - '0' < 10 ) value = value + _36.exp(pos) * fc::bigint(*itr - '0');
else if( *itr - 'a' < 26 ) value = value + (_36.exp(pos) * fc::bigint(10+*itr - 'a'));
else if( *itr - 'A' < 26 ) value = value + (_36.exp(pos) * fc::bigint(10+*itr - 'A'));
if( *itr >= '0' && *itr <= '9' )
value = value + _36.exp(pos) * fc::bigint(*itr - '0');
else if( *itr >= 'a' && *itr <= 'z' )
value = value + (_36.exp(pos) * fc::bigint(10+*itr - 'a'));
else if( *itr >= 'A' && *itr <= 'Z' )
value = value + (_36.exp(pos) * fc::bigint(10+*itr - 'A'));
else
{
wlog("unknown '${char}'", ("char",fc::string(&*itr,1)) );
}
++pos;
}
return value;
std::vector<char> bytes = value;
int leading_zeros = 0, len = bytes.size();
const char *in = b36.c_str();
while (*in++ == '0') { leading_zeros++; }
char* first = bytes.data();
while (len > 0 && *first == 0) { first++; len--; }
std::vector<char> result;
result.resize(leading_zeros + len, 0);
memcpy( result.data() + leading_zeros, first, len );
return result;
}
}

View file

@ -631,7 +631,7 @@ size_t from_base58( const std::string& base58_str, char* out_data, size_t out_da
if( !DecodeBase58( base58_str.c_str(), out ) ) {
FC_THROW_EXCEPTION( parse_error_exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) );
}
FC_ASSERT( out.size() <= out_data_len );
memcpy( out_data, out.data(), out.size() );
return out.size();
}

View file

@ -2,52 +2,45 @@
#include <openssl/dh.h>
namespace fc {
SSL_TYPE(ssl_dh, DH, DH_free)
static bool validate( const ssl_dh& dh, bool& valid ) {
int check;
DH_check(dh,&check);
return valid = !(check /*& DH_CHECK_P_NOT_SAFE_PRIME*/);
}
bool diffie_hellman::generate_params( int s, uint8_t g )
{
DH* dh = DH_generate_parameters( s, g, NULL, NULL );
ssl_dh dh = DH_generate_parameters( s, g, NULL, NULL );
p.resize( BN_num_bytes( dh->p ) );
if( p.size() )
BN_bn2bin( dh->p, (unsigned char*)&p.front() );
this->g = g;
int check;
DH_check(dh,&check);
DH_free(dh);
if( check & DH_CHECK_P_NOT_SAFE_PRIME )
return valid = false;
return valid = true;
return fc::validate( dh, valid );
}
bool diffie_hellman::validate()
{
if( !p.size() )
return valid = false;
DH* dh = DH_new();
ssl_dh dh = DH_new();
dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
dh->g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
int check;
DH_check(dh,&check);
DH_free(dh);
if( check & DH_CHECK_P_NOT_SAFE_PRIME )
return valid = false;
return valid = true;
return fc::validate( dh, valid );
}
bool diffie_hellman::generate_pub_key()
{
if( !p.size() )
return valid = false;
DH* dh = DH_new();
ssl_dh dh = DH_new();
dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
dh->g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
int check;
DH_check(dh,&check);
if( check & DH_CHECK_P_NOT_SAFE_PRIME )
if( !fc::validate( dh, valid ) )
{
DH_free(dh);
return valid = false;
return false;
}
DH_generate_key(dh);
@ -58,11 +51,10 @@ namespace fc {
if( priv_key.size() )
BN_bn2bin( dh->priv_key, (unsigned char*)&priv_key.front() );
DH_free(dh);
return valid = true;
return true;
}
bool diffie_hellman::compute_shared_key( const char* buf, uint32_t s ) {
DH* dh = DH_new();
ssl_dh dh = DH_new();
dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
dh->pub_key = BN_bin2bn( (unsigned char*)&pub_key.front(), pub_key.size(), NULL );
dh->priv_key = BN_bin2bn( (unsigned char*)&priv_key.front(), priv_key.size(), NULL );
@ -70,22 +62,19 @@ namespace fc {
int check;
DH_check(dh,&check);
if( check & DH_CHECK_P_NOT_SAFE_PRIME )
if( !fc::validate( dh, valid ) )
{
DH_free(dh);
return valid = false;
return false;
}
BIGNUM* pk = BN_bin2bn( (unsigned char*)buf, s, NULL );
ssl_bignum pk;
BN_bin2bn( (unsigned char*)buf, s, pk );
shared_key.resize( DH_size(dh) );
DH_compute_key( (unsigned char*)&shared_key.front(), pk, dh );
BN_free(pk);
DH_free(dh);
return valid = true;
return true;
}
bool diffie_hellman::compute_shared_key( const std::vector<char>& pubk ) {
return compute_shared_key( &pubk.front(), pubk.size() );
}
}

View file

@ -8,6 +8,7 @@
#include <fc/crypto/sha256.hpp>
#include <fc/variant.hpp>
#include <vector>
#include "_digest_common.hpp"
namespace fc
{
@ -69,11 +70,7 @@ void ripemd160::encoder::reset() {
ripemd160 operator << ( const ripemd160& h1, uint32_t i ) {
ripemd160 result;
uint8_t* r = (uint8_t*)result._hash;
uint8_t* s = (uint8_t*)h1._hash;
for( uint32_t p = 0; p < sizeof(h1._hash)-1; ++p )
r[p] = s[p] << i | (s[p+1]>>(8-i));
r[19] = s[19] << i;
fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i );
return result;
}
ripemd160 operator ^ ( const ripemd160& h1, const ripemd160& h2 ) {

View file

@ -5,6 +5,7 @@
#include <fc/crypto/sha1.hpp>
#include <fc/variant.hpp>
#include <vector>
#include "_digest_common.hpp"
namespace fc
{
@ -54,11 +55,7 @@ void sha1::encoder::reset() {
sha1 operator << ( const sha1& h1, uint32_t i ) {
sha1 result;
uint8_t* r = (uint8_t*)result._hash;
uint8_t* s = (uint8_t*)h1._hash;
for( uint32_t p = 0; p < sizeof(h1._hash)-1; ++p )
r[p] = s[p] << i | (s[p+1]>>(8-i));
r[19] = s[19] << i;
fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i );
return result;
}
sha1 operator ^ ( const sha1& h1, const sha1& h2 ) {

View file

@ -4,7 +4,8 @@
#include <string.h>
#include <fc/crypto/sha224.hpp>
#include <fc/variant.hpp>
#include "_digest_common.hpp"
namespace fc {
sha224::sha224() { memset( _hash, 0, sizeof(_hash) ); }
@ -52,11 +53,7 @@ namespace fc {
sha224 operator << ( const sha224& h1, uint32_t i ) {
sha224 result;
uint8_t* r = (uint8_t*)&result;//result._hash;
uint8_t* s = (uint8_t*)&h1;//h1._hash;
for( uint32_t p = 0; p < sizeof(sha224)-1; ++p )
r[p] = s[p] << i | (s[p+1]>>(8-i));
r[sizeof(sha224)-1] = s[sizeof(sha224)-1] << i;
fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i );
return result;
}
sha224 operator ^ ( const sha224& h1, const sha224& h2 ) {

View file

@ -5,7 +5,8 @@
#include <fc/crypto/sha256.hpp>
#include <fc/variant.hpp>
#include <fc/exception/exception.hpp>
#include "_digest_common.hpp"
namespace fc {
sha256::sha256() { memset( _hash, 0, sizeof(_hash) ); }
@ -64,11 +65,7 @@ namespace fc {
sha256 operator << ( const sha256& h1, uint32_t i ) {
sha256 result;
uint8_t* r = (uint8_t*)result._hash;
uint8_t* s = (uint8_t*)h1._hash;
for( uint32_t p = 0; p < sizeof(h1._hash)-1; ++p )
r[p] = s[p] << i | (s[p+1]>>(8-i));
r[31] = s[31] << i;
fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i );
return result;
}
sha256 operator ^ ( const sha256& h1, const sha256& h2 ) {

View file

@ -4,6 +4,7 @@
#include <string.h>
#include <fc/crypto/sha512.hpp>
#include <fc/variant.hpp>
#include "_digest_common.hpp"
namespace fc {
@ -52,11 +53,7 @@ namespace fc {
sha512 operator << ( const sha512& h1, uint32_t i ) {
sha512 result;
uint8_t* r = (uint8_t*)result._hash;
uint8_t* s = (uint8_t*)h1._hash;
for( uint32_t p = 0; p < sizeof(h1._hash)-1; ++p )
r[p] = s[p] << i | (s[p+1]>>(8-i));
r[63] = s[63] << i;
fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i );
return result;
}
sha512 operator ^ ( const sha512& h1, const sha512& h2 ) {

View file

@ -50,6 +50,19 @@ namespace fc
my->_elog = fc::move(msgs);
}
exception::exception(
const log_messages& msgs,
int64_t code,
const std::string& name_value,
const std::string& what_value )
:my( new detail::exception_impl() )
{
my->_code = code;
my->_what = what_value;
my->_name = name_value;
my->_elog = msgs;
}
unhandled_exception::unhandled_exception( log_message&& m, std::exception_ptr e )
:exception( fc::move(m) )
{

View file

@ -1,7 +1,10 @@
#include <fc/io/fstream.hpp>
#include <fc/filesystem.hpp>
#include <fstream>
#include <sstream>
#include <fc/filesystem.hpp>
#include <fc/exception/exception.hpp>
#include <fc/io/fstream.hpp>
#include <fc/log/logger.hpp>
#include <boost/filesystem/path.hpp>
@ -93,5 +96,14 @@ namespace fc {
bool ifstream::eof()const { return !my->ifs.good(); }
void read_file_contents( const fc::path& filename, std::string& result )
{
const boost::filesystem::path& bfp = filename;
boost::filesystem::ifstream f( bfp, std::ios::in | std::ios::binary );
// don't use fc::stringstream here as we need something with override for << rdbuf()
std::stringstream ss;
ss << f.rdbuf();
result = ss.str();
}
} // namespace fc

View file

@ -38,6 +38,9 @@ namespace fc {
FC_ASSERT( cfg.rotation_interval >= seconds( 1 ) );
FC_ASSERT( cfg.rotation_limit >= cfg.rotation_interval );
_rotation_task = async( [this]() { rotate_files( true ); }, "rotate_files(1)" );
}
}
@ -79,7 +82,11 @@ namespace fc {
out.close();
}
remove_all(link_filename); // on windows, you can't delete the link while the underlying file is opened for writing
out.open( log_filename );
if( fc::exists( log_filename ) )
out.open( log_filename, std::ios_base::out | std::ios_base::app );
else
out.open( log_filename, std::ios_base::out | std::ios_base::app);
create_hard_link(log_filename, link_filename);
}
@ -138,7 +145,8 @@ namespace fc {
fc::create_directories(my->cfg.filename.parent_path());
if(!my->cfg.rotate)
my->out.open(my->cfg.filename);
my->out.open( my->cfg.filename, std::ios_base::out | std::ios_base::app);
}
catch( ... )
{

View file

@ -196,7 +196,11 @@ namespace fc { namespace http {
wdump(("server")(msg->get_payload()));
//std::cerr<<"recv: "<<msg->get_payload()<<"\n";
auto payload = msg->get_payload();
fc::async([=](){ current_con->second->on_message( payload ); });
std::shared_ptr<websocket_connection> con = current_con->second;
++_pending_messages;
auto f = fc::async([this,con,payload](){ if( _pending_messages ) --_pending_messages; con->on_message( payload ); });
if( _pending_messages > 100 ) f.wait();
}).wait();
});
@ -228,6 +232,8 @@ namespace fc { namespace http {
{
wlog( "unknown connection closed" );
}
if( _connections.empty() && _closed )
_closed->set_value();
}).wait();
});
@ -244,17 +250,25 @@ namespace fc { namespace http {
{
wlog( "unknown connection failed" );
}
if( _connections.empty() && _closed )
_closed->set_value();
}).wait();
}
});
}
~websocket_server_impl()
{
{
if( _server.is_listening() )
_server.stop_listening();
if( _connections.size() )
_closed = new fc::promise<void>();
auto cpy_con = _connections;
for( auto item : cpy_con )
_server.close( item.first, 0, "server exit" );
if( _closed ) _closed->wait();
}
typedef std::map<connection_hdl, websocket_connection_ptr,std::owner_less<connection_hdl> > con_map;
@ -264,6 +278,7 @@ namespace fc { namespace http {
websocket_server_type _server;
on_connection_handler _on_connection;
fc::promise<void>::ptr _closed;
uint32_t _pending_messages = 0;
};
class websocket_tls_server_impl
@ -305,8 +320,8 @@ namespace fc { namespace http {
auto current_con = _connections.find(hdl);
assert( current_con != _connections.end() );
auto received = msg->get_payload();
wdump((received));
fc::async([=](){ current_con->second->on_message( received ); });
std::shared_ptr<websocket_connection> con = current_con->second;
fc::async([con,received](){ con->on_message( received ); });
}).wait();
});

View file

@ -30,6 +30,12 @@
namespace fc { namespace rpc {
static std::vector<std::string>& cli_commands()
{
static std::vector<std::string>* cmds = new std::vector<std::string>();
return *cmds;
}
cli::~cli()
{
if( _run_complete.valid() )
@ -55,6 +61,7 @@ void cli::send_notice( uint64_t callback_id, variants args /* = variants() */ )
void cli::start()
{
cli_commands() = get_method_names(0);
_run_complete = fc::async( [&](){ run(); } );
}
@ -118,6 +125,57 @@ void cli::run()
}
}
char * dupstr (const char* s) {
char *r;
r = (char*) malloc ((strlen (s) + 1));
strcpy (r, s);
return (r);
}
char* my_generator(const char* text, int state)
{
static int list_index, len;
const char *name;
if (!state) {
list_index = 0;
len = strlen (text);
}
auto& cmd = cli_commands();
while( list_index < cmd.size() )
{
name = cmd[list_index].c_str();
list_index++;
if (strncmp (name, text, len) == 0)
return (dupstr(name));
}
/* If no names matched, then return NULL. */
return ((char *)NULL);
}
static char** cli_completion( const char * text , int start, int end)
{
char **matches;
matches = (char **)NULL;
#ifdef HAVE_READLINE
if (start == 0)
matches = rl_completion_matches ((char*)text, &my_generator);
else
rl_bind_key('\t',rl_abort);
#endif
return (matches);
}
void cli::getline( const fc::string& prompt, fc::string& line)
{
// getting file descriptor for C++ streams is near impossible
@ -134,6 +192,8 @@ void cli::getline( const fc::string& prompt, fc::string& line)
if( _isatty( _fileno( stdin ) ) )
#endif
{
rl_attempted_completion_function = cli_completion;
static fc::thread getline_thread("getline");
getline_thread.async( [&](){
char* line_read = nullptr;
@ -141,6 +201,7 @@ void cli::getline( const fc::string& prompt, fc::string& line)
line_read = readline(prompt.c_str());
if( line_read == nullptr )
FC_THROW_EXCEPTION( fc::eof_exception, "" );
rl_bind_key( '\t', rl_complete );
if( *line_read )
add_history(line_read);
line = line_read;

View file

@ -117,7 +117,7 @@ namespace fc {
return result.str();
}
uint32_t years_ago = days_ago / 365;
result << years_ago << " year" << (months_ago > 1 ? "s " : " ");
result << years_ago << " year" << (months_ago > 1 ? "s" : "");
if (months_ago < 12 * 5)
{
uint32_t leftover_days = days_ago - (years_ago * 365);

View file

@ -350,6 +350,22 @@ namespace fc
return *this;
}
mutable_variant_object& mutable_variant_object::operator()( const variant_object& vo )
{
for( const variant_object::entry& e : vo )
set( e.key(), e.value() );
return *this;
}
mutable_variant_object& mutable_variant_object::operator()( const mutable_variant_object& mvo )
{
if( &mvo == this ) // mvo(mvo) is no-op
return *this;
for( const mutable_variant_object::entry& e : mvo )
set( e.key(), e.value() );
return *this;
}
void to_variant( const mutable_variant_object& var, variant& vo )
{
vo = variant(var);

View file

@ -1,46 +0,0 @@
#include <iostream>
#include <fc/crypto/aes.hpp>
#include <fc/crypto/city.hpp>
#include <fc/exception/exception.hpp>
#include <fc/variant.hpp>
int main( int argc, char** )
{
std::string line;
std::getline( std::cin, line );
auto key = fc::sha512::hash( "hello", 5 );
while( std::cin && line != "q" )
{
try {
std::vector<char> data( line.c_str(),line.c_str()+line.size()+1 );
std::vector<char> crypt = fc::aes_encrypt( key, data );
std::vector<char> dcrypt = fc::aes_decrypt( key, crypt );
std::cout<<"line.size: '"<<line.size()<<"'\n";
std::cout<<"data.size: '"<<data.size()<<"'\n";
std::cout<<"crypt.size: '"<<crypt.size()<<"'\n";
std::cout<<"dcrypt.size: '"<<dcrypt.size()<<"'\n";
std::cout<<"line: '"<<line<<"'\n";
std::cout<<"dcrypt: '"<<dcrypt.data()<<"'\n";
std::cout<<"dcrypt: "<<fc::variant(dcrypt).as_string()<<"\n";
std::cout<<"crypt: "<<fc::variant(crypt).as_string()<<"\n";
memset( crypt.data(), 0, crypt.size() );
fc::aes_encoder enc;
enc.init( fc::sha256::hash((char*)&key,sizeof(key) ), fc::city_hash_crc_128( (char*)&key, sizeof(key) ) );
auto len = enc.encode( dcrypt.data(), dcrypt.size(), crypt.data() );
// enc.final_encode( crypt.data() + len );
std::cout<<"crypt: "<<fc::variant(crypt).as_string()<<"\n";
fc::aes_decoder dec;
dec.init( fc::sha256::hash((char*)&key,sizeof(key) ), fc::city_hash_crc_128( (char*)&key, sizeof(key) ) );
}
catch ( fc::exception& e )
{
std::cout<<e.to_detail_string()<<"\n";
}
std::getline( std::cin, line );
}
return 0;
}

3
tests/all_tests.cpp Normal file
View file

@ -0,0 +1,3 @@
#define BOOST_TEST_MODULE AllTests
#include <boost/test/unit_test.hpp>

View file

@ -1,3 +1,5 @@
#include <boost/test/unit_test.hpp>
#include <fc/bloom_filter.hpp>
#include <fc/exception/exception.hpp>
#include <fc/reflect/variant.hpp>
@ -10,10 +12,8 @@
using namespace fc;
int main( int argc, char** argv )
static bloom_parameters setup_parameters()
{
try {
bloom_parameters parameters;
// How many elements roughly do we expect to insert?
@ -27,25 +27,31 @@ int main( int argc, char** argv )
if (!parameters)
{
std::cout << "Error - Invalid set of bloom filter parameters!" << std::endl;
return 1;
BOOST_FAIL( "Error - Invalid set of bloom filter parameters!" );
}
parameters.compute_optimal_parameters();
//Instantiate Bloom Filter
bloom_filter filter(parameters);
return parameters;
}
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(bloom_test_1)
{
try {
//Instantiate Bloom Filter
bloom_filter filter(setup_parameters());
if( argc > 1 )
{
uint32_t count = 0;
std::string line;
std::ifstream in(argv[1]);
std::ifstream in("README.md");
std::ofstream words("words.txt");
while( !in.eof() && count < 100000 )
{
std::getline(in, line);
std::cout << "'"<<line<<"'\n";
// std::cout << "'"<<line<<"'\n";
if( !filter.contains(line) )
{
filter.insert( line );
@ -53,23 +59,29 @@ int main( int argc, char** argv )
++count;
}
}
wdump((filter));
// wdump((filter));
auto packed_filter = fc::raw::pack(filter);
wdump((packed_filter.size()));
wdump((packed_filter));
std::ofstream out(argv[2]);
std::string str = fc::json::to_string(packed_filter);
// wdump((packed_filter.size()));
// wdump((packed_filter));
std::stringstream out;
// std::string str = fc::json::to_string(packed_filter);
auto b64 = fc::base64_encode( packed_filter.data(), packed_filter.size() );
for( uint32_t i = 0; i < b64.size(); i += 1024 )
out << '"' << b64.substr( i, 1024 ) << "\",\n";
return 0;
}
catch ( const fc::exception& e )
{
edump((e.to_detail_string()) );
}
}
BOOST_AUTO_TEST_CASE(bloom_test_2)
{
try {
//Instantiate Bloom Filter
bloom_filter filter(setup_parameters());
std::string str_list[] = { "AbC", "iJk", "XYZ" };
std::string str_list[] = { "AbC", "iJk", "XYZ" };
// Insert into Bloom Filter
{
@ -91,19 +103,13 @@ int main( int argc, char** argv )
// Query the existence of strings
for (std::size_t i = 0; i < (sizeof(str_list) / sizeof(std::string)); ++i)
{
if (filter.contains(str_list[i]))
{
std::cout << "BF contains: " << str_list[i] << std::endl;
}
BOOST_CHECK( filter.contains(str_list[i]) );
}
// Query the existence of numbers
for (std::size_t i = 0; i < 100; ++i)
{
if (filter.contains(i))
{
std::cout << "BF contains: " << i << std::endl;
}
BOOST_CHECK( filter.contains(i) );
}
std::string invalid_str_list[] = { "AbCX", "iJkX", "XYZX" };
@ -111,31 +117,20 @@ int main( int argc, char** argv )
// Query the existence of invalid strings
for (std::size_t i = 0; i < (sizeof(invalid_str_list) / sizeof(std::string)); ++i)
{
if (filter.contains(invalid_str_list[i]))
{
std::cout << "BF falsely contains: " << invalid_str_list[i] << std::endl;
}
BOOST_CHECK( !filter.contains(invalid_str_list[i]) );
}
// Query the existence of invalid numbers
for (int i = -1; i > -100; --i)
{
if (filter.contains(i))
{
std::cout << "BF falsely contains: " << i << std::endl;
}
BOOST_CHECK( !filter.contains(i) );
}
}
wdump((filter));
auto packed_filter = fc::raw::pack(filter);
wdump((packed_filter.size()));
wdump((packed_filter));
return 0;
}
catch ( const fc::exception& e )
{
edump((e.to_detail_string()) );
}
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,27 +0,0 @@
#include <iostream>
#include <fc/compress/smaz.hpp>
#include <fc/exception/exception.hpp>
int main( int argc, char** )
{
std::string line;
std::getline( std::cin, line );
while( std::cin && line != "q" )
{
try {
std::string compressed = fc::smaz_compress( line );
std::cout<<"compressed size: "<<compressed.size()<<"\n";
std::string decomp = fc::smaz_decompress( compressed );
std::cout<<"decomp: '"<<decomp<<"'\n";
std::cout<<"line: '"<<line<<"'\n";
FC_ASSERT( decomp == line );
}
catch ( fc::exception& e )
{
std::cout<<e.to_detail_string()<<"\n";
}
std::getline( std::cin, line );
}
return 0;
}

View file

@ -0,0 +1,89 @@
#include <boost/test/unit_test.hpp>
#include <fstream>
#include <iostream>
#include <fc/compress/smaz.hpp>
#include <fc/compress/zlib.hpp>
#include <fc/exception/exception.hpp>
BOOST_AUTO_TEST_SUITE(compress)
BOOST_AUTO_TEST_CASE(smaz_test)
{
std::ifstream testfile;
testfile.open("README.md");
std::stringstream buffer;
std::string line;
std::getline( testfile, line );
while( testfile.good() )
{
buffer << line << "\n";
try {
std::string compressed = fc::smaz_compress( line );
std::string decomp = fc::smaz_decompress( compressed );
BOOST_CHECK_EQUAL( decomp, line );
}
catch ( fc::exception& e )
{
std::cout<<e.to_detail_string()<<"\n";
}
std::getline( testfile, line );
}
line = buffer.str();
std::string compressed = fc::smaz_compress( line );
std::string decomp = fc::smaz_decompress( compressed );
BOOST_CHECK_EQUAL( decomp, line );
}
extern "C" {
enum
{
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
TINFL_FLAG_HAS_MORE_INPUT = 2,
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
TINFL_FLAG_COMPUTE_ADLER32 = 8
};
extern char* tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
}
static std::string zlib_decompress( const std::string compressed )
{
size_t decomp_len;
char* decomp = tinfl_decompress_mem_to_heap( compressed.c_str(), compressed.length(), &decomp_len, TINFL_FLAG_PARSE_ZLIB_HEADER );
std::string result( decomp, decomp_len );
free( decomp );
return result;
}
BOOST_AUTO_TEST_CASE(zlib_test)
{
std::ifstream testfile;
testfile.open("README.md");
std::stringstream buffer;
std::string line;
std::getline( testfile, line );
while( testfile.good() )
{
buffer << line << "\n";
std::string compressed = fc::zlib_compress( line );
std::string decomp = zlib_decompress( compressed );
BOOST_CHECK_EQUAL( decomp, line );
std::getline( testfile, line );
}
line = buffer.str();
std::string compressed = fc::zlib_compress( line );
std::string decomp = zlib_decompress( compressed );
BOOST_CHECK_EQUAL( decomp, line );
}
BOOST_AUTO_TEST_SUITE_END()

70
tests/crypto/aes_test.cpp Normal file
View file

@ -0,0 +1,70 @@
#include <boost/test/unit_test.hpp>
#include <fstream>
#include <iostream>
#include <fc/crypto/aes.hpp>
#include <fc/crypto/city.hpp>
#include <fc/exception/exception.hpp>
#include <fc/variant.hpp>
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(aes_test)
{
std::ifstream testfile;
testfile.open("README.md");
auto key = fc::sha512::hash( "hello", 5 );
std::stringstream buffer;
std::string line;
std::getline( testfile, line );
while( testfile.good() )
{
// std::cout << line << "\n";
buffer << line << "\n";
try {
std::vector<char> data( line.c_str(),line.c_str()+line.size()+1 );
std::vector<char> crypt = fc::aes_encrypt( key, data );
std::vector<char> dcrypt = fc::aes_decrypt( key, crypt );
BOOST_CHECK( data == dcrypt );
// memset( crypt.data(), 0, crypt.size() );
// fc::aes_encoder enc;
// enc.init( fc::sha256::hash((char*)&key,sizeof(key) ), fc::city_hash_crc_128( (char*)&key, sizeof(key) ) );
// auto len = enc.encode( dcrypt.data(), dcrypt.size(), crypt.data() );
// BOOST_CHECK_EQUAL( dcrypt.size(), len );
//
// fc::aes_decoder dec;
// dec.init( fc::sha256::hash((char*)&key,sizeof(key) ), fc::city_hash_crc_128( (char*)&key, sizeof(key) ) );
// len = dec.decode( crypt.data(), len, dcrypt.data() );
// BOOST_CHECK_EQUAL( dcrypt.size(), len );
// BOOST_CHECK( !memcmp( dcrypt.data(), data.data(), len) );
}
catch ( fc::exception& e )
{
std::cout<<e.to_detail_string()<<"\n";
}
std::getline( testfile, line );
}
line = buffer.str();
std::vector<char> data( line.c_str(),line.c_str()+line.size()+1 );
std::vector<char> crypt = fc::aes_encrypt( key, data );
std::vector<char> dcrypt = fc::aes_decrypt( key, crypt );
BOOST_CHECK( data == dcrypt );
// memset( crypt.data(), 0, crypt.size() );
// fc::aes_encoder enc;
// enc.init( fc::sha256::hash((char*)&key,sizeof(key) ), fc::city_hash_crc_128( (char*)&key, sizeof(key) ) );
// auto len = enc.encode( dcrypt.data(), dcrypt.size(), crypt.data() );
// BOOST_CHECK_EQUAL( dcrypt.size(), len );
//
// fc::aes_decoder dec;
// dec.init( fc::sha256::hash((char*)&key,sizeof(key) ), fc::city_hash_crc_128( (char*)&key, sizeof(key) ) );
// len = dec.decode( crypt.data(), len, dcrypt.data() );
// BOOST_CHECK_EQUAL( dcrypt.size(), len );
// BOOST_CHECK( !memcmp( dcrypt.data(), data.data(), len) );
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -0,0 +1,150 @@
#include <boost/test/unit_test.hpp>
#include <fc/crypto/hex.hpp>
#include <fc/crypto/base32.hpp>
#include <fc/crypto/base36.hpp>
#include <fc/crypto/base58.hpp>
#include <fc/crypto/base64.hpp>
#include <fc/exception/exception.hpp>
#include <iostream>
static const std::string TEST1("");
static const std::string TEST2("\0\00101", 4);
static const std::string TEST3("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
static const std::string TEST4("\377\376\000\375\001\374", 6);
static const std::string TEST5("\0\0\0", 3);
static void test_16( const std::string& test, const std::string& expected )
{
std::vector<char> vec( test.begin(), test.end() );
fc::string enc1 = fc::to_hex( vec );
fc::string enc2 = fc::to_hex( test.c_str(), test.size() );
BOOST_CHECK_EQUAL( enc1, enc2 );
BOOST_CHECK_EQUAL( expected, enc2 );
char out[32];
int len = fc::from_hex( enc1, out, 32 );
BOOST_CHECK_EQUAL( test.size(), len );
BOOST_CHECK( !memcmp( test.c_str(), out, len ) );
if (len > 10) {
BOOST_CHECK( fc::from_hex( enc1, out, 10 ) <= 10 );
}
}
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(hex_test)
{
test_16( TEST1, "" );
test_16( TEST2, "00013031" );
test_16( TEST3, "4142434445464748494a4b4c4d4e4f505152535455565758595a" );
test_16( TEST4, "fffe00fd01fc" );
test_16( TEST5, "000000" );
}
static void test_32( const std::string& test, const std::string& expected )
{
std::vector<char> vec( test.begin(), test.end() );
fc::string enc1 = fc::to_base32( vec );
fc::string enc2 = fc::to_base32( test.c_str(), test.size() );
BOOST_CHECK_EQUAL( enc1, enc2 );
BOOST_CHECK_EQUAL( expected, enc2 );
std::vector<char> dec = fc::from_base32( enc1 );
BOOST_CHECK_EQUAL( vec.size(), dec.size() );
BOOST_CHECK( !memcmp( vec.data(), dec.data(), vec.size() ) );
}
BOOST_AUTO_TEST_CASE(base32_test)
{
test_32( TEST1, "" );
test_32( TEST2, "AAATAMI=" );
test_32( TEST3, "IFBEGRCFIZDUQSKKJNGE2TSPKBIVEU2UKVLFOWCZLI======" );
test_32( TEST4, "777AB7IB7Q======" );
test_32( TEST5, "AAAAA===" );
}
static void test_36( const std::string& test, const std::string& expected )
{
std::vector<char> vec( test.begin(), test.end() );
fc::string enc1 = fc::to_base36( vec );
fc::string enc2 = fc::to_base36( test.c_str(), test.size() );
BOOST_CHECK_EQUAL( enc1, enc2 );
BOOST_CHECK_EQUAL( expected, enc2 );
std::vector<char> dec = fc::from_base36( enc1 );
BOOST_CHECK_EQUAL( vec.size(), dec.size() );
BOOST_CHECK( !memcmp( vec.data(), dec.data(), vec.size() ) );
}
BOOST_AUTO_TEST_CASE(base36_test)
{
test_36( TEST1, "" );
test_36( TEST2, "01o35" );
test_36( TEST3, "l4ksdleyi5pnl0un5raue268ptj43dwjwmz15ie2" );
test_36( TEST4, "2rrrvpb7y4" );
test_36( TEST5, "000" );
}
static void test_58( const std::string& test, const std::string& expected )
{
std::vector<char> vec( test.begin(), test.end() );
fc::string enc1 = fc::to_base58( vec );
fc::string enc2 = fc::to_base58( test.c_str(), test.size() );
BOOST_CHECK_EQUAL( enc1, enc2 );
BOOST_CHECK_EQUAL( expected, enc2 );
std::vector<char> dec = fc::from_base58( enc1 );
BOOST_CHECK_EQUAL( vec.size(), dec.size() );
BOOST_CHECK( !memcmp( vec.data(), dec.data(), vec.size() ) );
char buffer[64];
size_t len = fc::from_base58( enc1, buffer, 64 );
BOOST_CHECK( len <= 64 );
BOOST_CHECK( !memcmp( vec.data(), buffer, len ) );
if ( len > 10 ) {
try {
len = fc::from_base58( enc1, buffer, 10 );
BOOST_CHECK( len <= 10 );
} catch ( fc::exception expected ) {}
}
}
BOOST_AUTO_TEST_CASE(base58_test)
{
test_58( TEST1, "" );
test_58( TEST2, "1Q9e" );
test_58( TEST3, "2zuFXTJSTRK6ESktqhM2QDBkCnH1U46CnxaD" );
test_58( TEST4, "3CUeREErf" );
test_58( TEST5, "111" );
}
static void test_64( const std::string& test, const std::string& expected )
{
fc::string enc1 = fc::base64_encode( test );
fc::string enc2 = fc::base64_encode( test.c_str(), test.size() );
BOOST_CHECK_EQUAL( enc1, enc2 );
BOOST_CHECK_EQUAL( expected, enc2 );
std::string dec = fc::base64_decode( enc1 );
BOOST_CHECK_EQUAL( test.size(), dec.size() );
BOOST_CHECK_EQUAL( test, dec );
}
BOOST_AUTO_TEST_CASE(base64_test)
{
test_64( TEST1, "" );
test_64( TEST2, "AAEwMQ==" );
test_64( TEST3, "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=" );
test_64( TEST4, "//4A/QH8" );
test_64( TEST5, "AAAA" );
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -0,0 +1,77 @@
#include <boost/test/unit_test.hpp>
#include <fc/variant.hpp>
#include <fc/crypto/bigint.hpp>
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(bigint_test_1)
{
int64_t counter = 0, accu = 0, c_sq;
fc::bigint bi_accu(accu);
do {
c_sq = counter * counter;
fc::bigint add(c_sq);
bi_accu += add;
accu += c_sq;
BOOST_CHECK( fc::bigint(accu) == bi_accu );
bi_accu = bi_accu + add;
accu = accu + c_sq;
BOOST_CHECK_EQUAL( accu, bi_accu.to_int64() );
bi_accu = fc::bigint( bi_accu.dup() );
counter++;
} while (c_sq < 1000000);
fc::variant test;
fc::to_variant( bi_accu, test );
fc::bigint other;
fc::from_variant( test, other );
BOOST_CHECK( other == bi_accu );
}
BOOST_AUTO_TEST_CASE(bigint_test_2)
{
const fc::bigint bi_1(1), bi_3(3), bi_17(17), bi_65537(65537);
fc::bigint bi_accu(bi_1);
do {
std::vector<char> bytes = bi_accu;
fc::bigint a_1( bytes );
a_1 = a_1 + bi_1;
BOOST_CHECK( bi_accu < a_1 );
bi_accu = a_1 * bi_accu;
BOOST_CHECK( bi_accu >= a_1 );
} while ( bi_accu.log2() <= 128 );
bi_accu = bi_accu;
BOOST_CHECK( bi_accu && !bi_accu.is_negative() && bi_accu != bi_1 );
BOOST_CHECK( bi_3.exp( bi_accu.log2() ) > bi_accu );
fc::bigint big(1);
big <<= 30; big += bi_17; big <<= 30; big++;
big <<= 30; big -= bi_17; big >>= 5; big--;
fc::bigint rest = bi_accu % big;
BOOST_CHECK( (bi_accu - rest) / big == bi_accu / big );
fc::bigint big2; big2 = big;
big2 *= bi_65537.exp(3);
big2 /= bi_65537.exp(3);
BOOST_CHECK( big2 == big );
big--;
BOOST_CHECK_EQUAL( (std::string) bi_1, "1" );
BOOST_CHECK_EQUAL( (std::string) bi_3, "3" );
BOOST_CHECK_EQUAL( (std::string) bi_17, "17" );
BOOST_CHECK_EQUAL( (std::string) bi_65537, "65537" );
BOOST_CHECK_EQUAL( (std::string) bi_65537.exp(3), "281487861809153" );
BOOST_CHECK_EQUAL( (std::string) bi_accu, "12864938683278671740537145998360961546653259485195806" );
BOOST_CHECK_EQUAL( (std::string) big, "38685626840157682946539517" );
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,16 +1,14 @@
#include <boost/test/unit_test.hpp>
#include <fc/crypto/elliptic.hpp>
#include <fc/log/logger.hpp>
#include <fc/io/raw.hpp>
#include <fc/variant.hpp>
#include <fc/reflect/variant.hpp>
//extern "C" {
//#include <secp256k1.h>
//}
//struct secp256k1_scalar_t { uint64_t v[4]; };
//extern "C" { void secp256k1_scalar_get_b32(unsigned char *bin, const struct secp256k1_scalar_t* a); }
BOOST_AUTO_TEST_SUITE(fc_crypto)
int main( int argc, char** argv )
BOOST_AUTO_TEST_CASE(blind_test)
{
try {
auto InB1 = fc::sha256::hash("InB1");
@ -34,16 +32,16 @@ int main( int argc, char** argv )
//FC_ASSERT( fc::ecc::verify_sum( {InC1,InC2}, {OutC1}, -60 ) );
FC_ASSERT( fc::ecc::verify_sum( {InC1,InC2}, {OutC1,OutC2}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {InC1,InC2}, {OutC1,OutC2}, 0 ) );
auto nonce = fc::sha256::hash("nonce");
auto proof = fc::ecc::range_proof_sign( 0, OutC1, OutB1, nonce, 0, 0, 40 );
wdump( (proof.size()));
// wdump( (proof.size()));
auto result = fc::ecc::range_get_info( proof );
wdump((result));
FC_ASSERT( result.max_value >= 60 );
FC_ASSERT( result.min_value >= 0 );
// wdump((result));
BOOST_CHECK( result.max_value >= 60 );
BOOST_CHECK( result.min_value >= 0 );
auto B1 = fc::sha256::hash("B1");
@ -62,10 +60,10 @@ int main( int argc, char** argv )
auto B2m1 = fc::ecc::blind_sum( {B2,B1}, 1 );
auto C2m1 = fc::ecc::blind( B2m1, 1 );
FC_ASSERT( fc::ecc::verify_sum( {C1,C2}, {C3}, 0 ) );
FC_ASSERT( fc::ecc::verify_sum( {C1,C2}, {C3}, 0 ) );
FC_ASSERT( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
FC_ASSERT( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C1,C2}, {C3}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C1,C2}, {C3}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
{
@ -82,13 +80,13 @@ int main( int argc, char** argv )
auto C3 = fc::ecc::blind( B1, 1 );
auto C4 = fc::ecc::blind( B1, 2 );
FC_ASSERT( fc::ecc::verify_sum( {C2}, {C3}, -1 ) );
FC_ASSERT( fc::ecc::verify_sum( {C1}, {C1}, 0 ) );
FC_ASSERT( fc::ecc::verify_sum( {C2}, {C2}, 0 ) );
FC_ASSERT( fc::ecc::verify_sum( {C3}, {C2}, 1 ) );
FC_ASSERT( fc::ecc::verify_sum( {C1}, {C2}, INT64_MAX ) );
FC_ASSERT( fc::ecc::verify_sum( {C1}, {C2}, INT64_MAX ) );
FC_ASSERT( fc::ecc::verify_sum( {C2}, {C1}, -INT64_MAX ) );
BOOST_CHECK( fc::ecc::verify_sum( {C2}, {C3}, -1 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C1}, {C1}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C2}, {C2}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C3}, {C2}, 1 ) );
BOOST_CHECK( fc::ecc::verify_sum( {C1}, {C2}, INT64_MAX ) );
BOOST_CHECK( fc::ecc::verify_sum( {C1}, {C2}, INT64_MAX ) );
BOOST_CHECK( fc::ecc::verify_sum( {C2}, {C1}, -INT64_MAX ) );
}
@ -101,16 +99,15 @@ int main( int argc, char** argv )
auto InC = fc::ecc::blind( InBlind, 1000 );
auto In0 = fc::ecc::blind( InBlind, 0 );
FC_ASSERT( fc::ecc::verify_sum( {InC}, {OutC1,OutC2}, 0 ) );
FC_ASSERT( fc::ecc::verify_sum( {InC}, {In0}, 1000 ) );
BOOST_CHECK( fc::ecc::verify_sum( {InC}, {OutC1,OutC2}, 0 ) );
BOOST_CHECK( fc::ecc::verify_sum( {InC}, {In0}, 1000 ) );
}
}
catch ( const fc::exception& e )
{
edump((e.to_detail_string()));
}
return 0;
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -0,0 +1,169 @@
#include <boost/test/unit_test.hpp>
#include <fc/crypto/blowfish.hpp>
#include <fc/crypto/hex.hpp>
// Test vectors from https://www.schneier.com/code/vectors.txt
struct ecb_testdata {
char key[17], plain[17], cipher[17];
} ecb_tests[] = {
{ "0000000000000000", "0000000000000000", "4EF997456198DD78" },
{ "FFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFF", "51866FD5B85ECB8A" },
{ "3000000000000000", "1000000000000001", "7D856F9A613063F2" },
{ "1111111111111111", "1111111111111111", "2466DD878B963C9D" },
{ "0123456789ABCDEF", "1111111111111111", "61F9C3802281B096" },
{ "1111111111111111", "0123456789ABCDEF", "7D0CC630AFDA1EC7" },
{ "0000000000000000", "0000000000000000", "4EF997456198DD78" },
{ "FEDCBA9876543210", "0123456789ABCDEF", "0ACEAB0FC6A0A28D" },
{ "7CA110454A1A6E57", "01A1D6D039776742", "59C68245EB05282B" },
{ "0131D9619DC1376E", "5CD54CA83DEF57DA", "B1B8CC0B250F09A0" },
{ "07A1133E4A0B2686", "0248D43806F67172", "1730E5778BEA1DA4" },
{ "3849674C2602319E", "51454B582DDF440A", "A25E7856CF2651EB" },
{ "04B915BA43FEB5B6", "42FD443059577FA2", "353882B109CE8F1A" },
{ "0113B970FD34F2CE", "059B5E0851CF143A", "48F4D0884C379918" },
{ "0170F175468FB5E6", "0756D8E0774761D2", "432193B78951FC98" },
{ "43297FAD38E373FE", "762514B829BF486A", "13F04154D69D1AE5" },
{ "07A7137045DA2A16", "3BDD119049372802", "2EEDDA93FFD39C79" },
{ "04689104C2FD3B2F", "26955F6835AF609A", "D887E0393C2DA6E3" },
{ "37D06BB516CB7546", "164D5E404F275232", "5F99D04F5B163969" },
{ "1F08260D1AC2465E", "6B056E18759F5CCA", "4A057A3B24D3977B" },
{ "584023641ABA6176", "004BD6EF09176062", "452031C1E4FADA8E" },
{ "025816164629B007", "480D39006EE762F2", "7555AE39F59B87BD" },
{ "49793EBC79B3258F", "437540C8698F3CFA", "53C55F9CB49FC019" },
{ "4FB05E1515AB73A7", "072D43A077075292", "7A8E7BFA937E89A3" },
{ "49E95D6D4CA229BF", "02FE55778117F12A", "CF9C5D7A4986ADB5" },
{ "018310DC409B26D6", "1D9D5C5018F728C2", "D1ABB290658BC778" },
{ "1C587F1C13924FEF", "305532286D6F295A", "55CB3774D13EF201" },
{ "0101010101010101", "0123456789ABCDEF", "FA34EC4847B268B2" },
{ "1F1F1F1F0E0E0E0E", "0123456789ABCDEF", "A790795108EA3CAE" },
{ "E0FEE0FEF1FEF1FE", "0123456789ABCDEF", "C39E072D9FAC631D" },
{ "0000000000000000", "FFFFFFFFFFFFFFFF", "014933E0CDAFF6E4" },
{ "FFFFFFFFFFFFFFFF", "0000000000000000", "F21E9A77B71C49BC" },
{ "0123456789ABCDEF", "0000000000000000", "245946885754369A" },
{ "FEDCBA9876543210", "FFFFFFFFFFFFFFFF", "6B5C5A9C5D9E0A5A" }
};
const std::string key_test_key = "F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677";
const std::string key_test_plain = "FEDCBA9876543210";
const char key_test_ciphers[][17] = {
"F9AD597C49DB005E",
"E91D21C1D961A6D6",
"E9C2B70A1BC65CF3",
"BE1E639408640F05",
"B39E44481BDB1E6E",
"9457AA83B1928C0D",
"8BB77032F960629D",
"E87A244E2CC85E82",
"15750E7A4F4EC577",
"122BA70B3AB64AE0",
"3A833C9AFFC537F6",
"9409DA87A90F6BF2",
"884F80625060B8B4",
"1F85031C19E11968",
"79D9373A714CA34F",
"93142887EE3BE15C",
"03429E838CE2D14B",
"A4299E27469FF67B",
"AFD5AED1C1BC96A8",
"10851C0E3858DA9F",
"E6F51ED79B9DB21F",
"64A6E14AFD36B46F",
"80C7D7D45A5479AD",
"05044B62FA52D080",
};
const std::string chain_test_key = "0123456789ABCDEFF0E1D2C3B4A59687";
const std::string chain_test_iv = "FEDCBA9876543210";
const std::string chain_test_plain = "7654321 Now is the time for \0\0\0\0";
const std::string chain_test_cbc = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC";
const std::string chain_test_cfb = "E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3";
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(blowfish_ecb_test)
{
for ( int i = 0; i < 34; i++ ) {
unsigned char key[8], plain[8], cipher[8], out[8];
BOOST_CHECK_EQUAL( 8, fc::from_hex( ecb_tests[i].key, (char*) key, sizeof(key) ) );
BOOST_CHECK_EQUAL( 8, fc::from_hex( ecb_tests[i].plain, (char*) plain, sizeof(plain) ) );
BOOST_CHECK_EQUAL( 8, fc::from_hex( ecb_tests[i].cipher, (char*) cipher, sizeof(cipher) ) );
fc::blowfish fish;
fish.start( key, 8 );
fish.encrypt( plain, out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( cipher, out, 8) );
fish.decrypt( out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( plain, out, 8) );
fish.decrypt( cipher, out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( plain, out, 8) );
fish.encrypt( out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( cipher, out, 8) );
}
}
BOOST_AUTO_TEST_CASE(blowfish_key_test)
{
unsigned char key[24], plain[8], cipher[8], out[8];
BOOST_CHECK_EQUAL( 24, fc::from_hex( key_test_key.c_str(), (char*) key, sizeof(key) ) );
BOOST_CHECK_EQUAL( 8, fc::from_hex( key_test_plain.c_str(), (char*) plain, sizeof(plain) ) );
for ( unsigned int i = 0; i < sizeof(key); i++ ) {
BOOST_CHECK_EQUAL( 8, fc::from_hex( key_test_ciphers[i], (char*) cipher, sizeof(cipher) ) );
fc::blowfish fish;
fish.start( key, i + 1 );
fish.encrypt( plain, out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( cipher, out, 8) );
fish.decrypt( out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( plain, out, 8) );
fish.decrypt( cipher, out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( plain, out, 8) );
fish.encrypt( out, 8, fc::blowfish::ECB );
BOOST_CHECK( !memcmp( cipher, out, 8) );
}
}
static unsigned int from_bytes( const unsigned char* p ) {
return (((unsigned int) p[0]) << 24)
| (((unsigned int) p[1]) << 16)
| (((unsigned int) p[2]) << 8)
| ((unsigned int) p[3]);
}
BOOST_AUTO_TEST_CASE(blowfish_chain_test)
{
unsigned char key[16], iv[8], cipher[32], out[32];
BOOST_CHECK_EQUAL( 16, fc::from_hex( chain_test_key.c_str(), (char*) key, sizeof(key) ) );
BOOST_CHECK_EQUAL( 8, fc::from_hex( chain_test_iv.c_str(), (char*) iv, sizeof(iv) ) );
BOOST_CHECK_EQUAL( 32, fc::from_hex( chain_test_cbc.c_str(), (char*) cipher, sizeof(cipher) ) );
fc::blowfish fish;
fish.start( key, sizeof(key), fc::sblock( from_bytes( iv ), from_bytes( iv + 4 ) ) );
fish.encrypt( (unsigned char*) chain_test_plain.c_str(), out, sizeof(out), fc::blowfish::CBC );
BOOST_CHECK( !memcmp( cipher, out, sizeof(cipher) ) );
fish.reset_chain();
fish.decrypt( out, sizeof(out), fc::blowfish::CBC );
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
fish.reset_chain();
fish.encrypt( out, sizeof(out), fc::blowfish::CBC );
BOOST_CHECK( !memcmp( cipher, out, sizeof(cipher) ) );
fish.reset_chain();
fish.decrypt( cipher, out, sizeof(cipher), fc::blowfish::CBC );
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
BOOST_CHECK_EQUAL( 29, fc::from_hex( chain_test_cfb.c_str(), (char*) cipher, sizeof(cipher) ) );
fish.reset_chain();
fish.encrypt( (unsigned char*) chain_test_plain.c_str(), out, sizeof(out), fc::blowfish::CFB );
BOOST_CHECK( !memcmp( cipher, out, 29 ) );
fish.reset_chain(); memset( out + 29, 0, 3 );
fish.decrypt( out, sizeof(out), fc::blowfish::CFB );
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
fish.reset_chain(); memset( out + 29, 0, 3 );
fish.encrypt( out, sizeof(out), fc::blowfish::CFB );
BOOST_CHECK( !memcmp( cipher, out, 29 ) );
fish.reset_chain(); memset( out + 29, 0, 3 );
fish.decrypt( cipher, out, sizeof(cipher), fc::blowfish::CFB );
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
}
BOOST_AUTO_TEST_SUITE_END()

69
tests/crypto/dh_test.cpp Normal file
View file

@ -0,0 +1,69 @@
#include <boost/test/unit_test.hpp>
#include <fc/crypto/dh.hpp>
#include <fc/exception/exception.hpp>
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(dh_test)
{
fc::diffie_hellman alice;
BOOST_CHECK( alice.generate_params( 128, 5 ) );
BOOST_CHECK( alice.generate_pub_key() );
fc::diffie_hellman bob;
bob.p = alice.p;
BOOST_CHECK( bob.validate() );
BOOST_CHECK( bob.generate_pub_key() );
fc::diffie_hellman charlie;
BOOST_CHECK( !charlie.validate() );
BOOST_CHECK( !charlie.generate_pub_key() );
charlie.p = alice.p;
BOOST_CHECK( charlie.validate() );
BOOST_CHECK( charlie.generate_pub_key() );
BOOST_CHECK( alice.compute_shared_key( bob.pub_key ) );
BOOST_CHECK( bob.compute_shared_key( alice.pub_key ) );
BOOST_CHECK_EQUAL( alice.shared_key.size(), bob.shared_key.size() );
BOOST_CHECK( !memcmp( alice.shared_key.data(), bob.shared_key.data(), alice.shared_key.size() ) );
std::vector<char> alice_bob = alice.shared_key;
BOOST_CHECK( alice.compute_shared_key( charlie.pub_key ) );
BOOST_CHECK( charlie.compute_shared_key( alice.pub_key ) );
BOOST_CHECK_EQUAL( alice.shared_key.size(), charlie.shared_key.size() );
BOOST_CHECK( !memcmp( alice.shared_key.data(), charlie.shared_key.data(), alice.shared_key.size() ) );
std::vector<char> alice_charlie = alice.shared_key;
BOOST_CHECK( charlie.compute_shared_key( bob.pub_key ) );
BOOST_CHECK( bob.compute_shared_key( charlie.pub_key ) );
BOOST_CHECK_EQUAL( charlie.shared_key.size(), bob.shared_key.size() );
BOOST_CHECK( !memcmp( charlie.shared_key.data(), bob.shared_key.data(), bob.shared_key.size() ) );
std::vector<char> bob_charlie = charlie.shared_key;
BOOST_CHECK_EQUAL( alice_bob.size(), alice_charlie.size() );
BOOST_CHECK( memcmp( alice_bob.data(), alice_charlie.data(), alice_bob.size() ) );
BOOST_CHECK_EQUAL( alice_bob.size(), bob_charlie.size() );
BOOST_CHECK( memcmp( alice_bob.data(), bob_charlie.data(), alice_bob.size() ) );
BOOST_CHECK_EQUAL( alice_charlie.size(), bob_charlie.size() );
BOOST_CHECK( memcmp( alice_charlie.data(), bob_charlie.data(), alice_charlie.size() ) );
alice.p.clear(); alice.p.push_back(100); alice.p.push_back(2);
BOOST_CHECK( !alice.validate() );
alice.p = bob.p;
alice.g = 9;
BOOST_CHECK( !alice.validate() );
// It ain't easy...
// alice.g = 2;
// BOOST_CHECK( alice.validate() );
// BOOST_CHECK( alice.generate_pub_key() );
// BOOST_CHECK( alice.compute_shared_key( bob.pub_key ) );
// BOOST_CHECK( bob.compute_shared_key( alice.pub_key ) );
// BOOST_CHECK_EQUAL( alice.shared_key.size(), bob.shared_key.size() );
// BOOST_CHECK( memcmp( alice.shared_key.data(), bob.shared_key.data(), alice.shared_key.size() ) );
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -0,0 +1,43 @@
#include <boost/test/unit_test.hpp>
#include <fc/crypto/rand.hpp>
#include <cmath>
static void check_randomness( const char* buffer, size_t len ) {
if (len == 0) { return; }
// count bit runs and 0's / 1's
unsigned int zc = 0, oc = 0, rc = 0, last = 2;
for (size_t k = len; k; k--) {
char c = *buffer++;
for (int i = 0; i < 8; i++) {
unsigned int bit = c & 1;
c >>= 1;
if (bit) { oc++; } else { zc++; }
if (bit != last) { rc++; last = bit; }
}
}
BOOST_CHECK_EQUAL( 8*len, zc + oc );
double E = 1 + (zc + oc) / 2.0;
double variance = (E - 1) * (E - 2) / (oc + zc - 1);
double sigma = sqrt(variance);
BOOST_CHECK( rc > E - sigma && rc < E + sigma);
}
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(rand_test)
{
char buffer[128];
fc::rand_bytes( buffer, sizeof(buffer) );
check_randomness( buffer, sizeof(buffer) );
}
BOOST_AUTO_TEST_CASE(pseudo_rand_test)
{
char buffer[10013];
fc::rand_pseudo_bytes( buffer, sizeof(buffer) );
check_randomness( buffer, sizeof(buffer) );
}
BOOST_AUTO_TEST_SUITE_END()

178
tests/crypto/sha_tests.cpp Normal file
View file

@ -0,0 +1,178 @@
#include <boost/test/unit_test.hpp>
#include <fc/crypto/digest.hpp>
#include <fc/crypto/ripemd160.hpp>
#include <fc/crypto/sha1.hpp>
#include <fc/crypto/sha224.hpp>
#include <fc/crypto/sha256.hpp>
#include <fc/crypto/sha512.hpp>
#include <fc/exception/exception.hpp>
#include <iostream>
// SHA test vectors taken from http://www.di-mgt.com.au/sha_testvectors.html
static const std::string TEST1("abc");
static const std::string TEST2("");
static const std::string TEST3("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
static const std::string TEST4("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
static char TEST5[1000001];
static const std::string TEST6("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno");
static void init_5() {
memset( TEST5, 'a', sizeof(TEST5) - 1 );
TEST5[1000000] = 0;
}
template<typename H>
void test( const char* to_hash, const std::string& expected ) {
H hash = H::hash( to_hash, strlen( to_hash ) );
BOOST_CHECK_EQUAL( expected, (std::string) hash );
H hash2( expected );
BOOST_CHECK( hash == hash2 );
}
template<typename H>
void test( const std::string& to_hash, const std::string& expected ) {
H hash = H::hash( to_hash );
BOOST_CHECK_EQUAL( expected, (std::string) hash );
test<H>( to_hash.c_str(), expected );
}
template<typename H>
void test_big( const std::string& expected ) {
typename H::encoder enc;
for (char c : TEST6) { enc.put(c); }
for (int i = 0; i < 16777215; i++) {
enc.write( TEST6.c_str(), TEST6.size() );
}
H hash = enc.result();
BOOST_CHECK_EQUAL( expected, (std::string) hash );
enc.reset();
enc.write( TEST1.c_str(), TEST1.size() );
hash = enc.result();
BOOST_CHECK( hash >= H::hash( TEST1 ) );
test<H>( TEST1, (std::string) hash );
hash = hash ^ hash;
hash.data()[hash.data_size() - 1] = 1;
for (int i = hash.data_size() * 8 - 1; i > 0; i--) {
H other = hash << i;
BOOST_CHECK( other != hash );
BOOST_CHECK( other > hash );
BOOST_CHECK( hash < other );
}
H hash2( expected );
fc::variant v;
to_variant( hash2, v );
from_variant( v, hash );
BOOST_CHECK( hash == hash2 );
H hash3( expected.substr(15) + "000000000000000" );
BOOST_CHECK( hash3 == hash2 << 60 );
}
template<typename H>
void test_stream( ) {
H hash( TEST1 );
std::stringstream stream;
stream << hash;
H other;
stream >> other;
BOOST_CHECK( hash == other );
}
template void test_big<fc::ripemd160>( const std::string& expected );
template void test_big<fc::sha1>( const std::string& expected );
template void test_big<fc::sha224>( const std::string& expected );
template void test_big<fc::sha256>( const std::string& expected );
template void test_big<fc::sha512>( const std::string& expected );
template void test_stream<fc::ripemd160>();
template void test_stream<fc::sha256>();
template void test_stream<fc::sha512>();
BOOST_AUTO_TEST_SUITE(fc_crypto)
BOOST_AUTO_TEST_CASE(ripemd160_test)
{
init_5();
test<fc::ripemd160>( TEST1, "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" );
test<fc::ripemd160>( TEST2, "9c1185a5c5e9fc54612808977ee8f548b2258d31" );
test<fc::ripemd160>( TEST3, "12a053384a9c0c88e405a06c27dcf49ada62eb2b" );
// test<fc::ripemd160>( TEST4, "" );
test<fc::ripemd160>( TEST5, "52783243c1697bdbe16d37f97f68f08325dc1528" );
test_big<fc::ripemd160>( "29b6df855772aa9a95442bf83b282b495f9f6541" );
test_stream<fc::ripemd160>();
}
BOOST_AUTO_TEST_CASE(sha1_test)
{
init_5();
test<fc::sha1>( TEST1, "a9993e364706816aba3e25717850c26c9cd0d89d" );
test<fc::sha1>( TEST2, "da39a3ee5e6b4b0d3255bfef95601890afd80709" );
test<fc::sha1>( TEST3, "84983e441c3bd26ebaae4aa1f95129e5e54670f1" );
test<fc::sha1>( TEST4, "a49b2446a02c645bf419f995b67091253a04a259" );
test<fc::sha1>( TEST5, "34aa973cd4c4daa4f61eeb2bdbad27316534016f" );
test_big<fc::sha1>( "7789f0c9ef7bfc40d93311143dfbe69e2017f592" );
}
BOOST_AUTO_TEST_CASE(sha224_test)
{
init_5();
test<fc::sha224>( TEST1, "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" );
test<fc::sha224>( TEST2, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" );
test<fc::sha224>( TEST3, "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" );
test<fc::sha224>( TEST4, "c97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3" );
test<fc::sha224>( TEST5, "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" );
test_big<fc::sha224>( "b5989713ca4fe47a009f8621980b34e6d63ed3063b2a0a2c867d8a85" );
}
BOOST_AUTO_TEST_CASE(sha256_test)
{
init_5();
test<fc::sha256>( TEST1, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" );
test<fc::sha256>( TEST2, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" );
test<fc::sha256>( TEST3, "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" );
test<fc::sha256>( TEST4, "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" );
test<fc::sha256>( TEST5, "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" );
test_big<fc::sha256>( "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e" );
test_stream<fc::sha256>();
std::vector<int> test_object;
test_object.push_back( 42 );
fc::sha256 digest = fc::digest( test_object );
BOOST_CHECK( digest == fc::sha256::hash( test_object ) );
fc::sha256 other( digest.data(), digest.data_size() );
BOOST_CHECK( digest == other );
fc::sha512 yet_another = fc::sha512::hash( TEST1 );
try {
fc::sha256 fourth( yet_another.data(), yet_another.data_size() );
BOOST_FAIL( "Expected exception!" );
} catch ( fc::exception& expected ) {}
fc::sha256 fourth( "445C7A8007A93D8733188288BB320A8FE2DEBD2AE1B47F0F50BC10BAE845C094" );
BOOST_CHECK_EQUAL( "d61967f63c7dd183914a4ae452c9f6ad5d462ce3d277798075b107615c1a8a30", (std::string) fc::sha256::hash(fourth) );
}
BOOST_AUTO_TEST_CASE(sha512_test)
{
init_5();
test<fc::sha512>( TEST1, "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" );
test<fc::sha512>( TEST2, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
"47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" );
test<fc::sha512>( TEST3, "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335"
"96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445" );
test<fc::sha512>( TEST4, "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" );
test<fc::sha512>( TEST5, "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
"de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" );
test_big<fc::sha512>( "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d"
"77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086" );
test_stream<fc::sha512>();
}
BOOST_AUTO_TEST_SUITE_END()

Binary file not shown.

View file

@ -0,0 +1,70 @@
#include <boost/test/unit_test.hpp>
#include <fc/network/http/websocket.hpp>
#include <iostream>
BOOST_AUTO_TEST_SUITE(fc_network)
BOOST_AUTO_TEST_CASE(websocket_test)
{
fc::http::websocket_client client;
fc::http::websocket_connection_ptr s_conn, c_conn;
{
fc::http::websocket_server server;
server.on_connection([&]( const fc::http::websocket_connection_ptr& c ){
s_conn = c;
c->on_message_handler([&](const std::string& s){
c->send_message("echo: " + s);
});
});
server.listen( 8090 );
server.start_accept();
std::string echo;
c_conn = client.connect( "ws://localhost:8090" );
c_conn->on_message_handler([&](const std::string& s){
echo = s;
});
c_conn->send_message( "hello world" );
fc::usleep( fc::seconds(1) );
BOOST_CHECK_EQUAL("echo: hello world", echo);
c_conn->send_message( "again" );
fc::usleep( fc::seconds(1) );
BOOST_CHECK_EQUAL("echo: again", echo);
s_conn->close(0, "test");
fc::usleep( fc::seconds(1) );
try {
c_conn->send_message( "again" );
BOOST_FAIL("expected assertion failure");
} catch (const fc::assert_exception& e) {
//std::cerr << e.to_string() << "\n";
}
c_conn = client.connect( "ws://localhost:8090" );
c_conn->on_message_handler([&](const std::string& s){
echo = s;
});
c_conn->send_message( "hello world" );
fc::usleep( fc::seconds(1) );
BOOST_CHECK_EQUAL("echo: hello world", echo);
}
try {
c_conn->send_message( "again" );
BOOST_FAIL("expected assertion failure");
} catch (const fc::assert_exception& e) {
std::cerr << e.to_string() << "\n";
}
try {
c_conn = client.connect( "ws://localhost:8090" );
BOOST_FAIL("expected assertion failure");
} catch (const fc::assert_exception& e) {
std::cerr << e.to_string() << "\n";
}
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -0,0 +1,25 @@
#include <boost/test/unit_test.hpp>
#include <fc/network/ntp.hpp>
#include <fc/log/logger.hpp>
#include <fc/thread/thread.hpp>
BOOST_AUTO_TEST_SUITE(fc_network)
BOOST_AUTO_TEST_CASE( ntp_test )
{
fc::ntp ntp_service;
ntp_service.set_request_interval(5);
fc::usleep(fc::seconds(4) );
auto time = ntp_service.get_time();
BOOST_CHECK( time );
auto ntp_time = *time;
auto delta = ntp_time - fc::time_point::now();
// auto minutes = delta.count() / 1000000 / 60;
// auto hours = delta.count() / 1000000 / 60 / 60;
// auto seconds = delta.count() / 1000000;
auto msec= delta.count() / 1000;
BOOST_CHECK( msec < 100 );
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,8 +1,9 @@
#include <fc/real128.hpp>
#define BOOST_TEST_MODULE Real128Test
#include <boost/test/unit_test.hpp>
#include <fc/log/logger.hpp>
BOOST_AUTO_TEST_SUITE(fc)
using fc::real128;
using std::string;
@ -50,3 +51,5 @@ BOOST_AUTO_TEST_CASE(real128_test)
wdump((real128("12345.6789")) );
wdump( (ten/3*3) );
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,4 +1,3 @@
#define BOOST_TEST_MODULE fc_task_cancel_tests
#include <boost/test/unit_test.hpp>
#include <fc/thread/thread.hpp>
@ -8,6 +7,8 @@
#include <fc/exception/exception.hpp>
#include <fc/thread/non_preemptable_scope_check.hpp>
BOOST_AUTO_TEST_SUITE(fc_thread)
BOOST_AUTO_TEST_CASE( leave_mutex_locked )
{
{
@ -39,19 +40,22 @@ BOOST_AUTO_TEST_CASE( cancel_task_blocked_on_mutex)
BOOST_TEST_MESSAGE("--- In test_task, sleeps done, exiting");
}, "test_task");
fc::usleep(fc::seconds(3));
//test_task.cancel();
try
{
fc::scoped_lock<fc::mutex> test_lock2(test_mutex);
test_task.cancel();
try
{
test_task.wait(fc::seconds(1));
BOOST_ERROR("test should have been canceled, not exited cleanly");
}
catch (const fc::canceled_exception&)
{
}
catch (const fc::canceled_exception&)
{
BOOST_TEST_PASSPOINT();
}
catch (const fc::timeout_exception&)
{
}
catch (const fc::timeout_exception&)
{
BOOST_ERROR("unable to cancel task blocked on mutex");
}
}
BOOST_TEST_MESSAGE("Unlocking mutex locked from the main task so the test task will have the opportunity to lock it and be canceled");
}
@ -207,7 +211,7 @@ BOOST_AUTO_TEST_CASE( cleanup_cancelled_task )
{
BOOST_TEST_MESSAGE("Caught exception from canceled task: " << e.what());
}
BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should be done with it");
// BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should be done with it");
task = fc::future<void>();
BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should have been destroyed");
}
@ -227,15 +231,19 @@ BOOST_AUTO_TEST_CASE( cancel_scheduled_task )
//bool task_executed = false;
try
{
simple_task();
// simple_task();
simple_task();
fc::usleep(fc::seconds(4));
simple_task_done.cancel("canceling scheduled task to test if cancel works");
simple_task_done.wait();
BOOST_CHECK_EQUAL(task_execute_count, 2);
fc::usleep(fc::seconds(3));
BOOST_CHECK_EQUAL(task_execute_count, 2);
}
catch ( const fc::exception& e )
{
wlog( "${e}", ("e",e.to_detail_string() ) );
}
BOOST_CHECK_EQUAL(task_execute_count, 2);
}
BOOST_AUTO_TEST_SUITE_END()

84
tests/utf8_test.cpp Normal file
View file

@ -0,0 +1,84 @@
#include <boost/test/unit_test.hpp>
#include <fc/utf8.hpp>
using namespace fc;
static const std::string TEST_INVALID_1("\375\271\261\241\201\211\001");
static const std::string TEST_INVALID_2("\371\261\241\201\211\001");
static const std::string TEST_VALID_1("\361\241\201\211\001");
static const std::string TEST_VALID_2("\361\241\201\211");
static const std::string TEST_INVALID_3("\361\241\201");
static const std::string TEST_INVALID_4("\361\241\201\001");
static const std::string TEST_INVALID_5("\361\241");
static const std::string TEST_INVALID_6("\361\241\001");
static const std::string TEST_INVALID_7("\361");
static const std::string TEST_INVALID_8("\361\001");
static const std::string TEST_INVALID_9("\355\244\200");
static const std::string TEST_INVALID_10("\355\244\200\001");
static const std::string TEST_INVALID_11("\340\214\200");
static const std::string TEST_INVALID_12("\340\214\200\001");
BOOST_AUTO_TEST_SUITE(fc)
BOOST_AUTO_TEST_CASE(utf8_test)
{
std::wstring test(L"\0\001\002");
test.reserve(65536);
for (wchar_t c = 0xffff; c >= 0xe000; c--) {
test.push_back(c);
}
for (wchar_t c = 0xd7ff; c > 2; c--) {
test.push_back(c);
}
for (wchar_t c = 1; c < 16; c++) {
test.push_back((c << 16) | 0xffff);
}
std::string storage;
storage.reserve(257*1024);
fc::encodeUtf8(test, &storage);
BOOST_CHECK(fc::is_utf8(storage));
std::wstring decoded;
decoded.reserve(65536);
fc::decodeUtf8(storage, &decoded);
BOOST_CHECK(test.compare(decoded) == 0);
BOOST_CHECK(fc::is_utf8(TEST_VALID_1));
BOOST_CHECK(fc::is_utf8(TEST_VALID_2));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_1));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_2));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_3));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_4));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_5));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_6));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_7));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_8));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_9));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_10));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_11));
BOOST_CHECK(!fc::is_utf8(TEST_INVALID_12));
decoded.clear();
try {
fc::decodeUtf8(TEST_INVALID_1, &decoded);
BOOST_FAIL("expected invalid utf8 exception");
} catch (const std::exception& e) {
BOOST_CHECK(!strncmp("Invalid UTF-8", e.what(), 14));
}
try {
fc::decodeUtf8(TEST_INVALID_9, &decoded);
BOOST_FAIL("expected invalid code point exception");
} catch (const std::exception& e) {
BOOST_CHECK(!strncmp("Invalid code point", e.what(), 19));
}
try {
fc::decodeUtf8(TEST_INVALID_11, &decoded);
BOOST_FAIL("expected invalid utf8 exception");
} catch (const std::exception& e) {
BOOST_CHECK(!strncmp("Invalid UTF-8", e.what(), 14));
}
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,51 +0,0 @@
#include <fc/network/http/websocket.hpp>
#include <fc/log/logger.hpp>
#include <fc/thread/thread.hpp>
#include <fc/rpc/websocket_api.hpp>
using namespace fc::http;
class echo_session : public fc::http::websocket_session
{
public:
echo_session( const websocket_connection_ptr c ):fc::http::websocket_session(c){}
void on_message( const std::string& message )
{
idump((message));
if( message.size() < 64 )
send_message( "echo " + message );
}
};
int main( int argc, char** argv )
{
try {
auto create_session = [&]( const websocket_connection_ptr& c ){
return std::make_shared<echo_session>(c);
};
fc::http::websocket_server server;
server.on_connection(create_session);
server.listen( 8090 );
server.start_accept();
fc::http::websocket_client client;
auto session = client.connect( "ws://localhost:8090", create_session );
wlog( "connected" );
session->send_message( "hello world" );
fc::usleep( fc::seconds(2) );
return 0;
}
/*
catch ( const websocketpp::lib::error_code& e )
{
edump( (e.message()) );
}
*/
catch ( const fc::exception& e )
{
edump((e.to_detail_string()));
}
}