- `Hashing algorithm for blocks is Keccak (sha-3).`
- `The master branch is regularly built (see` [doc/build-*.md](https://github.com/BitgesellOfficial/bitgesell/tree/master/doc) `for instructions) and tested, but is not guaranteed to be completely stable.`
- [tags](https://github.com/BitgesellOfficial/bitgesell/tags) `are created regularly to indicate new official, stable release versions of BGL Core.`
-
-
-### Built With
-
-* [C++](#)
-* [C](#)
-* [Python](#)
-* [SourcePawn](#)
-* [M4](#)
-* [Shell](#)
-
-
-
-## Getting Started
-
-Visit official website: [click here](https://bitgesell.ca/)
+* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
+
+Implementation details
+----------------------
+
+* General
+ * No runtime heap allocation.
+ * Extensive testing infrastructure.
+ * Structured to facilitate review and analysis.
+ * Intended to be portable to any system with a C89 compiler and uint64_t support.
+ * No use of floating types.
+ * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
+* Field operations
+ * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
+ * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys).
+ * Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan).
+ * This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community.
+* Scalar operations
+ * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
+ * Using 4 64-bit limbs (relying on __int128 support in the compiler).
+ * Using 8 32-bit limbs.
+* Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman).
+* Group operations
+ * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
+ * Use addition between points in Jacobian and affine coordinates where possible.
+ * Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
+ * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
+* Point multiplication for verification (a*P + b*G).
+ * Use wNAF notation for point multiplicands.
+ * Use a much larger window for multiples of G, using precomputed multiples.
+ * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
+ * Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
+* Point multiplication for signing
+ * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
+ * Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)
+ * Access the table with branch-free conditional moves so memory access is uniform.
+ * No data-dependent branches
+ * Optional runtime blinding which attempts to frustrate differential power analysis.
+ * The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.
+
+Build steps
+-----------
+
+libsecp256k1 is built using autotools:
$ ./autogen.sh
$ ./configure
@@ -109,6 +113,16 @@ Visit official website: [click here](https://bitgesell.ca/)
$ make check # run the test suite
$ sudo make install # optional
+To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags.
+
+Usage examples
+-----------
+ Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`.
+ * [ECDSA example](examples/ecdsa.c)
+ * [Schnorr signatures example](examples/schnorr.c)
+ * [Deriving a shared secret (ECDH) example](examples/ecdh.c)
+ To compile the Schnorr signature and ECDH examples, you also need to configure with `--enable-module-schnorrsig` and `--enable-module-ecdh`.
+
Test coverage
-----------
diff --git a/ci/linux-debian.Dockerfile b/ci/linux-debian.Dockerfile
index fdba12aa00..5cccbb5565 100644
--- a/ci/linux-debian.Dockerfile
+++ b/ci/linux-debian.Dockerfile
@@ -19,7 +19,8 @@ RUN apt-get install --no-install-recommends --no-upgrade -y \
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \
gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 \
gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
- wine gcc-mingw-w64-x86-64
+ wine gcc-mingw-w64-x86-64 \
+ sagemath
# Run a dummy command in wine to make it set up configuration
RUN wine64-stable xcopy || true
diff --git a/configure.ac b/configure.ac
index 52403a2b4f..1597ff7e59 100755
--- a/configure.ac
+++ b/configure.ac
@@ -1,15 +1,24 @@
-AC_PREREQ([2.69])
-define(_CLIENT_VERSION_MAJOR, 23)
-define(_CLIENT_VERSION_MINOR, 99)
-define(_CLIENT_VERSION_BUILD, 0)
-define(_CLIENT_VERSION_RC, 0)
-define(_CLIENT_VERSION_IS_RELEASE, false)
-define(_COPYRIGHT_YEAR, 2022)
-define(_COPYRIGHT_HOLDERS,[The %s developers])
-define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[BGL Core]])
-AC_INIT([BGL Core],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_BUILD)m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/bitcoin/bitcoin/issues],[BGL],[https://bitcoincore.org/])
-AC_CONFIG_SRCDIR([src/validation.cpp])
-AC_CONFIG_HEADERS([src/config/BGL-config.h])
+AC_PREREQ([2.60])
+
+# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
+# the API. All changes in experimental modules are treated as
+# backwards-compatible and therefore at most increase the minor version.
+define(_PKG_VERSION_MAJOR, 0)
+define(_PKG_VERSION_MINOR, 1)
+define(_PKG_VERSION_BUILD, 0)
+define(_PKG_VERSION_IS_RELEASE, false)
+
+# The library version is based on libtool versioning of the ABI. The set of
+# rules for updating the version can be found here:
+# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+# All changes in experimental modules are treated as if they don't affect the
+# interface and therefore only increase the revision.
+define(_LIB_VERSION_CURRENT, 0)
+define(_LIB_VERSION_REVISION, 0)
+define(_LIB_VERSION_AGE, 0)
+
+AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_BUILD)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-pre]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1])
+
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([build-aux/m4])
@@ -37,20 +46,26 @@ if test "${ARFLAGS+set}" != "set"; then
fi
AC_CANONICAL_HOST
+AH_TOP([#ifndef LIBSECP256K1_CONFIG_H])
+AH_TOP([#define LIBSECP256K1_CONFIG_H])
+AH_BOTTOM([#endif /*LIBSECP256K1_CONFIG_H*/])
-LT_INIT([win32-dll])
-
-dnl Automake init set-up and checks
-AM_INIT_AUTOMAKE([1.13 no-define subdir-objects foreign])
+# Require Automake 1.11.2 for AM_PROG_AR
+AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
-AM_MAINTAINER_MODE([enable])
+# Make the compilation flags quiet unless V=1 is used.
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-AM_PROG_CC_C_O
-AC_PROG_CC_C89
+AC_PROG_CC
if test x"$ac_cv_prog_cc_c89" = x"no"; then
AC_MSG_ERROR([c89 compiler support required])
fi
AM_PROG_AS
+AM_PROG_AR
+
+LT_INIT([win32-dll])
+
+build_windows=no
case $host_os in
*darwin*)
@@ -75,6 +90,9 @@ case $host_os in
fi
fi
;;
+ cygwin*|mingw*)
+ build_windows=yes
+ ;;
esac
AC_ARG_WITH([seccomp],
@@ -148,234 +166,100 @@ AC_ARG_WITH([sqlite],
[use_sqlite=$withval],
[use_sqlite=auto])
-AC_ARG_WITH([bdb],
- [AS_HELP_STRING([--without-bdb],
- [disable bdb wallet support (default is enabled if wallet is enabled)])],
- [use_bdb=$withval],
- [use_bdb=auto])
-
-AC_ARG_ENABLE([usdt],
- [AS_HELP_STRING([--enable-usdt],
- [enable tracepoints for Userspace, Statically Defined Tracing (default is yes if sys/sdt.h is found)])],
- [use_usdt=$enableval],
- [use_usdt=yes])
-
-AC_ARG_WITH([miniupnpc],
- [AS_HELP_STRING([--with-miniupnpc],
- [enable UPNP (default is yes if libminiupnpc is found)])],
- [use_upnp=$withval],
- [use_upnp=auto])
-
-AC_ARG_ENABLE([upnp-default],
- [AS_HELP_STRING([--enable-upnp-default],
- [if UPNP is enabled, turn it on at startup (default is no)])],
- [use_upnp_default=$enableval],
- [use_upnp_default=no])
-
-AC_ARG_WITH([natpmp],
- [AS_HELP_STRING([--with-natpmp],
- [enable NAT-PMP (default is yes if libnatpmp is found)])],
- [use_natpmp=$withval],
- [use_natpmp=auto])
-
-AC_ARG_ENABLE([natpmp-default],
- [AS_HELP_STRING([--enable-natpmp-default],
- [if NAT-PMP is enabled, turn it on at startup (default is no)])],
- [use_natpmp_default=$enableval],
- [use_natpmp_default=no])
-
-AC_ARG_ENABLE(tests,
- AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]),
- [use_tests=$enableval],
- [use_tests=yes])
-
-AC_ARG_ENABLE(gui-tests,
- AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]),
- [use_gui_tests=$enableval],
- [use_gui_tests=$use_tests])
-
-AC_ARG_ENABLE(bench,
- AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]),
- [use_bench=$enableval],
- [use_bench=yes])
-
-AC_ARG_ENABLE([extended-functional-tests],
- AS_HELP_STRING([--enable-extended-functional-tests],[enable expensive functional tests when using lcov (default no)]),
- [use_extended_functional_tests=$enableval],
- [use_extended_functional_tests=no])
-
-AC_ARG_ENABLE([fuzz],
- AS_HELP_STRING([--enable-fuzz],
- [build for fuzzing (default no). enabling this will disable all other targets and override --{enable,disable}-fuzz-binary]),
- [enable_fuzz=$enableval],
- [enable_fuzz=no])
-
-AC_ARG_ENABLE([fuzz-binary],
- AS_HELP_STRING([--enable-fuzz-binary],
- [enable building of fuzz binary (default yes).]),
- [enable_fuzz_binary=$enableval],
- [enable_fuzz_binary=yes])
-
-AC_ARG_WITH([qrencode],
- [AS_HELP_STRING([--with-qrencode],
- [enable QR code support (default is yes if qt is enabled and libqrencode is found)])],
- [use_qr=$withval],
- [use_qr=auto])
-
-AC_ARG_ENABLE([hardening],
- [AS_HELP_STRING([--disable-hardening],
- [do not attempt to harden the resulting executables (default is to harden when possible)])],
- [use_hardening=$enableval],
- [use_hardening=auto])
-
-AC_ARG_ENABLE([reduce-exports],
- [AS_HELP_STRING([--enable-reduce-exports],
- [attempt to reduce exported symbols in the resulting executables (default is no)])],
- [use_reduce_exports=$enableval],
- [use_reduce_exports=no])
-
-AC_ARG_ENABLE([ccache],
- [AS_HELP_STRING([--disable-ccache],
- [do not use ccache for building (default is to use if found)])],
- [use_ccache=$enableval],
- [use_ccache=auto])
-
-dnl Suppress warnings from external headers (e.g. Boost, Qt).
-dnl May be useful if warnings from external headers clutter the build output
-dnl too much, so that it becomes difficult to spot Bitgesell Core warnings
-dnl or if they cause a build failure with --enable-werror.
-AC_ARG_ENABLE([suppress-external-warnings],
- [AS_HELP_STRING([--enable-suppress-external-warnings],
- [Suppress warnings from external headers (default is no)])],
- [suppress_external_warnings=$enableval],
- [suppress_external_warnings=no])
-
-AC_ARG_ENABLE([lcov],
- [AS_HELP_STRING([--enable-lcov],
- [enable lcov testing (default is no)])],
- [use_lcov=$enableval],
- [use_lcov=no])
-
-AC_ARG_ENABLE([lcov-branch-coverage],
- [AS_HELP_STRING([--enable-lcov-branch-coverage],
- [enable lcov testing branch coverage (default is no)])],
- [use_lcov_branch=yes],
- [use_lcov_branch=no])
-
-AC_ARG_ENABLE([threadlocal],
- [AS_HELP_STRING([--enable-threadlocal],
- [enable features that depend on the c++ thread_local keyword (currently just thread names in debug logs). (default is to enable if there is platform support)])],
- [use_thread_local=$enableval],
- [use_thread_local=auto])
-
-AC_ARG_ENABLE([asm],
- [AS_HELP_STRING([--disable-asm],
- [disable assembly routines (enabled by default)])],
- [use_asm=$enableval],
- [use_asm=yes])
+# In dev mode, we enable all binaries and modules by default but individual options can still be overridden explicitly.
+# Check for dev mode first because SECP_SET_DEFAULT needs enable_dev_mode set.
+AC_ARG_ENABLE(dev_mode, [], [],
+ [enable_dev_mode=no])
-if test "$use_asm" = "yes"; then
- AC_DEFINE([USE_ASM], [1], [Define this symbol to build in assembly routines])
-fi
+AC_ARG_ENABLE(benchmark,
+ AS_HELP_STRING([--enable-benchmark],[compile benchmark [default=yes]]), [],
+ [SECP_SET_DEFAULT([enable_benchmark], [yes], [yes])])
-AC_ARG_ENABLE([zmq],
- [AS_HELP_STRING([--disable-zmq],
- [disable ZMQ notifications])],
- [use_zmq=$enableval],
- [use_zmq=yes])
-
-AC_ARG_WITH([libmultiprocess],
- [AS_HELP_STRING([--with-libmultiprocess=yes|no|auto],
- [Build with libmultiprocess library. (default: auto, i.e. detect with pkg-config)])],
- [with_libmultiprocess=$withval],
- [with_libmultiprocess=auto])
-
-AC_ARG_WITH([mpgen],
- [AS_HELP_STRING([--with-mpgen=yes|no|auto|PREFIX],
- [Build with libmultiprocess codegen tool. Useful to specify different libmultiprocess host system library and build system codegen tool prefixes when cross-compiling (default is host system libmultiprocess prefix)])],
- [with_mpgen=$withval],
- [with_mpgen=auto])
-
-AC_ARG_ENABLE([multiprocess],
- [AS_HELP_STRING([--enable-multiprocess],
- [build multiprocess BGL-node, BGL-wallet, and BGL-gui executables in addition to monolithic BGLd and BGL-qt executables. Requires libmultiprocess library. Experimental (default is no)])],
- [enable_multiprocess=$enableval],
- [enable_multiprocess=no])
-
-AC_ARG_ENABLE(man,
- [AS_HELP_STRING([--disable-man],
- [do not install man pages (default is to install)])],,
- enable_man=yes)
-AM_CONDITIONAL([ENABLE_MAN], [test "$enable_man" != "no"])
-
-dnl Enable debug
-AC_ARG_ENABLE([debug],
- [AS_HELP_STRING([--enable-debug],
- [use compiler flags and macros suited for debugging (default is no)])],
- [enable_debug=$enableval],
- [enable_debug=no])
-
-dnl Enable different -fsanitize options
-AC_ARG_WITH([sanitizers],
- [AS_HELP_STRING([--with-sanitizers],
- [comma separated list of extra sanitizers to build with (default is none enabled)])],
- [use_sanitizers=$withval])
-
-dnl Enable gprof profiling
-AC_ARG_ENABLE([gprof],
- [AS_HELP_STRING([--enable-gprof],
- [use gprof profiling compiler flags (default is no)])],
- [enable_gprof=$enableval],
- [enable_gprof=no])
-
-dnl Turn warnings into errors
-AC_ARG_ENABLE([werror],
- [AS_HELP_STRING([--enable-werror],
- [Treat compiler warnings as errors (default is no)])],
- [enable_werror=$enableval],
- [enable_werror=no])
-
-AC_ARG_ENABLE([external-signer],
- [AS_HELP_STRING([--enable-external-signer],[compile external signer support (default is yes, requires Boost::Process)])],
- [use_external_signer=$enableval],
- [use_external_signer=auto])
-
-AC_ARG_ENABLE([lto],
- [AS_HELP_STRING([--enable-lto],[build using LTO (default is no)])],
- [enable_lto=$enableval],
- [enable_lto=no])
-
-AC_LANG_PUSH([C++])
-
-dnl Check for a flag to turn compiler warnings into errors. This is helpful for checks which may
-dnl appear to succeed because by default they merely emit warnings when they fail.
-dnl
-dnl Note that this is not necessarily a check to see if -Werror is supported, but rather to see if
-dnl a compile with -Werror can succeed. This is important because the compiler may already be
-dnl warning about something unrelated, for example about some path issue. If that is the case,
-dnl -Werror cannot be used because all of those warnings would be turned into errors.
-AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAG_WERROR="-Werror"], [CXXFLAG_WERROR=""])
-
-dnl Check for a flag to turn linker warnings into errors. When flags are passed to linkers via the
-dnl compiler driver using a -Wl,-foo flag, linker warnings may be swallowed rather than bubbling up.
-dnl See note above, the same applies here as well.
-dnl
-dnl LDFLAG_WERROR Should only be used when testing -Wl,*
-case $host in
- *darwin*)
- AX_CHECK_LINK_FLAG([-Wl,-fatal_warnings], [LDFLAG_WERROR="-Wl,-fatal_warnings"], [LDFLAG_WERROR=""])
- ;;
- *)
- AX_CHECK_LINK_FLAG([-Wl,--fatal-warnings], [LDFLAG_WERROR="-Wl,--fatal-warnings"], [LDFLAG_WERROR=""])
- ;;
-esac
+AC_ARG_ENABLE(coverage,
+ AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_coverage], [no], [no])])
-if test "$enable_debug" = "yes"; then
- dnl If debugging is enabled, and the user hasn't overriden CXXFLAGS, clear
- dnl them, to prevent autoconfs "-g -O2" being added. Otherwise we'd end up
- dnl with "-O0 -g3 -g -O2".
- if test "$CXXFLAGS_overridden" = "no"; then
- CXXFLAGS=""
+AC_ARG_ENABLE(tests,
+ AS_HELP_STRING([--enable-tests],[compile tests [default=yes]]), [],
+ [SECP_SET_DEFAULT([enable_tests], [yes], [yes])])
+
+AC_ARG_ENABLE(experimental,
+ AS_HELP_STRING([--enable-experimental],[allow experimental configure options [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_experimental], [no], [yes])])
+
+AC_ARG_ENABLE(exhaustive_tests,
+ AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests [default=yes]]), [],
+ [SECP_SET_DEFAULT([enable_exhaustive_tests], [yes], [yes])])
+
+AC_ARG_ENABLE(examples,
+ AS_HELP_STRING([--enable-examples],[compile the examples [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_examples], [no], [yes])])
+
+AC_ARG_ENABLE(module_ecdh,
+ AS_HELP_STRING([--enable-module-ecdh],[enable ECDH module [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_module_ecdh], [no], [yes])])
+
+AC_ARG_ENABLE(module_recovery,
+ AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_module_recovery], [no], [yes])])
+
+AC_ARG_ENABLE(module_extrakeys,
+ AS_HELP_STRING([--enable-module-extrakeys],[enable extrakeys module [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_module_extrakeys], [no], [yes])])
+
+AC_ARG_ENABLE(module_schnorrsig,
+ AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_module_schnorrsig], [no], [yes])])
+
+AC_ARG_ENABLE(external_default_callbacks,
+ AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [],
+ [SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])])
+
+# Test-only override of the (autodetected by the C code) "widemul" setting.
+# Legal values are int64 (for [u]int64_t), int128 (for [unsigned] __int128), and auto (the default).
+AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_widemul=auto])
+
+AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto],
+[assembly optimizations to use (experimental: arm) [default=auto]])],[req_asm=$withval], [req_asm=auto])
+
+AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE|auto],
+[window size for ecmult precomputation for verification, specified as integer in range [2..24].]
+[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.]
+[The table will store 2^(SIZE-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
+[A window size larger than 15 will require you delete the prebuilt precomputed_ecmult.c file so that it can be rebuilt.]
+[For very large window sizes, use "make -j 1" to reduce memory use during compilation.]
+["auto" is a reasonable setting for desktop machines (currently 15). [default=auto]]
+)],
+[req_ecmult_window=$withval], [req_ecmult_window=auto])
+
+AC_ARG_WITH([ecmult-gen-precision], [AS_HELP_STRING([--with-ecmult-gen-precision=2|4|8|auto],
+[Precision bits to tune the precomputed table size for signing.]
+[The size of the table is 32kB for 2 bits, 64kB for 4 bits, 512kB for 8 bits of precision.]
+[A larger table size usually results in possible faster signing.]
+["auto" is a reasonable setting for desktop machines (currently 4). [default=auto]]
+)],
+[req_ecmult_gen_precision=$withval], [req_ecmult_gen_precision=auto])
+
+AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind=yes|no|auto],
+[Build with extra checks for running inside Valgrind [default=auto]]
+)],
+[req_valgrind=$withval], [req_valgrind=auto])
+
+###
+### Handle config options (except for modules)
+###
+
+if test x"$req_valgrind" = x"no"; then
+ enable_valgrind=no
+else
+ SECP_VALGRIND_CHECK
+ if test x"$has_valgrind" != x"yes"; then
+ if test x"$req_valgrind" = x"yes"; then
+ AC_MSG_ERROR([Valgrind support explicitly requested but valgrind/memcheck.h header not available])
+ fi
+ enable_valgrind=no
+ else
+ enable_valgrind=yes
fi
dnl Disable all optimizations
@@ -961,154 +845,25 @@ if test "$use_hardening" != "no"; then
esac
fi
-dnl These flags are specific to ld64, and may cause issues with other linkers.
-dnl For example: GNU ld will interpret -dead_strip as -de and then try and use
-dnl "ad_strip" as the symbol for the entry point.
-if test "$TARGET_OS" = "darwin"; then
- AX_CHECK_LINK_FLAG([-Wl,-dead_strip], [CORE_LDFLAGS="$CORE_LDFLAGS -Wl,-dead_strip"], [], [$LDFLAG_WERROR])
- AX_CHECK_LINK_FLAG([-Wl,-dead_strip_dylibs], [CORE_LDFLAGS="$CORE_LDFLAGS -Wl,-dead_strip_dylibs"], [], [$LDFLAG_WERROR])
- AX_CHECK_LINK_FLAG([-Wl,-bind_at_load], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-bind_at_load"], [], [$LDFLAG_WERROR])
-fi
-
-AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h])
-
-AC_CHECK_DECLS([getifaddrs, freeifaddrs],[CHECK_SOCKET],,
- [#include
- #include ]
-)
-
-dnl These are used for daemonization in BGLd
-AC_CHECK_DECLS([fork])
-AC_CHECK_DECLS([setsid])
-
-AC_CHECK_DECLS([pipe2])
-
-AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
- [#if HAVE_ENDIAN_H
- #include
- #elif HAVE_SYS_ENDIAN_H
- #include
- #endif])
-
-AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
- [#if HAVE_BYTESWAP_H
- #include
- #endif])
-
-AC_MSG_CHECKING([for __builtin_clzl])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[
- (void) __builtin_clzl(0);
- ]])],
- [ AC_MSG_RESULT([yes]); have_clzl=yes; AC_DEFINE([HAVE_BUILTIN_CLZL], [1], [Define this symbol if you have __builtin_clzl])],
- [ AC_MSG_RESULT([no]); have_clzl=no;]
-)
-
-AC_MSG_CHECKING([for __builtin_clzll])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[
- (void) __builtin_clzll(0);
- ]])],
- [ AC_MSG_RESULT([yes]); have_clzll=yes; AC_DEFINE([HAVE_BUILTIN_CLZLL], [1], [Define this symbol if you have __builtin_clzll])],
- [ AC_MSG_RESULT([no]); have_clzll=no;]
-)
-
-dnl Check for malloc_info (for memory statistics information in getmemoryinfo)
-AC_MSG_CHECKING([for getmemoryinfo])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],
- [[ int f = malloc_info(0, NULL); ]])],
- [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_MALLOC_INFO], [1], [Define this symbol if you have malloc_info]) ],
- [ AC_MSG_RESULT([no])]
-)
-
-dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas)
-AC_MSG_CHECKING([for mallopt M_ARENA_MAX])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],
- [[ mallopt(M_ARENA_MAX, 1); ]])],
- [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_MALLOPT_ARENA_MAX], [1], [Define this symbol if you have mallopt with M_ARENA_MAX]) ],
- [ AC_MSG_RESULT([no])]
-)
-
-dnl Check for posix_fallocate
-AC_MSG_CHECKING([for posix_fallocate])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
- // same as in src/util/system.cpp
- #ifdef __linux__
- #ifdef _POSIX_C_SOURCE
- #undef _POSIX_C_SOURCE
- #endif
- #define _POSIX_C_SOURCE 200112L
- #endif // __linux__
- #include ]],
- [[ int f = posix_fallocate(0, 0, 0); ]])],
- [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_POSIX_FALLOCATE], [1], [Define this symbol if you have posix_fallocate]) ],
- [ AC_MSG_RESULT([no])]
-)
-
-AC_MSG_CHECKING([for default visibility attribute])
-AC_COMPILE_IFELSE([AC_LANG_SOURCE([
- int foo(void) __attribute__((visibility("default")));
- int main(){}
- ])],
- [
- AC_DEFINE([HAVE_DEFAULT_VISIBILITY_ATTRIBUTE], [1], [Define if the visibility attribute is supported.])
- AC_MSG_RESULT([yes])
- ],
- [
- AC_MSG_RESULT([no])
- if test "$use_reduce_exports" = "yes"; then
- AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.])
- fi
- ]
-)
-
-AC_MSG_CHECKING([for dllexport attribute])
-AC_COMPILE_IFELSE([AC_LANG_SOURCE([
- __declspec(dllexport) int foo(void);
- int main(){}
- ])],
- [
- AC_DEFINE([HAVE_DLLEXPORT_ATTRIBUTE], [1], [Define if the dllexport attribute is supported.])
- AC_MSG_RESULT([yes])
- ],
- [AC_MSG_RESULT([no])]
-)
+# Select assembly optimization
+enable_external_asm=no
+
+case $set_asm in
+x86_64)
+ AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations])
+ ;;
+arm)
+ enable_external_asm=yes
+ ;;
+no)
+ ;;
+*)
+ AC_MSG_ERROR([invalid assembly optimizations])
+ ;;
+esac
-if test "$use_thread_local" = "yes" || test "$use_thread_local" = "auto"; then
- TEMP_LDFLAGS="$LDFLAGS"
- LDFLAGS="$TEMP_LDFLAGS $PTHREAD_CFLAGS"
- AC_MSG_CHECKING([for thread_local support])
- AC_LINK_IFELSE([AC_LANG_SOURCE([
- #include
- static thread_local int foo = 0;
- static void run_thread() { foo++;}
- int main(){
- for(int i = 0; i < 10; i++) { std::thread(run_thread).detach();}
- return foo;
- }
- ])],
- [
- case $host in
- *mingw*)
- dnl mingw32's implementation of thread_local has also been shown to behave
- dnl erroneously under concurrent usage; see:
- dnl https://gist.github.com/jamesob/fe9a872051a88b2025b1aa37bfa98605
- AC_MSG_RESULT([no])
- ;;
- *freebsd*)
- dnl FreeBSD's implementation of thread_local is also buggy (per
- dnl https://groups.google.com/d/msg/bsdmailinglist/22ncTZAbDp4/Dii_pII5AwAJ)
- AC_MSG_RESULT([no])
- ;;
- *)
- AC_DEFINE([HAVE_THREAD_LOCAL], [1], [Define if thread_local is supported.])
- AC_MSG_RESULT([yes])
- ;;
- esac
- ],
- [
- AC_MSG_RESULT([no])
- ]
- )
- LDFLAGS="$TEMP_LDFLAGS"
+if test x"$enable_external_asm" = x"yes"; then
+ AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used])
fi
dnl check for gmtime_r(), fallback to gmtime_s() if that is unavailable
@@ -1557,13 +1312,8 @@ else
AC_DEFINE_UNQUOTED([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions])
fi
-if test "$use_zmq" = "yes"; then
- dnl Assume libzmq was built for static linking
- case $host in
- *mingw*)
- ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC"
- ;;
- esac
+if test x"$enable_external_default_callbacks" = x"yes"; then
+ AC_DEFINE(USE_EXTERNAL_DEFAULT_CALLBACKS, 1, [Define this symbol if an external implementation of the default callbacks is used])
fi
dnl libmultiprocess library check
@@ -1578,201 +1328,14 @@ elif test "$with_libmultiprocess" != "no"; then
AC_MSG_ERROR([--with-libmultiprocess=$with_libmultiprocess value is not yes, auto, or no])
fi
-dnl Enable multiprocess check
-
-if test "$enable_multiprocess" = "yes"; then
- if test "$libmultiprocess_found" != "yes"; then
- AC_MSG_ERROR([--enable-multiprocess=yes option specified but libmultiprocess library was not found. May need to install libmultiprocess library, or specify install path with PKG_CONFIG_PATH environment variable. Running 'pkg-config --debug libmultiprocess' may be helpful for debugging.])
- fi
- build_multiprocess=yes
-elif test "$enable_multiprocess" = "auto"; then
- build_multiprocess=$libmultiprocess_found
+if test x"$enable_experimental" = x"yes"; then
+ AC_MSG_NOTICE([******])
+ AC_MSG_NOTICE([WARNING: experimental build])
+ AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.])
+ AC_MSG_NOTICE([******])
else
- build_multiprocess=no
-fi
-
-AM_CONDITIONAL([BUILD_MULTIPROCESS], [test "$build_multiprocess" = "yes"])
-AM_CONDITIONAL([BUILD_BGL_NODE], [test "$build_multiprocess" = "yes"])
-AM_CONDITIONAL([BUILD_BGL_GUI], [test "$build_multiprocess" = "yes"])
-
-dnl codegen tools check
-
-if test "$build_multiprocess" != "no"; then
- if test "$with_mpgen" = "yes" || test "$with_mpgen" = "auto"; then
- MPGEN_PREFIX="$libmultiprocess_prefix"
- elif test "$with_mpgen" != "no"; then
- MPGEN_PREFIX="$with_mpgen";
- fi
- AC_SUBST(MPGEN_PREFIX)
-fi
-
-AC_MSG_CHECKING([whether to build BGLd])
-AM_CONDITIONAL([BUILD_BGLD], [test $build_BGLd = "yes"])
-AC_MSG_RESULT($build_BGLd)
-
-AC_MSG_CHECKING([whether to build BGL-cli])
-AM_CONDITIONAL([BUILD_BGL_CLI], [test $build_BGL_cli = "yes"])
-AC_MSG_RESULT($build_BGL_cli)
-
-AC_MSG_CHECKING([whether to build BGL-tx])
-AM_CONDITIONAL([BUILD_BGL_TX], [test $build_BGL_tx = "yes"])
-AC_MSG_RESULT($build_BGL_tx)
-
-AC_MSG_CHECKING([whether to build BGL-wallet])
-AM_CONDITIONAL([BUILD_BGL_WALLET], [test $build_BGL_wallet = "yes"])
-AC_MSG_RESULT($build_BGL_wallet)
-
-AC_MSG_CHECKING([whether to build BGL-util])
-AM_CONDITIONAL([BUILD_BGL_UTIL], [test $build_BGL_util = "yes"])
-AC_MSG_RESULT($build_BGL_util)
-
-AC_MSG_CHECKING([whether to build experimental BGL-chainstate])
-AM_CONDITIONAL([BUILD_BGL_CHAINSTATE], [test $build_BGL_chainstate = "yes"])
-AC_MSG_RESULT($build_BGL_chainstate)
-
-AC_MSG_CHECKING([whether to build libraries])
-AM_CONDITIONAL([BUILD_BGL_LIBS], [test $build_BGL_libs = "yes"])
-if test "$build_BGL_libs" = "yes"; then
- AC_DEFINE([HAVE_CONSENSUS_LIB], [1], [Define this symbol if the consensus lib has been built])
- AC_CONFIG_FILES([libBGLconsensus.pc:libBGLconsensus.pc.in])
-fi
-AC_MSG_RESULT($build_BGL_libs)
-
-AC_LANG_POP
-
-if test "$use_ccache" != "no"; then
- AC_MSG_CHECKING([if ccache should be used])
- if test "$CCACHE" = ""; then
- if test "$use_ccache" = "yes"; then
- AC_MSG_ERROR([ccache not found.]);
- else
- use_ccache=no
- fi
- else
- use_ccache=yes
- CC="$ac_cv_path_CCACHE $CC"
- CXX="$ac_cv_path_CCACHE $CXX"
- fi
- AC_MSG_RESULT($use_ccache)
- if test "$use_ccache" = "yes"; then
- AX_CHECK_COMPILE_FLAG([-fdebug-prefix-map=A=B], [DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -fdebug-prefix-map=\$(abs_top_srcdir)=."], [], [$CXXFLAG_WERROR])
- AX_CHECK_PREPROC_FLAG([-fmacro-prefix-map=A=B], [DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -fmacro-prefix-map=\$(abs_top_srcdir)=."], [], [$CXXFLAG_WERROR])
- fi
-fi
-
-dnl enable wallet
-AC_MSG_CHECKING([if wallet should be enabled])
-if test "$enable_wallet" != "no"; then
- AC_MSG_RESULT([yes])
- AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions])
- enable_wallet=yes
-
-else
- AC_MSG_RESULT([no])
-fi
-
-dnl enable upnp support
-AC_MSG_CHECKING([whether to build with support for UPnP])
-if test "$have_miniupnpc" = "no"; then
- if test "$use_upnp" = "yes"; then
- AC_MSG_ERROR([UPnP requested but cannot be built. Use --without-miniupnpc])
- fi
- AC_MSG_RESULT([no])
- use_upnp=no
-else
- if test "$use_upnp" != "no"; then
- AC_MSG_RESULT([yes])
- AC_MSG_CHECKING([whether to build with UPnP enabled by default])
- use_upnp=yes
- upnp_setting=0
- if test "$use_upnp_default" != "no"; then
- use_upnp_default=yes
- upnp_setting=1
- fi
- AC_MSG_RESULT([$use_upnp_default])
- AC_DEFINE_UNQUOTED([USE_UPNP],[$upnp_setting],[UPnP support not compiled if undefined, otherwise value (0 or 1) determines default state])
- if test "$TARGET_OS" = "windows"; then
- MINIUPNPC_CPPFLAGS="-DSTATICLIB -DMINIUPNP_STATICLIB"
- fi
- else
- AC_MSG_RESULT([no])
- fi
-fi
-
-dnl Enable NAT-PMP support.
-AC_MSG_CHECKING([whether to build with support for NAT-PMP])
-if test "$have_natpmp" = "no"; then
- if test "$use_natpmp" = "yes"; then
- AC_MSG_ERROR([NAT-PMP requested but cannot be built. Use --without-natpmp])
- fi
- AC_MSG_RESULT([no])
- use_natpmp=no
-else
- if test "$use_natpmp" != "no"; then
- AC_MSG_RESULT([yes])
- AC_MSG_CHECKING([whether to build with NAT-PMP enabled by default])
- use_natpmp=yes
- natpmp_setting=0
- if test "$use_natpmp_default" != "no"; then
- use_natpmp_default=yes
- natpmp_setting=1
- fi
- AC_MSG_RESULT($use_natpmp_default)
- AC_DEFINE_UNQUOTED([USE_NATPMP], [$natpmp_setting], [NAT-PMP support not compiled if undefined, otherwise value (0 or 1) determines default state])
- if test "$TARGET_OS" = "windows"; then
- NATPMP_CPPFLAGS="-DSTATICLIB -DNATPMP_STATICLIB"
- fi
- else
- AC_MSG_RESULT([no])
- fi
-fi
-
-dnl these are only used when qt is enabled
-BUILD_TEST_QT=""
-if test "$BGL_enable_qt" != "no"; then
- dnl enable dbus support
- AC_MSG_CHECKING([whether to build GUI with support for D-Bus])
- if test "$BGL_enable_qt_dbus" != "no"; then
- AC_DEFINE([USE_DBUS], [1], [Define if dbus support should be compiled in])
- fi
- AC_MSG_RESULT($BGL_enable_qt_dbus)
-
- dnl enable qr support
- AC_MSG_CHECKING([whether to build GUI with support for QR codes])
- if test "$have_qrencode" = "no"; then
- if test "$use_qr" = "yes"; then
- AC_MSG_ERROR([QR support requested but cannot be built. Use --without-qrencode])
- fi
- use_qr=no
- else
- if test "$use_qr" != "no"; then
- AC_DEFINE([USE_QRCODE], [1], [Define if QR support should be compiled in])
- use_qr=yes
- fi
- fi
- AC_MSG_RESULT([$use_qr])
-
- if test "$XGETTEXT" = ""; then
- AC_MSG_WARN([xgettext is required to update qt translations])
- fi
-
- AC_MSG_CHECKING([whether to build test_BGL-qt])
- if test "$use_gui_tests$BGL_enable_qt_test" = "yesyes"; then
- AC_MSG_RESULT([yes])
- BUILD_TEST_QT="yes"
- else
- AC_MSG_RESULT([no])
- fi
-fi
-
-AM_CONDITIONAL([ENABLE_ZMQ], [test "$use_zmq" = "yes"])
-
-AC_MSG_CHECKING([whether to build test_BGL])
-if test "$use_tests" = "yes"; then
- if test "$enable_fuzz" = "yes"; then
- AC_MSG_RESULT([no, because fuzzing is enabled])
- else
- AC_MSG_RESULT([yes])
+ if test x"$set_asm" = x"arm"; then
+ AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.])
fi
BUILD_TEST="yes"
else
@@ -1791,144 +1354,32 @@ if test "$build_BGL_wallet$build_BGL_cli$build_BGL_tx$build_BGL_libs$build_BGLd$
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests])
fi
-AM_CONDITIONAL([TARGET_DARWIN], [test "$TARGET_OS" = "darwin"])
-AM_CONDITIONAL([BUILD_DARWIN], [test "$BUILD_OS" = "darwin"])
-AM_CONDITIONAL([TARGET_LINUX], [test "$TARGET_OS" = "linux"])
-AM_CONDITIONAL([TARGET_WINDOWS], [test "$TARGET_OS" = "windows"])
-AM_CONDITIONAL([ENABLE_WALLET], [test "$enable_wallet" = "yes"])
-AM_CONDITIONAL([USE_SQLITE], [test "$use_sqlite" = "yes"])
-AM_CONDITIONAL([USE_BDB], [test "$use_bdb" = "yes"])
-AM_CONDITIONAL([ENABLE_TESTS], [test "$BUILD_TEST" = "yes"])
-AM_CONDITIONAL([ENABLE_FUZZ], [test "$enable_fuzz" = "yes"])
-AM_CONDITIONAL([ENABLE_FUZZ_BINARY], [test "$enable_fuzz_binary" = "yes"])
-AM_CONDITIONAL([ENABLE_QT], [test "$BGL_enable_qt" = "yes"])
-AM_CONDITIONAL([ENABLE_QT_TESTS], [test "$BUILD_TEST_QT" = "yes"])
-AM_CONDITIONAL([ENABLE_BENCH], [test "$use_bench" = "yes"])
-AM_CONDITIONAL([USE_QRCODE], [test "$use_qr" = "yes"])
-AM_CONDITIONAL([USE_LCOV], [test "$use_lcov" = "yes"])
-AM_CONDITIONAL([USE_LIBEVENT], [test "$use_libevent" = "yes"])
-AM_CONDITIONAL([HARDEN], [test "$use_hardening" = "yes"])
-AM_CONDITIONAL([ENABLE_SSE42], [test "$enable_sse42" = "yes"])
-AM_CONDITIONAL([ENABLE_SSE41], [test "$enable_sse41" = "yes"])
-AM_CONDITIONAL([ENABLE_AVX2], [test "$enable_avx2" = "yes"])
-AM_CONDITIONAL([ENABLE_X86_SHANI], [test "$enable_x86_shani" = "yes"])
-AM_CONDITIONAL([ENABLE_ARM_CRC], [test "$enable_arm_crc" = "yes"])
-AM_CONDITIONAL([ENABLE_ARM_SHANI], [test "$enable_arm_shani" = "yes"])
-AM_CONDITIONAL([USE_ASM], [test "$use_asm" = "yes"])
-AM_CONDITIONAL([WORDS_BIGENDIAN], [test "$ac_cv_c_bigendian" = "yes"])
-AM_CONDITIONAL([USE_NATPMP], [test "$use_natpmp" = "yes"])
-AM_CONDITIONAL([USE_UPNP], [test "$use_upnp" = "yes"])
-
-dnl for minisketch
-AM_CONDITIONAL([ENABLE_CLMUL], [test "$enable_clmul" = "yes"])
-AM_CONDITIONAL([HAVE_CLZ], [test "$have_clzl$have_clzll" = "yesyes"])
-
-AC_DEFINE([CLIENT_VERSION_MAJOR], [_CLIENT_VERSION_MAJOR], [Major version])
-AC_DEFINE([CLIENT_VERSION_MINOR], [_CLIENT_VERSION_MINOR], [Minor version])
-AC_DEFINE([CLIENT_VERSION_BUILD], [_CLIENT_VERSION_BUILD], [Version Build])
-AC_DEFINE([CLIENT_VERSION_IS_RELEASE], [_CLIENT_VERSION_IS_RELEASE], [Version is release])
-AC_DEFINE([COPYRIGHT_YEAR], [_COPYRIGHT_YEAR], [Copyright year])
-AC_DEFINE([COPYRIGHT_HOLDERS], ["_COPYRIGHT_HOLDERS"], [Copyright holder(s) before %s replacement])
-AC_DEFINE([COPYRIGHT_HOLDERS_SUBSTITUTION], ["_COPYRIGHT_HOLDERS_SUBSTITUTION"], [Replacement for %s in copyright holders string])
-define(_COPYRIGHT_HOLDERS_FINAL, [patsubst(_COPYRIGHT_HOLDERS, [%s], [_COPYRIGHT_HOLDERS_SUBSTITUTION])])
-AC_DEFINE([COPYRIGHT_HOLDERS_FINAL], ["_COPYRIGHT_HOLDERS_FINAL"], [Copyright holder(s)])
-AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR)
-AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR)
-AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD)
-AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE)
-AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR)
-AC_SUBST(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS")
-AC_SUBST(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION")
-AC_SUBST(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL")
-AC_SUBST(BGL_DAEMON_NAME)
-AC_SUBST(BGL_GUI_NAME)
-AC_SUBST(BGL_CLI_NAME)
-AC_SUBST(BGL_TX_NAME)
-AC_SUBST(BGL_UTIL_NAME)
-AC_SUBST(BGL_CHAINSTATE_NAME)
-AC_SUBST(BGL_WALLET_TOOL_NAME)
-AC_SUBST(BGL_MP_NODE_NAME)
-AC_SUBST(BGL_MP_GUI_NAME)
-
-AC_SUBST(RELDFLAGS)
-AC_SUBST(CORE_LDFLAGS)
-AC_SUBST(CORE_CPPFLAGS)
-AC_SUBST(CORE_CXXFLAGS)
-AC_SUBST(DEBUG_CPPFLAGS)
-AC_SUBST(WARN_CXXFLAGS)
-AC_SUBST(NOWARN_CXXFLAGS)
-AC_SUBST(DEBUG_CXXFLAGS)
-AC_SUBST(ERROR_CXXFLAGS)
-AC_SUBST(GPROF_CXXFLAGS)
-AC_SUBST(GPROF_LDFLAGS)
-AC_SUBST(HARDENED_CXXFLAGS)
-AC_SUBST(HARDENED_CPPFLAGS)
-AC_SUBST(HARDENED_LDFLAGS)
-AC_SUBST(LTO_CXXFLAGS)
-AC_SUBST(LTO_LDFLAGS)
-AC_SUBST(PIC_FLAGS)
-AC_SUBST(PIE_FLAGS)
-AC_SUBST(SANITIZER_CXXFLAGS)
-AC_SUBST(SANITIZER_LDFLAGS)
-AC_SUBST(SSE42_CXXFLAGS)
-AC_SUBST(SSE41_CXXFLAGS)
-AC_SUBST(CLMUL_CXXFLAGS)
-AC_SUBST(AVX2_CXXFLAGS)
-AC_SUBST(X86_SHANI_CXXFLAGS)
-AC_SUBST(ARM_CRC_CXXFLAGS)
-AC_SUBST(ARM_SHANI_CXXFLAGS)
-AC_SUBST(LIBTOOL_APP_LDFLAGS)
-AC_SUBST(USE_SQLITE)
-AC_SUBST(USE_BDB)
-AC_SUBST(ENABLE_EXTERNAL_SIGNER)
-AC_SUBST(USE_UPNP)
-AC_SUBST(USE_QRCODE)
-AC_SUBST(TESTDEFS)
-AC_SUBST(MINIUPNPC_CPPFLAGS)
-AC_SUBST(MINIUPNPC_LIBS)
-AC_SUBST(NATPMP_CPPFLAGS)
-AC_SUBST(NATPMP_LIBS)
-AC_SUBST(HAVE_GMTIME_R)
-AC_SUBST(HAVE_FDATASYNC)
-AC_SUBST(HAVE_FULLFSYNC)
-AC_SUBST(HAVE_O_CLOEXEC)
-AC_SUBST(HAVE_BUILTIN_PREFETCH)
-AC_SUBST(HAVE_MM_PREFETCH)
-AC_SUBST(HAVE_STRONG_GETAUXVAL)
-AC_SUBST(ANDROID_ARCH)
-AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini])
-AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh])
-AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])])
-AC_CONFIG_LINKS([contrib/devtools/security-check.py:contrib/devtools/security-check.py])
-AC_CONFIG_LINKS([contrib/devtools/symbol-check.py:contrib/devtools/symbol-check.py])
-AC_CONFIG_LINKS([contrib/devtools/test-security-check.py:contrib/devtools/test-security-check.py])
-AC_CONFIG_LINKS([contrib/devtools/test-symbol-check.py:contrib/devtools/test-symbol-check.py])
-AC_CONFIG_LINKS([contrib/filter-lcov.py:contrib/filter-lcov.py])
-AC_CONFIG_LINKS([contrib/macdeploy/background.tiff:contrib/macdeploy/background.tiff])
-AC_CONFIG_LINKS([src/.clang-tidy:src/.clang-tidy])
-AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py])
-AC_CONFIG_LINKS([test/fuzz/test_runner.py:test/fuzz/test_runner.py])
-AC_CONFIG_LINKS([test/util/test_runner.py:test/util/test_runner.py])
-AC_CONFIG_LINKS([test/util/rpcauth-test.py:test/util/rpcauth-test.py])
-
-dnl boost's m4 checks do something really nasty: they export these vars. As a
-dnl result, they leak into secp256k1's configure and crazy things happen.
-dnl Until this is fixed upstream and we've synced, we'll just un-export them.
-CPPFLAGS_TEMP="$CPPFLAGS"
-unset CPPFLAGS
-CPPFLAGS="$CPPFLAGS_TEMP"
-
-LDFLAGS_TEMP="$LDFLAGS"
-unset LDFLAGS
-LDFLAGS="$LDFLAGS_TEMP"
-
-LIBS_TEMP="$LIBS"
-unset LIBS
-LIBS="$LIBS_TEMP"
-
-PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
-unset PKG_CONFIG_PATH
-PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP"
+###
+### Generate output
+###
+
+AC_CONFIG_HEADERS([src/libsecp256k1-config.h])
+AC_CONFIG_FILES([Makefile libsecp256k1.pc])
+AC_SUBST(SECP_INCLUDES)
+AC_SUBST(SECP_LIBS)
+AC_SUBST(SECP_TEST_LIBS)
+AC_SUBST(SECP_TEST_INCLUDES)
+AC_SUBST(SECP_CFLAGS)
+AM_CONDITIONAL([ENABLE_COVERAGE], [test x"$enable_coverage" = x"yes"])
+AM_CONDITIONAL([USE_TESTS], [test x"$enable_tests" != x"no"])
+AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$enable_exhaustive_tests" != x"no"])
+AM_CONDITIONAL([USE_EXAMPLES], [test x"$enable_examples" != x"no"])
+AM_CONDITIONAL([USE_BENCHMARK], [test x"$enable_benchmark" = x"yes"])
+AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
+AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"])
+AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"yes"])
+AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"])
+AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
+AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"])
+AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"])
+AC_SUBST(LIB_VERSION_CURRENT, _LIB_VERSION_CURRENT)
+AC_SUBST(LIB_VERSION_REVISION, _LIB_VERSION_REVISION)
+AC_SUBST(LIB_VERSION_AGE, _LIB_VERSION_AGE)
PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR"
unset PKG_CONFIG_LIBDIR
@@ -1949,10 +1400,11 @@ esac
echo
echo "Build Options:"
-echo " with external callbacks = $use_external_default_callbacks"
-echo " with benchmarks = $use_benchmark"
-echo " with tests = $use_tests"
+echo " with external callbacks = $enable_external_default_callbacks"
+echo " with benchmarks = $enable_benchmark"
+echo " with tests = $enable_tests"
echo " with coverage = $enable_coverage"
+echo " with examples = $enable_examples"
echo " module ecdh = $enable_module_ecdh"
echo " module recovery = $enable_module_recovery"
echo " module extrakeys = $enable_module_extrakeys"
diff --git a/contrib/travis.sh b/contrib/travis.sh
index 7b9caeff40..88061b743a 100755
--- a/contrib/travis.sh
+++ b/contrib/travis.sh
@@ -14,10 +14,12 @@ fi
./configure \
--enable-experimental="$EXPERIMENTAL" \
- --with-test-override-wide-multiply="$WIDEMUL" --with-bignum="$BIGNUM" --with-asm="$ASM" \
- --enable-ecmult-static-precomputation="$STATICPRECOMPUTATION" --with-ecmult-gen-precision="$ECMULTGENPRECISION" \
+ --with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \
+ --with-ecmult-window="$ECMULTWINDOW" \
+ --with-ecmult-gen-precision="$ECMULTGENPRECISION" \
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
--enable-module-schnorrsig="$SCHNORRSIG" \
+ --enable-examples="$EXAMPLES" \
--with-valgrind="$WITH_VALGRIND" \
--host="$HOST" $EXTRAFLAGS
diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md
new file mode 100644
index 0000000000..3c4c2e4583
--- /dev/null
+++ b/doc/CHANGELOG.md
@@ -0,0 +1,12 @@
+# Changelog
+
+This file is currently only a template for future use.
+
+Each change falls into one of the following categories: Added, Changed, Deprecated, Removed, Fixed or Security.
+
+## [Unreleased]
+
+## [MAJOR.MINOR.PATCH] - YYYY-MM-DD
+
+### Added/Changed/Deprecated/Removed/Fixed/Security
+- [Title with link to Pull Request](https://link-to-pr)
diff --git a/doc/release-process.md b/doc/release-process.md
index 030581ef2a..a35b8a9db3 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -1,314 +1,14 @@
-Release Process
-====================
-
-## Branch updates
-
-### Before every release candidate
-
-* Update translations see [translation_process.md](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#synchronising-translations).
-* Update release candidate version in `configure.ac` (`CLIENT_VERSION_RC`).
-* Update manpages (after rebuilding the binaries), see [gen-manpages.py](https://github.com/bitcoin/bitcoin/blob/master/contrib/devtools/README.md#gen-manpagespy).
-
-### Before every major and minor release
-
-* Update [bips.md](bips.md) to account for changes since the last release (don't forget to bump the version number on the first line).
-* Update version in `configure.ac` (don't forget to set `CLIENT_VERSION_RC` to `0`).
-* Update manpages (see previous section)
-* Write release notes (see "Write the release notes" below).
-
-### Before every major release
-
-* On both the master branch and the new release branch:
- - update `CLIENT_VERSION_MAJOR` in [`configure.ac`](../configure.ac)
-* On the new release branch in [`configure.ac`](../configure.ac)(see [this commit](https://github.com/bitcoin/bitcoin/commit/742f7dd)):
- - set `CLIENT_VERSION_MINOR` to `0`
- - set `CLIENT_VERSION_BUILD` to `0`
- - set `CLIENT_VERSION_IS_RELEASE` to `true`
-
-#### Before branch-off
-
-* Update hardcoded [seeds](/contrib/seeds/README.md), see [this pull request](https://github.com/bitcoin/bitcoin/pull/7415) for an example.
-* Update [`src/chainparams.cpp`](/src/chainparams.cpp) m_assumed_blockchain_size and m_assumed_chain_state_size with the current size plus some overhead (see [this](#how-to-calculate-assumed-blockchain-and-chain-state-size) for information on how to calculate them).
-* Update [`src/chainparams.cpp`](/src/chainparams.cpp) chainTxData with statistics about the transaction count and rate. Use the output of the `getchaintxstats` RPC, see
- [this pull request](https://github.com/bitcoin/bitcoin/pull/20263) for an example. Reviewers can verify the results by running `getchaintxstats ` with the `window_block_count` and `window_final_block_hash` from your output.
-* Update `src/chainparams.cpp` nMinimumChainWork and defaultAssumeValid (and the block height comment) with information from the `getblockheader` (and `getblockhash`) RPCs.
- - The selected value must not be orphaned so it may be useful to set the value two blocks back from the tip.
- - Testnet should be set some tens of thousands back from the tip due to reorgs there.
- - This update should be reviewed with a reindex-chainstate with assumevalid=0 to catch any defect
- that causes rejection of blocks in the past history.
-- Clear the release notes and move them to the wiki (see "Write the release notes" below).
-- Translations on Transifex:
- - Pull translations from Transifex into the master branch.
- - Create [a new resource](https://www.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `[BGL.qt-translation-x]`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/BGL_en.xlf` to create it.
- - In the project workflow settings, ensure that [Translation Memory Fill-up](https://docs.transifex.com/translation-memory/enabling-autofill) is enabled and that [Translation Memory Context Matching](https://docs.transifex.com/translation-memory/translation-memory-with-context) is disabled.
- - Update the Transifex slug in [`.tx/config`](/.tx/config) to the slug of the resource created in the first step. This identifies which resource the translations will be synchronized from.
- - Make an announcement that translators can start translating for the new version. You can use one of the [previous announcements](https://www.transifex.com/bitcoin/bitcoin/announcements/) as a template.
- - Change the auto-update URL for the resource to `master`, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/qt/locale/bitcoin_en.xlf`. (Do this only after the previous steps, to prevent an auto-update from interfering.)
-
-#### After branch-off (on the major release branch)
-
-- Update the versions.
-- Create the draft, named "*version* Release Notes Draft", as a [collaborative wiki](https://github.com/bitcoin-core/bitcoin-devwiki/wiki/_new).
-- Clear the release notes: `cp doc/release-notes-empty-template.md doc/release-notes.md`
-- Create a pinned meta-issue for testing the release candidate (see [this issue](https://github.com/bitcoin/bitcoin/issues/17079) for an example) and provide a link to it in the release announcements where useful.
-- Translations on Transifex
- - Change the auto-update URL for the new major version's resource away from `master` and to the branch, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin//src/qt/locale/bitcoin_en.xlf`. Do not forget this or it will keep tracking the translations on master instead, drifting away from the specific major release.
-
-#### Before final release
-
-- Merge the release notes from [the wiki](https://github.com/bitcoin-core/bitcoin-devwiki/wiki/) into the branch.
-- Ensure the "Needs release note" label is removed from all relevant pull requests and issues.
-
-#### Tagging a release (candidate)
-
-To tag the version (or release candidate) in git, use the `make-tag.py` script from [BGL-maintainer-tools](https://github.com/bitcoin-core/bitcoin-maintainer-tools). From the root of the repository run:
-
- ../BGL-maintainer-tools/make-tag.py v(new version, e.g. 23.0)
-
-This will perform a few last-minute consistency checks in the build system files, and if they pass, create a signed tag.
-
-## Building
-
-### First time / New builders
-
-Install Guix using one of the installation methods detailed in
-[contrib/guix/INSTALL.md](/contrib/guix/INSTALL.md).
-
-Check out the source code in the following directory hierarchy.
-
- cd /path/to/your/toplevel/build
- git clone https://github.com/BitgesellOfficial/bitgesell.git
-
-### Write the release notes
-
-Open a draft of the release notes for collaborative editing at https://github.com/BGL-core/BGL-devwiki/wiki.
-
-For the period during which the notes are being edited on the wiki, the version on the branch should be wiped and replaced with a link to the wiki which should be used for all announcements until `-final`.
-
-Generate the change log. As this is a huge amount of work to do manually, there is the `list-pulls` script to do a pre-sorting step based on github PR metadata. See the [documentation in the README.md](https://github.com/bitcoin-core/bitcoin-maintainer-tools/blob/master/README.md#list-pulls).
-
-Generate list of authors:
-
- git log --format='- %aN' v(current version, e.g. 0.20.0)..v(new version, e.g. 0.20.1) | sort -fiu
-
-### Setup and perform Guix builds
-
-Checkout the Bitgesell Core version you'd like to build:
-
-```sh
-pushd ./BGL
-SIGNER='(your builder key, ie bluematt, sipa, etc)'
-VERSION='(new version without v-prefix, e.g. 0.20.0)'
-git fetch origin "v${VERSION}"
-git checkout "v${VERSION}"
-popd
-```
-
-Ensure your guix.sigs are up-to-date if you wish to `guix-verify` your builds
-against other `guix-attest` signatures.
-
-```sh
-git -C ./guix.sigs pull
-```
-
-### Create the macOS SDK tarball (first time, or when SDK version changes)
-
-Create the macOS SDK tarball, see the [macdeploy
-instructions](/contrib/macdeploy/README.md#deterministic-macos-dmg-notes) for
-details.
-
-### Build and attest to build outputs
-
-Follow the relevant Guix README.md sections:
-- [Building](/contrib/guix/README.md#building)
-- [Attesting to build outputs](/contrib/guix/README.md#attesting-to-build-outputs)
-
-### Verify other builders' signatures to your own (optional)
-
-- [Add other builders keys to your gpg keyring, and/or refresh keys](/contrib/builder-keys/README.md)
-- [Verifying build output attestations](/contrib/guix/README.md#verifying-build-output-attestations)
-
-### Commit your non codesigned signature to guix.sigs
-
-```sh
-pushd ./guix.sigs
-git add "${VERSION}/${SIGNER}"/noncodesigned.SHA256SUMS{,.asc}
-git commit -m "Add attestations by ${SIGNER} for ${VERSION} non-codesigned"
-git push # Assuming you can push to the guix.sigs tree
-popd
-```
-
-## Codesigning
-
-### macOS codesigner only: Create detached macOS signatures (assuming [signapple](https://github.com/achow101/signapple/) is installed and up to date with master branch)
-
- tar xf BGL-osx-unsigned.tar.gz
- ./detached-sig-create.sh /path/to/codesign.p12
- Enter the keychain password and authorize the signature
- signature-osx.tar.gz will be created
-
-### Windows codesigner only: Create detached Windows signatures
-
- tar xf BGL-win-unsigned.tar.gz
- ./detached-sig-create.sh -key /path/to/codesign.key
- Enter the passphrase for the key when prompted
- signature-win.tar.gz will be created
-
-### Windows and macOS codesigners only: test code signatures
-It is advised to test that the code signature attaches properly prior to tagging by performing the `guix-codesign` step.
-However if this is done, once the release has been tagged in the BGL-detached-sigs repo, the `guix-codesign` step must be performed again in order for the guix attestation to be valid when compared against the attestations of non-codesigner builds.
-
-### Windows and macOS codesigners only: Commit the detached codesign payloads
-
-```sh
-pushd ./BGL-detached-sigs
-# checkout the appropriate branch for this release series
-rm -rf ./*
-tar xf signature-osx.tar.gz
-tar xf signature-win.tar.gz
-git add -A
-git commit -m "point to ${VERSION}"
-git tag -s "v${VERSION}" HEAD
-git push the current branch and new tag
-popd
-```
-
-### Non-codesigners: wait for Windows and macOS detached signatures
-
-- Once the Windows and macOS builds each have 3 matching signatures, they will be signed with their respective release keys.
-- Detached signatures will then be committed to the [BGL-detached-sigs](https://github.com/bitcoin-core/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries.
-
-### Create the codesigned build outputs
-
-- [Codesigning build outputs](/contrib/guix/README.md#codesigning-build-outputs)
-
-### Verify other builders' signatures to your own (optional)
-
-- [Add other builders keys to your gpg keyring, and/or refresh keys](/contrib/builder-keys/README.md)
-- [Verifying build output attestations](/contrib/guix/README.md#verifying-build-output-attestations)
-
-### Commit your codesigned signature to guix.sigs (for the signed macOS/Windows binaries)
-
-```sh
-pushd ./guix.sigs
-git add "${VERSION}/${SIGNER}"/all.SHA256SUMS{,.asc}
-git commit -m "Add attestations by ${SIGNER} for ${VERSION} codesigned"
-git push # Assuming you can push to the guix.sigs tree
-popd
-```
-
-## After 3 or more people have guix-built and their results match
-
-Combine the `all.SHA256SUMS.asc` file from all signers into `SHA256SUMS.asc`:
-
-```bash
-cat "$VERSION"/*/all.SHA256SUMS.asc > SHA256SUMS.asc
-```
-
-
-- Upload to the BGLcore.org server (`/var/www/bin/BGL-core-${VERSION}/`):
- 1. The contents of each `./BGL/guix-build-${VERSION}/output/${HOST}/` directory, except for
- `*-debug*` files.
-
- Guix will output all of the results into host subdirectories, but the SHA256SUMS
- file does not include these subdirectories. In order for downloads via torrent
- to verify without directory structure modification, all of the uploaded files
- need to be in the same directory as the SHA256SUMS file.
-
- The `*-debug*` files generated by the guix build contain debug symbols
- for troubleshooting by developers. It is assumed that anyone that is
- interested in debugging can run guix to generate the files for
- themselves. To avoid end-user confusion about which file to pick, as well
- as save storage space *do not upload these to the BGLcore.org server,
- nor put them in the torrent*.
-
- ```sh
- find guix-build-${VERSION}/output/ -maxdepth 2 -type f -not -name "SHA256SUMS.part" -and -not -name "*debug*" -exec scp {} user@BGLcore.org:/var/www/bin/BGL-core-${VERSION} \;
- ```
-
- 2. The `SHA256SUMS` file
-
- 3. The `SHA256SUMS.asc` combined signature file you just created
-
-- Create a torrent of the `/var/www/bin/BGL-core-${VERSION}` directory such
- that at the top level there is only one file: the `BGL-core-${VERSION}`
- directory containing everything else. Name the torrent
- `BGL-${VERSION}.torrent` (note that there is no `-core-` in this name).
-
- Optionally help seed this torrent. To get the `magnet:` URI use:
-
- ```sh
- transmission-show -m
- ```
-
- Insert the magnet URI into the announcement sent to mailing lists. This permits
- people without access to `BGLcore.org` to download the binary distribution.
- Also put it into the `optional_magnetlink:` slot in the YAML file for
- BGLcore.org.
-
-- Update other repositories and websites for new version
-
- - BGLcore.org blog post
-
- - BGLcore.org maintained versions update:
- [table](https://github.com/BGL-core/BGLcore.org/commits/master/_includes/posts/maintenance-table.md)
-
- - Delete post-EOL [release branches](https://github.com/bitcoin/bitcoin/branches/all) and create a tag `v${branch_name}-final`.
-
- - Delete ["Needs backport" labels](https://github.com/bitcoin/bitcoin/labels?q=backport) for non-existing branches.
-
- - bitcoincore.org RPC documentation update
-
- - Install [golang](https://golang.org/doc/install)
-
- - Install the new BGL Core release
-
- - Run BGLd on regtest
-
- - Clone the [BGLcore.org repository](https://github.com/bitcoin-core/bitcoincore.org)
-
- - Run: `go run generate.go` while being in `contrib/doc-gen` folder, and with BGL-cli in PATH
-
- - Add the generated files to git
-
- - Update packaging repo
-
- - Push the flatpak to flathub, e.g. https://github.com/flathub/org.BGLcore.BGL-qt/pull/2
-
- - Push the snap, see https://github.com/bitcoin-core/packaging/blob/master/snap/build.md
-
- - This repo
-
- - Archive the release notes for the new version to `doc/release-notes/` (branch `master` and branch of the release)
-
- - Create a [new GitHub release](https://github.com/BGL/BGL/releases/new) with a link to the archived release notes
-
-- Announce the release:
-
- - BGL-dev and BGL-core-dev mailing list
-
- - BGL Core announcements list https://BGLcore.org/en/list/announcements/join/
-
- - BGL Core Twitter https://twitter.com/BGLcoreorg
-
- - Celebrate
-
-### Additional information
-
-#### How to calculate `m_assumed_blockchain_size` and `m_assumed_chain_state_size`
-
-Both variables are used as a guideline for how much space the user needs on their drive in total, not just strictly for the blockchain.
-Note that all values should be taken from a **fully synced** node and have an overhead of 5-10% added on top of its base value.
-
-To calculate `m_assumed_blockchain_size`:
-- For `mainnet` -> Take the size of the data directory, excluding `/regtest` and `/testnet3` directories.
-- For `testnet` -> Take the size of the `/testnet3` directory.
-
-
-To calculate `m_assumed_chain_state_size`:
-- For `mainnet` -> Take the size of the `/chainstate` directory.
-- For `testnet` -> Take the size of the `/testnet3/chainstate` directory.
-
-Notes:
-- When taking the size for `m_assumed_blockchain_size`, there's no need to exclude the `/chainstate` directory since it's a guideline value and an overhead will be added anyway.
-- The expected overhead for growth may change over time, so it may not be the same value as last release; pay attention to that when changing the variables.
+# Release Process
+
+1. Open PR to master that
+ 1. adds release notes to `doc/CHANGELOG.md` and
+ 2. if this is **not** a patch release, updates `_PKG_VERSION_{MAJOR,MINOR}` and `_LIB_VERSIONS_*` in `configure.ac`
+2. After the PR is merged,
+ * if this is **not** a patch release, create a release branch with name `MAJOR.MINOR`.
+ Make sure that the branch contains the right commits.
+ Create commit on the release branch that sets `_PKG_VERSION_IS_RELEASE` in `configure.ac` to `true`.
+ * if this **is** a patch release, open a pull request with the bugfixes to the `MAJOR.MINOR` branch.
+ Also include the release note commit bump `_PKG_VERSION_BUILD` and `_LIB_VERSIONS_*` in `configure.ac`.
+4. Tag the commit with `git tag -s vMAJOR.MINOR.PATCH`.
+5. Push branch and tag with `git push origin --tags`.
+6. Create a new GitHub release with a link to the corresponding entry in `doc/CHANGELOG.md`.
diff --git a/examples/EXAMPLES_COPYING b/examples/EXAMPLES_COPYING
new file mode 100644
index 0000000000..0e259d42c9
--- /dev/null
+++ b/examples/EXAMPLES_COPYING
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/examples/ecdh.c b/examples/ecdh.c
new file mode 100644
index 0000000000..d7e8add361
--- /dev/null
+++ b/examples/ecdh.c
@@ -0,0 +1,127 @@
+/*************************************************************************
+ * Written in 2020-2022 by Elichai Turkel *
+ * To the extent possible under law, the author(s) have dedicated all *
+ * copyright and related and neighboring rights to the software in this *
+ * file to the public domain worldwide. This software is distributed *
+ * without any warranty. For the CC0 Public Domain Dedication, see *
+ * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
+ *************************************************************************/
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "random.h"
+
+
+int main(void) {
+ unsigned char seckey1[32];
+ unsigned char seckey2[32];
+ unsigned char compressed_pubkey1[33];
+ unsigned char compressed_pubkey2[33];
+ unsigned char shared_secret1[32];
+ unsigned char shared_secret2[32];
+ unsigned char randomize[32];
+ int return_val;
+ size_t len;
+ secp256k1_pubkey pubkey1;
+ secp256k1_pubkey pubkey2;
+
+ /* The specification in secp256k1.h states that `secp256k1_ec_pubkey_create`
+ * needs a context object initialized for signing, which is why we create
+ * a context with the SECP256K1_CONTEXT_SIGN flag.
+ * (The docs for `secp256k1_ecdh` don't require any special context, just
+ * some initialized context) */
+ secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
+ if (!fill_random(randomize, sizeof(randomize))) {
+ printf("Failed to generate randomness\n");
+ return 1;
+ }
+ /* Randomizing the context is recommended to protect against side-channel
+ * leakage See `secp256k1_context_randomize` in secp256k1.h for more
+ * information about it. This should never fail. */
+ return_val = secp256k1_context_randomize(ctx, randomize);
+ assert(return_val);
+
+ /*** Key Generation ***/
+
+ /* If the secret key is zero or out of range (bigger than secp256k1's
+ * order), we try to sample a new key. Note that the probability of this
+ * happening is negligible. */
+ while (1) {
+ if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
+ printf("Failed to generate randomness\n");
+ return 1;
+ }
+ if (secp256k1_ec_seckey_verify(ctx, seckey1) && secp256k1_ec_seckey_verify(ctx, seckey2)) {
+ break;
+ }
+ }
+
+ /* Public key creation using a valid context with a verified secret key should never fail */
+ return_val = secp256k1_ec_pubkey_create(ctx, &pubkey1, seckey1);
+ assert(return_val);
+ return_val = secp256k1_ec_pubkey_create(ctx, &pubkey2, seckey2);
+ assert(return_val);
+
+ /* Serialize pubkey1 in a compressed form (33 bytes), should always return 1 */
+ len = sizeof(compressed_pubkey1);
+ return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey1, &len, &pubkey1, SECP256K1_EC_COMPRESSED);
+ assert(return_val);
+ /* Should be the same size as the size of the output, because we passed a 33 byte array. */
+ assert(len == sizeof(compressed_pubkey1));
+
+ /* Serialize pubkey2 in a compressed form (33 bytes) */
+ len = sizeof(compressed_pubkey2);
+ return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey2, &len, &pubkey2, SECP256K1_EC_COMPRESSED);
+ assert(return_val);
+ /* Should be the same size as the size of the output, because we passed a 33 byte array. */
+ assert(len == sizeof(compressed_pubkey2));
+
+ /*** Creating the shared secret ***/
+
+ /* Perform ECDH with seckey1 and pubkey2. Should never fail with a verified
+ * seckey and valid pubkey */
+ return_val = secp256k1_ecdh(ctx, shared_secret1, &pubkey2, seckey1, NULL, NULL);
+ assert(return_val);
+
+ /* Perform ECDH with seckey2 and pubkey1. Should never fail with a verified
+ * seckey and valid pubkey */
+ return_val = secp256k1_ecdh(ctx, shared_secret2, &pubkey1, seckey2, NULL, NULL);
+ assert(return_val);
+
+ /* Both parties should end up with the same shared secret */
+ return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1));
+ assert(return_val == 0);
+
+ printf("Secret Key1: ");
+ print_hex(seckey1, sizeof(seckey1));
+ printf("Compressed Pubkey1: ");
+ print_hex(compressed_pubkey1, sizeof(compressed_pubkey1));
+ printf("\nSecret Key2: ");
+ print_hex(seckey2, sizeof(seckey2));
+ printf("Compressed Pubkey2: ");
+ print_hex(compressed_pubkey2, sizeof(compressed_pubkey2));
+ printf("\nShared Secret: ");
+ print_hex(shared_secret1, sizeof(shared_secret1));
+
+ /* This will clear everything from the context and free the memory */
+ secp256k1_context_destroy(ctx);
+
+ /* It's best practice to try to clear secrets from memory after using them.
+ * This is done because some bugs can allow an attacker to leak memory, for
+ * example through "out of bounds" array access (see Heartbleed), Or the OS
+ * swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
+ *
+ * TODO: Prevent these writes from being optimized out, as any good compiler
+ * will remove any writes that aren't used. */
+ memset(seckey1, 0, sizeof(seckey1));
+ memset(seckey2, 0, sizeof(seckey2));
+ memset(shared_secret1, 0, sizeof(shared_secret1));
+ memset(shared_secret2, 0, sizeof(shared_secret2));
+
+ return 0;
+}
diff --git a/examples/ecdsa.c b/examples/ecdsa.c
new file mode 100644
index 0000000000..434c856ba0
--- /dev/null
+++ b/examples/ecdsa.c
@@ -0,0 +1,137 @@
+/*************************************************************************
+ * Written in 2020-2022 by Elichai Turkel *
+ * To the extent possible under law, the author(s) have dedicated all *
+ * copyright and related and neighboring rights to the software in this *
+ * file to the public domain worldwide. This software is distributed *
+ * without any warranty. For the CC0 Public Domain Dedication, see *
+ * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
+ *************************************************************************/
+
+#include
+#include
+#include
+
+#include
+
+#include "random.h"
+
+
+
+int main(void) {
+ /* Instead of signing the message directly, we must sign a 32-byte hash.
+ * Here the message is "Hello, world!" and the hash function was SHA-256.
+ * An actual implementation should just call SHA-256, but this example
+ * hardcodes the output to avoid depending on an additional library.
+ * See https://bitcoin.stackexchange.com/questions/81115/if-someone-wanted-to-pretend-to-be-satoshi-by-posting-a-fake-signature-to-defrau/81116#81116 */
+ unsigned char msg_hash[32] = {
+ 0x31, 0x5F, 0x5B, 0xDB, 0x76, 0xD0, 0x78, 0xC4,
+ 0x3B, 0x8A, 0xC0, 0x06, 0x4E, 0x4A, 0x01, 0x64,
+ 0x61, 0x2B, 0x1F, 0xCE, 0x77, 0xC8, 0x69, 0x34,
+ 0x5B, 0xFC, 0x94, 0xC7, 0x58, 0x94, 0xED, 0xD3,
+ };
+ unsigned char seckey[32];
+ unsigned char randomize[32];
+ unsigned char compressed_pubkey[33];
+ unsigned char serialized_signature[64];
+ size_t len;
+ int is_signature_valid;
+ int return_val;
+ secp256k1_pubkey pubkey;
+ secp256k1_ecdsa_signature sig;
+ /* The specification in secp256k1.h states that `secp256k1_ec_pubkey_create` needs
+ * a context object initialized for signing and `secp256k1_ecdsa_verify` needs
+ * a context initialized for verification, which is why we create a context
+ * for both signing and verification with the SECP256K1_CONTEXT_SIGN and
+ * SECP256K1_CONTEXT_VERIFY flags. */
+ secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
+ if (!fill_random(randomize, sizeof(randomize))) {
+ printf("Failed to generate randomness\n");
+ return 1;
+ }
+ /* Randomizing the context is recommended to protect against side-channel
+ * leakage See `secp256k1_context_randomize` in secp256k1.h for more
+ * information about it. This should never fail. */
+ return_val = secp256k1_context_randomize(ctx, randomize);
+ assert(return_val);
+
+ /*** Key Generation ***/
+
+ /* If the secret key is zero or out of range (bigger than secp256k1's
+ * order), we try to sample a new key. Note that the probability of this
+ * happening is negligible. */
+ while (1) {
+ if (!fill_random(seckey, sizeof(seckey))) {
+ printf("Failed to generate randomness\n");
+ return 1;
+ }
+ if (secp256k1_ec_seckey_verify(ctx, seckey)) {
+ break;
+ }
+ }
+
+ /* Public key creation using a valid context with a verified secret key should never fail */
+ return_val = secp256k1_ec_pubkey_create(ctx, &pubkey, seckey);
+ assert(return_val);
+
+ /* Serialize the pubkey in a compressed form(33 bytes). Should always return 1. */
+ len = sizeof(compressed_pubkey);
+ return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey, &len, &pubkey, SECP256K1_EC_COMPRESSED);
+ assert(return_val);
+ /* Should be the same size as the size of the output, because we passed a 33 byte array. */
+ assert(len == sizeof(compressed_pubkey));
+
+ /*** Signing ***/
+
+ /* Generate an ECDSA signature `noncefp` and `ndata` allows you to pass a
+ * custom nonce function, passing `NULL` will use the RFC-6979 safe default.
+ * Signing with a valid context, verified secret key
+ * and the default nonce function should never fail. */
+ return_val = secp256k1_ecdsa_sign(ctx, &sig, msg_hash, seckey, NULL, NULL);
+ assert(return_val);
+
+ /* Serialize the signature in a compact form. Should always return 1
+ * according to the documentation in secp256k1.h. */
+ return_val = secp256k1_ecdsa_signature_serialize_compact(ctx, serialized_signature, &sig);
+ assert(return_val);
+
+
+ /*** Verification ***/
+
+ /* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */
+ if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) {
+ printf("Failed parsing the signature\n");
+ return 1;
+ }
+
+ /* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */
+ if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) {
+ printf("Failed parsing the public key\n");
+ return 1;
+ }
+
+ /* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
+ is_signature_valid = secp256k1_ecdsa_verify(ctx, &sig, msg_hash, &pubkey);
+
+ printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
+ printf("Secret Key: ");
+ print_hex(seckey, sizeof(seckey));
+ printf("Public Key: ");
+ print_hex(compressed_pubkey, sizeof(compressed_pubkey));
+ printf("Signature: ");
+ print_hex(serialized_signature, sizeof(serialized_signature));
+
+
+ /* This will clear everything from the context and free the memory */
+ secp256k1_context_destroy(ctx);
+
+ /* It's best practice to try to clear secrets from memory after using them.
+ * This is done because some bugs can allow an attacker to leak memory, for
+ * example through "out of bounds" array access (see Heartbleed), Or the OS
+ * swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
+ *
+ * TODO: Prevent these writes from being optimized out, as any good compiler
+ * will remove any writes that aren't used. */
+ memset(seckey, 0, sizeof(seckey));
+
+ return 0;
+}
diff --git a/examples/random.h b/examples/random.h
new file mode 100644
index 0000000000..439226f09f
--- /dev/null
+++ b/examples/random.h
@@ -0,0 +1,73 @@
+/*************************************************************************
+ * Copyright (c) 2020-2021 Elichai Turkel *
+ * Distributed under the CC0 software license, see the accompanying file *
+ * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
+ *************************************************************************/
+
+/*
+ * This file is an attempt at collecting best practice methods for obtaining randomness with different operating systems.
+ * It may be out-of-date. Consult the documentation of the operating system before considering to use the methods below.
+ *
+ * Platform randomness sources:
+ * Linux -> `getrandom(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. http://man7.org/linux/man-pages/man2/getrandom.2.html, https://linux.die.net/man/4/urandom
+ * macOS -> `getentropy(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. https://www.unix.com/man-page/mojave/2/getentropy, https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man4/random.4.auto.html
+ * FreeBSD -> `getrandom(2)`(`sys/random.h`), if not available `kern.arandom` should be used. https://www.freebsd.org/cgi/man.cgi?query=getrandom, https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
+ * OpenBSD -> `getentropy(2)`(`unistd.h`), if not available `/dev/urandom` should be used. https://man.openbsd.org/getentropy, https://man.openbsd.org/urandom
+ * Windows -> `BCryptGenRandom`(`bcrypt.h`). https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
+ */
+
+#if defined(_WIN32)
+#include
+#include
+#include
+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
+#include
+#elif defined(__OpenBSD__)
+#include
+#else
+#error "Couldn't identify the OS"
+#endif
+
+#include
+#include
+#include
+
+
+/* Returns 1 on success, and 0 on failure. */
+static int fill_random(unsigned char* data, size_t size) {
+#if defined(_WIN32)
+ NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+ if (res != STATUS_SUCCESS || size > ULONG_MAX) {
+ return 0;
+ } else {
+ return 1;
+ }
+#elif defined(__linux__) || defined(__FreeBSD__)
+ /* If `getrandom(2)` is not available you should fallback to /dev/urandom */
+ ssize_t res = getrandom(data, size, 0);
+ if (res < 0 || (size_t)res != size ) {
+ return 0;
+ } else {
+ return 1;
+ }
+#elif defined(__APPLE__) || defined(__OpenBSD__)
+ /* If `getentropy(2)` is not available you should fallback to either
+ * `SecRandomCopyBytes` or /dev/urandom */
+ int res = getentropy(data, size);
+ if (res == 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+#endif
+ return 0;
+}
+
+static void print_hex(unsigned char* data, size_t size) {
+ size_t i;
+ printf("0x");
+ for (i = 0; i < size; i++) {
+ printf("%02x", data[i]);
+ }
+ printf("\n");
+}
diff --git a/examples/schnorr.c b/examples/schnorr.c
new file mode 100644
index 0000000000..82eb07d5d7
--- /dev/null
+++ b/examples/schnorr.c
@@ -0,0 +1,152 @@
+/*************************************************************************
+ * Written in 2020-2022 by Elichai Turkel *
+ * To the extent possible under law, the author(s) have dedicated all *
+ * copyright and related and neighboring rights to the software in this *
+ * file to the public domain worldwide. This software is distributed *
+ * without any warranty. For the CC0 Public Domain Dedication, see *
+ * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
+ *************************************************************************/
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "random.h"
+
+int main(void) {
+ unsigned char msg[12] = "Hello World!";
+ unsigned char msg_hash[32];
+ unsigned char tag[17] = "my_fancy_protocol";
+ unsigned char seckey[32];
+ unsigned char randomize[32];
+ unsigned char auxiliary_rand[32];
+ unsigned char serialized_pubkey[32];
+ unsigned char signature[64];
+ int is_signature_valid;
+ int return_val;
+ secp256k1_xonly_pubkey pubkey;
+ secp256k1_keypair keypair;
+ /* The specification in secp256k1_extrakeys.h states that `secp256k1_keypair_create`
+ * needs a context object initialized for signing. And in secp256k1_schnorrsig.h
+ * they state that `secp256k1_schnorrsig_verify` needs a context initialized for
+ * verification, which is why we create a context for both signing and verification
+ * with the SECP256K1_CONTEXT_SIGN and SECP256K1_CONTEXT_VERIFY flags. */
+ secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
+ if (!fill_random(randomize, sizeof(randomize))) {
+ printf("Failed to generate randomness\n");
+ return 1;
+ }
+ /* Randomizing the context is recommended to protect against side-channel
+ * leakage See `secp256k1_context_randomize` in secp256k1.h for more
+ * information about it. This should never fail. */
+ return_val = secp256k1_context_randomize(ctx, randomize);
+ assert(return_val);
+
+ /*** Key Generation ***/
+
+ /* If the secret key is zero or out of range (bigger than secp256k1's
+ * order), we try to sample a new key. Note that the probability of this
+ * happening is negligible. */
+ while (1) {
+ if (!fill_random(seckey, sizeof(seckey))) {
+ printf("Failed to generate randomness\n");
+ return 1;
+ }
+ /* Try to create a keypair with a valid context, it should only fail if
+ * the secret key is zero or out of range. */
+ if (secp256k1_keypair_create(ctx, &keypair, seckey)) {
+ break;
+ }
+ }
+
+ /* Extract the X-only public key from the keypair. We pass NULL for
+ * `pk_parity` as the parity isn't needed for signing or verification.
+ * `secp256k1_keypair_xonly_pub` supports returning the parity for
+ * other use cases such as tests or verifying Taproot tweaks.
+ * This should never fail with a valid context and public key. */
+ return_val = secp256k1_keypair_xonly_pub(ctx, &pubkey, NULL, &keypair);
+ assert(return_val);
+
+ /* Serialize the public key. Should always return 1 for a valid public key. */
+ return_val = secp256k1_xonly_pubkey_serialize(ctx, serialized_pubkey, &pubkey);
+ assert(return_val);
+
+ /*** Signing ***/
+
+ /* Instead of signing (possibly very long) messages directly, we sign a
+ * 32-byte hash of the message in this example.
+ *
+ * We use secp256k1_tagged_sha256 to create this hash. This function expects
+ * a context-specific "tag", which restricts the context in which the signed
+ * messages should be considered valid. For example, if protocol A mandates
+ * to use the tag "my_fancy_protocol" and protocol B mandates to use the tag
+ * "my_boring_protocol", then signed messages from protocol A will never be
+ * valid in protocol B (and vice versa), even if keys are reused across
+ * protocols. This implements "domain separation", which is considered good
+ * practice. It avoids attacks in which users are tricked into signing a
+ * message that has intended consequences in the intended context (e.g.,
+ * protocol A) but would have unintended consequences if it were valid in
+ * some other context (e.g., protocol B). */
+ return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg));
+ assert(return_val);
+
+ /* Generate 32 bytes of randomness to use with BIP-340 schnorr signing. */
+ if (!fill_random(auxiliary_rand, sizeof(auxiliary_rand))) {
+ printf("Failed to generate randomness\n");
+ return 1;
+ }
+
+ /* Generate a Schnorr signature.
+ *
+ * We use the secp256k1_schnorrsig_sign32 function that provides a simple
+ * interface for signing 32-byte messages (which in our case is a hash of
+ * the actual message). BIP-340 recommends passing 32 bytes of randomness
+ * to the signing function to improve security against side-channel attacks.
+ * Signing with a valid context, a 32-byte message, a verified keypair, and
+ * any 32 bytes of auxiliary random data should never fail. */
+ return_val = secp256k1_schnorrsig_sign32(ctx, signature, msg_hash, &keypair, auxiliary_rand);
+ assert(return_val);
+
+ /*** Verification ***/
+
+ /* Deserialize the public key. This will return 0 if the public key can't
+ * be parsed correctly */
+ if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) {
+ printf("Failed parsing the public key\n");
+ return 1;
+ }
+
+ /* Compute the tagged hash on the received messages using the same tag as the signer. */
+ return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg));
+ assert(return_val);
+
+ /* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
+ is_signature_valid = secp256k1_schnorrsig_verify(ctx, signature, msg_hash, 32, &pubkey);
+
+
+ printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
+ printf("Secret Key: ");
+ print_hex(seckey, sizeof(seckey));
+ printf("Public Key: ");
+ print_hex(serialized_pubkey, sizeof(serialized_pubkey));
+ printf("Signature: ");
+ print_hex(signature, sizeof(signature));
+
+ /* This will clear everything from the context and free the memory */
+ secp256k1_context_destroy(ctx);
+
+ /* It's best practice to try to clear secrets from memory after using them.
+ * This is done because some bugs can allow an attacker to leak memory, for
+ * example through "out of bounds" array access (see Heartbleed), Or the OS
+ * swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
+ *
+ * TODO: Prevent these writes from being optimized out, as any good compiler
+ * will remove any writes that aren't used. */
+ memset(seckey, 0, sizeof(seckey));
+
+ return 0;
+}
diff --git a/src/ecmult_compute_table.h b/src/ecmult_compute_table.h
new file mode 100644
index 0000000000..665f87ff3d
--- /dev/null
+++ b/src/ecmult_compute_table.h
@@ -0,0 +1,16 @@
+/*****************************************************************************************************
+ * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php. *
+ *****************************************************************************************************/
+
+#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_H
+#define SECP256K1_ECMULT_COMPUTE_TABLE_H
+
+/* Construct table of all odd multiples of gen in range 1..(2**(window_g-1)-1). */
+static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen);
+
+/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */
+static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen);
+
+#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_H */
diff --git a/src/ecmult_compute_table_impl.h b/src/ecmult_compute_table_impl.h
new file mode 100644
index 0000000000..69d59ce595
--- /dev/null
+++ b/src/ecmult_compute_table_impl.h
@@ -0,0 +1,49 @@
+/*****************************************************************************************************
+ * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php. *
+ *****************************************************************************************************/
+
+#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H
+#define SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H
+
+#include "ecmult_compute_table.h"
+#include "group_impl.h"
+#include "field_impl.h"
+#include "ecmult.h"
+#include "util.h"
+
+static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen) {
+ secp256k1_gej gj;
+ secp256k1_ge ge, dgen;
+ int j;
+
+ gj = *gen;
+ secp256k1_ge_set_gej_var(&ge, &gj);
+ secp256k1_ge_to_storage(&table[0], &ge);
+
+ secp256k1_gej_double_var(&gj, gen, NULL);
+ secp256k1_ge_set_gej_var(&dgen, &gj);
+
+ for (j = 1; j < ECMULT_TABLE_SIZE(window_g); ++j) {
+ secp256k1_gej_set_ge(&gj, &ge);
+ secp256k1_gej_add_ge_var(&gj, &gj, &dgen, NULL);
+ secp256k1_ge_set_gej_var(&ge, &gj);
+ secp256k1_ge_to_storage(&table[j], &ge);
+ }
+}
+
+/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */
+static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen) {
+ secp256k1_gej gj;
+ int i;
+
+ secp256k1_gej_set_ge(&gj, gen);
+ secp256k1_ecmult_compute_table(table, window_g, &gj);
+ for (i = 0; i < 128; ++i) {
+ secp256k1_gej_double_var(&gj, &gj, NULL);
+ }
+ secp256k1_ecmult_compute_table(table_128, window_g, &gj);
+}
+
+#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H */
diff --git a/src/ecmult_gen_prec.h b/src/ecmult_gen_compute_table.h
similarity index 60%
rename from src/ecmult_gen_prec.h
rename to src/ecmult_gen_compute_table.h
index 0cfcde9b79..e577158d92 100644
--- a/src/ecmult_gen_prec.h
+++ b/src/ecmult_gen_compute_table.h
@@ -4,11 +4,11 @@
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
-#ifndef SECP256K1_ECMULT_GEN_PREC_H
-#define SECP256K1_ECMULT_GEN_PREC_H
+#ifndef SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H
+#define SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H
#include "ecmult_gen.h"
-static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits);
+static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits);
-#endif /* SECP256K1_ECMULT_GEN_PREC_H */
+#endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H */
diff --git a/src/ecmult_gen_prec_impl.h b/src/ecmult_gen_compute_table_impl.h
similarity index 90%
rename from src/ecmult_gen_prec_impl.h
rename to src/ecmult_gen_compute_table_impl.h
index bac76c8b13..ff6a2992dc 100644
--- a/src/ecmult_gen_prec_impl.h
+++ b/src/ecmult_gen_compute_table_impl.h
@@ -4,16 +4,16 @@
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
-#ifndef SECP256K1_ECMULT_GEN_PREC_IMPL_H
-#define SECP256K1_ECMULT_GEN_PREC_IMPL_H
+#ifndef SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H
+#define SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H
-#include "ecmult_gen_prec.h"
+#include "ecmult_gen_compute_table.h"
#include "group_impl.h"
#include "field_impl.h"
#include "ecmult_gen.h"
#include "util.h"
-static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits) {
+static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits) {
int g = ECMULT_GEN_PREC_G(bits);
int n = ECMULT_GEN_PREC_N(bits);
@@ -78,4 +78,4 @@ static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table,
free(prec);
}
-#endif /* SECP256K1_ECMULT_GEN_PREC_IMPL_H */
+#endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H */
diff --git a/src/gen_ecmult_static_pre_g.c b/src/gen_ecmult_static_pre_g.c
deleted file mode 100644
index ba1d1f17d7..0000000000
--- a/src/gen_ecmult_static_pre_g.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*****************************************************************************************************
- * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor *
- * Distributed under the MIT software license, see the accompanying *
- * file COPYING or https://www.opensource.org/licenses/mit-license.php. *
- *****************************************************************************************************/
-
-#include
-#include
-
-/* Autotools creates libsecp256k1-config.h, of which ECMULT_WINDOW_SIZE is needed.
- ifndef guard so downstream users can define their own if they do not use autotools. */
-#if !defined(ECMULT_WINDOW_SIZE)
-#include "libsecp256k1-config.h"
-#endif
-
-#include "../include/secp256k1.h"
-#include "assumptions.h"
-#include "util.h"
-#include "field_impl.h"
-#include "group_impl.h"
-#include "ecmult.h"
-
-void print_table(FILE *fp, const char *name, int window_g, const secp256k1_gej *gen, int with_conditionals) {
- static secp256k1_gej gj;
- static secp256k1_ge ge, dgen;
- static secp256k1_ge_storage ges;
- int j;
- int i;
-
- gj = *gen;
- secp256k1_ge_set_gej_var(&ge, &gj);
- secp256k1_ge_to_storage(&ges, &ge);
-
- fprintf(fp, "static const secp256k1_ge_storage %s[ECMULT_TABLE_SIZE(WINDOW_G)] = {\n", name);
- fprintf(fp, " S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
- ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n",
- SECP256K1_GE_STORAGE_CONST_GET(ges));
-
- secp256k1_gej_double_var(&gj, gen, NULL);
- secp256k1_ge_set_gej_var(&dgen, &gj);
-
- j = 1;
- for(i = 3; i <= window_g; ++i) {
- if (with_conditionals) {
- fprintf(fp, "#if ECMULT_TABLE_SIZE(WINDOW_G) > %ld\n", ECMULT_TABLE_SIZE(i-1));
- }
- for(;j < ECMULT_TABLE_SIZE(i); ++j) {
- secp256k1_gej_set_ge(&gj, &ge);
- secp256k1_gej_add_ge_var(&gj, &gj, &dgen, NULL);
- secp256k1_ge_set_gej_var(&ge, &gj);
- secp256k1_ge_to_storage(&ges, &ge);
-
- fprintf(fp, ",S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
- ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n",
- SECP256K1_GE_STORAGE_CONST_GET(ges));
- }
- if (with_conditionals) {
- fprintf(fp, "#endif\n");
- }
- }
- fprintf(fp, "};\n");
-}
-
-void print_two_tables(FILE *fp, int window_g, const secp256k1_ge *g, int with_conditionals) {
- secp256k1_gej gj;
- int i;
-
- secp256k1_gej_set_ge(&gj, g);
- print_table(fp, "secp256k1_pre_g", window_g, &gj, with_conditionals);
- for (i = 0; i < 128; ++i) {
- secp256k1_gej_double_var(&gj, &gj, NULL);
- }
- print_table(fp, "secp256k1_pre_g_128", window_g, &gj, with_conditionals);
-}
-
-int main(void) {
- const secp256k1_ge g = SECP256K1_G;
- const secp256k1_ge g_13 = SECP256K1_G_ORDER_13;
- const secp256k1_ge g_199 = SECP256K1_G_ORDER_199;
- const int window_g_13 = 4;
- const int window_g_199 = 8;
- FILE* fp;
-
- fp = fopen("src/ecmult_static_pre_g.h","w");
- if (fp == NULL) {
- fprintf(stderr, "Could not open src/ecmult_static_pre_g.h for writing!\n");
- return -1;
- }
-
- fprintf(fp, "/* This file was automatically generated by gen_ecmult_static_pre_g. */\n");
- fprintf(fp, "/* This file contains an array secp256k1_pre_g with odd multiples of the base point G and\n");
- fprintf(fp, " * an array secp256k1_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G.\n");
- fprintf(fp, " */\n");
- fprintf(fp, "#ifndef SECP256K1_ECMULT_STATIC_PRE_G_H\n");
- fprintf(fp, "#define SECP256K1_ECMULT_STATIC_PRE_G_H\n");
- fprintf(fp, "#include \"group.h\"\n");
- fprintf(fp, "#ifdef S\n");
- fprintf(fp, " #error macro identifier S already in use.\n");
- fprintf(fp, "#endif\n");
- fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) "
- "SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,"
- "0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n");
- fprintf(fp, "#if ECMULT_TABLE_SIZE(ECMULT_WINDOW_SIZE) > %ld\n", ECMULT_TABLE_SIZE(ECMULT_WINDOW_SIZE));
- fprintf(fp, " #error configuration mismatch, invalid ECMULT_WINDOW_SIZE. Try deleting ecmult_static_pre_g.h before the build.\n");
- fprintf(fp, "#endif\n");
- fprintf(fp, "#if defined(EXHAUSTIVE_TEST_ORDER)\n");
- fprintf(fp, "#if EXHAUSTIVE_TEST_ORDER == 13\n");
- fprintf(fp, "#define WINDOW_G %d\n", window_g_13);
-
- print_two_tables(fp, window_g_13, &g_13, 0);
-
- fprintf(fp, "#elif EXHAUSTIVE_TEST_ORDER == 199\n");
- fprintf(fp, "#define WINDOW_G %d\n", window_g_199);
-
- print_two_tables(fp, window_g_199, &g_199, 0);
-
- fprintf(fp, "#else\n");
- fprintf(fp, " #error No known generator for the specified exhaustive test group order.\n");
- fprintf(fp, "#endif\n");
- fprintf(fp, "#else /* !defined(EXHAUSTIVE_TEST_ORDER) */\n");
- fprintf(fp, "#define WINDOW_G ECMULT_WINDOW_SIZE\n");
-
- print_two_tables(fp, ECMULT_WINDOW_SIZE, &g, 1);
-
- fprintf(fp, "#endif\n");
- fprintf(fp, "#undef S\n");
- fprintf(fp, "#endif\n");
- fclose(fp);
-
- return 0;
-}
diff --git a/src/hash.h b/src/hash.h
index 288af4f86b..4e0384cfbf 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -1,346 +1,41 @@
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2020 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BGL_HASH_H
-#define BGL_HASH_H
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include "logging.h"
-
-extern "C" {
-#include
-}
-
-typedef uint256 ChainCode;
-
-/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
-class CHash256 {
-private:
- CSHA256 sha;
-public:
- static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
-
- void Finalize(Span output) {
- assert(output.size() == OUTPUT_SIZE);
- unsigned char buf[CSHA256::OUTPUT_SIZE];
- sha.Finalize(buf);
- sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
- }
-
- CHash256& Write(Span input) {
- sha.Write(input.data(), input.size());
- return *this;
- }
-
- CHash256& Reset() {
- sha.Reset();
- return *this;
- }
-};
-
-/** A hasher class for BGL's 256-bit hash (single SHA-256). Used for tx ids/hashes */
-class CHash256Single {
-private:
- CSHA256 sha;
-public:
- static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
-
- void Finalize(unsigned char hash[OUTPUT_SIZE]) {
- sha.Finalize(hash);
- }
-
- CHash256Single& Write(const unsigned char *data, size_t len) {
- sha.Write(data, len);
- return *this;
- }
-
- CHash256Single& Reset() {
- sha.Reset();
- return *this;
- }
-};
-
-/** A SHA3 hasher class specifically for blocks and transactions of BGL. */
-class CHash256Keccak {
-private:
- sha3_context sha3context;
-public:
- static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
-
- CHash256Keccak() {
- sha3_Init256(&sha3context);
- sha3_SetFlags(&sha3context, SHA3_FLAGS_KECCAK);
- }
-
- void Finalize(unsigned char hash[OUTPUT_SIZE]) {
- void const *buf;
- buf = sha3_Finalize(&sha3context);
-
- for (int i = 0; i < 32; i++)
- {
- hash[i] = ((const unsigned char *) buf)[i];
- }
- }
-
- CHash256Keccak& Write(const unsigned char *data, size_t len) {
- sha3_Update(&sha3context, data, len);
- return *this;
- }
-
- CHash256Keccak& Reset() {
- sha3_Init256(&sha3context);
- return *this;
- }
-};
-
-/** A hasher class for BGL's 160-bit hash (SHA-256 + RIPEMD-160). */
-class CHash160 {
-private:
- CSHA256 sha;
-public:
- static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
-
- void Finalize(Span output) {
- assert(output.size() == OUTPUT_SIZE);
- unsigned char buf[CSHA256::OUTPUT_SIZE];
- sha.Finalize(buf);
- CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
- }
-
- CHash160& Write(Span input) {
- sha.Write(input.data(), input.size());
- return *this;
- }
-
- CHash160& Reset() {
- sha.Reset();
- return *this;
- }
-};
-
-/** Compute the 256-bit hash of an object. */
-template
-inline uint256 Hash(const T& in1)
-{
- uint256 result;
- CHash256().Write(MakeUCharSpan(in1)).Finalize(result);
- return result;
-}
-
-/** Compute the 256-bit hash of the concatenation of two objects. */
-template
-inline uint256 Hash(const T1& in1, const T2& in2) {
- uint256 result;
- CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result);
- return result;
-}
-
-/** Compute the 160-bit hash an object. */
-template
-inline uint160 Hash160(const T1& in1)
-{
- uint160 result;
- CHash160().Write(MakeUCharSpan(in1)).Finalize(result);
- return result;
-}
-
-/** A writer stream (for serialization) that computes a 256-bit Keccak hash. */
-class CHashWriterKeccak
-{
-private:
- CHash256Keccak ctx;
-
- const int nType;
- const int nVersion;
-public:
-
- CHashWriterKeccak(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
-
- int GetType() const { return nType; }
- int GetVersion() const { return nVersion; }
-
- void write(const char *pch, size_t size) {
- ctx.Write((const unsigned char*)pch, size);
- }
-
- /** Compute the double-SHA256 hash of all data written to this object.
- *
- * Invalidates this object.
- */
- uint256 GetHash() {
- uint256 result;
- ctx.Finalize((unsigned char*)&result);
- return result;
- }
-
- /** Compute the SHA256 hash of all data written to this object.
- *
- * Invalidates this object.
- */
- //uint256 GetSHA256() {
- // uint256 result;
- // ctx.Finalize(result.begin());
- // return result;
- //}
-
- /**
- * Returns the first 64 bits from the resulting hash.
- */
- inline uint64_t GetCheapHash() {
- unsigned char result[CHash256::OUTPUT_SIZE];
- ctx.Finalize(result);
- return ReadLE64(result);
- }
-
- template
- CHashWriterKeccak& operator<<(const T& obj) {
- // Serialize to this stream
- ::Serialize(*this, obj);
- return (*this);
- }
-};
-
-
-class CHashWriterSHA256
-{
-private:
- CHash256Single ctx;
-
- const int nType;
- const int nVersion;
-public:
-
- CHashWriterSHA256(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
-
- int GetType() const { return nType; }
- int GetVersion() const { return nVersion; }
-
- void write(Span src)
- {
- ctx.Write(UCharCast(src.data()), src.size());
- }
-
- /** Compute the double-SHA256 hash of all data written to this object.
- *
- * Invalidates this object.
- */
- uint256 GetHash() {
- uint256 result;
- ctx.Finalize(result.begin());
- ctx.Reset().Write(result.begin(), CSHA256::OUTPUT_SIZE).Finalize(result.begin());
- return result;
- }
-// uint256 GetHash() {
-// uint256 result;
-// ctx.Finalize(result.begin());
-// return result;
-// }
-
- /** Compute the SHA256 hash of all data written to this object.
- *
- * Invalidates this object.
- */
- uint256 GetSHA256() {
- uint256 result;
- ctx.Finalize(result.begin());
- return result;
- }
-
- /**
- * Returns the first 64 bits from the resulting hash.
- */
- inline uint64_t GetCheapHash() {
- unsigned char result[CHash256::OUTPUT_SIZE];
- ctx.Finalize(result);
- return ReadLE64(result);
- }
-
- template
- CHashWriterSHA256& operator<<(const T& obj) {
- // Serialize to this stream
- ::Serialize(*this, obj);
- return (*this);
- }
-};
-
-/** Reads data from an underlying stream, while hashing the read data. */
-template
-class CHashVerifier : public CHashWriterKeccak
-{
-private:
- Source* source;
-
-public:
- explicit CHashVerifier(Source* source_) : CHashWriterKeccak(source_->GetType(), source_->GetVersion()), source(source_) {}
-
- void read(Span dst)
- {
- source->read(dst);
- this->write(dst);
- }
-
- void ignore(size_t nSize)
- {
- std::byte data[1024];
- while (nSize > 0) {
- size_t now = std::min(nSize, 1024);
- read({data, now});
- nSize -= now;
- }
- }
-
- template
- CHashVerifier