Merge pull request #2491 from edtubbs/master

[feat] Added AVX2 SHA support
This commit is contained in:
Patrick Lodder 2021-11-01 18:47:05 -04:00 committed by GitHub
commit 8e4ea27962
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 135 additions and 1 deletions

View File

@ -36,6 +36,7 @@ jobs:
- x86_64-linux-nowallet
- x86_64-macos
- x86_64-win
- x86_64-linux-experimental
include:
- name: i686-linux
host: i686-pc-linux-gnu
@ -128,6 +129,14 @@ jobs:
config-opts: "--enable-gui=qt5 --disable-tests"
goal: deploy
sdk: 10.11
- name: x86_64-linux-experimental
host: x86_64-unknown-linux-gnu
os: ubuntu-20.04
packages: bc python3-zmq
run-tests: true
dep-opts: "AVX2=1"
config-opts: "--with-intel-avx2 --enable-gui=qt5 --enable-zmq --enable-glibc-back-compat --enable-reduce-exports"
goal: install
runs-on: ${{ matrix.os }}

View File

@ -177,6 +177,12 @@ AC_ARG_ENABLE([zmq],
[use_zmq=$enableval],
[use_zmq=yes])
AC_ARG_WITH([intel-avx2],
[AS_HELP_STRING([--with-intel-avx2],
[Build with intel avx2 (default is no)])],
[intel_avx2=$withval],
[intel_avx2=no])
AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], [])
AC_ARG_ENABLE(man,
@ -787,6 +793,16 @@ fi
fi
if test x$intel_avx2 = xyes; then
case $host in
x86_64-*-linux*)
AC_CHECK_LIB([IPSec_MB],[sha1_one_block_avx2],LIBS=-lIPSec_MB, AC_MSG_ERROR(IPSec_MB missing))
AC_CHECK_LIB([IPSec_MB],[sha256_one_block_avx2],LIBS=-lIPSec_MB, AC_MSG_ERROR(IPSec_MB missing))
AC_CHECK_LIB([IPSec_MB],[sha512_one_block_avx2],LIBS=-lIPSec_MB, AC_MSG_ERROR(IPSec_MB missing))
AC_DEFINE(USE_AVX2, 1, [Define this symbol if intel axv2 works])
esac
fi
if test x$use_pkgconfig = xyes; then
: dnl
m4_ifdef(

View File

@ -6,6 +6,7 @@ SDK_PATH ?= $(BASEDIR)/SDKs
NO_QT ?=
NO_WALLET ?=
NO_UPNP ?=
AVX2 ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
BUILD = $(shell ./config.guess)
@ -92,14 +93,19 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null)
qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages)
wallet_packages_$(NO_WALLET) = $(wallet_packages)
upnp_packages_$(NO_UPNP) = $(upnp_packages)
avx2_packages_$(AVX2) = $(avx2_$(host_arch)_$(host_os)_packages)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(avx2_packages_1) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
ifneq ($(qt_packages_),)
native_packages += $(qt_native_packages)
endif
ifneq ($(avx2_packages_1),)
native_packages += $(avx2_native_packages)
endif
all_packages = $(packages) $(native_packages)
meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk

View File

@ -0,0 +1,19 @@
package=intel-ipsec-mb
$(package)_version=1.0
$(package)_download_path=https://github.com/intel/intel-ipsec-mb/archive/refs/tags
$(package)_file_name=v$($(package)_version).tar.gz
$(package)_sha256_hash=03501aea472d3c8fdf8f1f207816eefeaf5e4ebbdc71d88dcb26b2519841bb74
$(package)_patches=remove_digest_init.patch
$(package)_dependencies=native_nasm
define $(package)_preprocess_cmds
patch -p1 < $($(package)_patch_dir)/remove_digest_init.patch
endef
define $(package)_build_cmds
$(MAKE) NASM=$(build_prefix)/bin/nasm
endef
define $(package)_stage_cmds
$(MAKE) NASM=$(build_prefix)/bin/nasm PREFIX=$($(package)_staging_prefix_dir) SHARED=n NOLDCONFIG=y install
endef

View File

@ -0,0 +1,21 @@
package=native_nasm
$(package)_version=2.15.05
$(package)_download_path=http://nasm.us/pub/nasm/releasebuilds/$($(package)_version)
$(package)_file_name=nasm-$($(package)_version).tar.bz2
$(package)_sha256_hash=3c4b8339e5ab54b1bcb2316101f8985a5da50a3f9e504d43fa6f35668bee2fd0
define $(package)_config_cmds
$($(package)_autoconf)
endef
define $(package)_build_cmds
$(MAKE)
endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
define $(package)_postprocess_cmds
rm -rf share
endef

View File

@ -14,6 +14,9 @@ wallet_packages=bdb
upnp_packages=miniupnpc
avx2_native_packages:=native_nasm
avx2_x86_64_linux_packages:=intel-ipsec-mb
darwin_native_packages = native_biplist native_ds_store native_mac_alias
ifneq ($(build_os),darwin)

View File

@ -0,0 +1,13 @@
diff -dur a/lib/include/sha_generic.h b/lib/include/sha_generic.h
index 3752546..77efd91 100644
--- a/lib/include/sha_generic.h
+++ b/lib/include/sha_generic.h
@@ -308,7 +308,7 @@ void sha_generic_1block(const void *data, void *digest,
if (data == NULL || digest == NULL)
return;
#endif
- sha_generic_init(digest, sha_type);
+// sha_generic_init(digest, sha_type);
sha_generic_one_block(data, digest, is_avx, sha_type);
#ifdef SAFE_DATA
clear_scratch_gps();

View File

@ -8,12 +8,20 @@
#include <string.h>
#if (defined(__ia64__) || defined(__x86_64__)) && \
(defined(__linux__) && !defined(__APPLE__)) && \
(defined(USE_AVX2))
#include <intel-ipsec-mb.h>
#endif
// Internal implementation code.
namespace
{
/// Internal SHA-1 implementation.
namespace sha1
{
#ifndef USE_AVX2
/** One round of SHA-1. */
void inline Round(uint32_t a, uint32_t& b, uint32_t c, uint32_t d, uint32_t& e, uint32_t f, uint32_t k, uint32_t w)
{
@ -26,6 +34,7 @@ uint32_t inline f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & (b | c)); }
uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); }
#endif
/** Initialize SHA-1 state. */
void inline Initialize(uint32_t* s)
@ -45,6 +54,12 @@ const uint32_t k4 = 0xCA62C1D6ul;
/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
{
#ifdef USE_AVX2
// Perform SHA1 one block (Intel AVX2)
sha1_one_block_avx2(chunk, s);
#else
// Perform SHA one block (legacy)
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
@ -138,6 +153,9 @@ void Transform(uint32_t* s, const unsigned char* chunk)
s[2] += c;
s[3] += d;
s[4] += e;
#endif
}
} // namespace sha1

View File

@ -8,12 +8,19 @@
#include <string.h>
#if (defined(__ia64__) || defined(__x86_64__)) && \
(defined(__linux__) && !defined(__APPLE__)) && \
(defined(USE_AVX2))
#include <intel-ipsec-mb.h>
#endif
// Internal implementation code.
namespace
{
/// Internal SHA-256 implementation.
namespace sha256
{
#ifndef USE_AVX2
uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
@ -29,6 +36,7 @@ void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, u
d += t1;
h = t1 + t2;
}
#endif
/** Initialize SHA-256 state. */
void inline Initialize(uint32_t* s)
@ -46,6 +54,11 @@ void inline Initialize(uint32_t* s)
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
{
#ifdef USE_AVX2
// Perform SHA256 one block (Intel AVX2)
sha256_one_block_avx2(chunk, s);
#else
// Perform SHA256 one block (legacy)
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
@ -125,6 +138,7 @@ void Transform(uint32_t* s, const unsigned char* chunk)
s[5] += f;
s[6] += g;
s[7] += h;
#endif
}
} // namespace sha256

View File

@ -8,12 +8,19 @@
#include <string.h>
#if (defined(__ia64__) || defined(__x86_64__)) && \
(defined(__linux__) && !defined(__APPLE__)) && \
(defined(USE_AVX2))
#include <intel-ipsec-mb.h>
#endif
// Internal implementation code.
namespace
{
/// Internal SHA-512 implementation.
namespace sha512
{
#ifndef USE_AVX2
uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
@ -29,6 +36,7 @@ void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, u
d += t1;
h = t1 + t2;
}
#endif
/** Initialize SHA-256 state. */
void inline Initialize(uint64_t* s)
@ -46,6 +54,11 @@ void inline Initialize(uint64_t* s)
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
void Transform(uint64_t* s, const unsigned char* chunk)
{
#ifdef USE_AVX2
// Perform SHA512 one block (Intel AVX2)
sha512_one_block_avx2(chunk, s);
#else
// Perform SHA512 one block (legacy)
uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
@ -142,6 +155,7 @@ void Transform(uint64_t* s, const unsigned char* chunk)
s[5] += f;
s[6] += g;
s[7] += h;
#endif
}
} // namespace sha512
@ -205,3 +219,4 @@ CSHA512& CSHA512::Reset()
sha512::Initialize(s);
return *this;
}