diff --git a/configure.ac b/configure.ac index 8248ba244f..6eb4dedcca 100644 --- a/configure.ac +++ b/configure.ac @@ -1,1407 +1,1419 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 18) define(_CLIENT_VERSION_REVISION, 3) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2018) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin]]) AC_INIT([Bitcoin ABC],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/Bitcoin-ABC/bitcoin-abc/issues],[bitcoin-abc],[https://bitcoinabc.org/]) AC_CONFIG_SRCDIR([src/validation.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) BITCOIN_DAEMON_NAME=bitcoind BITCOIN_GUI_NAME=bitcoin-qt BITCOIN_CLI_NAME=bitcoin-cli BITCOIN_TX_NAME=bitcoin-tx BITCOIN_SEEDER_NAME=bitcoin-seeder AC_CANONICAL_HOST AH_TOP([#ifndef BITCOIN_BITCOIN_CONFIG_H]) AH_TOP([#define BITCOIN_BITCOIN_CONFIG_H]) AH_BOTTOM([#endif // BITCOIN_BITCOIN_CONFIG_H]) dnl faketime breaks configure and is only needed for make. Disable it here. unset FAKETIME dnl Automake init set-up and checks AM_INIT_AUTOMAKE([no-define subdir-objects foreign]) dnl faketime messes with timestamps and causes configure to be re-run. dnl --disable-maintainer-mode can be used to bypass this. AM_MAINTAINER_MODE([enable]) dnl make the compilation flags quiet unless V=1 is used m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) dnl Compiler checks (here before libtool). if test "x${CXXFLAGS+set}" = "xset"; then CXXFLAGS_overridden=yes else CXXFLAGS_overridden=no fi AC_PROG_CXX dnl By default, libtool for mingw refuses to link static libs into a dll for dnl fear of mixing pic/non-pic objects, and import/export complications. Since dnl we have those under control, re-enable that functionality. case $host in *mingw*) lt_cv_deplibs_check_method="pass_all" ;; esac dnl Require C++11 compiler (no GNU extensions) AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault]) dnl Check if -latomic is required for CHECK_ATOMIC dnl Unless the user specified OBJCXX, force it to be the same as CXX. This ensures dnl that we get the same -std flags for both. m4_ifdef([AC_PROG_OBJCXX],[ if test "x${OBJCXX+set}" = "x"; then OBJCXX="${CXX}" fi AC_PROG_OBJCXX ]) dnl Libtool init checks. LT_INIT([pic-only]) dnl Check/return PATH for base programs. AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) dnl Python 3.x is supported from 3.4 on (see https://github.com/bitcoin/bitcoin/issues/7893) AC_PATH_PROGS([PYTHON], [python3.6 python3.5 python3.4 python3 python2.7 python2 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) AC_PATH_TOOL(READELF, readelf) AC_PATH_TOOL(CPPFILT, c++filt) AC_PATH_TOOL(OBJCOPY, objcopy) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) # Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], [disable wallet (enabled by default)])], [enable_wallet=$enableval], [enable_wallet=yes]) AC_ARG_WITH([miniupnpc], [AS_HELP_STRING([--with-miniupnpc], [enable UPNP (default is yes if libminiupnpc is found)])], [use_upnp=$withval], [use_upnp=auto]) AC_ARG_ENABLE([upnp-default], [AS_HELP_STRING([--enable-upnp-default], [if UPNP is enabled, turn it on at startup (default is no)])], [use_upnp_default=$enableval], [use_upnp_default=no]) AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]), [use_tests=$enableval], [use_tests=yes]) AC_ARG_ENABLE(gui-tests, AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]), [use_gui_tests=$enableval], [use_gui_tests=$use_tests]) AC_ARG_ENABLE(bench, AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]), [use_bench=$enableval], [use_bench=yes]) AC_ARG_ENABLE([extended-functional-tests], AS_HELP_STRING([--enable-extended-functional-tests],[enable expensive functional tests when using lcov (default no)]), [use_extended_functional_tests=$enableval], [use_extended_functional_tests=no]) AC_ARG_WITH([qrencode], [AS_HELP_STRING([--with-qrencode], [enable QR code support (default is yes if qt is enabled and libqrencode is found)])], [use_qr=$withval], [use_qr=auto]) AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--disable-hardening], [do not attempt to harden the resulting executables (default is to harden)])], [use_hardening=$enableval], [use_hardening=yes]) AC_ARG_ENABLE([reduce-exports], [AS_HELP_STRING([--enable-reduce-exports], [attempt to reduce exported symbols in the resulting executables (default is no)])], [use_reduce_exports=$enableval], [use_reduce_exports=no]) AC_ARG_ENABLE([ccache], [AS_HELP_STRING([--disable-ccache], [do not use ccache for building (default is to use if found)])], [use_ccache=$enableval], [use_ccache=auto]) AC_ARG_ENABLE([lcov], [AS_HELP_STRING([--enable-lcov], [enable lcov testing (default is no)])], [use_lcov=yes], [use_lcov=no]) AC_ARG_ENABLE([glibc-back-compat], [AS_HELP_STRING([--enable-glibc-back-compat], [enable backwards compatibility with glibc])], [use_glibc_compat=$enableval], [use_glibc_compat=no]) AC_ARG_ENABLE([asm], [AS_HELP_STRING([--enable-asm], [Enable assembly routines (default is yes)])], [use_asm=$enableval], [use_asm=yes]) if test "x$use_asm" = xyes; then AC_DEFINE(USE_ASM, 1, [Define this symbol to build in assembly routines]) fi AC_ARG_WITH([system-univalue], [AS_HELP_STRING([--with-system-univalue], [Build with system UniValue (default is no)])], [system_univalue=$withval], [system_univalue=no] ) AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--disable-zmq], [disable ZMQ notifications])], [use_zmq=$enableval], [use_zmq=yes]) 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, [AS_HELP_STRING([--disable-man], [do not install man pages (default is to install)])],, enable_man=yes) AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) # Enable debug AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [use debug compiler flags and macros (default is no)])], [enable_debug=$enableval], [enable_debug=no]) # Enable ASAN AC_ARG_ENABLE([asan], [AS_HELP_STRING([--enable-asan], [enable address sanitizer compiler flags (implies --enable-debug, default is no)])], [enable_asan=$enableval], [enable_asan=no]) # Enable TSAN AC_ARG_ENABLE([tsan], [AS_HELP_STRING([--enable-tsan], [enable thread sanitizer compiler flags; requires 64-bit target architecture (implies --enable-debug, default is no)])], [enable_tsan=$enableval], [enable_tsan=no]) # Enable UBSAN AC_ARG_ENABLE([ubsan], [AS_HELP_STRING([--enable-ubsan], [enable undefined behavior sanitizer compiler flags (implies --enable-debug, default is no)])], [enable_ubsan=$enableval], [enable_ubsan=no]) # Turn warnings into errors AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], [Treat certain compiler warnings as errors (default is no)])], [enable_werror=$enableval], [enable_werror=no]) AC_LANG_PUSH([C++]) AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) if test "x$enable_asan" = xyes; then enable_debug=yes asan_failed=no AX_CHECK_COMPILE_FLAG([-fsanitize=address], [CXXFLAGS="$CXXFLAGS -fsanitize=address"], [asan_failed=yes]) AX_CHECK_LINK_FLAG([-fsanitize=address], [LDFLAGS="$LDFLAGS -fsanitize=address"], [asan_failed=yes]) AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"], [asan_failed=yes]) if test "x$asan_failed" = xyes; then AC_MSG_ERROR("ASAN is not supported") fi # fix linkage in MacOs [LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -fsanitize=address"], fi if test "x$enable_tsan" = xyes; then enable_debug=yes tsan_failed=no AX_CHECK_COMPILE_FLAG([-fsanitize=thread], [CXXFLAGS="$CXXFLAGS -fsanitize=thread"], [tsan_failed=yes]) AX_CHECK_LINK_FLAG([-fsanitize=thread], [LDFLAGS="$LDFLAGS -fsanitize=thread"], [tsan_failed=yes]) AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"], [tsan_failed=yes]) if test "x$tsan_failed" = xyes; then AC_MSG_ERROR("TSAN is not supported") fi fi if test "x$enable_ubsan" = xyes; then enable_debug=yes ubsan_failed=no AX_CHECK_COMPILE_FLAG([-fsanitize=undefined], [CXXFLAGS="$CXXFLAGS -fsanitize=undefined"], [ubsan_failed=yes]) AX_CHECK_LINK_FLAG([-fsanitize=undefined], [LDFLAGS="$LDFLAGS -fsanitize=undefined"], [ubsan_failed=yes]) AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"], [ubsan_failed=yes]) if test "x$ubsan_failed" = xyes; then AC_MSG_ERROR("UBSAN is not supported") fi fi if test "x$enable_debug" = xyes; then CPPFLAGS="$CPPFLAGS -DDEBUG -DDEBUG_LOCKORDER" if test "x$GCC" = xyes; then CFLAGS="$CFLAGS -g3 -O0" fi if test "x$GXX" = xyes; then CXXFLAGS="$CXXFLAGS -g3 -O0" fi fi ERROR_CXXFLAGS= if test "x$enable_werror" = "xyes"; then if test "x$CXXFLAG_WERROR" = "x"; then AC_MSG_ERROR("enable-werror set but -Werror is not usable") fi AX_CHECK_COMPILE_FLAG([-Werror=vla],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=vla"],,[[$CXXFLAG_WERROR]]) fi if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wshadow],[CXXFLAGS="$CXXFLAGS -Wshadow"],,[[$CXXFLAG_WERROR]]) ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all ## unknown options if any other warning is produced. Test the -Wfoo case, and ## set the -Wno-foo case if it works. AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[CXXFLAGS="$CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]]) fi # Check for optional instruction set support. Enabling these does _not_ imply that all code will # be compiled with them, rather that specific objects/libs may use them after checking for runtime # compatibility. AX_CHECK_COMPILE_FLAG([-msse4.2],[[SSE42_CXXFLAGS="-msse4.2"]],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-msse4.1],[[SSE41_CXXFLAGS="-msse4.1"]],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-mavx -mavx2],[[AVX2_CXXFLAGS="-mavx -mavx2"]],,[[$CXXFLAG_WERROR]]) +AX_CHECK_COMPILE_FLAG([-msse4 -msha],[[SHANI_CXXFLAGS="-msse4 -msha"]],,[[$CXXFLAG_WERROR]]) TEMP_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS" AC_MSG_CHECKING(for assembler crc32 support) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #if defined(_MSC_VER) #include #elif defined(__GNUC__) && defined(__SSE4_2__) #include #endif ]],[[ uint64_t l = 0; l = _mm_crc32_u8(l, 0); l = _mm_crc32_u32(l, 0); l = _mm_crc32_u64(l, 0); return l; ]])], [ AC_MSG_RESULT(yes); enable_hwcrc32=yes], [ AC_MSG_RESULT(no)] ) CXXFLAGS="$TEMP_CXXFLAGS" TEMP_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $SSE41_CXXFLAGS" AC_MSG_CHECKING(for SSE4.1 intrinsics) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - #if defined(_MSC_VER) #include - #elif defined(__GNUC__) - #include - #endif ]],[[ __m128i l = _mm_set1_epi32(0); return _mm_extract_epi32(l, 3); ]])], [ AC_MSG_RESULT(yes); enable_sse41=yes; AC_DEFINE(ENABLE_SSE41, 1, [Define this symbol to build code that uses SSE4.1 intrinsics]) ], [ AC_MSG_RESULT(no)] ) CXXFLAGS="$TEMP_CXXFLAGS" TEMP_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $AVX2_CXXFLAGS" AC_MSG_CHECKING(for AVX2 intrinsics) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - #if defined(_MSC_VER) #include - #elif defined(__GNUC__) && defined(__AVX2__) - #include - #endif ]],[[ __m256i l = _mm256_set1_epi32(0); return _mm256_extract_epi32(l, 7); ]])], [ AC_MSG_RESULT(yes); enable_avx2=yes; AC_DEFINE(ENABLE_AVX2, 1, [Define this symbol to build code that uses AVX2 intrinsics]) ], [ AC_MSG_RESULT(no)] ) CXXFLAGS="$TEMP_CXXFLAGS" +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $SHANI_CXXFLAGS" +AC_MSG_CHECKING(for SHA-NI intrinsics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + __m128i i = _mm_set1_epi32(0); + __m128i j = _mm_set1_epi32(1); + __m128i k = _mm_set1_epi32(2); + return _mm_extract_epi32(_mm_sha256rnds2_epu32(i, i, k), 0); + ]])], + [ AC_MSG_RESULT(yes); enable_shani=yes; AC_DEFINE(ENABLE_SHANI, 1, [Define this symbol to build code that uses SHA-NI intrinsics]) ], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], [build bitcoin-cli bitcoin-tx (default=yes)])], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], [build libraries (default=yes)])], [build_bitcoin_libs=$withval], [build_bitcoin_libs=yes]) AC_ARG_WITH([daemon], [AS_HELP_STRING([--with-daemon], [build bitcoind daemon (default=yes)])], [build_bitcoind=$withval], [build_bitcoind=yes]) AC_ARG_WITH([seeder], [AS_HELP_STRING([--with-seeder], [build seeder (default=yes)])], [build_bitcoin_seeder=$withval], [build_bitcoin_seeder=yes]) use_pkgconfig=yes case $host in *mingw*) #pkgconfig does more harm than good with MinGW use_pkgconfig=no TARGET_OS=windows AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([winspool], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([shell32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([ole32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([rpcrt4], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([advapi32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([ws2_32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing)) # -static is interpreted by libtool, where it has a different meaning. # In libtool-speak, it's -all-static. AX_CHECK_LINK_FLAG([[-static]],[LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"]) AC_PATH_PROG([MAKENSIS], [makensis], none) if test x$MAKENSIS = xnone; then AC_MSG_WARN("makensis not found. Cannot create installer.") fi AC_PATH_TOOL(WINDRES, windres, none) if test x$WINDRES = xnone; then AC_MSG_ERROR("windres not found") fi CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB" LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" fi case $host in i?86-*) WINDOWS_BITS=32 ;; x86_64-*) WINDOWS_BITS=64 ;; *) AC_MSG_ERROR("Could not determine win32/win64 for installer") ;; esac AC_SUBST(WINDOWS_BITS) dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against. dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override dnl its command here, with the predeps/postdeps removed, and -static inserted. Postdeps are dnl also overridden to prevent their insertion later. dnl This should only affect dll's. archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib" postdeps_CXX= ;; *darwin*) TARGET_OS=darwin LEVELDB_TARGET_FLAGS="-DOS_MACOSX" if test x$cross_compiling != xyes; then BUILD_OS=darwin AC_CHECK_PROG([PORT],port, port) if test x$PORT = xport; then dnl add default macports paths CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" LIBS="$LIBS -L/opt/local/lib" if test -d /opt/local/include/db48; then CPPFLAGS="$CPPFLAGS -I/opt/local/include/db48" LIBS="$LIBS -L/opt/local/lib/db48" fi fi AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_CHECK_PROG([BREW],brew, brew) if test x$BREW = xbrew; then dnl These Homebrew packages may be keg-only, meaning that they won't be found dnl in expected paths because they may conflict with system files. Ask dnl Homebrew where each one is located, then adjust paths accordingly. dnl It's safe to add these paths even if the functionality is disabled by dnl the user (--without-wallet or --without-gui for example). openssl_prefix=`$BREW --prefix openssl 2>/dev/null` bdb_prefix=`$BREW --prefix berkeley-db 2>/dev/null` qt5_prefix=`$BREW --prefix qt5 2>/dev/null` if test x$openssl_prefix != x; then PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" export PKG_CONFIG_PATH fi if test x$bdb_prefix != x; then CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include" LIBS="$LIBS -L$bdb_prefix/lib" fi if test x$qt5_prefix != x; then PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" export PKG_CONFIG_PATH fi fi else case $build_os in *darwin*) BUILD_OS=darwin ;; *) AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) dnl libtool will try to strip the static lib, which is a problem for dnl cross-builds because strip attempts to call a hard-coded ld, dnl which may not exist in the path. Stripping the .a is not dnl necessary, so just disable it. old_striplib= ;; esac fi AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) CPPFLAGS="$CPPFLAGS -DMAC_OSX" OBJCXXFLAGS="$CXXFLAGS" ;; *linux*) TARGET_OS=linux LEVELDB_TARGET_FLAGS="-DOS_LINUX" ;; *freebsd*) LEVELDB_TARGET_FLAGS="-DOS_FREEBSD" ;; *openbsd*) LEVELDB_TARGET_FLAGS="-DOS_OPENBSD" ;; *) OTHER_OS=`echo ${host_os} | awk '{print toupper($0)}'` AC_MSG_WARN([Guessing LevelDB OS as OS_${OTHER_OS}, please check whether this is correct, if not add an entry to configure.ac.]) LEVELDB_TARGET_FLAGS="-DOS_${OTHER_OS}" ;; esac if test x$use_pkgconfig = xyes; then m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) m4_ifdef([PKG_PROG_PKG_CONFIG], [ PKG_PROG_PKG_CONFIG if test x"$PKG_CONFIG" = "x"; then AC_MSG_ERROR(pkg-config not found.) fi ]) fi if test x$use_extended_functional_tests != xno; then AC_SUBST(EXTENDED_FUNCTIONAL_TESTS, --extended) fi if test x$use_lcov = xyes; then if test x$LCOV = x; then AC_MSG_ERROR("lcov testing requested but lcov not found") fi if test x$GCOV = x; then AC_MSG_ERROR("lcov testing requested but gcov not found") fi if test x$PYTHON = x; then AC_MSG_ERROR("lcov testing requested but python not found") fi if test x$GENHTML = x; then AC_MSG_ERROR("lcov testing requested but genhtml not found") fi LCOV="$LCOV --gcov-tool=$GCOV" AX_CHECK_LINK_FLAG([[--coverage]], [LDFLAGS="$LDFLAGS --coverage"], [AC_MSG_ERROR("lcov testing requested but --coverage linker flag does not work")]) AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"], [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) fi dnl Check for endianness AC_C_BIGENDIAN dnl Check for pthread compile/link requirements AX_PTHREAD # The following macro will add the necessary defines to bitcoin-config.h, but # they also need to be passed down to any subprojects. Pull the results out of # the cache and add them to CPPFLAGS. AC_SYS_LARGEFILE # detect POSIX or GNU variant of strerror_r AC_FUNC_STRERROR_R if test x$ac_cv_sys_file_offset_bits != x && test x$ac_cv_sys_file_offset_bits != xno && test x$ac_cv_sys_file_offset_bits != xunknown; then CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits" fi if test x$ac_cv_sys_large_files != x && test x$ac_cv_sys_large_files != xno && test x$ac_cv_sys_large_files != xunknown; then CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files" fi AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large-address-aware"]) AX_GCC_FUNC_ATTRIBUTE([visibility]) AX_GCC_FUNC_ATTRIBUTE([dllexport]) AX_GCC_FUNC_ATTRIBUTE([dllimport]) if test x$use_glibc_compat != xno; then #glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link #in anyway for back-compat. AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(lib missing)) #__fdelt_chk's params and return type have changed from long unsigned int to long int. # See which one is present here. AC_MSG_CHECKING(__fdelt_chk type) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef _FORTIFY_SOURCE #undef _FORTIFY_SOURCE #endif #define _FORTIFY_SOURCE 2 #include extern "C" long unsigned int __fdelt_warn(long unsigned int);]],[[]])], [ fdelt_type="long unsigned int"], [ fdelt_type="long int"]) AC_MSG_RESULT($fdelt_type) AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk]) AX_CHECK_LINK_FLAG([[-Wl,--wrap=__divmoddi4]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=__divmoddi4"]) AX_CHECK_LINK_FLAG([[-Wl,--wrap=log2f]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=log2f"]) else AC_SEARCH_LIBS([clock_gettime],[rt]) fi if test x$TARGET_OS != xwindows; then # All windows code is PIC, forcing it on just adds useless compile warnings AX_CHECK_COMPILE_FLAG([-fPIC],[PIC_FLAGS="-fPIC"]) fi if test x$use_hardening != xno; then AX_CHECK_COMPILE_FLAG([-Wstack-protector],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"]) AX_CHECK_COMPILE_FLAG([-fstack-protector-all],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"]) AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[ HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE" ]) HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2" ]) AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"]) AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"]) AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"]) AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"]) AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"]) if test x$TARGET_OS != xwindows; then AX_CHECK_COMPILE_FLAG([-fPIE],[PIE_FLAGS="-fPIE"]) AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"]) fi case $host in *mingw*) AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing)) ;; esac fi dnl this flag screws up non-darwin gcc even when the check fails. special-case it. if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) AC_CHECK_DECLS([strnlen]) # Check for daemon(3), unrelated to --with-daemon (although used by it) AC_CHECK_DECLS([daemon]) AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,, [#if HAVE_ENDIAN_H #include #elif HAVE_SYS_ENDIAN_H #include #endif]) AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,, [#if HAVE_BYTESWAP_H #include #endif]) AC_CHECK_DECLS([__builtin_clz, __builtin_clzl, __builtin_clzll]) dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas) AC_MSG_CHECKING(for mallopt M_ARENA_MAX) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ mallopt(M_ARENA_MAX, 1); ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MALLOPT_ARENA_MAX, 1,[Define this symbol if you have mallopt with M_ARENA_MAX]) ], [ AC_MSG_RESULT(no)] ) AC_MSG_CHECKING([for visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); int main(){} ])], [ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE,1,[Define if the visibility attribute is supported.]) AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) if test x$use_reduce_exports = xyes; then AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.]) fi ] ) # Check for different ways of gathering OS randomness AC_MSG_CHECKING(for Linux getrandom syscall) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include #include ]], [[ syscall(SYS_getrandom, nullptr, 32, 0); ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYS_GETRANDOM, 1,[Define this symbol if the Linux getrandom system call is available]) ], [ AC_MSG_RESULT(no)] ) AC_MSG_CHECKING(for getentropy) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ getentropy(nullptr, 32) ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GETENTROPY, 1,[Define this symbol if the BSD getentropy system call is available]) ], [ AC_MSG_RESULT(no)] ) AC_MSG_CHECKING(for getentropy via random.h) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[ getentropy(nullptr, 32) ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GETENTROPY_RAND, 1,[Define this symbol if the BSD getentropy system call is available with sys/random.h]) ], [ AC_MSG_RESULT(no)] ) AC_MSG_CHECKING(for sysctl KERN_ARND) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[ static const int name[2] = {CTL_KERN, KERN_ARND}; sysctl(name, 2, nullptr, nullptr, nullptr, 0); ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSCTL_ARND, 1,[Define this symbol if the BSD sysctl(KERN_ARND) is available]) ], [ AC_MSG_RESULT(no)] ) # Check for reduced exports if test x$use_reduce_exports = xyes; then AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= AM_CONDITIONAL([EMBEDDED_LEVELDB],[true]) AC_SUBST(LEVELDB_CPPFLAGS) AC_SUBST(LIBLEVELDB) AC_SUBST(LIBMEMENV) if test x$enable_wallet != xno; then dnl Check for libdb_cxx only if wallet enabled BITCOIN_FIND_BDB53 fi dnl Check for libminiupnpc (optional) if test x$use_upnp != xno; then AC_CHECK_HEADERS( [miniupnpc/miniwget.h miniupnpc/miniupnpc.h miniupnpc/upnpcommands.h miniupnpc/upnperrors.h], [AC_CHECK_LIB([miniupnpc], [upnpDiscover], [MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])], [have_miniupnpc=no] ) fi BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig]) if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$build_bitcoin_seeder$use_tests$use_bench = xnononononono; then use_boost=no else use_boost=yes fi if test x$use_boost = xyes; then dnl Minimum required Boost version define(MINIMUM_REQUIRED_BOOST, 1.58.0) dnl Check for boost libs AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS AX_BOOST_THREAD AX_BOOST_CHRONO dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic dnl counter implementations. In 1.63 and later the std::atomic approach is default. m4_pattern_allow(DBOOST_AC_USE_STD_ATOMIC) dnl otherwise it's treated like a macro BOOST_CPPFLAGS="-DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS" if test x$use_reduce_exports = xyes; then AC_MSG_CHECKING([for working boost reduced exports]) TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS" AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= 104900 // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) ],[ AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.]) ]) CPPFLAGS="$TEMP_CPPFLAGS" fi fi if test x$use_reduce_exports = xyes; then CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS" AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"]) fi if test x$use_tests = xyes; then if test x$HEXDUMP = x; then AC_MSG_ERROR(hexdump is required for tests) fi if test x$use_boost = xyes; then AX_BOOST_UNIT_TEST_FRAMEWORK dnl Determine if -DBOOST_TEST_DYN_LINK is needed AC_MSG_CHECKING([for dynamic linked boost test]) TEMP_LIBS="$LIBS" LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_LINK_IFELSE([AC_LANG_SOURCE([ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN #include ])], [AC_MSG_RESULT(yes)] [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"], [AC_MSG_RESULT(no)]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" fi fi if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums dnl using c++98 constructs. Unfortunately, this implementation detail leaked into dnl the abi. This was fixed in 1.57. dnl When building against that installed version using c++11, the headers pick up dnl on the native c++11 scoped enum support and enable it, however it will fail to dnl link. This can be worked around by disabling c++11 scoped enums if linking will dnl fail. dnl BOOST_NO_SCOPED_ENUMS was changed to BOOST_NO_CXX11_SCOPED_ENUMS in 1.51. TEMP_LIBS="$LIBS" LIBS="$BOOST_LIBS $LIBS" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_MSG_CHECKING([for mismatched boost c++11 scoped enums]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #if !defined(BOOST_NO_SCOPED_ENUMS) && !defined(BOOST_NO_CXX11_SCOPED_ENUMS) && BOOST_VERSION < 105700 #define BOOST_NO_SCOPED_ENUMS #define BOOST_NO_CXX11_SCOPED_ENUMS #define CHECK #endif #include ]],[[ #if defined(CHECK) boost::filesystem::copy_file("foo", "bar"); #else choke; #endif ]])], [AC_MSG_RESULT(mismatched); BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS"], [AC_MSG_RESULT(ok)]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if dnl a working version is available, else fall back to sleep. sleep was removed dnl after 1.56. dnl If neither is available, abort. TEMP_LIBS="$LIBS" LIBS="$BOOST_LIBS $LIBS" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include ]],[[ #if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200) boost::this_thread::sleep_for(boost::chrono::milliseconds(0)); #else choke me #endif ]])], [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP_FOR, 1, [Define this symbol if boost sleep_for works])], [boost_sleep=no]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" if test x$boost_sleep != xyes; then TEMP_LIBS="$LIBS" LIBS="$BOOST_LIBS $LIBS" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]],[[ #if BOOST_VERSION <= 105600 boost::this_thread::sleep(boost::posix_time::milliseconds(0)); #else choke me #endif ]])], [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP, 1, [Define this symbol if boost sleep works])], [boost_sleep=no]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" fi if test x$boost_sleep != xyes; then AC_MSG_ERROR(No working boost sleep implementation found.) fi fi if test x$use_pkgconfig = xyes; then : dnl m4_ifdef( [PKG_CHECK_MODULES], [ PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])]) if test x$use_qr != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) if test x$TARGET_OS != xwindows; then PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) fi fi if test "x$use_zmq" = "xyes"; then PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) use_zmq=no]) else AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) fi ] ) else AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) if test x$TARGET_OS != xwindows; then AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) fi fi if test "x$use_zmq" = "xyes"; then AC_CHECK_HEADER([zmq.h], [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], [AC_MSG_WARN([zmq.h not found, disabling zmq support]) use_zmq=no AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) AC_CHECK_LIB([zmq],[zmq_ctx_shutdown],ZMQ_LIBS=-lzmq, [AC_MSG_WARN([libzmq >= 4.0 not found, disabling zmq support]) use_zmq=no AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) else AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) fi if test "x$use_zmq" = "xyes"; then dnl Assume libzmq was built for static linking case $host in *mingw*) ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" ;; esac fi BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) fi fi save_CXXFLAGS="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}" AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT #include ]) CXXFLAGS="${save_CXXFLAGS}" dnl univalue check need_bundled_univalue=yes if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then need_bundled_univalue=no else if test x$system_univalue != xno ; then found_univalue=no if test x$use_pkgconfig = xyes; then : #NOP m4_ifdef( [PKG_CHECK_MODULES], [ PKG_CHECK_MODULES([UNIVALUE],[libunivalue],[found_univalue=yes],[true]) ] ) else AC_CHECK_HEADER([univalue.h],[ AC_CHECK_LIB([univalue], [main],[ UNIVALUE_LIBS=-lunivalue found_univalue=yes ],[true]) ],[true]) fi if test x$found_univalue = xyes ; then system_univalue=yes need_bundled_univalue=no elif test x$system_univalue = xyes ; then AC_MSG_ERROR([univalue not found]) else system_univalue=no fi fi if test x$need_bundled_univalue = xyes ; then UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' UNIVALUE_LIBS='univalue/libunivalue.la' fi fi AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) AC_SUBST(UNIVALUE_CFLAGS) AC_SUBST(UNIVALUE_LIBS) BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) AC_MSG_CHECKING([whether to build bitcoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) AC_MSG_CHECKING([whether to build bitcoin-seeder]) AM_CONDITIONAL([BUILD_BITCOIN_SEEDER], [test x$build_bitcoin_seeder = xyes]) AC_MSG_RESULT($build_bitcoin_seeder) AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AC_MSG_RESULT($build_bitcoin_utils) AC_MSG_CHECKING([whether to build libraries]) AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes]) if test x$build_bitcoin_libs = xyes; then AC_DEFINE(HAVE_CONSENSUS_LIB, 1, [Define this symbol if the consensus lib has been built]) AC_CONFIG_FILES([libbitcoinconsensus.pc:libbitcoinconsensus.pc.in]) fi AC_MSG_RESULT($build_bitcoin_libs) AC_LANG_POP if test "x$use_ccache" != "xno"; then AC_MSG_CHECKING(if ccache should be used) if test x$CCACHE = x; then if test "x$use_ccache" = "xyes"; then AC_MSG_ERROR([ccache not found.]); else use_ccache=no fi else use_ccache=yes CC="$ac_cv_path_CCACHE $CC" CXX="$ac_cv_path_CCACHE $CXX" fi AC_MSG_RESULT($use_ccache) fi if test "x$use_ccache" = "xyes"; then AX_CHECK_PREPROC_FLAG([-Qunused-arguments],[CPPFLAGS="-Qunused-arguments $CPPFLAGS"]) fi dnl enable wallet AC_MSG_CHECKING([if wallet should be enabled]) if test x$enable_wallet != xno; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions]) else AC_MSG_RESULT(no) fi dnl enable upnp support AC_MSG_CHECKING([whether to build with support for UPnP]) if test x$have_miniupnpc = xno; then if test x$use_upnp = xyes; then AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc") fi AC_MSG_RESULT(no) else if test x$use_upnp != xno; then AC_MSG_RESULT(yes) AC_MSG_CHECKING([whether to build with UPnP enabled by default]) use_upnp=yes upnp_setting=0 if test x$use_upnp_default != xno; then use_upnp_default=yes upnp_setting=1 fi AC_MSG_RESULT($use_upnp_default) AC_DEFINE_UNQUOTED([USE_UPNP],[$upnp_setting],[UPnP support not compiled if undefined, otherwise value (0 or 1) determines default state]) if test x$TARGET_OS = xwindows; then MINIUPNPC_CPPFLAGS="-DSTATICLIB -DMINIUPNP_STATICLIB" fi else AC_MSG_RESULT(no) fi fi dnl these are only used when qt is enabled BUILD_TEST_QT="" if test x$bitcoin_enable_qt != xno; then dnl enable dbus support AC_MSG_CHECKING([whether to build GUI with support for D-Bus]) if test x$bitcoin_enable_qt_dbus != xno; then AC_DEFINE([USE_DBUS],[1],[Define if dbus support should be compiled in]) fi AC_MSG_RESULT($bitcoin_enable_qt_dbus) dnl enable qr support AC_MSG_CHECKING([whether to build GUI with support for QR codes]) if test x$have_qrencode = xno; then if test x$use_qr = xyes; then AC_MSG_ERROR("QR support requested but cannot be built. use --without-qrencode") fi AC_MSG_RESULT(no) else if test x$use_qr != xno; then AC_MSG_RESULT(yes) AC_DEFINE([USE_QRCODE],[1],[Define if QR support should be compiled in]) use_qr=yes else AC_MSG_RESULT(no) fi fi if test x$XGETTEXT = x; then AC_MSG_WARN("xgettext is required to update qt translations") fi AC_MSG_CHECKING([whether to build test_bitcoin-qt]) if test x$use_gui_tests$bitcoin_enable_qt_test = xyesyes; then AC_MSG_RESULT([yes]) BUILD_TEST_QT="yes" else AC_MSG_RESULT([no]) fi fi AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) AC_MSG_CHECKING([whether to build test_bitcoin]) if test x$use_tests = xyes; then AC_MSG_RESULT([yes]) BUILD_TEST="yes" else AC_MSG_RESULT([no]) BUILD_TEST="" fi AC_MSG_CHECKING([whether to reduce exports]) if test x$use_reduce_exports = xyes; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnononononono; then AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-seeder --with-gui --enable-bench or --enable-tests]) fi AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin]) AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes]) AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes]) AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) AM_CONDITIONAL([ENABLE_HWCRC32],[test x$enable_hwcrc32 = xyes]) AM_CONDITIONAL([ENABLE_SSE41],[test x$enable_sse41 = xyes]) AM_CONDITIONAL([ENABLE_AVX2],[test x$enable_avx2 = xyes]) +AM_CONDITIONAL([ENABLE_SHANI],[test x$enable_shani = xyes]) AM_CONDITIONAL([USE_ASM],[test x$use_asm = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) AC_DEFINE(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION, [Build revision]) AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build]) AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release]) AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Copyright year]) AC_DEFINE(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS", [Copyright holder(s) before %s replacement]) AC_DEFINE(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION", [Replacement for %s in copyright holders string]) define(_COPYRIGHT_HOLDERS_FINAL, [patsubst(_COPYRIGHT_HOLDERS, [%s], [_COPYRIGHT_HOLDERS_SUBSTITUTION])]) AC_DEFINE(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL", [Copyright holder(s)]) AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR) AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR) AC_SUBST(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION) AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD) AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE) AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) AC_SUBST(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS") AC_SUBST(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION") AC_SUBST(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL") AC_SUBST(BITCOIN_DAEMON_NAME) AC_SUBST(BITCOIN_GUI_NAME) AC_SUBST(BITCOIN_CLI_NAME) AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(BITCOIN_SEEDER_NAME) AC_SUBST(RELDFLAGS) AC_SUBST(COMPAT_LDFLAGS) AC_SUBST(ERROR_CXXFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) AC_SUBST(PIC_FLAGS) AC_SUBST(PIE_FLAGS) AC_SUBST(SSE42_CXXFLAGS) AC_SUBST(SSE41_CXXFLAGS) AC_SUBST(AVX2_CXXFLAGS) +AC_SUBST(SHANI_CXXFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) AC_SUBST(USE_UPNP) AC_SUBST(USE_QRCODE) AC_SUBST(BOOST_LIBS) AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_SUBST(CRYPTO_LIBS) AC_SUBST(SSL_LIBS) AC_SUBST(EVENT_LIBS) AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py]) AC_CONFIG_LINKS([test/util/bitcoin-util-test.py:test/util/bitcoin-util-test.py]) dnl boost's m4 checks do something really nasty: they export these vars. As a dnl result, they leak into secp256k1's configure and crazy things happen. dnl Until this is fixed upstream and we've synced, we'll just un-export them. CPPFLAGS_TEMP="$CPPFLAGS" unset CPPFLAGS CPPFLAGS="$CPPFLAGS_TEMP" LDFLAGS_TEMP="$LDFLAGS" unset LDFLAGS LDFLAGS="$LDFLAGS_TEMP" LIBS_TEMP="$LIBS" unset LIBS LIBS="$LIBS_TEMP" PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" unset PKG_CONFIG_PATH PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP" PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR" unset PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" if test x$need_bundled_univalue = xyes; then AC_CONFIG_SUBDIRS([src/univalue]) fi ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery --enable-module-multiset --disable-jni" AC_CONFIG_SUBDIRS([src/secp256k1]) AC_OUTPUT dnl Taken from https://wiki.debian.org/RpathIssue case $host in *-*-linux-gnu) AC_MSG_RESULT([Fixing libtool for -rpath problems.]) sed < libtool > libtool-2 \ 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/' mv libtool-2 libtool chmod 755 libtool ;; esac dnl Replace the BUILDDIR path with the correct Windows path if compiling on Native Windows case ${OS} in *Windows*) sed 's/BUILDDIR="\/\([[a-z]]\)/BUILDDIR="\1:/' test/config.ini > test/config-2.ini mv test/config-2.ini test/config.ini ;; esac echo echo "Options used to compile and link:" echo " with wallet = $enable_wallet" echo " with gui / qt = $bitcoin_enable_qt" if test x$bitcoin_enable_qt != xno; then echo " with qr = $use_qr" fi echo " with zmq = $use_zmq" echo " with test = $use_tests" echo " with bench = $use_bench" echo " with upnp = $use_upnp" echo " use asm = $use_asm" echo " debug enabled = $enable_debug" echo " werror = $enable_werror" echo echo " sanitizers " echo " asan = $enable_asan" echo " tsan = $enable_tsan" echo " ubsan = $enable_ubsan" echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" echo echo " CC = $CC" echo " CFLAGS = $CFLAGS" echo " CPPFLAGS = $CPPFLAGS" echo " CXX = $CXX" echo " CXXFLAGS = $CXXFLAGS" echo " LDFLAGS = $LDFLAGS" echo diff --git a/doc/release-notes.md b/doc/release-notes.md index ae1b454680..07fa0eb34a 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,9 +1,9 @@ Bitcoin ABC version 0.18.3 is now available from: This release includes the following features and fixes: - Remove support for Qt4 - Upgrade reproducible build to us Qt 5.9.6 - - Improve SHA256 performance using SSE4.1 or AVX2 if available. + - Improve SHA256 performance using SSE4.1, AVX2 and/or SHA if available. diff --git a/src/Makefile.am b/src/Makefile.am index 755e3c26f1..a19f6278dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,626 +1,636 @@ # Copyright (c) 2013-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) AM_CPPFLAGS = $(HARDENED_CPPFLAGS) EXTRA_LIBRARIES = if EMBEDDED_UNIVALUE LIBUNIVALUE = univalue/libunivalue.la $(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) else LIBUNIVALUE = $(UNIVALUE_LIBS) endif BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS) BITCOIN_SEEDER_INCLUDES = -I$(srcdir)/seeder BITCOIN_SEEDER_INCLUDES += $(BITCOIN_INCLUDES) LIBBITCOIN_SERVER=libbitcoin_server.a LIBBITCOIN_COMMON=libbitcoin_common.a LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a LIBBITCOIN_CLI=libbitcoin_cli.a LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO_BASE=crypto/libbitcoin_crypto_base.a LIBBITCOINQT=qt/libbitcoinqt.a LIBSECP256K1=secp256k1/libsecp256k1.la if ENABLE_ZMQ LIBBITCOIN_ZMQ=libbitcoin_zmq.a endif if BUILD_BITCOIN_LIBS LIBBITCOINCONSENSUS=libbitcoinconsensus.la endif if BUILD_BITCOIN_SEEDER LIBBITCOIN_SEEDER=libbitcoin_seeder.a endif if ENABLE_WALLET LIBBITCOIN_WALLET=libbitcoin_wallet.a endif LIBBITCOIN_CRYPTO= $(LIBBITCOIN_CRYPTO_BASE) if ENABLE_SSE41 LIBBITCOIN_CRYPTO_SSE41 = crypto/libbitcoin_crypto_sse41.a LIBBITCOIN_CRYPTO += $(LIBBITCOIN_CRYPTO_SSE41) endif if ENABLE_AVX2 LIBBITCOIN_CRYPTO_AVX2 = crypto/libbitcoin_crypto_avx2.a LIBBITCOIN_CRYPTO += $(LIBBITCOIN_CRYPTO_AVX2) endif +if ENABLE_SHANI +LIBBITCOIN_CRYPTO_SHANI = crypto/libbitcoin_crypto_shani.a +LIBBITCOIN_CRYPTO += $(LIBBITCOIN_CRYPTO_SHANI) +endif $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: EXTRA_LIBRARIES += \ $(LIBBITCOIN_CRYPTO) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_CLI) \ $(LIBBITCOIN_SEEDER) \ $(LIBBITCOIN_WALLET) \ $(LIBBITCOIN_ZMQ) lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS) bin_PROGRAMS = noinst_PROGRAMS = TESTS = BENCHMARKS = if BUILD_BITCOIND bin_PROGRAMS += bitcoind endif if BUILD_BITCOIN_SEEDER bin_PROGRAMS += bitcoin-seeder endif if BUILD_BITCOIN_UTILS bin_PROGRAMS += bitcoin-cli bitcoin-tx endif .PHONY: FORCE check-symbols check-security # bitcoin core # BITCOIN_CORE_H = \ addrdb.h \ addrman.h \ base58.h \ bloom.h \ blockencodings.h \ blockfileinfo.h \ blockindexworkcomparator.h \ blockstatus.h \ blockvalidity.h \ cashaddr.h \ cashaddrenc.h \ chain.h \ chainparams.h \ chainparamsbase.h \ chainparamsseeds.h \ checkpoints.h \ checkqueue.h \ clientversion.h \ coins.h \ compat.h \ compat/byteswap.h \ compat/endian.h \ compat/sanity.h \ compressor.h \ config.h \ consensus/activation.h \ consensus/consensus.h \ consensus/tx_verify.h \ core_io.h \ core_memusage.h \ cuckoocache.h \ diskblockpos.h \ dstencode.h \ fs.h \ globals.h \ httprpc.h \ httpserver.h \ indirectmap.h \ init.h \ key.h \ keystore.h \ dbwrapper.h \ limitedmap.h \ logging.h \ memusage.h \ merkleblock.h \ miner.h \ net.h \ net_processing.h \ netaddress.h \ netbase.h \ netmessagemaker.h \ noui.h \ policy/fees.h \ policy/policy.h \ pow.h \ protocol.h \ random.h \ reverselock.h \ rpc/blockchain.h \ rpc/client.h \ rpc/jsonrpcrequest.h \ rpc/mining.h \ rpc/misc.h \ rpc/protocol.h \ rpc/server.h \ rpc/tojson.h \ rpc/register.h \ scheduler.h \ script/scriptcache.h \ script/sigcache.h \ script/sign.h \ script/standard.h \ script/ismine.h \ streams.h \ support/allocators/secure.h \ support/allocators/zeroafterfree.h \ support/cleanse.h \ support/events.h \ support/lockedpool.h \ sync.h \ threadsafety.h \ threadinterrupt.h \ timedata.h \ torcontrol.h \ txdb.h \ txmempool.h \ ui_interface.h \ undo.h \ util.h \ utilmoneystr.h \ utiltime.h \ validation.h \ validationinterface.h \ versionbits.h \ wallet/coincontrol.h \ wallet/crypter.h \ wallet/db.h \ wallet/finaltx.h \ wallet/rpcdump.h \ wallet/fees.h \ wallet/init.h \ wallet/rpcwallet.h \ wallet/wallet.h \ wallet/walletdb.h \ warnings.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h\ zmq/zmqnotificationinterface.h \ zmq/zmqpublishnotifier.h obj/build.h: FORCE @$(MKDIR_P) "$(builddir)/obj" @$(top_srcdir)/share/genbuild.sh "$(abs_top_builddir)/src/obj/build.h" \ "$(abs_top_srcdir)" libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between bitcoind and bitcoin-qt libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ addrdb.cpp \ bloom.cpp \ blockencodings.cpp \ chain.cpp \ checkpoints.cpp \ config.cpp \ consensus/activation.cpp \ consensus/tx_verify.cpp \ globals.cpp \ httprpc.cpp \ httpserver.cpp \ init.cpp \ dbwrapper.cpp \ merkleblock.cpp \ miner.cpp \ net.cpp \ net_processing.cpp \ noui.cpp \ policy/fees.cpp \ policy/policy.cpp \ pow.cpp \ rest.cpp \ rpc/abc.cpp \ rpc/blockchain.cpp \ rpc/jsonrpcrequest.cpp \ rpc/mining.cpp \ rpc/misc.cpp \ rpc/net.cpp \ rpc/rawtransaction.cpp \ rpc/server.cpp \ script/scriptcache.cpp \ script/sigcache.cpp \ script/ismine.cpp \ timedata.cpp \ torcontrol.cpp \ txdb.cpp \ txmempool.cpp \ ui_interface.cpp \ validation.cpp \ validationinterface.cpp \ versionbits.cpp \ $(BITCOIN_CORE_H) if ENABLE_ZMQ libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_zmq_a_SOURCES = \ zmq/zmqabstractnotifier.cpp \ zmq/zmqnotificationinterface.cpp \ zmq/zmqpublishnotifier.cpp endif # wallet: shared between bitcoind and bitcoin-qt, but only linked # when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ wallet/crypter.cpp \ wallet/db.cpp \ wallet/finaltx.cpp \ wallet/fees.cpp \ wallet/init.cpp \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ wallet/walletdb.cpp \ $(BITCOIN_CORE_H) # crypto primitives library crypto_libbitcoin_crypto_base_a_CPPFLAGS = $(AM_CPPFLAGS) crypto_libbitcoin_crypto_base_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_base_a_SOURCES = \ crypto/aes.cpp \ crypto/aes.h \ crypto/chacha20.h \ crypto/chacha20.cpp \ crypto/common.h \ crypto/hmac_sha256.cpp \ crypto/hmac_sha256.h \ crypto/hmac_sha512.cpp \ crypto/hmac_sha512.h \ crypto/ripemd160.cpp \ crypto/ripemd160.h \ crypto/sha1.cpp \ crypto/sha1.h \ crypto/sha256.cpp \ crypto/sha256.h \ crypto/sha512.cpp \ crypto/sha512.h if USE_ASM crypto_libbitcoin_crypto_base_a_SOURCES += crypto/sha256_sse4.cpp endif crypto_libbitcoin_crypto_sse41_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_sse41_a_CPPFLAGS = $(AM_CPPFLAGS) crypto_libbitcoin_crypto_sse41_a_CXXFLAGS += $(SSE41_CXXFLAGS) crypto_libbitcoin_crypto_sse41_a_CPPFLAGS += -DENABLE_SSE41 crypto_libbitcoin_crypto_sse41_a_SOURCES = crypto/sha256_sse41.cpp crypto_libbitcoin_crypto_avx2_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_avx2_a_CPPFLAGS = $(AM_CPPFLAGS) crypto_libbitcoin_crypto_avx2_a_CXXFLAGS += $(AVX2_CXXFLAGS) crypto_libbitcoin_crypto_avx2_a_CPPFLAGS += -DENABLE_AVX2 crypto_libbitcoin_crypto_avx2_a_SOURCES = crypto/sha256_avx2.cpp +crypto_libbitcoin_crypto_shani_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +crypto_libbitcoin_crypto_shani_a_CPPFLAGS = $(AM_CPPFLAGS) +crypto_libbitcoin_crypto_shani_a_CXXFLAGS += $(SHANI_CXXFLAGS) +crypto_libbitcoin_crypto_shani_a_CPPFLAGS += -DENABLE_SHANI +crypto_libbitcoin_crypto_shani_a_SOURCES = crypto/sha256_shani.cpp + # consensus: shared between all executables that validate any consensus rules. libbitcoin_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_consensus_a_SOURCES = \ amount.h \ arith_uint256.cpp \ arith_uint256.h \ consensus/merkle.cpp \ consensus/merkle.h \ consensus/params.h \ consensus/validation.h \ feerate.h \ hash.cpp \ hash.h \ prevector.h \ primitives/block.cpp \ primitives/block.h \ primitives/transaction.cpp \ primitives/transaction.h \ primitives/txid.h \ pubkey.cpp \ pubkey.h \ script/bitcoinconsensus.cpp \ script/sighashtype.h \ script/interpreter.cpp \ script/interpreter.h \ script/script.cpp \ script/script.h \ script/script_error.cpp \ script/script_error.h \ script/script_flags.h \ script/sigencoding.cpp \ script/sigencoding.h \ serialize.h \ tinyformat.h \ uint256.cpp \ uint256.h \ utilstrencodings.cpp \ utilstrencodings.h \ version.h # common: shared between bitcoind, and bitcoin-qt and non-server tools libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_common_a_SOURCES = \ amount.cpp \ base58.cpp \ cashaddr.cpp \ cashaddrenc.cpp \ chainparams.cpp \ config.cpp \ coins.cpp \ compressor.cpp \ dstencode.cpp \ feerate.cpp \ globals.cpp \ core_read.cpp \ core_write.cpp \ key.cpp \ keystore.cpp \ netaddress.cpp \ netbase.cpp \ protocol.cpp \ scheduler.cpp \ script/sign.cpp \ script/standard.cpp \ warnings.cpp \ $(BITCOIN_CORE_H) # util: shared between all executables. # This library *must* be included to make sure that the glibc # backward-compatibility objects and their sanity checks are linked. libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_util_a_SOURCES = \ support/lockedpool.cpp \ chainparamsbase.cpp \ clientversion.cpp \ compat/glibc_sanity.cpp \ compat/glibcxx_sanity.cpp \ compat/strnlen.cpp \ fs.cpp \ logging.cpp \ random.cpp \ rpc/protocol.cpp \ support/cleanse.cpp \ sync.cpp \ threadinterrupt.cpp \ uint256.cpp \ uint256.h \ util.cpp \ utilmoneystr.cpp \ utilstrencodings.cpp \ utiltime.cpp \ $(BITCOIN_CORE_H) if GLIBC_BACK_COMPAT libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp AM_LDFLAGS += $(COMPAT_LDFLAGS) endif # cli: shared between bitcoin-cli and bitcoin-qt libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ rpc/client.cpp \ $(BITCOIN_CORE_H) # seeder library libbitcoin_seeder_a_CPPFLAGS = $(AM_CPPFLAGS) $(PIE_FLAGS) $(BITCOIN_SEEDER_INCLUDES) libbitcoin_seeder_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_seeder_a_SOURCES = \ seeder/bitcoin.cpp \ seeder/bitcoin.h \ seeder/compat.h \ seeder/db.cpp \ seeder/db.h \ seeder/dns.cpp \ seeder/dns.h \ seeder/strlcpy.h \ seeder/util.h nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # # bitcoind binary # bitcoind_SOURCES = bitcoind.cpp bitcoind_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) bitcoind_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS bitcoind_SOURCES += bitcoind-res.rc endif bitcoind_LDADD = \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_COMMON) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_WALLET) \ $(LIBBITCOIN_ZMQ) \ $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ $(LIBLEVELDB_SSE42) \ $(LIBMEMENV) \ $(LIBSECP256K1) bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) # bitcoin-cli binary # bitcoin_cli_SOURCES = bitcoin-cli.cpp bitcoin_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) bitcoin_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS bitcoin_cli_SOURCES += bitcoin-cli-res.rc endif bitcoin_cli_LDADD = \ $(LIBBITCOIN_CLI) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) # # bitcoin-seeder binary # bitcoin_seeder_SOURCES = seeder/main.cpp bitcoin_seeder_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_SEEDER_INCLUDES) bitcoin_seeder_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoin_seeder_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) bitcoin_seeder_LDADD = \ $(LIBBITCOIN_SEEDER) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) bitcoin_seeder_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # # bitcoin-tx binary # bitcoin_tx_SOURCES = bitcoin-tx.cpp bitcoin_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) bitcoin_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS bitcoin_tx_SOURCES += bitcoin-tx-res.rc endif bitcoin_tx_LDADD = \ $(LIBUNIVALUE) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBSECP256K1) bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # # bitcoinconsensus library # if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h libbitcoinconsensus_la_SOURCES = $(crypto_libbitcoin_crypto_base_a_SOURCES) $(libbitcoin_consensus_a_SOURCES) if GLIBC_BACK_COMPAT libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp endif libbitcoinconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) libbitcoinconsensus_la_LIBADD = $(LIBSECP256K1) libbitcoinconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) endif # CTAES_DIST = crypto/ctaes/bench.c CTAES_DIST += crypto/ctaes/ctaes.c CTAES_DIST += crypto/ctaes/ctaes.h CTAES_DIST += crypto/ctaes/README.md CTAES_DIST += crypto/ctaes/test.c CLEANFILES = $(EXTRA_LIBRARIES) CLEANFILES += *.gcda *.gcno CLEANFILES += compat/*.gcda compat/*.gcno CLEANFILES += consensus/*.gcda consensus/*.gcno CLEANFILES += crypto/*.gcda crypto/*.gcno CLEANFILES += policy/*.gcda policy/*.gcno CLEANFILES += primitives/*.gcda primitives/*.gcno CLEANFILES += script/*.gcda script/*.gcno CLEANFILES += support/*.gcda support/*.gcno CLEANFILES += univalue/*.gcda univalue/*.gcno CLEANFILES += wallet/*.gcda wallet/*.gcno CLEANFILES += wallet/test/*.gcda wallet/test/*.gcno CLEANFILES += zmq/*.gcda zmq/*.gcno DISTCLEANFILES = obj/build.h EXTRA_DIST = $(CTAES_DIST) clean-local: -$(MAKE) -C secp256k1 clean -$(MAKE) -C univalue clean -rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno -rm -rf test/__pycache__ .rc.o: @test -f $(WINDRES) ## FIXME: How to get the appropriate modulename_CPPFLAGS in here? $(AM_V_GEN) $(WINDRES) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -DWINDRES_PREPROC -i $< -o $@ .mm.o: $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) -c -o $@ $< check-symbols: $(bin_PROGRAMS) if GLIBC_BACK_COMPAT @echo "Checking glibc back compat..." $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py < $(bin_PROGRAMS) endif check-security: $(bin_PROGRAMS) if HARDEN @echo "Checking binary security..." $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) endif %.pb.cc %.pb.h: %.proto @test -f $(PROTOC) $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$( #include #include -#if defined(__x86_64__) || defined(__amd64__) +#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) #if defined(USE_ASM) #include namespace sha256_sse4 { void Transform(uint32_t *s, const uint8_t *chunk, size_t blocks); } #endif #endif namespace sha256d64_sse41 { void Transform_4way(uint8_t *out, const uint8_t *in); } namespace sha256d64_avx2 { void Transform_8way(uint8_t *out, const uint8_t *in); } +namespace sha256d64_shani { +void Transform_2way(unsigned char *out, const unsigned char *in); +} + +namespace sha256_shani { +void Transform(uint32_t *s, const unsigned char *chunk, size_t blocks); +} + // Internal implementation code. namespace { /// Internal SHA-256 implementation. namespace sha256 { inline uint32_t Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); } inline uint32_t Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); } inline uint32_t Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); } inline uint32_t Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); } inline uint32_t sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); } inline uint32_t sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); } /** One round of SHA-256. */ inline void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d, uint32_t e, uint32_t f, uint32_t g, uint32_t &h, uint32_t k) { uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k; uint32_t t2 = Sigma0(a) + Maj(a, b, c); d += t1; h = t1 + t2; } /** Initialize SHA-256 state. */ inline void Initialize(uint32_t *s) { s[0] = 0x6a09e667ul; s[1] = 0xbb67ae85ul; s[2] = 0x3c6ef372ul; s[3] = 0xa54ff53aul; s[4] = 0x510e527ful; s[5] = 0x9b05688cul; s[6] = 0x1f83d9abul; s[7] = 0x5be0cd19ul; } /** * Perform a number of SHA-256 transformations, processing 64-byte chunks. */ void Transform(uint32_t *s, const uint8_t *chunk, size_t blocks) { while (blocks--) { 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; Round(a, b, c, d, e, f, g, h, 0x428a2f98 + (w0 = ReadBE32(chunk + 0))); Round(h, a, b, c, d, e, f, g, 0x71374491 + (w1 = ReadBE32(chunk + 4))); Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf + (w2 = ReadBE32(chunk + 8))); Round(f, g, h, a, b, c, d, e, 0xe9b5dba5 + (w3 = ReadBE32(chunk + 12))); Round(e, f, g, h, a, b, c, d, 0x3956c25b + (w4 = ReadBE32(chunk + 16))); Round(d, e, f, g, h, a, b, c, 0x59f111f1 + (w5 = ReadBE32(chunk + 20))); Round(c, d, e, f, g, h, a, b, 0x923f82a4 + (w6 = ReadBE32(chunk + 24))); Round(b, c, d, e, f, g, h, a, 0xab1c5ed5 + (w7 = ReadBE32(chunk + 28))); Round(a, b, c, d, e, f, g, h, 0xd807aa98 + (w8 = ReadBE32(chunk + 32))); Round(h, a, b, c, d, e, f, g, 0x12835b01 + (w9 = ReadBE32(chunk + 36))); Round(g, h, a, b, c, d, e, f, 0x243185be + (w10 = ReadBE32(chunk + 40))); Round(f, g, h, a, b, c, d, e, 0x550c7dc3 + (w11 = ReadBE32(chunk + 44))); Round(e, f, g, h, a, b, c, d, 0x72be5d74 + (w12 = ReadBE32(chunk + 48))); Round(d, e, f, g, h, a, b, c, 0x80deb1fe + (w13 = ReadBE32(chunk + 52))); Round(c, d, e, f, g, h, a, b, 0x9bdc06a7 + (w14 = ReadBE32(chunk + 56))); Round(b, c, d, e, f, g, h, a, 0xc19bf174 + (w15 = ReadBE32(chunk + 60))); Round(a, b, c, d, e, f, g, h, 0xe49b69c1 + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0xefbe4786 + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x0fc19dc6 + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x240ca1cc + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x2de92c6f + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x4a7484aa + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x76f988da + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0x983e5152 + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0xa831c66d + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0xb00327c8 + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0xbf597fc7 + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0xc6e00bf3 + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xd5a79147 + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0x06ca6351 + (w14 += sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0x14292967 + (w15 += sigma1(w13) + w8 + sigma0(w0))); Round(a, b, c, d, e, f, g, h, 0x27b70a85 + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0x2e1b2138 + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x53380d13 + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x650a7354 + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x766a0abb + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x81c2c92e + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x92722c85 + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1 + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0xa81a664b + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0xc24b8b70 + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0xc76c51a3 + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0xd192e819 + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xd6990624 + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0xf40e3585 + (w14 += sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0x106aa070 + (w15 += sigma1(w13) + w8 + sigma0(w0))); Round(a, b, c, d, e, f, g, h, 0x19a4c116 + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0x1e376c08 + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x2748774c + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x34b0bcb5 + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x391c0cb3 + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x5b9cca4f + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x682e6ff3 + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0x748f82ee + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0x78a5636f + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0x84c87814 + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0x8cc70208 + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0x90befffa + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xa4506ceb + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0xbef9a3f7 + (w14 + sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0xc67178f2 + (w15 + sigma1(w13) + w8 + sigma0(w0))); s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h; chunk += 64; } } void TransformD64(uint8_t *out, const uint8_t *in) { // Transform 1 uint32_t a = 0x6a09e667ul; uint32_t b = 0xbb67ae85ul; uint32_t c = 0x3c6ef372ul; uint32_t d = 0xa54ff53aul; uint32_t e = 0x510e527ful; uint32_t f = 0x9b05688cul; uint32_t g = 0x1f83d9abul; uint32_t h = 0x5be0cd19ul; uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + (w0 = ReadBE32(in + 0))); Round(h, a, b, c, d, e, f, g, 0x71374491ul + (w1 = ReadBE32(in + 4))); Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + (w2 = ReadBE32(in + 8))); Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + (w3 = ReadBE32(in + 12))); Round(e, f, g, h, a, b, c, d, 0x3956c25bul + (w4 = ReadBE32(in + 16))); Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + (w5 = ReadBE32(in + 20))); Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + (w6 = ReadBE32(in + 24))); Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + (w7 = ReadBE32(in + 28))); Round(a, b, c, d, e, f, g, h, 0xd807aa98ul + (w8 = ReadBE32(in + 32))); Round(h, a, b, c, d, e, f, g, 0x12835b01ul + (w9 = ReadBE32(in + 36))); Round(g, h, a, b, c, d, e, f, 0x243185beul + (w10 = ReadBE32(in + 40))); Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul + (w11 = ReadBE32(in + 44))); Round(e, f, g, h, a, b, c, d, 0x72be5d74ul + (w12 = ReadBE32(in + 48))); Round(d, e, f, g, h, a, b, c, 0x80deb1feul + (w13 = ReadBE32(in + 52))); Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul + (w14 = ReadBE32(in + 56))); Round(b, c, d, e, f, g, h, a, 0xc19bf174ul + (w15 = ReadBE32(in + 60))); Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 += sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 += sigma1(w13) + w8 + sigma0(w0))); Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0))); Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0))); a += 0x6a09e667ul; b += 0xbb67ae85ul; c += 0x3c6ef372ul; d += 0xa54ff53aul; e += 0x510e527ful; f += 0x9b05688cul; g += 0x1f83d9abul; h += 0x5be0cd19ul; uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h; // Transform 2 Round(a, b, c, d, e, f, g, h, 0xc28a2f98ul); Round(h, a, b, c, d, e, f, g, 0x71374491ul); Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful); Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul); Round(e, f, g, h, a, b, c, d, 0x3956c25bul); Round(d, e, f, g, h, a, b, c, 0x59f111f1ul); Round(c, d, e, f, g, h, a, b, 0x923f82a4ul); Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul); Round(a, b, c, d, e, f, g, h, 0xd807aa98ul); Round(h, a, b, c, d, e, f, g, 0x12835b01ul); Round(g, h, a, b, c, d, e, f, 0x243185beul); Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul); Round(e, f, g, h, a, b, c, d, 0x72be5d74ul); Round(d, e, f, g, h, a, b, c, 0x80deb1feul); Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul); Round(b, c, d, e, f, g, h, a, 0xc19bf374ul); Round(a, b, c, d, e, f, g, h, 0x649b69c1ul); Round(h, a, b, c, d, e, f, g, 0xf0fe4786ul); Round(g, h, a, b, c, d, e, f, 0x0fe1edc6ul); Round(f, g, h, a, b, c, d, e, 0x240cf254ul); Round(e, f, g, h, a, b, c, d, 0x4fe9346ful); Round(d, e, f, g, h, a, b, c, 0x6cc984beul); Round(c, d, e, f, g, h, a, b, 0x61b9411eul); Round(b, c, d, e, f, g, h, a, 0x16f988faul); Round(a, b, c, d, e, f, g, h, 0xf2c65152ul); Round(h, a, b, c, d, e, f, g, 0xa88e5a6dul); Round(g, h, a, b, c, d, e, f, 0xb019fc65ul); Round(f, g, h, a, b, c, d, e, 0xb9d99ec7ul); Round(e, f, g, h, a, b, c, d, 0x9a1231c3ul); Round(d, e, f, g, h, a, b, c, 0xe70eeaa0ul); Round(c, d, e, f, g, h, a, b, 0xfdb1232bul); Round(b, c, d, e, f, g, h, a, 0xc7353eb0ul); Round(a, b, c, d, e, f, g, h, 0x3069bad5ul); Round(h, a, b, c, d, e, f, g, 0xcb976d5ful); Round(g, h, a, b, c, d, e, f, 0x5a0f118ful); Round(f, g, h, a, b, c, d, e, 0xdc1eeefdul); Round(e, f, g, h, a, b, c, d, 0x0a35b689ul); Round(d, e, f, g, h, a, b, c, 0xde0b7a04ul); Round(c, d, e, f, g, h, a, b, 0x58f4ca9dul); Round(b, c, d, e, f, g, h, a, 0xe15d5b16ul); Round(a, b, c, d, e, f, g, h, 0x007f3e86ul); Round(h, a, b, c, d, e, f, g, 0x37088980ul); Round(g, h, a, b, c, d, e, f, 0xa507ea32ul); Round(f, g, h, a, b, c, d, e, 0x6fab9537ul); Round(e, f, g, h, a, b, c, d, 0x17406110ul); Round(d, e, f, g, h, a, b, c, 0x0d8cd6f1ul); Round(c, d, e, f, g, h, a, b, 0xcdaa3b6dul); Round(b, c, d, e, f, g, h, a, 0xc0bbbe37ul); Round(a, b, c, d, e, f, g, h, 0x83613bdaul); Round(h, a, b, c, d, e, f, g, 0xdb48a363ul); Round(g, h, a, b, c, d, e, f, 0x0b02e931ul); Round(f, g, h, a, b, c, d, e, 0x6fd15ca7ul); Round(e, f, g, h, a, b, c, d, 0x521afacaul); Round(d, e, f, g, h, a, b, c, 0x31338431ul); Round(c, d, e, f, g, h, a, b, 0x6ed41a95ul); Round(b, c, d, e, f, g, h, a, 0x6d437890ul); Round(a, b, c, d, e, f, g, h, 0xc39c91f2ul); Round(h, a, b, c, d, e, f, g, 0x9eccabbdul); Round(g, h, a, b, c, d, e, f, 0xb5c9a0e6ul); Round(f, g, h, a, b, c, d, e, 0x532fb63cul); Round(e, f, g, h, a, b, c, d, 0xd2c741c6ul); Round(d, e, f, g, h, a, b, c, 0x07237ea3ul); Round(c, d, e, f, g, h, a, b, 0xa4954b68ul); Round(b, c, d, e, f, g, h, a, 0x4c191d76ul); w0 = t0 + a; w1 = t1 + b; w2 = t2 + c; w3 = t3 + d; w4 = t4 + e; w5 = t5 + f; w6 = t6 + g; w7 = t7 + h; // Transform 3 a = 0x6a09e667ul; b = 0xbb67ae85ul; c = 0x3c6ef372ul; d = 0xa54ff53aul; e = 0x510e527ful; f = 0x9b05688cul; g = 0x1f83d9abul; h = 0x5be0cd19ul; Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + w0); Round(h, a, b, c, d, e, f, g, 0x71374491ul + w1); Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + w2); Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + w3); Round(e, f, g, h, a, b, c, d, 0x3956c25bul + w4); Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + w5); Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + w6); Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + w7); Round(a, b, c, d, e, f, g, h, 0x5807aa98ul); Round(h, a, b, c, d, e, f, g, 0x12835b01ul); Round(g, h, a, b, c, d, e, f, 0x243185beul); Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul); Round(e, f, g, h, a, b, c, d, 0x72be5d74ul); Round(d, e, f, g, h, a, b, c, 0x80deb1feul); Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul); Round(b, c, d, e, f, g, h, a, 0xc19bf274ul); Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += 0xa00000ul + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + 0x100ul + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + 0x11002000ul)); Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 = 0x80000000ul + sigma1(w6) + w1)); Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 = sigma1(w7) + w2)); Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 = sigma1(w8) + w3)); Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 = sigma1(w9) + w4)); Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 = sigma1(w10) + w5)); Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 = sigma1(w11) + w6)); Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 = sigma1(w12) + w7 + 0x400022ul)); Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 = 0x100ul + sigma1(w13) + w8 + sigma0(w0))); Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0))); Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3))); Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6))); Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7))); Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9))); Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10))); Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13))); Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14))); Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15))); Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0))); // Output WriteBE32(out + 0, a + 0x6a09e667ul); WriteBE32(out + 4, b + 0xbb67ae85ul); WriteBE32(out + 8, c + 0x3c6ef372ul); WriteBE32(out + 12, d + 0xa54ff53aul); WriteBE32(out + 16, e + 0x510e527ful); WriteBE32(out + 20, f + 0x9b05688cul); WriteBE32(out + 24, g + 0x1f83d9abul); WriteBE32(out + 28, h + 0x5be0cd19ul); } } // namespace sha256 typedef void (*TransformType)(uint32_t *, const uint8_t *, size_t); typedef void (*TransformD64Type)(uint8_t *, const uint8_t *); template void TransformD64Wrapper(uint8_t *out, const uint8_t *in) { uint32_t s[8]; static const uint8_t padding1[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0}; uint8_t buffer2[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}; sha256::Initialize(s); tr(s, in, 1); tr(s, padding1, 1); WriteBE32(buffer2 + 0, s[0]); WriteBE32(buffer2 + 4, s[1]); WriteBE32(buffer2 + 8, s[2]); WriteBE32(buffer2 + 12, s[3]); WriteBE32(buffer2 + 16, s[4]); WriteBE32(buffer2 + 20, s[5]); WriteBE32(buffer2 + 24, s[6]); WriteBE32(buffer2 + 28, s[7]); sha256::Initialize(s); tr(s, buffer2, 1); WriteBE32(out + 0, s[0]); WriteBE32(out + 4, s[1]); WriteBE32(out + 8, s[2]); WriteBE32(out + 12, s[3]); WriteBE32(out + 16, s[4]); WriteBE32(out + 20, s[5]); WriteBE32(out + 24, s[6]); WriteBE32(out + 28, s[7]); } TransformType Transform = sha256::Transform; TransformD64Type TransformD64 = sha256::TransformD64; +TransformD64Type TransformD64_2way = nullptr; TransformD64Type TransformD64_4way = nullptr; TransformD64Type TransformD64_8way = nullptr; bool SelfTest() { // Input state (equal to the initial SHA256 state) static const uint32_t init[8] = {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul}; // Some random input data to test with static const uint8_t data[641] = "-" // Intentionally not aligned "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " "eiusmod tempor incididunt ut labore et dolore magna aliqua. Et m" "olestie ac feugiat sed lectus vestibulum mattis ullamcorper. Mor" "bi blandit cursus risus at ultrices mi tempus imperdiet nulla. N" "unc congue nisi vita suscipit tellus mauris. Imperdiet proin fer" "mentum leo vel orci. Massa tempor nec feugiat nisl pretium fusce" " id velit. Telus in metus vulputate eu scelerisque felis. Mi tem" "pus imperdiet nulla malesuada pellentesque. Tristique magna sit."; // Expected output state for hashing the i*64 first input bytes above // (excluding SHA256 padding). static const uint32_t result[9][8] = { {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul}, {0x91f8ec6bul, 0x4da10fe3ul, 0x1c9c292cul, 0x45e18185ul, 0x435cc111ul, 0x3ca26f09ul, 0xeb954caeul, 0x402a7069ul}, {0xcabea5acul, 0x374fb97cul, 0x182ad996ul, 0x7bd69cbful, 0x450ff900ul, 0xc1d2be8aul, 0x6a41d505ul, 0xe6212dc3ul}, {0xbcff09d6ul, 0x3e76f36eul, 0x3ecb2501ul, 0x78866e97ul, 0xe1c1e2fdul, 0x32f4eafful, 0x8aa6c4e5ul, 0xdfc024bcul}, {0xa08c5d94ul, 0x0a862f93ul, 0x6b7f2f40ul, 0x8f9fae76ul, 0x6d40439ful, 0x79dcee0cul, 0x3e39ff3aul, 0xdc3bdbb1ul}, {0x216a0895ul, 0x9f1a3662ul, 0xe99946f9ul, 0x87ba4364ul, 0x0fb5db2cul, 0x12bed3d3ul, 0x6689c0c7ul, 0x292f1b04ul}, {0xca3067f8ul, 0xbc8c2656ul, 0x37cb7e0dul, 0x9b6b8b0ful, 0x46dc380bul, 0xf1287f57ul, 0xc42e4b23ul, 0x3fefe94dul}, {0x3e4c4039ul, 0xbb6fca8cul, 0x6f27d2f7ul, 0x301e44a4ul, 0x8352ba14ul, 0x5769ce37ul, 0x48a1155ful, 0xc0e1c4c6ul}, {0xfe2fa9ddul, 0x69d0862bul, 0x1ae0db23ul, 0x471f9244ul, 0xf55c0145ul, 0xc30f9c3bul, 0x40a84ea0ul, 0x5b8a266cul}, }; // Expected output for each of the individual 8 64-byte messages under full // double SHA256 (including padding). static const uint8_t result_d64[256] = { 0x09, 0x3a, 0xc4, 0xd0, 0x0f, 0xf7, 0x57, 0xe1, 0x72, 0x85, 0x79, 0x42, 0xfe, 0xe7, 0xe0, 0xa0, 0xfc, 0x52, 0xd7, 0xdb, 0x07, 0x63, 0x45, 0xfb, 0x53, 0x14, 0x7d, 0x17, 0x22, 0x86, 0xf0, 0x52, 0x48, 0xb6, 0x11, 0x9e, 0x6e, 0x48, 0x81, 0x6d, 0xcc, 0x57, 0x1f, 0xb2, 0x97, 0xa8, 0xd5, 0x25, 0x9b, 0x82, 0xaa, 0x89, 0xe2, 0xfd, 0x2d, 0x56, 0xe8, 0x28, 0x83, 0x0b, 0xe2, 0xfa, 0x53, 0xb7, 0xd6, 0x6b, 0x07, 0x85, 0x83, 0xb0, 0x10, 0xa2, 0xf5, 0x51, 0x3c, 0xf9, 0x60, 0x03, 0xab, 0x45, 0x6c, 0x15, 0x6e, 0xef, 0xb5, 0xac, 0x3e, 0x6c, 0xdf, 0xb4, 0x92, 0x22, 0x2d, 0xce, 0xbf, 0x3e, 0xe9, 0xe5, 0xf6, 0x29, 0x0e, 0x01, 0x4f, 0xd2, 0xd4, 0x45, 0x65, 0xb3, 0xbb, 0xf2, 0x4c, 0x16, 0x37, 0x50, 0x3c, 0x6e, 0x49, 0x8c, 0x5a, 0x89, 0x2b, 0x1b, 0xab, 0xc4, 0x37, 0xd1, 0x46, 0xe9, 0x3d, 0x0e, 0x85, 0xa2, 0x50, 0x73, 0xa1, 0x5e, 0x54, 0x37, 0xd7, 0x94, 0x17, 0x56, 0xc2, 0xd8, 0xe5, 0x9f, 0xed, 0x4e, 0xae, 0x15, 0x42, 0x06, 0x0d, 0x74, 0x74, 0x5e, 0x24, 0x30, 0xce, 0xd1, 0x9e, 0x50, 0xa3, 0x9a, 0xb8, 0xf0, 0x4a, 0x57, 0x69, 0x78, 0x67, 0x12, 0x84, 0x58, 0xbe, 0xc7, 0x36, 0xaa, 0xee, 0x7c, 0x64, 0xa3, 0x76, 0xec, 0xff, 0x55, 0x41, 0x00, 0x2a, 0x44, 0x68, 0x4d, 0xb6, 0x53, 0x9e, 0x1c, 0x95, 0xb7, 0xca, 0xdc, 0x7f, 0x7d, 0x74, 0x27, 0x5c, 0x8e, 0xa6, 0x84, 0xb5, 0xac, 0x87, 0xa9, 0xf3, 0xff, 0x75, 0xf2, 0x34, 0xcd, 0x1a, 0x3b, 0x82, 0x2c, 0x2b, 0x4e, 0x6a, 0x46, 0x30, 0xa6, 0x89, 0x86, 0x23, 0xac, 0xf8, 0xa5, 0x15, 0xe9, 0x0a, 0xaa, 0x1e, 0x9a, 0xd7, 0x93, 0x6b, 0x28, 0xe4, 0x3b, 0xfd, 0x59, 0xc6, 0xed, 0x7c, 0x5f, 0xa5, 0x41, 0xcb, 0x51}; // Test Transform() for 0 through 8 transformations. for (size_t i = 0; i <= 8; ++i) { uint32_t state[8]; std::copy(init, init + 8, state); Transform(state, data + 1, i); if (!std::equal(state, state + 8, result[i])) return false; } // Test TransformD64 { uint8_t out[32]; TransformD64(out, data + 1); if (!std::equal(out, out + 32, result_d64)) return false; } + // Test TransformD64_2way, if available. + if (TransformD64_2way) { + unsigned char out[64]; + TransformD64_2way(out, data + 1); + if (!std::equal(out, out + 64, result_d64)) return false; + } + // Test TransformD64_4way, if available. if (TransformD64_4way) { uint8_t out[128]; TransformD64_4way(out, data + 1); if (!std::equal(out, out + 128, result_d64)) return false; } // Test TransformD64_8way, if available. if (TransformD64_8way) { uint8_t out[256]; TransformD64_8way(out, data + 1); if (!std::equal(out, out + 256, result_d64)) return false; } return true; } #if defined(USE_ASM) && \ (defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) // We can't use cpuid.h's __get_cpuid as it does not support subleafs. -void inline cpuid(uint32_t leaf, uint32_t subleaf, uint32_t &a, uint32_t &b, +inline void cpuid(uint32_t leaf, uint32_t subleaf, uint32_t &a, uint32_t &b, uint32_t &c, uint32_t &d) { +#ifdef __GNUC__ + __cpuid_count(leaf, subleaf, a, b, c, d); +#else __asm__("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf)); +#endif } /** Check whether the OS has enabled AVX registers. */ bool AVXEnabled() { uint32_t a, d; __asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0)); return (a & 6) == 6; } #endif } // namespace std::string SHA256AutoDetect() { std::string ret = "standard"; #if defined(USE_ASM) && \ (defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) - // Silence unused warning (in case ENABLE_AVX2 is not defined) + bool have_sse4 = false; + bool have_xsave = false; + bool have_avx = false; + bool have_avx2 = false; + bool have_shani = false; + bool enabled_avx = false; + (void)AVXEnabled; + (void)have_sse4; + (void)have_avx; + (void)have_xsave; + (void)have_avx2; + (void)have_shani; + (void)enabled_avx; + uint32_t eax, ebx, ecx, edx; cpuid(1, 0, eax, ebx, ecx, edx); - if ((ecx >> 19) & 1) { + have_sse4 = (ecx >> 19) & 1; + have_xsave = (ecx >> 27) & 1; + have_avx = (ecx >> 28) & 1; + if (have_xsave && have_avx) { + enabled_avx = AVXEnabled(); + } + if (have_sse4) { + cpuid(7, 0, eax, ebx, ecx, edx); + have_avx2 = (ebx >> 5) & 1; + have_shani = (ebx >> 29) & 1; + } + +#if defined(ENABLE_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) + if (have_shani) { + Transform = sha256_shani::Transform; + TransformD64 = TransformD64Wrapper; + TransformD64_2way = sha256d64_shani::Transform_2way; + ret = "shani(1way,2way)"; + have_sse4 = false; // Disable SSE4/AVX2; + have_avx2 = false; + } +#endif + + if (have_sse4) { #if defined(__x86_64__) || defined(__amd64__) Transform = sha256_sse4::Transform; TransformD64 = TransformD64Wrapper; + ret = "sse4(1way)"; #endif #if defined(ENABLE_SSE41) && !defined(BUILD_BITCOIN_INTERNAL) TransformD64_4way = sha256d64_sse41::Transform_4way; - ret = "sse4(1way+4way)"; -#if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL) - if (((ecx >> 27) & 1) && ((ecx >> 28) & 1)) { // XSAVE and AVX - cpuid(7, 0, eax, ebx, ecx, edx); - if ((ebx >> 5) & 1) { // AVX2 flag - if (AVXEnabled()) { // OS has enabled AVX registers - TransformD64_8way = sha256d64_avx2::Transform_8way; - ret += ",avx2(8way)"; - } - } - } -#endif -#else - ret = "sse4"; + ret += ",sse41(4way)"; #endif } + +#if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL) + if (have_avx2 && have_avx && enabled_avx) { + TransformD64_8way = sha256d64_avx2::Transform_8way; + ret += ",avx2(8way)"; + } +#endif #endif assert(SelfTest()); return ret; } ////// SHA-256 CSHA256::CSHA256() : bytes(0) { sha256::Initialize(s); } CSHA256 &CSHA256::Write(const uint8_t *data, size_t len) { const uint8_t *end = data + len; size_t bufsize = bytes % 64; if (bufsize && bufsize + len >= 64) { // Fill the buffer, and process it. memcpy(buf + bufsize, data, 64 - bufsize); bytes += 64 - bufsize; data += 64 - bufsize; Transform(s, buf, 1); bufsize = 0; } if (end - data >= 64) { size_t blocks = (end - data) / 64; Transform(s, data, blocks); data += 64 * blocks; bytes += 64 * blocks; } if (end > data) { // Fill the buffer with what remains. memcpy(buf + bufsize, data, end - data); bytes += end - data; } return *this; } void CSHA256::Finalize(uint8_t hash[OUTPUT_SIZE]) { static const uint8_t pad[64] = {0x80}; uint8_t sizedesc[8]; WriteBE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteBE32(hash, s[0]); WriteBE32(hash + 4, s[1]); WriteBE32(hash + 8, s[2]); WriteBE32(hash + 12, s[3]); WriteBE32(hash + 16, s[4]); WriteBE32(hash + 20, s[5]); WriteBE32(hash + 24, s[6]); WriteBE32(hash + 28, s[7]); } CSHA256 &CSHA256::Reset() { bytes = 0; sha256::Initialize(s); return *this; } void SHA256D64(uint8_t *out, const uint8_t *in, size_t blocks) { if (TransformD64_8way) { while (blocks >= 8) { TransformD64_8way(out, in); out += 256; in += 512; blocks -= 8; } } if (TransformD64_4way) { while (blocks >= 4) { TransformD64_4way(out, in); out += 128; in += 256; blocks -= 4; } } + if (TransformD64_2way) { + while (blocks >= 2) { + TransformD64_2way(out, in); + out += 64; + in += 128; + blocks -= 2; + } + } while (blocks) { TransformD64(out, in); out += 32; in += 64; --blocks; } } diff --git a/src/crypto/sha256_avx2.cpp b/src/crypto/sha256_avx2.cpp index 04c980ae2a..9a11ca56c5 100644 --- a/src/crypto/sha256_avx2.cpp +++ b/src/crypto/sha256_avx2.cpp @@ -1,458 +1,454 @@ #ifdef ENABLE_AVX2 -#include -#if defined(_MSC_VER) #include -#elif defined(__GNUC__) -#include -#endif +#include #include "crypto/common.h" #include "crypto/sha256.h" namespace sha256d64_avx2 { namespace { __m256i inline K(uint32_t x) { return _mm256_set1_epi32(x); } __m256i inline Add(__m256i x, __m256i y) { return _mm256_add_epi32(x, y); } __m256i inline Add(__m256i x, __m256i y, __m256i z) { return Add(Add(x, y), z); } __m256i inline Add(__m256i x, __m256i y, __m256i z, __m256i w) { return Add(Add(x, y), Add(z, w)); } __m256i inline Add(__m256i x, __m256i y, __m256i z, __m256i w, __m256i v) { return Add(Add(x, y, z), Add(w, v)); } __m256i inline Inc(__m256i &x, __m256i y) { x = Add(x, y); return x; } __m256i inline Inc(__m256i &x, __m256i y, __m256i z) { x = Add(x, y, z); return x; } __m256i inline Inc(__m256i &x, __m256i y, __m256i z, __m256i w) { x = Add(x, y, z, w); return x; } __m256i inline Xor(__m256i x, __m256i y) { return _mm256_xor_si256(x, y); } __m256i inline Xor(__m256i x, __m256i y, __m256i z) { return Xor(Xor(x, y), z); } __m256i inline Or(__m256i x, __m256i y) { return _mm256_or_si256(x, y); } __m256i inline And(__m256i x, __m256i y) { return _mm256_and_si256(x, y); } __m256i inline ShR(__m256i x, int n) { return _mm256_srli_epi32(x, n); } __m256i inline ShL(__m256i x, int n) { return _mm256_slli_epi32(x, n); } __m256i inline Ch(__m256i x, __m256i y, __m256i z) { return Xor(z, And(x, Xor(y, z))); } __m256i inline Maj(__m256i x, __m256i y, __m256i z) { return Or(And(x, y), And(z, Or(x, y))); } __m256i inline Sigma0(__m256i x) { return Xor(Or(ShR(x, 2), ShL(x, 30)), Or(ShR(x, 13), ShL(x, 19)), Or(ShR(x, 22), ShL(x, 10))); } __m256i inline Sigma1(__m256i x) { return Xor(Or(ShR(x, 6), ShL(x, 26)), Or(ShR(x, 11), ShL(x, 21)), Or(ShR(x, 25), ShL(x, 7))); } __m256i inline sigma0(__m256i x) { return Xor(Or(ShR(x, 7), ShL(x, 25)), Or(ShR(x, 18), ShL(x, 14)), ShR(x, 3)); } __m256i inline sigma1(__m256i x) { return Xor(Or(ShR(x, 17), ShL(x, 15)), Or(ShR(x, 19), ShL(x, 13)), ShR(x, 10)); } /** One round of SHA-256. */ - void inline __attribute__((always_inline)) + inline void __attribute__((always_inline)) Round(__m256i a, __m256i b, __m256i c, __m256i &d, __m256i e, __m256i f, __m256i g, __m256i &h, __m256i k) { __m256i t1 = Add(h, Sigma1(e), Ch(e, f, g), k); __m256i t2 = Add(Sigma0(a), Maj(a, b, c)); d = Add(d, t1); h = Add(t1, t2); } __m256i inline Read8(const uint8_t *chunk, int offset) { __m256i ret = _mm256_set_epi32( ReadLE32(chunk + 0 + offset), ReadLE32(chunk + 64 + offset), ReadLE32(chunk + 128 + offset), ReadLE32(chunk + 192 + offset), ReadLE32(chunk + 256 + offset), ReadLE32(chunk + 320 + offset), ReadLE32(chunk + 384 + offset), ReadLE32(chunk + 448 + offset)); return _mm256_shuffle_epi8( ret, _mm256_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL, 0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL)); } - void inline Write8(uint8_t *out, int offset, __m256i v) { + inline void Write8(uint8_t *out, int offset, __m256i v) { v = _mm256_shuffle_epi8( v, _mm256_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL, 0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL)); WriteLE32(out + 0 + offset, _mm256_extract_epi32(v, 7)); WriteLE32(out + 32 + offset, _mm256_extract_epi32(v, 6)); WriteLE32(out + 64 + offset, _mm256_extract_epi32(v, 5)); WriteLE32(out + 96 + offset, _mm256_extract_epi32(v, 4)); WriteLE32(out + 128 + offset, _mm256_extract_epi32(v, 3)); WriteLE32(out + 160 + offset, _mm256_extract_epi32(v, 2)); WriteLE32(out + 192 + offset, _mm256_extract_epi32(v, 1)); WriteLE32(out + 224 + offset, _mm256_extract_epi32(v, 0)); } } void Transform_8way(uint8_t *out, const uint8_t *in) { // Transform 1 __m256i a = K(0x6a09e667ul); __m256i b = K(0xbb67ae85ul); __m256i c = K(0x3c6ef372ul); __m256i d = K(0xa54ff53aul); __m256i e = K(0x510e527ful); __m256i f = K(0x9b05688cul); __m256i g = K(0x1f83d9abul); __m256i h = K(0x5be0cd19ul); __m256i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0 = Read8(in, 0))); Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1 = Read8(in, 4))); Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2 = Read8(in, 8))); Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3 = Read8(in, 12))); Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4 = Read8(in, 16))); Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5 = Read8(in, 20))); Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6 = Read8(in, 24))); Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7 = Read8(in, 28))); Round(a, b, c, d, e, f, g, h, Add(K(0xd807aa98ul), w8 = Read8(in, 32))); Round(h, a, b, c, d, e, f, g, Add(K(0x12835b01ul), w9 = Read8(in, 36))); Round(g, h, a, b, c, d, e, f, Add(K(0x243185beul), w10 = Read8(in, 40))); Round(f, g, h, a, b, c, d, e, Add(K(0x550c7dc3ul), w11 = Read8(in, 44))); Round(e, f, g, h, a, b, c, d, Add(K(0x72be5d74ul), w12 = Read8(in, 48))); Round(d, e, f, g, h, a, b, c, Add(K(0x80deb1feul), w13 = Read8(in, 52))); Round(c, d, e, f, g, h, a, b, Add(K(0x9bdc06a7ul), w14 = Read8(in, 56))); Round(b, c, d, e, f, g, h, a, Add(K(0xc19bf174ul), w15 = Read8(in, 60))); Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); a = Add(a, K(0x6a09e667ul)); b = Add(b, K(0xbb67ae85ul)); c = Add(c, K(0x3c6ef372ul)); d = Add(d, K(0xa54ff53aul)); e = Add(e, K(0x510e527ful)); f = Add(f, K(0x9b05688cul)); g = Add(g, K(0x1f83d9abul)); h = Add(h, K(0x5be0cd19ul)); __m256i t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h; // Transform 2 Round(a, b, c, d, e, f, g, h, K(0xc28a2f98ul)); Round(h, a, b, c, d, e, f, g, K(0x71374491ul)); Round(g, h, a, b, c, d, e, f, K(0xb5c0fbcful)); Round(f, g, h, a, b, c, d, e, K(0xe9b5dba5ul)); Round(e, f, g, h, a, b, c, d, K(0x3956c25bul)); Round(d, e, f, g, h, a, b, c, K(0x59f111f1ul)); Round(c, d, e, f, g, h, a, b, K(0x923f82a4ul)); Round(b, c, d, e, f, g, h, a, K(0xab1c5ed5ul)); Round(a, b, c, d, e, f, g, h, K(0xd807aa98ul)); Round(h, a, b, c, d, e, f, g, K(0x12835b01ul)); Round(g, h, a, b, c, d, e, f, K(0x243185beul)); Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul)); Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul)); Round(d, e, f, g, h, a, b, c, K(0x80deb1feul)); Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul)); Round(b, c, d, e, f, g, h, a, K(0xc19bf374ul)); Round(a, b, c, d, e, f, g, h, K(0x649b69c1ul)); Round(h, a, b, c, d, e, f, g, K(0xf0fe4786ul)); Round(g, h, a, b, c, d, e, f, K(0x0fe1edc6ul)); Round(f, g, h, a, b, c, d, e, K(0x240cf254ul)); Round(e, f, g, h, a, b, c, d, K(0x4fe9346ful)); Round(d, e, f, g, h, a, b, c, K(0x6cc984beul)); Round(c, d, e, f, g, h, a, b, K(0x61b9411eul)); Round(b, c, d, e, f, g, h, a, K(0x16f988faul)); Round(a, b, c, d, e, f, g, h, K(0xf2c65152ul)); Round(h, a, b, c, d, e, f, g, K(0xa88e5a6dul)); Round(g, h, a, b, c, d, e, f, K(0xb019fc65ul)); Round(f, g, h, a, b, c, d, e, K(0xb9d99ec7ul)); Round(e, f, g, h, a, b, c, d, K(0x9a1231c3ul)); Round(d, e, f, g, h, a, b, c, K(0xe70eeaa0ul)); Round(c, d, e, f, g, h, a, b, K(0xfdb1232bul)); Round(b, c, d, e, f, g, h, a, K(0xc7353eb0ul)); Round(a, b, c, d, e, f, g, h, K(0x3069bad5ul)); Round(h, a, b, c, d, e, f, g, K(0xcb976d5ful)); Round(g, h, a, b, c, d, e, f, K(0x5a0f118ful)); Round(f, g, h, a, b, c, d, e, K(0xdc1eeefdul)); Round(e, f, g, h, a, b, c, d, K(0x0a35b689ul)); Round(d, e, f, g, h, a, b, c, K(0xde0b7a04ul)); Round(c, d, e, f, g, h, a, b, K(0x58f4ca9dul)); Round(b, c, d, e, f, g, h, a, K(0xe15d5b16ul)); Round(a, b, c, d, e, f, g, h, K(0x007f3e86ul)); Round(h, a, b, c, d, e, f, g, K(0x37088980ul)); Round(g, h, a, b, c, d, e, f, K(0xa507ea32ul)); Round(f, g, h, a, b, c, d, e, K(0x6fab9537ul)); Round(e, f, g, h, a, b, c, d, K(0x17406110ul)); Round(d, e, f, g, h, a, b, c, K(0x0d8cd6f1ul)); Round(c, d, e, f, g, h, a, b, K(0xcdaa3b6dul)); Round(b, c, d, e, f, g, h, a, K(0xc0bbbe37ul)); Round(a, b, c, d, e, f, g, h, K(0x83613bdaul)); Round(h, a, b, c, d, e, f, g, K(0xdb48a363ul)); Round(g, h, a, b, c, d, e, f, K(0x0b02e931ul)); Round(f, g, h, a, b, c, d, e, K(0x6fd15ca7ul)); Round(e, f, g, h, a, b, c, d, K(0x521afacaul)); Round(d, e, f, g, h, a, b, c, K(0x31338431ul)); Round(c, d, e, f, g, h, a, b, K(0x6ed41a95ul)); Round(b, c, d, e, f, g, h, a, K(0x6d437890ul)); Round(a, b, c, d, e, f, g, h, K(0xc39c91f2ul)); Round(h, a, b, c, d, e, f, g, K(0x9eccabbdul)); Round(g, h, a, b, c, d, e, f, K(0xb5c9a0e6ul)); Round(f, g, h, a, b, c, d, e, K(0x532fb63cul)); Round(e, f, g, h, a, b, c, d, K(0xd2c741c6ul)); Round(d, e, f, g, h, a, b, c, K(0x07237ea3ul)); Round(c, d, e, f, g, h, a, b, K(0xa4954b68ul)); Round(b, c, d, e, f, g, h, a, K(0x4c191d76ul)); w0 = Add(t0, a); w1 = Add(t1, b); w2 = Add(t2, c); w3 = Add(t3, d); w4 = Add(t4, e); w5 = Add(t5, f); w6 = Add(t6, g); w7 = Add(t7, h); // Transform 3 a = K(0x6a09e667ul); b = K(0xbb67ae85ul); c = K(0x3c6ef372ul); d = K(0xa54ff53aul); e = K(0x510e527ful); f = K(0x9b05688cul); g = K(0x1f83d9abul); h = K(0x5be0cd19ul); Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0)); Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1)); Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2)); Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3)); Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4)); Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5)); Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6)); Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7)); Round(a, b, c, d, e, f, g, h, K(0x5807aa98ul)); Round(h, a, b, c, d, e, f, g, K(0x12835b01ul)); Round(g, h, a, b, c, d, e, f, K(0x243185beul)); Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul)); Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul)); Round(d, e, f, g, h, a, b, c, K(0x80deb1feul)); Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul)); Round(b, c, d, e, f, g, h, a, K(0xc19bf274ul)); Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, K(0xa00000ul), sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), K(0x100ul), sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, K(0x11002000ul)))); Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), w8 = Add(K(0x80000000ul), sigma1(w6), w1))); Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), w9 = Add(sigma1(w7), w2))); Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), w10 = Add(sigma1(w8), w3))); Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), w11 = Add(sigma1(w9), w4))); Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), w12 = Add(sigma1(w10), w5))); Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), w13 = Add(sigma1(w11), w6))); Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), w14 = Add(sigma1(w12), w7, K(0x400022ul)))); Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), w15 = Add(K(0x100ul), sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), w14, sigma1(w12), w7, sigma0(w15))); Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), w15, sigma1(w13), w8, sigma0(w0))); // Output Write8(out, 0, Add(a, K(0x6a09e667ul))); Write8(out, 4, Add(b, K(0xbb67ae85ul))); Write8(out, 8, Add(c, K(0x3c6ef372ul))); Write8(out, 12, Add(d, K(0xa54ff53aul))); Write8(out, 16, Add(e, K(0x510e527ful))); Write8(out, 20, Add(f, K(0x9b05688cul))); Write8(out, 24, Add(g, K(0x1f83d9abul))); Write8(out, 28, Add(h, K(0x5be0cd19ul))); } } #endif diff --git a/src/crypto/sha256_shani.cpp b/src/crypto/sha256_shani.cpp new file mode 100644 index 0000000000..d3a0b6563f --- /dev/null +++ b/src/crypto/sha256_shani.cpp @@ -0,0 +1,358 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// +// Based on https://github.com/noloader/SHA-Intrinsics/blob/master/sha256-x86.c, +// Written and placed in public domain by Jeffrey Walton. +// Based on code from Intel, and by Sean Gulley for the miTLS project. + +#ifdef ENABLE_SHANI + +#include +#include + +#include + +namespace { + +const __m128i MASK = + _mm_set_epi64x(0x0c0d0e0f08090a0bULL, 0x0405060700010203ULL); +const __m128i INIT0 = + _mm_set_epi64x(0x6a09e667bb67ae85ull, 0x510e527f9b05688cull); +const __m128i INIT1 = + _mm_set_epi64x(0x3c6ef372a54ff53aull, 0x1f83d9ab5be0cd19ull); + +inline void __attribute__((always_inline)) +QuadRound(__m128i &state0, __m128i &state1, uint64_t k1, uint64_t k0) { + const __m128i msg = _mm_set_epi64x(k1, k0); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + state0 = + _mm_sha256rnds2_epu32(state0, state1, _mm_shuffle_epi32(msg, 0x0e)); +} + +inline void __attribute__((always_inline)) +QuadRound(__m128i &state0, __m128i &state1, __m128i m, uint64_t k1, + uint64_t k0) { + const __m128i msg = _mm_add_epi32(m, _mm_set_epi64x(k1, k0)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + state0 = + _mm_sha256rnds2_epu32(state0, state1, _mm_shuffle_epi32(msg, 0x0e)); +} + +inline void __attribute__((always_inline)) +ShiftMessageA(__m128i &m0, __m128i m1) { + m0 = _mm_sha256msg1_epu32(m0, m1); +} + +inline void __attribute__((always_inline)) +ShiftMessageC(__m128i &m0, __m128i m1, __m128i &m2) { + m2 = + _mm_sha256msg2_epu32(_mm_add_epi32(m2, _mm_alignr_epi8(m1, m0, 4)), m1); +} + +inline void __attribute__((always_inline)) +ShiftMessageB(__m128i &m0, __m128i m1, __m128i &m2) { + ShiftMessageC(m0, m1, m2); + ShiftMessageA(m0, m1); +} + +inline void __attribute__((always_inline)) Shuffle(__m128i &s0, __m128i &s1) { + const __m128i t1 = _mm_shuffle_epi32(s0, 0xB1); + const __m128i t2 = _mm_shuffle_epi32(s1, 0x1B); + s0 = _mm_alignr_epi8(t1, t2, 0x08); + s1 = _mm_blend_epi16(t2, t1, 0xF0); +} + +inline void __attribute__((always_inline)) Unshuffle(__m128i &s0, __m128i &s1) { + const __m128i t1 = _mm_shuffle_epi32(s0, 0x1B); + const __m128i t2 = _mm_shuffle_epi32(s1, 0xB1); + s0 = _mm_blend_epi16(t1, t2, 0xF0); + s1 = _mm_alignr_epi8(t2, t1, 0x08); +} + +__m128i inline __attribute__((always_inline)) Load(const unsigned char *in) { + return _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *)in), MASK); +} + +inline void __attribute__((always_inline)) Save(unsigned char *out, __m128i s) { + _mm_storeu_si128((__m128i *)out, _mm_shuffle_epi8(s, MASK)); +} +} + +namespace sha256_shani { +void Transform(uint32_t *s, const unsigned char *chunk, size_t blocks) { + __m128i m0, m1, m2, m3, s0, s1, so0, so1; + + /* Load state */ + s0 = _mm_loadu_si128((const __m128i *)s); + s1 = _mm_loadu_si128((const __m128i *)(s + 4)); + Shuffle(s0, s1); + + while (blocks--) { + /* Remember old state */ + so0 = s0; + so1 = s1; + + /* Load data and transform */ + m0 = Load(chunk); + QuadRound(s0, s1, m0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull); + m1 = Load(chunk + 16); + QuadRound(s0, s1, m1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull); + ShiftMessageA(m0, m1); + m2 = Load(chunk + 32); + QuadRound(s0, s1, m2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull); + ShiftMessageA(m1, m2); + m3 = Load(chunk + 48); + QuadRound(s0, s1, m3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull); + ShiftMessageB(m2, m3, m0); + QuadRound(s0, s1, m0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull); + ShiftMessageB(m3, m0, m1); + QuadRound(s0, s1, m1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full); + ShiftMessageB(m0, m1, m2); + QuadRound(s0, s1, m2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull); + ShiftMessageB(m1, m2, m3); + QuadRound(s0, s1, m3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull); + ShiftMessageB(m2, m3, m0); + QuadRound(s0, s1, m0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull); + ShiftMessageB(m3, m0, m1); + QuadRound(s0, s1, m1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull); + ShiftMessageB(m0, m1, m2); + QuadRound(s0, s1, m2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull); + ShiftMessageB(m1, m2, m3); + QuadRound(s0, s1, m3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull); + ShiftMessageB(m2, m3, m0); + QuadRound(s0, s1, m0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull); + ShiftMessageB(m3, m0, m1); + QuadRound(s0, s1, m1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull); + ShiftMessageC(m0, m1, m2); + QuadRound(s0, s1, m2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull); + ShiftMessageC(m1, m2, m3); + QuadRound(s0, s1, m3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull); + + /* Combine with old state */ + s0 = _mm_add_epi32(s0, so0); + s1 = _mm_add_epi32(s1, so1); + + /* Advance */ + chunk += 64; + } + + Unshuffle(s0, s1); + _mm_storeu_si128((__m128i *)s, s0); + _mm_storeu_si128((__m128i *)(s + 4), s1); +} +} + +namespace sha256d64_shani { + +void Transform_2way(unsigned char *out, const unsigned char *in) { + __m128i am0, am1, am2, am3, as0, as1, aso0, aso1; + __m128i bm0, bm1, bm2, bm3, bs0, bs1, bso0, bso1; + + /* Transform 1 */ + bs0 = as0 = INIT0; + bs1 = as1 = INIT1; + am0 = Load(in); + bm0 = Load(in + 64); + QuadRound(as0, as1, am0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull); + QuadRound(bs0, bs1, bm0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull); + am1 = Load(in + 16); + bm1 = Load(in + 80); + QuadRound(as0, as1, am1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull); + QuadRound(bs0, bs1, bm1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull); + ShiftMessageA(am0, am1); + ShiftMessageA(bm0, bm1); + am2 = Load(in + 32); + bm2 = Load(in + 96); + QuadRound(as0, as1, am2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull); + QuadRound(bs0, bs1, bm2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull); + ShiftMessageA(am1, am2); + ShiftMessageA(bm1, bm2); + am3 = Load(in + 48); + bm3 = Load(in + 112); + QuadRound(as0, as1, am3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull); + QuadRound(bs0, bs1, bm3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull); + ShiftMessageB(am2, am3, am0); + ShiftMessageB(bm2, bm3, bm0); + QuadRound(as0, as1, am0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull); + QuadRound(bs0, bs1, bm0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull); + ShiftMessageB(am3, am0, am1); + ShiftMessageB(bm3, bm0, bm1); + QuadRound(as0, as1, am1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full); + QuadRound(bs0, bs1, bm1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full); + ShiftMessageB(am0, am1, am2); + ShiftMessageB(bm0, bm1, bm2); + QuadRound(as0, as1, am2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull); + QuadRound(bs0, bs1, bm2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull); + ShiftMessageB(am1, am2, am3); + ShiftMessageB(bm1, bm2, bm3); + QuadRound(as0, as1, am3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull); + QuadRound(bs0, bs1, bm3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull); + ShiftMessageB(am2, am3, am0); + ShiftMessageB(bm2, bm3, bm0); + QuadRound(as0, as1, am0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull); + QuadRound(bs0, bs1, bm0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull); + ShiftMessageB(am3, am0, am1); + ShiftMessageB(bm3, bm0, bm1); + QuadRound(as0, as1, am1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull); + QuadRound(bs0, bs1, bm1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull); + ShiftMessageB(am0, am1, am2); + ShiftMessageB(bm0, bm1, bm2); + QuadRound(as0, as1, am2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull); + QuadRound(bs0, bs1, bm2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull); + ShiftMessageB(am1, am2, am3); + ShiftMessageB(bm1, bm2, bm3); + QuadRound(as0, as1, am3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull); + QuadRound(bs0, bs1, bm3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull); + ShiftMessageB(am2, am3, am0); + ShiftMessageB(bm2, bm3, bm0); + QuadRound(as0, as1, am0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull); + QuadRound(bs0, bs1, bm0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull); + ShiftMessageB(am3, am0, am1); + ShiftMessageB(bm3, bm0, bm1); + QuadRound(as0, as1, am1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull); + QuadRound(bs0, bs1, bm1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull); + ShiftMessageC(am0, am1, am2); + ShiftMessageC(bm0, bm1, bm2); + QuadRound(as0, as1, am2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull); + QuadRound(bs0, bs1, bm2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull); + ShiftMessageC(am1, am2, am3); + ShiftMessageC(bm1, bm2, bm3); + QuadRound(as0, as1, am3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull); + QuadRound(bs0, bs1, bm3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull); + as0 = _mm_add_epi32(as0, INIT0); + bs0 = _mm_add_epi32(bs0, INIT0); + as1 = _mm_add_epi32(as1, INIT1); + bs1 = _mm_add_epi32(bs1, INIT1); + + /* Transform 2 */ + aso0 = as0; + bso0 = bs0; + aso1 = as1; + bso1 = bs1; + QuadRound(as0, as1, 0xe9b5dba5b5c0fbcfull, 0x71374491c28a2f98ull); + QuadRound(bs0, bs1, 0xe9b5dba5b5c0fbcfull, 0x71374491c28a2f98ull); + QuadRound(as0, as1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull); + QuadRound(bs0, bs1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull); + QuadRound(as0, as1, 0x550c7dc3243185beull, 0x12835b01d807aa98ull); + QuadRound(bs0, bs1, 0x550c7dc3243185beull, 0x12835b01d807aa98ull); + QuadRound(as0, as1, 0xc19bf3749bdc06a7ull, 0x80deb1fe72be5d74ull); + QuadRound(bs0, bs1, 0xc19bf3749bdc06a7ull, 0x80deb1fe72be5d74ull); + QuadRound(as0, as1, 0x240cf2540fe1edc6ull, 0xf0fe4786649b69c1ull); + QuadRound(bs0, bs1, 0x240cf2540fe1edc6ull, 0xf0fe4786649b69c1ull); + QuadRound(as0, as1, 0x16f988fa61b9411eull, 0x6cc984be4fe9346full); + QuadRound(bs0, bs1, 0x16f988fa61b9411eull, 0x6cc984be4fe9346full); + QuadRound(as0, as1, 0xb9d99ec7b019fc65ull, 0xa88e5a6df2c65152ull); + QuadRound(bs0, bs1, 0xb9d99ec7b019fc65ull, 0xa88e5a6df2c65152ull); + QuadRound(as0, as1, 0xc7353eb0fdb1232bull, 0xe70eeaa09a1231c3ull); + QuadRound(bs0, bs1, 0xc7353eb0fdb1232bull, 0xe70eeaa09a1231c3ull); + QuadRound(as0, as1, 0xdc1eeefd5a0f118full, 0xcb976d5f3069bad5ull); + QuadRound(bs0, bs1, 0xdc1eeefd5a0f118full, 0xcb976d5f3069bad5ull); + QuadRound(as0, as1, 0xe15d5b1658f4ca9dull, 0xde0b7a040a35b689ull); + QuadRound(bs0, bs1, 0xe15d5b1658f4ca9dull, 0xde0b7a040a35b689ull); + QuadRound(as0, as1, 0x6fab9537a507ea32ull, 0x37088980007f3e86ull); + QuadRound(bs0, bs1, 0x6fab9537a507ea32ull, 0x37088980007f3e86ull); + QuadRound(as0, as1, 0xc0bbbe37cdaa3b6dull, 0x0d8cd6f117406110ull); + QuadRound(bs0, bs1, 0xc0bbbe37cdaa3b6dull, 0x0d8cd6f117406110ull); + QuadRound(as0, as1, 0x6fd15ca70b02e931ull, 0xdb48a36383613bdaull); + QuadRound(bs0, bs1, 0x6fd15ca70b02e931ull, 0xdb48a36383613bdaull); + QuadRound(as0, as1, 0x6d4378906ed41a95ull, 0x31338431521afacaull); + QuadRound(bs0, bs1, 0x6d4378906ed41a95ull, 0x31338431521afacaull); + QuadRound(as0, as1, 0x532fb63cb5c9a0e6ull, 0x9eccabbdc39c91f2ull); + QuadRound(bs0, bs1, 0x532fb63cb5c9a0e6ull, 0x9eccabbdc39c91f2ull); + QuadRound(as0, as1, 0x4c191d76a4954b68ull, 0x07237ea3d2c741c6ull); + QuadRound(bs0, bs1, 0x4c191d76a4954b68ull, 0x07237ea3d2c741c6ull); + as0 = _mm_add_epi32(as0, aso0); + bs0 = _mm_add_epi32(bs0, bso0); + as1 = _mm_add_epi32(as1, aso1); + bs1 = _mm_add_epi32(bs1, bso1); + + /* Extract hash */ + Unshuffle(as0, as1); + Unshuffle(bs0, bs1); + am0 = as0; + bm0 = bs0; + am1 = as1; + bm1 = bs1; + + /* Transform 3 */ + bs0 = as0 = INIT0; + bs1 = as1 = INIT1; + QuadRound(as0, as1, am0, 0xe9b5dba5B5c0fbcfull, 0x71374491428a2f98ull); + QuadRound(bs0, bs1, bm0, 0xe9b5dba5B5c0fbcfull, 0x71374491428a2f98ull); + QuadRound(as0, as1, am1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull); + QuadRound(bs0, bs1, bm1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull); + ShiftMessageA(am0, am1); + ShiftMessageA(bm0, bm1); + bm2 = am2 = _mm_set_epi64x(0x0ull, 0x80000000ull); + QuadRound(as0, as1, 0x550c7dc3243185beull, 0x12835b015807aa98ull); + QuadRound(bs0, bs1, 0x550c7dc3243185beull, 0x12835b015807aa98ull); + ShiftMessageA(am1, am2); + ShiftMessageA(bm1, bm2); + bm3 = am3 = _mm_set_epi64x(0x10000000000ull, 0x0ull); + QuadRound(as0, as1, 0xc19bf2749bdc06a7ull, 0x80deb1fe72be5d74ull); + QuadRound(bs0, bs1, 0xc19bf2749bdc06a7ull, 0x80deb1fe72be5d74ull); + ShiftMessageB(am2, am3, am0); + ShiftMessageB(bm2, bm3, bm0); + QuadRound(as0, as1, am0, 0x240ca1cc0fc19dc6ull, 0xefbe4786e49b69c1ull); + QuadRound(bs0, bs1, bm0, 0x240ca1cc0fc19dc6ull, 0xefbe4786e49b69c1ull); + ShiftMessageB(am3, am0, am1); + ShiftMessageB(bm3, bm0, bm1); + QuadRound(as0, as1, am1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full); + QuadRound(bs0, bs1, bm1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full); + ShiftMessageB(am0, am1, am2); + ShiftMessageB(bm0, bm1, bm2); + QuadRound(as0, as1, am2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull); + QuadRound(bs0, bs1, bm2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull); + ShiftMessageB(am1, am2, am3); + ShiftMessageB(bm1, bm2, bm3); + QuadRound(as0, as1, am3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull); + QuadRound(bs0, bs1, bm3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull); + ShiftMessageB(am2, am3, am0); + ShiftMessageB(bm2, bm3, bm0); + QuadRound(as0, as1, am0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull); + QuadRound(bs0, bs1, bm0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull); + ShiftMessageB(am3, am0, am1); + ShiftMessageB(bm3, bm0, bm1); + QuadRound(as0, as1, am1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull); + QuadRound(bs0, bs1, bm1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull); + ShiftMessageB(am0, am1, am2); + ShiftMessageB(bm0, bm1, bm2); + QuadRound(as0, as1, am2, 0xc76c51a3c24b8b70ull, 0xa81a664ba2bfe8A1ull); + QuadRound(bs0, bs1, bm2, 0xc76c51a3c24b8b70ull, 0xa81a664ba2bfe8A1ull); + ShiftMessageB(am1, am2, am3); + ShiftMessageB(bm1, bm2, bm3); + QuadRound(as0, as1, am3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull); + QuadRound(bs0, bs1, bm3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull); + ShiftMessageB(am2, am3, am0); + ShiftMessageB(bm2, bm3, bm0); + QuadRound(as0, as1, am0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull); + QuadRound(bs0, bs1, bm0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull); + ShiftMessageB(am3, am0, am1); + ShiftMessageB(bm3, bm0, bm1); + QuadRound(as0, as1, am1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull); + QuadRound(bs0, bs1, bm1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull); + ShiftMessageC(am0, am1, am2); + ShiftMessageC(bm0, bm1, bm2); + QuadRound(as0, as1, am2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull); + QuadRound(bs0, bs1, bm2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull); + ShiftMessageC(am1, am2, am3); + ShiftMessageC(bm1, bm2, bm3); + QuadRound(as0, as1, am3, 0xc67178f2bef9a3f7ull, 0xa4506ceb90befffaull); + QuadRound(bs0, bs1, bm3, 0xc67178f2bef9a3f7ull, 0xa4506ceb90befffaull); + as0 = _mm_add_epi32(as0, INIT0); + bs0 = _mm_add_epi32(bs0, INIT0); + as1 = _mm_add_epi32(as1, INIT1); + bs1 = _mm_add_epi32(bs1, INIT1); + + /* Extract hash into out */ + Unshuffle(as0, as1); + Unshuffle(bs0, bs1); + Save(out, as0); + Save(out + 16, as1); + Save(out + 32, bs0); + Save(out + 48, bs1); +} +} + +#endif diff --git a/src/crypto/sha256_sse41.cpp b/src/crypto/sha256_sse41.cpp index 86bacc3493..6105094231 100644 --- a/src/crypto/sha256_sse41.cpp +++ b/src/crypto/sha256_sse41.cpp @@ -1,448 +1,444 @@ #ifdef ENABLE_SSE41 -#include -#if defined(_MSC_VER) #include -#elif defined(__GNUC__) -#include -#endif +#include #include "crypto/common.h" #include "crypto/sha256.h" namespace sha256d64_sse41 { namespace { __m128i inline K(uint32_t x) { return _mm_set1_epi32(x); } __m128i inline Add(__m128i x, __m128i y) { return _mm_add_epi32(x, y); } __m128i inline Add(__m128i x, __m128i y, __m128i z) { return Add(Add(x, y), z); } __m128i inline Add(__m128i x, __m128i y, __m128i z, __m128i w) { return Add(Add(x, y), Add(z, w)); } __m128i inline Add(__m128i x, __m128i y, __m128i z, __m128i w, __m128i v) { return Add(Add(x, y, z), Add(w, v)); } __m128i inline Inc(__m128i &x, __m128i y) { x = Add(x, y); return x; } __m128i inline Inc(__m128i &x, __m128i y, __m128i z) { x = Add(x, y, z); return x; } __m128i inline Inc(__m128i &x, __m128i y, __m128i z, __m128i w) { x = Add(x, y, z, w); return x; } __m128i inline Xor(__m128i x, __m128i y) { return _mm_xor_si128(x, y); } __m128i inline Xor(__m128i x, __m128i y, __m128i z) { return Xor(Xor(x, y), z); } __m128i inline Or(__m128i x, __m128i y) { return _mm_or_si128(x, y); } __m128i inline And(__m128i x, __m128i y) { return _mm_and_si128(x, y); } __m128i inline ShR(__m128i x, int n) { return _mm_srli_epi32(x, n); } __m128i inline ShL(__m128i x, int n) { return _mm_slli_epi32(x, n); } __m128i inline Ch(__m128i x, __m128i y, __m128i z) { return Xor(z, And(x, Xor(y, z))); } __m128i inline Maj(__m128i x, __m128i y, __m128i z) { return Or(And(x, y), And(z, Or(x, y))); } __m128i inline Sigma0(__m128i x) { return Xor(Or(ShR(x, 2), ShL(x, 30)), Or(ShR(x, 13), ShL(x, 19)), Or(ShR(x, 22), ShL(x, 10))); } __m128i inline Sigma1(__m128i x) { return Xor(Or(ShR(x, 6), ShL(x, 26)), Or(ShR(x, 11), ShL(x, 21)), Or(ShR(x, 25), ShL(x, 7))); } __m128i inline sigma0(__m128i x) { return Xor(Or(ShR(x, 7), ShL(x, 25)), Or(ShR(x, 18), ShL(x, 14)), ShR(x, 3)); } __m128i inline sigma1(__m128i x) { return Xor(Or(ShR(x, 17), ShL(x, 15)), Or(ShR(x, 19), ShL(x, 13)), ShR(x, 10)); } /** One round of SHA-256. */ - void inline __attribute__((always_inline)) + inline void __attribute__((always_inline)) Round(__m128i a, __m128i b, __m128i c, __m128i &d, __m128i e, __m128i f, __m128i g, __m128i &h, __m128i k) { __m128i t1 = Add(h, Sigma1(e), Ch(e, f, g), k); __m128i t2 = Add(Sigma0(a), Maj(a, b, c)); d = Add(d, t1); h = Add(t1, t2); } __m128i inline Read4(const uint8_t *chunk, int offset) { __m128i ret = _mm_set_epi32( ReadLE32(chunk + 0 + offset), ReadLE32(chunk + 64 + offset), ReadLE32(chunk + 128 + offset), ReadLE32(chunk + 192 + offset)); return _mm_shuffle_epi8(ret, _mm_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL)); } - void inline Write4(uint8_t *out, int offset, __m128i v) { + inline void Write4(uint8_t *out, int offset, __m128i v) { v = _mm_shuffle_epi8(v, _mm_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL)); WriteLE32(out + 0 + offset, _mm_extract_epi32(v, 3)); WriteLE32(out + 32 + offset, _mm_extract_epi32(v, 2)); WriteLE32(out + 64 + offset, _mm_extract_epi32(v, 1)); WriteLE32(out + 96 + offset, _mm_extract_epi32(v, 0)); } } void Transform_4way(uint8_t *out, const uint8_t *in) { // Transform 1 __m128i a = K(0x6a09e667ul); __m128i b = K(0xbb67ae85ul); __m128i c = K(0x3c6ef372ul); __m128i d = K(0xa54ff53aul); __m128i e = K(0x510e527ful); __m128i f = K(0x9b05688cul); __m128i g = K(0x1f83d9abul); __m128i h = K(0x5be0cd19ul); __m128i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0 = Read4(in, 0))); Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1 = Read4(in, 4))); Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2 = Read4(in, 8))); Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3 = Read4(in, 12))); Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4 = Read4(in, 16))); Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5 = Read4(in, 20))); Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6 = Read4(in, 24))); Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7 = Read4(in, 28))); Round(a, b, c, d, e, f, g, h, Add(K(0xd807aa98ul), w8 = Read4(in, 32))); Round(h, a, b, c, d, e, f, g, Add(K(0x12835b01ul), w9 = Read4(in, 36))); Round(g, h, a, b, c, d, e, f, Add(K(0x243185beul), w10 = Read4(in, 40))); Round(f, g, h, a, b, c, d, e, Add(K(0x550c7dc3ul), w11 = Read4(in, 44))); Round(e, f, g, h, a, b, c, d, Add(K(0x72be5d74ul), w12 = Read4(in, 48))); Round(d, e, f, g, h, a, b, c, Add(K(0x80deb1feul), w13 = Read4(in, 52))); Round(c, d, e, f, g, h, a, b, Add(K(0x9bdc06a7ul), w14 = Read4(in, 56))); Round(b, c, d, e, f, g, h, a, Add(K(0xc19bf174ul), w15 = Read4(in, 60))); Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); a = Add(a, K(0x6a09e667ul)); b = Add(b, K(0xbb67ae85ul)); c = Add(c, K(0x3c6ef372ul)); d = Add(d, K(0xa54ff53aul)); e = Add(e, K(0x510e527ful)); f = Add(f, K(0x9b05688cul)); g = Add(g, K(0x1f83d9abul)); h = Add(h, K(0x5be0cd19ul)); __m128i t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h; // Transform 2 Round(a, b, c, d, e, f, g, h, K(0xc28a2f98ul)); Round(h, a, b, c, d, e, f, g, K(0x71374491ul)); Round(g, h, a, b, c, d, e, f, K(0xb5c0fbcful)); Round(f, g, h, a, b, c, d, e, K(0xe9b5dba5ul)); Round(e, f, g, h, a, b, c, d, K(0x3956c25bul)); Round(d, e, f, g, h, a, b, c, K(0x59f111f1ul)); Round(c, d, e, f, g, h, a, b, K(0x923f82a4ul)); Round(b, c, d, e, f, g, h, a, K(0xab1c5ed5ul)); Round(a, b, c, d, e, f, g, h, K(0xd807aa98ul)); Round(h, a, b, c, d, e, f, g, K(0x12835b01ul)); Round(g, h, a, b, c, d, e, f, K(0x243185beul)); Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul)); Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul)); Round(d, e, f, g, h, a, b, c, K(0x80deb1feul)); Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul)); Round(b, c, d, e, f, g, h, a, K(0xc19bf374ul)); Round(a, b, c, d, e, f, g, h, K(0x649b69c1ul)); Round(h, a, b, c, d, e, f, g, K(0xf0fe4786ul)); Round(g, h, a, b, c, d, e, f, K(0x0fe1edc6ul)); Round(f, g, h, a, b, c, d, e, K(0x240cf254ul)); Round(e, f, g, h, a, b, c, d, K(0x4fe9346ful)); Round(d, e, f, g, h, a, b, c, K(0x6cc984beul)); Round(c, d, e, f, g, h, a, b, K(0x61b9411eul)); Round(b, c, d, e, f, g, h, a, K(0x16f988faul)); Round(a, b, c, d, e, f, g, h, K(0xf2c65152ul)); Round(h, a, b, c, d, e, f, g, K(0xa88e5a6dul)); Round(g, h, a, b, c, d, e, f, K(0xb019fc65ul)); Round(f, g, h, a, b, c, d, e, K(0xb9d99ec7ul)); Round(e, f, g, h, a, b, c, d, K(0x9a1231c3ul)); Round(d, e, f, g, h, a, b, c, K(0xe70eeaa0ul)); Round(c, d, e, f, g, h, a, b, K(0xfdb1232bul)); Round(b, c, d, e, f, g, h, a, K(0xc7353eb0ul)); Round(a, b, c, d, e, f, g, h, K(0x3069bad5ul)); Round(h, a, b, c, d, e, f, g, K(0xcb976d5ful)); Round(g, h, a, b, c, d, e, f, K(0x5a0f118ful)); Round(f, g, h, a, b, c, d, e, K(0xdc1eeefdul)); Round(e, f, g, h, a, b, c, d, K(0x0a35b689ul)); Round(d, e, f, g, h, a, b, c, K(0xde0b7a04ul)); Round(c, d, e, f, g, h, a, b, K(0x58f4ca9dul)); Round(b, c, d, e, f, g, h, a, K(0xe15d5b16ul)); Round(a, b, c, d, e, f, g, h, K(0x007f3e86ul)); Round(h, a, b, c, d, e, f, g, K(0x37088980ul)); Round(g, h, a, b, c, d, e, f, K(0xa507ea32ul)); Round(f, g, h, a, b, c, d, e, K(0x6fab9537ul)); Round(e, f, g, h, a, b, c, d, K(0x17406110ul)); Round(d, e, f, g, h, a, b, c, K(0x0d8cd6f1ul)); Round(c, d, e, f, g, h, a, b, K(0xcdaa3b6dul)); Round(b, c, d, e, f, g, h, a, K(0xc0bbbe37ul)); Round(a, b, c, d, e, f, g, h, K(0x83613bdaul)); Round(h, a, b, c, d, e, f, g, K(0xdb48a363ul)); Round(g, h, a, b, c, d, e, f, K(0x0b02e931ul)); Round(f, g, h, a, b, c, d, e, K(0x6fd15ca7ul)); Round(e, f, g, h, a, b, c, d, K(0x521afacaul)); Round(d, e, f, g, h, a, b, c, K(0x31338431ul)); Round(c, d, e, f, g, h, a, b, K(0x6ed41a95ul)); Round(b, c, d, e, f, g, h, a, K(0x6d437890ul)); Round(a, b, c, d, e, f, g, h, K(0xc39c91f2ul)); Round(h, a, b, c, d, e, f, g, K(0x9eccabbdul)); Round(g, h, a, b, c, d, e, f, K(0xb5c9a0e6ul)); Round(f, g, h, a, b, c, d, e, K(0x532fb63cul)); Round(e, f, g, h, a, b, c, d, K(0xd2c741c6ul)); Round(d, e, f, g, h, a, b, c, K(0x07237ea3ul)); Round(c, d, e, f, g, h, a, b, K(0xa4954b68ul)); Round(b, c, d, e, f, g, h, a, K(0x4c191d76ul)); w0 = Add(t0, a); w1 = Add(t1, b); w2 = Add(t2, c); w3 = Add(t3, d); w4 = Add(t4, e); w5 = Add(t5, f); w6 = Add(t6, g); w7 = Add(t7, h); // Transform 3 a = K(0x6a09e667ul); b = K(0xbb67ae85ul); c = K(0x3c6ef372ul); d = K(0xa54ff53aul); e = K(0x510e527ful); f = K(0x9b05688cul); g = K(0x1f83d9abul); h = K(0x5be0cd19ul); Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0)); Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1)); Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2)); Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3)); Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4)); Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5)); Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6)); Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7)); Round(a, b, c, d, e, f, g, h, K(0x5807aa98ul)); Round(h, a, b, c, d, e, f, g, K(0x12835b01ul)); Round(g, h, a, b, c, d, e, f, K(0x243185beul)); Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul)); Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul)); Round(d, e, f, g, h, a, b, c, K(0x80deb1feul)); Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul)); Round(b, c, d, e, f, g, h, a, K(0xc19bf274ul)); Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, K(0xa00000ul), sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), K(0x100ul), sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, K(0x11002000ul)))); Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), w8 = Add(K(0x80000000ul), sigma1(w6), w1))); Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), w9 = Add(sigma1(w7), w2))); Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), w10 = Add(sigma1(w8), w3))); Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), w11 = Add(sigma1(w9), w4))); Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), w12 = Add(sigma1(w10), w5))); Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), w13 = Add(sigma1(w11), w6))); Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), w14 = Add(sigma1(w12), w7, K(0x400022ul)))); Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), w15 = Add(K(0x100ul), sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15)))); Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0)))); Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1)))); Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2)))); Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3)))); Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4)))); Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5)))); Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6)))); Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7)))); Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8)))); Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9)))); Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10)))); Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11)))); Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12)))); Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13)))); Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14)))); Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), w14, sigma1(w12), w7, sigma0(w15))); Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), w15, sigma1(w13), w8, sigma0(w0))); // Output Write4(out, 0, Add(a, K(0x6a09e667ul))); Write4(out, 4, Add(b, K(0xbb67ae85ul))); Write4(out, 8, Add(c, K(0x3c6ef372ul))); Write4(out, 12, Add(d, K(0xa54ff53aul))); Write4(out, 16, Add(e, K(0x510e527ful))); Write4(out, 20, Add(f, K(0x9b05688cul))); Write4(out, 24, Add(g, K(0x1f83d9abul))); Write4(out, 28, Add(h, K(0x5be0cd19ul))); } } #endif