mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Add hardened_hash, prevents adversarial inputs
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -246,6 +246,7 @@
|
||||
<ClInclude Include="..\..\beast\utility\Debug.h" />
|
||||
<ClInclude Include="..\..\beast\utility\empty_base_optimization.h" />
|
||||
<ClInclude Include="..\..\beast\utility\Error.h" />
|
||||
<ClInclude Include="..\..\beast\utility\hardened_hash.h" />
|
||||
<ClInclude Include="..\..\beast\utility\hash_pair.h" />
|
||||
<ClInclude Include="..\..\beast\utility\is_call_possible.h" />
|
||||
<ClInclude Include="..\..\beast\utility\Journal.h" />
|
||||
@@ -756,6 +757,12 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\utility\tests\hardened_hash.test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\utility\Utility.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\PeerRole.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
@@ -766,6 +773,8 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\SSLContext.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\beast_asio.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPClientType.cpp">
|
||||
@@ -892,6 +901,8 @@
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\FatalError.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\SemanticVersion.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
@@ -1301,7 +1312,6 @@
|
||||
</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
@@ -1316,7 +1326,7 @@
|
||||
</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -1351,6 +1361,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -1227,6 +1227,9 @@
|
||||
<ClInclude Include="..\..\beast\unit_test\define_print.cpp">
|
||||
<Filter>beast\unit_test</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\utility\hardened_hash.h">
|
||||
<Filter>beast\utility</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\files\DirectoryIterator.cpp">
|
||||
@@ -1700,6 +1703,9 @@
|
||||
<ClCompile Include="..\..\beast\threads\tests\Atomic.test.cpp">
|
||||
<Filter>beast\threads\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\utility\tests\hardened_hash.test.cpp">
|
||||
<Filter>beast\utility\tests</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\TODO.txt">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
@@ -34,3 +34,4 @@
|
||||
|
||||
#include "tests/bassert.test.cpp"
|
||||
#include "tests/empty_base_optimization.test.cpp"
|
||||
#include "tests/hardened_hash.test.cpp"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
168
src/beast/beast/utility/hardened_hash.h
Normal file
168
src/beast/beast/utility/hardened_hash.h
Normal file
@@ -0,0 +1,168 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_UTILITY_HARDENED_HASH_H_INCLUDED
|
||||
#define BEAST_UTILITY_HARDENED_HASH_H_INCLUDED
|
||||
|
||||
#include "is_call_possible.h"
|
||||
|
||||
#include "noexcept.h"
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
#include "../cxx14/utility.h" // <utility>
|
||||
|
||||
// When set to 1, makes the seed per-process instead
|
||||
// of per default-constructed instance of hardened_hash
|
||||
//
|
||||
#ifndef BEAST_NO_HARDENED_HASH_INSTANCE_SEED
|
||||
# ifdef __GLIBCXX__
|
||||
# define BEAST_NO_HARDENED_HASH_INSTANCE_SEED 1
|
||||
# else
|
||||
# define BEAST_NO_HARDENED_HASH_INSTANCE_SEED 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Result>
|
||||
class hardened_hash_base
|
||||
{
|
||||
public:
|
||||
typedef Result result_type;
|
||||
|
||||
private:
|
||||
static
|
||||
result_type
|
||||
next_seed() noexcept
|
||||
{
|
||||
static std::mutex mutex;
|
||||
static std::random_device rng;
|
||||
static std::mt19937_64 gen (rng());
|
||||
std::lock_guard <std::mutex> lock (mutex);
|
||||
std::uniform_int_distribution <result_type> dist;
|
||||
result_type value;
|
||||
for(;;)
|
||||
{
|
||||
value = dist (gen);
|
||||
// VFALCO Do we care if 0 is picked?
|
||||
if (value != 0)
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
#if BEAST_NO_HARDENED_HASH_INSTANCE_SEED
|
||||
protected:
|
||||
result_type
|
||||
seed() const noexcept
|
||||
{
|
||||
static result_type const value (next_seed());
|
||||
return value;
|
||||
}
|
||||
|
||||
#else
|
||||
protected:
|
||||
hardened_hash_base() noexcept
|
||||
: m_seed (next_seed())
|
||||
{
|
||||
}
|
||||
|
||||
result_type
|
||||
seed() const noexcept
|
||||
{
|
||||
return m_seed;
|
||||
}
|
||||
|
||||
private:
|
||||
// VFALCO Should seed be per process or per hash function?
|
||||
result_type m_seed;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/** A std compatible hash adapter that resists adversarial inputs.
|
||||
For this to work, one of the following must exist:
|
||||
|
||||
* A member function of `T` called `hash_combine` with
|
||||
this signature:
|
||||
|
||||
@code
|
||||
|
||||
void hash_combine (std::size_t&) const noexcept;
|
||||
|
||||
@endcode
|
||||
|
||||
* A free function called `hash_combine`, found via argument
|
||||
dependent lookup, callable with this signature:
|
||||
|
||||
@code
|
||||
|
||||
void hash_combine (std::size_t, T const& t) noexcept;
|
||||
|
||||
@endcode
|
||||
*/
|
||||
template <class T>
|
||||
class hardened_hash
|
||||
: public detail::hardened_hash_base <std::size_t>
|
||||
{
|
||||
public:
|
||||
typedef T argument_type;
|
||||
using detail::hardened_hash_base <std::size_t>::result_type;
|
||||
|
||||
private:
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_hash_combine,hash_combine);
|
||||
|
||||
typedef detail::hardened_hash_base <std::size_t> base;
|
||||
|
||||
// Called when hash_combine is a member function
|
||||
result_type
|
||||
operator() (argument_type const& key, std::true_type) const noexcept
|
||||
{
|
||||
result_type result (base::seed());
|
||||
key.hash_combine (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
operator() (argument_type const& key, std::false_type) const noexcept
|
||||
{
|
||||
result_type result (base::seed());
|
||||
hash_combine (result, key);
|
||||
return result;
|
||||
}
|
||||
|
||||
public:
|
||||
hardened_hash() = default;
|
||||
|
||||
result_type
|
||||
operator() (argument_type const& key) const noexcept
|
||||
{
|
||||
return operator() (key, std::integral_constant <bool,
|
||||
has_hash_combine <T,void(result_type&)>::value>());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -29,25 +29,25 @@ namespace beast {
|
||||
//
|
||||
namespace is_call_possible_detail
|
||||
{
|
||||
template<typename T>
|
||||
template<typename Z>
|
||||
struct add_reference
|
||||
{
|
||||
typedef T& type;
|
||||
typedef Z& type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct add_reference<T&>
|
||||
template<typename Z>
|
||||
struct add_reference<Z&>
|
||||
{
|
||||
typedef T& type;
|
||||
typedef Z& type;
|
||||
};
|
||||
|
||||
template <typename T> class void_exp_result {};
|
||||
template <typename Z> class void_exp_result {};
|
||||
|
||||
template <typename T, typename U>
|
||||
U const& operator,(U const&, void_exp_result<T>);
|
||||
template <typename Z, typename U>
|
||||
U const& operator,(U const&, void_exp_result<Z>);
|
||||
|
||||
template <typename T, typename U>
|
||||
U& operator,(U&, void_exp_result<T>);
|
||||
template <typename Z, typename U>
|
||||
U& operator,(U&, void_exp_result<Z>);
|
||||
|
||||
template <typename src_type, typename dest_type>
|
||||
struct clone_constness
|
||||
@@ -63,10 +63,10 @@ namespace is_call_possible_detail
|
||||
}
|
||||
|
||||
#define BEAST_DEFINE_HAS_MEMBER_FUNCTION(trait_name, member_function_name) \
|
||||
template<typename T, typename IsCallPossibleSignature> class trait_name; \
|
||||
template<typename Z, typename IsCallPossibleSignature> class trait_name; \
|
||||
\
|
||||
template<typename T, typename Result> \
|
||||
class trait_name<T, Result(void)> \
|
||||
template<typename Z, typename Result> \
|
||||
class trait_name<Z, Result(void)> \
|
||||
{ \
|
||||
class yes { char m; }; \
|
||||
class no { yes m[2]; }; \
|
||||
@@ -74,7 +74,7 @@ class trait_name<T, Result(void)>
|
||||
{ \
|
||||
Result member_function_name(); \
|
||||
}; \
|
||||
struct base : public T, public base_mixin { private: base(); }; \
|
||||
struct base : public Z, public base_mixin { private: base(); }; \
|
||||
template <typename U, U t> class helper{}; \
|
||||
template <typename U> \
|
||||
static no deduce(U*, helper<Result (base_mixin::*)(), &U::member_function_name>* = 0); \
|
||||
@@ -83,8 +83,8 @@ public:
|
||||
static const bool value = sizeof(yes) == sizeof(deduce(static_cast<base*>(0))); \
|
||||
}; \
|
||||
\
|
||||
template<typename T, typename Result, typename Arg> \
|
||||
class trait_name<T, Result(Arg)> \
|
||||
template<typename Z, typename Result, typename Arg> \
|
||||
class trait_name<Z, Result(Arg)> \
|
||||
{ \
|
||||
class yes { char m; }; \
|
||||
class no { yes m[2]; }; \
|
||||
@@ -92,7 +92,7 @@ class trait_name<T, Result(Arg)>
|
||||
{ \
|
||||
Result member_function_name(Arg); \
|
||||
}; \
|
||||
struct base : public T, public base_mixin { private: base(); }; \
|
||||
struct base : public Z, public base_mixin { private: base(); }; \
|
||||
template <typename U, U t> class helper{}; \
|
||||
template <typename U> \
|
||||
static no deduce(U*, helper<Result (base_mixin::*)(Arg), &U::member_function_name>* = 0); \
|
||||
@@ -101,8 +101,8 @@ public:
|
||||
static const bool value = sizeof(yes) == sizeof(deduce(static_cast<base*>(0))); \
|
||||
}; \
|
||||
\
|
||||
template<typename T, typename Result, typename Arg1, typename Arg2> \
|
||||
class trait_name<T, Result(Arg1,Arg2)> \
|
||||
template<typename Z, typename Result, typename Arg1, typename Arg2> \
|
||||
class trait_name<Z, Result(Arg1,Arg2)> \
|
||||
{ \
|
||||
class yes { char m; }; \
|
||||
class no { yes m[2]; }; \
|
||||
@@ -110,7 +110,7 @@ class trait_name<T, Result(Arg1,Arg2)>
|
||||
{ \
|
||||
Result member_function_name(Arg1,Arg2); \
|
||||
}; \
|
||||
struct base : public T, public base_mixin { private: base(); }; \
|
||||
struct base : public Z, public base_mixin { private: base(); }; \
|
||||
template <typename U, U t> class helper{}; \
|
||||
template <typename U> \
|
||||
static no deduce(U*, helper<Result (base_mixin::*)(Arg1,Arg2), &U::member_function_name>* = 0); \
|
||||
@@ -119,8 +119,8 @@ public:
|
||||
static const bool value = sizeof(yes) == sizeof(deduce(static_cast<base*>(0))); \
|
||||
}; \
|
||||
\
|
||||
template<typename T, typename Result, typename Arg1, typename Arg2, typename Arg3> \
|
||||
class trait_name<T, Result(Arg1,Arg2,Arg3)> \
|
||||
template<typename Z, typename Result, typename Arg1, typename Arg2, typename Arg3> \
|
||||
class trait_name<Z, Result(Arg1,Arg2,Arg3)> \
|
||||
{ \
|
||||
class yes { char m; }; \
|
||||
class no { yes m[2]; }; \
|
||||
@@ -128,7 +128,7 @@ class trait_name<T, Result(Arg1,Arg2,Arg3)>
|
||||
{ \
|
||||
Result member_function_name(Arg1,Arg2,Arg3); \
|
||||
}; \
|
||||
struct base : public T, public base_mixin { private: base(); }; \
|
||||
struct base : public Z, public base_mixin { private: base(); }; \
|
||||
template <typename U, U t> class helper{}; \
|
||||
template <typename U> \
|
||||
static no deduce(U*, helper<Result (base_mixin::*)(Arg1,Arg2,Arg3), &U::member_function_name>* = 0); \
|
||||
@@ -137,8 +137,8 @@ public:
|
||||
static const bool value = sizeof(yes) == sizeof(deduce(static_cast<base*>(0))); \
|
||||
}; \
|
||||
\
|
||||
template<typename T, typename Result, typename Arg1, typename Arg2, typename Arg3, typename Arg4> \
|
||||
class trait_name<T, Result(Arg1,Arg2,Arg3,Arg4)> \
|
||||
template<typename Z, typename Result, typename Arg1, typename Arg2, typename Arg3, typename Arg4> \
|
||||
class trait_name<Z, Result(Arg1,Arg2,Arg3,Arg4)> \
|
||||
{ \
|
||||
class yes { char m; }; \
|
||||
class no { yes m[2]; }; \
|
||||
@@ -146,7 +146,7 @@ class trait_name<T, Result(Arg1,Arg2,Arg3,Arg4)>
|
||||
{ \
|
||||
Result member_function_name(Arg1,Arg2,Arg3,Arg4); \
|
||||
}; \
|
||||
struct base : public T, public base_mixin { private: base(); }; \
|
||||
struct base : public Z, public base_mixin { private: base(); }; \
|
||||
template <typename U, U t> class helper{}; \
|
||||
template <typename U> \
|
||||
static no deduce(U*, helper<Result (base_mixin::*)(Arg1,Arg2,Arg3,Arg4), &U::member_function_name>* = 0); \
|
||||
@@ -165,17 +165,17 @@ template <typename DT, typename IsCallPossibleSignature>
|
||||
struct trait_name \
|
||||
{ \
|
||||
private: \
|
||||
typedef std::remove_reference_t <DT> T; \
|
||||
typedef std::remove_reference_t <DT> Z; \
|
||||
class yes {}; \
|
||||
class no { yes m[2]; }; \
|
||||
struct derived : public T \
|
||||
struct derived : public Z \
|
||||
{ \
|
||||
using T::member_function_name; \
|
||||
using Z::member_function_name; \
|
||||
no member_function_name(...) const; \
|
||||
private: derived (); \
|
||||
}; \
|
||||
\
|
||||
typedef typename beast::is_call_possible_detail::clone_constness<T, derived>::type derived_type; \
|
||||
typedef typename beast::is_call_possible_detail::clone_constness<Z, derived>::type derived_type; \
|
||||
\
|
||||
template <typename U, typename Result> \
|
||||
struct return_value_check \
|
||||
@@ -183,7 +183,7 @@ private:
|
||||
static yes deduce(Result); \
|
||||
static no deduce(...); \
|
||||
static no deduce(no); \
|
||||
static no deduce(beast::is_call_possible_detail::void_exp_result<T>); \
|
||||
static no deduce(beast::is_call_possible_detail::void_exp_result<Z>); \
|
||||
}; \
|
||||
\
|
||||
template <typename U> \
|
||||
@@ -206,8 +206,8 @@ private:
|
||||
\
|
||||
static const bool value = \
|
||||
sizeof( \
|
||||
return_value_check<T, Result>::deduce( \
|
||||
(test_me.member_function_name(), beast::is_call_possible_detail::void_exp_result<T>())) \
|
||||
return_value_check<Z, Result>::deduce( \
|
||||
(test_me.member_function_name(), beast::is_call_possible_detail::void_exp_result<Z>())) \
|
||||
) == sizeof(yes); \
|
||||
}; \
|
||||
\
|
||||
@@ -219,8 +219,8 @@ private:
|
||||
\
|
||||
static const bool value = \
|
||||
sizeof( \
|
||||
return_value_check<T, Result>::deduce( \
|
||||
(test_me.member_function_name(arg), beast::is_call_possible_detail::void_exp_result<T>()) \
|
||||
return_value_check<Z, Result>::deduce( \
|
||||
(test_me.member_function_name(arg), beast::is_call_possible_detail::void_exp_result<Z>()) \
|
||||
) \
|
||||
) == sizeof(yes); \
|
||||
}; \
|
||||
@@ -234,8 +234,8 @@ private:
|
||||
\
|
||||
static const bool value = \
|
||||
sizeof( \
|
||||
return_value_check<T, Result>::deduce( \
|
||||
(test_me.member_function_name(arg1,arg2), beast::is_call_possible_detail::void_exp_result<T>()) \
|
||||
return_value_check<Z, Result>::deduce( \
|
||||
(test_me.member_function_name(arg1,arg2), beast::is_call_possible_detail::void_exp_result<Z>()) \
|
||||
) \
|
||||
) == sizeof(yes); \
|
||||
}; \
|
||||
@@ -250,8 +250,8 @@ private:
|
||||
\
|
||||
static const bool value = \
|
||||
sizeof( \
|
||||
return_value_check<T, Result>::deduce( \
|
||||
(test_me.member_function_name(arg1,arg2,arg3), beast::is_call_possible_detail::void_exp_result<T>()) \
|
||||
return_value_check<Z, Result>::deduce( \
|
||||
(test_me.member_function_name(arg1,arg2,arg3), beast::is_call_possible_detail::void_exp_result<Z>()) \
|
||||
) \
|
||||
) == sizeof(yes); \
|
||||
}; \
|
||||
@@ -267,15 +267,15 @@ private:
|
||||
\
|
||||
static const bool value = \
|
||||
sizeof( \
|
||||
return_value_check<T, Result>::deduce( \
|
||||
return_value_check<Z, Result>::deduce( \
|
||||
(test_me.member_function_name(arg1,arg2,arg3,arg4), \
|
||||
beast::is_call_possible_detail::void_exp_result<T>()) \
|
||||
beast::is_call_possible_detail::void_exp_result<Z>()) \
|
||||
) \
|
||||
) == sizeof(yes); \
|
||||
}; \
|
||||
\
|
||||
public: \
|
||||
static const bool value = impl<trait_name##_detail::template has_member<T,IsCallPossibleSignature>::value, \
|
||||
static const bool value = impl<trait_name##_detail::template has_member<Z,IsCallPossibleSignature>::value, \
|
||||
IsCallPossibleSignature>::value; \
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//-------------------- empty_base_optimization.test.cpp ------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2014 Ripple Labs Inc.
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
311
src/beast/beast/utility/tests/hardened_hash.test.cpp
Normal file
311
src/beast/beast/utility/tests/hardened_hash.test.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include "../../../BeastConfig.h"
|
||||
#endif
|
||||
|
||||
#include "../hardened_hash.h"
|
||||
#include "../../unit_test/suite.h"
|
||||
|
||||
#include "../../crypto/Sha256.h"
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
class test_user_type_member
|
||||
{
|
||||
private:
|
||||
T t;
|
||||
|
||||
public:
|
||||
explicit test_user_type_member (T const& t_ = T())
|
||||
: t (t_)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
hash_combine (std::size_t& seed) const noexcept
|
||||
{
|
||||
boost::hash_combine (seed, t);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class test_user_type_free
|
||||
{
|
||||
private:
|
||||
T t;
|
||||
|
||||
public:
|
||||
explicit test_user_type_free (T const& t_ = T())
|
||||
: t (t_)
|
||||
{
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
hash_combine (std::size_t& seed,
|
||||
test_user_type_free const& v) noexcept
|
||||
{
|
||||
boost::hash_combine (seed, v.t);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
using test_hardened_unordered_set =
|
||||
std::unordered_set <T, hardened_hash <T>>;
|
||||
|
||||
template <class T>
|
||||
using test_hardened_unordered_map =
|
||||
std::unordered_map <T, int, hardened_hash <T>>;
|
||||
|
||||
template <class T>
|
||||
using test_hardened_unordered_multiset =
|
||||
std::unordered_multiset <T, hardened_hash <T>>;
|
||||
|
||||
template <class T>
|
||||
using test_hardened_unordered_multimap =
|
||||
std::unordered_multimap <T, int, hardened_hash <T>>;
|
||||
|
||||
} // beast
|
||||
|
||||
template <std::size_t Bits, class UInt = std::uint64_t>
|
||||
class unsigned_integer
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_integral<UInt>::value &&
|
||||
std::is_unsigned <UInt>::value,
|
||||
"UInt must be an unsigned integral type");
|
||||
|
||||
static_assert (Bits%(8*sizeof(UInt))==0,
|
||||
"Bits must be a multiple of 8*sizeof(UInt)");
|
||||
|
||||
static_assert (Bits >= (8*sizeof(UInt)),
|
||||
"Bits must be at least 8*sizeof(UInt)");
|
||||
|
||||
static std::size_t const size = Bits/(8*sizeof(UInt));
|
||||
|
||||
std::array <UInt, size> m_vec;
|
||||
|
||||
public:
|
||||
typedef UInt value_type;
|
||||
|
||||
static std::size_t const bits = Bits;
|
||||
static std::size_t const bytes = bits / 8;
|
||||
|
||||
template <class Int>
|
||||
static
|
||||
unsigned_integer
|
||||
from_number (Int v)
|
||||
{
|
||||
unsigned_integer result;
|
||||
for (std::size_t i (1); i < size; ++i)
|
||||
result.m_vec [i] = 0;
|
||||
result.m_vec[0] = v;
|
||||
return result;
|
||||
}
|
||||
|
||||
void*
|
||||
data() noexcept
|
||||
{
|
||||
return &m_vec[0];
|
||||
}
|
||||
|
||||
void const*
|
||||
data() const noexcept
|
||||
{
|
||||
return &m_vec[0];
|
||||
}
|
||||
|
||||
void
|
||||
hash_combine (std::size_t& seed) const noexcept
|
||||
{
|
||||
for (std::size_t i (0); i < size; ++i)
|
||||
boost::hash_combine (seed, m_vec[i]);
|
||||
}
|
||||
|
||||
friend
|
||||
std::ostream&
|
||||
operator<< (std::ostream& s, unsigned_integer const& v)
|
||||
{
|
||||
for (std::size_t i (0); i < size; ++i)
|
||||
s <<
|
||||
std::hex <<
|
||||
std::setfill ('0') <<
|
||||
std::setw (2*sizeof(UInt)) <<
|
||||
v.m_vec[i]
|
||||
;
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
typedef unsigned_integer <256, std::size_t> sha256_t;
|
||||
|
||||
static_assert (sha256_t::bits == 256,
|
||||
"sha256_t must have 256 bits");
|
||||
|
||||
} // beast
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace beast {
|
||||
|
||||
class hardened_hash_test
|
||||
: public unit_test::suite
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
void
|
||||
check ()
|
||||
{
|
||||
T t{};
|
||||
hardened_hash <T>() (t);
|
||||
pass();
|
||||
}
|
||||
|
||||
template <template <class T> class U>
|
||||
void
|
||||
check_user_type()
|
||||
{
|
||||
check <U <bool>> ();
|
||||
check <U <char>> ();
|
||||
check <U <signed char>> ();
|
||||
check <U <unsigned char>> ();
|
||||
// These cause trouble for boost
|
||||
//check <U <char16_t>> ();
|
||||
//check <U <char32_t>> ();
|
||||
check <U <wchar_t>> ();
|
||||
check <U <short>> ();
|
||||
check <U <unsigned short>> ();
|
||||
check <U <int>> ();
|
||||
check <U <unsigned int>> ();
|
||||
check <U <long>> ();
|
||||
check <U <long long>> ();
|
||||
check <U <unsigned long>> ();
|
||||
check <U <unsigned long long>> ();
|
||||
check <U <float>> ();
|
||||
check <U <double>> ();
|
||||
check <U <long double>> ();
|
||||
}
|
||||
|
||||
template <template <class T> class C >
|
||||
void
|
||||
check_container()
|
||||
{
|
||||
{
|
||||
C <detail::test_user_type_member <std::string>> c;
|
||||
}
|
||||
|
||||
pass();
|
||||
|
||||
{
|
||||
C <detail::test_user_type_free <std::string>> c;
|
||||
}
|
||||
|
||||
pass();
|
||||
}
|
||||
|
||||
void
|
||||
test_user_types()
|
||||
{
|
||||
testcase ("user types");
|
||||
check_user_type <detail::test_user_type_member> ();
|
||||
check_user_type <detail::test_user_type_free> ();
|
||||
}
|
||||
|
||||
void
|
||||
test_containers()
|
||||
{
|
||||
testcase ("containers");
|
||||
check_container <detail::test_hardened_unordered_set>();
|
||||
check_container <detail::test_hardened_unordered_map>();
|
||||
check_container <detail::test_hardened_unordered_multiset>();
|
||||
check_container <detail::test_hardened_unordered_multimap>();
|
||||
}
|
||||
|
||||
void
|
||||
run ()
|
||||
{
|
||||
test_user_types();
|
||||
test_containers();
|
||||
}
|
||||
};
|
||||
|
||||
class hardened_hash_sha256_test
|
||||
: public unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
testSHA256()
|
||||
{
|
||||
testcase ("sha256");
|
||||
|
||||
log <<
|
||||
"sizeof(std::size_t) == " << sizeof(std::size_t);
|
||||
|
||||
hardened_hash <sha256_t> h;
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
sha256_t v (sha256_t::from_number (i));
|
||||
Sha256::digest_type d;
|
||||
Sha256::hash (v.data(), sha256_t::bytes, d);
|
||||
sha256_t d_;
|
||||
memcpy (d_.data(), d.data(), sha256_t::bytes);
|
||||
std::size_t result (h (d_));
|
||||
log <<
|
||||
"i=" << std::setw(2) << i << " " <<
|
||||
"sha256=0x" << d_ << " " <<
|
||||
"hash=0x" <<
|
||||
std::setfill ('0') <<
|
||||
std::setw (2*sizeof(std::size_t)) << result
|
||||
;
|
||||
pass();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run ()
|
||||
{
|
||||
testSHA256();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(hardened_hash,utility,beast);
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(hardened_hash_sha256,utility,beast);
|
||||
|
||||
} // beast
|
||||
Reference in New Issue
Block a user