Skip to content

Commit

Permalink
Merge pull request #1551 from evoskuil/master
Browse files Browse the repository at this point in the history
Major refactor of sha algorithm, split 3 into 12 files.
  • Loading branch information
evoskuil authored Nov 24, 2024
2 parents 60cbd9a + 9129b08 commit 062b97c
Show file tree
Hide file tree
Showing 26 changed files with 2,298 additions and 1,833 deletions.
13 changes: 11 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,18 @@ 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_compress.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_double.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_functions.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_iterate.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_merkle.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_native.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_vector.ipp
include/bitcoin/system/impl/hash/sha/algorithm_padding.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_parsing.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_schedule.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_sigma.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_single.ipp \
include/bitcoin/system/impl/hash/sha/algorithm_stream.ipp

include_bitcoin_system_impl_machinedir = ${includedir}/bitcoin/system/impl/machine
include_bitcoin_system_impl_machine_HEADERS = \
Expand Down
13 changes: 11 additions & 2 deletions builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,18 @@
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\pbkd.ipp" />
<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_compress.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_double.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_functions.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_iterate.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_merkle.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\hash\sha\algorithm_padding.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_parsing.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_schedule.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_sigma.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_single.ipp" />
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_stream.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 @@ -1507,13 +1507,40 @@
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\scrypt.ipp">
<Filter>include\bitcoin\system\impl\hash</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm.ipp">
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_compress.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_double.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_functions.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_iterate.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_merkle.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<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_vector.ipp">
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_padding.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_parsing.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_schedule.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_sigma.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_single.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\hash\sha\algorithm_stream.ipp">
<Filter>include\bitcoin\system\impl\hash\sha</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\system\impl\machine\interpreter.ipp">
Expand Down
6 changes: 5 additions & 1 deletion include/bitcoin/system/hash/rmd/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@
#include <bitcoin/system/hash/algorithm.hpp>
#include <bitcoin/system/math/math.hpp>

// This file is a common include for rmd.
// algorithm.hpp file is the common include for rmd.
#include <bitcoin/system/hash/rmd/rmd.hpp>
#include <bitcoin/system/hash/rmd/rmd128.hpp>
#include <bitcoin/system/hash/rmd/rmd160.hpp>

// Based on:
// homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf
// [Dobbertin, Bosselaers, Preneel]

namespace libbitcoin {
namespace system {
namespace rmd {
Expand Down
133 changes: 86 additions & 47 deletions include/bitcoin/system/hash/sha/algorithm.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS)
* Copyright (c) 2011-2024 libbitcoin developers (see AUTHORS)
*
* This file is part of libbitcoin.
*
Expand All @@ -26,12 +26,17 @@
#include <bitcoin/system/intrinsics/intrinsics.hpp>
#include <bitcoin/system/math/math.hpp>

// This file is a common include for sha.
// algorithm.hpp file is the common include for sha.
#include <bitcoin/system/hash/sha/sha.hpp>
#include <bitcoin/system/hash/sha/sha160.hpp>
#include <bitcoin/system/hash/sha/sha256.hpp>
#include <bitcoin/system/hash/sha/sha512.hpp>

// Based on:
// FIPS PUB 180-4 [Secure Hash Standard (SHS)].
// All aspects of FIPS180 are supported within the implmentation.
// nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

namespace libbitcoin {
namespace system {
namespace sha {
Expand Down Expand Up @@ -90,13 +95,15 @@ class algorithm
template <size_t Size>
static constexpr digest_t hash(const ablocks_t<Size>& blocks) NOEXCEPT;
static constexpr digest_t hash(const block_t& block) NOEXCEPT;
static constexpr digest_t hash(const state_t& state) NOEXCEPT;
static constexpr digest_t hash(const half_t& half) NOEXCEPT;
static constexpr digest_t hash(const half_t& left, const half_t& right) NOEXCEPT;
static digest_t hash(iblocks_t&& blocks) NOEXCEPT;

/// Double hashing (sha256/512).
/// -----------------------------------------------------------------------

static constexpr void reinput(auto& buffer, const auto& state) NOEXCEPT;

template <size_t Size>
static constexpr digest_t double_hash(const ablocks_t<Size>& blocks) NOEXCEPT;
static constexpr digest_t double_hash(const block_t& block) NOEXCEPT;
Expand All @@ -106,37 +113,38 @@ class algorithm

/// Merkle hashing (sha256/512).
/// -----------------------------------------------------------------------
static VCONSTEXPR digest_t merkle_root(digests_t&& digests) NOEXCEPT;
static VCONSTEXPR digests_t& merkle_hash(digests_t& digests) NOEXCEPT;
static VCONSTEXPR digest_t merkle_root(digests_t&& digests) NOEXCEPT;

/// Streamed hashing (unfinalized).
/// Streamed hashing (explicitly finalized).
/// -----------------------------------------------------------------------
static void accumulate(state_t& state, iblocks_t&& blocks) NOEXCEPT;
static constexpr void accumulate(state_t& state, const block_t& block) NOEXCEPT;
static constexpr digest_t normalize(const state_t& state) NOEXCEPT;
static constexpr digest_t finalize(state_t& state, size_t blocks) NOEXCEPT;
static constexpr digest_t finalize_second(const state_t& state) NOEXCEPT;
static constexpr digest_t finalize_double(state_t& state, size_t blocks) NOEXCEPT;
static constexpr digest_t normalize(const state_t& state) NOEXCEPT;

protected:
/// Functions
/// -----------------------------------------------------------------------
using uint = unsigned int;

template <uint A, uint B, uint C>
INLINE static constexpr auto sigma(auto x) NOEXCEPT;
template <uint A, uint B, uint C>
INLINE static constexpr auto Sigma(auto x) NOEXCEPT;

INLINE static constexpr auto parity(auto x, auto y, auto z) NOEXCEPT;
INLINE static constexpr auto choice(auto x, auto y, auto z) NOEXCEPT;
INLINE static constexpr auto majority(auto x, auto y, auto z) NOEXCEPT;

INLINE static constexpr auto Sigma0(auto x) NOEXCEPT;
INLINE static constexpr auto Sigma1(auto x) NOEXCEPT;
template <uint A, uint B, uint C>
INLINE static constexpr auto sigma(auto x) NOEXCEPT;
INLINE static constexpr auto sigma0(auto x) NOEXCEPT;
INLINE static constexpr auto sigma1(auto x) NOEXCEPT;

/// Rounds
template <uint A, uint B, uint C>
INLINE static constexpr auto Sigma(auto x) NOEXCEPT;
INLINE static constexpr auto Sigma0(auto x) NOEXCEPT;
INLINE static constexpr auto Sigma1(auto x) NOEXCEPT;

/// Compression
/// -----------------------------------------------------------------------

template<size_t Round, typename Auto>
Expand All @@ -154,18 +162,20 @@ class algorithm
INLINE static constexpr void round(auto& state, const auto& wk) NOEXCEPT;
INLINE static constexpr void summarize(auto& out, const auto& in) NOEXCEPT;

template <size_t Lane = zero>
static constexpr void compress_(auto& state, const auto& buffer) NOEXCEPT;
template <size_t Lane = zero>
static constexpr void compress(auto& state, const auto& buffer) NOEXCEPT;

/// Message Scheduling
/// -----------------------------------------------------------------------

template <size_t Round>
INLINE static constexpr void prepare(auto& buffer) NOEXCEPT;
INLINE static constexpr void add_k(auto& buffer) NOEXCEPT;
INLINE static constexpr void schedule_(auto& buffer) NOEXCEPT;
static constexpr void schedule_(auto& buffer) NOEXCEPT;
static constexpr void schedule(auto& buffer) NOEXCEPT;

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

/// Parsing (endian sensitive)
/// -----------------------------------------------------------------------
INLINE static constexpr void input(buffer_t& buffer, const block_t& block) NOEXCEPT;
Expand All @@ -182,23 +192,18 @@ class algorithm
static constexpr void pad_half(buffer_t& buffer) NOEXCEPT;
static constexpr void pad_n(buffer_t& buffer, count_t blocks) NOEXCEPT;

/// Block iteration.
/// -----------------------------------------------------------------------

template <size_t Size>
INLINE static constexpr void iterate(state_t& state,
const ablocks_t<Size>& blocks) NOEXCEPT;
INLINE static void iterate(state_t& state, iblocks_t& blocks) NOEXCEPT;

/// Block iteration.
/// ---------------------------------------------------------------------------
protected:
template <size_t Size>
INLINE static constexpr void iterate_(state_t& state,
const ablocks_t<Size>& blocks) NOEXCEPT;
INLINE static void iterate_(state_t& state, iblocks_t& blocks) NOEXCEPT;

/// Merkle iteration.
/// -----------------------------------------------------------------------
VCONSTEXPR static void merkle_hash_(digests_t& digests,
size_t offset=zero) NOEXCEPT;
template <size_t Size>
INLINE static constexpr void iterate(state_t& state,
const ablocks_t<Size>& blocks) NOEXCEPT;
INLINE static void iterate(state_t& state, iblocks_t& blocks) NOEXCEPT;

private:
using pad_t = std_array<word_t, subtract(SHA::block_words,
Expand Down Expand Up @@ -234,7 +239,7 @@ class algorithm
INLINE static auto pack(const xblock_t<Lanes>& xblock) NOEXCEPT;

template <typename xWord>
INLINE static void input(xbuffer_t<xWord>& xbuffer,
INLINE static void xinput(xbuffer_t<xWord>& xbuffer,
iblocks_t& blocks) NOEXCEPT;

/// Merkle Hash.
Expand Down Expand Up @@ -262,12 +267,6 @@ class algorithm
INLINE static void output(idigests_t& digests,
const xstate_t<xWord>& xstate) NOEXCEPT;

template <typename xWord, if_extended<xWord> = true>
INLINE static void merkle_hash_invoke(idigests_t& digests,
iblocks_t& blocks) NOEXCEPT;

INLINE static void merkle_hash_dispatch(digests_t& digests) NOEXCEPT;

/// Message Schedule (block vectorization).
/// -----------------------------------------------------------------------

Expand All @@ -279,19 +278,20 @@ class algorithm
INLINE static Word extract(xWord a) NOEXCEPT;

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

template <typename xWord, if_extended<xWord> = true>
INLINE static void iterate_invoke(state_t& state, iblocks_t& blocks) NOEXCEPT;
INLINE static void vector_schedule_sequential_compress(state_t& state,
iblocks_t& blocks) NOEXCEPT;

template <size_t Size>
INLINE static void iterate_dispatch(state_t& state,
INLINE static void iterate_vector(state_t& state,
const ablocks_t<Size>& blocks) NOEXCEPT;
INLINE static void iterate_dispatch(state_t& state,
INLINE static void iterate_vector(state_t& state,
iblocks_t& blocks) NOEXCEPT;

/// Message Schedule (sigma vectorization).
/// sigma0 vectorization.
/// -----------------------------------------------------------------------

template <typename xWord, if_extended<xWord> = true>
Expand All @@ -304,11 +304,11 @@ class algorithm
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;
INLINE static void schedule_sigma(xbuffer_t<xWord>& xbuffer) NOEXCEPT;
INLINE static void schedule_sigma(buffer_t& buffer) NOEXCEPT;

/// Native.
/// ---------------------------------------------------------------------------
/// -----------------------------------------------------------------------
protected:
using cword_t = xint128_t;
static constexpr auto cratio = sizeof(cword_t) / SHA::word_bytes;
Expand All @@ -320,6 +320,25 @@ class algorithm
INLINE static void schedule_native(xbuffer_t<xWord>& xbuffer) NOEXCEPT;
INLINE static void schedule_native(buffer_t& buffer) NOEXCEPT;

template <typename xWord, size_t Lane = zero>
INLINE static void compress_native(xstate_t<xWord>& xstate,
const xbuffer_t<xWord>& xbuffer) NOEXCEPT;
template <size_t Lane = zero>
INLINE static void compress_native(state_t& state,
const buffer_t& buffer) NOEXCEPT;

/// Merkle.
/// -----------------------------------------------------------------------
protected:
VCONSTEXPR static void merkle_hash_(digests_t& digests,
size_t offset = zero) NOEXCEPT;

template <typename xWord, if_extended<xWord> = true>
INLINE static void merkle_hash_vector(idigests_t& digests,
iblocks_t& blocks) NOEXCEPT;

INLINE static void merkle_hash_vector(digests_t& digests) NOEXCEPT;

public:
static constexpr auto use_neon = Native && system::with_neon;
static constexpr auto use_shani = Native && system::with_shani;
Expand All @@ -345,9 +364,29 @@ class algorithm
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>
// Bogus warning suggests constexpr when declared consteval.
BC_PUSH_WARNING(USE_CONSTEXPR_FOR_FUNCTION)
BC_PUSH_WARNING(NO_UNGUARDED_POINTERS)
BC_PUSH_WARNING(NO_POINTER_ARITHMETIC)
BC_PUSH_WARNING(NO_ARRAY_INDEXING)

#include <bitcoin/system/impl/hash/sha/algorithm_compress.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_double.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_functions.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_iterate.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_merkle.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_native.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_vector.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_padding.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_parsing.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_schedule.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_sigma.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_single.ipp>
#include <bitcoin/system/impl/hash/sha/algorithm_stream.ipp>

BC_POP_WARNING()
BC_POP_WARNING()
BC_POP_WARNING()
BC_POP_WARNING()

#undef CLASS
#undef TEMPLATE
Expand Down
4 changes: 2 additions & 2 deletions include/bitcoin/system/impl/hash/accumulator.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ double_flush() NOEXCEPT
if (is_empty())
return Algorithm::finalize_double(state_, size_ / block_size);
else
return Algorithm::hash(pad());
return Algorithm::finalize_second(pad());
}
else
{
Expand All @@ -383,7 +383,7 @@ double_flush(digest_t& digest) NOEXCEPT
if (is_empty())
digest = Algorithm::finalize_double(state_, size_ / block_size);
else
digest = Algorithm::hash(pad());
digest = Algorithm::finalize_second(pad());
}
else
{
Expand Down
Loading

0 comments on commit 062b97c

Please sign in to comment.