Repository: bitcoin-core/secp256k1
Pull request #1084 (2022-03-10 19:12:01)

ci: Add MSVC builds
This adds MSVC builds built on Linux using wine. This requires some
settings of tools and flags because the autotools support for MSVC is
naturally somewhat limited.

The advantage of this approach is that it is compatible with our
existing CI scripts, so there's no need to write a Windows CI script
(in PowerShell or similar). If we want to test building and running on
Windows native (e.g., as supported by Cirrus CI) we could still do this
in the future.

Another advantage of this approach is that contributors can simply use
the docker image if they need a MSVC installation in a non-Windows
environment.

real-or-random: by the way, rather for fun:	
```
Benchmark                     ,    Min(us)    ,    Avg(us)    ,    Max(us)

32-bit MSVC -O2 (over wine):
ecdsa_verify                  ,   226.0       ,   227.0       ,   230.0
ecdsa_sign                    ,   133.0       ,   134.0       ,   134.0
ecdh                          ,   226.0       ,   227.0       ,   229.0
ecdsa_recover                 ,   230.0       ,   231.0       ,   233.0
schnorrsig_sign               ,   120.0       ,   120.0       ,   123.0
schnorrsig_verify             ,   227.0       ,   228.0       ,   232.0

32-bit MinGw -O2 (over wine):
ecdsa_verify                  ,   195.0       ,   196.0       ,   198.0
ecdsa_sign                    ,   115.0       ,   116.0       ,   117.0
ecdh                          ,   199.0       ,   200.0       ,   204.0
ecdsa_recover                 ,   199.0       ,   200.0       ,   204.0
schnorrsig_sign               ,   101.0       ,   102.0       ,   103.0
schnorrsig_verify             ,   196.0       ,   197.0       ,   200.0

32-bit Linux GCC -O2:
ecdsa_verify                  ,    95.6       ,    96.0       ,    96.7    
ecdsa_sign                    ,    64.9       ,    65.6       ,    68.0    
ecdh                          ,    98.7       ,    99.4       ,   102.0    
ecdsa_recover                 ,    97.9       ,    98.8       ,   100.0    
schnorrsig_sign               ,    55.0       ,    55.4       ,    56.6    
schnorrsig_verify             ,    95.9       ,    97.0       ,    99.5   
```

(Not sure why windows binaries are so much slower. Maybe there's something wrong with testing on Linux but wine shouldn't have a large overhead...)
real-or-random: Ready for review (if CI passes...)
real-or-random: This will probably conflict with #1088. Let's first try to merge the fix there. 

Patch:
diff --git a/.cirrus.yml b/.cirrus.yml
index a2e7f36..647457c 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -67,12 +67,12 @@ task:
   << : *LINUX_CONTAINER
   matrix: &ENV_MATRIX
     - env: {WIDEMUL:  int64,  RECOVERY: yes}
-    - env: {WIDEMUL:  int64,                 ECDH: yes, SCHNORRSIG: yes}
+    - env: {WIDEMUL:  int64,                 ECDH: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes}
     - env: {WIDEMUL: int128}
-    - env: {WIDEMUL: int128,  RECOVERY: yes,            SCHNORRSIG: yes}
-    - env: {WIDEMUL: int128,                 ECDH: yes, SCHNORRSIG: yes}
+    - env: {WIDEMUL: int128,  RECOVERY: yes,            EXPERIMENTAL: yes, SCHNORRSIG: yes}
+    - env: {WIDEMUL: int128,                 ECDH: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes}
     - env: {WIDEMUL: int128,  ASM: x86_64}
-    - env: {                  RECOVERY: yes,            SCHNORRSIG: yes}
+    - env: {                  RECOVERY: yes,            EXPERIMENTAL: yes, SCHNORRSIG: yes}
     - env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETEST: no, BENCH: no}
     - env: {CPPFLAGS: -DDETERMINISTIC}
     - env: {CFLAGS: -O0, CTIMETEST: no}
@@ -95,6 +95,7 @@ task:
     HOST: i686-linux-gnu
     ECDH: yes
     RECOVERY: yes
+    EXPERIMENTAL: yes
     SCHNORRSIG: yes
   matrix:
     - env:
@@ -177,6 +178,7 @@ task:
     WITH_VALGRIND: no
     ECDH: yes
     RECOVERY: yes
+    EXPERIMENTAL: yes
     SCHNORRSIG: yes
     CTIMETEST: no
   << : *MERGE_BASE
@@ -196,11 +198,12 @@ task:
     WITH_VALGRIND: no
     ECDH: yes
     RECOVERY: yes
+    EXPERIMENTAL: yes
     SCHNORRSIG: yes
     CTIMETEST: no
   matrix:
     - env: {}
-    - env: {EXPERIMENTAL: yes, ASM: arm}
+    - env: {ASM: arm}
   << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
@@ -216,6 +219,7 @@ task:
     WITH_VALGRIND: no
     ECDH: yes
     RECOVERY: yes
+    EXPERIMENTAL: yes
     SCHNORRSIG: yes
     CTIMETEST: no
   << : *MERGE_BASE
@@ -233,6 +237,7 @@ task:
     WITH_VALGRIND: no
     ECDH: yes
     RECOVERY: yes
+    EXPERIMENTAL: yes
     SCHNORRSIG: yes
     CTIMETEST: no
   << : *MERGE_BASE
@@ -241,17 +246,58 @@ task:
   << : *CAT_LOGS
 
 task:
-  name: "x86_64 (mingw32-w64): Windows (Debian stable, Wine)"
   << : *LINUX_CONTAINER
   env:
-    WRAPPER_CMD: wine64-stable
-    SECP256K1_TEST_ITERS: 16
-    HOST: x86_64-w64-mingw32
+    WRAPPER_CMD: wine
+    WITH_VALGRIND: no
+    ECDH: yes
+    RECOVERY: yes
+    EXPERIMENTAL: yes
+    SCHNORRSIG: yes
+    CTIMETEST: no
+  matrix:
+    - name: "x86_64 (mingw32-w64): Windows (Debian stable, Wine)"
+      env:
+        HOST: x86_64-w64-mingw32
+    - name: "i686 (mingw32-w64): Windows (Debian stable, Wine)"
+      env:
+        HOST: i686-w64-mingw32
+  << : *MERGE_BASE
+  test_script:
+    - ./ci/cirrus.sh
+  << : *CAT_LOGS
+
+task:
+  << : *LINUX_CONTAINER
+  env:
+    WRAPPER_CMD: wine
+    WERROR_CFLAGS: -WX
     WITH_VALGRIND: no
     ECDH: yes
     RECOVERY: yes
+    EXPERIMENTAL: yes
     SCHNORRSIG: yes
     CTIMETEST: no
+    # Set non-essential options that affect the CLI messages here.
+    # (They depend on the user's taste, so we don't want to set them automatically in configure.ac.)
+    CFLAGS: -nologo -diagnostics:caret
+    LDFLAGS: -XCClinker -nologo -XCClinker -diagnostics:caret
+  # Use a MinGW-w64 host to tell ./configure we're building for Windows.
+  # This will detect some MinGW-w64 tools but then make will need only
+  # the MSVC tools CC, AR and NM as specified below.
+  matrix:
+    - name: "x86_64 (MSVC): Windows (Debian stable, Wine)"
+      env:
+        HOST: x86_64-w64-mingw32
+        CC: /opt/msvc/bin/x64/cl
+        AR: /opt/msvc/bin/x64/lib
+        NM: /opt/msvc/bin/x64/dumpbin -symbols -headers
+    - name: "i686 (MSVC): Windows (Debian stable, Wine)"
+      env:
+        HOST: i686-w64-mingw32
+        CC: /opt/msvc/bin/x86/cl
+        AR: /opt/msvc/bin/x86/lib
+        NM: /opt/msvc/bin/x86/dumpbin -symbols -headers
   << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
@@ -263,6 +309,7 @@ task:
   env:
     ECDH: yes
     RECOVERY: yes
+    EXPERIMENTAL: yes
     SCHNORRSIG: yes
     CTIMETEST: no
   matrix:
@@ -302,14 +349,14 @@ task:
   << : *CAT_LOGS
 
 task:
-  name: "C++ -fpermissive"
+  name: "C++ -fpermissive (entire project)"
   << : *LINUX_CONTAINER
   env:
-    # ./configure correctly errors out when given CC=g++.
-    # We hack around this by passing CC=g++ only to make.
-    CC: gcc
-    MAKEFLAGS: -j4 CC=g++ CFLAGS=-fpermissive\ -g
+    CC: g++
+    CFLAGS: -fpermissive -g
+    CPPFLAGS: -DSECP256K1_CPLUSPLUS_TEST_OVERRIDE
     WERROR_CFLAGS:
+    EXPERIMENTAL: yes
     ECDH: yes
     RECOVERY: yes
     SCHNORRSIG: yes
@@ -318,6 +365,14 @@ task:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
 
+task:
+  name: "C++ (public headers)"
+  << : *LINUX_CONTAINER
+  test_script:
+    - g++ -Werror include/*.h
+    - clang -Werror -x c++-header include/*.h
+    - /opt/msvc/bin/x64/cl.exe -c -WX -TP include/*.h
+
 task:
   name: "sage prover"
   << : *LINUX_CONTAINER
diff --git a/README.md b/README.md
index f5db915..f1ae215 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,9 @@ Features:
 * Suitable for embedded systems.
 * Optional module for public key recovery.
 * Optional module for ECDH key exchange.
-* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
+* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) (experimental).
+
+Experimental features have not received enough scrutiny to satisfy the standard of quality of this library but are made available for testing and review by the community. The APIs of these features should not be considered stable.
 
 Implementation details
 ----------------------
@@ -33,7 +35,6 @@ Implementation details
   * 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).
@@ -68,15 +69,13 @@ libsecp256k1 is built using autotools:
     $ 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`.
+  For experimental modules, you will also need `--enable-experimental` as well as a flag for each individual module, e.g. `--enable-module-ecdh`.
   * [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`.
+  * [Schnorr Signatures example](examples/schnorr.c)
+  * [Deriving a shared secret(ECDH) example](examples/ecdh.c)
 
 Test coverage
 -----------
diff --git a/build-aux/m4/bitcoin_secp.m4 b/build-aux/m4/bitcoin_secp.m4
index 9cb54de..61ca3c2 100644
--- a/build-aux/m4/bitcoin_secp.m4
+++ b/build-aux/m4/bitcoin_secp.m4
@@ -1,7 +1,7 @@
 dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell.
 AC_DEFUN([SECP_64BIT_ASM_CHECK],[
 AC_MSG_CHECKING(for x86_64 assembly availability)
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
   #include <stdint.h>]],[[
   uint64_t a = 11, tmp;
   __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
@@ -10,6 +10,7 @@ AC_MSG_RESULT([$has_64bit_asm])
 ])
 
 AC_DEFUN([SECP_VALGRIND_CHECK],[
+AC_MSG_CHECKING([for valgrind support])
 if test x"$has_valgrind" != x"yes"; then
   CPPFLAGS_TEMP="$CPPFLAGS"
   CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS"
@@ -21,6 +22,7 @@ if test x"$has_valgrind" != x"yes"; then
     #endif
   ]])], [has_valgrind=yes; AC_DEFINE(HAVE_VALGRIND,1,[Define this symbol if valgrind is installed, and it supports the host platform])])
 fi
+AC_MSG_RESULT($has_valgrind)
 ])
 
 dnl SECP_TRY_APPEND_CFLAGS(flags, VAR)
diff --git a/ci/cirrus.sh b/ci/cirrus.sh
index b85f012..23f7c6d 100755
--- a/ci/cirrus.sh
+++ b/ci/cirrus.sh
@@ -5,10 +5,20 @@ set -x
 
 export LC_ALL=C
 
+# Start persistent wineserver if necessary.
+# This speeds up jobs with many invocations of wine (e.g., ./configure with MSVC) tremendously.
+case "$WRAPPER_CMD" in
+    *wine*)
+        # This is apparently only reliable when we run a dummy command such as "hh.exe" afterwards.
+        wineserver -p && wine hh.exe
+        ;;
+esac
+
 env >> test_env.log
 
 $CC -v || true
 valgrind --version || true
+$WRAPPER_CMD --version || true
 
 ./autogen.sh
 
@@ -63,6 +73,9 @@ then
     make precomp
 fi
 
+# Shutdown wineserver again
+wineserver -k || true
+
 # Check that no repo files have been modified by the build.
 # (This fails for example if the precomp files need to be updated in the repo.)
 git diff --exit-code
diff --git a/ci/linux-debian.Dockerfile b/ci/linux-debian.Dockerfile
index 5cccbb5..a83a4e3 100644
--- a/ci/linux-debian.Dockerfile
+++ b/ci/linux-debian.Dockerfile
@@ -1,15 +1,14 @@
 FROM debian:stable
 
-RUN dpkg --add-architecture i386
-RUN dpkg --add-architecture s390x
-RUN dpkg --add-architecture armhf
-RUN dpkg --add-architecture arm64
-RUN dpkg --add-architecture ppc64el
-RUN apt-get update
+RUN dpkg --add-architecture i386 && \
+    dpkg --add-architecture s390x && \
+    dpkg --add-architecture armhf && \
+    dpkg --add-architecture arm64 && \
+    dpkg --add-architecture ppc64el
 
 # dkpg-dev: to make pkg-config work in cross-builds
 # llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces
-RUN apt-get install --no-install-recommends --no-upgrade -y \
+RUN apt-get update && apt-get install --no-install-recommends -y \
         git ca-certificates \
         make automake libtool pkg-config dpkg-dev valgrind qemu-user \
         gcc clang llvm libc6-dbg \
@@ -19,8 +18,20 @@ 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 \
+        gcc-mingw-w64-x86-64-win32 wine64 wine \
+        gcc-mingw-w64-i686-win32 wine32 \
         sagemath
 
-# Run a dummy command in wine to make it set up configuration
-RUN wine64-stable xcopy || true
+WORKDIR /root
+# The "wine" package provides a convience wrapper that we need
+RUN apt-get update && apt-get install --no-install-recommends -y \
+        git ca-certificates wine64 wine python3-simplejson python3-six msitools winbind procps && \
+    git clone https://github.com/mstorsjo/msvc-wine && \
+    mkdir /opt/msvc && \
+    python3 msvc-wine/vsdownload.py --accept-license --dest /opt/msvc Microsoft.VisualStudio.Workload.VCTools && \
+    msvc-wine/install.sh /opt/msvc
+
+# Initialize the wine environment. Wait until the wineserver process has
+# exited before closing the session, to avoid corrupting the wine prefix.
+RUN wine64 wineboot --init && \
+    while (ps -A | grep wineserver) > /dev/null; do sleep 1; done
diff --git a/configure.ac b/configure.ac
index 2db59a8..cd5b304 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,14 +33,18 @@ AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 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
 
+# Clear some cache variables as a workaround for a bug that appears due to a bad
+# interaction between AM_PROG_AR and LT_INIT when combining MSVC's archiver lib.exe.
+# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=54421
+AS_UNSET(ac_cv_prog_AR)
+AS_UNSET(ac_cv_prog_ac_ct_AR)
 LT_INIT([win32-dll])
 
+PKG_PROG_PKG_CONFIG
+
 build_windows=no
 
 case $host_os in
@@ -87,23 +91,35 @@ esac
 #
 # TODO We should analogously not touch CPPFLAGS and LDFLAGS but currently there are no issues.
 AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
-    # Try to append -Werror=unknown-warning-option to CFLAGS temporarily. Otherwise clang will
-    # not error out if it gets unknown warning flags and the checks here will always succeed
-    # no matter if clang knows the flag or not.
-    SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS"
-    SECP_TRY_APPEND_CFLAGS([-Werror=unknown-warning-option], CFLAGS)
-
-    SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
-    SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
-    SECP_TRY_APPEND_CFLAGS([-Wall], $1) # GCC >= 2.95 and probably many other compilers
-    SECP_TRY_APPEND_CFLAGS([-Wno-unused-function], $1) # GCC >= 3.0, -Wunused-function is implied by -Wall.
-    SECP_TRY_APPEND_CFLAGS([-Wextra], $1) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
-    SECP_TRY_APPEND_CFLAGS([-Wcast-align], $1) # GCC >= 2.95
-    SECP_TRY_APPEND_CFLAGS([-Wcast-align=strict], $1) # GCC >= 8.0
-    SECP_TRY_APPEND_CFLAGS([-Wconditional-uninitialized], $1) # Clang >= 3.0 only
-    SECP_TRY_APPEND_CFLAGS([-fvisibility=hidden], $1) # GCC >= 4.0
-
-    CFLAGS="$SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS"
+    # GCC and compatible (incl. clang)
+    if test "x$GCC" = "xyes"; then
+      # Try to append -Werror=unknown-warning-option to CFLAGS temporarily. Otherwise clang will
+      # not error out if it gets unknown warning flags and the checks here will always succeed
+      # no matter if clang knows the flag or not.
+      SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS"
+      SECP_TRY_APPEND_CFLAGS([-Werror=unknown-warning-option], CFLAGS)
+
+      SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
+      SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
+      SECP_TRY_APPEND_CFLAGS([-Wall], $1) # GCC >= 2.95 and probably many other compilers
+      SECP_TRY_APPEND_CFLAGS([-Wno-unused-function], $1) # GCC >= 3.0, -Wunused-function is implied by -Wall.
+      SECP_TRY_APPEND_CFLAGS([-Wextra], $1) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
+      SECP_TRY_APPEND_CFLAGS([-Wcast-align], $1) # GCC >= 2.95
+      SECP_TRY_APPEND_CFLAGS([-Wcast-align=strict], $1) # GCC >= 8.0
+      SECP_TRY_APPEND_CFLAGS([-Wconditional-uninitialized], $1) # Clang >= 3.0 only
+      SECP_TRY_APPEND_CFLAGS([-fvisibility=hidden], $1) # GCC >= 4.0
+
+      CFLAGS="$SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS"
+    fi
+
+    # MSVC
+    # Assume MSVC if we're building for Windows but not with GCC or compatible;
+    # libtool makes the same assumption internally.
+    # Note that "/opt" and "-opt" are equivalent for MSVC; we use "-opt" because "/opt" looks like a path.
+    if test x"$GCC" != x"yes" && test x"$build_windows" = x"yes"; then
+      SECP_TRY_APPEND_CFLAGS([-W2 -wd4146], $1) # Moderate warning level, disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned"
+      SECP_TRY_APPEND_CFLAGS([-external:anglebrackets -external:W0], $1) # Suppress warnings from #include <...> files
+    fi
 ])
 SECP_TRY_APPEND_DEFAULT_CFLAGS(SECP_CFLAGS)
 
@@ -141,7 +157,7 @@ AC_ARG_ENABLE(examples,
     [SECP_SET_DEFAULT([enable_examples], [no], [yes])])
 
 AC_ARG_ENABLE(module_ecdh,
-    AS_HELP_STRING([--enable-module-ecdh],[enable ECDH module [default=no]]), [],
+    AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation]), [],
     [SECP_SET_DEFAULT([enable_module_ecdh], [no], [yes])])
 
 AC_ARG_ENABLE(module_recovery,
@@ -149,11 +165,11 @@ AC_ARG_ENABLE(module_recovery,
     [SECP_SET_DEFAULT([enable_module_recovery], [no], [yes])])
 
 AC_ARG_ENABLE(module_extrakeys,
-    AS_HELP_STRING([--enable-module-extrakeys],[enable extrakeys module [default=no]]), [],
+    AS_HELP_STRING([--enable-module-extrakeys],[enable extrakeys module (experimental)]), [],
     [SECP_SET_DEFAULT([enable_module_extrakeys], [no], [yes])])
 
 AC_ARG_ENABLE(module_schnorrsig,
-    AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=no]]), [],
+    AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module (experimental)]), [],
     [SECP_SET_DEFAULT([enable_module_schnorrsig], [no], [yes])])
 
 AC_ARG_ENABLE(external_default_callbacks,
@@ -326,7 +342,9 @@ if test x"$enable_valgrind" = x"yes"; then
   SECP_INCLUDES="$SECP_INCLUDES $VALGRIND_CPPFLAGS"
 fi
 
-# Add -Werror and similar flags passed from the outside (for testing, e.g., in CI)
+# Add -Werror and similar flags passed from the outside (for testing, e.g., in CI).
+# We don't want to set the user variable CFLAGS in CI because this would disable
+# autoconf's logic for setting default CFLAGS, which we would like to test in CI.
 SECP_CFLAGS="$SECP_CFLAGS $WERROR_CFLAGS"
 
 ###
@@ -364,8 +382,16 @@ 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([Building extrakeys module: $enable_module_extrakeys])
+  AC_MSG_NOTICE([Building schnorrsig module: $enable_module_schnorrsig])
   AC_MSG_NOTICE([******])
 else
+  if test x"$enable_module_extrakeys" = x"yes"; then
+    AC_MSG_ERROR([extrakeys module is experimental. Use --enable-experimental to allow.])
+  fi
+  if test x"$enable_module_schnorrsig" = x"yes"; then
+    AC_MSG_ERROR([schnorrsig module is experimental. Use --enable-experimental to allow.])
+  fi
   if test x"$set_asm" = x"arm"; then
     AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.])
   fi
@@ -398,6 +424,11 @@ AC_SUBST(LIB_VERSION_CURRENT, _LIB_VERSION_CURRENT)
 AC_SUBST(LIB_VERSION_REVISION, _LIB_VERSION_REVISION)
 AC_SUBST(LIB_VERSION_AGE, _LIB_VERSION_AGE)
 
+# Make sure nothing new is exported so that we don't break the cache.
+PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
+unset PKG_CONFIG_PATH
+PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP"
+
 AC_OUTPUT
 
 echo
diff --git a/examples/schnorr.c b/examples/schnorr.c
index 82eb07d..a3533b6 100644
--- a/examples/schnorr.c
+++ b/examples/schnorr.c
@@ -18,9 +18,16 @@
 #include "random.h"
 
 int main(void) {
-    unsigned char msg[12] = "Hello World!";
-    unsigned char msg_hash[32];
-    unsigned char tag[17] = "my_fancy_protocol";
+    /* 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. */
+    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 auxiliary_rand[32];
@@ -77,38 +84,19 @@ int main(void) {
 
     /*** 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);
+    /* Generate a Schnorr signature `noncefp` and `ndata` allows you to pass a
+     * custom nonce function, passing `NULL` will use the BIP-340 safe default.
+     * BIP-340 recommends passing 32 bytes of randomness to the nonce function to
+     * improve security against side-channel attacks. Signing with a valid
+     * context, verified keypair and the default nonce function should never
+     * fail. */
+    return_val = secp256k1_schnorrsig_sign(ctx, signature, msg_hash, &keypair, auxiliary_rand);
     assert(return_val);
 
     /*** Verification ***/
@@ -120,10 +108,6 @@ int main(void) {
         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);
 
diff --git a/include/secp256k1.h b/include/secp256k1.h
index dddab34..57114b8 100644
--- a/include/secp256k1.h
+++ b/include/secp256k1.h
@@ -141,13 +141,9 @@ typedef int (*secp256k1_nonce_function)(
 # define SECP256K1_NO_BUILD
 #endif
 
-/** At secp256k1 build-time DLL_EXPORT is defined when building objects destined
- *  for a shared library, but not for those intended for static libraries.
- */
-
 #ifndef SECP256K1_API
 # if defined(_WIN32)
-#  if defined(SECP256K1_BUILD) && defined(DLL_EXPORT)
+#  ifdef SECP256K1_BUILD
 #   define SECP256K1_API __declspec(dllexport)
 #  else
 #   define SECP256K1_API
@@ -173,17 +169,6 @@ typedef int (*secp256k1_nonce_function)(
 #  define SECP256K1_ARG_NONNULL(_x)
 # endif
 
-/** Attribute for marking functions, types, and variables as deprecated */
-#if !defined(SECP256K1_BUILD) && defined(__has_attribute)
-# if __has_attribute(__deprecated__)
-#  define SECP256K1_DEPRECATED(_msg) __attribute__ ((__deprecated__(_msg)))
-# else
-#  define SECP256K1_DEPRECATED(_msg)
-# endif
-#else
-# define SECP256K1_DEPRECATED(_msg)
-#endif
-
 /** All flags' lower 8 bits indicate what they're for. Do not use directly. */
 #define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1)
 #define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0)
@@ -656,8 +641,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
 SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
     const secp256k1_context* ctx,
     unsigned char *seckey
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
-  SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead");
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
 
 /** Negates a public key in place.
  *
@@ -697,8 +681,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
     const secp256k1_context* ctx,
     unsigned char *seckey,
     const unsigned char *tweak32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
-  SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_add instead");
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
 
 /** Tweak a public key by adding tweak times the generator to it.
  *
@@ -744,8 +727,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
     const secp256k1_context* ctx,
     unsigned char *seckey,
     const unsigned char *tweak32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
-  SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_mul instead");
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
 
 /** Tweak a public key by multiplying it by a tweak value.
  *
@@ -818,7 +800,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
  *  implementations optimized for a specific tag can precompute the SHA256 state
  *  after hashing the tag hashes.
  *
- *  Returns: 1 always.
+ *  Returns 0 if the arguments are invalid and 1 otherwise.
  *  Args:    ctx: pointer to a context object
  *  Out:  hash32: pointer to a 32-byte array to store the resulting hash
  *  In:      tag: pointer to an array containing the tag
diff --git a/include/secp256k1_extrakeys.h b/include/secp256k1_extrakeys.h
index 09cbeaa..a64d561 100644
--- a/include/secp256k1_extrakeys.h
+++ b/include/secp256k1_extrakeys.h
@@ -81,7 +81,8 @@ SECP256K1_API int secp256k1_xonly_pubkey_cmp(
 
 /** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
  *
- *  Returns: 1 always.
+ *  Returns: 1 if the public key was successfully converted
+ *           0 otherwise
  *
  *  Args:         ctx: pointer to a context object.
  *  Out: xonly_pubkey: pointer to an x-only public key object for placing the converted public key.
@@ -171,7 +172,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
 
 /** Get the secret key from a keypair.
  *
- *  Returns: 1 always.
+ *  Returns: 0 if the arguments are invalid. 1 otherwise.
  *  Args:   ctx: pointer to a context object.
  *  Out: seckey: pointer to a 32-byte buffer for the secret key.
  *  In: keypair: pointer to a keypair.
@@ -184,7 +185,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
 
 /** Get the public key from a keypair.
  *
- *  Returns: 1 always.
+ *  Returns: 0 if the arguments are invalid. 1 otherwise.
  *  Args:    ctx: pointer to a context object.
  *  Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to
  *               the keypair public key. If not, it's set to an invalid value.
@@ -201,7 +202,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
  *  This is the same as calling secp256k1_keypair_pub and then
  *  secp256k1_xonly_pubkey_from_pubkey.
  *
- *  Returns: 1 always.
+ *  Returns: 0 if the arguments are invalid. 1 otherwise.
  *  Args:   ctx: pointer to a context object.
  *  Out: pubkey: pointer to an xonly_pubkey object. If 1 is returned, it is set
  *               to the keypair public key after converting it to an
diff --git a/include/secp256k1_schnorrsig.h b/include/secp256k1_schnorrsig.h
index 5fedcb0..e971ddc 100644
--- a/include/secp256k1_schnorrsig.h
+++ b/include/secp256k1_schnorrsig.h
@@ -116,24 +116,13 @@ typedef struct {
  *                BIP-340 "Default Signing" for a full explanation of this
  *                argument and for guidance if randomness is expensive.
  */
-SECP256K1_API int secp256k1_schnorrsig_sign32(
-    const secp256k1_context* ctx,
-    unsigned char *sig64,
-    const unsigned char *msg32,
-    const secp256k1_keypair *keypair,
-    const unsigned char *aux_rand32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
-
-/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in
- *  future versions. */
 SECP256K1_API int secp256k1_schnorrsig_sign(
     const secp256k1_context* ctx,
     unsigned char *sig64,
     const unsigned char *msg32,
     const secp256k1_keypair *keypair,
     const unsigned char *aux_rand32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
-  SECP256K1_DEPRECATED("Use secp256k1_schnorrsig_sign32 instead");
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
 
 /** Create a Schnorr signature with a more flexible API.
  *
diff --git a/sage/prove_group_implementations.sage b/sage/prove_group_implementations.sage
index 652bd87..96ce335 100644
--- a/sage/prove_group_implementations.sage
+++ b/sage/prove_group_implementations.sage
@@ -40,26 +40,29 @@ def formula_secp256k1_gej_add_var(branch, a, b):
   s2 = s2 * a.Z
   h = -u1
   h = h + u2
-  i = -s2
-  i = i + s1
+  i = -s1
+  i = i + s2
   if branch == 2:
     r = formula_secp256k1_gej_double_var(a)
     return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r)
   if branch == 3:
     return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity())
-  t = h * b.Z
-  rz = a.Z * t
+  i2 = i^2
   h2 = h^2
-  h2 = -h2
   h3 = h2 * h
+  h = h * b.Z
+  rz = a.Z * h
   t = u1 * h2
-  rx = i^2
+  rx = t
+  rx = rx * 2
   rx = rx + h3
-  rx = rx + t
-  rx = rx + t
-  t = t + rx
-  ry = t * i
+  rx = -rx
+  rx = rx + i2
+  ry = -rx
+  ry = ry + t
+  ry = ry * i
   h3 = h3 * s1
+  h3 = -h3
   ry = ry + h3
   return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
 
@@ -77,25 +80,28 @@ def formula_secp256k1_gej_add_ge_var(branch, a, b):
   s2 = s2 * a.Z
   h = -u1
   h = h + u2
-  i = -s2
-  i = i + s1
+  i = -s1
+  i = i + s2
   if (branch == 2):
     r = formula_secp256k1_gej_double_var(a)
     return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
   if (branch == 3):
     return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
-  rz = a.Z * h
+  i2 = i^2
   h2 = h^2
-  h2 = -h2
-  h3 = h2 * h
+  h3 = h * h2
+  rz = a.Z * h
   t = u1 * h2
-  rx = i^2
+  rx = t
+  rx = rx * 2
   rx = rx + h3
-  rx = rx + t
-  rx = rx + t
-  t = t + rx
-  ry = t * i
+  rx = -rx
+  rx = rx + i2
+  ry = -rx
+  ry = ry + t
+  ry = ry * i
   h3 = h3 * s1
+  h3 = -h3
   ry = ry + h3
   return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
 
@@ -103,15 +109,14 @@ def formula_secp256k1_gej_add_zinv_var(branch, a, b):
   """libsecp256k1's secp256k1_gej_add_zinv_var"""
   bzinv = b.Z^(-1)
   if branch == 0:
-    rinf = b.Infinity
+    return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a)
+  if branch == 1:
     bzinv2 = bzinv^2
     bzinv3 = bzinv2 * bzinv
     rx = b.X * bzinv2
     ry = b.Y * bzinv3
     rz = 1
-    return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz, rinf))
-  if branch == 1:
-    return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a)
+    return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz))
   azz = a.Z * bzinv
   z12 = azz^2
   u1 = a.X
@@ -121,25 +126,29 @@ def formula_secp256k1_gej_add_zinv_var(branch, a, b):
   s2 = s2 * azz
   h = -u1
   h = h + u2
-  i = -s2
-  i = i + s1
+  i = -s1
+  i = i + s2
   if branch == 2:
     r = formula_secp256k1_gej_double_var(a)
     return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
   if branch == 3:
     return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
-  rz = a.Z * h
+  i2 = i^2
   h2 = h^2
-  h2 = -h2
-  h3 = h2 * h
+  h3 = h * h2
+  rz = a.Z
+  rz = rz * h
   t = u1 * h2
-  rx = i^2
+  rx = t
+  rx = rx * 2
   rx = rx + h3
-  rx = rx + t
-  rx = rx + t
-  t = t + rx
-  ry = t * i
+  rx = -rx
+  rx = rx + i2
+  ry = -rx
+  ry = ry + t
+  ry = ry * i
   h3 = h3 * s1
+  h3 = -h3
   ry = ry + h3
   return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
 
diff --git a/src/bench.h b/src/bench.h
index aa275fe..611ba11 100644
--- a/src/bench.h
+++ b/src/bench.h
@@ -7,15 +7,31 @@
 #ifndef SECP256K1_BENCH_H
 #define SECP256K1_BENCH_H
 
+#include <stdlib.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
-#include "sys/time.h"
+
+#if (defined(_MSC_VER) && _MSC_VER >= 1900)
+#  include <time.h>
+#else
+#  include "sys/time.h"
+#endif
 
 static int64_t gettime_i64(void) {
+#if (defined(_MSC_VER) && _MSC_VER >= 1900)
+    /* C11 way to get wallclock time */
+    struct timespec tv;
+    if (!timespec_get(&tv, TIME_UTC)) {
+        fputs("timespec_get failed!", stderr);
+        exit(1);
+    }
+    return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL;
+#else
     struct timeval tv;
     gettimeofday(&tv, NULL);
     return (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * 1000000LL;
+#endif
 }
 
 #define FP_EXP (6)
diff --git a/src/bench_internal.c b/src/bench_internal.c
index 7eb3af2..3c145f3 100644
--- a/src/bench_internal.c
+++ b/src/bench_internal.c
@@ -254,15 +254,6 @@ void bench_group_add_affine_var(void* arg, int iters) {
     }
 }
 
-void bench_group_add_zinv_var(void* arg, int iters) {
-    int i;
-    bench_inv *data = (bench_inv*)arg;
-
-    for (i = 0; i < iters; i++) {
-        secp256k1_gej_add_zinv_var(&data->gej[0], &data->gej[0], &data->ge[1], &data->gej[0].y);
-    }
-}
-
 void bench_group_to_affine_var(void* arg, int iters) {
     int i;
     bench_inv *data = (bench_inv*)arg;
@@ -385,7 +376,6 @@ int main(int argc, char **argv) {
     if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, iters*10);
     if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, iters*10);
     if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, iters*10);
-    if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_zinv_var", bench_group_add_zinv_var, bench_setup, NULL, &data, 10, iters*10);
     if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, 10, iters);
 
     if (d || have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, iters);
diff --git a/src/group_impl.h b/src/group_impl.h
index 63735ab..b19b02a 100644
--- a/src/group_impl.h
+++ b/src/group_impl.h
@@ -330,14 +330,15 @@ static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, s
 }
 
 static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) {
-    /* 12 mul, 4 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
-    secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, h2, h3, t;
+    /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */
+    secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
 
     if (a->infinity) {
         VERIFY_CHECK(rzr == NULL);
         *r = *b;
         return;
     }
+
     if (b->infinity) {
         if (rzr != NULL) {
             secp256k1_fe_set_int(rzr, 1);
@@ -346,6 +347,7 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons
         return;
     }
 
+    r->infinity = 0;
     secp256k1_fe_sqr(&z22, &b->z);
     secp256k1_fe_sqr(&z12, &a->z);
     secp256k1_fe_mul(&u1, &a->x, &z22);
@@ -353,7 +355,7 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons
     secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z);
     secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
     secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
-    secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
+    secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
     if (secp256k1_fe_normalizes_to_zero_var(&h)) {
         if (secp256k1_fe_normalizes_to_zero_var(&i)) {
             secp256k1_gej_double_var(r, a, rzr);
@@ -365,33 +367,24 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons
         }
         return;
     }
-
-    r->infinity = 0;
-    secp256k1_fe_mul(&t, &h, &b->z);
+    secp256k1_fe_sqr(&i2, &i);
+    secp256k1_fe_sqr(&h2, &h);
+    secp256k1_fe_mul(&h3, &h, &h2);
+    secp256k1_fe_mul(&h, &h, &b->z);
     if (rzr != NULL) {
-        *rzr = t;
+        *rzr = h;
     }
-    secp256k1_fe_mul(&r->z, &a->z, &t);
-
-    secp256k1_fe_sqr(&h2, &h);
-    secp256k1_fe_negate(&h2, &h2, 1);
-    secp256k1_fe_mul(&h3, &h2, &h);
+    secp256k1_fe_mul(&r->z, &a->z, &h);
     secp256k1_fe_mul(&t, &u1, &h2);
-
-    secp256k1_fe_sqr(&r->x, &i);
-    secp256k1_fe_add(&r->x, &h3);
-    secp256k1_fe_add(&r->x, &t);
-    secp256k1_fe_add(&r->x, &t);
-
-    secp256k1_fe_add(&t, &r->x);
-    secp256k1_fe_mul(&r->y, &t, &i);
-    secp256k1_fe_mul(&h3, &h3, &s1);
+    r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
+    secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
+    secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
     secp256k1_fe_add(&r->y, &h3);
 }
 
 static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) {
-    /* 8 mul, 3 sqr, 13 add/negate/normalize_weak/normalizes_to_zero (ignoring special cases) */
-    secp256k1_fe z12, u1, u2, s1, s2, h, i, h2, h3, t;
+    /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */
+    secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
     if (a->infinity) {
         VERIFY_CHECK(rzr == NULL);
         secp256k1_gej_set_ge(r, b);
@@ -404,6 +397,7 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, c
         *r = *a;
         return;
     }
+    r->infinity = 0;
 
     secp256k1_fe_sqr(&z12, &a->z);
     u1 = a->x; secp256k1_fe_normalize_weak(&u1);
@@ -411,7 +405,7 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, c
     s1 = a->y; secp256k1_fe_normalize_weak(&s1);
     secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
     secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
-    secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
+    secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
     if (secp256k1_fe_normalizes_to_zero_var(&h)) {
         if (secp256k1_fe_normalizes_to_zero_var(&i)) {
             secp256k1_gej_double_var(r, a, rzr);
@@ -423,33 +417,28 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, c
         }
         return;
     }
-
-    r->infinity = 0;
+    secp256k1_fe_sqr(&i2, &i);
+    secp256k1_fe_sqr(&h2, &h);
+    secp256k1_fe_mul(&h3, &h, &h2);
     if (rzr != NULL) {
         *rzr = h;
     }
     secp256k1_fe_mul(&r->z, &a->z, &h);
-
-    secp256k1_fe_sqr(&h2, &h);
-    secp256k1_fe_negate(&h2, &h2, 1);
-    secp256k1_fe_mul(&h3, &h2, &h);
     secp256k1_fe_mul(&t, &u1, &h2);
-
-    secp256k1_fe_sqr(&r->x, &i);
-    secp256k1_fe_add(&r->x, &h3);
-    secp256k1_fe_add(&r->x, &t);
-    secp256k1_fe_add(&r->x, &t);
-
-    secp256k1_fe_add(&t, &r->x);
-    secp256k1_fe_mul(&r->y, &t, &i);
-    secp256k1_fe_mul(&h3, &h3, &s1);
+    r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
+    secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
+    secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
     secp256k1_fe_add(&r->y, &h3);
 }
 
 static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) {
-    /* 9 mul, 3 sqr, 13 add/negate/normalize_weak/normalizes_to_zero (ignoring special cases) */
-    secp256k1_fe az, z12, u1, u2, s1, s2, h, i, h2, h3, t;
+    /* 9 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */
+    secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
 
+    if (b->infinity) {
+        *r = *a;
+        return;
+    }
     if (a->infinity) {
         secp256k1_fe bzinv2, bzinv3;
         r->infinity = b->infinity;
@@ -460,10 +449,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a,
         secp256k1_fe_set_int(&r->z, 1);
         return;
     }
-    if (b->infinity) {
-        *r = *a;
-        return;
-    }
+    r->infinity = 0;
 
     /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to
      *  secp256k1's isomorphism we can multiply the Z coordinates on both sides
@@ -481,7 +467,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a,
     s1 = a->y; secp256k1_fe_normalize_weak(&s1);
     secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az);
     secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
-    secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
+    secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
     if (secp256k1_fe_normalizes_to_zero_var(&h)) {
         if (secp256k1_fe_normalizes_to_zero_var(&i)) {
             secp256k1_gej_double_var(r, a, NULL);
@@ -490,23 +476,14 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a,
         }
         return;
     }
-
-    r->infinity = 0;
-    secp256k1_fe_mul(&r->z, &a->z, &h);
-
+    secp256k1_fe_sqr(&i2, &i);
     secp256k1_fe_sqr(&h2, &h);
-    secp256k1_fe_negate(&h2, &h2, 1);
-    secp256k1_fe_mul(&h3, &h2, &h);
+    secp256k1_fe_mul(&h3, &h, &h2);
+    r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h);
     secp256k1_fe_mul(&t, &u1, &h2);
-
-    secp256k1_fe_sqr(&r->x, &i);
-    secp256k1_fe_add(&r->x, &h3);
-    secp256k1_fe_add(&r->x, &t);
-    secp256k1_fe_add(&r->x, &t);
-
-    secp256k1_fe_add(&t, &r->x);
-    secp256k1_fe_mul(&r->y, &t, &i);
-    secp256k1_fe_mul(&h3, &h3, &s1);
+    r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
+    secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
+    secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
     secp256k1_fe_add(&r->y, &h3);
 }
 
diff --git a/src/hash.h b/src/hash.h
index 4e0384c..0947a09 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -12,8 +12,8 @@
 
 typedef struct {
     uint32_t s[8];
-    unsigned char buf[64];
-    uint64_t bytes;
+    uint32_t buf[16]; /* In big endian */
+    size_t bytes;
 } secp256k1_sha256;
 
 static void secp256k1_sha256_initialize(secp256k1_sha256 *hash);
diff --git a/src/hash_impl.h b/src/hash_impl.h
index 0991fe7..f8cd3a1 100644
--- a/src/hash_impl.h
+++ b/src/hash_impl.h
@@ -28,6 +28,12 @@
     (h) = t1 + t2; \
 } while(0)
 
+#if defined(SECP256K1_BIG_ENDIAN)
+#define BE32(x) (x)
+#elif defined(SECP256K1_LITTLE_ENDIAN)
+#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24))
+#endif
+
 static void secp256k1_sha256_initialize(secp256k1_sha256 *hash) {
     hash->s[0] = 0x6a09e667ul;
     hash->s[1] = 0xbb67ae85ul;
@@ -41,26 +47,26 @@ static void secp256k1_sha256_initialize(secp256k1_sha256 *hash) {
 }
 
 /** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */
-static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* buf) {
+static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) {
     uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
     uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
 
-    Round(a, b, c, d, e, f, g, h, 0x428a2f98,  w0 = secp256k1_read_be32(&buf[0]));
-    Round(h, a, b, c, d, e, f, g, 0x71374491,  w1 = secp256k1_read_be32(&buf[4]));
-    Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf,  w2 = secp256k1_read_be32(&buf[8]));
-    Round(f, g, h, a, b, c, d, e, 0xe9b5dba5,  w3 = secp256k1_read_be32(&buf[12]));
-    Round(e, f, g, h, a, b, c, d, 0x3956c25b,  w4 = secp256k1_read_be32(&buf[16]));
-    Round(d, e, f, g, h, a, b, c, 0x59f111f1,  w5 = secp256k1_read_be32(&buf[20]));
-    Round(c, d, e, f, g, h, a, b, 0x923f82a4,  w6 = secp256k1_read_be32(&buf[24]));
-    Round(b, c, d, e, f, g, h, a, 0xab1c5ed5,  w7 = secp256k1_read_be32(&buf[28]));
-    Round(a, b, c, d, e, f, g, h, 0xd807aa98,  w8 = secp256k1_read_be32(&buf[32]));
-    Round(h, a, b, c, d, e, f, g, 0x12835b01,  w9 = secp256k1_read_be32(&buf[36]));
-    Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = secp256k1_read_be32(&buf[40]));
-    Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = secp256k1_read_be32(&buf[44]));
-    Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = secp256k1_read_be32(&buf[48]));
-    Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = secp256k1_read_be32(&buf[52]));
-    Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = secp256k1_read_be32(&buf[56]));
-    Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = secp256k1_read_be32(&buf[60]));
+    Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = BE32(chunk[0]));
+    Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = BE32(chunk[1]));
+    Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = BE32(chunk[2]));
+    Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = BE32(chunk[3]));
+    Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = BE32(chunk[4]));
+    Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = BE32(chunk[5]));
+    Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = BE32(chunk[6]));
+    Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = BE32(chunk[7]));
+    Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = BE32(chunk[8]));
+    Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = BE32(chunk[9]));
+    Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = BE32(chunk[10]));
+    Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = BE32(chunk[11]));
+    Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = BE32(chunk[12]));
+    Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = BE32(chunk[13]));
+    Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = BE32(chunk[14]));
+    Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = BE32(chunk[15]));
 
     Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
     Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
@@ -130,7 +136,7 @@ static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *
     while (len >= 64 - bufsize) {
         /* Fill the buffer, and process it. */
         size_t chunk_len = 64 - bufsize;
-        memcpy(hash->buf + bufsize, data, chunk_len);
+        memcpy(((unsigned char*)hash->buf) + bufsize, data, chunk_len);
         data += chunk_len;
         len -= chunk_len;
         secp256k1_sha256_transform(hash->s, hash->buf);
@@ -143,19 +149,19 @@ static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *
 }
 
 static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32) {
-    static const unsigned char pad[64] = {0x80};
-    unsigned char sizedesc[8];
-    int i;
-    /* The maximum message size of SHA256 is 2^64-1 bits. */
-    VERIFY_CHECK(hash->bytes < ((uint64_t)1 << 61));
-    secp256k1_write_be32(&sizedesc[0], hash->bytes >> 29);
-    secp256k1_write_be32(&sizedesc[4], hash->bytes << 3);
+    static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    uint32_t sizedesc[2];
+    uint32_t out[8];
+    int i = 0;
+    sizedesc[0] = BE32(hash->bytes >> 29);
+    sizedesc[1] = BE32(hash->bytes << 3);
     secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64));
-    secp256k1_sha256_write(hash, sizedesc, 8);
+    secp256k1_sha256_write(hash, (const unsigned char*)sizedesc, 8);
     for (i = 0; i < 8; i++) {
-        secp256k1_write_be32(&out32[4*i], hash->s[i]);
+        out[i] = BE32(hash->s[i]);
         hash->s[i] = 0;
     }
+    memcpy(out32, (const unsigned char*)out, 32);
 }
 
 /* Initializes a sha256 struct and writes the 64 byte string
@@ -279,6 +285,7 @@ static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256
     rng->retry = 0;
 }
 
+#undef BE32
 #undef Round
 #undef sigma1
 #undef sigma0
diff --git a/src/modules/schnorrsig/bench_impl.h b/src/modules/schnorrsig/bench_impl.h
index 41f393c..84a1727 100644
--- a/src/modules/schnorrsig/bench_impl.h
+++ b/src/modules/schnorrsig/bench_impl.h
@@ -91,10 +91,12 @@ void run_schnorrsig_bench(int iters, int argc, char** argv) {
         free((void *)data.msgs[i]);
         free((void *)data.sigs[i]);
     }
-    free(data.keypairs);
-    free(data.pk);
-    free(data.msgs);
-    free(data.sigs);
+
+    /* Casting to (void *) avoids a stupid warning in MSVC. */
+    free((void *)data.keypairs);
+    free((void *)data.pk);
+    free((void *)data.msgs);
+    free((void *)data.sigs);
 
     secp256k1_context_destroy(data.ctx);
 }
diff --git a/src/modules/schnorrsig/main_impl.h b/src/modules/schnorrsig/main_impl.h
index cd65159..94e3ee4 100644
--- a/src/modules/schnorrsig/main_impl.h
+++ b/src/modules/schnorrsig/main_impl.h
@@ -192,15 +192,11 @@ static int secp256k1_schnorrsig_sign_internal(const secp256k1_context* ctx, unsi
     return ret;
 }
 
-int secp256k1_schnorrsig_sign32(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
+int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
     /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */
     return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, secp256k1_nonce_function_bip340, (unsigned char*)aux_rand32);
 }
 
-int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
-    return secp256k1_schnorrsig_sign32(ctx, sig64, msg32, keypair, aux_rand32);
-}
-
 int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_schnorrsig_extraparams *extraparams) {
     secp256k1_nonce_function_hardened noncefp = NULL;
     void *ndata = NULL;
diff --git a/src/secp256k1.c b/src/secp256k1.c
index 8f34c35..96102d3 100644
--- a/src/secp256k1.c
+++ b/src/secp256k1.c
@@ -4,6 +4,17 @@
  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
  ***********************************************************************/
 
+/* This is a C project. It should not be compiled with a C++ compiler,
+ * and we error out if we detect one.
+ *
+ * We still want to be able to test the project with a C++ compiler
+ * because it is still good to know if this will lead to real trouble, so
+ * there is a possibility to override the check. But be warned that
+ * compiling with a C++ compiler is not supported. */
+#if defined(__cplusplus) && !defined(SECP256K1_CPLUSPLUS_TEST_OVERRIDE)
+#error Trying to compile a C project with a C++ compiler.
+#endif
+
 #define SECP256K1_BUILD
 
 #include "../include/secp256k1.h"
diff --git a/src/util.h b/src/util.h
index dac86bd..04227a7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -173,6 +173,31 @@ static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void
 # define SECP256K1_GNUC_EXT
 #endif
 
+/* If SECP256K1_{LITTLE,BIG}_ENDIAN is not explicitly provided, infer from various other system macros. */
+#if !defined(SECP256K1_LITTLE_ENDIAN) && !defined(SECP256K1_BIG_ENDIAN)
+/* Inspired by https://github.com/rofl0r/endianness.h/blob/9853923246b065a3b52d2c43835f3819a62c7199/endianness.h#L52L73 */
+# if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
+     defined(_X86_) || defined(__x86_64__) || defined(__i386__) || \
+     defined(__i486__) || defined(__i586__) || defined(__i686__) || \
+     defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) || \
+     defined(__ARMEL__) || defined(__AARCH64EL__) || \
+     (defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__ == 1) || \
+     (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN == 1) || \
+     defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM) /* MSVC */
+#  define SECP256K1_LITTLE_ENDIAN
+# endif
+# if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
+     defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) || \
+     defined(__MICROBLAZEEB__) || defined(__ARMEB__) || defined(__AARCH64EB__) || \
+     (defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ == 1) || \
+     (defined(_BIG_ENDIAN) && _BIG_ENDIAN == 1)
+#  define SECP256K1_BIG_ENDIAN
+# endif
+#endif
+#if defined(SECP256K1_LITTLE_ENDIAN) == defined(SECP256K1_BIG_ENDIAN)
+# error Please make sure that either SECP256K1_LITTLE_ENDIAN or SECP256K1_BIG_ENDIAN is set, see src/util.h.
+#endif
+
 /* Zero memory if flag == 1. Flag must be 0 or 1. Constant time. */
 static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag) {
     unsigned char *p = (unsigned char *)s;
@@ -313,20 +338,4 @@ static SECP256K1_INLINE int secp256k1_ctz64_var(uint64_t x) {
 #endif
 }
 
-/* Read a uint32_t in big endian */
-SECP256K1_INLINE static uint32_t secp256k1_read_be32(const unsigned char* p) {
-    return (uint32_t)p[0] << 24 |
-           (uint32_t)p[1] << 16 |
-           (uint32_t)p[2] << 8  |
-           (uint32_t)p[3];
-}
-
-/* Write a uint32_t in big endian */
-SECP256K1_INLINE static void secp256k1_write_be32(unsigned char* p, uint32_t x) {
-    p[3] = x;
-    p[2] = x >>  8;
-    p[1] = x >> 16;
-    p[0] = x >> 24;
-}
-
 #endif /* SECP256K1_UTIL_H */


Test patch:
diff --git a/src/modules/schnorrsig/tests_impl.h b/src/modules/schnorrsig/tests_impl.h
index 25840b8..7c4321f 100644
--- a/src/modules/schnorrsig/tests_impl.h
+++ b/src/modules/schnorrsig/tests_impl.h
@@ -160,21 +160,21 @@ void test_schnorrsig_api(void) {
 
     /** main test body **/
     ecount = 0;
-    CHECK(secp256k1_schnorrsig_sign32(none, sig, msg, &keypairs[0], NULL) == 1);
+    CHECK(secp256k1_schnorrsig_sign(none, sig, msg, &keypairs[0], NULL) == 1);
     CHECK(ecount == 0);
-    CHECK(secp256k1_schnorrsig_sign32(vrfy, sig, msg, &keypairs[0], NULL) == 1);
+    CHECK(secp256k1_schnorrsig_sign(vrfy, sig, msg, &keypairs[0], NULL) == 1);
     CHECK(ecount == 0);
-    CHECK(secp256k1_schnorrsig_sign32(sign, sig, msg, &keypairs[0], NULL) == 1);
+    CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, &keypairs[0], NULL) == 1);
     CHECK(ecount == 0);
-    CHECK(secp256k1_schnorrsig_sign32(sign, NULL, msg, &keypairs[0], NULL) == 0);
+    CHECK(secp256k1_schnorrsig_sign(sign, NULL, msg, &keypairs[0], NULL) == 0);
     CHECK(ecount == 1);
-    CHECK(secp256k1_schnorrsig_sign32(sign, sig, NULL, &keypairs[0], NULL) == 0);
+    CHECK(secp256k1_schnorrsig_sign(sign, sig, NULL, &keypairs[0], NULL) == 0);
     CHECK(ecount == 2);
-    CHECK(secp256k1_schnorrsig_sign32(sign, sig, msg, NULL, NULL) == 0);
+    CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, NULL, NULL) == 0);
     CHECK(ecount == 3);
-    CHECK(secp256k1_schnorrsig_sign32(sign, sig, msg, &invalid_keypair, NULL) == 0);
+    CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, &invalid_keypair, NULL) == 0);
     CHECK(ecount == 4);
-    CHECK(secp256k1_schnorrsig_sign32(sttc, sig, msg, &keypairs[0], NULL) == 0);
+    CHECK(secp256k1_schnorrsig_sign(sttc, sig, msg, &keypairs[0], NULL) == 0);
     CHECK(ecount == 5);
 
     ecount = 0;
@@ -202,7 +202,7 @@ void test_schnorrsig_api(void) {
     CHECK(ecount == 6);
 
     ecount = 0;
-    CHECK(secp256k1_schnorrsig_sign32(sign, sig, msg, &keypairs[0], NULL) == 1);
+    CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, &keypairs[0], NULL) == 1);
     CHECK(secp256k1_schnorrsig_verify(none, sig, msg, sizeof(msg), &pk[0]) == 1);
     CHECK(ecount == 0);
     CHECK(secp256k1_schnorrsig_verify(sign, sig, msg, sizeof(msg), &pk[0]) == 1);
@@ -247,7 +247,7 @@ void test_schnorrsig_bip_vectors_check_signing(const unsigned char *sk, const un
     secp256k1_xonly_pubkey pk, pk_expected;
 
     CHECK(secp256k1_keypair_create(ctx, &keypair, sk));
-    CHECK(secp256k1_schnorrsig_sign32(ctx, sig, msg32, &keypair, aux_rand));
+    CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg32, &keypair, aux_rand));
     CHECK(secp256k1_memcmp_var(sig, expected_sig, 64) == 0);
 
     CHECK(secp256k1_xonly_pubkey_parse(ctx, &pk_expected, pk_serialized));
@@ -740,11 +740,8 @@ void test_schnorrsig_sign(void) {
     secp256k1_testrand256(aux_rand);
     CHECK(secp256k1_keypair_create(ctx, &keypair, sk));
     CHECK(secp256k1_keypair_xonly_pub(ctx, &pk, NULL, &keypair));
-    CHECK(secp256k1_schnorrsig_sign32(ctx, sig, msg, &keypair, NULL) == 1);
+    CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL) == 1);
     CHECK(secp256k1_schnorrsig_verify(ctx, sig, msg, sizeof(msg), &pk));
-    /* Check that deprecated alias gives the same result */
-    CHECK(secp256k1_schnorrsig_sign(ctx, sig2, msg, &keypair, NULL) == 1);
-    CHECK(secp256k1_memcmp_var(sig, sig2, sizeof(sig)) == 0);
 
     /* Test different nonce functions */
     CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, &extraparams) == 1);
@@ -767,7 +764,7 @@ void test_schnorrsig_sign(void) {
     extraparams.noncefp = NULL;
     extraparams.ndata = aux_rand;
     CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, &extraparams) == 1);
-    CHECK(secp256k1_schnorrsig_sign32(ctx, sig2, msg, &keypair, extraparams.ndata) == 1);
+    CHECK(secp256k1_schnorrsig_sign(ctx, sig2, msg, &keypair, extraparams.ndata) == 1);
     CHECK(secp256k1_memcmp_var(sig, sig2, sizeof(sig)) == 0);
 }
 
@@ -790,7 +787,7 @@ void test_schnorrsig_sign_verify(void) {
 
     for (i = 0; i < N_SIGS; i++) {
         secp256k1_testrand256(msg[i]);
-        CHECK(secp256k1_schnorrsig_sign32(ctx, sig[i], msg[i], &keypair, NULL));
+        CHECK(secp256k1_schnorrsig_sign(ctx, sig[i], msg[i], &keypair, NULL));
         CHECK(secp256k1_schnorrsig_verify(ctx, sig[i], msg[i], sizeof(msg[i]), &pk));
     }
 
@@ -819,13 +816,13 @@ void test_schnorrsig_sign_verify(void) {
     }
 
     /* Test overflowing s */
-    CHECK(secp256k1_schnorrsig_sign32(ctx, sig[0], msg[0], &keypair, NULL));
+    CHECK(secp256k1_schnorrsig_sign(ctx, sig[0], msg[0], &keypair, NULL));
     CHECK(secp256k1_schnorrsig_verify(ctx, sig[0], msg[0], sizeof(msg[0]), &pk));
     memset(&sig[0][32], 0xFF, 32);
     CHECK(!secp256k1_schnorrsig_verify(ctx, sig[0], msg[0], sizeof(msg[0]), &pk));
 
     /* Test negative s */
-    CHECK(secp256k1_schnorrsig_sign32(ctx, sig[0], msg[0], &keypair, NULL));
+    CHECK(secp256k1_schnorrsig_sign(ctx, sig[0], msg[0], &keypair, NULL));
     CHECK(secp256k1_schnorrsig_verify(ctx, sig[0], msg[0], sizeof(msg[0]), &pk));
     secp256k1_scalar_set_b32(&s, &sig[0][32], NULL);
     secp256k1_scalar_negate(&s, &s);
@@ -876,7 +873,7 @@ void test_schnorrsig_taproot(void) {
 
     /* Key spend */
     secp256k1_testrand256(msg);
-    CHECK(secp256k1_schnorrsig_sign32(ctx, sig, msg, &keypair, NULL) == 1);
+    CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL) == 1);
     /* Verify key spend */
     CHECK(secp256k1_xonly_pubkey_parse(ctx, &output_pk, output_pk_bytes) == 1);
     CHECK(secp256k1_schnorrsig_verify(ctx, sig, msg, sizeof(msg), &output_pk) == 1);
diff --git a/src/tests.c b/src/tests.c
index dd53173..26063a8 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -451,18 +451,14 @@ void run_ctz_tests(void) {
 
 /***** HASH TESTS *****/
 
-void run_sha256_known_output_tests(void) {
-    static const char *inputs[] = {
+void run_sha256_tests(void) {
+    static const char *inputs[8] = {
         "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe",
         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
         "For this sample, this 63-byte string will be used as input data",
-        "This is exactly 64 bytes long, not counting the terminating byte",
-        "aaaaa",
+        "This is exactly 64 bytes long, not counting the terminating byte"
     };
-    static const unsigned int repeat[] = {
-        1, 1, 1, 1, 1, 1, 1, 1, 1000000/5
-    };
-    static const unsigned char outputs[][32] = {
+    static const unsigned char outputs[8][32] = {
         {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55},
         {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad},
         {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50},
@@ -470,146 +466,27 @@ void run_sha256_known_output_tests(void) {
         {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30},
         {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1},
         {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42},
-        {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8},
-        {0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67, 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0},
+        {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8}
     };
-    unsigned int i, ninputs;
-
-    /* Skip last input vector for low iteration counts */
-    ninputs = sizeof(inputs)/sizeof(inputs[0]) - 1;
-    CONDITIONAL_TEST(16, "run_sha256_known_output_tests 1000000") ninputs++;
-
-    for (i = 0; i < ninputs; i++) {
+    int i;
+    for (i = 0; i < 8; i++) {
         unsigned char out[32];
         secp256k1_sha256 hasher;
-        unsigned int j;
-        /* 1. Run: simply write the input bytestrings */
-        j = repeat[i];
         secp256k1_sha256_initialize(&hasher);
-        while (j > 0) {
-            secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
-            j--;
-        }
+        secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
         secp256k1_sha256_finalize(&hasher, out);
         CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0);
-        /* 2. Run: split the input bytestrings randomly before writing */
         if (strlen(inputs[i]) > 0) {
             int split = secp256k1_testrand_int(strlen(inputs[i]));
             secp256k1_sha256_initialize(&hasher);
-            j = repeat[i];
-            while (j > 0) {
-                secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
-                secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
-                j--;
-            }
+            secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
+            secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
             secp256k1_sha256_finalize(&hasher, out);
             CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0);
         }
     }
 }
 
-/** SHA256 counter tests
-
-The tests verify that the SHA256 counter doesn't wrap around at message length
-2^i bytes for i = 20, ..., 33. This wide range aims at being independent of the
-implementation of the counter and it catches multiple natural 32-bit overflows
-(e.g., counting bits, counting bytes, counting blocks, ...).
-
-The test vectors have been generated using following Python script which relies
-on https://github.com/cloudtools/sha256/ (v0.3 on Python v3.10.2).
-
-```
-from sha256 import sha256
-from copy import copy
-
-def midstate_c_definition(hasher):
-    ret  = '    {{0x' + hasher.state[0].hex('_', 4).replace('_', ', 0x') + '},\n'
-    ret += '    {0x00}, ' + str(hex(hasher.state[1])) + '}'
-    return ret
-
-def output_c_literal(hasher):
-    return '{0x' + hasher.digest().hex('_').replace('_', ', 0x') + '}'
-
-MESSAGE = b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno'
-assert(len(MESSAGE) == 64)
-BYTE_BOUNDARIES = [(2**b)//len(MESSAGE) - 1 for b in range(20, 34)]
-
-midstates = []
-digests = []
-hasher = sha256()
-for i in range(BYTE_BOUNDARIES[-1] + 1):
-    if i in BYTE_BOUNDARIES:
-        midstates.append(midstate_c_definition(hasher))
-        hasher_copy = copy(hasher)
-        hasher_copy.update(MESSAGE)
-        digests.append(output_c_literal(hasher_copy))
-    hasher.update(MESSAGE)
-
-for x in midstates:
-    print(x + ',')
-
-for x in digests:
-    print(x + ',')
-```
-*/
-void run_sha256_counter_tests(void) {
-    static const char *input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno";
-    static const secp256k1_sha256 midstates[] = {
-        {{0xa2b5c8bb, 0x26c88bb3, 0x2abdc3d2, 0x9def99a3, 0xdfd21a6e, 0x41fe585b, 0x7ef2c440, 0x2b79adda},
-         {0x00}, 0xfffc0},
-        {{0xa0d29445, 0x9287de66, 0x76aabd71, 0x41acd765, 0x0c7528b4, 0x84e14906, 0x942faec6, 0xcc5a7b26},
-         {0x00}, 0x1fffc0},
-        {{0x50449526, 0xb9f1d657, 0xa0fc13e9, 0x50860f10, 0xa550c431, 0x3fbc97c1, 0x7bbb2d89, 0xdb67bac1},
-         {0x00}, 0x3fffc0},
-        {{0x54a6efdc, 0x46762e7b, 0x88bfe73f, 0xbbd149c7, 0x41620c43, 0x1168da7b, 0x2c5960f9, 0xeccffda6},
-         {0x00}, 0x7fffc0},
-        {{0x2515a8f5, 0x5faa2977, 0x3a850486, 0xac858cad, 0x7b7276ee, 0x235c0385, 0xc53a157c, 0x7cb3e69c},
-         {0x00}, 0xffffc0},
-        {{0x34f39828, 0x409fedb7, 0x4bbdd0fb, 0x3b643634, 0x7806bf2e, 0xe0d1b713, 0xca3f2e1e, 0xe38722c2},
-         {0x00}, 0x1ffffc0},
-        {{0x389ef5c5, 0x38c54167, 0x8f5d56ab, 0x582a75cc, 0x8217caef, 0xf10947dd, 0x6a1998a8, 0x048f0b8c},
-         {0x00}, 0x3ffffc0},
-        {{0xd6c3f394, 0x0bee43b9, 0x6783f497, 0x29fa9e21, 0x6ce491c1, 0xa81fe45e, 0x2fc3859a, 0x269012d0},
-         {0x00}, 0x7ffffc0},
-        {{0x6dd3c526, 0x44d88aa0, 0x806a1bae, 0xfbcc0d32, 0x9d6144f3, 0x9d2bd757, 0x9851a957, 0xb50430ad},
-         {0x00}, 0xfffffc0},
-        {{0x2add4021, 0xdfe8a9e6, 0xa56317c6, 0x7a15f5bb, 0x4a48aacd, 0x5d368414, 0x4f00e6f0, 0xd9355023},
-         {0x00}, 0x1fffffc0},
-        {{0xb66666b4, 0xdbeac32b, 0x0ea351ae, 0xcba9da46, 0x6278b874, 0x8c508e23, 0xe16ca776, 0x8465bac1},
-         {0x00}, 0x3fffffc0},
-        {{0xb6744789, 0x9cce87aa, 0xc4c478b7, 0xf38404d8, 0x2e38ba62, 0xa3f7019b, 0x50458fe7, 0x3047dbec},
-         {0x00}, 0x7fffffc0},
-        {{0x8b1297ba, 0xba261a80, 0x2ba1b0dd, 0xfbc67d6d, 0x61072c4e, 0x4b5a2a0f, 0x52872760, 0x2dfeb162},
-         {0x00}, 0xffffffc0},
-        {{0x24f33cf7, 0x41ad6583, 0x41c8ff5d, 0xca7ef35f, 0x50395756, 0x021b743e, 0xd7126cd7, 0xd037473a},
-         {0x00}, 0x1ffffffc0},
-    };
-    static const unsigned char outputs[][32] = {
-        {0x0e, 0x83, 0xe2, 0xc9, 0x4f, 0xb2, 0xb8, 0x2b, 0x89, 0x06, 0x92, 0x78, 0x04, 0x03, 0x48, 0x5c, 0x48, 0x44, 0x67, 0x61, 0x77, 0xa4, 0xc7, 0x90, 0x9e, 0x92, 0x55, 0x10, 0x05, 0xfe, 0x39, 0x15},
-        {0x1d, 0x1e, 0xd7, 0xb8, 0xa3, 0xa7, 0x8a, 0x79, 0xfd, 0xa0, 0x05, 0x08, 0x9c, 0xeb, 0xf0, 0xec, 0x67, 0x07, 0x9f, 0x8e, 0x3c, 0x0d, 0x8e, 0xf9, 0x75, 0x55, 0x13, 0xc1, 0xe8, 0x77, 0xf8, 0xbb},
-        {0x66, 0x95, 0x6c, 0xc9, 0xe0, 0x39, 0x65, 0xb6, 0xb0, 0x05, 0xd1, 0xaf, 0xaf, 0xf3, 0x1d, 0xb9, 0xa4, 0xda, 0x6f, 0x20, 0xcd, 0x3a, 0xae, 0x64, 0xc2, 0xdb, 0xee, 0xf5, 0xb8, 0x8d, 0x57, 0x0e},
-        {0x3c, 0xbb, 0x1c, 0x12, 0x5e, 0x17, 0xfd, 0x54, 0x90, 0x45, 0xa7, 0x7b, 0x61, 0x6c, 0x1d, 0xfe, 0xe6, 0xcc, 0x7f, 0xee, 0xcf, 0xef, 0x33, 0x35, 0x50, 0x62, 0x16, 0x70, 0x2f, 0x87, 0xc3, 0xc9},
-        {0x53, 0x4d, 0xa8, 0xe7, 0x1e, 0x98, 0x73, 0x8d, 0xd9, 0xa3, 0x54, 0xa5, 0x0e, 0x59, 0x2c, 0x25, 0x43, 0x6f, 0xaa, 0xa2, 0xf5, 0x21, 0x06, 0x3e, 0xc9, 0x82, 0x06, 0x94, 0x98, 0x72, 0x9d, 0xa7},
-        {0xef, 0x7e, 0xe9, 0x6b, 0xd3, 0xe5, 0xb7, 0x41, 0x4c, 0xc8, 0xd3, 0x07, 0x52, 0x9a, 0x5a, 0x8b, 0x4e, 0x1e, 0x75, 0xa4, 0x17, 0x78, 0xc8, 0x36, 0xcd, 0xf8, 0x2e, 0xd9, 0x57, 0xe3, 0xd7, 0x07},
-        {0x87, 0x16, 0xfb, 0xf9, 0xa5, 0xf8, 0xc4, 0x56, 0x2b, 0x48, 0x52, 0x8e, 0x2d, 0x30, 0x85, 0xb6, 0x4c, 0x56, 0xb5, 0xd1, 0x16, 0x9c, 0xcf, 0x32, 0x95, 0xad, 0x03, 0xe8, 0x05, 0x58, 0x06, 0x76},
-        {0x75, 0x03, 0x80, 0x28, 0xf2, 0xa7, 0x63, 0x22, 0x1a, 0x26, 0x9c, 0x68, 0xe0, 0x58, 0xfc, 0x73, 0xeb, 0x42, 0xf6, 0x86, 0x16, 0x24, 0x4b, 0xbc, 0x24, 0xf7, 0x02, 0xc8, 0x3d, 0x90, 0xe2, 0xb0},
-        {0xdf, 0x49, 0x0f, 0x15, 0x7b, 0x7d, 0xbf, 0xe0, 0xd4, 0xcf, 0x47, 0xc0, 0x80, 0x93, 0x4a, 0x61, 0xaa, 0x03, 0x07, 0x66, 0xb3, 0x38, 0x5d, 0xc8, 0xc9, 0x07, 0x61, 0xfb, 0x97, 0x10, 0x2f, 0xd8},
-        {0x77, 0x19, 0x40, 0x56, 0x41, 0xad, 0xbc, 0x59, 0xda, 0x1e, 0xc5, 0x37, 0x14, 0x63, 0x7b, 0xfb, 0x79, 0xe2, 0x7a, 0xb1, 0x55, 0x42, 0x99, 0x42, 0x56, 0xfe, 0x26, 0x9d, 0x0f, 0x7e, 0x80, 0xc6},
-        {0x50, 0xe7, 0x2a, 0x0e, 0x26, 0x44, 0x2f, 0xe2, 0x55, 0x2d, 0xc3, 0x93, 0x8a, 0xc5, 0x86, 0x58, 0x22, 0x8c, 0x0c, 0xbf, 0xb1, 0xd2, 0xca, 0x87, 0x2a, 0xe4, 0x35, 0x26, 0x6f, 0xcd, 0x05, 0x5e},
-        {0xe4, 0x80, 0x6f, 0xdb, 0x3d, 0x7d, 0xba, 0xde, 0x50, 0x3f, 0xea, 0x00, 0x3d, 0x46, 0x59, 0x64, 0xfd, 0x58, 0x1c, 0xa1, 0xb8, 0x7d, 0x5f, 0xac, 0x94, 0x37, 0x9e, 0xa0, 0xc0, 0x9c, 0x93, 0x8b},
-        {0x2c, 0xf3, 0xa9, 0xf6, 0x15, 0x25, 0x80, 0x70, 0x76, 0x99, 0x7d, 0xf1, 0xc3, 0x2f, 0xa3, 0x31, 0xff, 0x92, 0x35, 0x2e, 0x8d, 0x04, 0x13, 0x33, 0xd8, 0x0d, 0xdb, 0x4a, 0xf6, 0x8c, 0x03, 0x34},
-        {0xec, 0x12, 0x24, 0x9f, 0x35, 0xa4, 0x29, 0x8b, 0x9e, 0x4a, 0x95, 0xf8, 0x61, 0xaf, 0x61, 0xc5, 0x66, 0x55, 0x3e, 0x3f, 0x2a, 0x98, 0xea, 0x71, 0x16, 0x6b, 0x1c, 0xd9, 0xe4, 0x09, 0xd2, 0x8e},
-    };
-    unsigned int i;
-    for (i = 0; i < sizeof(midstates)/sizeof(midstates[0]); i++) {
-        unsigned char out[32];
-        secp256k1_sha256 hasher = midstates[i];
-        secp256k1_sha256_write(&hasher, (const unsigned char*)input, strlen(input));
-        secp256k1_sha256_finalize(&hasher, out);
-        CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0);
-    }
-}
-
 void run_hmac_sha256_tests(void) {
     static const char *keys[6] = {
         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
@@ -6887,19 +6764,6 @@ void run_secp256k1_memczero_test(void) {
     CHECK(secp256k1_memcmp_var(buf1, buf2, sizeof(buf1)) == 0);
 }
 
-void run_secp256k1_byteorder_tests(void) {
-    const uint32_t x = 0xFF03AB45;
-    const unsigned char x_be[4] = {0xFF, 0x03, 0xAB, 0x45};
-    unsigned char buf[4];
-    uint32_t x_;
-
-    secp256k1_write_be32(buf, x);
-    CHECK(secp256k1_memcmp_var(buf, x_be, sizeof(buf)) == 0);
-
-    x_ = secp256k1_read_be32(buf);
-    CHECK(x == x_);
-}
-
 void int_cmov_test(void) {
     int r = INT_MAX;
     int a = 0;
@@ -7100,8 +6964,7 @@ int main(int argc, char **argv) {
     run_modinv_tests();
     run_inverse_tests();
 
-    run_sha256_known_output_tests();
-    run_sha256_counter_tests();
+    run_sha256_tests();
     run_hmac_sha256_tests();
     run_rfc6979_hmac_sha256_tests();
     run_tagged_sha256_tests();
@@ -7174,7 +7037,6 @@ int main(int argc, char **argv) {
 
     /* util tests */
     run_secp256k1_memczero_test();
-    run_secp256k1_byteorder_tests();
 
     run_cmov_tests();
 
diff --git a/src/valgrind_ctime_test.c b/src/valgrind_ctime_test.c
index 6ff0085..ea6d4b3 100644
--- a/src/valgrind_ctime_test.c
+++ b/src/valgrind_ctime_test.c
@@ -166,7 +166,7 @@ void run_tests(secp256k1_context *ctx, unsigned char *key) {
     ret = secp256k1_keypair_create(ctx, &keypair, key);
     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
     CHECK(ret == 1);
-    ret = secp256k1_schnorrsig_sign32(ctx, sig, msg, &keypair, NULL);
+    ret = secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL);
     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
     CHECK(ret == 1);
 #endif