Skip to content

Commit

Permalink
Merge pull request #1549 from evoskuil/master
Browse files Browse the repository at this point in the history
Mild hash library refactoring.
  • Loading branch information
evoskuil authored Nov 22, 2024
2 parents a87e103 + 5beb479 commit 319f48e
Show file tree
Hide file tree
Showing 25 changed files with 633 additions and 699 deletions.
6 changes: 3 additions & 3 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ test_libbitcoin_system_test_SOURCES = \
test/hash/sha/sha160.cpp \
test/hash/sha/sha256.cpp \
test/hash/sha/sha512.cpp \
test/hash/sha/vectorization.cpp \
test/hash/sha/vector.cpp \
test/intrinsics/haves.cpp \
test/intrinsics/intrinsics.cpp \
test/intrinsics/xcpu/cpuid.cpp \
Expand Down Expand Up @@ -619,8 +619,8 @@ include_bitcoin_system_impl_hash_rmd_HEADERS = \
include_bitcoin_system_impl_hash_shadir = ${includedir}/bitcoin/system/impl/hash/sha
include_bitcoin_system_impl_hash_sha_HEADERS = \
include/bitcoin/system/impl/hash/sha/algorithm.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_compression.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_vectorization.ipp
include/bitcoin/system/impl/hash/sha/algorithm_native.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_vector.ipp

include_bitcoin_system_impl_machinedir = ${includedir}/bitcoin/system/impl/machine
include_bitcoin_system_impl_machine_HEADERS = \
Expand Down
2 changes: 1 addition & 1 deletion builds/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ if (with-tests)
"../../test/hash/sha/sha160.cpp"
"../../test/hash/sha/sha256.cpp"
"../../test/hash/sha/sha512.cpp"
"../../test/hash/sha/vectorization.cpp"
"../../test/hash/sha/vector.cpp"
"../../test/intrinsics/haves.cpp"
"../../test/intrinsics/intrinsics.cpp"
"../../test/intrinsics/xcpu/cpuid.cpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
<ObjectFileName>$(IntDir)test_hash_sha_sha256.obj</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\..\..\test\hash\sha\sha512.cpp" />
<ClCompile Include="..\..\..\..\test\hash\sha\vectorization.cpp" />
<ClCompile Include="..\..\..\..\test\hash\sha\vector.cpp" />
<ClCompile Include="..\..\..\..\test\hash\siphash.cpp" />
<ClCompile Include="..\..\..\..\test\intrinsics\haves.cpp" />
<ClCompile Include="..\..\..\..\test\intrinsics\intrinsics.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@
<ClCompile Include="..\..\..\..\test\hash\sha\sha512.cpp">
<Filter>src\hash\sha</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\hash\sha\vectorization.cpp">
<ClCompile Include="..\..\..\..\test\hash\sha\vector.cpp">
<Filter>src\hash\sha</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\hash\siphash.cpp">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,8 @@
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\rmd\algorithm.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\scrypt.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_compression.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_vectorization.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_native.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_vector.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\machine\interpreter.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\machine\number.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\machine\program.ipp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1510,10 +1510,10 @@
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_compression.ipp">
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_native.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_vectorization.ipp">
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_vector.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\machine\interpreter.ipp">
Expand Down
18 changes: 16 additions & 2 deletions include/bitcoin/system/constraints.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ template <typename Type>
using if_integer = bool_if<
is_integer<Type>>;

template <typename Type>
using if_non_integer = bool_if<
!is_integer<Type>>;

template <typename Type>
using if_signed_integer = bool_if<
is_integer<Type> &&
Expand Down Expand Up @@ -198,15 +202,25 @@ using if_not_uintx = bool_if<
!is_uintx<Type>>;

/// Integral integer types (native, non-floating point, non-bool).
/// All integrals are integers but not all integers are integral.

template <typename Type>
using if_integral = bool_if<
is_integral<Type>>;

template <typename Type>
using if_non_integral = bool_if<
!is_integral<Type>>;

// Alias for if_integral.
template <typename Type>
using if_integral_integer = bool_if<
is_integral_integer<Type>>;

template <typename Type>
using if_non_integral_integer = bool_if<
is_integer<Type> &&
!is_integral<Type>>;
!is_integral<Type> &&
is_integer<Type>>;

template <typename Type>
using if_signed_integral_integer = bool_if<
Expand Down
85 changes: 50 additions & 35 deletions include/bitcoin/system/hash/sha/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ namespace system {
namespace sha {

/// SHA hashing algorithm.
/// Compression not yet implemented.
/// Native not yet implemented.
/// Vectorization of message schedules and merkle hashes.
template <typename SHA, bool Compressed = true, bool Vectorized = true,
bool Cached = true, if_same<typename SHA::T, sha::shah_t> = true>
template <typename SHA, bool Native = true, bool Vector = true, bool Cached = true,
if_same<typename SHA::T, sha::shah_t> = true>
class algorithm
: algorithm_t
{
Expand Down Expand Up @@ -163,13 +163,14 @@ class algorithm
INLINE static constexpr void schedule_(auto& buffer) NOEXCEPT;
static constexpr void schedule(auto& buffer) NOEXCEPT;

INLINE static constexpr void input(auto& buffer, const auto& state) NOEXCEPT;
/// A double hash optimization (hashing the output of the first hash).
INLINE static constexpr void reinput(auto& buffer, const auto& state) NOEXCEPT;

/// Parsing
/// Parsing (endian sensitive)
/// -----------------------------------------------------------------------
INLINE static constexpr void input(buffer_t& buffer, const block_t& block) NOEXCEPT;
INLINE static constexpr void input1(buffer_t& buffer, const half_t& half) NOEXCEPT;
INLINE static constexpr void input2(buffer_t& buffer, const half_t& half) NOEXCEPT;
INLINE static constexpr void input_left(buffer_t& buffer, const half_t& half) NOEXCEPT;
INLINE static constexpr void input_right(buffer_t& buffer, const half_t& half) NOEXCEPT;
INLINE static constexpr digest_t output(const state_t& state) NOEXCEPT;

/// Padding
Expand Down Expand Up @@ -197,7 +198,7 @@ class algorithm
/// Merkle iteration.
/// -----------------------------------------------------------------------
VCONSTEXPR static void merkle_hash_(digests_t& digests,
size_t offset = zero) NOEXCEPT;
size_t offset=zero) NOEXCEPT;

private:
using pad_t = std_array<word_t, subtract(SHA::block_words,
Expand All @@ -208,24 +209,16 @@ class algorithm
static CONSTEVAL chunk_t chunk_pad() NOEXCEPT;
static CONSTEVAL pad_t stream_pad() NOEXCEPT;

/// Compression.
/// -----------------------------------------------------------------------
protected:
public:
static constexpr auto have_shani = Compressed && system::with_shani;
static constexpr auto have_neon = Compressed && system::with_neon;
static constexpr auto compression = have_shani || have_neon;

/// Vectorization.
/// -----------------------------------------------------------------------
/// ---------------------------------------------------------------------------
protected:
/// Extended integer capacity for uint32_t/uint64_t is 2/4/8/16 only.
template <size_t Lanes>
static constexpr auto is_valid_lanes =
(Lanes == 16u || Lanes == 8u || Lanes == 4u || Lanes == 2u);

template <size_t Lanes, bool_if<is_valid_lanes<Lanes>> = true>
using wblock_t = std_array<words_t, Lanes>;
using xblock_t = std_array<words_t, Lanes>;
template <typename xWord, if_extended<xWord> = true>
using xbuffer_t = std_array<xWord, SHA::rounds>;
template <typename xWord, if_extended<xWord> = true>
Expand All @@ -238,7 +231,7 @@ class algorithm
/// -----------------------------------------------------------------------

template <size_t Word, size_t Lanes>
INLINE static auto pack(const wblock_t<Lanes>& wblock) NOEXCEPT;
INLINE static auto pack(const xblock_t<Lanes>& xblock) NOEXCEPT;

template <typename xWord>
INLINE static void input(xbuffer_t<xWord>& xbuffer,
Expand Down Expand Up @@ -286,7 +279,7 @@ class algorithm
INLINE static Word extract(xWord a) NOEXCEPT;

template <typename xWord>
INLINE static void compress_dispatch(state_t& state,
INLINE static void compress_invoke(state_t& state,
const xbuffer_t<xWord>& xbuffer) NOEXCEPT;

template <typename xWord, if_extended<xWord> = true>
Expand All @@ -305,34 +298,56 @@ class algorithm
INLINE static auto sigma0_8(auto x1, auto x2, auto x3, auto x4, auto x5,
auto x6, auto x7, auto x8) NOEXCEPT;

template<size_t Round, size_t Offset>
INLINE static void prepare1(buffer_t& buffer, const auto& xsigma0) NOEXCEPT;
template<size_t Round>
INLINE static void prepare_dispatch(buffer_t& buffer) NOEXCEPT;
INLINE static void schedule_invoke(buffer_t& buffer) NOEXCEPT;
INLINE static void schedule_dispatch(auto& buffer) NOEXCEPT;
INLINE static void prepare8(buffer_t& buffer) NOEXCEPT;

template <typename xWord>
INLINE static void schedule_vector(xbuffer_t<xWord>& xbuffer) NOEXCEPT;
INLINE static void schedule_vector(buffer_t& buffer) NOEXCEPT;

/// Native.
/// ---------------------------------------------------------------------------
protected:
using cword_t = xint128_t;
static constexpr auto cratio = sizeof(cword_t) / SHA::word_bytes;
static constexpr auto crounds = SHA::rounds / cratio;
using cbuffer_t = std_array<cword_t, crounds>;
using cstate_t = std_array<xint128_t, two>;

template <typename xWord>
INLINE static void schedule_native(xbuffer_t<xWord>& xbuffer) NOEXCEPT;
INLINE static void schedule_native(buffer_t& buffer) NOEXCEPT;

public:
static constexpr auto have_x128 = Vectorized && system::with_sse41;
static constexpr auto have_x256 = Vectorized && system::with_avx2;
static constexpr auto have_x512 = Vectorized && system::with_avx512;
static constexpr auto vectorization = (have_x128 || have_x256 || have_x512)
static constexpr auto use_neon = Native && system::with_neon;
static constexpr auto use_shani = Native && system::with_shani;
static constexpr auto native = use_shani || use_neon;

static constexpr auto use_x128 = Vector && system::with_sse41;
static constexpr auto use_x256 = Vector && system::with_avx2;
static constexpr auto use_x512 = Vector && system::with_avx512;
static constexpr auto vector = (use_x128 || use_x256 || use_x512)
&& !(build_x32 && is_same_size<word_t, uint64_t>);

static constexpr auto min_lanes =
(have_x128 ? bytes<128> :
(have_x256 ? bytes<256> :
(have_x512 ? bytes<512> : 0))) / SHA::word_bytes;
(use_x128 ? bytes<128> :
(use_x256 ? bytes<256> :
(use_x512 ? bytes<512> : 0))) / SHA::word_bytes;
};

} // namespace sha
} // namespace system
} // namespace libbitcoin

#define TEMPLATE template <typename SHA, bool Compressed, bool Vectorized, \
bool Cached, if_same<typename SHA::T, sha::shah_t> If>
#define CLASS algorithm<SHA, Compressed, Vectorized, Cached, If>
#define TEMPLATE template <typename SHA, bool Native, bool Vector, bool Cached, \
if_same<typename SHA::T, sha::shah_t> If>
#define CLASS algorithm<SHA, Native, Vector, Cached, If>

#include <bitcoin/system/impl/hash/sha/algorithm.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_compression.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_vectorization.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_native.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_vector.ipp>

#undef CLASS
#undef TEMPLATE
Expand Down
15 changes: 8 additions & 7 deletions include/bitcoin/system/have.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,21 +128,22 @@
#endif

/// XCPU architecture intrinsics sse41, avx2, avx512f, sha-ni.
/// All require runtime evaluation, as the binary is portable across XCPUs.
/// This assumes that avx512 implies avx2 and that all imply sse41.
/// All require runtime evaluation for the binary is portable across XCPUs.
#if defined(HAVE_XCPU)
// TODO: CLANG/GCC compile test and set -msse4 -mavx2 -mavx512f -msha.
#if defined (WITH_AVX512)
#if defined(WITH_SHANI)
#define HAVE_SHANI
#endif
#if defined(WITH_AVX512)
#define HAVE_AVX512
#endif
#if defined (WITH_AVX2)
#if defined(WITH_AVX2) || defined(WITH_AVX512)
#define HAVE_AVX2
#endif
#if defined (WITH_SSE41)
#if defined(WITH_SSE41) || defined(WITH_AVX2) || defined(WITH_SHANI)
#define HAVE_SSE41
#endif
#if defined (WITH_SHANI)
#define HAVE_SHANI
#endif
#endif

/// MSC predefined constant for Visual Studio version (exclusive).
Expand Down
Loading

0 comments on commit 319f48e

Please sign in to comment.