FC Updates from BitShares and myself #21
11 changed files with 140 additions and 236 deletions
|
|
@ -1,145 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/crypto/base64.hpp>
|
||||
#include <fc/variant.hpp>
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
/**
|
||||
* Provides a fixed size array that is easier for templates to specialize
|
||||
* against or overload than T[N].
|
||||
*/
|
||||
template<typename T, size_t N>
|
||||
class array {
|
||||
public:
|
||||
/**
|
||||
* Checked indexing (when in debug build) that also simplifies dereferencing
|
||||
* when you have an array<T,N>*.
|
||||
*/
|
||||
///@{
|
||||
T& at( size_t pos ) { assert( pos < N); return data[pos]; }
|
||||
const T& at( size_t pos )const { assert( pos < N); return data[pos]; }
|
||||
///@}
|
||||
|
||||
T& operator[]( size_t pos ) { assert( pos < N); return data[pos]; }
|
||||
const T& operator[]( size_t pos )const { assert( pos < N); return data[pos]; }
|
||||
|
||||
|
||||
const T* begin()const { return &data[0]; }
|
||||
const T* end()const { return &data[N]; }
|
||||
|
||||
T* begin() { return &data[0]; }
|
||||
T* end() { return &data[N]; }
|
||||
|
||||
size_t size()const { return N; }
|
||||
|
||||
T data[N];
|
||||
};
|
||||
|
||||
/** provided for default 0 init */
|
||||
template<size_t N>
|
||||
class array<unsigned char,N>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char T;
|
||||
array(){ memset( data, 0, sizeof(data) ); }
|
||||
/**
|
||||
* Checked indexing (when in debug build) that also simplifies dereferencing
|
||||
* when you have an array<T,N>*.
|
||||
*/
|
||||
///@{
|
||||
T& at( size_t pos ) { assert( pos < N); return data[pos]; }
|
||||
const T& at( size_t pos )const { assert( pos < N); return data[pos]; }
|
||||
///@}
|
||||
|
||||
T* begin() { return &data[0]; }
|
||||
const T* begin()const { return &data[0]; }
|
||||
const T* end()const { return &data[N]; }
|
||||
|
||||
size_t size()const { return N; }
|
||||
|
||||
T data[N];
|
||||
};
|
||||
|
||||
/** provided for default 0 init */
|
||||
template<size_t N>
|
||||
class array<char,N>
|
||||
{
|
||||
public:
|
||||
typedef char T;
|
||||
array(){ memset( data, 0, sizeof(data) ); }
|
||||
/**
|
||||
* Checked indexing (when in debug build) that also simplifies dereferencing
|
||||
* when you have an array<T,N>*.
|
||||
*/
|
||||
///@{
|
||||
T& at( size_t pos ) { assert( pos < N); return data[pos]; }
|
||||
const T& at( size_t pos )const { assert( pos < N); return data[pos]; }
|
||||
///@}
|
||||
|
||||
T* begin() { return &data[0]; }
|
||||
const T* begin()const { return &data[0]; }
|
||||
const T* end()const { return &data[N]; }
|
||||
|
||||
size_t size()const { return N; }
|
||||
|
||||
T data[N];
|
||||
};
|
||||
|
||||
template<typename T, size_t N>
|
||||
bool operator == ( const array<T,N>& a, const array<T,N>& b )
|
||||
{ return 0 == memcmp( a.data, b.data, N*sizeof(T) ); }
|
||||
template<typename T, size_t N>
|
||||
bool operator < ( const array<T,N>& a, const array<T,N>& b )
|
||||
{ return memcmp( a.data, b.data, N*sizeof(T) ) < 0 ; }
|
||||
|
||||
template<typename T, size_t N>
|
||||
bool operator > ( const array<T,N>& a, const array<T,N>& b )
|
||||
{ return memcmp( a.data, b.data, N*sizeof(T) ) > 0 ; }
|
||||
|
||||
template<typename T, size_t N>
|
||||
bool operator != ( const array<T,N>& a, const array<T,N>& b )
|
||||
{ return 0 != memcmp( a.data, b.data, N*sizeof(T) ); }
|
||||
|
||||
template<typename T, size_t N>
|
||||
void to_variant( const array<T,N>& bi, variant& v, uint32_t max_depth = 1 )
|
||||
{
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, 1 );
|
||||
}
|
||||
template<typename T, size_t N>
|
||||
void from_variant( const variant& v, array<T,N>& bi, uint32_t max_depth = 1 )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( 1 );
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), std::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
}
|
||||
|
||||
|
||||
template<typename T,size_t N> struct get_typename< fc::array<T,N> >
|
||||
{
|
||||
static const char* name()
|
||||
{
|
||||
static std::string _name = std::string("fc::array<")+std::string(fc::get_typename<T>::name())+","+ fc::to_string(N) + ">";
|
||||
return _name.c_str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#include <unordered_map>
|
||||
#include <fc/crypto/city.hpp>
|
||||
namespace std
|
||||
{
|
||||
template<typename T, size_t N>
|
||||
struct hash<fc::array<T,N> >
|
||||
{
|
||||
size_t operator()( const fc::array<T,N>& e )const
|
||||
{
|
||||
return fc::city_hash_size_t( (char*)&e, sizeof(e) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -4,9 +4,10 @@
|
|||
#include <fc/crypto/sha256.hpp>
|
||||
#include <fc/crypto/sha512.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/array.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace fc {
|
||||
|
||||
namespace ecc {
|
||||
|
|
@ -16,15 +17,15 @@ namespace fc {
|
|||
class private_key_impl;
|
||||
}
|
||||
|
||||
typedef fc::sha256 blind_factor_type;
|
||||
typedef fc::array<char,33> commitment_type;
|
||||
typedef fc::array<char,33> public_key_data;
|
||||
typedef fc::sha256 private_key_secret;
|
||||
typedef fc::array<char,65> public_key_point_data; ///< the full non-compressed version of the ECC point
|
||||
typedef fc::array<char,72> signature;
|
||||
typedef fc::array<unsigned char,65> compact_signature;
|
||||
typedef std::vector<char> range_proof_type;
|
||||
typedef fc::array<char,78> extended_key_data;
|
||||
typedef fc::sha256 blind_factor_type;
|
||||
typedef std::array<unsigned char,33> commitment_type;
|
||||
typedef std::array<unsigned char,33> public_key_data;
|
||||
typedef fc::sha256 private_key_secret;
|
||||
typedef std::array<unsigned char,65> public_key_point_data; ///< the full non-compressed version of the ECC point
|
||||
typedef std::array<unsigned char,72> signature;
|
||||
typedef std::array<unsigned char,65> compact_signature;
|
||||
typedef std::vector<char> range_proof_type;
|
||||
typedef std::array<unsigned char,78> extended_key_data;
|
||||
|
||||
/**
|
||||
* @class public_key
|
||||
|
|
|
|||
|
|
@ -146,22 +146,22 @@ namespace fc {
|
|||
} FC_RETHROW_EXCEPTIONS( warn, "" ) }
|
||||
|
||||
template<typename Stream, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<char,N>& v, uint32_t _max_depth ) {
|
||||
s.write( &v.data[0], N );
|
||||
inline void pack( Stream& s, const std::array<char,N>& v, uint32_t _max_depth ) {
|
||||
s.write( v.data(), N );
|
||||
}
|
||||
template<typename Stream, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<unsigned char,N>& v, uint32_t _max_depth ) {
|
||||
s.write( (char*)&v.data[0], N );
|
||||
inline void pack( Stream& s, const std::array<unsigned char,N>& v, uint32_t _max_depth ) {
|
||||
s.write( (char*)v.data(), N );
|
||||
}
|
||||
|
||||
template<typename Stream, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<char,N>& v, uint32_t _max_depth ) { try {
|
||||
s.read( &v.data[0], N );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<char,${length}>", ("length",N) ) }
|
||||
inline void unpack( Stream& s, std::array<char,N>& v, uint32_t _max_depth ) { try {
|
||||
s.read( v.data(), N );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "std::array<char,${length}>", ("length",N) ) }
|
||||
template<typename Stream, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<unsigned char,N>& v, uint32_t _max_depth ) { try {
|
||||
s.read( (char*)&v.data[0], N );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<unsigned char,${length}>", ("length",N) ) }
|
||||
inline void unpack( Stream& s, std::array<unsigned char,N>& v, uint32_t _max_depth ) { try {
|
||||
s.read( (char*)v.data(), N );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "std::array<unsigned char,${length}>", ("length",N) ) }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::shared_ptr<T>& v, uint32_t _max_depth )
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@
|
|||
#include <fc/config.hpp>
|
||||
#include <fc/container/flat_fwd.hpp>
|
||||
#include <fc/io/varint.hpp>
|
||||
#include <fc/array.hpp>
|
||||
#include <fc/safe.hpp>
|
||||
#include <fc/uint128.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
|
@ -130,13 +131,17 @@ namespace fc {
|
|||
inline void unpack( Stream& s, boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth );
|
||||
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth ) = delete;
|
||||
inline void pack( Stream& s, const std::array<T,N>& v, uint32_t _max_depth ) = delete;
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth ) = delete;
|
||||
template<typename Stream, size_t N> inline void pack( Stream& s, const fc::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, size_t N> inline void unpack( Stream& s, fc::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
|
||||
template<typename Stream, size_t N> inline void pack( Stream& s, const fc::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, size_t N> inline void unpack( Stream& s, fc::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
|
||||
inline void unpack( Stream& s, std::array<T,N>& v, uint32_t _max_depth ) = delete;
|
||||
template<typename Stream, size_t N>
|
||||
inline void pack( Stream& s, const std::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, size_t N>
|
||||
inline void unpack( Stream& s, std::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
|
||||
template<typename Stream, size_t N>
|
||||
inline void pack( Stream& s, const std::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, size_t N>
|
||||
inline void unpack( Stream& s, std::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
|
||||
|
||||
template<typename Stream, typename T> inline void pack( Stream& s, const std::shared_ptr<T>& v,
|
||||
uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
|
@ -7,7 +8,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <fc/optional.hpp>
|
||||
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/container/flat_fwd.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
|
@ -92,6 +93,15 @@ namespace fc {
|
|||
return n.c_str();
|
||||
}
|
||||
};
|
||||
template<typename T,size_t N> struct get_typename< std::array<T,N> >
|
||||
{
|
||||
static const char* name()
|
||||
{
|
||||
static std::string _name = std::string("std::array<") + std::string(fc::get_typename<T>::name())
|
||||
+ "," + fc::to_string(N) + ">";
|
||||
return _name.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
struct unsigned_int;
|
||||
class variant_object;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@
|
|||
**/
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <fc/array.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
|
@ -216,17 +216,17 @@ public:
|
|||
} // namespace impl
|
||||
|
||||
template<int L,typename Visitor,typename Data>
|
||||
static const fc::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
static const std::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
init_wrappers( Visitor& v, Data d, typename Visitor::result_type(**funcs)(Visitor&,Data) = 0)
|
||||
{
|
||||
return fc::array<typename Visitor::result_type(*)(Visitor&,Data),L>();
|
||||
return std::array<typename Visitor::result_type(*)(Visitor&,Data),L>();
|
||||
}
|
||||
|
||||
template<int L,typename Visitor,typename Data,typename T, typename ... Types>
|
||||
static const fc::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
static const std::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
init_wrappers( Visitor& v, Data d, typename Visitor::result_type(**funcs)(Visitor&,Data) = 0 )
|
||||
{
|
||||
fc::array<typename Visitor::result_type(*)(Visitor&,Data),L> result{};
|
||||
std::array<typename Visitor::result_type(*)(Visitor&,Data),L> result{};
|
||||
if( !funcs ) funcs = result.begin();
|
||||
*funcs++ = [] ( Visitor& v, Data d ) { return v( *reinterpret_cast<T*>( d ) ); };
|
||||
init_wrappers<L,Visitor,Data,Types...>( v, d, funcs );
|
||||
|
|
@ -234,17 +234,17 @@ static const fc::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
|||
}
|
||||
|
||||
template<int L,typename Visitor,typename Data>
|
||||
static const fc::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
static const std::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
init_const_wrappers( Visitor& v, Data d, typename Visitor::result_type(**funcs)(Visitor&,Data) = 0 )
|
||||
{
|
||||
return fc::array<typename Visitor::result_type(*)(Visitor&,Data),L>();
|
||||
return std::array<typename Visitor::result_type(*)(Visitor&,Data),L>();
|
||||
}
|
||||
|
||||
template<int L,typename Visitor,typename Data,typename T, typename ... Types>
|
||||
static const fc::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
static const std::array<typename Visitor::result_type(*)(Visitor&,Data),L>
|
||||
init_const_wrappers( Visitor& v, Data d, typename Visitor::result_type(**funcs)(Visitor&,Data) = 0 )
|
||||
{
|
||||
fc::array<typename Visitor::result_type(*)(Visitor&,Data),L> result{};
|
||||
std::array<typename Visitor::result_type(*)(Visitor&,Data),L> result{};
|
||||
if( !funcs ) funcs = result.begin();
|
||||
*funcs++ = [] ( Visitor& v, Data d ) { return v( *reinterpret_cast<const T*>( d ) ); };
|
||||
init_const_wrappers<L,Visitor,Data,Types...>( v, d, funcs );
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
|
@ -658,6 +659,36 @@ namespace fc
|
|||
c.insert( item.as<T>( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
void to_variant( const std::array<char,N>& bi, variant& v, uint32_t max_depth = 1 )
|
||||
{
|
||||
to_variant( std::vector<char>( bi.begin(), bi.end() ), v, 1 );
|
||||
}
|
||||
template<size_t N>
|
||||
void from_variant( const variant& v, std::array<char,N>& bi, uint32_t max_depth = 1 )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( 1 );
|
||||
if( ve.size() )
|
||||
memcpy( bi.data(), ve.data(), std::min<size_t>( ve.size(), bi.size() ) );
|
||||
else
|
||||
memset( bi.data(), 0, bi.size() );
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
void to_variant( const std::array<unsigned char,N>& bi, variant& v, uint32_t max_depth = 1 )
|
||||
{
|
||||
to_variant( std::vector<char>( bi.begin(), bi.end() ), v, 1 );
|
||||
}
|
||||
template<size_t N>
|
||||
void from_variant( const variant& v, std::array<unsigned char,N>& bi, uint32_t max_depth = 1 )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( 1 );
|
||||
if( ve.size() )
|
||||
memcpy( bi.data(), ve.data(), std::min<size_t>( ve.size(), bi.size() ) );
|
||||
else
|
||||
memset( bi.data(), 0, bi.size() );
|
||||
}
|
||||
|
||||
variant operator + ( const variant& a, const variant& b );
|
||||
variant operator - ( const variant& a, const variant& b );
|
||||
variant operator * ( const variant& a, const variant& b );
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
namespace fc { namespace ecc {
|
||||
|
||||
namespace detail {
|
||||
typedef fc::array<char,37> chr37;
|
||||
typedef std::array<unsigned char,37> chr37;
|
||||
|
||||
fc::sha256 _left( const fc::sha512& v )
|
||||
{
|
||||
|
|
@ -52,10 +52,10 @@ namespace fc { namespace ecc {
|
|||
return result;
|
||||
}
|
||||
|
||||
static chr37 _derive_message( char first, const char* key32, int i )
|
||||
static chr37 _derive_message( unsigned char first, const unsigned char* key32, int i )
|
||||
{
|
||||
chr37 result;
|
||||
unsigned char* dest = (unsigned char*) result.begin();
|
||||
unsigned char* dest = result.begin();
|
||||
*dest++ = first;
|
||||
memcpy( dest, key32, 32 ); dest += 32;
|
||||
_put( &dest, i );
|
||||
|
|
@ -69,7 +69,7 @@ namespace fc { namespace ecc {
|
|||
|
||||
static chr37 _derive_message( const private_key_secret& key, int i )
|
||||
{
|
||||
return _derive_message( 0, key.data(), i );
|
||||
return _derive_message( 0, (unsigned char*) key.data(), i );
|
||||
}
|
||||
|
||||
const ec_group& get_curve()
|
||||
|
|
@ -139,40 +139,40 @@ namespace fc { namespace ecc {
|
|||
|
||||
std::string public_key::to_base58( const public_key_data &key )
|
||||
{
|
||||
sha256 check = sha256::hash(key.data, sizeof(key));
|
||||
sha256 check = sha256::hash((char*) key.data(), sizeof(key));
|
||||
static_assert(sizeof(key) + 4 == 37, "Elliptic public key size (or its hash) is incorrect");
|
||||
array<char, 37> data;
|
||||
memcpy(data.data, key.begin(), key.size());
|
||||
detail::chr37 data;
|
||||
memcpy(data.data(), key.begin(), key.size());
|
||||
memcpy(data.begin() + key.size(), (const char*)check._hash, 4);
|
||||
return fc::to_base58(data.begin(), data.size());
|
||||
return fc::to_base58((char*) data.begin(), data.size());
|
||||
}
|
||||
|
||||
public_key public_key::from_base58( const std::string& b58 )
|
||||
{
|
||||
array<char, 37> data;
|
||||
detail::chr37 data;
|
||||
size_t s = fc::from_base58(b58, (char*)&data, sizeof(data) );
|
||||
FC_ASSERT( s == sizeof(data) );
|
||||
|
||||
public_key_data key;
|
||||
sha256 check = sha256::hash(data.data, sizeof(key));
|
||||
FC_ASSERT( memcmp( (char*)check._hash, data.data + sizeof(key), 4 ) == 0 );
|
||||
memcpy( (char*)key.data, data.data, sizeof(key) );
|
||||
sha256 check = sha256::hash((char*) data.data(), sizeof(key));
|
||||
FC_ASSERT( memcmp( (char*)check._hash, data.data() + key.size(), 4 ) == 0 );
|
||||
memcpy( (char*)key.data(), data.data(), key.size() );
|
||||
return from_key_data(key);
|
||||
}
|
||||
|
||||
unsigned int public_key::fingerprint() const
|
||||
{
|
||||
public_key_data key = serialize();
|
||||
ripemd160 hash = ripemd160::hash( sha256::hash( key.begin(), key.size() ) );
|
||||
ripemd160 hash = ripemd160::hash( sha256::hash( (char*) key.begin(), key.size() ) );
|
||||
unsigned char* fp = (unsigned char*) hash._hash;
|
||||
return (fp[0] << 24) | (fp[1] << 16) | (fp[2] << 8) | fp[3];
|
||||
}
|
||||
|
||||
bool public_key::is_canonical( const compact_signature& c ) {
|
||||
return !(c.data[1] & 0x80)
|
||||
&& !(c.data[1] == 0 && !(c.data[2] & 0x80))
|
||||
&& !(c.data[33] & 0x80)
|
||||
&& !(c.data[33] == 0 && !(c.data[34] & 0x80));
|
||||
return !(c[1] & 0x80)
|
||||
&& !(c[1] == 0 && !(c[2] & 0x80))
|
||||
&& !(c[33] & 0x80)
|
||||
&& !(c[33] == 0 && !(c[34] & 0x80));
|
||||
}
|
||||
|
||||
private_key private_key::generate_from_seed( const fc::sha256& seed, const fc::sha256& offset )
|
||||
|
|
@ -234,7 +234,7 @@ namespace fc { namespace ecc {
|
|||
size_t buf_len = key.size() + 4;
|
||||
char *buffer = (char*)alloca(buf_len);
|
||||
memcpy( buffer, key.begin(), key.size() );
|
||||
fc::sha256 double_hash = fc::sha256::hash( fc::sha256::hash( key.begin(), key.size() ));
|
||||
fc::sha256 double_hash = fc::sha256::hash( fc::sha256::hash( (char*) key.begin(), key.size() ));
|
||||
memcpy( buffer + key.size(), double_hash.data(), 4 );
|
||||
return fc::to_base58( buffer, buf_len );
|
||||
}
|
||||
|
|
@ -311,7 +311,7 @@ namespace fc { namespace ecc {
|
|||
{
|
||||
const detail::chr37 data = detail::_derive_message( get_public_key().serialize(), i );
|
||||
hmac_sha512 mac;
|
||||
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
||||
fc::sha512 l = mac.digest( c.data(), c.data_size(), (char*) data.begin(), data.size() );
|
||||
return private_derive_rest( l, i );
|
||||
}
|
||||
|
||||
|
|
@ -320,7 +320,7 @@ namespace fc { namespace ecc {
|
|||
hmac_sha512 mac;
|
||||
private_key_secret key = get_secret();
|
||||
const detail::chr37 data = detail::_derive_message( key, i );
|
||||
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
||||
fc::sha512 l = mac.digest( c.data(), c.data_size(), (char*) data.begin(), data.size() );
|
||||
return private_derive_rest( l, i );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ namespace fc { namespace ecc {
|
|||
public_key_impl() BOOST_NOEXCEPT
|
||||
{
|
||||
_init_lib();
|
||||
memset( _key.data(), 0, _key.size() );
|
||||
}
|
||||
|
||||
public_key_impl( const public_key_impl& cpy ) BOOST_NOEXCEPT
|
||||
|
|
@ -52,16 +53,16 @@ namespace fc { namespace ecc {
|
|||
public_key_data _key;
|
||||
};
|
||||
|
||||
typedef fc::array<char,37> chr37;
|
||||
typedef std::array<char,37> chr37;
|
||||
chr37 _derive_message( const public_key_data& key, int i );
|
||||
fc::sha256 _left( const fc::sha512& v );
|
||||
fc::sha256 _right( const fc::sha512& v );
|
||||
const ec_group& get_curve();
|
||||
const private_key_secret& get_curve_order();
|
||||
const private_key_secret& get_half_curve_order();
|
||||
}
|
||||
} // detail
|
||||
|
||||
static const public_key_data empty_pub;
|
||||
static const public_key_data empty_pub = detail::public_key_impl()._key;
|
||||
static const private_key_secret empty_priv;
|
||||
|
||||
fc::sha512 private_key::get_shared_secret( const public_key& other )const
|
||||
|
|
@ -69,8 +70,8 @@ namespace fc { namespace ecc {
|
|||
FC_ASSERT( my->_key != empty_priv );
|
||||
FC_ASSERT( other.my->_key != empty_pub );
|
||||
public_key_data pub(other.my->_key);
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), (unsigned char*) pub.begin(), pub.size(), (unsigned char*) my->_key.data() ) );
|
||||
return fc::sha512::hash( pub.begin() + 1, pub.size() - 1 );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), pub.begin(), pub.size(), (unsigned char*) my->_key.data() ) );
|
||||
return fc::sha512::hash( (char*) pub.begin() + 1, pub.size() - 1 );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -104,7 +105,7 @@ namespace fc { namespace ecc {
|
|||
FC_ASSERT( my->_key != empty_pub );
|
||||
public_key_data new_key;
|
||||
memcpy( new_key.begin(), my->_key.begin(), new_key.size() );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) new_key.begin(), new_key.size(), (unsigned char*) digest.data() ) );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), new_key.begin(), new_key.size(), (unsigned char*) digest.data() ) );
|
||||
return public_key( new_key );
|
||||
}
|
||||
|
||||
|
|
@ -126,22 +127,22 @@ namespace fc { namespace ecc {
|
|||
public_key_point_data dat;
|
||||
unsigned int pk_len = my->_key.size();
|
||||
memcpy( dat.begin(), my->_key.begin(), pk_len );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_decompress( detail::_get_context(), (unsigned char *) dat.begin(), (int*) &pk_len ) );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_decompress( detail::_get_context(), dat.begin(), (int*) &pk_len ) );
|
||||
FC_ASSERT( pk_len == dat.size() );
|
||||
return dat;
|
||||
}
|
||||
|
||||
public_key::public_key( const public_key_point_data& dat )
|
||||
{
|
||||
const char* front = &dat.data[0];
|
||||
const unsigned char* front = dat.data();
|
||||
if( *front == 0 ){}
|
||||
else
|
||||
{
|
||||
EC_KEY *key = EC_KEY_new_by_curve_name( NID_secp256k1 );
|
||||
key = o2i_ECPublicKey( &key, (const unsigned char**)&front, sizeof(dat) );
|
||||
key = o2i_ECPublicKey( &key, &front, sizeof(dat) );
|
||||
FC_ASSERT( key );
|
||||
EC_KEY_set_conv_form( key, POINT_CONVERSION_COMPRESSED );
|
||||
unsigned char* buffer = (unsigned char*) my->_key.begin();
|
||||
unsigned char* buffer = my->_key.begin();
|
||||
i2o_ECPublicKey( key, &buffer ); // FIXME: questionable memory handling
|
||||
EC_KEY_free( key );
|
||||
}
|
||||
|
|
@ -154,7 +155,7 @@ namespace fc { namespace ecc {
|
|||
|
||||
public_key::public_key( const compact_signature& c, const fc::sha256& digest, bool check_canonical )
|
||||
{
|
||||
int nV = c.data[0];
|
||||
int nV = c[0];
|
||||
if (nV<27 || nV>=35)
|
||||
FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );
|
||||
|
||||
|
|
@ -164,7 +165,7 @@ namespace fc { namespace ecc {
|
|||
}
|
||||
|
||||
unsigned int pk_len;
|
||||
FC_ASSERT( secp256k1_ecdsa_recover_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) c.begin() + 1, (unsigned char*) my->_key.begin(), (int*) &pk_len, 1, (*c.begin() - 27) & 3 ) );
|
||||
FC_ASSERT( secp256k1_ecdsa_recover_compact( detail::_get_context(), (unsigned char*) digest.data(), c.begin() + 1, my->_key.begin(), (int*) &pk_len, 1, (*c.begin() - 27) & 3 ) );
|
||||
FC_ASSERT( pk_len == my->_key.size() );
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +181,7 @@ namespace fc { namespace ecc {
|
|||
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
||||
fc::sha256 left = detail::_left(l);
|
||||
FC_ASSERT( left < detail::get_curve_order() );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) key.begin(), key.size(), (unsigned char*) left.data() ) > 0 );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), key.begin(), key.size(), (unsigned char*) left.data() ) > 0 );
|
||||
// FIXME: check validity - if left + key == infinity then invalid
|
||||
extended_public_key result( key, detail::_right(l), i, fingerprint(), depth + 1 );
|
||||
return result;
|
||||
|
|
@ -204,7 +205,7 @@ namespace fc { namespace ecc {
|
|||
commitment_type blind( const blind_factor_type& blind, uint64_t value )
|
||||
{
|
||||
commitment_type result;
|
||||
FC_ASSERT( secp256k1_pedersen_commit( detail::_get_context(), (unsigned char*)&result, (unsigned char*)&blind, value ) );
|
||||
FC_ASSERT( secp256k1_pedersen_commit( detail::_get_context(), result.data(), (unsigned char*) blind.data(), value ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -212,8 +213,8 @@ namespace fc { namespace ecc {
|
|||
{
|
||||
blind_factor_type result;
|
||||
std::vector<const unsigned char*> blinds(blinds_in.size());
|
||||
for( uint32_t i = 0; i < blinds_in.size(); ++i ) blinds[i] = (const unsigned char*)&blinds_in[i];
|
||||
FC_ASSERT( secp256k1_pedersen_blind_sum( detail::_get_context(), (unsigned char*)&result, blinds.data(), blinds_in.size(), non_neg ) );
|
||||
for( uint32_t i = 0; i < blinds_in.size(); ++i ) blinds[i] = (unsigned char*) blinds_in[i].data();
|
||||
FC_ASSERT( secp256k1_pedersen_blind_sum( detail::_get_context(), (unsigned char*) result.data(), blinds.data(), blinds_in.size(), non_neg ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -221,16 +222,16 @@ namespace fc { namespace ecc {
|
|||
bool verify_sum( const std::vector<commitment_type>& commits_in, const std::vector<commitment_type>& neg_commits_in, int64_t excess )
|
||||
{
|
||||
std::vector<const unsigned char*> commits(commits_in.size());
|
||||
for( uint32_t i = 0; i < commits_in.size(); ++i ) commits[i] = (const unsigned char*)&commits_in[i];
|
||||
for( uint32_t i = 0; i < commits_in.size(); ++i ) commits[i] = commits_in[i].data();
|
||||
std::vector<const unsigned char*> neg_commits(neg_commits_in.size());
|
||||
for( uint32_t i = 0; i < neg_commits_in.size(); ++i ) neg_commits[i] = (const unsigned char*)&neg_commits_in[i];
|
||||
for( uint32_t i = 0; i < neg_commits_in.size(); ++i ) neg_commits[i] = neg_commits_in[i].data();
|
||||
|
||||
return secp256k1_pedersen_verify_tally( detail::_get_context(), commits.data(), commits.size(), neg_commits.data(), neg_commits.size(), excess );
|
||||
}
|
||||
|
||||
bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const std::vector<char>& proof )
|
||||
{
|
||||
return secp256k1_rangeproof_verify( detail::_get_context(), &min_val, &max_val, (const unsigned char*)&commit, (const unsigned char*)proof.data(), proof.size() );
|
||||
return secp256k1_rangeproof_verify( detail::_get_context(), &min_val, &max_val, commit.data(), (const unsigned char*)proof.data(), proof.size() );
|
||||
}
|
||||
|
||||
std::vector<char> range_proof_sign( uint64_t min_value,
|
||||
|
|
@ -245,12 +246,12 @@ namespace fc { namespace ecc {
|
|||
int proof_len = 5134;
|
||||
std::vector<char> proof(proof_len);
|
||||
|
||||
FC_ASSERT( secp256k1_rangeproof_sign( detail::_get_context(),
|
||||
(unsigned char*)proof.data(),
|
||||
&proof_len, min_value,
|
||||
(const unsigned char*)&commit,
|
||||
(const unsigned char*)&commit_blind,
|
||||
(const unsigned char*)&nonce,
|
||||
FC_ASSERT( secp256k1_rangeproof_sign( detail::_get_context(),
|
||||
(unsigned char*)proof.data(),
|
||||
&proof_len, min_value,
|
||||
commit.data(),
|
||||
(unsigned char*) commit_blind.data(),
|
||||
(unsigned char*) nonce.data(),
|
||||
base10_exp, min_bits, actual_value ) );
|
||||
proof.resize(proof_len);
|
||||
return proof;
|
||||
|
|
@ -269,14 +270,14 @@ namespace fc { namespace ecc {
|
|||
char msg[4096];
|
||||
int mlen = 0;
|
||||
FC_ASSERT( secp256k1_rangeproof_rewind( detail::_get_context(),
|
||||
(unsigned char*)&blind_out,
|
||||
(unsigned char*) blind_out.data(),
|
||||
&value_out,
|
||||
(unsigned char*)msg,
|
||||
(unsigned char*) msg,
|
||||
&mlen,
|
||||
(const unsigned char*)&nonce,
|
||||
(unsigned char*) nonce.data(),
|
||||
&min_val,
|
||||
&max_val,
|
||||
(const unsigned char*)&commit,
|
||||
commit.data(),
|
||||
(const unsigned char*)proof.data(),
|
||||
proof.size() ) );
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static void interop_do(const char * const data, size_t len) {
|
|||
}
|
||||
|
||||
static void interop_do(const fc::ecc::public_key_data &data) {
|
||||
interop_do(data.begin(), data.size());
|
||||
interop_do((char*) data.begin(), data.size());
|
||||
}
|
||||
|
||||
static void interop_do(const fc::ecc::private_key_secret &data) {
|
||||
|
|
@ -31,7 +31,7 @@ static void interop_do(const fc::ecc::private_key_secret &data) {
|
|||
}
|
||||
|
||||
static void interop_do(const fc::ecc::public_key_point_data &data) {
|
||||
interop_do(data.begin(), data.size());
|
||||
interop_do((char*) data.begin(), data.size());
|
||||
}
|
||||
|
||||
static void interop_do(const std::string &data) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
#define BOOST_TEST_MODULE HmacTest
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <fc/array.hpp>
|
||||
#include <fc/crypto/hex.hpp>
|
||||
#include <fc/crypto/hmac.hpp>
|
||||
#include <fc/crypto/sha224.hpp>
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
#include <fc/crypto/sha512.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
// See http://tools.ietf.org/html/rfc4231
|
||||
|
||||
static const std::string TEST1_KEY = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b";
|
||||
|
|
@ -77,9 +78,9 @@ static void run_test( const std::string& key, const std::string& data, const std
|
|||
const std::string& expect_256, const std::string& expect_512 )
|
||||
{
|
||||
|
||||
fc::array<char,N> key_arr;
|
||||
std::array<char,N> key_arr;
|
||||
BOOST_CHECK_EQUAL( fc::from_hex( key, key_arr.begin(), key_arr.size() ), N );
|
||||
fc::array<char,M> data_arr;
|
||||
std::array<char,M> data_arr;
|
||||
BOOST_CHECK_EQUAL( fc::from_hex( data, data_arr.begin(), data_arr.size() ), M );
|
||||
|
||||
BOOST_CHECK_EQUAL( mac_224.digest( key_arr.begin(), N, data_arr.begin(), M ).str(), expect_224 );
|
||||
|
|
|
|||
Loading…
Reference in a new issue