aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--configure.ac44
-rw-r--r--contrib/init/README.md2
-rw-r--r--depends/README.md6
-rw-r--r--depends/description.md2
-rw-r--r--doc/README.md4
-rw-r--r--doc/README_osx.md10
-rw-r--r--doc/build-freebsd.md46
-rw-r--r--doc/build-osx.md6
-rw-r--r--doc/build-unix.md33
-rw-r--r--doc/developer-notes.md30
-rw-r--r--doc/init.md6
-rw-r--r--doc/release-process.md22
-rw-r--r--src/Makefile.am28
-rw-r--r--src/Makefile.bench.include3
-rw-r--r--src/Makefile.qt.include2
-rw-r--r--src/Makefile.qttest.include2
-rw-r--r--src/Makefile.test.include5
-rw-r--r--src/bench/bench_bitcoin.cpp14
-rw-r--r--src/bench/crypto_hash.cpp9
-rw-r--r--src/bench/merkle_root.cpp26
-rw-r--r--src/bitcoin-cli.cpp13
-rw-r--r--src/bitcoin-tx.cpp4
-rw-r--r--src/consensus/merkle.cpp133
-rw-r--r--src/consensus/merkle.h11
-rw-r--r--src/crypto/sha256.cpp498
-rw-r--r--src/crypto/sha256.h7
-rw-r--r--src/crypto/sha256_avx2.cpp329
-rw-r--r--src/crypto/sha256_sse41.cpp321
-rw-r--r--src/qt/README.md8
-rw-r--r--src/rpc/blockchain.cpp20
-rw-r--r--src/rpc/blockchain.h3
-rw-r--r--src/rpc/mining.cpp2
-rw-r--r--src/rpc/rawtransaction.cpp4
-rw-r--r--src/script/sign.cpp8
-rw-r--r--src/script/sign.h1
-rw-r--r--src/script/standard.cpp1
-rw-r--r--src/test/blockchain_tests.cpp54
-rw-r--r--src/test/crypto_tests.cpp16
-rw-r--r--src/test/merkle_tests.cpp117
-rw-r--r--src/test/script_standard_tests.cpp26
-rw-r--r--src/test/transaction_tests.cpp8
-rw-r--r--src/test/txvalidationcache_tests.cpp4
-rw-r--r--src/util.cpp20
-rw-r--r--src/wallet/wallet.cpp6
-rwxr-xr-xtest/functional/feature_includeconf.py19
-rwxr-xr-xtest/lint/lint-includes.sh76
-rwxr-xr-xtest/lint/lint-locale-dependence.sh229
48 files changed, 1860 insertions, 380 deletions
diff --git a/README.md b/README.md
index acdbe46104..4e830109c2 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ There are also [regression and integration tests](/test), written
in Python, that are run automatically on the build server.
These tests can be run (if the [test dependencies](/test) are installed) with: `test/functional/test_runner.py`
-The Travis CI system makes sure that every pull request is built for Windows, Linux, and OS X, and that unit/sanity tests are run automatically.
+The Travis CI system makes sure that every pull request is built for Windows, Linux, and macOS, and that unit/sanity tests are run automatically.
### Manual Quality Assurance (QA) Testing
diff --git a/configure.ac b/configure.ac
index 1ffef1527b..af60b28c71 100644
--- a/configure.ac
+++ b/configure.ac
@@ -312,6 +312,8 @@ fi
# 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]])
TEMP_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS"
@@ -335,6 +337,44 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
)
CXXFLAGS="$TEMP_CXXFLAGS"
+TEMP_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS $SSE41_CXXFLAGS"
+AC_MSG_CHECKING(for SSE4.1 intrinsics)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <stdint.h>
+ #if defined(_MSC_VER)
+ #include <immintrin.h>
+ #elif defined(__GNUC__)
+ #include <x86intrin.h>
+ #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 <stdint.h>
+ #if defined(_MSC_VER)
+ #include <immintrin.h>
+ #elif defined(__GNUC__) && defined(__AVX2__)
+ #include <x86intrin.h>
+ #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"
+
CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
AC_ARG_WITH([utils],
@@ -1253,6 +1293,8 @@ 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([USE_ASM],[test x$use_asm = xyes])
AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version])
@@ -1295,6 +1337,8 @@ AC_SUBST(PIE_FLAGS)
AC_SUBST(SANITIZER_CXXFLAGS)
AC_SUBST(SANITIZER_LDFLAGS)
AC_SUBST(SSE42_CXXFLAGS)
+AC_SUBST(SSE41_CXXFLAGS)
+AC_SUBST(AVX2_CXXFLAGS)
AC_SUBST(LIBTOOL_APP_LDFLAGS)
AC_SUBST(USE_UPNP)
AC_SUBST(USE_QRCODE)
diff --git a/contrib/init/README.md b/contrib/init/README.md
index 1a949f3c07..8d3e57c526 100644
--- a/contrib/init/README.md
+++ b/contrib/init/README.md
@@ -5,7 +5,7 @@ Upstart: bitcoind.conf
OpenRC: bitcoind.openrc
bitcoind.openrcconf
CentOS: bitcoind.init
-OS X: org.bitcoin.bitcoind.plist
+macOS: org.bitcoin.bitcoind.plist
```
have been made available to assist packagers in creating node packages here.
diff --git a/depends/README.md b/depends/README.md
index 99eef1952c..482b94a64f 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -22,7 +22,7 @@ Common `host-platform-triplets` for cross compilation are:
- `i686-w64-mingw32` for Win32
- `x86_64-w64-mingw32` for Win64
-- `x86_64-apple-darwin11` for MacOSX
+- `x86_64-apple-darwin11` for macOS
- `arm-linux-gnueabihf` for Linux ARM 32 bit
- `aarch64-linux-gnu` for Linux ARM 64 bit
@@ -49,7 +49,7 @@ The following can be set when running make: make FOO=bar
SOURCES_PATH: downloaded sources will be placed here
BASE_CACHE: built packages will be placed here
- SDK_PATH: Path where sdk's can be found (used by OSX)
+ SDK_PATH: Path where sdk's can be found (used by macOS)
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
NO_QT: Don't download/build/cache qt and its dependencies
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
@@ -64,7 +64,7 @@ options will be passed to bitcoin's configure. In this case, `--disable-wallet`.
Additional targets:
download: run 'make download' to fetch all sources without building them
- download-osx: run 'make download-osx' to fetch all sources needed for osx builds
+ download-osx: run 'make download-osx' to fetch all sources needed for macOS builds
download-win: run 'make download-win' to fetch all sources needed for win builds
download-linux: run 'make download-linux' to fetch all sources needed for linux builds
diff --git a/depends/description.md b/depends/description.md
index 74f9ef3f20..9fc7093be4 100644
--- a/depends/description.md
+++ b/depends/description.md
@@ -7,7 +7,7 @@ In theory, binaries for any target OS/architecture can be created, from a
builder running any OS/architecture. In practice, build-side tools must be
specified when the defaults don't fit, and packages must be amended to work
on new hosts. For now, a build architecture of x86_64 is assumed, either on
-Linux or OSX.
+Linux or macOS.
### No reliance on timestamps
diff --git a/doc/README.md b/doc/README.md
index ddb239f60c..45762b2374 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -22,7 +22,7 @@ Unpack the files into a directory and run:
Unpack the files into a directory, and then run bitcoin-qt.exe.
-### OS X
+### macOS
Drag Bitcoin-Core to your applications folder, and then run Bitcoin-Core.
@@ -38,7 +38,7 @@ Building
The following are developer notes on how to build Bitcoin on your native platform. They are not complete guides, but include notes on the necessary libraries, compile flags, etc.
- [Dependencies](dependencies.md)
-- [OS X Build Notes](build-osx.md)
+- [macOS Build Notes](build-osx.md)
- [Unix Build Notes](build-unix.md)
- [Windows Build Notes](build-windows.md)
- [OpenBSD Build Notes](build-openbsd.md)
diff --git a/doc/README_osx.md b/doc/README_osx.md
index 975be4be9e..739e22d634 100644
--- a/doc/README_osx.md
+++ b/doc/README_osx.md
@@ -1,12 +1,12 @@
-Deterministic OS X DMG Notes.
+Deterministic macOS DMG Notes.
-Working OS X DMGs are created in Linux by combining a recent clang,
+Working macOS DMGs are created in Linux by combining a recent clang,
the Apple binutils (ld, ar, etc) and DMG authoring tools.
Apple uses clang extensively for development and has upstreamed the necessary
functionality so that a vanilla clang can take advantage. It supports the use
of -F, -target, -mmacosx-version-min, and --sysroot, which are all necessary
-when building for OS X.
+when building for macOS.
Apple's version of binutils (called cctools) contains lots of functionality
missing in the FSF's binutils. In addition to extra linker options for
@@ -38,7 +38,7 @@ Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.1
Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file.
To create a tarball suitable for Gitian input, there are two options:
-Using Mac OS X, you can mount the dmg, and then create it with:
+Using macOS, you can mount the dmg, and then create it with:
```
$ hdiutil attach Xcode_7.3.1.dmg
$ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.11.sdk.tar.gz MacOSX10.11.sdk
@@ -81,7 +81,7 @@ Background images and other features can be added to DMG files by inserting a
.DS_Store before creation. This is generated by the script
contrib/macdeploy/custom_dsstore.py.
-As of OS X Mavericks (10.9), using an Apple-blessed key to sign binaries is a
+As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a
requirement in order to satisfy the new Gatekeeper requirements. Because this
private key cannot be shared, we'll have to be a bit creative in order for the
build process to remain somewhat deterministic. Here's how it works:
diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md
new file mode 100644
index 0000000000..c2e4e36dff
--- /dev/null
+++ b/doc/build-freebsd.md
@@ -0,0 +1,46 @@
+FreeBSD build guide
+======================
+(updated for FreeBSD 11.1)
+
+This guide describes how to build bitcoind and command-line utilities on FreeBSD.
+
+This guide does not contain instructions for building the GUI.
+
+## Preparation
+
+You will need the following dependencies, which can be installed as root via pkg:
+
+```
+pkg install autoconf automake boost-libs git gmake libevent libtool openssl pkgconf
+```
+
+For the wallet (optional):
+```
+./contrib/install_db4.sh `pwd`
+export BDB_PREFIX='$PWD/db4'
+```
+
+See [dependencies.md](dependencies.md) for a complete overview.
+
+Download the source code:
+```
+git clone https://github.com/bitcoin/bitcoin
+```
+
+## Building Bitcoin Core
+
+**Important**: Use `gmake` (the non-GNU `make` will exit with an error).
+
+```
+./autogen.sh
+
+./configure # to build with wallet OR
+./configure --disable-wallet # to build without wallet
+
+gmake
+```
+
+*Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement).
+It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and
+use the versioned gdb command (e.g. `gdb7111`).
+
diff --git a/doc/build-osx.md b/doc/build-osx.md
index e52a770ced..abd305cf9a 100644
--- a/doc/build-osx.md
+++ b/doc/build-osx.md
@@ -1,11 +1,11 @@
-Mac OS X Build Instructions and Notes
+macOS Build Instructions and Notes
====================================
The commands in this guide should be executed in a Terminal application.
The built-in one is located in `/Applications/Utilities/Terminal.app`.
Preparation
-----------
-Install the OS X command line tools:
+Install the macOS command line tools:
`xcode-select --install`
@@ -93,6 +93,6 @@ Other commands:
Notes
-----
-* Tested on OS X 10.8 through 10.13 on 64-bit Intel processors only.
+* Tested on OS X 10.8 Mountain Lion through macOS 10.13 High Sierra on 64-bit Intel processors only.
* Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714)
diff --git a/doc/build-unix.md b/doc/build-unix.md
index 2d10484a65..60d888a297 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -2,8 +2,7 @@ UNIX BUILD NOTES
====================
Some notes on how to build Bitcoin Core in Unix.
-(For BSD specific instructions, see [build-openbsd.md](build-openbsd.md) and/or
-[build-netbsd.md](build-netbsd.md))
+(For BSD specific instructions, see `build-*bsd.md` in this directory.)
Note
---------------------
@@ -303,33 +302,3 @@ To build executables for ARM:
For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory.
-Building on FreeBSD
---------------------
-
-(Updated as of FreeBSD 11.0)
-
-Clang is installed by default as `cc` compiler, this makes it easier to get
-started than on [OpenBSD](build-openbsd.md). Installing dependencies:
-
- pkg install autoconf automake libtool pkgconf
- pkg install boost-libs openssl libevent
- pkg install gmake
-
-You need to use GNU make (`gmake`) instead of `make`.
-(`libressl` instead of `openssl` will also work)
-
-For the wallet (optional):
-
- ./contrib/install_db4.sh `pwd`
- setenv BDB_PREFIX $PWD/db4
-
-Then build using:
-
- ./autogen.sh
- ./configure --disable-wallet # OR
- ./configure BDB_CFLAGS="-I${BDB_PREFIX}/include" BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx"
- gmake
-
-*Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement).
-It is not suitable for debugging a multi-threaded C++ program, not even for getting backtraces. Please install the package `gdb` and
-use the versioned gdb command e.g. `gdb7111`.
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index 9081cab911..8f6c662f19 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -499,7 +499,35 @@ Strings and formatting
- Use `ParseInt32`, `ParseInt64`, `ParseUInt32`, `ParseUInt64`, `ParseDouble` from `utilstrencodings.h` for number parsing
- - *Rationale*: These functions do overflow checking, and avoid pesky locale issues
+ - *Rationale*: These functions do overflow checking, and avoid pesky locale issues.
+
+- Avoid using locale dependent functions if possible. You can use the provided
+ [`lint-locale-dependence.sh`](/contrib/devtools/lint-locale-dependence.sh)
+ to check for accidental use of locale dependent functions.
+
+ - *Rationale*: Unnecessary locale dependence can cause bugs that are very tricky to isolate and fix.
+
+ - These functions are known to be locale dependent:
+ `alphasort`, `asctime`, `asprintf`, `atof`, `atoi`, `atol`, `atoll`, `atoq`,
+ `btowc`, `ctime`, `dprintf`, `fgetwc`, `fgetws`, `fprintf`, `fputwc`,
+ `fputws`, `fscanf`, `fwprintf`, `getdate`, `getwc`, `getwchar`, `isalnum`,
+ `isalpha`, `isblank`, `iscntrl`, `isdigit`, `isgraph`, `islower`, `isprint`,
+ `ispunct`, `isspace`, `isupper`, `iswalnum`, `iswalpha`, `iswblank`,
+ `iswcntrl`, `iswctype`, `iswdigit`, `iswgraph`, `iswlower`, `iswprint`,
+ `iswpunct`, `iswspace`, `iswupper`, `iswxdigit`, `isxdigit`, `mblen`,
+ `mbrlen`, `mbrtowc`, `mbsinit`, `mbsnrtowcs`, `mbsrtowcs`, `mbstowcs`,
+ `mbtowc`, `mktime`, `putwc`, `putwchar`, `scanf`, `snprintf`, `sprintf`,
+ `sscanf`, `stoi`, `stol`, `stoll`, `strcasecmp`, `strcasestr`, `strcoll`,
+ `strfmon`, `strftime`, `strncasecmp`, `strptime`, `strtod`, `strtof`,
+ `strtoimax`, `strtol`, `strtold`, `strtoll`, `strtoq`, `strtoul`,
+ `strtoull`, `strtoumax`, `strtouq`, `strxfrm`, `swprintf`, `tolower`,
+ `toupper`, `towctrans`, `towlower`, `towupper`, `ungetwc`, `vasprintf`,
+ `vdprintf`, `versionsort`, `vfprintf`, `vfscanf`, `vfwprintf`, `vprintf`,
+ `vscanf`, `vsnprintf`, `vsprintf`, `vsscanf`, `vswprintf`, `vwprintf`,
+ `wcrtomb`, `wcscasecmp`, `wcscoll`, `wcsftime`, `wcsncasecmp`, `wcsnrtombs`,
+ `wcsrtombs`, `wcstod`, `wcstof`, `wcstoimax`, `wcstol`, `wcstold`,
+ `wcstoll`, `wcstombs`, `wcstoul`, `wcstoull`, `wcstoumax`, `wcswidth`,
+ `wcsxfrm`, `wctob`, `wctomb`, `wctrans`, `wctype`, `wcwidth`, `wprintf`
- For `strprintf`, `LogPrint`, `LogPrintf` formatting characters don't need size specifiers
diff --git a/doc/init.md b/doc/init.md
index ffd13ae1f9..d04f7d186a 100644
--- a/doc/init.md
+++ b/doc/init.md
@@ -15,7 +15,7 @@ Service User
All three Linux startup configurations assume the existence of a "bitcoin" user
and group. They must be created before attempting to use these scripts.
-The OS X configuration assumes bitcoind will be set up for the current user.
+The macOS configuration assumes bitcoind will be set up for the current user.
Configuration
---------------------------------
@@ -65,7 +65,7 @@ reasons to make the configuration file and data directory only readable by the
bitcoin user and group. Access to bitcoin-cli and other bitcoind rpc clients
can then be controlled by group membership.
-### Mac OS X
+### macOS
Binary: `/usr/local/bin/bitcoind`
Configuration file: `~/Library/Application Support/Bitcoin/bitcoin.conf`
@@ -111,7 +111,7 @@ Using this script, you can adjust the path and flags to the bitcoind program by
setting the BITCOIND and FLAGS environment variables in the file
/etc/sysconfig/bitcoind. You can also use the DAEMONOPTS environment variable here.
-### Mac OS X
+### macOS
Copy org.bitcoin.bitcoind.plist into ~/Library/LaunchAgents. Load the launch agent by
running `launchctl load ~/Library/LaunchAgents/org.bitcoin.bitcoind.plist`.
diff --git a/doc/release-process.md b/doc/release-process.md
index fb6f08750d..912b620794 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -89,7 +89,7 @@ Ensure gitian-builder is up-to-date:
wget -P inputs http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz
popd
-Create the OS X SDK tarball, see the [OS X readme](README_osx.md) for details, and copy it into the inputs directory.
+Create the macOS SDK tarball, see the [macOS readme](README_osx.md) for details, and copy it into the inputs directory.
### Optional: Seed the Gitian sources cache and offline git repositories
@@ -111,7 +111,7 @@ NOTE: Offline builds must use the --url flag to ensure Gitian fetches only from
The gbuild invocations below <b>DO NOT DO THIS</b> by default.
-### Build and sign Bitcoin Core for Linux, Windows, and OS X:
+### Build and sign Bitcoin Core for Linux, Windows, and macOS:
pushd ./gitian-builder
./bin/gbuild --num-make 2 --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
@@ -134,7 +134,7 @@ Build output expected:
1. source tarball (`bitcoin-${VERSION}.tar.gz`)
2. linux 32-bit and 64-bit dist tarballs (`bitcoin-${VERSION}-linux[32|64].tar.gz`)
3. windows 32-bit and 64-bit unsigned installers and dist zips (`bitcoin-${VERSION}-win[32|64]-setup-unsigned.exe`, `bitcoin-${VERSION}-win[32|64].zip`)
- 4. OS X unsigned installer and dist tarball (`bitcoin-${VERSION}-osx-unsigned.dmg`, `bitcoin-${VERSION}-osx64.tar.gz`)
+ 4. macOS unsigned installer and dist tarball (`bitcoin-${VERSION}-osx-unsigned.dmg`, `bitcoin-${VERSION}-osx64.tar.gz`)
5. Gitian signatures (in `gitian.sigs/${VERSION}-<linux|{win,osx}-unsigned>/(your Gitian key)/`)
### Verify other gitian builders signatures to your own. (Optional)
@@ -161,13 +161,13 @@ Commit your signature to gitian.sigs:
git push # Assuming you can push to the gitian.sigs tree
popd
-Codesigner only: Create Windows/OS X detached signatures:
+Codesigner only: Create Windows/macOS detached signatures:
- Only one person handles codesigning. Everyone else should skip to the next step.
-- Only once the Windows/OS X builds each have 3 matching signatures may they be signed with their respective release keys.
+- Only once the Windows/macOS builds each have 3 matching signatures may they be signed with their respective release keys.
-Codesigner only: Sign the osx binary:
+Codesigner only: Sign the macOS binary:
- transfer bitcoin-osx-unsigned.tar.gz to osx for signing
+ transfer bitcoin-osx-unsigned.tar.gz to macOS for signing
tar xf bitcoin-osx-unsigned.tar.gz
./detached-sig-create.sh -s "Key ID"
Enter the keychain password and authorize the signature
@@ -192,12 +192,12 @@ Codesigner only: Commit the detached codesign payloads:
git tag -s v${VERSION} HEAD
git push the current branch and new tag
-Non-codesigners: wait for Windows/OS X detached signatures:
+Non-codesigners: wait for Windows/macOS detached signatures:
-- Once the Windows/OS X builds each have 3 matching signatures, they will be signed with their respective release keys.
+- Once the Windows/macOS builds each have 3 matching signatures, they will be signed with their respective release keys.
- Detached signatures will then be committed to the [bitcoin-detached-sigs](https://github.com/bitcoin-core/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries.
-Create (and optionally verify) the signed OS X binary:
+Create (and optionally verify) the signed macOS binary:
pushd ./gitian-builder
./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
@@ -216,7 +216,7 @@ Create (and optionally verify) the signed Windows binaries:
mv build/out/bitcoin-*win32-setup.exe ../bitcoin-${VERSION}-win32-setup.exe
popd
-Commit your signature for the signed OS X/Windows binaries:
+Commit your signature for the signed macOS/Windows binaries:
pushd gitian.sigs
git add ${VERSION}-osx-signed/"${SIGNER}"
diff --git a/src/Makefile.am b/src/Makefile.am
index 9b2ae36f6a..96e56915a6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,6 +30,8 @@ LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a
LIBBITCOIN_CLI=libbitcoin_cli.a
LIBBITCOIN_UTIL=libbitcoin_util.a
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
+LIBBITCOIN_CRYPTO_SSE41=crypto/libbitcoin_crypto_sse41.a
+LIBBITCOIN_CRYPTO_AVX2=crypto/libbitcoin_crypto_avx2.a
LIBBITCOINQT=qt/libbitcoinqt.a
LIBSECP256K1=secp256k1/libsecp256k1.la
@@ -50,6 +52,8 @@ $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
# But to build the less dependent modules first, we manually select their order here:
EXTRA_LIBRARIES += \
$(LIBBITCOIN_CRYPTO) \
+ $(LIBBITCOIN_CRYPTO_SSE41) \
+ $(LIBBITCOIN_CRYPTO_AVX2) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_CONSENSUS) \
@@ -289,6 +293,22 @@ if USE_ASM
crypto_libbitcoin_crypto_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)
+if ENABLE_SSE41
+crypto_libbitcoin_crypto_sse41_a_CXXFLAGS += $(SSE41_CXXFLAGS)
+crypto_libbitcoin_crypto_sse41_a_CPPFLAGS += -DENABLE_SSE41
+endif
+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)
+if ENABLE_AVX2
+crypto_libbitcoin_crypto_avx2_a_CXXFLAGS += $(AVX2_CXXFLAGS)
+crypto_libbitcoin_crypto_avx2_a_CPPFLAGS += -DENABLE_AVX2
+endif
+crypto_libbitcoin_crypto_avx2_a_SOURCES = crypto/sha256_avx2.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)
@@ -411,6 +431,8 @@ bitcoind_LDADD = \
$(LIBBITCOIN_ZMQ) \
$(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
+ $(LIBBITCOIN_CRYPTO_SSE41) \
+ $(LIBBITCOIN_CRYPTO_AVX2) \
$(LIBLEVELDB) \
$(LIBLEVELDB_SSE42) \
$(LIBMEMENV) \
@@ -432,7 +454,9 @@ bitcoin_cli_LDADD = \
$(LIBBITCOIN_CLI) \
$(LIBUNIVALUE) \
$(LIBBITCOIN_UTIL) \
- $(LIBBITCOIN_CRYPTO)
+ $(LIBBITCOIN_CRYPTO) \
+ $(LIBBITCOIN_CRYPTO_SSE41) \
+ $(LIBBITCOIN_CRYPTO_AVX2)
bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
#
@@ -453,6 +477,8 @@ bitcoin_tx_LDADD = \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
+ $(LIBBITCOIN_CRYPTO_SSE41) \
+ $(LIBBITCOIN_CRYPTO_AVX2) \
$(LIBSECP256K1)
bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index 3306dcf598..804df3bf21 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -21,6 +21,7 @@ bench_bench_bitcoin_SOURCES = \
bench/rollingbloom.cpp \
bench/crypto_hash.cpp \
bench/ccoins_caching.cpp \
+ bench/merkle_root.cpp \
bench/mempool_eviction.cpp \
bench/verify_script.cpp \
bench/base58.cpp \
@@ -38,6 +39,8 @@ bench_bench_bitcoin_LDADD = \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
+ $(LIBBITCOIN_CRYPTO_SSE41) \
+ $(LIBBITCOIN_CRYPTO_AVX2) \
$(LIBLEVELDB) \
$(LIBLEVELDB_SSE42) \
$(LIBMEMENV) \
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index a84a11ac45..f8c31be3d4 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -408,7 +408,7 @@ endif
if ENABLE_ZMQ
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
-qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
+qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_CRYPTO_SSE41) $(LIBBITCOIN_CRYPTO_AVX2) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index 4b14212b2e..a4356f1cbd 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -62,7 +62,7 @@ endif
if ENABLE_ZMQ
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
-qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
+qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_CRYPTO_SSE41) $(LIBBITCOIN_CRYPTO_AVX2) $(LIBUNIVALUE) $(LIBLEVELDB) \
$(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 28ce7e4e1e..cbd63cd53d 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -109,7 +109,8 @@ test_test_bitcoin_LDADD =
if ENABLE_WALLET
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
endif
-test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
+
+test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_CRYPTO_SSE41) $(LIBBITCOIN_CRYPTO_AVX2) $(LIBUNIVALUE) \
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
@@ -134,6 +135,8 @@ test_test_bitcoin_fuzzy_LDADD = \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
+ $(LIBBITCOIN_CRYPTO_SSE41) \
+ $(LIBBITCOIN_CRYPTO_AVX2) \
$(LIBSECP256K1)
test_test_bitcoin_fuzzy_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp
index 556d1fae9e..f3302bfe5a 100644
--- a/src/bench/bench_bitcoin.cpp
+++ b/src/bench/bench_bitcoin.cpp
@@ -6,11 +6,10 @@
#include <crypto/sha256.h>
#include <key.h>
-#include <validation.h>
-#include <util.h>
#include <random.h>
-
-#include <boost/lexical_cast.hpp>
+#include <util.h>
+#include <utilstrencodings.h>
+#include <validation.h>
#include <memory>
@@ -64,8 +63,11 @@ int main(int argc, char** argv)
std::string scaling_str = gArgs.GetArg("-scaling", DEFAULT_BENCH_SCALING);
bool is_list_only = gArgs.GetBoolArg("-list", false);
- double scaling_factor = boost::lexical_cast<double>(scaling_str);
-
+ double scaling_factor;
+ if (!ParseDouble(scaling_str, &scaling_factor)) {
+ fprintf(stderr, "Error parsing scaling factor as double: %s\n", scaling_str.c_str());
+ return EXIT_FAILURE;
+ }
std::unique_ptr<benchmark::Printer> printer(new benchmark::ConsolePrinter());
std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER);
diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp
index adb69bc6c3..7d907eaf10 100644
--- a/src/bench/crypto_hash.cpp
+++ b/src/bench/crypto_hash.cpp
@@ -52,6 +52,14 @@ static void SHA256_32b(benchmark::State& state)
}
}
+static void SHA256D64_1024(benchmark::State& state)
+{
+ std::vector<uint8_t> in(64 * 1024, 0);
+ while (state.KeepRunning()) {
+ SHA256D64(in.data(), in.data(), 1024);
+ }
+}
+
static void SHA512(benchmark::State& state)
{
uint8_t hash[CSHA512::OUTPUT_SIZE];
@@ -94,5 +102,6 @@ BENCHMARK(SHA512, 330);
BENCHMARK(SHA256_32b, 4700 * 1000);
BENCHMARK(SipHash_32b, 40 * 1000 * 1000);
+BENCHMARK(SHA256D64_1024, 7400);
BENCHMARK(FastRandom_32bit, 110 * 1000 * 1000);
BENCHMARK(FastRandom_1bit, 440 * 1000 * 1000);
diff --git a/src/bench/merkle_root.cpp b/src/bench/merkle_root.cpp
new file mode 100644
index 0000000000..ae2a0a28dc
--- /dev/null
+++ b/src/bench/merkle_root.cpp
@@ -0,0 +1,26 @@
+// Copyright (c) 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.
+
+#include "bench.h"
+
+#include "uint256.h"
+#include "random.h"
+#include "consensus/merkle.h"
+
+static void MerkleRoot(benchmark::State& state)
+{
+ FastRandomContext rng(true);
+ std::vector<uint256> leaves;
+ leaves.resize(9001);
+ for (auto& item : leaves) {
+ item = rng.rand256();
+ }
+ while (state.KeepRunning()) {
+ bool mutation = false;
+ uint256 hash = ComputeMerkleRoot(std::vector<uint256>(leaves), &mutation);
+ leaves[mutation] = hash;
+ }
+}
+
+BENCHMARK(MerkleRoot, 800);
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index be5ce14480..b332b5e581 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -56,6 +56,18 @@ static void SetupCliArgs()
gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN);
}
+/** libevent event log callback */
+static void libevent_log_cb(int severity, const char *msg)
+{
+#ifndef EVENT_LOG_ERR // EVENT_LOG_ERR was added in 2.0.19; but before then _EVENT_LOG_ERR existed.
+# define EVENT_LOG_ERR _EVENT_LOG_ERR
+#endif
+ // Ignore everything other than errors
+ if (severity >= EVENT_LOG_ERR) {
+ throw std::runtime_error(strprintf("libevent error: %s", msg));
+ }
+}
+
//////////////////////////////////////////////////////////////////////////////
//
// Start
@@ -506,6 +518,7 @@ int main(int argc, char* argv[])
fprintf(stderr, "Error: Initializing networking failed\n");
return EXIT_FAILURE;
}
+ event_set_log_callback(&libevent_log_cb);
try {
int ret = AppInitRPC(argc, argv);
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 3fb505d739..2a594c3051 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -637,7 +637,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
// Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
- const CTxIn& txin = mergedTx.vin[i];
+ CTxIn& txin = mergedTx.vin[i];
const Coin& coin = view.AccessCoin(txin.prevout);
if (coin.IsSpent()) {
continue;
@@ -652,7 +652,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
// ... and merge in other signatures:
sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i));
- UpdateTransaction(mergedTx, i, sigdata);
+ UpdateInput(txin, sigdata);
}
tx = mergedTx;
diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp
index 74a9ebb2e3..07cd109cc1 100644
--- a/src/consensus/merkle.cpp
+++ b/src/consensus/merkle.cpp
@@ -42,118 +42,26 @@
root.
*/
-/* This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */
-static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot, bool* pmutated, uint32_t branchpos, std::vector<uint256>* pbranch) {
- if (pbranch) pbranch->clear();
- if (leaves.size() == 0) {
- if (pmutated) *pmutated = false;
- if (proot) *proot = uint256();
- return;
- }
- bool mutated = false;
- // count is the number of leaves processed so far.
- uint32_t count = 0;
- // inner is an array of eagerly computed subtree hashes, indexed by tree
- // level (0 being the leaves).
- // For example, when count is 25 (11001 in binary), inner[4] is the hash of
- // the first 16 leaves, inner[3] of the next 8 leaves, and inner[0] equal to
- // the last leaf. The other inner entries are undefined.
- uint256 inner[32];
- // Which position in inner is a hash that depends on the matching leaf.
- int matchlevel = -1;
- // First process all leaves into 'inner' values.
- while (count < leaves.size()) {
- uint256 h = leaves[count];
- bool matchh = count == branchpos;
- count++;
- int level;
- // For each of the lower bits in count that are 0, do 1 step. Each
- // corresponds to an inner value that existed before processing the
- // current leaf, and each needs a hash to combine it.
- for (level = 0; !(count & (((uint32_t)1) << level)); level++) {
- if (pbranch) {
- if (matchh) {
- pbranch->push_back(inner[level]);
- } else if (matchlevel == level) {
- pbranch->push_back(h);
- matchh = true;
- }
+
+uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated) {
+ bool mutation = false;
+ while (hashes.size() > 1) {
+ if (mutated) {
+ for (size_t pos = 0; pos + 1 < hashes.size(); pos += 2) {
+ if (hashes[pos] == hashes[pos + 1]) mutation = true;
}
- mutated |= (inner[level] == h);
- CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin());
}
- // Store the resulting hash at inner position level.
- inner[level] = h;
- if (matchh) {
- matchlevel = level;
+ if (hashes.size() & 1) {
+ hashes.push_back(hashes.back());
}
+ SHA256D64(hashes[0].begin(), hashes[0].begin(), hashes.size() / 2);
+ hashes.resize(hashes.size() / 2);
}
- // Do a final 'sweep' over the rightmost branch of the tree to process
- // odd levels, and reduce everything to a single top value.
- // Level is the level (counted from the bottom) up to which we've sweeped.
- int level = 0;
- // As long as bit number level in count is zero, skip it. It means there
- // is nothing left at this level.
- while (!(count & (((uint32_t)1) << level))) {
- level++;
- }
- uint256 h = inner[level];
- bool matchh = matchlevel == level;
- while (count != (((uint32_t)1) << level)) {
- // If we reach this point, h is an inner value that is not the top.
- // We combine it with itself (Bitcoin's special rule for odd levels in
- // the tree) to produce a higher level one.
- if (pbranch && matchh) {
- pbranch->push_back(h);
- }
- CHash256().Write(h.begin(), 32).Write(h.begin(), 32).Finalize(h.begin());
- // Increment count to the value it would have if two entries at this
- // level had existed.
- count += (((uint32_t)1) << level);
- level++;
- // And propagate the result upwards accordingly.
- while (!(count & (((uint32_t)1) << level))) {
- if (pbranch) {
- if (matchh) {
- pbranch->push_back(inner[level]);
- } else if (matchlevel == level) {
- pbranch->push_back(h);
- matchh = true;
- }
- }
- CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin());
- level++;
- }
- }
- // Return result.
- if (pmutated) *pmutated = mutated;
- if (proot) *proot = h;
+ if (mutated) *mutated = mutation;
+ if (hashes.size() == 0) return uint256();
+ return hashes[0];
}
-uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated) {
- uint256 hash;
- MerkleComputation(leaves, &hash, mutated, -1, nullptr);
- return hash;
-}
-
-std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position) {
- std::vector<uint256> ret;
- MerkleComputation(leaves, nullptr, nullptr, position, &ret);
- return ret;
-}
-
-uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& vMerkleBranch, uint32_t nIndex) {
- uint256 hash = leaf;
- for (std::vector<uint256>::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) {
- if (nIndex & 1) {
- hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
- } else {
- hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
- }
- nIndex >>= 1;
- }
- return hash;
-}
uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
{
@@ -162,7 +70,7 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
for (size_t s = 0; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetHash();
}
- return ComputeMerkleRoot(leaves, mutated);
+ return ComputeMerkleRoot(std::move(leaves), mutated);
}
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
@@ -173,15 +81,6 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
for (size_t s = 1; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetWitnessHash();
}
- return ComputeMerkleRoot(leaves, mutated);
+ return ComputeMerkleRoot(std::move(leaves), mutated);
}
-std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position)
-{
- std::vector<uint256> leaves;
- leaves.resize(block.vtx.size());
- for (size_t s = 0; s < block.vtx.size(); s++) {
- leaves[s] = block.vtx[s]->GetHash();
- }
- return ComputeMerkleBranch(leaves, position);
-}
diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h
index 0afb73adb5..01d75b1329 100644
--- a/src/consensus/merkle.h
+++ b/src/consensus/merkle.h
@@ -12,9 +12,7 @@
#include <primitives/block.h>
#include <uint256.h>
-uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated = nullptr);
-std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position);
-uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& branch, uint32_t position);
+uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated = nullptr);
/*
* Compute the Merkle root of the transactions in a block.
@@ -28,11 +26,4 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated = nullptr);
*/
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated = nullptr);
-/*
- * Compute the Merkle branch for the tree of transactions in a block, for a
- * given position.
- * This can be verified using ComputeMerkleRootFromBranch.
- */
-std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position);
-
#endif // BITCOIN_CONSENSUS_MERKLE_H
diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp
index f3245b8dea..6ac51d11cd 100644
--- a/src/crypto/sha256.cpp
+++ b/src/crypto/sha256.cpp
@@ -19,6 +19,16 @@ void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
#endif
#endif
+namespace sha256d64_sse41
+{
+void Transform_4way(unsigned char* out, const unsigned char* in);
+}
+
+namespace sha256d64_avx2
+{
+void Transform_8way(unsigned char* out, const unsigned char* in);
+}
+
// Internal implementation code.
namespace
{
@@ -33,9 +43,9 @@ uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x <<
uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
/** One round of SHA-256. */
-void inline 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 w)
+void inline 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 + w;
+ 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;
@@ -61,73 +71,73 @@ void Transform(uint32_t* s, const unsigned char* chunk, size_t 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));
+ 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;
@@ -141,9 +151,300 @@ void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
}
}
+void TransformD64(unsigned char* out, const unsigned char* 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 unsigned char*, size_t);
+typedef void (*TransformD64Type)(unsigned char*, const unsigned char*);
+
+template<TransformType tr>
+void TransformD64Wrapper(unsigned char* out, const unsigned char* in)
+{
+ uint32_t s[8];
+ static const unsigned char 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
+ };
+ unsigned char 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]);
+}
bool SelfTest(TransformType tr) {
static const unsigned char in1[65] = {0, 0x80};
@@ -173,22 +474,47 @@ bool SelfTest(TransformType tr) {
}
TransformType Transform = sha256::Transform;
+TransformD64Type TransformD64 = sha256::TransformD64;
+TransformD64Type TransformD64_4way = nullptr;
+TransformD64Type TransformD64_8way = nullptr;
+#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__))
+// 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, uint32_t& c, uint32_t& d)
+{
+ __asm__ ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf));
+}
+#endif
} // namespace
+
std::string SHA256AutoDetect()
{
+ std::string ret = "standard";
#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__))
uint32_t eax, ebx, ecx, edx;
- if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) {
+ cpuid(1, 0, eax, ebx, ecx, edx);
+ if ((ecx >> 19) & 1) {
Transform = sha256_sse4::Transform;
- assert(SelfTest(Transform));
- return "sse4";
+ TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
+#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)
+ cpuid(7, 0, eax, ebx, ecx, edx);
+ if ((ebx >> 5) & 1) {
+ TransformD64_8way = sha256d64_avx2::Transform_8way;
+ ret += ",avx2(8way)";
+ }
+#endif
+#else
+ ret = "sse4";
+#endif
}
#endif
assert(SelfTest(Transform));
- return "standard";
+ return ret;
}
////// SHA-256
@@ -247,3 +573,29 @@ CSHA256& CSHA256::Reset()
sha256::Initialize(s);
return *this;
}
+
+void SHA256D64(unsigned char* out, const unsigned char* 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;
+ }
+ }
+ while (blocks) {
+ TransformD64(out, in);
+ out += 32;
+ in += 64;
+ --blocks;
+ }
+}
diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h
index dd30fe396f..31b2b3b3df 100644
--- a/src/crypto/sha256.h
+++ b/src/crypto/sha256.h
@@ -31,4 +31,11 @@ public:
*/
std::string SHA256AutoDetect();
+/** Compute multiple double-SHA256's of 64-byte blobs.
+ * output: pointer to a blocks*32 byte output buffer
+ * input: pointer to a blocks*64 byte input buffer
+ * blocks: the number of hashes to compute.
+ */
+void SHA256D64(unsigned char* output, const unsigned char* input, size_t blocks);
+
#endif // BITCOIN_CRYPTO_SHA256_H
diff --git a/src/crypto/sha256_avx2.cpp b/src/crypto/sha256_avx2.cpp
new file mode 100644
index 0000000000..f45c1d4ab6
--- /dev/null
+++ b/src/crypto/sha256_avx2.cpp
@@ -0,0 +1,329 @@
+#ifdef ENABLE_AVX2
+
+#include <stdint.h>
+#if defined(_MSC_VER)
+#include <immintrin.h>
+#elif defined(__GNUC__)
+#include <x86intrin.h>
+#endif
+
+#include "crypto/sha256.h"
+#include "crypto/common.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)) 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 unsigned char* 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(unsigned char* 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(unsigned char* out, const unsigned char* 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_sse41.cpp b/src/crypto/sha256_sse41.cpp
new file mode 100644
index 0000000000..a11d658c70
--- /dev/null
+++ b/src/crypto/sha256_sse41.cpp
@@ -0,0 +1,321 @@
+#ifdef ENABLE_SSE41
+
+#include <stdint.h>
+#if defined(_MSC_VER)
+#include <immintrin.h>
+#elif defined(__GNUC__)
+#include <x86intrin.h>
+#endif
+
+#include "crypto/sha256.h"
+#include "crypto/common.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)) 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 unsigned char* 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(unsigned char* 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(unsigned char* out, const unsigned char* 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
diff --git a/src/qt/README.md b/src/qt/README.md
index d8acf96ceb..bf8139666c 100644
--- a/src/qt/README.md
+++ b/src/qt/README.md
@@ -4,7 +4,7 @@ The current precise version for Qt 5 is specified in [qt.mk](/depends/packages/q
## Compile and run
-See build instructions ([OSX](/doc/build-osx.md), [Windows](/doc/build-windows.md), [Unix](/doc/build-unix.md), etc).
+See build instructions ([macOS](/doc/build-osx.md), [Windows](/doc/build-windows.md), [Unix](/doc/build-unix.md), etc).
To run:
@@ -65,7 +65,7 @@ Represents the view to a single wallet.
* `guiconstants.h`: UI colors, app name, etc
* `guiutil.h`: several helper functions
* `macdockiconhandler.(h/cpp)`
-* `macdockiconhandler.(h/cpp)`: display notifications in OSX
+* `macdockiconhandler.(h/cpp)`: display notifications in macOS
## Contribute
@@ -81,9 +81,9 @@ the UI layout.
Download and install the community edition of [Qt Creator](https://www.qt.io/download/).
Uncheck everything except Qt Creator during the installation process.
-Instructions for OSX:
+Instructions for macOS:
-1. Make sure you installed everything through Homebrew mentioned in the [OSX build instructions](/doc/build-osx.md)
+1. Make sure you installed everything through Homebrew mentioned in the [macOS build instructions](/doc/build-osx.md)
2. Use `./configure` with the `--enable-debug` flag
3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project
4. Enter "bitcoin-qt" as project name, enter src/qt as location
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 24fb522e60..48e0e02d1a 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -6,7 +6,6 @@
#include <rpc/blockchain.h>
#include <amount.h>
-#include <chain.h>
#include <chainparams.h>
#include <checkpoints.h>
#include <coins.h>
@@ -49,17 +48,13 @@ static std::mutex cs_blockchange;
static std::condition_variable cond_blockchange;
static CUpdatedBlock latestblock;
-/* Calculate the difficulty for a given block index,
- * or the block index of the given chain.
+/* Calculate the difficulty for a given block index.
*/
-double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex)
+double GetDifficulty(const CBlockIndex* blockindex)
{
if (blockindex == nullptr)
{
- if (chain.Tip() == nullptr)
- return 1.0;
- else
- blockindex = chain.Tip();
+ return 1.0;
}
int nShift = (blockindex->nBits >> 24) & 0xff;
@@ -80,11 +75,6 @@ double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex)
return dDiff;
}
-double GetDifficulty(const CBlockIndex* blockindex)
-{
- return GetDifficulty(chainActive, blockindex);
-}
-
UniValue blockheaderToJSON(const CBlockIndex* blockindex)
{
AssertLockHeld(cs_main);
@@ -354,7 +344,7 @@ static UniValue getdifficulty(const JSONRPCRequest& request)
);
LOCK(cs_main);
- return GetDifficulty();
+ return GetDifficulty(chainActive.Tip());
}
static std::string EntryDescriptionString()
@@ -1240,7 +1230,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.pushKV("blocks", (int)chainActive.Height());
obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1);
obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex());
- obj.pushKV("difficulty", (double)GetDifficulty());
+ obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip()));
obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast());
obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()));
obj.pushKV("initialblockdownload", IsInitialBlockDownload());
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index 960edfd56f..3aa8de2d2b 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -16,7 +16,7 @@ class UniValue;
* @return A floating point number that is a multiple of the main net minimum
* difficulty (4295032833 hashes).
*/
-double GetDifficulty(const CBlockIndex* blockindex = nullptr);
+double GetDifficulty(const CBlockIndex* blockindex);
/** Callback for when block tip changed. */
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
@@ -34,4 +34,3 @@ UniValue mempoolToJSON(bool fVerbose = false);
UniValue blockheaderToJSON(const CBlockIndex* blockindex);
#endif
-
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 203fac39e2..85b864e6b9 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -214,7 +214,7 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
obj.pushKV("blocks", (int)chainActive.Height());
obj.pushKV("currentblockweight", (uint64_t)nLastBlockWeight);
obj.pushKV("currentblocktx", (uint64_t)nLastBlockTx);
- obj.pushKV("difficulty", (double)GetDifficulty());
+ obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip()));
obj.pushKV("networkhashps", getnetworkhashps(request));
obj.pushKV("pooledtx", (uint64_t)mempool.size());
obj.pushKV("chain", Params().NetworkIDString());
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index ad2d55afe7..3b3f43edea 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -748,7 +748,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
}
}
- UpdateTransaction(mergedTx, i, sigdata);
+ UpdateInput(txin, sigdata);
}
return EncodeHexTx(mergedTx);
@@ -882,7 +882,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
}
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i));
- UpdateTransaction(mtx, i, sigdata);
+ UpdateInput(txin, sigdata);
ScriptError serror = SCRIPT_ERR_OK;
if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index c5468f633b..6dbfbda029 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -199,12 +199,6 @@ void UpdateInput(CTxIn& input, const SignatureData& data)
input.scriptWitness = data.scriptWitness;
}
-void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data)
-{
- assert(tx.vin.size() > nIn);
- UpdateInput(tx.vin[nIn], data);
-}
-
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
{
assert(nIn < txTo.vin.size());
@@ -213,7 +207,7 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C
SignatureData sigdata;
bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
- UpdateTransaction(txTo, nIn, sigdata);
+ UpdateInput(txTo.vin.at(nIn), sigdata);
return ret;
}
diff --git a/src/script/sign.h b/src/script/sign.h
index a10366dcd1..8ef0306bfe 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -73,7 +73,6 @@ SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignature
/** Extract signature data from a transaction, and insert it. */
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn);
-void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data);
void UpdateInput(CTxIn& input, const SignatureData& data);
/* Check whether we know how to sign for an output like this, assuming we
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 53fcbe37de..d9269d6147 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -114,6 +114,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
vSolutionsRet.push_back(std::move(witnessprogram));
return true;
}
+ typeRet = TX_NONSTANDARD;
return false;
}
diff --git a/src/test/blockchain_tests.cpp b/src/test/blockchain_tests.cpp
index 5b8df32158..d2d0008122 100644
--- a/src/test/blockchain_tests.cpp
+++ b/src/test/blockchain_tests.cpp
@@ -2,7 +2,7 @@
#include "stdlib.h"
-#include "rpc/blockchain.cpp"
+#include "rpc/blockchain.h"
#include "test/test_bitcoin.h"
/* Equality between doubles is imprecise. Comparison should be done
@@ -22,14 +22,6 @@ static CBlockIndex* CreateBlockIndexWithNbits(uint32_t nbits)
return block_index;
}
-static CChain CreateChainWithNbits(uint32_t nbits)
-{
- CBlockIndex* block_index = CreateBlockIndexWithNbits(nbits);
- CChain chain;
- chain.SetTip(block_index);
- return chain;
-}
-
static void RejectDifficultyMismatch(double difficulty, double expected_difficulty) {
BOOST_CHECK_MESSAGE(
DoubleEquals(difficulty, expected_difficulty, 0.00001),
@@ -43,12 +35,7 @@ static void RejectDifficultyMismatch(double difficulty, double expected_difficul
static void TestDifficulty(uint32_t nbits, double expected_difficulty)
{
CBlockIndex* block_index = CreateBlockIndexWithNbits(nbits);
- /* Since we are passing in block index explicitly,
- * there is no need to set up anything within the chain itself.
- */
- CChain chain;
-
- double difficulty = GetDifficulty(chain, block_index);
+ double difficulty = GetDifficulty(block_index);
delete block_index;
RejectDifficultyMismatch(difficulty, expected_difficulty);
@@ -84,43 +71,8 @@ BOOST_AUTO_TEST_CASE(get_difficulty_for_very_high_target)
// Verify that difficulty is 1.0 for an empty chain.
BOOST_AUTO_TEST_CASE(get_difficulty_for_null_tip)
{
- CChain chain;
- double difficulty = GetDifficulty(chain, nullptr);
+ double difficulty = GetDifficulty(nullptr);
RejectDifficultyMismatch(difficulty, 1.0);
}
-/* Verify that if difficulty is based upon the block index
- * in the chain, if no block index is explicitly specified.
- */
-BOOST_AUTO_TEST_CASE(get_difficulty_for_null_block_index)
-{
- CChain chain = CreateChainWithNbits(0x1df88f6f);
-
- double difficulty = GetDifficulty(chain, nullptr);
- delete chain.Tip();
-
- double expected_difficulty = 0.004023;
-
- RejectDifficultyMismatch(difficulty, expected_difficulty);
-}
-
-/* Verify that difficulty is based upon the explicitly specified
- * block index rather than being taken from the provided chain,
- * when both are present.
- */
-BOOST_AUTO_TEST_CASE(get_difficulty_for_block_index_overrides_tip)
-{
- CChain chain = CreateChainWithNbits(0x1df88f6f);
- /* This block index's nbits should be used
- * instead of the chain's when calculating difficulty.
- */
- CBlockIndex* override_block_index = CreateBlockIndexWithNbits(0x12345678);
-
- double difficulty = GetDifficulty(chain, override_block_index);
- delete chain.Tip();
- delete override_block_index;
-
- RejectDifficultyMismatch(difficulty, 5913134931067755359633408.0);
-}
-
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index 518cb849bb..d701f3bc4e 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -546,4 +546,20 @@ BOOST_AUTO_TEST_CASE(countbits_tests)
}
}
+BOOST_AUTO_TEST_CASE(sha256d64)
+{
+ for (int i = 0; i <= 32; ++i) {
+ unsigned char in[64 * 32];
+ unsigned char out1[32 * 32], out2[32 * 32];
+ for (int j = 0; j < 64 * i; ++j) {
+ in[j] = InsecureRandBits(8);
+ }
+ for (int j = 0; j < i; ++j) {
+ CHash256().Write(in + 64 * j, 64).Finalize(out1 + 32 * j);
+ }
+ SHA256D64(out2, in, i);
+ BOOST_CHECK(memcmp(out1, out2, 32 * i) == 0);
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp
index 72a2672352..259e45dacf 100644
--- a/src/test/merkle_tests.cpp
+++ b/src/test/merkle_tests.cpp
@@ -9,6 +9,123 @@
BOOST_FIXTURE_TEST_SUITE(merkle_tests, TestingSetup)
+static uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& vMerkleBranch, uint32_t nIndex) {
+ uint256 hash = leaf;
+ for (std::vector<uint256>::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) {
+ if (nIndex & 1) {
+ hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
+ } else {
+ hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
+ }
+ nIndex >>= 1;
+ }
+ return hash;
+}
+
+/* This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */
+static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot, bool* pmutated, uint32_t branchpos, std::vector<uint256>* pbranch) {
+ if (pbranch) pbranch->clear();
+ if (leaves.size() == 0) {
+ if (pmutated) *pmutated = false;
+ if (proot) *proot = uint256();
+ return;
+ }
+ bool mutated = false;
+ // count is the number of leaves processed so far.
+ uint32_t count = 0;
+ // inner is an array of eagerly computed subtree hashes, indexed by tree
+ // level (0 being the leaves).
+ // For example, when count is 25 (11001 in binary), inner[4] is the hash of
+ // the first 16 leaves, inner[3] of the next 8 leaves, and inner[0] equal to
+ // the last leaf. The other inner entries are undefined.
+ uint256 inner[32];
+ // Which position in inner is a hash that depends on the matching leaf.
+ int matchlevel = -1;
+ // First process all leaves into 'inner' values.
+ while (count < leaves.size()) {
+ uint256 h = leaves[count];
+ bool matchh = count == branchpos;
+ count++;
+ int level;
+ // For each of the lower bits in count that are 0, do 1 step. Each
+ // corresponds to an inner value that existed before processing the
+ // current leaf, and each needs a hash to combine it.
+ for (level = 0; !(count & (((uint32_t)1) << level)); level++) {
+ if (pbranch) {
+ if (matchh) {
+ pbranch->push_back(inner[level]);
+ } else if (matchlevel == level) {
+ pbranch->push_back(h);
+ matchh = true;
+ }
+ }
+ mutated |= (inner[level] == h);
+ CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin());
+ }
+ // Store the resulting hash at inner position level.
+ inner[level] = h;
+ if (matchh) {
+ matchlevel = level;
+ }
+ }
+ // Do a final 'sweep' over the rightmost branch of the tree to process
+ // odd levels, and reduce everything to a single top value.
+ // Level is the level (counted from the bottom) up to which we've sweeped.
+ int level = 0;
+ // As long as bit number level in count is zero, skip it. It means there
+ // is nothing left at this level.
+ while (!(count & (((uint32_t)1) << level))) {
+ level++;
+ }
+ uint256 h = inner[level];
+ bool matchh = matchlevel == level;
+ while (count != (((uint32_t)1) << level)) {
+ // If we reach this point, h is an inner value that is not the top.
+ // We combine it with itself (Bitcoin's special rule for odd levels in
+ // the tree) to produce a higher level one.
+ if (pbranch && matchh) {
+ pbranch->push_back(h);
+ }
+ CHash256().Write(h.begin(), 32).Write(h.begin(), 32).Finalize(h.begin());
+ // Increment count to the value it would have if two entries at this
+ // level had existed.
+ count += (((uint32_t)1) << level);
+ level++;
+ // And propagate the result upwards accordingly.
+ while (!(count & (((uint32_t)1) << level))) {
+ if (pbranch) {
+ if (matchh) {
+ pbranch->push_back(inner[level]);
+ } else if (matchlevel == level) {
+ pbranch->push_back(h);
+ matchh = true;
+ }
+ }
+ CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin());
+ level++;
+ }
+ }
+ // Return result.
+ if (pmutated) *pmutated = mutated;
+ if (proot) *proot = h;
+}
+
+static std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position) {
+ std::vector<uint256> ret;
+ MerkleComputation(leaves, nullptr, nullptr, position, &ret);
+ return ret;
+}
+
+static std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position)
+{
+ std::vector<uint256> leaves;
+ leaves.resize(block.vtx.size());
+ for (size_t s = 0; s < block.vtx.size(); s++) {
+ leaves[s] = block.vtx[s]->GetHash();
+ }
+ return ComputeMerkleBranch(leaves, position);
+}
+
// Older version of the merkle root computation code, for comparison.
static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::vector<uint256>& vMerkleTree)
{
diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp
index ff0bf6c66d..7ab0978228 100644
--- a/src/test/script_standard_tests.cpp
+++ b/src/test/script_standard_tests.cpp
@@ -726,6 +726,32 @@ BOOST_AUTO_TEST_CASE(script_standard_IsMine)
BOOST_CHECK(!isInvalid);
}
+ // witness unspendable
+ {
+ CBasicKeyStore keystore;
+ keystore.AddKey(keys[0]);
+
+ scriptPubKey.clear();
+ scriptPubKey << OP_0 << ToByteVector(ParseHex("aabb"));
+
+ result = IsMine(keystore, scriptPubKey, isInvalid);
+ BOOST_CHECK_EQUAL(result, ISMINE_NO);
+ BOOST_CHECK(!isInvalid);
+ }
+
+ // witness unknown
+ {
+ CBasicKeyStore keystore;
+ keystore.AddKey(keys[0]);
+
+ scriptPubKey.clear();
+ scriptPubKey << OP_16 << ToByteVector(ParseHex("aabb"));
+
+ result = IsMine(keystore, scriptPubKey, isInvalid);
+ BOOST_CHECK_EQUAL(result, ISMINE_NO);
+ BOOST_CHECK(!isInvalid);
+ }
+
// Nonstandard
{
CBasicKeyStore keystore;
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index cc72e96eb1..65c5b8ea1d 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -629,7 +629,7 @@ BOOST_AUTO_TEST_CASE(test_witness)
CreateCreditAndSpend(keystore2, scriptMulti, output2, input2, false);
CheckWithFlag(output2, input2, 0, false);
BOOST_CHECK(*output1 == *output2);
- UpdateTransaction(input1, 0, CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ UpdateInput(input1.vin[0], CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
// P2SH 2-of-2 multisig
@@ -640,7 +640,7 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output2, input2, 0, true);
CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false);
BOOST_CHECK(*output1 == *output2);
- UpdateTransaction(input1, 0, CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ UpdateInput(input1.vin[0], CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
@@ -652,7 +652,7 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output2, input2, 0, true);
CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
BOOST_CHECK(*output1 == *output2);
- UpdateTransaction(input1, 0, CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ UpdateInput(input1.vin[0], CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);
CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
@@ -664,7 +664,7 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, true);
CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
BOOST_CHECK(*output1 == *output2);
- UpdateTransaction(input1, 0, CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ UpdateInput(input1.vin[0], CombineSignatures(output1->vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1->vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);
CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
}
diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp
index 06497667c3..2b00064cd0 100644
--- a/src/test/txvalidationcache_tests.cpp
+++ b/src/test/txvalidationcache_tests.cpp
@@ -315,7 +315,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign
SignatureData sigdata;
ProduceSignature(keystore, MutableTransactionSignatureCreator(&valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata);
- UpdateTransaction(valid_with_witness_tx, 0, sigdata);
+ UpdateInput(valid_with_witness_tx.vin[0], sigdata);
// This should be valid under all script flags.
ValidateCheckInputsForAllFlags(valid_with_witness_tx, 0, true);
@@ -343,7 +343,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
for (int i=0; i<2; ++i) {
SignatureData sigdata;
ProduceSignature(keystore, MutableTransactionSignatureCreator(&tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata);
- UpdateTransaction(tx, i, sigdata);
+ UpdateInput(tx.vin[i], sigdata);
}
// This should be valid under all script flags
diff --git a/src/util.cpp b/src/util.cpp
index 34483d95b0..48d64e3eec 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -459,9 +459,9 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
if (it != m_override_args.end()) {
if (it->second.size() > 0) {
for (const auto& ic : it->second) {
- fprintf(stderr, "warning: -includeconf cannot be used from commandline; ignoring -includeconf=%s\n", ic.c_str());
+ error += "-includeconf cannot be used from commandline; -includeconf=" + ic + "\n";
}
- m_override_args.erase(it);
+ return false;
}
}
return true;
@@ -849,11 +849,12 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
// if there is an -includeconf in the override args, but it is empty, that means the user
// passed '-noincludeconf' on the command line, in which case we should not include anything
if (m_override_args.count("-includeconf") == 0) {
+ std::string chain_id = GetChainName();
std::vector<std::string> includeconf(GetArgs("-includeconf"));
{
// We haven't set m_network yet (that happens in SelectParams()), so manually check
// for network.includeconf args.
- std::vector<std::string> includeconf_net(GetArgs(std::string("-") + GetChainName() + ".includeconf"));
+ std::vector<std::string> includeconf_net(GetArgs(std::string("-") + chain_id + ".includeconf"));
includeconf.insert(includeconf.end(), includeconf_net.begin(), includeconf_net.end());
}
@@ -862,7 +863,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
{
LOCK(cs_args);
m_config_args.erase("-includeconf");
- m_config_args.erase(std::string("-") + GetChainName() + ".includeconf");
+ m_config_args.erase(std::string("-") + chain_id + ".includeconf");
}
for (const std::string& to_include : includeconf) {
@@ -873,15 +874,22 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
}
LogPrintf("Included configuration file %s\n", to_include.c_str());
} else {
- fprintf(stderr, "Failed to include configuration file %s\n", to_include.c_str());
+ error = "Failed to include configuration file " + to_include;
+ return false;
}
}
// Warn about recursive -includeconf
includeconf = GetArgs("-includeconf");
{
- std::vector<std::string> includeconf_net(GetArgs(std::string("-") + GetChainName() + ".includeconf"));
+ std::vector<std::string> includeconf_net(GetArgs(std::string("-") + chain_id + ".includeconf"));
includeconf.insert(includeconf.end(), includeconf_net.begin(), includeconf_net.end());
+ std::string chain_id_final = GetChainName();
+ if (chain_id_final != chain_id) {
+ // Also warn about recursive includeconf for the chain that was specified in one of the includeconfs
+ includeconf_net = GetArgs(std::string("-") + chain_id_final + ".includeconf");
+ includeconf.insert(includeconf.end(), includeconf_net.begin(), includeconf_net.end());
+ }
}
for (const std::string& to_include : includeconf) {
fprintf(stderr, "warning: -includeconf cannot be used from included files; ignoring -includeconf=%s\n", to_include.c_str());
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 3987e8e70a..c3597aace8 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2609,7 +2609,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
// sign the new tx
int nIn = 0;
- for (const auto& input : tx.vin) {
+ for (auto& input : tx.vin) {
std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
return false;
@@ -2620,7 +2620,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
if (!ProduceSignature(*this, MutableTransactionSignatureCreator(&tx, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
return false;
}
- UpdateTransaction(tx, nIn, sigdata);
+ UpdateInput(input, sigdata);
nIn++;
}
return true;
@@ -3050,7 +3050,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
strFailReason = _("Signing transaction failed");
return false;
} else {
- UpdateTransaction(txNew, nIn, sigdata);
+ UpdateInput(txNew.vin.at(nIn), sigdata);
}
nIn++;
diff --git a/test/functional/feature_includeconf.py b/test/functional/feature_includeconf.py
index 9ccb89af43..9a7a0ca103 100755
--- a/test/functional/feature_includeconf.py
+++ b/test/functional/feature_includeconf.py
@@ -41,14 +41,9 @@ class IncludeConfTest(BitcoinTestFramework):
subversion = self.nodes[0].getnetworkinfo()["subversion"]
assert subversion.endswith("main; relative)/")
- self.log.info("-includeconf cannot be used as command-line arg. subversion should still end with 'main; relative)/'")
+ self.log.info("-includeconf cannot be used as command-line arg")
self.stop_node(0)
-
- self.start_node(0, extra_args=["-includeconf=relative2.conf"])
-
- subversion = self.nodes[0].getnetworkinfo()["subversion"]
- assert subversion.endswith("main; relative)/")
- self.stop_node(0, expected_stderr="warning: -includeconf cannot be used from commandline; ignoring -includeconf=relative2.conf")
+ self.nodes[0].assert_start_raises_init_error(extra_args=["-includeconf=relative2.conf"], expected_msg="Error parsing command line arguments: -includeconf cannot be used from commandline; -includeconf=relative2.conf")
self.log.info("-includeconf cannot be used recursively. subversion should end with 'main; relative)/'")
with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "a", encoding="utf8") as f:
@@ -59,8 +54,18 @@ class IncludeConfTest(BitcoinTestFramework):
assert subversion.endswith("main; relative)/")
self.stop_node(0, expected_stderr="warning: -includeconf cannot be used from included files; ignoring -includeconf=relative2.conf")
+ self.log.info("-includeconf cannot contain invalid arg")
+ with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f:
+ f.write("foo=bar\n")
+ self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Invalid configuration value foo")
+
+ self.log.info("-includeconf cannot be invalid path")
+ os.remove(os.path.join(self.options.tmpdir, "node0", "relative.conf"))
+ self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Failed to include configuration file relative.conf")
+
self.log.info("multiple -includeconf args can be used from the base config file. subversion should end with 'main; relative; relative2)/'")
with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f:
+ # Restore initial file contents
f.write("uacomment=relative\n")
with open(os.path.join(self.options.tmpdir, "node0", "bitcoin.conf"), "a", encoding='utf8') as f:
diff --git a/test/lint/lint-includes.sh b/test/lint/lint-includes.sh
index f54be46b52..2c3456b644 100755
--- a/test/lint/lint-includes.sh
+++ b/test/lint/lint-includes.sh
@@ -5,12 +5,14 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Check for duplicate includes.
+# Guard against accidental introduction of new Boost dependencies.
filter_suffix() {
git ls-files | grep -E "^src/.*\.${1}"'$' | grep -Ev "/(leveldb|secp256k1|univalue)/"
}
EXIT_CODE=0
+
for HEADER_FILE in $(filter_suffix h); do
DUPLICATE_INCLUDES_IN_HEADER_FILE=$(grep -E "^#include " < "${HEADER_FILE}" | sort | uniq -d)
if [[ ${DUPLICATE_INCLUDES_IN_HEADER_FILE} != "" ]]; then
@@ -20,6 +22,7 @@ for HEADER_FILE in $(filter_suffix h); do
EXIT_CODE=1
fi
done
+
for CPP_FILE in $(filter_suffix cpp); do
DUPLICATE_INCLUDES_IN_CPP_FILE=$(grep -E "^#include " < "${CPP_FILE}" | sort | uniq -d)
if [[ ${DUPLICATE_INCLUDES_IN_CPP_FILE} != "" ]]; then
@@ -29,4 +32,77 @@ for CPP_FILE in $(filter_suffix cpp); do
EXIT_CODE=1
fi
done
+
+INCLUDED_CPP_FILES=$(git grep -E "^#include [<\"][^>\"]+\.cpp[>\"]" -- "*.cpp" "*.h")
+if [[ ${INCLUDED_CPP_FILES} != "" ]]; then
+ echo "The following files #include .cpp files:"
+ echo "${INCLUDED_CPP_FILES}"
+ echo
+ EXIT_CODE=1
+fi
+
+EXPECTED_BOOST_INCLUDES=(
+ boost/algorithm/string.hpp
+ boost/algorithm/string/case_conv.hpp
+ boost/algorithm/string/classification.hpp
+ boost/algorithm/string/join.hpp
+ boost/algorithm/string/predicate.hpp
+ boost/algorithm/string/replace.hpp
+ boost/algorithm/string/split.hpp
+ boost/assign/std/vector.hpp
+ boost/bind.hpp
+ boost/chrono/chrono.hpp
+ boost/date_time/posix_time/posix_time.hpp
+ boost/filesystem.hpp
+ boost/filesystem/detail/utf8_codecvt_facet.hpp
+ boost/filesystem/fstream.hpp
+ boost/interprocess/sync/file_lock.hpp
+ boost/multi_index/hashed_index.hpp
+ boost/multi_index/ordered_index.hpp
+ boost/multi_index/sequenced_index.hpp
+ boost/multi_index_container.hpp
+ boost/optional.hpp
+ boost/preprocessor/cat.hpp
+ boost/preprocessor/stringize.hpp
+ boost/program_options/detail/config_file.hpp
+ boost/scoped_array.hpp
+ boost/signals2/connection.hpp
+ boost/signals2/last_value.hpp
+ boost/signals2/signal.hpp
+ boost/test/unit_test.hpp
+ boost/thread.hpp
+ boost/thread/condition_variable.hpp
+ boost/thread/mutex.hpp
+ boost/thread/thread.hpp
+ boost/variant.hpp
+ boost/variant/apply_visitor.hpp
+ boost/variant/static_visitor.hpp
+)
+
+for BOOST_INCLUDE in $(git grep '^#include <boost/' -- "*.cpp" "*.h" | cut -f2 -d: | cut -f2 -d'<' | cut -f1 -d'>' | sort -u); do
+ IS_EXPECTED_INCLUDE=0
+ for EXPECTED_BOOST_INCLUDE in "${EXPECTED_BOOST_INCLUDES[@]}"; do
+ if [[ "${BOOST_INCLUDE}" == "${EXPECTED_BOOST_INCLUDE}" ]]; then
+ IS_EXPECTED_INCLUDE=1
+ break
+ fi
+ done
+ if [[ ${IS_EXPECTED_INCLUDE} == 0 ]]; then
+ EXIT_CODE=1
+ echo "A new Boost dependency in the form of \"${BOOST_INCLUDE}\" appears to have been introduced:"
+ git grep "${BOOST_INCLUDE}" -- "*.cpp" "*.h"
+ echo
+ fi
+done
+
+for EXPECTED_BOOST_INCLUDE in "${EXPECTED_BOOST_INCLUDES[@]}"; do
+ if ! git grep -q "^#include <${EXPECTED_BOOST_INCLUDE}>" -- "*.cpp" "*.h"; then
+ echo "Good job! The Boost dependency \"${EXPECTED_BOOST_INCLUDE}\" is no longer used."
+ echo "Please remove it from EXPECTED_BOOST_INCLUDES in $0"
+ echo "to make sure this dependency is not accidentally reintroduced."
+ echo
+ EXIT_CODE=1
+ fi
+done
+
exit ${EXIT_CODE}
diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh
new file mode 100755
index 0000000000..3144f2c841
--- /dev/null
+++ b/test/lint/lint-locale-dependence.sh
@@ -0,0 +1,229 @@
+#!/bin/bash
+
+KNOWN_VIOLATIONS=(
+ "src/base58.cpp:.*isspace"
+ "src/bitcoin-tx.cpp.*stoul"
+ "src/bitcoin-tx.cpp.*trim_right"
+ "src/bitcoin-tx.cpp:.*atoi"
+ "src/core_read.cpp.*is_digit"
+ "src/dbwrapper.cpp.*stoul"
+ "src/dbwrapper.cpp:.*vsnprintf"
+ "src/httprpc.cpp.*trim"
+ "src/init.cpp:.*atoi"
+ "src/netbase.cpp.*to_lower"
+ "src/qt/rpcconsole.cpp:.*atoi"
+ "src/qt/rpcconsole.cpp:.*isdigit"
+ "src/rest.cpp:.*strtol"
+ "src/rpc/server.cpp.*to_upper"
+ "src/test/dbwrapper_tests.cpp:.*snprintf"
+ "src/test/getarg_tests.cpp.*split"
+ "src/torcontrol.cpp:.*atoi"
+ "src/torcontrol.cpp:.*strtol"
+ "src/uint256.cpp:.*isspace"
+ "src/uint256.cpp:.*tolower"
+ "src/util.cpp:.*atoi"
+ "src/util.cpp:.*fprintf"
+ "src/util.cpp:.*tolower"
+ "src/utilmoneystr.cpp:.*isdigit"
+ "src/utilmoneystr.cpp:.*isspace"
+ "src/utilstrencodings.cpp:.*atoi"
+ "src/utilstrencodings.cpp:.*isspace"
+ "src/utilstrencodings.cpp:.*strtol"
+ "src/utilstrencodings.cpp:.*strtoll"
+ "src/utilstrencodings.cpp:.*strtoul"
+ "src/utilstrencodings.cpp:.*strtoull"
+ "src/utilstrencodings.h:.*atoi"
+)
+
+REGEXP_IGNORE_EXTERNAL_DEPENDENCIES="^src/(crypto/ctaes/|leveldb/|secp256k1/|tinyformat.h|univalue/)"
+
+LOCALE_DEPENDENT_FUNCTIONS=(
+ alphasort # LC_COLLATE (via strcoll)
+ asctime # LC_TIME (directly)
+ asprintf # (via vasprintf)
+ atof # LC_NUMERIC (via strtod)
+ atoi # LC_NUMERIC (via strtol)
+ atol # LC_NUMERIC (via strtol)
+ atoll # (via strtoll)
+ atoq
+ btowc # LC_CTYPE (directly)
+ ctime # (via asctime or localtime)
+ dprintf # (via vdprintf)
+ fgetwc
+ fgetws
+ fold_case # boost::locale::fold_case
+ fprintf # (via vfprintf)
+ fputwc
+ fputws
+ fscanf # (via __vfscanf)
+ fwprintf # (via __vfwprintf)
+ getdate # via __getdate_r => isspace // __localtime_r
+ getwc
+ getwchar
+ is_digit # boost::algorithm::is_digit
+ is_space # boost::algorithm::is_space
+ isalnum # LC_CTYPE
+ isalpha # LC_CTYPE
+ isblank # LC_CTYPE
+ iscntrl # LC_CTYPE
+ isctype # LC_CTYPE
+ isdigit # LC_CTYPE
+ isgraph # LC_CTYPE
+ islower # LC_CTYPE
+ isprint # LC_CTYPE
+ ispunct # LC_CTYPE
+ isspace # LC_CTYPE
+ isupper # LC_CTYPE
+ iswalnum # LC_CTYPE
+ iswalpha # LC_CTYPE
+ iswblank # LC_CTYPE
+ iswcntrl # LC_CTYPE
+ iswctype # LC_CTYPE
+ iswdigit # LC_CTYPE
+ iswgraph # LC_CTYPE
+ iswlower # LC_CTYPE
+ iswprint # LC_CTYPE
+ iswpunct # LC_CTYPE
+ iswspace # LC_CTYPE
+ iswupper # LC_CTYPE
+ iswxdigit # LC_CTYPE
+ isxdigit # LC_CTYPE
+ localeconv # LC_NUMERIC + LC_MONETARY
+ mblen # LC_CTYPE
+ mbrlen
+ mbrtowc
+ mbsinit
+ mbsnrtowcs
+ mbsrtowcs
+ mbstowcs # LC_CTYPE
+ mbtowc # LC_CTYPE
+ mktime
+ normalize # boost::locale::normalize
+# printf # LC_NUMERIC
+ putwc
+ putwchar
+ scanf # LC_NUMERIC
+ setlocale
+ snprintf
+ sprintf
+ sscanf
+ stod
+ stof
+ stoi
+ stol
+ stold
+ stoll
+ stoul
+ stoull
+ strcasecmp
+ strcasestr
+ strcoll # LC_COLLATE
+# strerror
+ strfmon
+ strftime # LC_TIME
+ strncasecmp
+ strptime
+ strtod # LC_NUMERIC
+ strtof
+ strtoimax
+ strtol # LC_NUMERIC
+ strtold
+ strtoll
+ strtoq
+ strtoul # LC_NUMERIC
+ strtoull
+ strtoumax
+ strtouq
+ strxfrm # LC_COLLATE
+ swprintf
+ to_lower # boost::locale::to_lower
+ to_title # boost::locale::to_title
+ to_upper # boost::locale::to_upper
+ tolower # LC_CTYPE
+ toupper # LC_CTYPE
+ towctrans
+ towlower # LC_CTYPE
+ towupper # LC_CTYPE
+ trim # boost::algorithm::trim
+ trim_left # boost::algorithm::trim_left
+ trim_right # boost::algorithm::trim_right
+ ungetwc
+ vasprintf
+ vdprintf
+ versionsort
+ vfprintf
+ vfscanf
+ vfwprintf
+ vprintf
+ vscanf
+ vsnprintf
+ vsprintf
+ vsscanf
+ vswprintf
+ vwprintf
+ wcrtomb
+ wcscasecmp
+ wcscoll # LC_COLLATE
+ wcsftime # LC_TIME
+ wcsncasecmp
+ wcsnrtombs
+ wcsrtombs
+ wcstod # LC_NUMERIC
+ wcstof
+ wcstoimax
+ wcstol # LC_NUMERIC
+ wcstold
+ wcstoll
+ wcstombs # LC_CTYPE
+ wcstoul # LC_NUMERIC
+ wcstoull
+ wcstoumax
+ wcswidth
+ wcsxfrm # LC_COLLATE
+ wctob
+ wctomb # LC_CTYPE
+ wctrans
+ wctype
+ wcwidth
+ wprintf
+)
+
+function join_array {
+ local IFS="$1"
+ shift
+ echo "$*"
+}
+
+REGEXP_IGNORE_KNOWN_VIOLATIONS=$(join_array "|" "${KNOWN_VIOLATIONS[@]}")
+
+# Invoke "git grep" only once in order to minimize run-time
+REGEXP_LOCALE_DEPENDENT_FUNCTIONS=$(join_array "|" "${LOCALE_DEPENDENT_FUNCTIONS[@]}")
+GIT_GREP_OUTPUT=$(git grep -E "[^a-zA-Z0-9_\`'\"<>](${REGEXP_LOCALE_DEPENDENT_FUNCTIONS}(|_r|_s))[^a-zA-Z0-9_\`'\"<>]" -- "*.cpp" "*.h")
+
+EXIT_CODE=0
+for LOCALE_DEPENDENT_FUNCTION in "${LOCALE_DEPENDENT_FUNCTIONS[@]}"; do
+ MATCHES=$(grep -E "[^a-zA-Z0-9_\`'\"<>]${LOCALE_DEPENDENT_FUNCTION}(|_r|_s)[^a-zA-Z0-9_\`'\"<>]" <<< "${GIT_GREP_OUTPUT}" | \
+ grep -vE "\.(c|cpp|h):\s*(//|\*|/\*|\").*${LOCALE_DEPENDENT_FUNCTION}" | \
+ grep -vE 'fprintf\(.*(stdout|stderr)')
+ if [[ ${REGEXP_IGNORE_EXTERNAL_DEPENDENCIES} != "" ]]; then
+ MATCHES=$(grep -vE "${REGEXP_IGNORE_EXTERNAL_DEPENDENCIES}" <<< "${MATCHES}")
+ fi
+ if [[ ${REGEXP_IGNORE_KNOWN_VIOLATIONS} != "" ]]; then
+ MATCHES=$(grep -vE "${REGEXP_IGNORE_KNOWN_VIOLATIONS}" <<< "${MATCHES}")
+ fi
+ if [[ ${MATCHES} != "" ]]; then
+ echo "The locale dependent function ${LOCALE_DEPENDENT_FUNCTION}(...) appears to be used:"
+ echo "${MATCHES}"
+ echo
+ EXIT_CODE=1
+ fi
+done
+if [[ ${EXIT_CODE} != 0 ]]; then
+ echo "Unnecessary locale dependence can cause bugs that are very"
+ echo "tricky to isolate and fix. Please avoid using locale dependent"
+ echo "functions if possible."
+ echo
+ echo "Advice not applicable in this specific case? Add an exception"
+ echo "by updating the ignore list in $0"
+fi
+exit ${EXIT_CODE}