Repository: bitcoin-core/secp256k1
Pull request #1340 (2023-06-11 14:52:04)

clean up in-comment Sage code (refer to secp256k1_params.sage, update to Python3)
Some of the C source files contain contain in-comment Sage code calculating secp256k1 parameters that are already defined in the file secp256k1_params.sage.  Replace that by a corresponding load instruction and access the necessary variables. In ecdsa_impl.h, update the comment to use a one-line shell command calling sage to get the values.

The remaining code (test `test_add_neg_y_diff_x` in tests.c) is updated to work with a current version based on Python3 (Sage 9.0+, see https://wiki.sagemath.org/Python3-Switch).

The latter can be seen as a small follow-up to PR #849 (commit 13c88efed0005eb6745a222963ee74564054eafb).


theStack: > I think the sage code for `secp256k1_ecdsa_const_order_as_fe` and also `secp256k1_ecdsa_const_p_minus_order` could be dropped entirely. They're easy to write given https://github.com/bitcoin-core/secp256k1/blob/master/sage/secp256k1_params.sage#L17. Or even better, those values can just be defined in the `secp256k1_params.sage` file, which is run on CI to avoid code rot.
 
Sounds like a good idea. By the way, I found this approach for calculating p interesting (i.e. "find the first number equal or lower than 2^256 - 2^32 - 1023 which is prime"):
https://github.com/bitcoin-core/secp256k1/blob/67214f5f7d8e0bdf193ceb1f47ba8277d1a0871a/src/ecdsa_impl.h#L18-L23

But I guess there's no good reason to keep that code and having the fixed p number (as it is now in `secp256k1_params.sage`) is just fine? The referenced SEC2 document also doesn't mention anything about the above approach. 🤷‍♂️ 

> Not sure what do to with the code in the test. I haven't checked. Are these the only instances in the entire code base?

I think that's the only instances. My approach was manually looking through all the results of `$ git grep -i sage` (which included many false-positives due to the word "message") -- of course, it could still be possible that I either missed something, or there is sage code around without the word "sage" in a description close.
real-or-random: > But I guess there's no good reason to keep that code and having the fixed p number (as it is now in `secp256k1_params.sage`) is just fine?

Yeah. If anything, the definition in SEC2 is canonical, and it just gives the number as you point out. 

---

For the code in the tests, perhaps that can at least be shortened to assume that the constants from https://github.com/bitcoin-core/secp256k1/blob/master/sage/secp256k1_params.sage are already defined.
theStack: I've removed all in-comment sage code for calculating secp256k1 parameters and referred to `secp256k1_params.sage` instead. For ecdsa_impl.h, the comment is now a shell command which calls sage to emit the necessary values. There's still a small chance for code rot, though I'd argue it's neglible -- the chance that the filename `secp256k1_params.sage` ever changes or that the basic parameters `P` and `N` are renamed is rather small I'd say. Still open for alternative approaches.
real-or-random: > There's still a small chance for code rot, though I'd argue it's negligible -- the chance that the filename `secp256k1_params.sage` ever changes or that the basic parameters `P` and `N` are renamed is rather small I'd say. Still open for alternative approaches.

certainly good enough :)

Patch:
diff --git a/.cirrus.yml b/.cirrus.yml
index 89eec3d..12e9870 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -21,7 +21,6 @@ env:
   ECDH: no
   RECOVERY: no
   SCHNORRSIG: no
-  ELLSWIFT: no
   ### test options
   SECP256K1_TEST_ITERS:
   BENCH: yes
@@ -54,6 +53,12 @@ cat_logs_snippet: &CAT_LOGS
     cat_ci_env_script:
       - env
 
+merge_base_script_snippet: &MERGE_BASE
+  merge_base_script:
+    - if [ "$CIRRUS_PR" = "" ]; then exit 0; fi
+    - git fetch --depth=1 $CIRRUS_REPO_CLONE_URL "pull/${CIRRUS_PR}/merge"
+    - git checkout FETCH_HEAD  # Use merged changes to detect silent merge conflicts
+
 linux_container_snippet: &LINUX_CONTAINER
   container:
     dockerfile: ci/linux-debian.Dockerfile
@@ -69,18 +74,17 @@ task:
   << : *LINUX_CONTAINER
   matrix: &ENV_MATRIX
     - env: {WIDEMUL:  int64,  RECOVERY: yes}
-    - env: {WIDEMUL:  int64,                 ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes}
+    - env: {WIDEMUL:  int64,                 ECDH: yes, SCHNORRSIG: yes}
     - env: {WIDEMUL: int128}
-    - env: {WIDEMUL: int128_struct,                                      ELLSWIFT: yes}
-    - env: {WIDEMUL: int128,  RECOVERY: yes,            SCHNORRSIG: yes, ELLSWIFT: yes}
+    - env: {WIDEMUL: int128_struct}
+    - env: {WIDEMUL: int128,  RECOVERY: yes,            SCHNORRSIG: yes}
     - env: {WIDEMUL: int128,                 ECDH: yes, SCHNORRSIG: yes}
-    - env: {WIDEMUL: int128,  ASM: x86_64                              , ELLSWIFT: yes}
+    - env: {WIDEMUL: int128,  ASM: x86_64}
     - env: {                  RECOVERY: yes,            SCHNORRSIG: yes}
     - env: {CTIMETESTS: no,    RECOVERY: yes, ECDH: yes, SCHNORRSIG: yes, CPPFLAGS: -DVERIFY}
     - env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETESTS: no, BENCH: no}
     - env: {CPPFLAGS: -DDETERMINISTIC}
     - env: {CFLAGS: -O0, CTIMETESTS: no}
-    - env: {CFLAGS: -O1, RECOVERY: yes, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes}
     - env: { ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 }
     - env: { ECMULTGENPRECISION: 8, ECMULTWINDOW: 4 }
   matrix:
@@ -88,6 +92,7 @@ task:
         CC: gcc
     - env:
         CC: clang
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -105,6 +110,7 @@ task:
         CC: i686-linux-gnu-gcc
     - env:
         CC: clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -131,6 +137,7 @@ task:
         CC: clang
   brew_script:
     - brew install automake libtool gcc
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -147,8 +154,8 @@ task:
     ECDH: yes
     RECOVERY: yes
     SCHNORRSIG: yes
-    ELLSWIFT: yes
     CTIMETESTS: no
+  << : *MERGE_BASE
   test_script:
     # https://sourceware.org/bugzilla/show_bug.cgi?id=27008
     - rm /etc/ld.so.cache
@@ -166,11 +173,11 @@ task:
     ECDH: yes
     RECOVERY: yes
     SCHNORRSIG: yes
-    ELLSWIFT: yes
     CTIMETESTS: no
   matrix:
     - env: {}
     - env: {EXPERIMENTAL: yes, ASM: arm32}
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -186,8 +193,8 @@ task:
     ECDH: yes
     RECOVERY: yes
     SCHNORRSIG: yes
-    ELLSWIFT: yes
     CTIMETESTS: no
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -203,8 +210,8 @@ task:
     ECDH: yes
     RECOVERY: yes
     SCHNORRSIG: yes
-    ELLSWIFT: yes
     CTIMETESTS: no
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -225,6 +232,7 @@ task:
     - name: "i686 (mingw32-w64): Windows (Debian stable, Wine)"
       env:
         HOST: i686-w64-mingw32
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -239,7 +247,6 @@ task:
     RECOVERY: yes
     EXPERIMENTAL: yes
     SCHNORRSIG: yes
-    ELLSWIFT: yes
     CTIMETESTS: no
     # 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
@@ -267,6 +274,7 @@ task:
         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
   << : *CAT_LOGS
@@ -278,7 +286,6 @@ task:
     ECDH: yes
     RECOVERY: yes
     SCHNORRSIG: yes
-    ELLSWIFT: yes
     CTIMETESTS: no
   matrix:
     - name: "Valgrind (memcheck)"
@@ -311,6 +318,7 @@ task:
     - env:
         HOST: i686-linux-gnu
         CC: i686-linux-gnu-gcc
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -337,6 +345,7 @@ task:
         ECMULTGENPRECISION: 2
         ECMULTWINDOW: 2
         CFLAGS: "-fsanitize=memory -g -O3"
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -352,7 +361,7 @@ task:
     ECDH: yes
     RECOVERY: yes
     SCHNORRSIG: yes
-    ELLSWIFT: yes
+  << : *MERGE_BASE
   test_script:
     - ./ci/cirrus.sh
   << : *CAT_LOGS
@@ -384,17 +393,11 @@ task:
     # Ignore MSBuild warning MSB8029.
     # See: https://learn.microsoft.com/en-us/visualstudio/msbuild/errors/msb8029?view=vs-2022
     IgnoreWarnIntDirInTempDetected: 'true'
-  matrix:
-    - env:
-        BUILD_SHARED_LIBS: ON
-    - env:
-        BUILD_SHARED_LIBS: OFF
-  git_show_script:
-    # Print commit to allow reproducing the job outside of CI.
-    - git show --no-patch
+  merge_script:
+    - PowerShell -NoLogo -Command if ($env:CIRRUS_PR -ne $null) { git fetch $env:CIRRUS_REPO_CLONE_URL pull/$env:CIRRUS_PR/merge; git reset --hard FETCH_HEAD; }
   configure_script:
     - '%x64_NATIVE_TOOLS%'
-    - cmake -E env CFLAGS="/WX" cmake -A x64 -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
+    - cmake -E env CFLAGS="/WX" cmake -G "Visual Studio 17 2022" -A x64 -S . -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON
   build_script:
     - '%x64_NATIVE_TOOLS%'
     - cmake --build build --config RelWithDebInfo -- -property:UseMultiToolTask=true;CL_MPcount=5
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dacb0a3..8e31edc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,16 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
-#### Added
- - New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them.
-   ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See:
-   - Header file `include/secp256k1_ellswift.h` which defines the new API.
-   - Document `doc/ellswift.md` which explains the mathematical background of the scheme.
-   - The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based.
-
-#### Changed
- - When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`.
-
 ## [0.3.2] - 2023-05-13
 We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`.
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3107eb3..240557f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -71,11 +71,6 @@ if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
   add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1)
 endif()
 
-option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
-if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
-  add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
-endif()
-
 option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
 if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS)
   add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1)
@@ -275,7 +270,6 @@ message("  ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}
 message("  ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}")
 message("  extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}")
 message("  schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
-message("  ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
 message("Parameters:")
 message("  ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
 message("  ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}")
diff --git a/Makefile.am b/Makefile.am
index 32bc729..51484a0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -153,7 +153,7 @@ endif
 if USE_EXAMPLES
 noinst_PROGRAMS += ecdsa_example
 ecdsa_example_SOURCES = examples/ecdsa.c
-ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include
 ecdsa_example_LDADD = libsecp256k1.la
 ecdsa_example_LDFLAGS = -static
 if BUILD_WINDOWS
@@ -163,7 +163,7 @@ TESTS += ecdsa_example
 if ENABLE_MODULE_ECDH
 noinst_PROGRAMS += ecdh_example
 ecdh_example_SOURCES = examples/ecdh.c
-ecdh_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+ecdh_example_CPPFLAGS = -I$(top_srcdir)/include
 ecdh_example_LDADD = libsecp256k1.la
 ecdh_example_LDFLAGS = -static
 if BUILD_WINDOWS
@@ -174,7 +174,7 @@ endif
 if ENABLE_MODULE_SCHNORRSIG
 noinst_PROGRAMS += schnorr_example
 schnorr_example_SOURCES = examples/schnorr.c
-schnorr_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+schnorr_example_CPPFLAGS = -I$(top_srcdir)/include
 schnorr_example_LDADD = libsecp256k1.la
 schnorr_example_LDFLAGS = -static
 if BUILD_WINDOWS
@@ -267,7 +267,3 @@ endif
 if ENABLE_MODULE_SCHNORRSIG
 include src/modules/schnorrsig/Makefile.am.include
 endif
-
-if ENABLE_MODULE_ELLSWIFT
-include src/modules/ellswift/Makefile.am.include
-endif
diff --git a/ci/cirrus.sh b/ci/cirrus.sh
index 48a9783..5e39e4d 100755
--- a/ci/cirrus.sh
+++ b/ci/cirrus.sh
@@ -4,8 +4,7 @@ set -eux
 
 export LC_ALL=C
 
-# Print commit and relevant CI environment to allow reproducing the job outside of CI.
-git show --no-patch
+# Print relevant CI environment to allow reproducing the job outside of CI.
 print_environment() {
     # Turn off -x because it messes up the output
     set +x
@@ -54,22 +53,6 @@ if [ -n "$WRAPPER_CMD" ]; then
     $WRAPPER_CMD --version
 fi
 
-# Workaround for https://bugs.kde.org/show_bug.cgi?id=452758 (fixed in valgrind 3.20.0).
-case "${CC:-undefined}" in
-    clang*)
-        if [ "$CTIMETESTS" = "yes" ] && [ "$WITH_VALGRIND" = "yes" ]
-        then
-            export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
-        else
-            case "$WRAPPER_CMD" in
-                valgrind*)
-                    export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
-                    ;;
-            esac
-        fi
-        ;;
-esac
-
 ./autogen.sh
 
 ./configure \
@@ -78,7 +61,6 @@ esac
     --with-ecmult-window="$ECMULTWINDOW" \
     --with-ecmult-gen-precision="$ECMULTGENPRECISION" \
     --enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
-    --enable-module-ellswift="$ELLSWIFT" \
     --enable-module-schnorrsig="$SCHNORRSIG" \
     --enable-examples="$EXAMPLES" \
     --enable-ctime-tests="$CTIMETESTS" \
diff --git a/ci/linux-debian.Dockerfile b/ci/linux-debian.Dockerfile
index 0a5bd54..54eafca 100644
--- a/ci/linux-debian.Dockerfile
+++ b/ci/linux-debian.Dockerfile
@@ -11,9 +11,9 @@ RUN dpkg --add-architecture i386 && \
 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 libclang-rt-dev libc6-dbg \
+        gcc clang llvm libc6-dbg \
         g++ \
-        gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan8:i386 \
+        gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan6:i386 \
         gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \
         gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \
         gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 \
@@ -26,9 +26,6 @@ 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 && \
-# Workaround for `wine` package failure to employ the Debian alternatives system properly.
-    ln -s /usr/lib/wine/wine64 /usr/bin/wine64 && \
-# Set of tools for using MSVC on Linux.
     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 && \
diff --git a/configure.ac b/configure.ac
index a502d13..fe3ef90 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,6 +127,12 @@ AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
       SECP_TRY_APPEND_CFLAGS([-wd4267], $1) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
       # Eliminate deprecation warnings for the older, less secure functions.
       CPPFLAGS="-D_CRT_SECURE_NO_WARNINGS $CPPFLAGS"
+      # We pass -ignore:4217 to the MSVC linker to suppress warning 4217 when
+      # importing variables from a statically linked secp256k1.
+      # (See the libtool manual, section "Windows DLLs" for background.)
+      # Unfortunately, libtool tries to be too clever and strips "-Xlinker arg"
+      # into "arg", so this will be " -Xlinker -ignore:4217" after stripping.
+      LDFLAGS="-Xlinker -Xlinker -Xlinker -ignore:4217 $LDFLAGS" 
     fi
 ])
 SECP_TRY_APPEND_DEFAULT_CFLAGS(SECP_CFLAGS)
@@ -184,10 +190,6 @@ AC_ARG_ENABLE(module_schnorrsig,
     AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=yes]]), [],
     [SECP_SET_DEFAULT([enable_module_schnorrsig], [yes], [yes])])
 
-AC_ARG_ENABLE(module_ellswift,
-    AS_HELP_STRING([--enable-module-ellswift],[enable ElligatorSwift module [default=yes]]), [],
-    [SECP_SET_DEFAULT([enable_module_ellswift], [yes], [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])])
@@ -400,10 +402,6 @@ if test x"$enable_module_schnorrsig" = x"yes"; then
   enable_module_extrakeys=yes
 fi
 
-if test x"$enable_module_ellswift" = x"yes"; then
-  AC_DEFINE(ENABLE_MODULE_ELLSWIFT, 1, [Define this symbol to enable the ElligatorSwift module])
-fi
-
 # Test if extrakeys is set after the schnorrsig module to allow the schnorrsig
 # module to set enable_module_extrakeys=yes
 if test x"$enable_module_extrakeys" = x"yes"; then
@@ -446,7 +444,6 @@ 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([ENABLE_MODULE_ELLSWIFT], [test x"$enable_module_ellswift" = x"yes"])
 AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
 AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm32"])
 AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"])
@@ -468,7 +465,6 @@ echo "  module ecdh             = $enable_module_ecdh"
 echo "  module recovery         = $enable_module_recovery"
 echo "  module extrakeys        = $enable_module_extrakeys"
 echo "  module schnorrsig       = $enable_module_schnorrsig"
-echo "  module ellswift         = $enable_module_ellswift"
 echo
 echo "  asm                     = $set_asm"
 echo "  ecmult window size      = $set_ecmult_window"
diff --git a/doc/ellswift.md b/doc/ellswift.md
deleted file mode 100644
index 9d60e6b..0000000
--- a/doc/ellswift.md
+++ /dev/null
@@ -1,483 +0,0 @@
-# ElligatorSwift for secp256k1 explained
-
-In this document we explain how the `ellswift` module implementation is related to the
-construction in the
-["SwiftEC: Shallue–van de Woestijne Indifferentiable Function To Elliptic Curves"](https://eprint.iacr.org/2022/759)
-paper by Jorge Chávez-Saab, Francisco Rodríguez-Henríquez, and Mehdi Tibouchi.
-
-* [1. Introduction](#1-introduction)
-* [2. The decoding function](#2-the-decoding-function)
-  + [2.1 Decoding for `secp256k1`](#21-decoding-for-secp256k1)
-* [3. The encoding function](#3-the-encoding-function)
-  + [3.1 Switching to *v, w* coordinates](#31-switching-to-v-w-coordinates)
-  + [3.2 Avoiding computing all inverses](#32-avoiding-computing-all-inverses)
-  + [3.3 Finding the inverse](#33-finding-the-inverse)
-  + [3.4 Dealing with special cases](#34-dealing-with-special-cases)
-  + [3.5 Encoding for `secp256k1`](#35-encoding-for-secp256k1)
-* [4. Encoding and decoding full *(x, y)* coordinates](#4-encoding-and-decoding-full-x-y-coordinates)
-  + [4.1 Full *(x, y)* coordinates for `secp256k1`](#41-full-x-y-coordinates-for-secp256k1)
-
-## 1. Introduction
-
-The `ellswift` module effectively introduces a new 64-byte public key format, with the property
-that (uniformly random) public keys can be encoded as 64-byte arrays which are computationally
-indistinguishable from uniform byte arrays. The module provides functions to convert public keys
-from and to this format, as well as convenience functions for key generation and ECDH that operate
-directly on ellswift-encoded keys.
-
-The encoding consists of the concatenation of two (32-byte big endian) encoded field elements $u$
-and $t.$ Together they encode an x-coordinate on the curve $x$, or (see further) a full point $(x, y)$ on
-the curve.
-
-**Decoding** consists of decoding the field elements $u$ and $t$ (values above the field size $p$
-are taken modulo $p$), and then evaluating $F_u(t)$, which for every $u$ and $t$ results in a valid
-x-coordinate on the curve. The functions $F_u$ will be defined in [Section 2](#2-the-decoding-function).
-
-**Encoding** a given $x$ coordinate is conceptually done as follows:
-* Loop:
-  * Pick a uniformly random field element $u.$
-  * Compute the set $L = F_u^{-1}(x)$ of $t$ values for which $F_u(t) = x$, which may have up to *8* elements.
-  * With probability $1 - \dfrac{\\#L}{8}$, restart the loop.
-  * Select a uniformly random $t \in L$ and return $(u, t).$
-
-This is the *ElligatorSwift* algorithm, here given for just x-coordinates. An extension to full
-$(x, y)$ points will be given in [Section 4](#4-encoding-and-decoding-full-x-y-coordinates).
-The algorithm finds a uniformly random $(u, t)$ among (almost all) those
-for which $F_u(t) = x.$ Section 3.2 in the paper proves that the number of such encodings for
-almost all x-coordinates on the curve (all but at most 39) is close to two times the field size
-(specifically, it lies in the range $2q \pm (22\sqrt{q} + O(1))$, where $q$ is the size of the field).
-
-## 2. The decoding function
-
-First some definitions:
-* $\mathbb{F}$ is the finite field of size $q$, of characteristic 5 or more, and $q \equiv 1 \mod 3.$
-  * For `secp256k1`, $q = 2^{256} - 2^{32} - 977$, which satisfies that requirement.
-* Let $E$ be the elliptic curve of points $(x, y) \in \mathbb{F}^2$ for which $y^2 = x^3 + ax + b$, with $a$ and $b$
-  public constants, for which $\Delta_E = -16(4a^3 + 27b^2)$ is a square, and at least one of $(-b \pm \sqrt{-3 \Delta_E} / 36)/2$ is a square.
-  This implies that the order of $E$ is either odd, or a multiple of *4*.
-  If $a=0$, this condition is always fulfilled.
-  * For `secp256k1`, $a=0$ and $b=7.$
-* Let the function $g(x) = x^3 + ax + b$, so the $E$ curve equation is also $y^2 = g(x).$
-* Let the function $h(x) = 3x^3 + 4a.$
-* Define $V$ as the set of solutions $(x_1, x_2, x_3, z)$ to $z^2 = g(x_1)g(x_2)g(x_3).$
-* Define $S_u$ as the set of solutions $(X, Y)$ to $X^2 + h(u)Y^2 = -g(u)$ and $Y \neq 0.$
-* $P_u$ is a function from $\mathbb{F}$ to $S_u$ that will be defined below.
-* $\psi_u$ is a function from $S_u$ to $V$ that will be defined below.
-
-**Note**: In the paper:
-* $F_u$ corresponds to $F_{0,u}$ there.
-* $P_u(t)$ is called $P$ there.
-* All $S_u$ sets together correspond to $S$ there.
-* All $\psi_u$ functions together (operating on elements of $S$) correspond to $\psi$ there.
-
-Note that for $V$, the left hand side of the equation $z^2$ is square, and thus the right
-hand must also be square. As multiplying non-squares results in a square in $\mathbb{F}$,
-out of the three right-hand side factors an even number must be non-squares.
-This implies that exactly *1* or exactly *3* out of
-$\\{g(x_1), g(x_2), g(x_3)\\}$ must be square, and thus that for any $(x_1,x_2,x_3,z) \in V$,
-at least one of $\\{x_1, x_2, x_3\\}$ must be a valid x-coordinate on $E.$ There is one exception
-to this, namely when $z=0$, but even then one of the three values is a valid x-coordinate.
-
-**Define** the decoding function $F_u(t)$ as:
-* Let $(x_1, x_2, x_3, z) = \psi_u(P_u(t)).$
-* Return the first element $x$ of $(x_3, x_2, x_1)$ which is a valid x-coordinate on $E$ (i.e., $g(x)$ is square).
-
-$P_u(t) = (X(u, t), Y(u, t))$, where:
-
-$$
-\begin{array}{lcl}
-X(u, t) & = & \left\\{\begin{array}{ll}
-  \dfrac{g(u) - t^2}{2t} & a = 0 \\
-  \dfrac{g(u) + h(u)(Y_0(u) - X_0(u)t)^2}{X_0(u)(1 + h(u)t^2)} & a \neq 0
-\end{array}\right. \\
-Y(u, t) & = & \left\\{\begin{array}{ll}
-  \dfrac{X(u, t) + t}{u \sqrt{-3}} = \dfrac{g(u) + t^2}{2tu\sqrt{-3}} & a = 0 \\
-  Y_0(u) + t(X(u, t) - X_0(u)) & a \neq 0
-\end{array}\right.
-\end{array}
-$$
-
-$P_u(t)$ is defined:
-* For $a=0$, unless:
-  * $u = 0$ or $t = 0$ (division by zero)
-  * $g(u) = -t^2$ (would give $Y=0$).
-* For $a \neq 0$, unless:
-  * $X_0(u) = 0$ or $h(u)t^2 = -1$ (division by zero)
-  * $Y_0(u) (1 - h(u)t^2) = 2X_0(u)t$ (would give $Y=0$).
-
-The functions $X_0(u)$ and $Y_0(u)$ are defined in Appendix A of the paper, and depend on various properties of $E.$
-
-The function $\psi_u$ is the same for all curves: $\psi_u(X, Y) = (x_1, x_2, x_3, z)$, where:
-
-$$
-\begin{array}{lcl}
-  x_1 & = & \dfrac{X}{2Y} - \dfrac{u}{2} && \\
-  x_2 & = & -\dfrac{X}{2Y} - \dfrac{u}{2} && \\
-  x_3 & = & u + 4Y^2 && \\
-  z   & = & \dfrac{g(x_3)}{2Y}(u^2 + ux_1 + x_1^2 + a) = \dfrac{-g(u)g(x_3)}{8Y^3}
-\end{array}
-$$
-
-### 2.1 Decoding for `secp256k1`
-
-Put together and specialized for $a=0$ curves, decoding $(u, t)$ to an x-coordinate is:
-
-**Define** $F_u(t)$ as:
-* Let $X = \dfrac{u^3 + b - t^2}{2t}.$
-* Let $Y = \dfrac{X + t}{u\sqrt{-3}}.$
-* Return the first $x$ in $(u + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u}{2}, \dfrac{X}{2Y} - \dfrac{u}{2})$ for which $g(x)$ is square.
-
-To make sure that every input decodes to a valid x-coordinate, we remap the inputs in case
-$P_u$ is not defined (when $u=0$, $t=0$, or $g(u) = -t^2$):
-
-**Define** $F_u(t)$ as:
-* Let $u'=u$ if $u \neq 0$; $1$ otherwise (guaranteeing $u' \neq 0$).
-* Let $t'=t$ if $t \neq 0$; $1$ otherwise (guaranteeing $t' \neq 0$).
-* Let $t''=t'$ if $g(u') \neq -t'^2$; $2t'$ otherwise (guaranteeing $t'' \neq 0$ and $g(u') \neq -t''^2$).
-* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
-* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
-* Return the first $x$ in $(u' + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u'}{2}, \dfrac{X}{2Y} - \dfrac{u'}{2})$ for which $x^3 + b$ is square.
-
-The choices here are not strictly necessary. Just returning a fixed constant in any of the undefined cases would suffice,
-but the approach here is simple enough and gives fairly uniform output even in these cases.
-
-**Note**: in the paper these conditions result in $\infty$ as output, due to the use of projective coordinates there.
-We wish to avoid the need for callers to deal with this special case.
-
-This is implemented in `secp256k1_ellswift_xswiftec_frac_var` (which decodes to an x-coordinate represented as a fraction), and
-in `secp256k1_ellswift_xswiftec_var` (which outputs the actual x-coordinate).
-
-## 3. The encoding function
-
-To implement $F_u^{-1}(x)$, the function to find the set of inverses $t$ for which $F_u(t) = x$, we have to reverse the process:
-* Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$
-* Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$
-* For each of the found $t$ values, verify that $F_u(t) = x.$
-* Return the remaining $t$ values.
-
-The function $P_u^{-1}$, which finds $t$ given $(X, Y) \in S_u$, is significantly simpler than $P_u:$
-
-$$
-P_u^{-1}(X, Y) = \left\\{\begin{array}{ll}
-Yu\sqrt{-3} - X & a = 0 \\
-\dfrac{Y-Y_0(u)}{X-X_0(u)} & a \neq 0 \land X \neq X_0(u) \\
-\dfrac{-X_0(u)}{h(u)Y_0(u)} & a \neq 0 \land X = X_0(u) \land Y = Y_0(u)
-\end{array}\right.
-$$
-
-The third step above, verifying that $F_u(t) = x$, is necessary because for the $(X, Y)$ values found through the $x_1$ and $x_2$ expressions,
-it is possible that decoding through $\psi_u(X, Y)$ yields a valid $x_3$ on the curve, which would take precedence over the
-$x_1$ or $x_2$ decoding. These $(X, Y)$ solutions must be rejected.
-
-Since we know that exactly one or exactly three out of $\\{x_1, x_2, x_3\\}$ are valid x-coordinates for any $t$,
-the case where either $x_1$ or $x_2$ is valid and in addition also $x_3$ is valid must mean that all three are valid.
-This means that instead of checking whether $x_3$ is on the curve, it is also possible to check whether the other one out of
-$x_1$ and $x_2$ is on the curve. This is significantly simpler, as it turns out.
-
-Observe that $\psi_u$ guarantees that $x_1 + x_2 = -u.$ So given either $x = x_1$ or $x = x_2$, the other one of the two can be computed as
-$-u - x.$ Thus, when encoding $x$ through the $x_1$ or $x_2$ expressions, one can simply check whether $g(-u-x)$ is a square,
-and if so, not include the corresponding $t$ values in the returned set. As this does not need $X$, $Y$, or $t$, this condition can be determined
-before those values are computed.
-
-It is not possible that an encoding found through the $x_1$ expression decodes to a different valid x-coordinate using $x_2$ (which would
-take precedence), for the same reason: if both $x_1$ and $x_2$ decodings were valid, $x_3$ would be valid as well, and thus take
-precedence over both. Because of this, the $g(-u-x)$ being square test for $x_1$ and $x_2$ is the only test necessary to guarantee the found $t$
-values round-trip back to the input $x$ correctly. This is the reason for choosing the $(x_3, x_2, x_1)$ precedence order in the decoder;
-any order which does not place $x_3$ first requires more complicated round-trip checks in the encoder.
-
-### 3.1 Switching to *v, w* coordinates
-
-Before working out the formulas for all this, we switch to different variables for $S_u.$ Let $v = (X/Y - u)/2$, and
-$w = 2Y.$ Or in the other direction, $X = w(u/2 + v)$ and $Y = w/2:$
-* $S_u'$ becomes the set of $(v, w)$ for which $w^2 (u^2 + uv + v^2 + a) = -g(u)$ and $w \neq 0.$
-* For $a=0$ curves, $P_u^{-1}$ can be stated for $(v,w)$ as $P_u^{'-1}(v, w) = w\left(\frac{\sqrt{-3}-1}{2}u - v\right).$
-* $\psi_u$ can be stated for $(v, w)$ as $\psi_u'(v, w) = (x_1, x_2, x_3, z)$, where
-
-$$
-\begin{array}{lcl}
-  x_1 & = & v \\
-  x_2 & = & -u - v \\
-  x_3 & = & u + w^2 \\
-  z   & = & \dfrac{g(x_3)}{w}(u^2 + uv + v^2 + a) = \dfrac{-g(u)g(x_3)}{w^3}
-\end{array}
-$$
-
-We can now write the expressions for finding $(v, w)$ given $x$ explicitly, by solving each of the $\\{x_1, x_2, x_3\\}$
-expressions for $v$ or $w$, and using the $S_u'$ equation to find the other variable:
-* Assuming $x = x_1$, we find $v = x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
-* Assuming $x = x_2$, we find $v = -u-x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
-* Assuming $x = x_3$, we find $w = \pm\sqrt{x-u}$ and $v = -u/2 \pm \sqrt{-w^2(4g(u) + w^2h(u))}/(2w^2)$ (four solutions).
-
-### 3.2 Avoiding computing all inverses
-
-The *ElligatorSwift* algorithm as stated in Section 1 requires the computation of $L = F_u^{-1}(x)$ (the
-set of all $t$ such that $(u, t)$ decode to $x$) in full. This is unnecessary.
-
-Observe that the procedure of restarting with probability $(1 - \frac{\\#L}{8})$ and otherwise returning a
-uniformly random element from $L$ is actually equivalent to always padding $L$ with $\bot$ values up to length 8,
-picking a uniformly random element from that, restarting whenever $\bot$ is picked:
-
-**Define** *ElligatorSwift(x)* as:
-* Loop:
-  * Pick a uniformly random field element $u.$
-  * Compute the set $L = F_u^{-1}(x).$
-  * Let $T$ be the 8-element vector consisting of the elements of $L$, plus $8 - \\#L$ times $\\{\bot\\}.$
-  * Select a uniformly random $t \in T.$
-  * If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
-
-Now notice that the order of elements in $T$ does not matter, as all we do is pick a uniformly
-random element in it, so we do not need to have all $\bot$ values at the end.
-As we have 8 distinct formulas for finding $(v, w)$ (taking the variants due to $\pm$ into account),
-we can associate every index in $T$ with exactly one of those formulas, making sure that:
-* Formulas that yield no solutions (due to division by zero or non-existing square roots) or invalid solutions are made to return $\bot.$
-* For the $x_1$ and $x_2$ cases, if $g(-u-x)$ is a square, $\bot$ is returned instead (the round-trip check).
-* In case multiple formulas would return the same non- $\bot$ result, all but one of those must be turned into $\bot$ to avoid biasing those.
-
-The last condition above only occurs with negligible probability for cryptographically-sized curves, but is interesting
-to take into account as it allows exhaustive testing in small groups. See [Section 3.4](#34-dealing-with-special-cases)
-for an analysis of all the negligible cases.
-
-If we define $T = (G_{0,u}(x), G_{1,u}(x), \ldots, G_{7,u}(x))$, with each $G_{i,u}$ matching one of the formulas,
-the loop can be simplified to only compute one of the inverses instead of all of them:
-
-**Define** *ElligatorSwift(x)* as:
-* Loop:
-  * Pick a uniformly random field element $u.$
-  * Pick a uniformly random integer $c$ in $[0,8).$
-  * Let $t = G_{c,u}(x).$
-  * If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
-
-This is implemented in `secp256k1_ellswift_xelligatorswift_var`.
-
-### 3.3 Finding the inverse
-
-To implement $G_{c,u}$, we map $c=0$ to the $x_1$ formula, $c=1$ to the $x_2$ formula, and $c=2$ and $c=3$ to the $x_3$ formula.
-Those are then repeated as $c=4$ through $c=7$ for the other sign of $w$ (noting that in each formula, $w$ is a square root of some expression).
-Ignoring the negligible cases, we get:
-
-**Define** $G_{c,u}(x)$ as:
-* If $c \in \\{0, 1, 4, 5\\}$ (for $x_1$ and $x_2$ formulas):
-  * If $g(-u-x)$ is square, return $\bot$ (as $x_3$ would be valid and take precedence).
-  * If $c \in \\{0, 4\\}$ (the $x_1$ formula) let $v = x$, otherwise let $v = -u-x$ (the $x_2$ formula)
-  * Let $s = -g(u)/(u^2 + uv + v^2 + a)$ (using $s = w^2$ in what follows).
-* Otherwise, when $c \in \\{2, 3, 6, 7\\}$ (for $x_3$ formulas):
-  * Let $s = x-u.$
-  * Let $r = \sqrt{-s(4g(u) + sh(u))}.$
-  * Let $v = (r/s - u)/2$ if $c \in \\{3, 7\\}$; $(-r/s - u)/2$ otherwise.
-* Let $w = \sqrt{s}.$
-* Depending on $c:$
-  * If $c \in \\{0, 1, 2, 3\\}:$ return $P_u^{'-1}(v, w).$
-  * If $c \in \\{4, 5, 6, 7\\}:$ return $P_u^{'-1}(v, -w).$
-
-Whenever a square root of a non-square is taken, $\bot$ is returned; for both square roots this happens with roughly
-50% on random inputs. Similarly, when a division by 0 would occur, $\bot$ is returned as well; this will only happen
-with negligible probability. A division by 0 in the first branch in fact cannot occur at all, because $u^2 + uv + v^2 + a = 0$
-implies $g(-u-x) = g(x)$ which would mean the $g(-u-x)$ is square condition has triggered
-and $\bot$ would have been returned already.
-
-**Note**: In the paper, the $case$ variable corresponds roughly to the $c$ above, but only takes on 4 possible values (1 to 4).
-The conditional negation of $w$ at the end is done randomly, which is equivalent, but makes testing harder. We choose to
-have the $G_{c,u}$ be deterministic, and capture all choices in $c.$
-
-Now observe that the $c \in \\{1, 5\\}$ and $c \in \\{3, 7\\}$ conditions effectively perform the same $v \rightarrow -u-v$
-transformation. Furthermore, that transformation has no effect on $s$ in the first branch
-as $u^2 + ux + x^2 + a = u^2 + u(-u-x) + (-u-x)^2 + a.$ Thus we can extract it out and move it down:
-
-**Define** $G_{c,u}(x)$ as:
-* If $c \in \\{0, 1, 4, 5\\}:$
-  * If $g(-u-x)$ is square, return $\bot.$
-  * Let $s = -g(u)/(u^2 + ux + x^2 + a).$
-  * Let $v = x.$
-* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
-  * Let $s = x-u.$
-  * Let $r = \sqrt{-s(4g(u) + sh(u))}.$
-  * Let $v = (r/s - u)/2.$
-* Let $w = \sqrt{s}.$
-* Depending on $c:$
-  * If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w).$
-  * If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w).$
-  * If $c \in \\{4, 6\\}:$ return $P_u^{'-1}(v, -w).$
-  * If $c \in \\{5, 7\\}:$ return $P_u^{'-1}(-u-v, -w).$
-
-This shows there will always be exactly 0, 4, or 8 $t$ values for a given $(u, x)$ input.
-There can be 0, 1, or 2 $(v, w)$ pairs before invoking $P_u^{'-1}$, and each results in 4 distinct $t$ values.
-
-### 3.4 Dealing with special cases
-
-As mentioned before there are a few cases to deal with which only happen in a negligibly small subset of inputs.
-For cryptographically sized fields, if only random inputs are going to be considered, it is unnecessary to deal with these. Still, for completeness
-we analyse them here. They generally fall into two categories: cases in which the encoder would produce $t$ values that
-do not decode back to $x$ (or at least cannot guarantee that they do), and cases in which the encoder might produce the same
-$t$ value for multiple $c$ inputs (thereby biasing that encoding):
-
-* In the branch for $x_1$ and $x_2$ (where $c \in \\{0, 1, 4, 5\\}$):
-  * When $g(u) = 0$, we would have $s=w=Y=0$, which is not on $S_u.$ This is only possible on even-ordered curves.
-    Excluding this also removes the one condition under which the simplified check for $x_3$ on the curve
-    fails (namely when $g(x_1)=g(x_2)=0$ but $g(x_3)$ is not square).
-    This does exclude some valid encodings: when both $g(u)=0$ and $u^2+ux+x^2+a=0$ (also implying $g(x)=0$),
-    the $S_u'$ equation degenerates to $0 = 0$, and many valid $t$ values may exist. Yet, these cannot be targeted uniformly by the
-    encoder anyway as there will generally be more than 8.
-  * When $g(x) = 0$, the same $t$ would be produced as in the $x_3$ branch (where $c \in \\{2, 3, 6, 7\\}$) which we give precedence
-    as it can deal with $g(u)=0$.
-    This is again only possible on even-ordered curves.
-* In the branch for $x_3$ (where $c \in \\{2, 3, 6, 7\\}$):
-  * When $s=0$, a division by zero would occur.
-  * When $v = -u-v$ and $c \in \\{3, 7\\}$, the same $t$ would be returned as in the $c \in \\{2, 6\\}$ cases.
-    It is equivalent to checking whether $r=0$.
-    This cannot occur in the $x_1$ or $x_2$ branches, as it would trigger the $g(-u-x)$ is square condition.
-    A similar concern for $w = -w$ does not exist, as $w=0$ is already impossible in both branches: in the first
-    it requires $g(u)=0$ which is already outlawed on even-ordered curves and impossible on others; in the second it would trigger division by zero.
-* Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder:
-  * For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve.
-  * For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$.
-
-**Define** a version of $G_{c,u}(x)$ which deals with all these cases:
-* If $a=0$ and $u=0$, return $\bot.$
-* If $a \neq 0$ and $X_0(u)=0$, return $\bot.$
-* If $c \in \\{0, 1, 4, 5\\}:$
-  * If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
-  * If $g(-u-x)$ is square, return $\bot.$
-  * Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
-  * Let $v = x.$
-* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
-  * Let $s = x-u.$
-  * Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
-  * If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
-  * If $s = 0$, return $\bot.$
-  * Let $v = (r/s - u)/2.$
-* Let $w = \sqrt{s}$; return $\bot$ if not square.
-* If $a \neq 0$ and $w(u+2v) = 2X_0(u)$ and either $w \neq 2Y_0(u)$ or $h(u) = 0$, return $\bot.$
-* Depending on $c:$
-  * If $c \in \\{0, 2\\}$, let $t = P_u^{'-1}(v, w).$
-  * If $c \in \\{1, 3\\}$, let $t = P_u^{'-1}(-u-v, w).$
-  * If $c \in \\{4, 6\\}$, let $t = P_u^{'-1}(v, -w).$
-  * If $c \in \\{5, 7\\}$, let $t = P_u^{'-1}(-u-v, -w).$
-* If $a=0$ and $t=0$, return $\bot$ (even curves only).
-* If $a \neq 0$ and $h(u)t^2 = -1$, return $\bot.$
-* Return $t.$
-
-Given any $u$, using this algorithm over all $x$ and $c$ values, every $t$ value will be reached exactly once,
-for an $x$ for which $F_u(t) = x$ holds, except for these cases that will not be reached:
-* All cases where $P_u(t)$ is not defined:
-  * For $a=0$ curves, when $u=0$, $t=0$, or $g(u) = -t^2.$
-  * For $a \neq 0$ curves, when $h(u)t^2 = -1$, $X_0(u) = 0$, or $Y_0(u) (1 - h(u) t^2) = 2X_0(u)t.$
-* When $g(u)=0$, the potentially many $t$ values that decode to an $x$ satisfying $g(x)=0$ using the $x_2$ formula. These were excluded by the $g(u)=0$ condition in the $c \in \\{0, 1, 4, 5\\}$ branch.
-
-These cases form a negligible subset of all $(u, t)$ for cryptographically sized curves.
-
-### 3.5 Encoding for `secp256k1`
-
-Specialized for odd-ordered $a=0$ curves:
-
-**Define** $G_{c,u}(x)$ as:
-* If $u=0$, return $\bot.$
-* If $c \in \\{0, 1, 4, 5\\}:$
-  * If $(-u-x)^3 + b$ is square, return $\bot$
-  * Let $s = -(u^3 + b)/(u^2 + ux + x^2)$ (cannot cause division by 0).
-  * Let $v = x.$
-* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
-  * Let $s = x-u.$
-  * Let $r = \sqrt{-s(4(u^3 + b) + 3su^2)}$; return $\bot$ if not square.
-  * If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
-  * If $s = 0$, return $\bot.$
-  * Let $v = (r/s - u)/2.$
-* Let $w = \sqrt{s}$; return $\bot$ if not square.
-* Depending on $c:$
-  * If $c \in \\{0, 2\\}:$ return $w(\frac{\sqrt{-3}-1}{2}u - v).$
-  * If $c \in \\{1, 3\\}:$ return $w(\frac{\sqrt{-3}+1}{2}u + v).$
-  * If $c \in \\{4, 6\\}:$ return $w(\frac{-\sqrt{-3}+1}{2}u + v).$
-  * If $c \in \\{5, 7\\}:$ return $w(\frac{-\sqrt{-3}-1}{2}u - v).$
-
-This is implemented in `secp256k1_ellswift_xswiftec_inv_var`.
-
-And the x-only ElligatorSwift encoding algorithm is still:
-
-**Define** *ElligatorSwift(x)* as:
-* Loop:
-  * Pick a uniformly random field element $u.$
-  * Pick a uniformly random integer $c$ in $[0,8).$
-  * Let $t = G_{c,u}(x).$
-  * If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
-
-Note that this logic does not take the remapped $u=0$, $t=0$, and $g(u) = -t^2$ cases into account; it just avoids them.
-While it is not impossible to make the encoder target them, this would increase the maximum number of $t$ values for a given $(u, x)$
-combination beyond 8, and thereby slow down the ElligatorSwift loop proportionally, for a negligible gain in uniformity.
-
-## 4. Encoding and decoding full *(x, y)* coordinates
-
-So far we have only addressed encoding and decoding x-coordinates, but in some cases an encoding
-for full points with $(x, y)$ coordinates is desirable. It is possible to encode this information
-in $t$ as well.
-
-Note that for any $(X, Y) \in S_u$, $(\pm X, \pm Y)$ are all on $S_u.$ Moreover, all of these are
-mapped to the same x-coordinate. Negating $X$ or negating $Y$ just results in $x_1$ and $x_2$
-being swapped, and does not affect $x_3.$ This will not change the outcome x-coordinate as the order
-of $x_1$ and $x_2$ only matters if both were to be valid, and in that case $x_3$ would be used instead.
-
-Still, these four $(X, Y)$ combinations all correspond to distinct $t$ values, so we can encode
-the sign of the y-coordinate in the sign of $X$ or the sign of $Y.$ They correspond to the
-four distinct $P_u^{'-1}$ calls in the definition of $G_{u,c}.$
-
-**Note**: In the paper, the sign of the y coordinate is encoded in a separately-coded bit.
-
-To encode the sign of $y$ in the sign of $Y:$
-
-**Define** *Decode(u, t)* for full $(x, y)$ as:
-* Let $(X, Y) = P_u(t).$
-* Let $x$ be the first value in $(u + 4Y^2, \frac{-X}{2Y} - \frac{u}{2}, \frac{X}{2Y} - \frac{u}{2})$ for which $g(x)$ is square.
-* Let $y = \sqrt{g(x)}.$
-* If $sign(y) = sign(Y)$, return $(x, y)$; otherwise return $(x, -y).$
-
-And encoding would be done using a $G_{c,u}(x, y)$ function defined as:
-
-**Define** $G_{c,u}(x, y)$ as:
-* If $c \in \\{0, 1\\}:$
-  * If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
-  * If $g(-u-x)$ is square, return $\bot.$
-  * Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
-  * Let $v = x.$
-* Otherwise, when $c \in \\{2, 3\\}:$
-  * Let $s = x-u.$
-  * Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
-  * If $c = 3$ and $r = 0$, return $\bot.$
-  * Let $v = (r/s - u)/2.$
-* Let $w = \sqrt{s}$; return $\bot$ if not square.
-* Let $w' = w$ if $sign(w/2) = sign(y)$; $-w$ otherwise.
-* Depending on $c:$
-  * If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w').$
-  * If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w').$
-
-Note that $c$ now only ranges $[0,4)$, as the sign of $w'$ is decided based on that of $y$, rather than on $c.$
-This change makes some valid encodings unreachable: when $y = 0$ and $sign(Y) \neq sign(0)$.
-
-In the above logic, $sign$ can be implemented in several ways, such as parity of the integer representation
-of the input field element (for prime-sized fields) or the quadratic residuosity (for fields where
-$-1$ is not square). The choice does not matter, as long as it only takes on two possible values, and for $x \neq 0$ it holds that $sign(x) \neq sign(-x)$.
-
-### 4.1 Full *(x, y)* coordinates for `secp256k1`
-
-For $a=0$ curves, there is another option. Note that for those,
-the $P_u(t)$ function translates negations of $t$ to negations of (both) $X$ and $Y.$ Thus, we can use $sign(t)$ to
-encode the y-coordinate directly. Combined with the earlier remapping to guarantee all inputs land on the curve, we get
-as decoder:
-
-**Define** *Decode(u, t)* as:
-* Let $u'=u$ if $u \neq 0$; $1$ otherwise.
-* Let $t'=t$ if $t \neq 0$; $1$ otherwise.
-* Let $t''=t'$ if $u'^3 + b + t'^2 \neq 0$; $2t'$ otherwise.
-* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
-* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
-* Let $x$ be the first element of $(u' + 4Y^2, \frac{-X}{2Y} - \frac{u'}{2}, \frac{X}{2Y} - \frac{u'}{2})$ for which $g(x)$ is square.
-* Let $y = \sqrt{g(x)}.$
-* Return $(x, y)$ if $sign(y) = sign(t)$; $(x, -y)$ otherwise.
-
-This is implemented in `secp256k1_ellswift_swiftec_var`. The used $sign(x)$ function is the parity of $x$ when represented as in integer in $[0,q).$
-
-The corresponding encoder would invoke the x-only one, but negating the output $t$ if $sign(t) \neq sign(y).$
-
-This is implemented in `secp256k1_ellswift_elligatorswift_var`.
-
-Note that this is only intended for encoding points where both the x-coordinate and y-coordinate are unpredictable. When encoding x-only points
-where the y-coordinate is implicitly even (or implicitly square, or implicitly in $[0,q/2]$), the encoder in
-[Section 3.5](#35-encoding-for-secp256k1) must be used, or a bias is reintroduced that undoes all the benefit of using ElligatorSwift
-in the first place.
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index e2ea473..e095b7f 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -6,6 +6,9 @@ target_link_libraries(example INTERFACE
   secp256k1
   $<$<PLATFORM_ID:Windows>:bcrypt>
 )
+if(NOT BUILD_SHARED_LIBS AND MSVC)
+  target_link_options(example INTERFACE /IGNORE:4217)
+endif()
 
 add_executable(ecdsa_example ecdsa.c)
 target_link_libraries(ecdsa_example example)
diff --git a/examples/examples_util.h b/examples/examples_util.h
index 3293b64..8e3a8f0 100644
--- a/examples/examples_util.h
+++ b/examples/examples_util.h
@@ -95,7 +95,7 @@ static void secure_erase(void *ptr, size_t len) {
      *    As best as we can tell, this is sufficient to break any optimisations that
      *    might try to eliminate "superfluous" memsets.
      * This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is
-     * pretty efficient, because the compiler can still implement the memset() efficiently,
+     * pretty efficient, because the compiler can still implement the memset() efficently,
      * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
      * Yang et al. (USENIX Security 2017) for more background.
      */
diff --git a/include/secp256k1.h b/include/secp256k1.h
index 936f0b4..a7a2be7 100644
--- a/include/secp256k1.h
+++ b/include/secp256k1.h
@@ -133,35 +133,28 @@ typedef int (*secp256k1_nonce_function)(
 # define SECP256K1_NO_BUILD
 #endif
 
-/* Symbol visibility. */
-#if defined(_WIN32)
-  /* GCC for Windows (e.g., MinGW) accepts the __declspec syntax
-   * for MSVC compatibility. A __declspec declaration implies (but is not
-   * exactly equivalent to) __attribute__ ((visibility("default"))), and so we
-   * actually want __declspec even on GCC, see "Microsoft Windows Function
-   * Attributes" in the GCC manual and the recommendations in
-   * https://gcc.gnu.org/wiki/Visibility. */
-# if defined(SECP256K1_BUILD)
-#  if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT)
-    /* Building libsecp256k1 as a DLL.
-     * 1. If using Libtool, it defines DLL_EXPORT automatically.
-     * 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */
-#   define SECP256K1_API extern __declspec (dllexport)
+/* Symbol visibility. See libtool manual, section "Windows DLLs". */
+#if defined(_WIN32) && !defined(__GNUC__)
+# ifdef SECP256K1_BUILD
+#  ifdef DLL_EXPORT
+#   define SECP256K1_API            __declspec (dllexport)
+#   define SECP256K1_API_VAR extern __declspec (dllexport)
 #  endif
-  /* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static
-   * library on Windows. */
-# elif !defined(SECP256K1_STATIC)
-   /* Consuming libsecp256k1 as a DLL. */
-#  define SECP256K1_API extern __declspec (dllimport)
+# elif defined _MSC_VER
+#  define SECP256K1_API
+#  define SECP256K1_API_VAR  extern __declspec (dllimport)
+# elif defined DLL_EXPORT
+#  define SECP256K1_API             __declspec (dllimport)
+#  define SECP256K1_API_VAR  extern __declspec (dllimport)
 # endif
 #endif
 #ifndef SECP256K1_API
 # if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
-   /* Building libsecp256k1 on non-Windows using GCC or compatible. */
-#  define SECP256K1_API extern __attribute__ ((visibility ("default")))
+#  define SECP256K1_API             __attribute__ ((visibility ("default")))
+#  define SECP256K1_API_VAR  extern __attribute__ ((visibility ("default")))
 # else
-   /* All cases not captured above. */
-#  define SECP256K1_API extern
+#  define SECP256K1_API
+#  define SECP256K1_API_VAR  extern
 # endif
 #endif
 
@@ -233,10 +226,10 @@ typedef int (*secp256k1_nonce_function)(
  *
  *  It is highly recommended to call secp256k1_selftest before using this context.
  */
-SECP256K1_API const secp256k1_context *secp256k1_context_static;
+SECP256K1_API_VAR const secp256k1_context *secp256k1_context_static;
 
 /** Deprecated alias for secp256k1_context_static. */
-SECP256K1_API const secp256k1_context *secp256k1_context_no_precomp
+SECP256K1_API_VAR const secp256k1_context *secp256k1_context_no_precomp
 SECP256K1_DEPRECATED("Use secp256k1_context_static instead");
 
 /** Perform basic self tests (to be used in conjunction with secp256k1_context_static)
@@ -633,10 +626,10 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize(
  * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
  * extra entropy.
  */
-SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
+SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
 
 /** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
-SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_default;
+SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_default;
 
 /** Create an ECDSA signature.
  *
@@ -740,10 +733,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
  *                  invalid according to secp256k1_ec_seckey_verify, this
  *                  function returns 0. seckey will be set to some unspecified
  *                  value if this function returns 0.
- *  In:    tweak32: pointer to a 32-byte tweak, which must be valid according to
- *                  secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
- *                  random 32-byte tweaks, the chance of being invalid is
- *                  negligible (around 1 in 2^128).
+ *  In:    tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
+ *                  secp256k1_ec_seckey_verify, this function returns 0. For
+ *                  uniformly random 32-byte arrays the chance of being invalid
+ *                  is negligible (around 1 in 2^128).
  */
 SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
     const secp256k1_context *ctx,
@@ -768,10 +761,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
  *  Args:    ctx:   pointer to a context object.
  *  In/Out: pubkey: pointer to a public key object. pubkey will be set to an
  *                  invalid value if this function returns 0.
- *  In:    tweak32: pointer to a 32-byte tweak, which must be valid according to
- *                  secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
- *                  random 32-byte tweaks, the chance of being invalid is
- *                  negligible (around 1 in 2^128).
+ *  In:    tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
+ *                  secp256k1_ec_seckey_verify, this function returns 0. For
+ *                  uniformly random 32-byte arrays the chance of being invalid
+ *                  is negligible (around 1 in 2^128).
  */
 SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
     const secp256k1_context *ctx,
diff --git a/include/secp256k1_ecdh.h b/include/secp256k1_ecdh.h
index 515e174..837ae2a 100644
--- a/include/secp256k1_ecdh.h
+++ b/include/secp256k1_ecdh.h
@@ -27,11 +27,11 @@ typedef int (*secp256k1_ecdh_hash_function)(
 
 /** An implementation of SHA256 hash function that applies to compressed public key.
  * Populates the output parameter with 32 bytes. */
-SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
+SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
 
 /** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256).
  * Populates the output parameter with 32 bytes. */
-SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
+SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
 
 /** Compute an EC Diffie-Hellman secret in constant time
  *
diff --git a/include/secp256k1_ellswift.h b/include/secp256k1_ellswift.h
deleted file mode 100644
index f79bd88..0000000
--- a/include/secp256k1_ellswift.h
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef SECP256K1_ELLSWIFT_H
-#define SECP256K1_ELLSWIFT_H
-
-#include "secp256k1.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This module provides an implementation of ElligatorSwift as well as a
- * version of x-only ECDH using it (including compatibility with BIP324).
- *
- * ElligatorSwift is described in https://eprint.iacr.org/2022/759 by
- * Chavez-Saab, Rodriguez-Henriquez, and Tibouchi. It permits encoding
- * uniformly chosen public keys as 64-byte arrays which are indistinguishable
- * from uniformly random arrays.
- *
- * Let f be the function from pairs of field elements to point X coordinates,
- * defined as follows (all operations modulo p = 2^256 - 2^32 - 977)
- * f(u,t):
- * - Let C = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852,
- *   a square root of -3.
- * - If u=0, set u=1 instead.
- * - If t=0, set t=1 instead.
- * - If u^3 + t^2 + 7 = 0, multiply t by 2.
- * - Let X = (u^3 + 7 - t^2) / (2 * t)
- * - Let Y = (X + t) / (C * u)
- * - Return the first in [u + 4 * Y^2, (-X/Y - u) / 2, (X/Y - u) / 2] that is an
- *   X coordinate on the curve (at least one of them is, for any u and t).
- *
- * Then an ElligatorSwift encoding of x consists of the 32-byte big-endian
- * encodings of field elements u and t concatenated, where f(u,t) = x.
- * The encoding algorithm is described in the paper, and effectively picks a
- * uniformly random pair (u,t) among those which encode x.
- *
- * If the Y coordinate is relevant, it is given the same parity as t.
- *
- * Changes w.r.t. the the paper:
- * - The u=0, t=0, and u^3+t^2+7=0 conditions result in decoding to the point
- *   at infinity in the paper. Here they are remapped to finite points.
- * - The paper uses an additional encoding bit for the parity of y. Here the
- *   parity of t is used (negating t does not affect the decoded x coordinate,
- *   so this is possible).
- *
- * For mathematical background about the scheme, see the doc/ellswift.md file.
- */
-
-/** A pointer to a function used by secp256k1_ellswift_xdh to hash the shared X
- *  coordinate along with the encoded public keys to a uniform shared secret.
- *
- *  Returns: 1 if a shared secret was successfully computed.
- *           0 will cause secp256k1_ellswift_xdh to fail and return 0.
- *           Other return values are not allowed, and the behaviour of
- *           secp256k1_ellswift_xdh is undefined for other return values.
- *  Out:     output:     pointer to an array to be filled by the function
- *  In:      x32:        pointer to the 32-byte serialized X coordinate
- *                       of the resulting shared point (will not be NULL)
- *           ell_a64:    pointer to the 64-byte encoded public key of party A
- *                       (will not be NULL)
- *           ell_b64:    pointer to the 64-byte encoded public key of party B
- *                       (will not be NULL)
- *           data:       arbitrary data pointer that is passed through
- */
-typedef int (*secp256k1_ellswift_xdh_hash_function)(
-    unsigned char *output,
-    const unsigned char *x32,
-    const unsigned char *ell_a64,
-    const unsigned char *ell_b64,
-    void *data
-);
-
-/** An implementation of an secp256k1_ellswift_xdh_hash_function which uses
- *  SHA256(prefix64 || ell_a64 || ell_b64 || x32), where prefix64 is the 64-byte
- *  array pointed to by data. */
-SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix;
-
-/** An implementation of an secp256k1_ellswift_xdh_hash_function compatible with
- *  BIP324. It returns H_tag(ell_a64 || ell_b64 || x32), where H_tag is the
- *  BIP340 tagged hash function with tag "bip324_ellswift_xonly_ecdh". Equivalent
- *  to secp256k1_ellswift_xdh_hash_function_prefix with prefix64 set to
- *  SHA256("bip324_ellswift_xonly_ecdh")||SHA256("bip324_ellswift_xonly_ecdh").
- *  The data argument is ignored. */
-SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324;
-
-/** Construct a 64-byte ElligatorSwift encoding of a given pubkey.
- *
- *  Returns: 1 always.
- *  Args:    ctx:        pointer to a context object
- *  Out:     ell64:      pointer to a 64-byte array to be filled
- *  In:      pubkey:     a pointer to a secp256k1_pubkey containing an
- *                       initialized public key
- *           rnd32:      pointer to 32 bytes of randomness
- *
- * It is recommended that rnd32 consists of 32 uniformly random bytes, not
- * known to any adversary trying to detect whether public keys are being
- * encoded, though 16 bytes of randomness (padded to an array of 32 bytes,
- * e.g., with zeros) suffice to make the result indistinguishable from
- * uniform. The randomness in rnd32 must not be a deterministic function of
- * the pubkey (it can be derived from the private key, though).
- *
- * It is not guaranteed that the computed encoding is stable across versions
- * of the library, even if all arguments to this function (including rnd32)
- * are the same.
- *
- * This function runs in variable time.
- */
-SECP256K1_API int secp256k1_ellswift_encode(
-    const secp256k1_context *ctx,
-    unsigned char *ell64,
-    const secp256k1_pubkey *pubkey,
-    const unsigned char *rnd32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
-
-/** Decode a 64-bytes ElligatorSwift encoded public key.
- *
- *  Returns: always 1
- *  Args:    ctx:        pointer to a context object
- *  Out:     pubkey:     pointer to a secp256k1_pubkey that will be filled
- *  In:      ell64:      pointer to a 64-byte array to decode
- *
- * This function runs in variable time.
- */
-SECP256K1_API int secp256k1_ellswift_decode(
-    const secp256k1_context *ctx,
-    secp256k1_pubkey *pubkey,
-    const unsigned char *ell64
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Compute an ElligatorSwift public key for a secret key.
- *
- *  Returns: 1: secret was valid, public key was stored.
- *           0: secret was invalid, try again.
- *  Args:    ctx:        pointer to a context object
- *  Out:     ell64:      pointer to a 64-byte array to receive the ElligatorSwift
- *                       public key
- *  In:      seckey32:   pointer to a 32-byte secret key
- *           auxrnd32:   (optional) pointer to 32 bytes of randomness
- *
- * Constant time in seckey and auxrnd32, but not in the resulting public key.
- *
- * It is recommended that auxrnd32 contains 32 uniformly random bytes, though
- * it is optional (and does result in encodings that are indistinguishable from
- * uniform even without any auxrnd32). It differs from the (mandatory) rnd32
- * argument to secp256k1_ellswift_encode in this regard.
- *
- * This function can be used instead of calling secp256k1_ec_pubkey_create
- * followed by secp256k1_ellswift_encode. It is safer, as it uses the secret
- * key as entropy for the encoding (supplemented with auxrnd32, if provided).
- *
- * Like secp256k1_ellswift_encode, this function does not guarantee that the
- * computed encoding is stable across versions of the library, even if all
- * arguments (including auxrnd32) are the same.
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create(
-    const secp256k1_context *ctx,
-    unsigned char *ell64,
-    const unsigned char *seckey32,
-    const unsigned char *auxrnd32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Given a private key, and ElligatorSwift public keys sent in both directions,
- *  compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH).
- *
- *  Returns: 1: shared secret was successfully computed
- *           0: secret was invalid or hashfp returned 0
- *  Args:    ctx:       pointer to a context object.
- *  Out:     output:    pointer to an array to be filled by hashfp.
- *  In:      ell_a64:   pointer to the 64-byte encoded public key of party A
- *                      (will not be NULL)
- *           ell_b64:   pointer to the 64-byte encoded public key of party B
- *                      (will not be NULL)
- *           seckey32:  a pointer to our 32-byte secret key
- *           party:     boolean indicating which party we are: zero if we are
- *                      party A, non-zero if we are party B. seckey32 must be
- *                      the private key corresponding to that party's ell_?64.
- *                      This correspondence is not checked.
- *           hashfp:    pointer to a hash function.
- *           data:      arbitrary data pointer passed through to hashfp.
- *
- * Constant time in seckey32.
- *
- * This function is more efficient than decoding the public keys, and performing
- * ECDH on them.
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_xdh(
-  const secp256k1_context *ctx,
-  unsigned char *output,
-  const unsigned char *ell_a64,
-  const unsigned char *ell_b64,
-  const unsigned char *seckey32,
-  int party,
-  secp256k1_ellswift_xdh_hash_function hashfp,
-  void *data
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SECP256K1_ELLSWIFT_H */
diff --git a/include/secp256k1_extrakeys.h b/include/secp256k1_extrakeys.h
index 7fcce68..52bba24 100644
--- a/include/secp256k1_extrakeys.h
+++ b/include/secp256k1_extrakeys.h
@@ -112,10 +112,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubke
  *  Out:  output_pubkey: pointer to a public key to store the result. Will be set
  *                       to an invalid value if this function returns 0.
  *  In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to.
- *              tweak32: pointer to a 32-byte tweak, which must be valid
- *                       according to secp256k1_ec_seckey_verify or 32 zero
- *                       bytes. For uniformly random 32-byte tweaks, the chance of
- *                       being invalid is negligible (around 1 in 2^128).
+ *              tweak32: pointer to a 32-byte tweak. If the tweak is invalid
+ *                       according to secp256k1_ec_seckey_verify, this function
+ *                       returns 0. For uniformly random 32-byte arrays the
+ *                       chance of being invalid is negligible (around 1 in 2^128).
  */
 SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
     const secp256k1_context *ctx,
@@ -185,8 +185,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
 /** Get the public key from a keypair.
  *
  *  Returns: 1 always.
- *  Args:   ctx: pointer to a context object.
- *  Out: pubkey: pointer to a pubkey object, set to the keypair public key.
+ *  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.
  *  In: keypair: pointer to a keypair.
  */
 SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
@@ -202,8 +203,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
  *
  *  Returns: 1 always.
  *  Args:   ctx: pointer to a context object.
- *  Out: pubkey: pointer to an xonly_pubkey object, set to the keypair
- *               public key after converting it to an xonly_pubkey.
+ *  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
+ *               xonly_pubkey. If not, it's set to an invalid value.
  *    pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the
  *               pk_parity argument of secp256k1_xonly_pubkey_from_pubkey.
  *  In: keypair: pointer to a keypair.
@@ -229,10 +231,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
  *  Args:       ctx: pointer to a context object.
  *  In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to
  *                   an invalid value if this function returns 0.
- *  In:     tweak32: pointer to a 32-byte tweak, which must be valid according to
- *                   secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
- *                   random 32-byte tweaks, the chance of being invalid is
- *                   negligible (around 1 in 2^128).
+ *  In:     tweak32: pointer to a 32-byte tweak. If the tweak is invalid according
+ *                   to secp256k1_ec_seckey_verify, this function returns 0. For
+ *                   uniformly random 32-byte arrays the chance of being invalid
+ *                   is negligible (around 1 in 2^128).
  */
 SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
     const secp256k1_context *ctx,
diff --git a/include/secp256k1_schnorrsig.h b/include/secp256k1_schnorrsig.h
index 2635853..1ee665f 100644
--- a/include/secp256k1_schnorrsig.h
+++ b/include/secp256k1_schnorrsig.h
@@ -61,7 +61,7 @@ typedef int (*secp256k1_nonce_function_hardened)(
  *  Therefore, to create BIP-340 compliant signatures, algo must be set to
  *  "BIP0340/nonce" and algolen to 13.
  */
-SECP256K1_API const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
+SECP256K1_API_VAR const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
 
 /** Data structure that contains additional arguments for schnorrsig_sign_custom.
  *
diff --git a/sage/group_prover.sage b/sage/group_prover.sage
index bb09295..9305c21 100644
--- a/sage/group_prover.sage
+++ b/sage/group_prover.sage
@@ -198,7 +198,7 @@ def normalize_factor(p):
   (8) * (-bx + ax)^3
   ```
   """
-  # Assert p is not 0 and that its non-zero coefficients are coprime.
+  # Assert p is not 0 and that its non-zero coeffients are coprime.
   # (We could just work with the primitive part p/p.content() but we want to be
   # aware if factor() does not return a primitive part in future sage versions.)
   assert p.content() == 1
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b305751..93844ca 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,10 +20,10 @@ if(SECP256K1_ASM STREQUAL "arm32")
   target_link_libraries(secp256k1_asm INTERFACE secp256k1_asm_arm)
 endif()
 
+# Define our export symbol only for Win32 and only for shared libs.
+# This matches libtool's usage of DLL_EXPORT
 if(WIN32)
-  # Define our export symbol only for shared libs.
-  set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL SECP256K1_DLL_EXPORT)
-  target_compile_definitions(secp256k1 INTERFACE $<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:SECP256K1_STATIC>)
+  set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL "DLL_EXPORT")
 endif()
 
 # Object libs don't know if they're being built for a shared or static lib.
@@ -132,9 +132,6 @@ if(SECP256K1_INSTALL)
   if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
     list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_schnorrsig.h")
   endif()
-  if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
-    list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ellswift.h")
-  endif()
   install(FILES ${${PROJECT_NAME}_headers}
     DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
   )
diff --git a/src/bench.c b/src/bench.c
index 1127df6..9992056 100644
--- a/src/bench.c
+++ b/src/bench.c
@@ -38,8 +38,6 @@ static void help(int default_iters) {
     printf("    ecdsa             : all ECDSA algorithms--sign, verify, recovery (if enabled)\n");
     printf("    ecdsa_sign        : ECDSA siging algorithm\n");
     printf("    ecdsa_verify      : ECDSA verification algorithm\n");
-    printf("    ec                : all EC public key algorithms (keygen)\n");
-    printf("    ec_keygen         : EC public key generation\n");
 
 #ifdef ENABLE_MODULE_RECOVERY
     printf("    ecdsa_recover     : ECDSA public key recovery algorithm\n");
@@ -55,14 +53,6 @@ static void help(int default_iters) {
     printf("    schnorrsig_verify : Schnorr verification algorithm\n");
 #endif
 
-#ifdef ENABLE_MODULE_ELLSWIFT
-    printf("    ellswift          : all ElligatorSwift benchmarks (encode, decode, keygen, ecdh)\n");
-    printf("    ellswift_encode   : ElligatorSwift encoding\n");
-    printf("    ellswift_decode   : ElligatorSwift decoding\n");
-    printf("    ellswift_keygen   : ElligatorSwift key generation\n");
-    printf("    ellswift_ecdh     : ECDH on ElligatorSwift keys\n");
-#endif
-
     printf("\n");
 }
 
@@ -125,30 +115,6 @@ static void bench_sign_run(void* arg, int iters) {
     }
 }
 
-static void bench_keygen_setup(void* arg) {
-    int i;
-    bench_data *data = (bench_data*)arg;
-
-    for (i = 0; i < 32; i++) {
-        data->key[i] = i + 65;
-    }
-}
-
-static void bench_keygen_run(void *arg, int iters) {
-    int i;
-    bench_data *data = (bench_data*)arg;
-
-    for (i = 0; i < iters; i++) {
-        unsigned char pub33[33];
-        size_t len = 33;
-        secp256k1_pubkey pubkey;
-        CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->key));
-        CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pub33, &len, &pubkey, SECP256K1_EC_COMPRESSED));
-        memcpy(data->key, pub33 + 1, 32);
-    }
-}
-
-
 #ifdef ENABLE_MODULE_ECDH
 # include "modules/ecdh/bench_impl.h"
 #endif
@@ -161,10 +127,6 @@ static void bench_keygen_run(void *arg, int iters) {
 # include "modules/schnorrsig/bench_impl.h"
 #endif
 
-#ifdef ENABLE_MODULE_ELLSWIFT
-# include "modules/ellswift/bench_impl.h"
-#endif
-
 int main(int argc, char** argv) {
     int i;
     secp256k1_pubkey pubkey;
@@ -177,9 +139,7 @@ int main(int argc, char** argv) {
 
     /* Check for invalid user arguments */
     char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover",
-                         "ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign", "ec",
-                         "keygen", "ec_keygen", "ellswift", "encode", "ellswift_encode", "decode",
-                         "ellswift_decode", "ellswift_keygen", "ellswift_ecdh"};
+                         "ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign"};
     size_t valid_args_size = sizeof(valid_args)/sizeof(valid_args[0]);
     int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size);
 
@@ -221,16 +181,6 @@ int main(int argc, char** argv) {
     }
 #endif
 
-#ifndef ENABLE_MODULE_ELLSWIFT
-    if (have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "ellswift_encode") || have_flag(argc, argv, "ellswift_decode") ||
-        have_flag(argc, argv, "encode") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_keygen") ||
-        have_flag(argc, argv, "ellswift_ecdh")) {
-        fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n");
-        fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n");
-        return 1;
-    }
-#endif
-
     /* ECDSA benchmark */
     data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
 
@@ -251,7 +201,6 @@ int main(int argc, char** argv) {
     if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "ecdsa_verify")) run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters);
 
     if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "ecdsa_sign")) run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters);
-    if (d || have_flag(argc, argv, "ec") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ec_keygen")) run_benchmark("ec_keygen", bench_keygen_run, bench_keygen_setup, NULL, &data, 10, iters);
 
     secp256k1_context_destroy(data.ctx);
 
@@ -270,10 +219,5 @@ int main(int argc, char** argv) {
     run_schnorrsig_bench(iters, argc, argv);
 #endif
 
-#ifdef ENABLE_MODULE_ELLSWIFT
-    /* ElligatorSwift benchmarks */
-    run_ellswift_bench(iters, argc, argv);
-#endif
-
     return 0;
 }
diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h
index 48e3085..e71254d 100644
--- a/src/ecdsa_impl.h
+++ b/src/ecdsa_impl.h
@@ -16,17 +16,8 @@
 #include "ecdsa.h"
 
 /** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1
- *  sage: for t in xrange(1023, -1, -1):
- *     ..   p = 2**256 - 2**32 - t
- *     ..   if p.is_prime():
- *     ..     print '%x'%p
- *     ..     break
- *   'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'
- *  sage: a = 0
- *  sage: b = 7
- *  sage: F = FiniteField (p)
- *  sage: '%x' % (EllipticCurve ([F (a), F (b)]).order())
- *   'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'
+ *  $ sage -c 'load("secp256k1_params.sage"); print(hex(N))'
+ *  0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
  */
 static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST(
     0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL,
@@ -35,12 +26,8 @@ static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST
 
 /** Difference between field and order, values 'p' and 'n' values defined in
  *  "Standards for Efficient Cryptography" (SEC2) 2.7.1.
- *  sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
- *  sage: a = 0
- *  sage: b = 7
- *  sage: F = FiniteField (p)
- *  sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order())
- *   '14551231950b75fc4402da1722fc9baee'
+ *  $ sage -c 'load("secp256k1_params.sage"); print(hex(P-N))'
+ *  0x14551231950b75fc4402da1722fc9baee
  */
 static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST(
     0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
diff --git a/src/ecmult.h b/src/ecmult.h
index 326a5ee..e28c602 100644
--- a/src/ecmult.h
+++ b/src/ecmult.h
@@ -22,7 +22,7 @@
 #  pragma message DEBUG_CONFIG_DEF(ECMULT_WINDOW_SIZE)
 #endif
 
-/* No one will ever need more than a window size of 24. The code might
+/* Noone will ever need more than a window size of 24. The code might
  * be correct for larger values of ECMULT_WINDOW_SIZE but this is not
  * tested.
  *
diff --git a/src/ecmult_const_impl.h b/src/ecmult_const_impl.h
index 06f9e53..26b3e23 100644
--- a/src/ecmult_const_impl.h
+++ b/src/ecmult_const_impl.h
@@ -276,7 +276,7 @@ static int secp256k1_ecmult_const_xonly(secp256k1_fe* r, const secp256k1_fe *n,
      *
      * It is easy to verify that both (n*g, g^2, v) and its negation (n*g, -g^2, v) have affine X
      * coordinate n/d, and this holds even when the square root function doesn't have a
-     * deterministic sign. We choose the (n*g, g^2, v) version.
+     * determinstic sign. We choose the (n*g, g^2, v) version.
      *
      * Now switch to the effective affine curve using phi_v, where the input point has coordinates
      * (n*g, g^2). Compute (X, Y, Z) = q * (n*g, g^2) there.
diff --git a/src/ecmult_gen_compute_table_impl.h b/src/ecmult_gen_compute_table_impl.h
index dfbacdb..7d672b9 100644
--- a/src/ecmult_gen_compute_table_impl.h
+++ b/src/ecmult_gen_compute_table_impl.h
@@ -22,9 +22,6 @@ static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, cons
     secp256k1_gej nums_gej;
     int i, j;
 
-    VERIFY_CHECK(g > 0);
-    VERIFY_CHECK(n > 0);
-
     /* get the generator */
     secp256k1_gej_set_ge(&gj, gen);
 
diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h
index 6d14c7a..f462467 100644
--- a/src/ecmult_impl.h
+++ b/src/ecmult_impl.h
@@ -288,9 +288,7 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *
     }
 
     /* Bring them to the same Z denominator. */
-    if (no) {
-        secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, state->aux);
-    }
+    secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, state->aux);
 
     for (np = 0; np < no; ++np) {
         for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) {
diff --git a/src/field.h b/src/field.h
index bb99f94..e632f9e 100644
--- a/src/field.h
+++ b/src/field.h
@@ -88,8 +88,8 @@ static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST(
 #  define secp256k1_fe_set_b32_mod secp256k1_fe_impl_set_b32_mod
 #  define secp256k1_fe_set_b32_limit secp256k1_fe_impl_set_b32_limit
 #  define secp256k1_fe_get_b32 secp256k1_fe_impl_get_b32
-#  define secp256k1_fe_negate_unchecked secp256k1_fe_impl_negate_unchecked
-#  define secp256k1_fe_mul_int_unchecked secp256k1_fe_impl_mul_int_unchecked
+#  define secp256k1_fe_negate secp256k1_fe_impl_negate
+#  define secp256k1_fe_mul_int secp256k1_fe_impl_mul_int
 #  define secp256k1_fe_add secp256k1_fe_impl_add
 #  define secp256k1_fe_mul secp256k1_fe_impl_mul
 #  define secp256k1_fe_sqr secp256k1_fe_impl_sqr
@@ -192,14 +192,14 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b);
 
 /** Set a field element equal to a provided 32-byte big endian value, reducing it.
  *
- * On input, r does not need to be initialized. a must be a pointer to an initialized 32-byte array.
+ * On input, r does not need to be initalized. a must be a pointer to an initialized 32-byte array.
  * On output, r = a (mod p). It will have magnitude 1, and not be normalized.
  */
 static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a);
 
 /** Set a field element equal to a provided 32-byte big endian value, checking for overflow.
  *
- * On input, r does not need to be initialized. a must be a pointer to an initialized 32-byte array.
+ * On input, r does not need to be initalized. a must be a pointer to an initialized 32-byte array.
  * On output, r = a if (a < p), it will be normalized with magnitude 1, and 1 is returned.
  * If a >= p, 0 is returned, and r will be made invalid (and must not be used without overwriting).
  */
@@ -214,17 +214,11 @@ static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a);
 /** Negate a field element.
  *
  * On input, r does not need to be initialized. a must be a valid field element with
- * magnitude not exceeding m. m must be an integer constant expression in [0,31].
+ * magnitude not exceeding m. m must be an integer in [0,31].
  * Performs {r = -a}.
  * On output, r will not be normalized, and will have magnitude m+1.
  */
-#define secp256k1_fe_negate(r, a, m) ASSERT_INT_CONST_AND_DO(m, secp256k1_fe_negate_unchecked(r, a, m))
-
-/** Like secp256k1_fe_negate_unchecked but m is not checked to be an integer constant expression.
- *
- * Should not be called directly outside of tests.
- */
-static void secp256k1_fe_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m);
+static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m);
 
 /** Add a small integer to a field element.
  *
@@ -235,18 +229,12 @@ static void secp256k1_fe_add_int(secp256k1_fe *r, int a);
 
 /** Multiply a field element with a small integer.
  *
- * On input, r must be a valid field element. a must be an integer constant expression in [0,32].
+ * On input, r must be a valid field element. a must be an integer in [0,32].
  * The magnitude of r times a must not exceed 32.
  * Performs {r *= a}.
  * On output, r's magnitude is multiplied by a, and r will not be normalized.
  */
-#define secp256k1_fe_mul_int(r, a) ASSERT_INT_CONST_AND_DO(a, secp256k1_fe_mul_int_unchecked(r, a))
-
-/** Like secp256k1_fe_mul_int but a is not checked to be an integer constant expression.
- * 
- * Should not be called directly outside of tests.
- */
-static void secp256k1_fe_mul_int_unchecked(secp256k1_fe *r, int a);
+static void secp256k1_fe_mul_int(secp256k1_fe *r, int a);
 
 /** Increment a field element by another.
  *
@@ -279,10 +267,8 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a);
 /** Compute a square root of a field element.
  *
  * On input, a must be a valid field element with magnitude<=8; r need not be initialized.
- * If sqrt(a) exists, performs {r = sqrt(a)} and returns 1.
- * Otherwise, sqrt(-a) exists. The function performs {r = sqrt(-a)} and returns 0.
- * The resulting value represented by r will be a square itself.
- * Variables r and a must not point to the same object.
+ * Performs {r = sqrt(a)} or {r = sqrt(-a)}, whichever exists. The resulting value
+ * represented by r will be a square itself. Variables r and a must not point to the same object.
  * On output, r will have magnitude 1 but will not be normalized.
  */
 static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a);
diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h
index 8445db1..c1b32b8 100644
--- a/src/field_10x26_impl.h
+++ b/src/field_10x26_impl.h
@@ -344,7 +344,7 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) {
     r[31] = a->n[0] & 0xff;
 }
 
-SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) {
+SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) {
     /* For all legal values of m (0..31), the following properties hold: */
     VERIFY_CHECK(0x3FFFC2FUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
     VERIFY_CHECK(0x3FFFFBFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
@@ -365,7 +365,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r,
     r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9];
 }
 
-SECP256K1_INLINE static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a) {
+SECP256K1_INLINE static void secp256k1_fe_impl_mul_int(secp256k1_fe *r, int a) {
     r->n[0] *= a;
     r->n[1] *= a;
     r->n[2] *= a;
diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h
index ecb7050..0a4cc1a 100644
--- a/src/field_5x52_impl.h
+++ b/src/field_5x52_impl.h
@@ -314,7 +314,7 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) {
     r[31] = a->n[0] & 0xFF;
 }
 
-SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) {
+SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) {
     /* For all legal values of m (0..31), the following properties hold: */
     VERIFY_CHECK(0xFFFFEFFFFFC2FULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m);
     VERIFY_CHECK(0xFFFFFFFFFFFFFULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m);
@@ -329,7 +329,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r,
     r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4];
 }
 
-SECP256K1_INLINE static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a) {
+SECP256K1_INLINE static void secp256k1_fe_impl_mul_int(secp256k1_fe *r, int a) {
     r->n[0] *= a;
     r->n[1] *= a;
     r->n[2] *= a;
diff --git a/src/field_impl.h b/src/field_impl.h
index 2a0fba2..f9769a4 100644
--- a/src/field_impl.h
+++ b/src/field_impl.h
@@ -289,23 +289,23 @@ SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp25
     secp256k1_fe_impl_get_b32(r, a);
 }
 
-static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m);
-SECP256K1_INLINE static void secp256k1_fe_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) {
+static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m);
+SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) {
     secp256k1_fe_verify(a);
     VERIFY_CHECK(m >= 0 && m <= 31);
     VERIFY_CHECK(a->magnitude <= m);
-    secp256k1_fe_impl_negate_unchecked(r, a, m);
+    secp256k1_fe_impl_negate(r, a, m);
     r->magnitude = m + 1;
     r->normalized = 0;
     secp256k1_fe_verify(r);
 }
 
-static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a);
-SECP256K1_INLINE static void secp256k1_fe_mul_int_unchecked(secp256k1_fe *r, int a) {
+static void secp256k1_fe_impl_mul_int(secp256k1_fe *r, int a);
+SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) {
     secp256k1_fe_verify(r);
     VERIFY_CHECK(a >= 0 && a <= 32);
     VERIFY_CHECK(a*r->magnitude <= 32);
-    secp256k1_fe_impl_mul_int_unchecked(r, a);
+    secp256k1_fe_impl_mul_int(r, a);
     r->magnitude *= a;
     r->normalized = 0;
     secp256k1_fe_verify(r);
diff --git a/src/group.h b/src/group.h
index 1cc6137..77ad743 100644
--- a/src/group.h
+++ b/src/group.h
@@ -51,12 +51,6 @@ static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const se
  *  for Y. Return value indicates whether the result is valid. */
 static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd);
 
-/** Determine whether x is a valid X coordinate on the curve. */
-static int secp256k1_ge_x_on_curve_var(const secp256k1_fe *x);
-
-/** Determine whether fraction xn/xd is a valid X coordinate on the curve (xd != 0). */
-static int secp256k1_ge_x_frac_on_curve_var(const secp256k1_fe *xn, const secp256k1_fe *xd);
-
 /** Check whether a group element is the point at infinity. */
 static int secp256k1_ge_is_infinity(const secp256k1_ge *a);
 
@@ -106,8 +100,7 @@ static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a);
 /** Check two group elements (jacobian) for equality in variable time. */
 static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b);
 
-/** Compare the X coordinate of a group element (jacobian).
-  * The magnitude of the group element's X coordinate must not exceed 31. */
+/** Compare the X coordinate of a group element (jacobian). */
 static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a);
 
 /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */
diff --git a/src/group_impl.h b/src/group_impl.h
index ffdfeaa..44d9843 100644
--- a/src/group_impl.h
+++ b/src/group_impl.h
@@ -314,17 +314,13 @@ static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b)
 }
 
 static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) {
-    secp256k1_fe r;
-
-#ifdef VERIFY
+    secp256k1_fe r, r2;
     secp256k1_fe_verify(x);
-    VERIFY_CHECK(a->x.magnitude <= 31);
     secp256k1_gej_verify(a);
     VERIFY_CHECK(!a->infinity);
-#endif
-
     secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x);
-    return secp256k1_fe_equal_var(&r, &a->x);
+    r2 = a->x; secp256k1_fe_normalize_weak(&r2);
+    return secp256k1_fe_equal_var(&r, &r2);
 }
 
 static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) {
@@ -353,6 +349,7 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) {
     secp256k1_fe_sqr(&y2, &a->y);
     secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
     secp256k1_fe_add_int(&x3, SECP256K1_B);
+    secp256k1_fe_normalize_weak(&x3);
     return secp256k1_fe_equal_var(&y2, &x3);
 }
 
@@ -826,32 +823,4 @@ static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge) {
 #endif
 }
 
-static int secp256k1_ge_x_on_curve_var(const secp256k1_fe *x) {
-    secp256k1_fe c;
-    secp256k1_fe_sqr(&c, x);
-    secp256k1_fe_mul(&c, &c, x);
-    secp256k1_fe_add_int(&c, SECP256K1_B);
-    return secp256k1_fe_is_square_var(&c);
-}
-
-static int secp256k1_ge_x_frac_on_curve_var(const secp256k1_fe *xn, const secp256k1_fe *xd) {
-    /* We want to determine whether (xn/xd) is on the curve.
-     *
-     * (xn/xd)^3 + 7 is square <=> xd*xn^3 + 7*xd^4 is square (multiplying by xd^4, a square).
-     */
-     secp256k1_fe r, t;
-#ifdef VERIFY
-     VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(xd));
-#endif
-     secp256k1_fe_mul(&r, xd, xn); /* r = xd*xn */
-     secp256k1_fe_sqr(&t, xn); /* t = xn^2 */
-     secp256k1_fe_mul(&r, &r, &t); /* r = xd*xn^3 */
-     secp256k1_fe_sqr(&t, xd); /* t = xd^2 */
-     secp256k1_fe_sqr(&t, &t); /* t = xd^4 */
-     VERIFY_CHECK(SECP256K1_B <= 31);
-     secp256k1_fe_mul_int(&t, SECP256K1_B); /* t = 7*xd^4 */
-     secp256k1_fe_add(&r, &t); /* r = xd*xn^3 + 7*xd^4 */
-     return secp256k1_fe_is_square_var(&r);
-}
-
 #endif /* SECP256K1_GROUP_IMPL_H */
diff --git a/src/int128_struct_impl.h b/src/int128_struct_impl.h
index 962a71d..990982d 100644
--- a/src/int128_struct_impl.h
+++ b/src/int128_struct_impl.h
@@ -80,12 +80,7 @@ static SECP256K1_INLINE void secp256k1_u128_rshift(secp256k1_uint128 *r, unsigne
      r->lo = r->hi >> (n-64);
      r->hi = 0;
    } else if (n > 0) {
-#if defined(_MSC_VER) && defined(_M_X64)
-     VERIFY_CHECK(n < 64);
-     r->lo = __shiftright128(r->lo, r->hi, n);
-#else
      r->lo = ((1U * r->hi) << (64-n)) | r->lo >> n;
-#endif
      r->hi >>= n;
    }
 }
diff --git a/src/modules/ellswift/Makefile.am.include b/src/modules/ellswift/Makefile.am.include
deleted file mode 100644
index 8251231..0000000
--- a/src/modules/ellswift/Makefile.am.include
+++ /dev/null
@@ -1,5 +0,0 @@
-include_HEADERS += include/secp256k1_ellswift.h
-noinst_HEADERS += src/modules/ellswift/bench_impl.h
-noinst_HEADERS += src/modules/ellswift/main_impl.h
-noinst_HEADERS += src/modules/ellswift/tests_impl.h
-noinst_HEADERS += src/modules/ellswift/tests_exhaustive_impl.h
diff --git a/src/modules/ellswift/bench_impl.h b/src/modules/ellswift/bench_impl.h
deleted file mode 100644
index b16a3a3..0000000
--- a/src/modules/ellswift/bench_impl.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/***********************************************************************
- * Distributed under the MIT software license, see the accompanying    *
- * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
- ***********************************************************************/
-
-#ifndef SECP256K1_MODULE_ELLSWIFT_BENCH_H
-#define SECP256K1_MODULE_ELLSWIFT_BENCH_H
-
-#include "../../../include/secp256k1_ellswift.h"
-
-typedef struct {
-    secp256k1_context *ctx;
-    secp256k1_pubkey point[256];
-    unsigned char rnd64[64];
-} bench_ellswift_data;
-
-static void bench_ellswift_setup(void *arg) {
-    int i;
-    bench_ellswift_data *data = (bench_ellswift_data*)arg;
-    static const unsigned char init[64] = {
-        0x78, 0x1f, 0xb7, 0xd4, 0x67, 0x7f, 0x08, 0x68,
-        0xdb, 0xe3, 0x1d, 0x7f, 0x1b, 0xb0, 0xf6, 0x9e,
-        0x0a, 0x64, 0xca, 0x32, 0x9e, 0xc6, 0x20, 0x79,
-        0x03, 0xf3, 0xd0, 0x46, 0x7a, 0x0f, 0xd2, 0x21,
-        0xb0, 0x2c, 0x46, 0xd8, 0xba, 0xca, 0x26, 0x4f,
-        0x8f, 0x8c, 0xd4, 0xdd, 0x2d, 0x04, 0xbe, 0x30,
-        0x48, 0x51, 0x1e, 0xd4, 0x16, 0xfd, 0x42, 0x85,
-        0x62, 0xc9, 0x02, 0xf9, 0x89, 0x84, 0xff, 0xdc
-    };
-    memcpy(data->rnd64, init, 64);
-    for (i = 0; i < 256; ++i) {
-        int j;
-        CHECK(secp256k1_ellswift_decode(data->ctx, &data->point[i], data->rnd64));
-        for (j = 0; j < 64; ++j) {
-            data->rnd64[j] += 1;
-        }
-    }
-    CHECK(secp256k1_ellswift_encode(data->ctx, data->rnd64, &data->point[255], init + 16));
-}
-
-static void bench_ellswift_encode(void *arg, int iters) {
-    int i;
-    bench_ellswift_data *data = (bench_ellswift_data*)arg;
-
-    for (i = 0; i < iters; i++) {
-        CHECK(secp256k1_ellswift_encode(data->ctx, data->rnd64, &data->point[i & 255], data->rnd64 + 16));
-    }
-}
-
-static void bench_ellswift_create(void *arg, int iters) {
-    int i;
-    bench_ellswift_data *data = (bench_ellswift_data*)arg;
-
-    for (i = 0; i < iters; i++) {
-        unsigned char buf[64];
-        CHECK(secp256k1_ellswift_create(data->ctx, buf, data->rnd64, data->rnd64 + 32));
-        memcpy(data->rnd64, buf, 64);
-    }
-}
-
-static void bench_ellswift_decode(void *arg, int iters) {
-    int i;
-    secp256k1_pubkey out;
-    size_t len;
-    bench_ellswift_data *data = (bench_ellswift_data*)arg;
-
-    for (i = 0; i < iters; i++) {
-        CHECK(secp256k1_ellswift_decode(data->ctx, &out, data->rnd64) == 1);
-        len = 33;
-        CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->rnd64 + (i % 32), &len, &out, SECP256K1_EC_COMPRESSED));
-    }
-}
-
-static void bench_ellswift_xdh(void *arg, int iters) {
-    int i;
-    bench_ellswift_data *data = (bench_ellswift_data*)arg;
-
-    for (i = 0; i < iters; i++) {
-        int party = i & 1;
-        CHECK(secp256k1_ellswift_xdh(data->ctx,
-                                     data->rnd64 + (i % 33),
-                                     data->rnd64,
-                                     data->rnd64,
-                                     data->rnd64 + ((i + 16) % 33),
-                                     party,
-                                     secp256k1_ellswift_xdh_hash_function_bip324,
-                                     NULL) == 1);
-    }
-}
-
-void run_ellswift_bench(int iters, int argc, char **argv) {
-    bench_ellswift_data data;
-    int d = argc == 1;
-
-    /* create a context with signing capabilities */
-    data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
-
-    if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "encode") || have_flag(argc, argv, "ellswift_encode")) run_benchmark("ellswift_encode", bench_ellswift_encode, bench_ellswift_setup, NULL, &data, 10, iters);
-    if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_decode")) run_benchmark("ellswift_decode", bench_ellswift_decode, bench_ellswift_setup, NULL, &data, 10, iters);
-    if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ellswift_keygen")) run_benchmark("ellswift_keygen", bench_ellswift_create, bench_ellswift_setup, NULL, &data, 10, iters);
-    if (d || have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "ecdh") || have_flag(argc, argv, "ellswift_ecdh")) run_benchmark("ellswift_ecdh", bench_ellswift_xdh, bench_ellswift_setup, NULL, &data, 10, iters);
-
-    secp256k1_context_destroy(data.ctx);
-}
-
-#endif
diff --git a/src/modules/ellswift/main_impl.h b/src/modules/ellswift/main_impl.h
deleted file mode 100644
index 00bb8a3..0000000
--- a/src/modules/ellswift/main_impl.h
+++ /dev/null
@@ -1,589 +0,0 @@
-/***********************************************************************
- * Distributed under the MIT software license, see the accompanying    *
- * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
- ***********************************************************************/
-
-#ifndef SECP256K1_MODULE_ELLSWIFT_MAIN_H
-#define SECP256K1_MODULE_ELLSWIFT_MAIN_H
-
-#include "../../../include/secp256k1.h"
-#include "../../../include/secp256k1_ellswift.h"
-#include "../../eckey.h"
-#include "../../hash.h"
-
-/** c1 = (sqrt(-3)-1)/2 */
-static const secp256k1_fe secp256k1_ellswift_c1 = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa40);
-/** c2 = (-sqrt(-3)-1)/2 = -(c1+1) */
-static const secp256k1_fe secp256k1_ellswift_c2 = SECP256K1_FE_CONST(0x7ae96a2b, 0x657c0710, 0x6e64479e, 0xac3434e9, 0x9cf04975, 0x12f58995, 0xc1396c28, 0x719501ee);
-/** c3 = (-sqrt(-3)+1)/2 = -c1 = c2+1 */
-static const secp256k1_fe secp256k1_ellswift_c3 = SECP256K1_FE_CONST(0x7ae96a2b, 0x657c0710, 0x6e64479e, 0xac3434e9, 0x9cf04975, 0x12f58995, 0xc1396c28, 0x719501ef);
-/** c4 = (sqrt(-3)+1)/2 = -c2 = c1+1 */
-static const secp256k1_fe secp256k1_ellswift_c4 = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa41);
-
-/** Decode ElligatorSwift encoding (u, t) to a fraction xn/xd representing a curve X coordinate. */
-static void secp256k1_ellswift_xswiftec_frac_var(secp256k1_fe *xn, secp256k1_fe *xd, const secp256k1_fe *u, const secp256k1_fe *t) {
-    /* The implemented algorithm is the following (all operations in GF(p)):
-     *
-     * - Let c0 = sqrt(-3) = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852.
-     * - If u = 0, set u = 1.
-     * - If t = 0, set t = 1.
-     * - If u^3+7+t^2 = 0, set t = 2*t.
-     * - Let X = (u^3+7-t^2)/(2*t).
-     * - Let Y = (X+t)/(c0*u).
-     * - If x3 = u+4*Y^2 is a valid x coordinate, return it.
-     * - If x2 = (-X/Y-u)/2 is a valid x coordinate, return it.
-     * - Return x1 = (X/Y-u)/2 (which is now guaranteed to be a valid x coordinate).
-     *
-     * Introducing s=t^2, g=u^3+7, and simplifying x1=-(x2+u) we get:
-     *
-     * - Let c0 = ...
-     * - If u = 0, set u = 1.
-     * - If t = 0, set t = 1.
-     * - Let s = t^2
-     * - Let g = u^3+7
-     * - If g+s = 0, set t = 2*t, s = 4*s
-     * - Let X = (g-s)/(2*t).
-     * - Let Y = (X+t)/(c0*u) = (g+s)/(2*c0*t*u).
-     * - If x3 = u+4*Y^2 is a valid x coordinate, return it.
-     * - If x2 = (-X/Y-u)/2 is a valid x coordinate, return it.
-     * - Return x1 = -(x2+u).
-     *
-     * Now substitute Y^2 = -(g+s)^2/(12*s*u^2) and X/Y = c0*u*(g-s)/(g+s). This
-     * means X and Y do not need to be evaluated explicitly anymore.
-     *
-     * - ...
-     * - If g+s = 0, set s = 4*s.
-     * - If x3 = u-(g+s)^2/(3*s*u^2) is a valid x coordinate, return it.
-     * - If x2 = (-c0*u*(g-s)/(g+s)-u)/2 is a valid x coordinate, return it.
-     * - Return x1 = -(x2+u).
-     *
-     * Simplifying x2 using 2 additional constants:
-     *
-     * - Let c1 = (c0-1)/2 = 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40.
-     * - Let c2 = (-c0-1)/2 = 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee.
-     * - ...
-     * - If x2 = u*(c1*s+c2*g)/(g+s) is a valid x coordinate, return it.
-     * - ...
-     *
-     * Writing x3 as a fraction:
-     *
-     * - ...
-     * - If x3 = (3*s*u^3-(g+s)^2)/(3*s*u^2) ...
-     * - ...
-
-     * Overall, we get:
-     *
-     * - Let c1 = 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40.
-     * - Let c2 = 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee.
-     * - If u = 0, set u = 1.
-     * - If t = 0, set s = 1, else set s = t^2.
-     * - Let g = u^3+7.
-     * - If g+s = 0, set s = 4*s.
-     * - If x3 = (3*s*u^3-(g+s)^2)/(3*s*u^2) is a valid x coordinate, return it.
-     * - If x2 = u*(c1*s+c2*g)/(g+s) is a valid x coordinate, return it.
-     * - Return x1 = -(x2+u).
-     */
-    secp256k1_fe u1, s, g, p, d, n, l;
-    u1 = *u;
-    if (EXPECT(secp256k1_fe_normalizes_to_zero_var(&u1), 0)) u1 = secp256k1_fe_one;
-    secp256k1_fe_sqr(&s, t);
-    if (EXPECT(secp256k1_fe_normalizes_to_zero_var(t), 0)) s = secp256k1_fe_one;
-    secp256k1_fe_sqr(&l, &u1);                                   /* l = u^2 */
-    secp256k1_fe_mul(&g, &l, &u1);                               /* g = u^3 */
-    secp256k1_fe_add_int(&g, SECP256K1_B);                       /* g = u^3 + 7 */
-    p = g;                                                       /* p = g */
-    secp256k1_fe_add(&p, &s);                                    /* p = g+s */
-    if (EXPECT(secp256k1_fe_normalizes_to_zero_var(&p), 0)) {
-        secp256k1_fe_mul_int(&s, 4);
-        /* Recompute p = g+s */
-        p = g;                                                   /* p = g */
-        secp256k1_fe_add(&p, &s);                                /* p = g+s */
-    }
-    secp256k1_fe_mul(&d, &s, &l);                                /* d = s*u^2 */
-    secp256k1_fe_mul_int(&d, 3);                                 /* d = 3*s*u^2 */
-    secp256k1_fe_sqr(&l, &p);                                    /* l = (g+s)^2 */
-    secp256k1_fe_negate(&l, &l, 1);                              /* l = -(g+s)^2 */
-    secp256k1_fe_mul(&n, &d, &u1);                               /* n = 3*s*u^3 */
-    secp256k1_fe_add(&n, &l);                                    /* n = 3*s*u^3-(g+s)^2 */
-    if (secp256k1_ge_x_frac_on_curve_var(&n, &d)) {
-        /* Return x3 = n/d = (3*s*u^3-(g+s)^2)/(3*s*u^2) */
-        *xn = n;
-        *xd = d;
-        return;
-    }
-    *xd = p;
-    secp256k1_fe_mul(&l, &secp256k1_ellswift_c1, &s);            /* l = c1*s */
-    secp256k1_fe_mul(&n, &secp256k1_ellswift_c2, &g);            /* n = c2*g */
-    secp256k1_fe_add(&n, &l);                                    /* n = c1*s+c2*g */
-    secp256k1_fe_mul(&n, &n, &u1);                               /* n = u*(c1*s+c2*g) */
-    /* Possible optimization: in the invocation below, p^2 = (g+s)^2 is computed,
-     * which we already have computed above. This could be deduplicated. */
-    if (secp256k1_ge_x_frac_on_curve_var(&n, &p)) {
-        /* Return x2 = n/p = u*(c1*s+c2*g)/(g+s) */
-        *xn = n;
-        return;
-    }
-    secp256k1_fe_mul(&l, &p, &u1);                               /* l = u*(g+s) */
-    secp256k1_fe_add(&n, &l);                                    /* n = u*(c1*s+c2*g)+u*(g+s) */
-    secp256k1_fe_negate(xn, &n, 2);                              /* n = -u*(c1*s+c2*g)-u*(g+s) */
-#ifdef VERIFY
-    VERIFY_CHECK(secp256k1_ge_x_frac_on_curve_var(xn, &p));
-#endif
-    /* Return x3 = n/p = -(u*(c1*s+c2*g)/(g+s)+u) */
-}
-
-/** Decode ElligatorSwift encoding (u, t) to X coordinate. */
-static void secp256k1_ellswift_xswiftec_var(secp256k1_fe *x, const secp256k1_fe *u, const secp256k1_fe *t) {
-    secp256k1_fe xn, xd;
-    secp256k1_ellswift_xswiftec_frac_var(&xn, &xd, u, t);
-    secp256k1_fe_inv_var(&xd, &xd);
-    secp256k1_fe_mul(x, &xn, &xd);
-}
-
-/** Decode ElligatorSwift encoding (u, t) to point P. */
-static void secp256k1_ellswift_swiftec_var(secp256k1_ge *p, const secp256k1_fe *u, const secp256k1_fe *t) {
-    secp256k1_fe x;
-    secp256k1_ellswift_xswiftec_var(&x, u, t);
-    secp256k1_ge_set_xo_var(p, &x, secp256k1_fe_is_odd(t));
-}
-
-/* Try to complete an ElligatorSwift encoding (u, t) for X coordinate x, given u and x.
- *
- * There may be up to 8 distinct t values such that (u, t) decodes back to x, but also
- * fewer, or none at all. Each such partial inverse can be accessed individually using a
- * distinct input argument c (in range 0-7), and some or all of these may return failure.
- * The following guarantees exist:
- * - Given (x, u), no two distinct c values give the same successful result t.
- * - Every successful result maps back to x through secp256k1_ellswift_xswiftec_var.
- * - Given (x, u), all t values that map back to x can be reached by combining the
- *   successful results from this function over all c values, with the exception of:
- *   - this function cannot be called with u=0
- *   - no result with t=0 will be returned
- *   - no result for which u^3 + t^2 + 7 = 0 will be returned.
- *
- * The rather unusual encoding of bits in c (a large "if" based on the middle bit, and then
- * using the low and high bits to pick signs of square roots) is to match the paper's
- * encoding more closely: c=0 through c=3 match branches 1..4 in the paper, while c=4 through
- * c=7 are copies of those with an additional negation of sqrt(w).
- */
-static int secp256k1_ellswift_xswiftec_inv_var(secp256k1_fe *t, const secp256k1_fe *x_in, const secp256k1_fe *u_in, int c) {
-    /* The implemented algorithm is this (all arithmetic, except involving c, is mod p):
-     *
-     * - If (c & 2) = 0:
-     *   - If (-x-u) is a valid X coordinate, fail.
-     *   - Let s=-(u^3+7)/(u^2+u*x+x^2).
-     *   - If s is not square, fail.
-     *   - Let v=x.
-     * - If (c & 2) = 2:
-     *   - Let s=x-u.
-     *   - If s is not square, fail.
-     *   - Let r=sqrt(-s*(4*(u^3+7)+3*u^2*s)); fail if it doesn't exist.
-     *   - If (c & 1) = 1 and r = 0, fail.
-     *   - If s=0, fail.
-     *   - Let v=(r/s-u)/2.
-     * - Let w=sqrt(s).
-     * - If (c & 5) = 0: return -w*(c3*u + v).
-     * - If (c & 5) = 1: return  w*(c4*u + v).
-     * - If (c & 5) = 4: return  w*(c3*u + v).
-     * - If (c & 5) = 5: return -w*(c4*u + v).
-     */
-    secp256k1_fe x = *x_in, u = *u_in, g, v, s, m, r, q;
-    int ret;
-
-    secp256k1_fe_normalize_weak(&x);
-    secp256k1_fe_normalize_weak(&u);
-
-#ifdef VERIFY
-    VERIFY_CHECK(c >= 0 && c < 8);
-    VERIFY_CHECK(secp256k1_ge_x_on_curve_var(&x));
-#endif
-
-    if (!(c & 2)) {
-        /* c is in {0, 1, 4, 5}. In this case we look for an inverse under the x1 (if c=0 or
-         * c=4) formula, or x2 (if c=1 or c=5) formula. */
-
-        /* If -u-x is a valid X coordinate, fail. This would yield an encoding that roundtrips
-         * back under the x3 formula instead (which has priority over x1 and x2, so the decoding
-         * would not match x). */
-        m = x;                                          /* m = x */
-        secp256k1_fe_add(&m, &u);                       /* m = u+x */
-        secp256k1_fe_negate(&m, &m, 2);                 /* m = -u-x */
-        /* Test if (-u-x) is a valid X coordinate. If so, fail. */
-        if (secp256k1_ge_x_on_curve_var(&m)) return 0;
-
-        /* Let s = -(u^3 + 7)/(u^2 + u*x + x^2) [first part] */
-        secp256k1_fe_sqr(&s, &m);                       /* s = (u+x)^2 */
-        secp256k1_fe_negate(&s, &s, 1);                 /* s = -(u+x)^2 */
-        secp256k1_fe_mul(&m, &u, &x);                   /* m = u*x */
-        secp256k1_fe_add(&s, &m);                       /* s = -(u^2 + u*x + x^2) */
-
-        /* Note that at this point, s = 0 is impossible. If it were the case:
-         *             s = -(u^2 + u*x + x^2) = 0
-         * =>                 u^2 + u*x + x^2 = 0
-         * =>   (u + 2*x) * (u^2 + u*x + x^2) = 0
-         * => 2*x^3 + 3*x^2*u + 3*x*u^2 + u^3 = 0
-         * =>                 (x + u)^3 + x^3 = 0
-         * =>                             x^3 = -(x + u)^3
-         * =>                         x^3 + B = (-u - x)^3 + B
-         *
-         * However, we know x^3 + B is square (because x is on the curve) and
-         * that (-u-x)^3 + B is not square (the secp256k1_ge_x_on_curve_var(&m)
-         * test above would have failed). This is a contradiction, and thus the
-         * assumption s=0 is false. */
-#ifdef VERIFY
-        VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(&s));
-#endif
-
-        /* If s is not square, fail. We have not fully computed s yet, but s is square iff
-         * -(u^3+7)*(u^2+u*x+x^2) is square (because a/b is square iff a*b is square and b is
-         * nonzero). */
-        secp256k1_fe_sqr(&g, &u);                       /* g = u^2 */
-        secp256k1_fe_mul(&g, &g, &u);                   /* g = u^3 */
-        secp256k1_fe_add_int(&g, SECP256K1_B);          /* g = u^3+7 */
-        secp256k1_fe_mul(&m, &s, &g);                   /* m = -(u^3 + 7)*(u^2 + u*x + x^2) */
-        if (!secp256k1_fe_is_square_var(&m)) return 0;
-
-        /* Let s = -(u^3 + 7)/(u^2 + u*x + x^2) [second part] */
-        secp256k1_fe_inv_var(&s, &s);                   /* s = -1/(u^2 + u*x + x^2) [no div by 0] */
-        secp256k1_fe_mul(&s, &s, &g);                   /* s = -(u^3 + 7)/(u^2 + u*x + x^2) */
-
-        /* Let v = x. */
-        v = x;
-    } else {
-        /* c is in {2, 3, 6, 7}. In this case we look for an inverse under the x3 formula. */
-
-        /* Let s = x-u. */
-        secp256k1_fe_negate(&m, &u, 1);                 /* m = -u */
-        s = m;                                          /* s = -u */
-        secp256k1_fe_add(&s, &x);                       /* s = x-u */
-
-        /* If s is not square, fail. */
-        if (!secp256k1_fe_is_square_var(&s)) return 0;
-
-        /* Let r = sqrt(-s*(4*(u^3+7)+3*u^2*s)); fail if it doesn't exist. */
-        secp256k1_fe_sqr(&g, &u);                       /* g = u^2 */
-        secp256k1_fe_mul(&q, &s, &g);                   /* q = s*u^2 */
-        secp256k1_fe_mul_int(&q, 3);                    /* q = 3*s*u^2 */
-        secp256k1_fe_mul(&g, &g, &u);                   /* g = u^3 */
-        secp256k1_fe_mul_int(&g, 4);                    /* g = 4*u^3 */
-        secp256k1_fe_add_int(&g, 4 * SECP256K1_B);      /* g = 4*(u^3+7) */
-        secp256k1_fe_add(&q, &g);                       /* q = 4*(u^3+7)+3*s*u^2 */
-        secp256k1_fe_mul(&q, &q, &s);                   /* q = s*(4*(u^3+7)+3*u^2*s) */
-        secp256k1_fe_negate(&q, &q, 1);                 /* q = -s*(4*(u^3+7)+3*u^2*s) */
-        if (!secp256k1_fe_is_square_var(&q)) return 0;
-        ret = secp256k1_fe_sqrt(&r, &q);                /* r = sqrt(-s*(4*(u^3+7)+3*u^2*s)) */
-        VERIFY_CHECK(ret);
-
-        /* If (c & 1) = 1 and r = 0, fail. */
-        if (EXPECT((c & 1) && secp256k1_fe_normalizes_to_zero_var(&r), 0)) return 0;
-
-        /* If s = 0, fail. */
-        if (EXPECT(secp256k1_fe_normalizes_to_zero_var(&s), 0)) return 0;
-
-        /* Let v = (r/s-u)/2. */
-        secp256k1_fe_inv_var(&v, &s);                   /* v = 1/s [no div by 0] */
-        secp256k1_fe_mul(&v, &v, &r);                   /* v = r/s */
-        secp256k1_fe_add(&v, &m);                       /* v = r/s-u */
-        secp256k1_fe_half(&v);                          /* v = (r/s-u)/2 */
-    }
-
-    /* Let w = sqrt(s). */
-    ret = secp256k1_fe_sqrt(&m, &s);                    /* m = sqrt(s) = w */
-    VERIFY_CHECK(ret);
-
-    /* Return logic. */
-    if ((c & 5) == 0 || (c & 5) == 5) {
-        secp256k1_fe_negate(&m, &m, 1);                 /* m = -w */
-    }
-    /* Now m = {-w if c&5=0 or c&5=5; w otherwise}. */
-    secp256k1_fe_mul(&u, &u, c&1 ? &secp256k1_ellswift_c4 : &secp256k1_ellswift_c3);
-    /* u = {c4 if c&1=1; c3 otherwise}*u */
-    secp256k1_fe_add(&u, &v);                           /* u = {c4 if c&1=1; c3 otherwise}*u + v */
-    secp256k1_fe_mul(t, &m, &u);
-    return 1;
-}
-
-/** Use SHA256 as a PRNG, returning SHA256(hasher || cnt).
- *
- * hasher is a SHA256 object to which an incrementing 4-byte counter is written to generate randomness.
- * Writing 13 bytes (4 bytes for counter, plus 9 bytes for the SHA256 padding) cannot cross a
- * 64-byte block size boundary (to make sure it only triggers a single SHA256 compression). */
-static void secp256k1_ellswift_prng(unsigned char* out32, const secp256k1_sha256 *hasher, uint32_t cnt) {
-    secp256k1_sha256 hash = *hasher;
-    unsigned char buf4[4];
-#ifdef VERIFY
-    size_t blocks = hash.bytes >> 6;
-#endif
-    buf4[0] = cnt;
-    buf4[1] = cnt >> 8;
-    buf4[2] = cnt >> 16;
-    buf4[3] = cnt >> 24;
-    secp256k1_sha256_write(&hash, buf4, 4);
-    secp256k1_sha256_finalize(&hash, out32);
-#ifdef VERIFY
-    /* Writing and finalizing together should trigger exactly one SHA256 compression. */
-    VERIFY_CHECK(((hash.bytes) >> 6) == (blocks + 1));
-#endif
-}
-
-/** Find an ElligatorSwift encoding (u, t) for X coordinate x, and random Y coordinate.
- *
- * u32 is the 32-byte big endian encoding of u; t is the output field element t that still
- * needs encoding.
- *
- * hasher is a hasher in the secp256k1_ellswift_prng sense, with the same restrictions. */
-static void secp256k1_ellswift_xelligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_fe *x, const secp256k1_sha256 *hasher) {
-    /* Pool of 3-bit branch values. */
-    unsigned char branch_hash[32];
-    /* Number of 3-bit values in branch_hash left. */
-    int branches_left = 0;
-    /* Field elements u and branch values are extracted from RNG based on hasher for consecutive
-     * values of cnt. cnt==0 is first used to populate a pool of 64 4-bit branch values. The 64
-     * cnt values that follow are used to generate field elements u. cnt==65 (and multiples
-     * thereof) are used to repopulate the pool and start over, if that were ever necessary.
-     * On average, 4 iterations are needed. */
-    uint32_t cnt = 0;
-    while (1) {
-        int branch;
-        secp256k1_fe u;
-        /* If the pool of branch values is empty, populate it. */
-        if (branches_left == 0) {
-            secp256k1_ellswift_prng(branch_hash, hasher, cnt++);
-            branches_left = 64;
-        }
-        /* Take a 3-bit branch value from the branch pool (top bit is discarded). */
-        --branches_left;
-        branch = (branch_hash[branches_left >> 1] >> ((branches_left & 1) << 2)) & 7;
-        /* Compute a new u value by hashing. */
-        secp256k1_ellswift_prng(u32, hasher, cnt++);
-        /* overflow is not a problem (we prefer uniform u32 over uniform u). */
-        secp256k1_fe_set_b32_mod(&u, u32);
-        /* Since u is the output of a hash, it should practically never be 0. We could apply the
-         * u=0 to u=1 correction here too to deal with that case still, but it's such a low
-         * probability event that we do not bother. */
-#ifdef VERIFY
-        VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(&u));
-#endif
-        /* Find a remainder t, and return it if found. */
-        if (EXPECT(secp256k1_ellswift_xswiftec_inv_var(t, x, &u, branch), 0)) break;
-    }
-}
-
-/** Find an ElligatorSwift encoding (u, t) for point P.
- *
- * This is similar secp256k1_ellswift_xelligatorswift_var, except it takes a full group element p
- * as input, and returns an encoding that matches the provided Y coordinate rather than a random
- * one.
- */
-static void secp256k1_ellswift_elligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_ge *p, const secp256k1_sha256 *hasher) {
-    secp256k1_ellswift_xelligatorswift_var(u32, t, &p->x, hasher);
-    secp256k1_fe_normalize_var(t);
-    if (secp256k1_fe_is_odd(t) != secp256k1_fe_is_odd(&p->y)) {
-        secp256k1_fe_negate(t, t, 1);
-        secp256k1_fe_normalize_var(t);
-    }
-}
-
-/** Set hash state to the BIP340 tagged hash midstate for "secp256k1_ellswift_encode". */
-static void secp256k1_ellswift_sha256_init_encode(secp256k1_sha256* hash) {
-    secp256k1_sha256_initialize(hash);
-    hash->s[0] = 0xd1a6524bul;
-    hash->s[1] = 0x028594b3ul;
-    hash->s[2] = 0x96e42f4eul;
-    hash->s[3] = 0x1037a177ul;
-    hash->s[4] = 0x1b8fcb8bul;
-    hash->s[5] = 0x56023885ul;
-    hash->s[6] = 0x2560ede1ul;
-    hash->s[7] = 0xd626b715ul;
-
-    hash->bytes = 64;
-}
-
-int secp256k1_ellswift_encode(const secp256k1_context *ctx, unsigned char *ell64, const secp256k1_pubkey *pubkey, const unsigned char *rnd32) {
-    secp256k1_ge p;
-    VERIFY_CHECK(ctx != NULL);
-    ARG_CHECK(ell64 != NULL);
-    ARG_CHECK(pubkey != NULL);
-    ARG_CHECK(rnd32 != NULL);
-
-    if (secp256k1_pubkey_load(ctx, &p, pubkey)) {
-        secp256k1_fe t;
-        unsigned char p64[64] = {0};
-        size_t ser_size;
-        int ser_ret;
-        secp256k1_sha256 hash;
-
-        /* Set up hasher state; the used RNG is H(pubkey || "\x00"*31 || rnd32 || cnt++), using
-         * BIP340 tagged hash with tag "secp256k1_ellswift_encode". */
-        secp256k1_ellswift_sha256_init_encode(&hash);
-        ser_ret = secp256k1_eckey_pubkey_serialize(&p, p64, &ser_size, 1);
-        VERIFY_CHECK(ser_ret && ser_size == 33);
-        secp256k1_sha256_write(&hash, p64, sizeof(p64));
-        secp256k1_sha256_write(&hash, rnd32, 32);
-
-        /* Compute ElligatorSwift encoding and construct output. */
-        secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */
-        secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */
-        return 1;
-    }
-    /* Only reached in case the provided pubkey is invalid. */
-    memset(ell64, 0, 64);
-    return 0;
-}
-
-/** Set hash state to the BIP340 tagged hash midstate for "secp256k1_ellswift_create". */
-static void secp256k1_ellswift_sha256_init_create(secp256k1_sha256* hash) {
-    secp256k1_sha256_initialize(hash);
-    hash->s[0] = 0xd29e1bf5ul;
-    hash->s[1] = 0xf7025f42ul;
-    hash->s[2] = 0x9b024773ul;
-    hash->s[3] = 0x094cb7d5ul;
-    hash->s[4] = 0xe59ed789ul;
-    hash->s[5] = 0x03bc9786ul;
-    hash->s[6] = 0x68335b35ul;
-    hash->s[7] = 0x4e363b53ul;
-
-    hash->bytes = 64;
-}
-
-int secp256k1_ellswift_create(const secp256k1_context *ctx, unsigned char *ell64, const unsigned char *seckey32, const unsigned char *auxrnd32) {
-    secp256k1_ge p;
-    secp256k1_fe t;
-    secp256k1_sha256 hash;
-    secp256k1_scalar seckey_scalar;
-    int ret;
-    static const unsigned char zero32[32] = {0};
-
-    /* Sanity check inputs. */
-    VERIFY_CHECK(ctx != NULL);
-    ARG_CHECK(ell64 != NULL);
-    memset(ell64, 0, 64);
-    ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
-    ARG_CHECK(seckey32 != NULL);
-
-    /* Compute (affine) public key */
-    ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &seckey_scalar, &p, seckey32);
-    secp256k1_declassify(ctx, &p, sizeof(p)); /* not constant time in produced pubkey */
-    secp256k1_fe_normalize_var(&p.x);
-    secp256k1_fe_normalize_var(&p.y);
-
-    /* Set up hasher state. The used RNG is H(privkey || "\x00"*32 [|| auxrnd32] || cnt++),
-     * using BIP340 tagged hash with tag "secp256k1_ellswift_create". */
-    secp256k1_ellswift_sha256_init_create(&hash);
-    secp256k1_sha256_write(&hash, seckey32, 32);
-    secp256k1_sha256_write(&hash, zero32, sizeof(zero32));
-    secp256k1_declassify(ctx, &hash, sizeof(hash)); /* private key is hashed now */
-    if (auxrnd32) secp256k1_sha256_write(&hash, auxrnd32, 32);
-
-    /* Compute ElligatorSwift encoding and construct output. */
-    secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */
-    secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */
-
-    secp256k1_memczero(ell64, 64, !ret);
-    secp256k1_scalar_clear(&seckey_scalar);
-
-    return ret;
-}
-
-int secp256k1_ellswift_decode(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *ell64) {
-    secp256k1_fe u, t;
-    secp256k1_ge p;
-    VERIFY_CHECK(ctx != NULL);
-    ARG_CHECK(pubkey != NULL);
-    ARG_CHECK(ell64 != NULL);
-
-    secp256k1_fe_set_b32_mod(&u, ell64);
-    secp256k1_fe_set_b32_mod(&t, ell64 + 32);
-    secp256k1_fe_normalize_var(&t);
-    secp256k1_ellswift_swiftec_var(&p, &u, &t);
-    secp256k1_pubkey_save(pubkey, &p);
-    return 1;
-}
-
-static int ellswift_xdh_hash_function_prefix(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) {
-    secp256k1_sha256 sha;
-
-    secp256k1_sha256_initialize(&sha);
-    secp256k1_sha256_write(&sha, data, 64);
-    secp256k1_sha256_write(&sha, ell_a64, 64);
-    secp256k1_sha256_write(&sha, ell_b64, 64);
-    secp256k1_sha256_write(&sha, x32, 32);
-    secp256k1_sha256_finalize(&sha, output);
-
-    return 1;
-}
-
-/** Set hash state to the BIP340 tagged hash midstate for "bip324_ellswift_xonly_ecdh". */
-static void secp256k1_ellswift_sha256_init_bip324(secp256k1_sha256* hash) {
-    secp256k1_sha256_initialize(hash);
-    hash->s[0] = 0x8c12d730ul;
-    hash->s[1] = 0x827bd392ul;
-    hash->s[2] = 0x9e4fb2eeul;
-    hash->s[3] = 0x207b373eul;
-    hash->s[4] = 0x2292bd7aul;
-    hash->s[5] = 0xaa5441bcul;
-    hash->s[6] = 0x15c3779ful;
-    hash->s[7] = 0xcfb52549ul;
-
-    hash->bytes = 64;
-}
-
-static int ellswift_xdh_hash_function_bip324(unsigned char* output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) {
-    secp256k1_sha256 sha;
-
-    (void)data;
-
-    secp256k1_ellswift_sha256_init_bip324(&sha);
-    secp256k1_sha256_write(&sha, ell_a64, 64);
-    secp256k1_sha256_write(&sha, ell_b64, 64);
-    secp256k1_sha256_write(&sha, x32, 32);
-    secp256k1_sha256_finalize(&sha, output);
-
-    return 1;
-}
-
-const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix = ellswift_xdh_hash_function_prefix;
-const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324 = ellswift_xdh_hash_function_bip324;
-
-int secp256k1_ellswift_xdh(const secp256k1_context *ctx, unsigned char *output, const unsigned char *ell_a64, const unsigned char *ell_b64, const unsigned char *seckey32, int party, secp256k1_ellswift_xdh_hash_function hashfp, void *data) {
-    int ret = 0;
-    int overflow;
-    secp256k1_scalar s;
-    secp256k1_fe xn, xd, px, u, t;
-    unsigned char sx[32];
-    const unsigned char* theirs64;
-
-    VERIFY_CHECK(ctx != NULL);
-    ARG_CHECK(output != NULL);
-    ARG_CHECK(ell_a64 != NULL);
-    ARG_CHECK(ell_b64 != NULL);
-    ARG_CHECK(seckey32 != NULL);
-    ARG_CHECK(hashfp != NULL);
-
-    /* Load remote public key (as fraction). */
-    theirs64 = party ? ell_a64 : ell_b64;
-    secp256k1_fe_set_b32_mod(&u, theirs64);
-    secp256k1_fe_set_b32_mod(&t, theirs64 + 32);
-    secp256k1_ellswift_xswiftec_frac_var(&xn, &xd, &u, &t);
-
-    /* Load private key (using one if invalid). */
-    secp256k1_scalar_set_b32(&s, seckey32, &overflow);
-    overflow = secp256k1_scalar_is_zero(&s);
-    secp256k1_scalar_cmov(&s, &secp256k1_scalar_one, overflow);
-
-    /* Compute shared X coordinate. */
-    secp256k1_ecmult_const_xonly(&px, &xn, &xd, &s, 1);
-    secp256k1_fe_normalize(&px);
-    secp256k1_fe_get_b32(sx, &px);
-
-    /* Invoke hasher */
-    ret = hashfp(output, sx, ell_a64, ell_b64, data);
-
-    memset(sx, 0, 32);
-    secp256k1_fe_clear(&px);
-    secp256k1_scalar_clear(&s);
-
-    return !!ret & !overflow;
-}
-
-#endif
diff --git a/src/precompute_ecmult.c b/src/precompute_ecmult.c
index 5ef198a..10aba5b 100644
--- a/src/precompute_ecmult.c
+++ b/src/precompute_ecmult.c
@@ -56,12 +56,11 @@ static void print_two_tables(FILE *fp, int window_g) {
 int main(void) {
     /* Always compute all tables for window sizes up to 15. */
     int window_g = (ECMULT_WINDOW_SIZE < 15) ? 15 : ECMULT_WINDOW_SIZE;
-    const char outfile[] = "src/precomputed_ecmult.c";
     FILE* fp;
 
-    fp = fopen(outfile, "w");
+    fp = fopen("src/precomputed_ecmult.c","w");
     if (fp == NULL) {
-        fprintf(stderr, "Could not open %s for writing!\n", outfile);
+        fprintf(stderr, "Could not open src/precomputed_ecmult.h for writing!\n");
         return -1;
     }
 
@@ -69,6 +68,7 @@ int main(void) {
     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, "#include \"../include/secp256k1.h\"\n");
     fprintf(fp, "#include \"group.h\"\n");
     fprintf(fp, "#include \"ecmult.h\"\n");
     fprintf(fp, "#include \"precomputed_ecmult.h\"\n");
diff --git a/src/precompute_ecmult_gen.c b/src/precompute_ecmult_gen.c
index ce648cb..bfe212f 100644
--- a/src/precompute_ecmult_gen.c
+++ b/src/precompute_ecmult_gen.c
@@ -33,6 +33,7 @@ int main(int argc, char **argv) {
 
     fprintf(fp, "/* This file was automatically generated by precompute_ecmult_gen. */\n");
     fprintf(fp, "/* See ecmult_gen_impl.h for details about the contents of this file. */\n");
+    fprintf(fp, "#include \"../include/secp256k1.h\"\n");
     fprintf(fp, "#include \"group.h\"\n");
     fprintf(fp, "#include \"ecmult_gen.h\"\n");
     fprintf(fp, "#include \"precomputed_ecmult_gen.h\"\n");
diff --git a/src/precomputed_ecmult.c b/src/precomputed_ecmult.c
index cbd030c..fbc634e 100644
--- a/src/precomputed_ecmult.c
+++ b/src/precomputed_ecmult.c
@@ -2,6 +2,7 @@
 /* This file contains an array secp256k1_pre_g with odd multiples of the base point G and
  * an array secp256k1_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G.
  */
+#include "../include/secp256k1.h"
 #include "group.h"
 #include "ecmult.h"
 #include "precomputed_ecmult.h"
diff --git a/src/precomputed_ecmult.h b/src/precomputed_ecmult.h
index 17df102..a4aa83e 100644
--- a/src/precomputed_ecmult.h
+++ b/src/precomputed_ecmult.h
@@ -11,7 +11,6 @@
 extern "C" {
 #endif
 
-#include "ecmult.h"
 #include "group.h"
 #if defined(EXHAUSTIVE_TEST_ORDER)
 #    if EXHAUSTIVE_TEST_ORDER == 7
diff --git a/src/precomputed_ecmult_gen.c b/src/precomputed_ecmult_gen.c
index 75ec59c..e9d62a1 100644
--- a/src/precomputed_ecmult_gen.c
+++ b/src/precomputed_ecmult_gen.c
@@ -1,5 +1,6 @@
 /* This file was automatically generated by precompute_ecmult_gen. */
 /* See ecmult_gen_impl.h for details about the contents of this file. */
+#include "../include/secp256k1.h"
 #include "group.h"
 #include "ecmult_gen.h"
 #include "precomputed_ecmult_gen.h"
diff --git a/src/scalar_4x64_impl.h b/src/scalar_4x64_impl.h
index 1d14740..0d342fd 100644
--- a/src/scalar_4x64_impl.h
+++ b/src/scalar_4x64_impl.h
@@ -133,10 +133,10 @@ static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int
 
 static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) {
     int over;
-    r->d[0] = secp256k1_read_be64(&b32[24]);
-    r->d[1] = secp256k1_read_be64(&b32[16]);
-    r->d[2] = secp256k1_read_be64(&b32[8]);
-    r->d[3] = secp256k1_read_be64(&b32[0]);
+    r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56;
+    r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56;
+    r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56;
+    r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56;
     over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r));
     if (overflow) {
         *overflow = over;
@@ -144,10 +144,10 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b
 }
 
 static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {
-    secp256k1_write_be64(&bin[0],  a->d[3]);
-    secp256k1_write_be64(&bin[8],  a->d[2]);
-    secp256k1_write_be64(&bin[16], a->d[1]);
-    secp256k1_write_be64(&bin[24], a->d[0]);
+    bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3];
+    bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2];
+    bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1];
+    bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0];
 }
 
 SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) {
diff --git a/src/scalar_8x32_impl.h b/src/scalar_8x32_impl.h
index 80ef3ef..da9936d 100644
--- a/src/scalar_8x32_impl.h
+++ b/src/scalar_8x32_impl.h
@@ -169,14 +169,14 @@ static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int
 
 static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) {
     int over;
-    r->d[0] = secp256k1_read_be32(&b32[28]);
-    r->d[1] = secp256k1_read_be32(&b32[24]);
-    r->d[2] = secp256k1_read_be32(&b32[20]);
-    r->d[3] = secp256k1_read_be32(&b32[16]);
-    r->d[4] = secp256k1_read_be32(&b32[12]);
-    r->d[5] = secp256k1_read_be32(&b32[8]);
-    r->d[6] = secp256k1_read_be32(&b32[4]);
-    r->d[7] = secp256k1_read_be32(&b32[0]);
+    r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24;
+    r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24;
+    r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24;
+    r->d[3] = (uint32_t)b32[19] | (uint32_t)b32[18] << 8 | (uint32_t)b32[17] << 16 | (uint32_t)b32[16] << 24;
+    r->d[4] = (uint32_t)b32[15] | (uint32_t)b32[14] << 8 | (uint32_t)b32[13] << 16 | (uint32_t)b32[12] << 24;
+    r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24;
+    r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24;
+    r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24;
     over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r));
     if (overflow) {
         *overflow = over;
@@ -184,14 +184,14 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b
 }
 
 static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {
-    secp256k1_write_be32(&bin[0], a->d[7]);
-    secp256k1_write_be32(&bin[4], a->d[6]);
-    secp256k1_write_be32(&bin[8], a->d[5]);
-    secp256k1_write_be32(&bin[12], a->d[4]);
-    secp256k1_write_be32(&bin[16], a->d[3]);
-    secp256k1_write_be32(&bin[20], a->d[2]);
-    secp256k1_write_be32(&bin[24], a->d[1]);
-    secp256k1_write_be32(&bin[28], a->d[0]);
+    bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7];
+    bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6];
+    bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5];
+    bin[12] = a->d[4] >> 24; bin[13] = a->d[4] >> 16; bin[14] = a->d[4] >> 8; bin[15] = a->d[4];
+    bin[16] = a->d[3] >> 24; bin[17] = a->d[3] >> 16; bin[18] = a->d[3] >> 8; bin[19] = a->d[3];
+    bin[20] = a->d[2] >> 24; bin[21] = a->d[2] >> 16; bin[22] = a->d[2] >> 8; bin[23] = a->d[2];
+    bin[24] = a->d[1] >> 24; bin[25] = a->d[1] >> 16; bin[26] = a->d[1] >> 8; bin[27] = a->d[1];
+    bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0];
 }
 
 SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) {
diff --git a/src/secp256k1.c b/src/secp256k1.c
index 4c11e7f..bdbd97c 100644
--- a/src/secp256k1.c
+++ b/src/secp256k1.c
@@ -247,8 +247,8 @@ static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge,
     } else {
         /* Otherwise, fall back to 32-byte big endian for X and Y. */
         secp256k1_fe x, y;
-        ARG_CHECK(secp256k1_fe_set_b32_limit(&x, pubkey->data));
-        ARG_CHECK(secp256k1_fe_set_b32_limit(&y, pubkey->data + 32));
+        secp256k1_fe_set_b32_mod(&x, pubkey->data);
+        secp256k1_fe_set_b32_mod(&y, pubkey->data + 32);
         secp256k1_ge_set_xy(ge, &x, &y);
     }
     ARG_CHECK(!secp256k1_fe_is_zero(&ge->x));
@@ -811,7 +811,3 @@ int secp256k1_tagged_sha256(const secp256k1_context* ctx, unsigned char *hash32,
 #ifdef ENABLE_MODULE_SCHNORRSIG
 # include "modules/schnorrsig/main_impl.h"
 #endif
-
-#ifdef ENABLE_MODULE_ELLSWIFT
-# include "modules/ellswift/main_impl.h"
-#endif
diff --git a/src/util.h b/src/util.h
index 801ea0c..0e3faf0 100644
--- a/src/util.h
+++ b/src/util.h
@@ -51,19 +51,6 @@ static void print_buf_plain(const unsigned char *buf, size_t len) {
 #  define SECP256K1_INLINE inline
 # endif
 
-/** Assert statically that expr is an integer constant expression, and run stmt.
- *
- * Useful for example to enforce that magnitude arguments are constant.
- */
-#define ASSERT_INT_CONST_AND_DO(expr, stmt) do { \
-    switch(42) { \
-        case /* ERROR: integer argument is not constant */ expr: \
-            break; \
-        default: ; \
-    } \
-    stmt; \
-} while(0)
-
 typedef struct {
     void (*fn)(const char *text, void* data);
     const void* data;
@@ -366,28 +353,4 @@ SECP256K1_INLINE static void secp256k1_write_be32(unsigned char* p, uint32_t x)
     p[0] = x >> 24;
 }
 
-/* Read a uint64_t in big endian */
-SECP256K1_INLINE static uint64_t secp256k1_read_be64(const unsigned char* p) {
-    return (uint64_t)p[0] << 56 |
-           (uint64_t)p[1] << 48 |
-           (uint64_t)p[2] << 40 |
-           (uint64_t)p[3] << 32 |
-           (uint64_t)p[4] << 24 |
-           (uint64_t)p[5] << 16 |
-           (uint64_t)p[6] << 8  |
-           (uint64_t)p[7];
-}
-
-/* Write a uint64_t in big endian */
-SECP256K1_INLINE static void secp256k1_write_be64(unsigned char* p, uint64_t x) {
-    p[7] = x;
-    p[6] = x >>  8;
-    p[5] = x >> 16;
-    p[4] = x >> 24;
-    p[3] = x >> 32;
-    p[2] = x >> 40;
-    p[1] = x >> 48;
-    p[0] = x >> 56;
-}
-
 #endif /* SECP256K1_UTIL_H */


Test patch:
diff --git a/src/ctime_tests.c b/src/ctime_tests.c
index af7891a..713eb42 100644
--- a/src/ctime_tests.c
+++ b/src/ctime_tests.c
@@ -30,10 +30,6 @@
 #include "../include/secp256k1_schnorrsig.h"
 #endif
 
-#ifdef ENABLE_MODULE_ELLSWIFT
-#include "../include/secp256k1_ellswift.h"
-#endif
-
 static void run_tests(secp256k1_context *ctx, unsigned char *key);
 
 int main(void) {
@@ -84,10 +80,6 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {
 #ifdef ENABLE_MODULE_EXTRAKEYS
     secp256k1_keypair keypair;
 #endif
-#ifdef ENABLE_MODULE_ELLSWIFT
-    unsigned char ellswift[64];
-    static const unsigned char prefix[64] = {'t', 'e', 's', 't'};
-#endif
 
     for (i = 0; i < 32; i++) {
         msg[i] = i + 1;
@@ -179,31 +171,4 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {
     SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
     CHECK(ret == 1);
 #endif
-
-#ifdef ENABLE_MODULE_ELLSWIFT
-    VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
-    ret = secp256k1_ellswift_create(ctx, ellswift, key, NULL);
-    VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
-    CHECK(ret == 1);
-
-    VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
-    ret = secp256k1_ellswift_create(ctx, ellswift, key, ellswift);
-    VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
-    CHECK(ret == 1);
-
-    for (i = 0; i < 2; i++) {
-        VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
-        VALGRIND_MAKE_MEM_DEFINED(&ellswift, sizeof(ellswift));
-        ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
-        VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
-        CHECK(ret == 1);
-
-        VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
-        VALGRIND_MAKE_MEM_DEFINED(&ellswift, sizeof(ellswift));
-        ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_prefix, (void *)prefix);
-        VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
-        CHECK(ret == 1);
-    }
-
-#endif
 }
diff --git a/src/modules/ellswift/tests_exhaustive_impl.h b/src/modules/ellswift/tests_exhaustive_impl.h
deleted file mode 100644
index e002a8c..0000000
--- a/src/modules/ellswift/tests_exhaustive_impl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/***********************************************************************
- * Distributed under the MIT software license, see the accompanying    *
- * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
- ***********************************************************************/
-
-#ifndef SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H
-#define SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H
-
-#include "../../../include/secp256k1_ellswift.h"
-#include "main_impl.h"
-
-static void test_exhaustive_ellswift(const secp256k1_context *ctx, const secp256k1_ge *group) {
-    int i;
-
-    /* Note that SwiftEC/ElligatorSwift are inherently curve operations, not
-     * group operations, and this test only checks the curve points which are in
-     * a tiny subgroup. In that sense it can't be really seen as exhaustive as
-     * it doesn't (and for computational reasons obviously cannot) test the
-     * entire domain ellswift operates under. */
-    for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) {
-        secp256k1_scalar scalar_i;
-        unsigned char sec32[32];
-        unsigned char ell64[64];
-        secp256k1_pubkey pub_decoded;
-        secp256k1_ge ge_decoded;
-
-        /* Construct ellswift pubkey from exhaustive loop scalar i. */
-        secp256k1_scalar_set_int(&scalar_i, i);
-        secp256k1_scalar_get_b32(sec32, &scalar_i);
-        CHECK(secp256k1_ellswift_create(ctx, ell64, sec32, NULL));
-
-        /* Decode ellswift pubkey and check that it matches the precomputed group element. */
-        secp256k1_ellswift_decode(ctx, &pub_decoded, ell64);
-        secp256k1_pubkey_load(ctx, &ge_decoded, &pub_decoded);
-        ge_equals_ge(&ge_decoded, &group[i]);
-    }
-}
-
-#endif
diff --git a/src/modules/ellswift/tests_impl.h b/src/modules/ellswift/tests_impl.h
deleted file mode 100644
index 86ca098..0000000
--- a/src/modules/ellswift/tests_impl.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/***********************************************************************
- * Distributed under the MIT software license, see the accompanying    *
- * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
- ***********************************************************************/
-
-#ifndef SECP256K1_MODULE_ELLSWIFT_TESTS_H
-#define SECP256K1_MODULE_ELLSWIFT_TESTS_H
-
-#include "../../../include/secp256k1_ellswift.h"
-
-struct ellswift_xswiftec_inv_test {
-    int enc_bitmap;
-    secp256k1_fe u;
-    secp256k1_fe x;
-    secp256k1_fe encs[8];
-};
-
-struct ellswift_decode_test {
-    unsigned char enc[64];
-    secp256k1_fe x;
-    int odd_y;
-};
-
-struct ellswift_xdh_test {
-    unsigned char priv_ours[32];
-    unsigned char ellswift_ours[64];
-    unsigned char ellswift_theirs[64];
-    int initiating;
-    unsigned char shared_secret[32];
-};
-
-/* Set of (point, encodings) test vectors, selected to maximize branch coverage, part of the BIP324
- * test vectors. Created using an independent implementation, and tested decoding against paper
- * authors' code. */
-static const struct ellswift_xswiftec_inv_test ellswift_xswiftec_inv_tests[] = {
-    {0xcc, SECP256K1_FE_CONST(0x05ff6bda, 0xd900fc32, 0x61bc7fe3, 0x4e2fb0f5, 0x69f06e09, 0x1ae437d3, 0xa52e9da0, 0xcbfb9590), SECP256K1_FE_CONST(0x80cdf637, 0x74ec7022, 0xc89a5a85, 0x58e373a2, 0x79170285, 0xe0ab2741, 0x2dbce510, 0xbdfe23fc), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x45654798, 0xece071ba, 0x79286d04, 0xf7f3eb1c, 0x3f1d17dd, 0x883610f2, 0xad2efd82, 0xa287466b), SECP256K1_FE_CONST(0x0aeaa886, 0xf6b76c71, 0x58452418, 0xcbf5033a, 0xdc5747e9, 0xe9b5d3b2, 0x303db969, 0x36528557), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xba9ab867, 0x131f8e45, 0x86d792fb, 0x080c14e3, 0xc0e2e822, 0x77c9ef0d, 0x52d1027c, 0x5d78b5c4), SECP256K1_FE_CONST(0xf5155779, 0x0948938e, 0xa7badbe7, 0x340afcc5, 0x23a8b816, 0x164a2c4d, 0xcfc24695, 0xc9ad76d8)}},
-    {0x33, SECP256K1_FE_CONST(0x1737a85f, 0x4c8d146c, 0xec96e3ff, 0xdca76d99, 0x03dcf3bd, 0x53061868, 0xd478c78c, 0x63c2aa9e), SECP256K1_FE_CONST(0x39e48dd1, 0x50d2f429, 0xbe088dfd, 0x5b61882e, 0x7e840748, 0x3702ae9a, 0x5ab35927, 0xb15f85ea), {SECP256K1_FE_CONST(0x1be8cc0b, 0x04be0c68, 0x1d0c6a68, 0xf733f82c, 0x6c896e0c, 0x8a262fcd, 0x392918e3, 0x03a7abf4), SECP256K1_FE_CONST(0x605b5814, 0xbf9b8cb0, 0x66667c9e, 0x5480d22d, 0xc5b6c92f, 0x14b4af3e, 0xe0a9eb83, 0xb03685e3), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xe41733f4, 0xfb41f397, 0xe2f39597, 0x08cc07d3, 0x937691f3, 0x75d9d032, 0xc6d6e71b, 0xfc58503b), SECP256K1_FE_CONST(0x9fa4a7eb, 0x4064734f, 0x99998361, 0xab7f2dd2, 0x3a4936d0, 0xeb4b50c1, 0x1f56147b, 0x4fc9764c), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x00, SECP256K1_FE_CONST(0x1aaa1cce, 0xbf9c7241, 0x91033df3, 0x66b36f69, 0x1c4d902c, 0x228033ff, 0x4516d122, 0xb2564f68), SECP256K1_FE_CONST(0xc7554125, 0x9d3ba98f, 0x207eaa30, 0xc69634d1, 0x87d0b6da, 0x594e719e, 0x420f4898, 0x638fc5b0), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x33, SECP256K1_FE_CONST(0x2323a1d0, 0x79b0fd72, 0xfc8bb62e, 0xc34230a8, 0x15cb0596, 0xc2bfac99, 0x8bd6b842, 0x60f5dc26), SECP256K1_FE_CONST(0x239342df, 0xb675500a, 0x34a19631, 0x0b8d87d5, 0x4f49dcac, 0x9da50c17, 0x43ceab41, 0xa7b249ff), {SECP256K1_FE_CONST(0xf63580b8, 0xaa49c484, 0x6de56e39, 0xe1b3e73f, 0x171e881e, 0xba8c66f6, 0x14e67e5c, 0x975dfc07), SECP256K1_FE_CONST(0xb6307b33, 0x2e699f1c, 0xf77841d9, 0x0af25365, 0x404deb7f, 0xed5edb30, 0x90db49e6, 0x42a156b6), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x09ca7f47, 0x55b63b7b, 0x921a91c6, 0x1e4c18c0, 0xe8e177e1, 0x45739909, 0xeb1981a2, 0x68a20028), SECP256K1_FE_CONST(0x49cf84cc, 0xd19660e3, 0x0887be26, 0xf50dac9a, 0xbfb21480, 0x12a124cf, 0x6f24b618, 0xbd5ea579), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x33, SECP256K1_FE_CONST(0x2dc90e64, 0x0cb646ae, 0x9164c0b5, 0xa9ef0169, 0xfebe34dc, 0x4437d6e4, 0x6acb0e27, 0xe219d1e8), SECP256K1_FE_CONST(0xd236f19b, 0xf349b951, 0x6e9b3f4a, 0x5610fe96, 0x0141cb23, 0xbbc8291b, 0x9534f1d7, 0x1de62a47), {SECP256K1_FE_CONST(0xe69df7d9, 0xc026c366, 0x00ebdf58, 0x80726758, 0x47c0c431, 0xc8eb7306, 0x82533e96, 0x4b6252c9), SECP256K1_FE_CONST(0x4f18bbdf, 0x7c2d6c5f, 0x818c1880, 0x2fa35cd0, 0x69eaa79f, 0xff74e4fc, 0x837c80d9, 0x3fece2f8), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x19620826, 0x3fd93c99, 0xff1420a7, 0x7f8d98a7, 0xb83f3bce, 0x37148cf9, 0x7dacc168, 0xb49da966), SECP256K1_FE_CONST(0xb0e74420, 0x83d293a0, 0x7e73e77f, 0xd05ca32f, 0x96155860, 0x008b1b03, 0x7c837f25, 0xc0131937), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0xcc, SECP256K1_FE_CONST(0x3edd7b39, 0x80e2f2f3, 0x4d1409a2, 0x07069f88, 0x1fda5f96, 0xf08027ac, 0x4465b63d, 0xc278d672), SECP256K1_FE_CONST(0x053a98de, 0x4a27b196, 0x1155822b, 0x3a3121f0, 0x3b2a1445, 0x8bd80eb4, 0xa560c4c7, 0xa85c149c), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xb3dae4b7, 0xdcf858e4, 0xc6968057, 0xcef2b156, 0x46543152, 0x6538199c, 0xf52dc1b2, 0xd62fda30), SECP256K1_FE_CONST(0x4aa77dd5, 0x5d6b6d3c, 0xfa10cc9d, 0x0fe42f79, 0x232e4575, 0x661049ae, 0x36779c1d, 0x0c666d88), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x4c251b48, 0x2307a71b, 0x39697fa8, 0x310d4ea9, 0xb9abcead, 0x9ac7e663, 0x0ad23e4c, 0x29d021ff), SECP256K1_FE_CONST(0xb558822a, 0xa29492c3, 0x05ef3362, 0xf01bd086, 0xdcd1ba8a, 0x99efb651, 0xc98863e1, 0xf3998ea7)}},
-    {0x00, SECP256K1_FE_CONST(0x4295737e, 0xfcb1da6f, 0xb1d96b9c, 0xa7dcd1e3, 0x20024b37, 0xa736c494, 0x8b625981, 0x73069f70), SECP256K1_FE_CONST(0xfa7ffe4f, 0x25f88362, 0x831c087a, 0xfe2e8a9b, 0x0713e2ca, 0xc1ddca6a, 0x383205a2, 0x66f14307), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0xff, SECP256K1_FE_CONST(0x587c1a0c, 0xee91939e, 0x7f784d23, 0xb963004a, 0x3bf44f5d, 0x4e32a008, 0x1995ba20, 0xb0fca59e), SECP256K1_FE_CONST(0x2ea98853, 0x0715e8d1, 0x0363907f, 0xf2512452, 0x4d471ba2, 0x454d5ce3, 0xbe3f0419, 0x4dfd3a3c), {SECP256K1_FE_CONST(0xcfd5a094, 0xaa0b9b88, 0x91b76c6a, 0xb9438f66, 0xaa1c095a, 0x65f9f701, 0x35e81712, 0x92245e74), SECP256K1_FE_CONST(0xa89057d7, 0xc6563f0d, 0x6efa19ae, 0x84412b8a, 0x7b47e791, 0xa191ecdf, 0xdf2af84f, 0xd97bc339), SECP256K1_FE_CONST(0x475d0ae9, 0xef46920d, 0xf07b3411, 0x7be5a081, 0x7de1023e, 0x3cc32689, 0xe9be145b, 0x406b0aef), SECP256K1_FE_CONST(0xa0759178, 0xad802324, 0x54f827ef, 0x05ea3e72, 0xad8d7541, 0x8e6d4cc1, 0xcd4f5306, 0xc5e7c453), SECP256K1_FE_CONST(0x302a5f6b, 0x55f46477, 0x6e489395, 0x46bc7099, 0x55e3f6a5, 0x9a0608fe, 0xca17e8ec, 0x6ddb9dbb), SECP256K1_FE_CONST(0x576fa828, 0x39a9c0f2, 0x9105e651, 0x7bbed475, 0x84b8186e, 0x5e6e1320, 0x20d507af, 0x268438f6), SECP256K1_FE_CONST(0xb8a2f516, 0x10b96df2, 0x0f84cbee, 0x841a5f7e, 0x821efdc1, 0xc33cd976, 0x1641eba3, 0xbf94f140), SECP256K1_FE_CONST(0x5f8a6e87, 0x527fdcdb, 0xab07d810, 0xfa15c18d, 0x52728abe, 0x7192b33e, 0x32b0acf8, 0x3a1837dc)}},
-    {0xcc, SECP256K1_FE_CONST(0x5fa88b33, 0x65a635cb, 0xbcee003c, 0xce9ef51d, 0xd1a310de, 0x277e441a, 0xbccdb7be, 0x1e4ba249), SECP256K1_FE_CONST(0x79461ff6, 0x2bfcbcac, 0x4249ba84, 0xdd040f2c, 0xec3c63f7, 0x25204dc7, 0xf464c16b, 0xf0ff3170), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x6bb700e1, 0xf4d7e236, 0xe8d193ff, 0x4a76c1b3, 0xbcd4e2b2, 0x5acac3d5, 0x1c8dac65, 0x3fe909a0), SECP256K1_FE_CONST(0xf4c73410, 0x633da7f6, 0x3a4f1d55, 0xaec6dd32, 0xc4c6d89e, 0xe74075ed, 0xb5515ed9, 0x0da9e683), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x9448ff1e, 0x0b281dc9, 0x172e6c00, 0xb5893e4c, 0x432b1d4d, 0xa5353c2a, 0xe3725399, 0xc016f28f), SECP256K1_FE_CONST(0x0b38cbef, 0x9cc25809, 0xc5b0e2aa, 0x513922cd, 0x3b392761, 0x18bf8a12, 0x4aaea125, 0xf25615ac)}},
-    {0xcc, SECP256K1_FE_CONST(0x6fb31c75, 0x31f03130, 0xb42b155b, 0x952779ef, 0xbb46087d, 0xd9807d24, 0x1a48eac6, 0x3c3d96d6), SECP256K1_FE_CONST(0x56f81be7, 0x53e8d4ae, 0x4940ea6f, 0x46f6ec9f, 0xda66a6f9, 0x6cc95f50, 0x6cb2b574, 0x90e94260), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x59059774, 0x795bdb7a, 0x837fbe11, 0x40a5fa59, 0x984f48af, 0x8df95d57, 0xdd6d1c05, 0x437dcec1), SECP256K1_FE_CONST(0x22a644db, 0x79376ad4, 0xe7b3a009, 0xe58b3f13, 0x137c54fd, 0xf911122c, 0xc93667c4, 0x7077d784), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xa6fa688b, 0x86a42485, 0x7c8041ee, 0xbf5a05a6, 0x67b0b750, 0x7206a2a8, 0x2292e3f9, 0xbc822d6e), SECP256K1_FE_CONST(0xdd59bb24, 0x86c8952b, 0x184c5ff6, 0x1a74c0ec, 0xec83ab02, 0x06eeedd3, 0x36c9983a, 0x8f8824ab)}},
-    {0x00, SECP256K1_FE_CONST(0x704cd226, 0xe71cb682, 0x6a590e80, 0xdac90f2d, 0x2f5830f0, 0xfdf135a3, 0xeae3965b, 0xff25ff12), SECP256K1_FE_CONST(0x138e0afa, 0x68936ee6, 0x70bd2b8d, 0xb53aedbb, 0x7bea2a85, 0x97388b24, 0xd0518edd, 0x22ad66ec), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x33, SECP256K1_FE_CONST(0x725e9147, 0x92cb8c89, 0x49e7e116, 0x8b7cdd8a, 0x8094c91c, 0x6ec2202c, 0xcd53a6a1, 0x8771edeb), SECP256K1_FE_CONST(0x8da16eb8, 0x6d347376, 0xb6181ee9, 0x74832275, 0x7f6b36e3, 0x913ddfd3, 0x32ac595d, 0x788e0e44), {SECP256K1_FE_CONST(0xdd357786, 0xb9f68733, 0x30391aa5, 0x62580965, 0x4e43116e, 0x82a5a5d8, 0x2ffd1d66, 0x24101fc4), SECP256K1_FE_CONST(0xa0b7efca, 0x01814594, 0xc59c9aae, 0x8e497001, 0x86ca5d95, 0xe88bcc80, 0x399044d9, 0xc2d8613d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x22ca8879, 0x460978cc, 0xcfc6e55a, 0x9da7f69a, 0xb1bcee91, 0x7d5a5a27, 0xd002e298, 0xdbefdc6b), SECP256K1_FE_CONST(0x5f481035, 0xfe7eba6b, 0x3a636551, 0x71b68ffe, 0x7935a26a, 0x1774337f, 0xc66fbb25, 0x3d279af2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x00, SECP256K1_FE_CONST(0x78fe6b71, 0x7f2ea4a3, 0x2708d79c, 0x151bf503, 0xa5312a18, 0xc0963437, 0xe865cc6e, 0xd3f6ae97), SECP256K1_FE_CONST(0x8701948e, 0x80d15b5c, 0xd8f72863, 0xeae40afc, 0x5aced5e7, 0x3f69cbc8, 0x179a3390, 0x2c094d98), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x44, SECP256K1_FE_CONST(0x7c37bb9c, 0x5061dc07, 0x413f11ac, 0xd5a34006, 0xe64c5c45, 0x7fdb9a43, 0x8f217255, 0xa961f50d), SECP256K1_FE_CONST(0x5c1a76b4, 0x4568eb59, 0xd6789a74, 0x42d9ed7c, 0xdc6226b7, 0x752b4ff8, 0xeaf8e1a9, 0x5736e507), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xb94d30cd, 0x7dbff60b, 0x64620c17, 0xca0fafaa, 0x40b3d1f5, 0x2d077a60, 0xa2e0cafd, 0x145086c2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x46b2cf32, 0x824009f4, 0x9b9df3e8, 0x35f05055, 0xbf4c2e0a, 0xd2f8859f, 0x5d1f3501, 0xebaf756d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x00, SECP256K1_FE_CONST(0x82388888, 0x967f82a6, 0xb444438a, 0x7d44838e, 0x13c0d478, 0xb9ca060d, 0xa95a41fb, 0x94303de6), SECP256K1_FE_CONST(0x29e96541, 0x70628fec, 0x8b497289, 0x8b113cf9, 0x8807f460, 0x9274f4f3, 0x140d0674, 0x157c90a0), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x33, SECP256K1_FE_CONST(0x91298f57, 0x70af7a27, 0xf0a47188, 0xd24c3b7b, 0xf98ab299, 0x0d84b0b8, 0x98507e3c, 0x561d6472), SECP256K1_FE_CONST(0x144f4ccb, 0xd9a74698, 0xa88cbf6f, 0xd00ad886, 0xd339d29e, 0xa19448f2, 0xc572cac0, 0xa07d5562), {SECP256K1_FE_CONST(0xe6a0ffa3, 0x807f09da, 0xdbe71e0f, 0x4be4725f, 0x2832e76c, 0xad8dc1d9, 0x43ce8393, 0x75eff248), SECP256K1_FE_CONST(0x837b8e68, 0xd4917544, 0x764ad090, 0x3cb11f86, 0x15d2823c, 0xefbb06d8, 0x9049dbab, 0xc69befda), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x195f005c, 0x7f80f625, 0x2418e1f0, 0xb41b8da0, 0xd7cd1893, 0x52723e26, 0xbc317c6b, 0x8a1009e7), SECP256K1_FE_CONST(0x7c847197, 0x2b6e8abb, 0x89b52f6f, 0xc34ee079, 0xea2d7dc3, 0x1044f927, 0x6fb62453, 0x39640c55), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x00, SECP256K1_FE_CONST(0xb682f3d0, 0x3bbb5dee, 0x4f54b5eb, 0xfba931b4, 0xf52f6a19, 0x1e5c2f48, 0x3c73c66e, 0x9ace97e1), SECP256K1_FE_CONST(0x904717bf, 0x0bc0cb78, 0x73fcdc38, 0xaa97f19e, 0x3a626309, 0x72acff92, 0xb24cc6dd, 0xa197cb96), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x77, SECP256K1_FE_CONST(0xc17ec69e, 0x665f0fb0, 0xdbab48d9, 0xc2f94d12, 0xec8a9d7e, 0xacb58084, 0x83309180, 0x1eb0b80b), SECP256K1_FE_CONST(0x147756e6, 0x6d96e31c, 0x426d3cc8, 0x5ed0c4cf, 0xbef6341d, 0xd8b28558, 0x5aa574ea, 0x0204b55e), {SECP256K1_FE_CONST(0x6f4aea43, 0x1a0043bd, 0xd03134d6, 0xd9159119, 0xce034b88, 0xc32e50e8, 0xe36c4ee4, 0x5eac7ae9), SECP256K1_FE_CONST(0xfd5be16d, 0x4ffa2690, 0x126c67c3, 0xef7cb9d2, 0x9b74d397, 0xc78b06b3, 0x605fda34, 0xdc9696a6), SECP256K1_FE_CONST(0x5e9c6079, 0x2a2f000e, 0x45c6250f, 0x296f875e, 0x174efc0e, 0x9703e628, 0x706103a9, 0xdd2d82c7), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x90b515bc, 0xe5ffbc42, 0x2fcecb29, 0x26ea6ee6, 0x31fcb477, 0x3cd1af17, 0x1c93b11a, 0xa1538146), SECP256K1_FE_CONST(0x02a41e92, 0xb005d96f, 0xed93983c, 0x1083462d, 0x648b2c68, 0x3874f94c, 0x9fa025ca, 0x23696589), SECP256K1_FE_CONST(0xa1639f86, 0xd5d0fff1, 0xba39daf0, 0xd69078a1, 0xe8b103f1, 0x68fc19d7, 0x8f9efc55, 0x22d27968), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0xcc, SECP256K1_FE_CONST(0xc25172fc, 0x3f29b6fc, 0x4a1155b8, 0x57523315, 0x5486b274, 0x64b74b8b, 0x260b499a, 0x3f53cb14), SECP256K1_FE_CONST(0x1ea9cbdb, 0x35cf6e03, 0x29aa31b0, 0xbb0a702a, 0x65123ed0, 0x08655a93, 0xb7dcd528, 0x0e52e1ab), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x7422edc7, 0x843136af, 0x0053bb88, 0x54448a82, 0x99994f9d, 0xdcefd3a9, 0xa92d4546, 0x2c59298a), SECP256K1_FE_CONST(0x78c7774a, 0x266f8b97, 0xea23d05d, 0x064f033c, 0x77319f92, 0x3f6b78bc, 0xe4e20bf0, 0x5fa5398d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x8bdd1238, 0x7bcec950, 0xffac4477, 0xabbb757d, 0x6666b062, 0x23102c56, 0x56d2bab8, 0xd3a6d2a5), SECP256K1_FE_CONST(0x873888b5, 0xd9907468, 0x15dc2fa2, 0xf9b0fcc3, 0x88ce606d, 0xc0948743, 0x1b1df40e, 0xa05ac2a2)}},
-    {0x00, SECP256K1_FE_CONST(0xcab6626f, 0x832a4b12, 0x80ba7add, 0x2fc5322f, 0xf011caed, 0xedf7ff4d, 0xb6735d50, 0x26dc0367), SECP256K1_FE_CONST(0x2b2bef08, 0x52c6f7c9, 0x5d72ac99, 0xa23802b8, 0x75029cd5, 0x73b248d1, 0xf1b3fc80, 0x33788eb6), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x33, SECP256K1_FE_CONST(0xd8621b4f, 0xfc85b9ed, 0x56e99d8d, 0xd1dd24ae, 0xdcecb147, 0x63b861a1, 0x7112dc77, 0x1a104fd2), SECP256K1_FE_CONST(0x812cabe9, 0x72a22aa6, 0x7c7da0c9, 0x4d8a9362, 0x96eb9949, 0xd70c37cb, 0x2b248757, 0x4cb3ce58), {SECP256K1_FE_CONST(0xfbc5febc, 0x6fdbc9ae, 0x3eb88a93, 0xb982196e, 0x8b6275a6, 0xd5a73c17, 0x387e000c, 0x711bd0e3), SECP256K1_FE_CONST(0x8724c96b, 0xd4e5527f, 0x2dd195a5, 0x1c468d2d, 0x211ba2fa, 0xc7cbe0b4, 0xb3434253, 0x409fb42d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x043a0143, 0x90243651, 0xc147756c, 0x467de691, 0x749d8a59, 0x2a58c3e8, 0xc781fff2, 0x8ee42b4c), SECP256K1_FE_CONST(0x78db3694, 0x2b1aad80, 0xd22e6a5a, 0xe3b972d2, 0xdee45d05, 0x38341f4b, 0x4cbcbdab, 0xbf604802), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x00, SECP256K1_FE_CONST(0xda463164, 0xc6f4bf71, 0x29ee5f0e, 0xc00f65a6, 0x75a8adf1, 0xbd931b39, 0xb64806af, 0xdcda9a22), SECP256K1_FE_CONST(0x25b9ce9b, 0x390b408e, 0xd611a0f1, 0x3ff09a59, 0x8a57520e, 0x426ce4c6, 0x49b7f94f, 0x2325620d), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0xcc, SECP256K1_FE_CONST(0xdafc971e, 0x4a3a7b6d, 0xcfb42a08, 0xd9692d82, 0xad9e7838, 0x523fcbda, 0x1d4827e1, 0x4481ae2d), SECP256K1_FE_CONST(0x250368e1, 0xb5c58492, 0x304bd5f7, 0x2696d27d, 0x526187c7, 0xadc03425, 0xe2b7d81d, 0xbb7e4e02), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x370c28f1, 0xbe665efa, 0xcde6aa43, 0x6bf86fe2, 0x1e6e314c, 0x1e53dd04, 0x0e6c73a4, 0x6b4c8c49), SECP256K1_FE_CONST(0xcd8acee9, 0x8ffe5653, 0x1a84d7eb, 0x3e48fa40, 0x34206ce8, 0x25ace907, 0xd0edf0ea, 0xeb5e9ca2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xc8f3d70e, 0x4199a105, 0x321955bc, 0x9407901d, 0xe191ceb3, 0xe1ac22fb, 0xf1938c5a, 0x94b36fe6), SECP256K1_FE_CONST(0x32753116, 0x7001a9ac, 0xe57b2814, 0xc1b705bf, 0xcbdf9317, 0xda5316f8, 0x2f120f14, 0x14a15f8d)}},
-    {0x44, SECP256K1_FE_CONST(0xe0294c8b, 0xc1a36b41, 0x66ee92bf, 0xa70a5c34, 0x976fa982, 0x9405efea, 0x8f9cd54d, 0xcb29b99e), SECP256K1_FE_CONST(0xae9690d1, 0x3b8d20a0, 0xfbbf37be, 0xd8474f67, 0xa04e142f, 0x56efd787, 0x70a76b35, 0x9165d8a1), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xdcd45d93, 0x5613916a, 0xf167b029, 0x058ba3a7, 0x00d37150, 0xb9df3472, 0x8cb05412, 0xc16d4182), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x232ba26c, 0xa9ec6e95, 0x0e984fd6, 0xfa745c58, 0xff2c8eaf, 0x4620cb8d, 0x734fabec, 0x3e92baad), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0x00, SECP256K1_FE_CONST(0xe148441c, 0xd7b92b8b, 0x0e4fa3bd, 0x68712cfd, 0x0d709ad1, 0x98cace61, 0x1493c10e, 0x97f5394e), SECP256K1_FE_CONST(0x164a6397, 0x94d74c53, 0xafc4d329, 0x4e79cdb3, 0xcd25f99f, 0x6df45c00, 0x0f758aba, 0x54d699c0), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0xff, SECP256K1_FE_CONST(0xe4b00ec9, 0x7aadcca9, 0x7644d3b0, 0xc8a931b1, 0x4ce7bcf7, 0xbc877954, 0x6d6e35aa, 0x5937381c), SECP256K1_FE_CONST(0x94e9588d, 0x41647b3f, 0xcc772dc8, 0xd83c67ce, 0x3be00353, 0x8517c834, 0x103d2cd4, 0x9d62ef4d), {SECP256K1_FE_CONST(0xc88d25f4, 0x1407376b, 0xb2c03a7f, 0xffeb3ec7, 0x811cc434, 0x91a0c3aa, 0xc0378cdc, 0x78357bee), SECP256K1_FE_CONST(0x51c02636, 0xce00c234, 0x5ecd89ad, 0xb6089fe4, 0xd5e18ac9, 0x24e3145e, 0x6669501c, 0xd37a00d4), SECP256K1_FE_CONST(0x205b3512, 0xdb40521c, 0xb200952e, 0x67b46f67, 0xe09e7839, 0xe0de4400, 0x4138329e, 0xbd9138c5), SECP256K1_FE_CONST(0x58aab390, 0xab6fb55c, 0x1d1b8089, 0x7a207ce9, 0x4a78fa5b, 0x4aa61a33, 0x398bcae9, 0xadb20d3e), SECP256K1_FE_CONST(0x3772da0b, 0xebf8c894, 0x4d3fc580, 0x0014c138, 0x7ee33bcb, 0x6e5f3c55, 0x3fc87322, 0x87ca8041), SECP256K1_FE_CONST(0xae3fd9c9, 0x31ff3dcb, 0xa1327652, 0x49f7601b, 0x2a1e7536, 0xdb1ceba1, 0x9996afe2, 0x2c85fb5b), SECP256K1_FE_CONST(0xdfa4caed, 0x24bfade3, 0x4dff6ad1, 0x984b9098, 0x1f6187c6, 0x1f21bbff, 0xbec7cd60, 0x426ec36a), SECP256K1_FE_CONST(0xa7554c6f, 0x54904aa3, 0xe2e47f76, 0x85df8316, 0xb58705a4, 0xb559e5cc, 0xc6743515, 0x524deef1)}},
-    {0x00, SECP256K1_FE_CONST(0xe5bbb9ef, 0x360d0a50, 0x1618f006, 0x7d36dceb, 0x75f5be9a, 0x620232aa, 0x9fd5139d, 0x0863fde5), SECP256K1_FE_CONST(0xe5bbb9ef, 0x360d0a50, 0x1618f006, 0x7d36dceb, 0x75f5be9a, 0x620232aa, 0x9fd5139d, 0x0863fde5), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0xff, SECP256K1_FE_CONST(0xe6bcb5c3, 0xd63467d4, 0x90bfa54f, 0xbbc6092a, 0x7248c25e, 0x11b248dc, 0x2964a6e1, 0x5edb1457), SECP256K1_FE_CONST(0x19434a3c, 0x29cb982b, 0x6f405ab0, 0x4439f6d5, 0x8db73da1, 0xee4db723, 0xd69b591d, 0xa124e7d8), {SECP256K1_FE_CONST(0x67119877, 0x832ab8f4, 0x59a82165, 0x6d8261f5, 0x44a553b8, 0x9ae4f25c, 0x52a97134, 0xb70f3426), SECP256K1_FE_CONST(0xffee02f5, 0xe649c07f, 0x0560eff1, 0x867ec7b3, 0x2d0e595e, 0x9b1c0ea6, 0xe2a4fc70, 0xc97cd71f), SECP256K1_FE_CONST(0xb5e0c189, 0xeb5b4bac, 0xd025b744, 0x4d74178b, 0xe8d5246c, 0xfa4a9a20, 0x7964a057, 0xee969992), SECP256K1_FE_CONST(0x5746e459, 0x1bf7f4c3, 0x044609ea, 0x372e9086, 0x03975d27, 0x9fdef834, 0x9f0b08d3, 0x2f07619d), SECP256K1_FE_CONST(0x98ee6788, 0x7cd5470b, 0xa657de9a, 0x927d9e0a, 0xbb5aac47, 0x651b0da3, 0xad568eca, 0x48f0c809), SECP256K1_FE_CONST(0x0011fd0a, 0x19b63f80, 0xfa9f100e, 0x7981384c, 0xd2f1a6a1, 0x64e3f159, 0x1d5b038e, 0x36832510), SECP256K1_FE_CONST(0x4a1f3e76, 0x14a4b453, 0x2fda48bb, 0xb28be874, 0x172adb93, 0x05b565df, 0x869b5fa7, 0x1169629d), SECP256K1_FE_CONST(0xa8b91ba6, 0xe4080b3c, 0xfbb9f615, 0xc8d16f79, 0xfc68a2d8, 0x602107cb, 0x60f4f72b, 0xd0f89a92)}},
-    {0x33, SECP256K1_FE_CONST(0xf28fba64, 0xaf766845, 0xeb2f4302, 0x456e2b9f, 0x8d80affe, 0x57e7aae4, 0x2738d7cd, 0xdb1c2ce6), SECP256K1_FE_CONST(0xf28fba64, 0xaf766845, 0xeb2f4302, 0x456e2b9f, 0x8d80affe, 0x57e7aae4, 0x2738d7cd, 0xdb1c2ce6), {SECP256K1_FE_CONST(0x4f867ad8, 0xbb3d8404, 0x09d26b67, 0x307e6210, 0x0153273f, 0x72fa4b74, 0x84becfa1, 0x4ebe7408), SECP256K1_FE_CONST(0x5bbc4f59, 0xe452cc5f, 0x22a99144, 0xb10ce898, 0x9a89a995, 0xec3cea1c, 0x91ae10e8, 0xf721bb5d), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xb0798527, 0x44c27bfb, 0xf62d9498, 0xcf819def, 0xfeacd8c0, 0x8d05b48b, 0x7b41305d, 0xb1418827), SECP256K1_FE_CONST(0xa443b0a6, 0x1bad33a0, 0xdd566ebb, 0x4ef31767, 0x6576566a, 0x13c315e3, 0x6e51ef16, 0x08de40d2), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-    {0xcc, SECP256K1_FE_CONST(0xf455605b, 0xc85bf48e, 0x3a908c31, 0x023faf98, 0x381504c6, 0xc6d3aeb9, 0xede55f8d, 0xd528924d), SECP256K1_FE_CONST(0xd31fbcd5, 0xcdb798f6, 0xc00db669, 0x2f8fe896, 0x7fa9c79d, 0xd10958f4, 0xa194f013, 0x74905e99), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0x0c00c571, 0x5b56fe63, 0x2d814ad8, 0xa77f8e66, 0x628ea47a, 0x6116834f, 0x8c1218f3, 0xa03cbd50), SECP256K1_FE_CONST(0xdf88e44f, 0xac84fa52, 0xdf4d59f4, 0x8819f18f, 0x6a8cd415, 0x1d162afa, 0xf773166f, 0x57c7ff46), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0xf3ff3a8e, 0xa4a9019c, 0xd27eb527, 0x58807199, 0x9d715b85, 0x9ee97cb0, 0x73ede70b, 0x5fc33edf), SECP256K1_FE_CONST(0x20771bb0, 0x537b05ad, 0x20b2a60b, 0x77e60e70, 0x95732bea, 0xe2e9d505, 0x088ce98f, 0xa837fce9)}},
-    {0xff, SECP256K1_FE_CONST(0xf58cd4d9, 0x830bad32, 0x2699035e, 0x8246007d, 0x4be27e19, 0xb6f53621, 0x317b4f30, 0x9b3daa9d), SECP256K1_FE_CONST(0x78ec2b3d, 0xc0948de5, 0x60148bbc, 0x7c6dc963, 0x3ad5df70, 0xa5a5750c, 0xbed72180, 0x4f082a3b), {SECP256K1_FE_CONST(0x6c4c580b, 0x76c75940, 0x43569f9d, 0xae16dc28, 0x01c16a1f, 0xbe128608, 0x81b75f8e, 0xf929bce5), SECP256K1_FE_CONST(0x94231355, 0xe7385c5f, 0x25ca436a, 0xa6419147, 0x1aea4393, 0xd6e86ab7, 0xa35fe2af, 0xacaefd0d), SECP256K1_FE_CONST(0xdff2a195, 0x1ada6db5, 0x74df8340, 0x48149da3, 0x397a75b8, 0x29abf58c, 0x7e69db1b, 0x41ac0989), SECP256K1_FE_CONST(0xa52b66d3, 0xc9070355, 0x48028bf8, 0x04711bf4, 0x22aba95f, 0x1a666fc8, 0x6f4648e0, 0x5f29caae), SECP256K1_FE_CONST(0x93b3a7f4, 0x8938a6bf, 0xbca96062, 0x51e923d7, 0xfe3e95e0, 0x41ed79f7, 0x7e48a070, 0x06d63f4a), SECP256K1_FE_CONST(0x6bdcecaa, 0x18c7a3a0, 0xda35bc95, 0x59be6eb8, 0xe515bc6c, 0x29179548, 0x5ca01d4f, 0x5350ff22), SECP256K1_FE_CONST(0x200d5e6a, 0xe525924a, 0x8b207cbf, 0xb7eb625c, 0xc6858a47, 0xd6540a73, 0x819624e3, 0xbe53f2a6), SECP256K1_FE_CONST(0x5ad4992c, 0x36f8fcaa, 0xb7fd7407, 0xfb8ee40b, 0xdd5456a0, 0xe5999037, 0x90b9b71e, 0xa0d63181)}},
-    {0x00, SECP256K1_FE_CONST(0xfd7d912a, 0x40f182a3, 0x588800d6, 0x9ebfb504, 0x8766da20, 0x6fd7ebc8, 0xd2436c81, 0xcbef6421), SECP256K1_FE_CONST(0x8d37c862, 0x054debe7, 0x31694536, 0xff46b273, 0xec122b35, 0xa9bf1445, 0xac3c4ff9, 0xf262c952), {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0)}},
-};
-
-/* Set of (encoding, xcoord) test vectors, selected to maximize branch coverage, part of the BIP324
- * test vectors. Created using an independent implementation, and tested decoding against the paper
- * authors' code. */
-static const struct ellswift_decode_test ellswift_decode_tests[] = {
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x47, 0x5b, 0xf7, 0x65, 0x5b, 0x0f, 0xb2, 0xd8, 0x52, 0x92, 0x10, 0x35, 0xb2, 0xef, 0x60, 0x7f, 0x49, 0x06, 0x9b, 0x97, 0x45, 0x4e, 0x67, 0x95, 0x25, 0x10, 0x62, 0x74, 0x17, 0x71}, SECP256K1_FE_CONST(0xb5da00b7, 0x3cd65605, 0x20e7c364, 0x086e7cd2, 0x3a34bf60, 0xd0e707be, 0x9fc34d4c, 0xd5fdfa2c), 1},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x27, 0x7c, 0x4a, 0x71, 0xf9, 0xd2, 0x2e, 0x66, 0xec, 0xe5, 0x23, 0xf8, 0xfa, 0x08, 0x74, 0x1a, 0x7c, 0x09, 0x12, 0xc6, 0x6a, 0x69, 0xce, 0x68, 0x51, 0x4b, 0xfd, 0x35, 0x15, 0xb4, 0x9f}, SECP256K1_FE_CONST(0xf482f2e2, 0x41753ad0, 0xfb89150d, 0x8491dc1e, 0x34ff0b8a, 0xcfbb442c, 0xfe999e2e, 0x5e6fd1d2), 1},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x21, 0xcc, 0x93, 0x0e, 0x77, 0xc9, 0xf5, 0x14, 0xb6, 0x91, 0x5c, 0x3d, 0xbe, 0x2a, 0x94, 0xc6, 0xd8, 0xf6, 0x90, 0xb5, 0xb7, 0x39, 0x86, 0x4b, 0xa6, 0x78, 0x9f, 0xb8, 0xa5, 0x5d, 0xd0}, SECP256K1_FE_CONST(0x9f59c402, 0x75f5085a, 0x006f05da, 0xe77eb98c, 0x6fd0db1a, 0xb4a72ac4, 0x7eae90a4, 0xfc9e57e0), 0},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41}, SECP256K1_FE_CONST(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaa9, 0xfffffd6b), 1},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x9c, 0x18, 0x2d, 0x27, 0x59, 0xcd, 0x99, 0x82, 0x42, 0x28, 0xd9, 0x47, 0x99, 0xf8, 0xc6, 0x55, 0x7c, 0x38, 0xa1, 0xc0, 0xd6, 0x77, 0x9b, 0x9d, 0x4b, 0x72, 0x9c, 0x6f, 0x1c, 0xcc, 0x42}, SECP256K1_FE_CONST(0x70720db7, 0xe238d041, 0x21f5b1af, 0xd8cc5ad9, 0xd18944c6, 0xbdc94881, 0xf502b7a3, 0xaf3aecff), 0},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x64, 0xbb, 0xd5}, SECP256K1_FE_CONST(0x50873db3, 0x1badcc71, 0x890e4f67, 0x753a6575, 0x7f97aaa7, 0xdd5f1e82, 0xb753ace3, 0x2219064b), 0},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x28, 0xde, 0x7d}, SECP256K1_FE_CONST(0x1eea9cc5, 0x9cfcf2fa, 0x151ac6c2, 0x74eea411, 0x0feb4f7b, 0x68c59657, 0x32e9992e, 0x976ef68e), 0},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xcf, 0xb7, 0xe7}, SECP256K1_FE_CONST(0x12303941, 0xaedc2088, 0x80735b1f, 0x1795c8e5, 0x5be520ea, 0x93e10335, 0x7b5d2adb, 0x7ed59b8e), 0},
-    {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x11, 0x3a, 0xd9}, SECP256K1_FE_CONST(0x7eed6b70, 0xe7b0767c, 0x7d7feac0, 0x4e57aa2a, 0x12fef5e0, 0xf48f878f, 0xcbb88b3b, 0x6b5e0783), 0},
-    {{0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c, 0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x532167c1, 0x1200b08c, 0x0e84a354, 0xe74dcc40, 0xf8b25f4f, 0xe686e308, 0x69526366, 0x278a0688), 0},
-    {{0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c, 0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x532167c1, 0x1200b08c, 0x0e84a354, 0xe74dcc40, 0xf8b25f4f, 0xe686e308, 0x69526366, 0x278a0688), 0},
-    {{0x0f, 0xfd, 0xe9, 0xca, 0x81, 0xd7, 0x51, 0xe9, 0xcd, 0xaf, 0xfc, 0x1a, 0x50, 0x77, 0x92, 0x45, 0x32, 0x0b, 0x28, 0x99, 0x6d, 0xba, 0xf3, 0x2f, 0x82, 0x2f, 0x20, 0x11, 0x7c, 0x22, 0xfb, 0xd6, 0xc7, 0x4d, 0x99, 0xef, 0xce, 0xaa, 0x55, 0x0f, 0x1a, 0xd1, 0xc0, 0xf4, 0x3f, 0x46, 0xe7, 0xff, 0x1e, 0xe3, 0xbd, 0x01, 0x62, 0xb7, 0xbf, 0x55, 0xf2, 0x96, 0x5d, 0xa9, 0xc3, 0x45, 0x06, 0x46}, SECP256K1_FE_CONST(0x74e880b3, 0xffd18fe3, 0xcddf7902, 0x522551dd, 0xf97fa4a3, 0x5a3cfda8, 0x197f9470, 0x81a57b8f), 0},
-    {{0x0f, 0xfd, 0xe9, 0xca, 0x81, 0xd7, 0x51, 0xe9, 0xcd, 0xaf, 0xfc, 0x1a, 0x50, 0x77, 0x92, 0x45, 0x32, 0x0b, 0x28, 0x99, 0x6d, 0xba, 0xf3, 0x2f, 0x82, 0x2f, 0x20, 0x11, 0x7c, 0x22, 0xfb, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x6c, 0xa8, 0x96}, SECP256K1_FE_CONST(0x377b643f, 0xce2271f6, 0x4e5c8101, 0x566107c1, 0xbe498074, 0x50917838, 0x04f65478, 0x1ac9217c), 1},
-    {{0x12, 0x36, 0x58, 0x44, 0x4f, 0x32, 0xbe, 0x8f, 0x02, 0xea, 0x20, 0x34, 0xaf, 0xa7, 0xef, 0x4b, 0xbe, 0x8a, 0xdc, 0x91, 0x8c, 0xeb, 0x49, 0xb1, 0x27, 0x73, 0xb6, 0x25, 0xf4, 0x90, 0xb3, 0x68, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8d, 0xc5, 0xfe, 0x11}, SECP256K1_FE_CONST(0xed16d65c, 0xf3a9538f, 0xcb2c139f, 0x1ecbc143, 0xee148271, 0x20cbc265, 0x9e667256, 0x800b8142), 0},
-    {{0x14, 0x6f, 0x92, 0x46, 0x4d, 0x15, 0xd3, 0x6e, 0x35, 0x38, 0x2b, 0xd3, 0xca, 0x5b, 0x0f, 0x97, 0x6c, 0x95, 0xcb, 0x08, 0xac, 0xdc, 0xf2, 0xd5, 0xb3, 0x57, 0x06, 0x17, 0x99, 0x08, 0x39, 0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x31, 0x45, 0xe9, 0x3b}, SECP256K1_FE_CONST(0x0d5cd840, 0x427f941f, 0x65193079, 0xab8e2e83, 0x024ef2ee, 0x7ca558d8, 0x8879ffd8, 0x79fb6657), 0},
-    {{0x15, 0xfd, 0xf5, 0xcf, 0x09, 0xc9, 0x07, 0x59, 0xad, 0xd2, 0x27, 0x2d, 0x57, 0x4d, 0x2b, 0xb5, 0xfe, 0x14, 0x29, 0xf9, 0xf3, 0xc1, 0x4c, 0x65, 0xe3, 0x19, 0x4b, 0xf6, 0x1b, 0x82, 0xaa, 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0xcf, 0xd9, 0x06}, SECP256K1_FE_CONST(0x16d0e439, 0x46aec93f, 0x62d57eb8, 0xcde68951, 0xaf136cf4, 0xb307938d, 0xd1447411, 0xe07bffe1), 1},
-    {{0x1f, 0x67, 0xed, 0xf7, 0x79, 0xa8, 0xa6, 0x49, 0xd6, 0xde, 0xf6, 0x00, 0x35, 0xf2, 0xfa, 0x22, 0xd0, 0x22, 0xdd, 0x35, 0x90, 0x79, 0xa1, 0xa1, 0x44, 0x07, 0x3d, 0x84, 0xf1, 0x9b, 0x92, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x025661f9, 0xaba9d15c, 0x3118456b, 0xbe980e3e, 0x1b8ba2e0, 0x47c737a4, 0xeb48a040, 0xbb566f6c), 0},
-    {{0x1f, 0x67, 0xed, 0xf7, 0x79, 0xa8, 0xa6, 0x49, 0xd6, 0xde, 0xf6, 0x00, 0x35, 0xf2, 0xfa, 0x22, 0xd0, 0x22, 0xdd, 0x35, 0x90, 0x79, 0xa1, 0xa1, 0x44, 0x07, 0x3d, 0x84, 0xf1, 0x9b, 0x92, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x025661f9, 0xaba9d15c, 0x3118456b, 0xbe980e3e, 0x1b8ba2e0, 0x47c737a4, 0xeb48a040, 0xbb566f6c), 0},
-    {{0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x98bec3b2, 0xa351fa96, 0xcfd191c1, 0x77835193, 0x1b9e9ba9, 0xad1149f6, 0xd9eadca8, 0x0981b801), 0},
-    {{0x40, 0x56, 0xa3, 0x4a, 0x21, 0x0e, 0xec, 0x78, 0x92, 0xe8, 0x82, 0x06, 0x75, 0xc8, 0x60, 0x09, 0x9f, 0x85, 0x7b, 0x26, 0xaa, 0xd8, 0x54, 0x70, 0xee, 0x6d, 0x3c, 0xf1, 0x30, 0x4a, 0x9d, 0xcf, 0x37, 0x5e, 0x70, 0x37, 0x42, 0x71, 0xf2, 0x0b, 0x13, 0xc9, 0x98, 0x6e, 0xd7, 0xd3, 0xc1, 0x77, 0x99, 0x69, 0x8c, 0xfc, 0x43, 0x5d, 0xbe, 0xd3, 0xa9, 0xf3, 0x4b, 0x38, 0xc8, 0x23, 0xc2, 0xb4}, SECP256K1_FE_CONST(0x868aac20, 0x03b29dbc, 0xad1a3e80, 0x3855e078, 0xa89d1654, 0x3ac64392, 0xd1224172, 0x98cec76e), 0},
-    {{0x41, 0x97, 0xec, 0x37, 0x23, 0xc6, 0x54, 0xcf, 0xdd, 0x32, 0xab, 0x07, 0x55, 0x06, 0x64, 0x8b, 0x2f, 0xf5, 0x07, 0x03, 0x62, 0xd0, 0x1a, 0x4f, 0xff, 0x14, 0xb3, 0x36, 0xb7, 0x8f, 0x96, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0xab, 0x1e, 0x95}, SECP256K1_FE_CONST(0xba5a6314, 0x502a8952, 0xb8f456e0, 0x85928105, 0xf665377a, 0x8ce27726, 0xa5b0eb7e, 0xc1ac0286), 0},
-    {{0x47, 0xeb, 0x3e, 0x20, 0x8f, 0xed, 0xcd, 0xf8, 0x23, 0x4c, 0x94, 0x21, 0xe9, 0xcd, 0x9a, 0x7a, 0xe8, 0x73, 0xbf, 0xbd, 0xbc, 0x39, 0x37, 0x23, 0xd1, 0xba, 0x1e, 0x1e, 0x6a, 0x8e, 0x6b, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0xd1, 0x2c, 0xb1}, SECP256K1_FE_CONST(0xd192d520, 0x07e541c9, 0x807006ed, 0x0468df77, 0xfd214af0, 0xa795fe11, 0x9359666f, 0xdcf08f7c), 0},
-    {{0x5e, 0xb9, 0x69, 0x6a, 0x23, 0x36, 0xfe, 0x2c, 0x3c, 0x66, 0x6b, 0x02, 0xc7, 0x55, 0xdb, 0x4c, 0x0c, 0xfd, 0x62, 0x82, 0x5c, 0x7b, 0x58, 0x9a, 0x7b, 0x7b, 0xb4, 0x42, 0xe1, 0x41, 0xc1, 0xd6, 0x93, 0x41, 0x3f, 0x00, 0x52, 0xd4, 0x9e, 0x64, 0xab, 0xec, 0x6d, 0x58, 0x31, 0xd6, 0x6c, 0x43, 0x61, 0x28, 0x30, 0xa1, 0x7d, 0xf1, 0xfe, 0x43, 0x83, 0xdb, 0x89, 0x64, 0x68, 0x10, 0x02, 0x21}, SECP256K1_FE_CONST(0xef6e1da6, 0xd6c7627e, 0x80f7a723, 0x4cb08a02, 0x2c1ee1cf, 0x29e4d0f9, 0x642ae924, 0xcef9eb38), 1},
-    {{0x7b, 0xf9, 0x6b, 0x7b, 0x6d, 0xa1, 0x5d, 0x34, 0x76, 0xa2, 0xb1, 0x95, 0x93, 0x4b, 0x69, 0x0a, 0x3a, 0x3d, 0xe3, 0xe8, 0xab, 0x84, 0x74, 0x85, 0x68, 0x63, 0xb0, 0xde, 0x3a, 0xf9, 0x0b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x50851dfc, 0x9f418c31, 0x4a437295, 0xb24feeea, 0x27af3d0c, 0xd2308348, 0xfda6e21c, 0x463e46ff), 0},
-    {{0x7b, 0xf9, 0x6b, 0x7b, 0x6d, 0xa1, 0x5d, 0x34, 0x76, 0xa2, 0xb1, 0x95, 0x93, 0x4b, 0x69, 0x0a, 0x3a, 0x3d, 0xe3, 0xe8, 0xab, 0x84, 0x74, 0x85, 0x68, 0x63, 0xb0, 0xde, 0x3a, 0xf9, 0x0b, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x50851dfc, 0x9f418c31, 0x4a437295, 0xb24feeea, 0x27af3d0c, 0xd2308348, 0xfda6e21c, 0x463e46ff), 0},
-    {{0x85, 0x1b, 0x1c, 0xa9, 0x45, 0x49, 0x37, 0x1c, 0x4f, 0x1f, 0x71, 0x87, 0x32, 0x1d, 0x39, 0xbf, 0x51, 0xc6, 0xb7, 0xfb, 0x61, 0xf7, 0xcb, 0xf0, 0x27, 0xc9, 0xda, 0x62, 0x02, 0x1b, 0x7a, 0x65, 0xfc, 0x54, 0xc9, 0x68, 0x37, 0xfb, 0x22, 0xb3, 0x62, 0xed, 0xa6, 0x3e, 0xc5, 0x2e, 0xc8, 0x3d, 0x81, 0xbe, 0xdd, 0x16, 0x0c, 0x11, 0xb2, 0x2d, 0x96, 0x5d, 0x9f, 0x4a, 0x6d, 0x64, 0xd2, 0x51}, SECP256K1_FE_CONST(0x3e731051, 0xe12d3323, 0x7eb324f2, 0xaa5b16bb, 0x868eb49a, 0x1aa1fadc, 0x19b6e876, 0x1b5a5f7b), 1},
-    {{0x94, 0x3c, 0x2f, 0x77, 0x51, 0x08, 0xb7, 0x37, 0xfe, 0x65, 0xa9, 0x53, 0x1e, 0x19, 0xf2, 0xfc, 0x2a, 0x19, 0x7f, 0x56, 0x03, 0xe3, 0xa2, 0x88, 0x1d, 0x1d, 0x83, 0xe4, 0x00, 0x8f, 0x91, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x311c61f0, 0xab2f32b7, 0xb1f0223f, 0xa72f0a78, 0x752b8146, 0xe46107f8, 0x876dd9c4, 0xf92b2942), 0},
-    {{0x94, 0x3c, 0x2f, 0x77, 0x51, 0x08, 0xb7, 0x37, 0xfe, 0x65, 0xa9, 0x53, 0x1e, 0x19, 0xf2, 0xfc, 0x2a, 0x19, 0x7f, 0x56, 0x03, 0xe3, 0xa2, 0x88, 0x1d, 0x1d, 0x83, 0xe4, 0x00, 0x8f, 0x91, 0x25, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x311c61f0, 0xab2f32b7, 0xb1f0223f, 0xa72f0a78, 0x752b8146, 0xe46107f8, 0x876dd9c4, 0xf92b2942), 0},
-    {{0xa0, 0xf1, 0x84, 0x92, 0x18, 0x3e, 0x61, 0xe8, 0x06, 0x3e, 0x57, 0x36, 0x06, 0x59, 0x14, 0x21, 0xb0, 0x6b, 0xc3, 0x51, 0x36, 0x31, 0x57, 0x8a, 0x73, 0xa3, 0x9c, 0x1c, 0x33, 0x06, 0x23, 0x9f, 0x2f, 0x32, 0x90, 0x4f, 0x0d, 0x2a, 0x33, 0xec, 0xca, 0x8a, 0x54, 0x51, 0x70, 0x5b, 0xb5, 0x37, 0xd3, 0xbf, 0x44, 0xe0, 0x71, 0x22, 0x60, 0x25, 0xcd, 0xbf, 0xd2, 0x49, 0xfe, 0x0f, 0x7a, 0xd6}, SECP256K1_FE_CONST(0x97a09cf1, 0xa2eae7c4, 0x94df3c6f, 0x8a9445bf, 0xb8c09d60, 0x832f9b0b, 0x9d5eabe2, 0x5fbd14b9), 0},
-    {{0xa1, 0xed, 0x0a, 0x0b, 0xd7, 0x9d, 0x8a, 0x23, 0xcf, 0xe4, 0xec, 0x5f, 0xef, 0x5b, 0xa5, 0xcc, 0xcf, 0xd8, 0x44, 0xe4, 0xff, 0x5c, 0xb4, 0xb0, 0xf2, 0xe7, 0x16, 0x27, 0x34, 0x1f, 0x1c, 0x5b, 0x17, 0xc4, 0x99, 0x24, 0x9e, 0x0a, 0xc0, 0x8d, 0x5d, 0x11, 0xea, 0x1c, 0x2c, 0x8c, 0xa7, 0x00, 0x16, 0x16, 0x55, 0x9a, 0x79, 0x94, 0xea, 0xde, 0xc9, 0xca, 0x10, 0xfb, 0x4b, 0x85, 0x16, 0xdc}, SECP256K1_FE_CONST(0x65a89640, 0x744192cd, 0xac64b2d2, 0x1ddf989c, 0xdac75007, 0x25b645be, 0xf8e2200a, 0xe39691f2), 0},
-    {{0xba, 0x94, 0x59, 0x4a, 0x43, 0x27, 0x21, 0xaa, 0x35, 0x80, 0xb8, 0x4c, 0x16, 0x1d, 0x0d, 0x13, 0x4b, 0xc3, 0x54, 0xb6, 0x90, 0x40, 0x4d, 0x7c, 0xd4, 0xec, 0x57, 0xc1, 0x6d, 0x3f, 0xbe, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0x50, 0x7d, 0xd7}, SECP256K1_FE_CONST(0x5e0d7656, 0x4aae92cb, 0x347e01a6, 0x2afd389a, 0x9aa401c7, 0x6c8dd227, 0x543dc9cd, 0x0efe685a), 0},
-    {{0xbc, 0xaf, 0x72, 0x19, 0xf2, 0xf6, 0xfb, 0xf5, 0x5f, 0xe5, 0xe0, 0x62, 0xdc, 0xe0, 0xe4, 0x8c, 0x18, 0xf6, 0x81, 0x03, 0xf1, 0x0b, 0x81, 0x98, 0xe9, 0x74, 0xc1, 0x84, 0x75, 0x0e, 0x1b, 0xe3, 0x93, 0x20, 0x16, 0xcb, 0xf6, 0x9c, 0x44, 0x71, 0xbd, 0x1f, 0x65, 0x6c, 0x6a, 0x10, 0x7f, 0x19, 0x73, 0xde, 0x4a, 0xf7, 0x08, 0x6d, 0xb8, 0x97, 0x27, 0x70, 0x60, 0xe2, 0x56, 0x77, 0xf1, 0x9a}, SECP256K1_FE_CONST(0x2d97f96c, 0xac882dfe, 0x73dc44db, 0x6ce0f1d3, 0x1d624135, 0x8dd5d74e, 0xb3d3b500, 0x03d24c2b), 0},
-    {{0xbc, 0xaf, 0x72, 0x19, 0xf2, 0xf6, 0xfb, 0xf5, 0x5f, 0xe5, 0xe0, 0x62, 0xdc, 0xe0, 0xe4, 0x8c, 0x18, 0xf6, 0x81, 0x03, 0xf1, 0x0b, 0x81, 0x98, 0xe9, 0x74, 0xc1, 0x84, 0x75, 0x0e, 0x1b, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x65, 0x07, 0xd0, 0x9a}, SECP256K1_FE_CONST(0xe7008afe, 0x6e8cbd50, 0x55df120b, 0xd748757c, 0x686dadb4, 0x1cce75e4, 0xaddcc5e0, 0x2ec02b44), 1},
-    {{0xc5, 0x98, 0x1b, 0xae, 0x27, 0xfd, 0x84, 0x40, 0x1c, 0x72, 0xa1, 0x55, 0xe5, 0x70, 0x7f, 0xbb, 0x81, 0x1b, 0x2b, 0x62, 0x06, 0x45, 0xd1, 0x02, 0x8e, 0xa2, 0x70, 0xcb, 0xe0, 0xee, 0x22, 0x5d, 0x4b, 0x62, 0xaa, 0x4d, 0xca, 0x65, 0x06, 0xc1, 0xac, 0xdb, 0xec, 0xc0, 0x55, 0x25, 0x69, 0xb4, 0xb2, 0x14, 0x36, 0xa5, 0x69, 0x2e, 0x25, 0xd9, 0x0d, 0x3b, 0xc2, 0xeb, 0x7c, 0xe2, 0x40, 0x78}, SECP256K1_FE_CONST(0x948b40e7, 0x181713bc, 0x018ec170, 0x2d3d054d, 0x15746c59, 0xa7020730, 0xdd13ecf9, 0x85a010d7), 0},
-    {{0xc8, 0x94, 0xce, 0x48, 0xbf, 0xec, 0x43, 0x30, 0x14, 0xb9, 0x31, 0xa6, 0xad, 0x42, 0x26, 0xd7, 0xdb, 0xd8, 0xea, 0xa7, 0xb6, 0xe3, 0xfa, 0xa8, 0xd0, 0xef, 0x94, 0x05, 0x2b, 0xcf, 0x8c, 0xff, 0x33, 0x6e, 0xeb, 0x39, 0x19, 0xe2, 0xb4, 0xef, 0xb7, 0x46, 0xc7, 0xf7, 0x1b, 0xbc, 0xa7, 0xe9, 0x38, 0x32, 0x30, 0xfb, 0xbc, 0x48, 0xff, 0xaf, 0xe7, 0x7e, 0x8b, 0xcc, 0x69, 0x54, 0x24, 0x71}, SECP256K1_FE_CONST(0xf1c91acd, 0xc2525330, 0xf9b53158, 0x434a4d43, 0xa1c547cf, 0xf29f1550, 0x6f5da4eb, 0x4fe8fa5a), 1},
-    {{0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x872d81ed, 0x8831d999, 0x8b67cb71, 0x05243edb, 0xf86c10ed, 0xfebb786c, 0x110b02d0, 0x7b2e67cd), 0},
-    {{0xd9, 0x17, 0xb7, 0x86, 0xda, 0xc3, 0x56, 0x70, 0xc3, 0x30, 0xc9, 0xc5, 0xae, 0x59, 0x71, 0xdf, 0xb4, 0x95, 0xc8, 0xae, 0x52, 0x3e, 0xd9, 0x7e, 0xe2, 0x42, 0x01, 0x17, 0xb1, 0x71, 0xf4, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x01, 0xf6, 0xf6}, SECP256K1_FE_CONST(0xe45b71e1, 0x10b831f2, 0xbdad8651, 0x994526e5, 0x8393fde4, 0x328b1ec0, 0x4d598971, 0x42584691), 1},
-    {{0xe2, 0x8b, 0xd8, 0xf5, 0x92, 0x9b, 0x46, 0x7e, 0xb7, 0x0e, 0x04, 0x33, 0x23, 0x74, 0xff, 0xb7, 0xe7, 0x18, 0x02, 0x18, 0xad, 0x16, 0xea, 0xa4, 0x6b, 0x71, 0x61, 0xaa, 0x67, 0x9e, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x66b8c980, 0xa75c72e5, 0x98d383a3, 0x5a62879f, 0x844242ad, 0x1e73ff12, 0xedaa59f4, 0xe58632b5), 0},
-    {{0xe2, 0x8b, 0xd8, 0xf5, 0x92, 0x9b, 0x46, 0x7e, 0xb7, 0x0e, 0x04, 0x33, 0x23, 0x74, 0xff, 0xb7, 0xe7, 0x18, 0x02, 0x18, 0xad, 0x16, 0xea, 0xa4, 0x6b, 0x71, 0x61, 0xaa, 0x67, 0x9e, 0xb4, 0x26, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x66b8c980, 0xa75c72e5, 0x98d383a3, 0x5a62879f, 0x844242ad, 0x1e73ff12, 0xedaa59f4, 0xe58632b5), 0},
-    {{0xe7, 0xee, 0x58, 0x14, 0xc1, 0x70, 0x6b, 0xf8, 0xa8, 0x93, 0x96, 0xa9, 0xb0, 0x32, 0xbc, 0x01, 0x4c, 0x2c, 0xac, 0x9c, 0x12, 0x11, 0x27, 0xdb, 0xf6, 0xc9, 0x92, 0x78, 0xf8, 0xbb, 0x53, 0xd1, 0xdf, 0xd0, 0x4d, 0xbc, 0xda, 0x8e, 0x35, 0x24, 0x66, 0xb6, 0xfc, 0xd5, 0xf2, 0xde, 0xa3, 0xe1, 0x7d, 0x5e, 0x13, 0x31, 0x15, 0x88, 0x6e, 0xda, 0x20, 0xdb, 0x8a, 0x12, 0xb5, 0x4d, 0xe7, 0x1b}, SECP256K1_FE_CONST(0xe842c6e3, 0x529b2342, 0x70a5e977, 0x44edc34a, 0x04d7ba94, 0xe44b6d25, 0x23c9cf01, 0x95730a50), 1},
-    {{0xf2, 0x92, 0xe4, 0x68, 0x25, 0xf9, 0x22, 0x5a, 0xd2, 0x3d, 0xc0, 0x57, 0xc1, 0xd9, 0x1c, 0x4f, 0x57, 0xfc, 0xb1, 0x38, 0x6f, 0x29, 0xef, 0x10, 0x48, 0x1c, 0xb1, 0xd2, 0x25, 0x18, 0x59, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x11, 0xc9, 0x89}, SECP256K1_FE_CONST(0x3cea2c53, 0xb8b01701, 0x66ac7da6, 0x7194694a, 0xdacc84d5, 0x6389225e, 0x330134da, 0xb85a4d55), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x01, 0xd3, 0x47, 0x5b, 0xf7, 0x65, 0x5b, 0x0f, 0xb2, 0xd8, 0x52, 0x92, 0x10, 0x35, 0xb2, 0xef, 0x60, 0x7f, 0x49, 0x06, 0x9b, 0x97, 0x45, 0x4e, 0x67, 0x95, 0x25, 0x10, 0x62, 0x74, 0x17, 0x71}, SECP256K1_FE_CONST(0xb5da00b7, 0x3cd65605, 0x20e7c364, 0x086e7cd2, 0x3a34bf60, 0xd0e707be, 0x9fc34d4c, 0xd5fdfa2c), 1},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee}, SECP256K1_FE_CONST(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaa9, 0xfffffd6b), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x82, 0x27, 0x7c, 0x4a, 0x71, 0xf9, 0xd2, 0x2e, 0x66, 0xec, 0xe5, 0x23, 0xf8, 0xfa, 0x08, 0x74, 0x1a, 0x7c, 0x09, 0x12, 0xc6, 0x6a, 0x69, 0xce, 0x68, 0x51, 0x4b, 0xfd, 0x35, 0x15, 0xb4, 0x9f}, SECP256K1_FE_CONST(0xf482f2e2, 0x41753ad0, 0xfb89150d, 0x8491dc1e, 0x34ff0b8a, 0xcfbb442c, 0xfe999e2e, 0x5e6fd1d2), 1},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x84, 0x21, 0xcc, 0x93, 0x0e, 0x77, 0xc9, 0xf5, 0x14, 0xb6, 0x91, 0x5c, 0x3d, 0xbe, 0x2a, 0x94, 0xc6, 0xd8, 0xf6, 0x90, 0xb5, 0xb7, 0x39, 0x86, 0x4b, 0xa6, 0x78, 0x9f, 0xb8, 0xa5, 0x5d, 0xd0}, SECP256K1_FE_CONST(0x9f59c402, 0x75f5085a, 0x006f05da, 0xe77eb98c, 0x6fd0db1a, 0xb4a72ac4, 0x7eae90a4, 0xfc9e57e0), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xd1, 0x9c, 0x18, 0x2d, 0x27, 0x59, 0xcd, 0x99, 0x82, 0x42, 0x28, 0xd9, 0x47, 0x99, 0xf8, 0xc6, 0x55, 0x7c, 0x38, 0xa1, 0xc0, 0xd6, 0x77, 0x9b, 0x9d, 0x4b, 0x72, 0x9c, 0x6f, 0x1c, 0xcc, 0x42}, SECP256K1_FE_CONST(0x70720db7, 0xe238d041, 0x21f5b1af, 0xd8cc5ad9, 0xd18944c6, 0xbdc94881, 0xf502b7a3, 0xaf3aecff), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x64, 0xbb, 0xd5}, SECP256K1_FE_CONST(0x50873db3, 0x1badcc71, 0x890e4f67, 0x753a6575, 0x7f97aaa7, 0xdd5f1e82, 0xb753ace3, 0x2219064b), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x28, 0xde, 0x7d}, SECP256K1_FE_CONST(0x1eea9cc5, 0x9cfcf2fa, 0x151ac6c2, 0x74eea411, 0x0feb4f7b, 0x68c59657, 0x32e9992e, 0x976ef68e), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xcf, 0xb7, 0xe7}, SECP256K1_FE_CONST(0x12303941, 0xaedc2088, 0x80735b1f, 0x1795c8e5, 0x5be520ea, 0x93e10335, 0x7b5d2adb, 0x7ed59b8e), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x11, 0x3a, 0xd9}, SECP256K1_FE_CONST(0x7eed6b70, 0xe7b0767c, 0x7d7feac0, 0x4e57aa2a, 0x12fef5e0, 0xf48f878f, 0xcbb88b3b, 0x6b5e0783), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xce, 0xa4, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x64998443, 0x5b62b4a2, 0x5d40c613, 0x3e8d9ab8, 0xc53d4b05, 0x9ee8a154, 0xa3be0fcf, 0x4e892edb), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xce, 0xa4, 0xa7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x64998443, 0x5b62b4a2, 0x5d40c613, 0x3e8d9ab8, 0xc53d4b05, 0x9ee8a154, 0xa3be0fcf, 0x4e892edb), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x02, 0x8c, 0x59, 0x00, 0x63, 0xf6, 0x4d, 0x5a, 0x7f, 0x1c, 0x14, 0x91, 0x5c, 0xd6, 0x1e, 0xac, 0x88, 0x6a, 0xb2, 0x95, 0xbe, 0xbd, 0x91, 0x99, 0x25, 0x04, 0xcf, 0x77, 0xed, 0xb0, 0x28, 0xbd, 0xd6, 0x26, 0x7f}, SECP256K1_FE_CONST(0x3fde5713, 0xf8282eea, 0xd7d39d42, 0x01f44a7c, 0x85a5ac8a, 0x0681f35e, 0x54085c6b, 0x69543374), 1},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x27, 0x15, 0xde, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x3524f77f, 0xa3a6eb43, 0x89c3cb5d, 0x27f1f914, 0x62086429, 0xcd6c0cb0, 0xdf43ea8f, 0x1e7b3fb4), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x27, 0x15, 0xde, 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x3524f77f, 0xa3a6eb43, 0x89c3cb5d, 0x27f1f914, 0x62086429, 0xcd6c0cb0, 0xdf43ea8f, 0x1e7b3fb4), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x2c, 0x57, 0x09, 0xe7, 0x15, 0x6c, 0x41, 0x77, 0x17, 0xf2, 0xfe, 0xab, 0x14, 0x71, 0x41, 0xec, 0x3d, 0xa1, 0x9f, 0xb7, 0x59, 0x57, 0x5c, 0xc6, 0xe3, 0x7b, 0x2e, 0xa5, 0xac, 0x93, 0x09, 0xf2, 0x6f, 0x0f, 0x66}, SECP256K1_FE_CONST(0xd2469ab3, 0xe04acbb2, 0x1c65a180, 0x9f39caaf, 0xe7a77c13, 0xd10f9dd3, 0x8f391c01, 0xdc499c52), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3a, 0x08, 0xcc, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x60, 0xe9, 0xf0}, SECP256K1_FE_CONST(0x38e2a5ce, 0x6a93e795, 0xe16d2c39, 0x8bc99f03, 0x69202ce2, 0x1e8f09d5, 0x6777b40f, 0xc512bccc), 1},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x91, 0x25, 0x7d, 0x93, 0x20, 0x16, 0xcb, 0xf6, 0x9c, 0x44, 0x71, 0xbd, 0x1f, 0x65, 0x6c, 0x6a, 0x10, 0x7f, 0x19, 0x73, 0xde, 0x4a, 0xf7, 0x08, 0x6d, 0xb8, 0x97, 0x27, 0x70, 0x60, 0xe2, 0x56, 0x77, 0xf1, 0x9a}, SECP256K1_FE_CONST(0x864b3dc9, 0x02c37670, 0x9c10a93a, 0xd4bbe29f, 0xce0012f3, 0xdc8672c6, 0x286bba28, 0xd7d6d6fc), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x79, 0x5d, 0x6c, 0x1c, 0x32, 0x2c, 0xad, 0xf5, 0x99, 0xdb, 0xb8, 0x64, 0x81, 0x52, 0x2b, 0x3c, 0xc5, 0x5f, 0x15, 0xa6, 0x79, 0x32, 0xdb, 0x2a, 0xfa, 0x01, 0x11, 0xd9, 0xed, 0x69, 0x81, 0xbc, 0xd1, 0x24, 0xbf, 0x44}, SECP256K1_FE_CONST(0x766dfe4a, 0x700d9bee, 0x288b903a, 0xd58870e3, 0xd4fe2f0e, 0xf780bcac, 0x5c823f32, 0x0d9a9bef), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x42, 0x6f, 0x03, 0x92, 0x38, 0x90, 0x78, 0xc1, 0x2b, 0x1a, 0x89, 0xe9, 0x54, 0x2f, 0x05, 0x93, 0xbc, 0x96, 0xb6, 0xbf, 0xde, 0x82, 0x24, 0xf8, 0x65, 0x4e, 0xf5, 0xd5, 0xcd, 0xa9, 0x35, 0xa3, 0x58, 0x21, 0x94}, SECP256K1_FE_CONST(0xfaec7bc1, 0x987b6323, 0x3fbc5f95, 0x6edbf37d, 0x54404e74, 0x61c58ab8, 0x631bc68e, 0x451a0478), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x91, 0x19, 0x21, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x45, 0xf0, 0xf1, 0xeb}, SECP256K1_FE_CONST(0xec29a50b, 0xae138dbf, 0x7d8e2482, 0x5006bb5f, 0xc1a2cc12, 0x43ba335b, 0xc6116fb9, 0xe498ec1f), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xeb, 0x9a, 0xb7, 0x6e, 0x84, 0x49, 0x9c, 0x48, 0x3b, 0x3b, 0xf0, 0x62, 0x14, 0xab, 0xfe, 0x06, 0x5d, 0xdd, 0xf4, 0x3b, 0x86, 0x01, 0xde, 0x59, 0x6d, 0x63, 0xb9, 0xe4, 0x5a, 0x16, 0x6a, 0x58, 0x05, 0x41, 0xfe}, SECP256K1_FE_CONST(0x1e0ff2de, 0xe9b09b13, 0x6292a9e9, 0x10f0d6ac, 0x3e552a64, 0x4bba39e6, 0x4e9dd3e3, 0xbbd3d4d4), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9b, 0x77, 0xb7, 0xf2, 0xc7, 0x4d, 0x99, 0xef, 0xce, 0xaa, 0x55, 0x0f, 0x1a, 0xd1, 0xc0, 0xf4, 0x3f, 0x46, 0xe7, 0xff, 0x1e, 0xe3, 0xbd, 0x01, 0x62, 0xb7, 0xbf, 0x55, 0xf2, 0x96, 0x5d, 0xa9, 0xc3, 0x45, 0x06, 0x46}, SECP256K1_FE_CONST(0x8b7dd5c3, 0xedba9ee9, 0x7b70eff4, 0x38f22dca, 0x9849c825, 0x4a2f3345, 0xa0a572ff, 0xeaae0928), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9b, 0x77, 0xb7, 0xf2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x6c, 0xa8, 0x96}, SECP256K1_FE_CONST(0x0881950c, 0x8f51d6b9, 0xa6387465, 0xd5f12609, 0xef1bb254, 0x12a08a74, 0xcb2dfb20, 0x0c74bfbf), 1},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa2, 0xf5, 0xcd, 0x83, 0x88, 0x16, 0xc1, 0x6c, 0x4f, 0xe8, 0xa1, 0x66, 0x1d, 0x60, 0x6f, 0xdb, 0x13, 0xcf, 0x9a, 0xf0, 0x4b, 0x97, 0x9a, 0x2e, 0x15, 0x9a, 0x09, 0x40, 0x9e, 0xbc, 0x86, 0x45, 0xd5, 0x8f, 0xde, 0x02}, SECP256K1_FE_CONST(0x2f083207, 0xb9fd9b55, 0x0063c31c, 0xd62b8746, 0xbd543bdc, 0x5bbf10e3, 0xa35563e9, 0x27f440c8), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x3f, 0x75, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x4f51e0be, 0x078e0cdd, 0xab274215, 0x6adba7e7, 0xa148e731, 0x57072fd6, 0x18cd6094, 0x2b146bd0), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x3f, 0x75, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x4f51e0be, 0x078e0cdd, 0xab274215, 0x6adba7e7, 0xa148e731, 0x57072fd6, 0x18cd6094, 0x2b146bd0), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xbc, 0x1f, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SECP256K1_FE_CONST(0x16c2ccb5, 0x4352ff4b, 0xd794f6ef, 0xd613c721, 0x97ab7082, 0xda5b563b, 0xdf9cb3ed, 0xaafe74c2), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xbc, 0x1f, 0x8d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}, SECP256K1_FE_CONST(0x16c2ccb5, 0x4352ff4b, 0xd794f6ef, 0xd613c721, 0x97ab7082, 0xda5b563b, 0xdf9cb3ed, 0xaafe74c2), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x64, 0xd1, 0x62, 0x75, 0x05, 0x46, 0xce, 0x42, 0xb0, 0x43, 0x13, 0x61, 0xe5, 0x2d, 0x4f, 0x52, 0x42, 0xd8, 0xf2, 0x4f, 0x33, 0xe6, 0xb1, 0xf9, 0x9b, 0x59, 0x16, 0x47, 0xcb, 0xc8, 0x08, 0xf4, 0x62, 0xaf, 0x51}, SECP256K1_FE_CONST(0xd41244d1, 0x1ca4f652, 0x40687759, 0xf95ca9ef, 0xbab767ed, 0xedb38fd1, 0x8c36e18c, 0xd3b6f6a9), 1},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe5, 0xbe, 0x52, 0x37, 0x2d, 0xd6, 0xe8, 0x94, 0xb2, 0xa3, 0x26, 0xfc, 0x36, 0x05, 0xa6, 0xe8, 0xf3, 0xc6, 0x9c, 0x71, 0x0b, 0xf2, 0x7d, 0x63, 0x0d, 0xfe, 0x20, 0x04, 0x98, 0x8b, 0x78, 0xeb, 0x6e, 0xab, 0x36}, SECP256K1_FE_CONST(0x64bf84dd, 0x5e03670f, 0xdb24c0f5, 0xd3c2c365, 0x736f51db, 0x6c92d950, 0x10716ad2, 0xd36134c8), 0},
-    {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfb, 0xb9, 0x82, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xd6, 0xdb, 0x1f}, SECP256K1_FE_CONST(0x1c92ccdf, 0xcf4ac550, 0xc28db57c, 0xff0c8515, 0xcb26936c, 0x786584a7, 0x0114008d, 0x6c33a34b), 0},
-};
-
-/* Set of expected ellswift_xdh BIP324 shared secrets, given private key, encodings, initiating,
- * taken from the BIP324 test vectors. Created using an independent implementation, and tested
- * against the paper authors' decoding code. */
-static const struct ellswift_xdh_test ellswift_xdh_tests_bip324[] = {
-    {{0x61, 0x06, 0x2e, 0xa5, 0x07, 0x1d, 0x80, 0x0b, 0xbf, 0xd5, 0x9e, 0x2e, 0x8b, 0x53, 0xd4, 0x7d, 0x19, 0x4b, 0x09, 0x5a, 0xe5, 0xa4, 0xdf, 0x04, 0x93, 0x6b, 0x49, 0x77, 0x2e, 0xf0, 0xd4, 0xd7}, {0xec, 0x0a, 0xdf, 0xf2, 0x57, 0xbb, 0xfe, 0x50, 0x0c, 0x18, 0x8c, 0x80, 0xb4, 0xfd, 0xd6, 0x40, 0xf6, 0xb4, 0x5a, 0x48, 0x2b, 0xbc, 0x15, 0xfc, 0x7c, 0xef, 0x59, 0x31, 0xde, 0xff, 0x0a, 0xa1, 0x86, 0xf6, 0xeb, 0x9b, 0xba, 0x7b, 0x85, 0xdc, 0x4d, 0xcc, 0x28, 0xb2, 0x87, 0x22, 0xde, 0x1e, 0x3d, 0x91, 0x08, 0xb9, 0x85, 0xe2, 0x96, 0x70, 0x45, 0x66, 0x8f, 0x66, 0x09, 0x8e, 0x47, 0x5b}, {0xa4, 0xa9, 0x4d, 0xfc, 0xe6, 0x9b, 0x4a, 0x2a, 0x0a, 0x09, 0x93, 0x13, 0xd1, 0x0f, 0x9f, 0x7e, 0x7d, 0x64, 0x9d, 0x60, 0x50, 0x1c, 0x9e, 0x1d, 0x27, 0x4c, 0x30, 0x0e, 0x0d, 0x89, 0xaa, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xaf, 0x88, 0xd5}, 1, {0xc6, 0x99, 0x2a, 0x11, 0x7f, 0x5e, 0xdb, 0xea, 0x70, 0xc3, 0xf5, 0x11, 0xd3, 0x2d, 0x26, 0xb9, 0x79, 0x8b, 0xe4, 0xb8, 0x1a, 0x62, 0xea, 0xee, 0x1a, 0x5a, 0xca, 0xa8, 0x45, 0x9a, 0x35, 0x92}},
-    {{0x1f, 0x9c, 0x58, 0x1b, 0x35, 0x23, 0x18, 0x38, 0xf0, 0xf1, 0x7c, 0xf0, 0xc9, 0x79, 0x83, 0x5b, 0xac, 0xcb, 0x7f, 0x3a, 0xbb, 0xbb, 0x96, 0xff, 0xcc, 0x31, 0x8a, 0xb7, 0x1e, 0x6e, 0x12, 0x6f}, {0xa1, 0x85, 0x5e, 0x10, 0xe9, 0x4e, 0x00, 0xba, 0xa2, 0x30, 0x41, 0xd9, 0x16, 0xe2, 0x59, 0xf7, 0x04, 0x4e, 0x49, 0x1d, 0xa6, 0x17, 0x12, 0x69, 0x69, 0x47, 0x63, 0xf0, 0x18, 0xc7, 0xe6, 0x36, 0x93, 0xd2, 0x95, 0x75, 0xdc, 0xb4, 0x64, 0xac, 0x81, 0x6b, 0xaa, 0x1b, 0xe3, 0x53, 0xba, 0x12, 0xe3, 0x87, 0x6c, 0xba, 0x76, 0x28, 0xbd, 0x0b, 0xd8, 0xe7, 0x55, 0xe7, 0x21, 0xeb, 0x01, 0x40}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0, {0xa0, 0x13, 0x8f, 0x56, 0x4f, 0x74, 0xd0, 0xad, 0x70, 0xbc, 0x33, 0x7d, 0xac, 0xc9, 0xd0, 0xbf, 0x1d, 0x23, 0x49, 0x36, 0x4c, 0xaf, 0x11, 0x88, 0xa1, 0xe6, 0xe8, 0xdd, 0xb3, 0xb7, 0xb1, 0x84}},
-    {{0x02, 0x86, 0xc4, 0x1c, 0xd3, 0x09, 0x13, 0xdb, 0x0f, 0xdf, 0xf7, 0xa6, 0x4e, 0xbd, 0xa5, 0xc8, 0xe3, 0xe7, 0xce, 0xf1, 0x0f, 0x2a, 0xeb, 0xc0, 0x0a, 0x76, 0x50, 0x44, 0x3c, 0xf4, 0xc6, 0x0d}, {0xd1, 0xee, 0x8a, 0x93, 0xa0, 0x11, 0x30, 0xcb, 0xf2, 0x99, 0x24, 0x9a, 0x25, 0x8f, 0x94, 0xfe, 0xb5, 0xf4, 0x69, 0xe7, 0xd0, 0xf2, 0xf2, 0x8f, 0x69, 0xee, 0x5e, 0x9a, 0xa8, 0xf9, 0xb5, 0x4a, 0x60, 0xf2, 0xc3, 0xff, 0x2d, 0x02, 0x36, 0x34, 0xec, 0x7f, 0x41, 0x27, 0xa9, 0x6c, 0xc1, 0x16, 0x62, 0xe4, 0x02, 0x89, 0x4c, 0xf1, 0xf6, 0x94, 0xfb, 0x9a, 0x7e, 0xaa, 0x5f, 0x1d, 0x92, 0x44}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, 0xd5, 0xe4, 0x41, 0x52, 0x4d, 0x57, 0x1a, 0x52, 0xb3, 0xde, 0xf1, 0x26, 0x18, 0x9d, 0x3f, 0x41, 0x68, 0x90, 0xa9, 0x9d, 0x4d, 0xa6, 0xed, 0xe2, 0xb0, 0xcd, 0xe1, 0x76, 0x0c, 0xe2, 0xc3, 0xf9, 0x84, 0x57, 0xae}, 1, {0x25, 0x0b, 0x93, 0x57, 0x0d, 0x41, 0x11, 0x49, 0x10, 0x5a, 0xb8, 0xcb, 0x0b, 0xc5, 0x07, 0x99, 0x14, 0x90, 0x63, 0x06, 0x36, 0x8c, 0x23, 0xe9, 0xd7, 0x7c, 0x2a, 0x33, 0x26, 0x5b, 0x99, 0x4c}},
-    {{0x6c, 0x77, 0x43, 0x2d, 0x1f, 0xda, 0x31, 0xe9, 0xf9, 0x42, 0xf8, 0xaf, 0x44, 0x60, 0x7e, 0x10, 0xf3, 0xad, 0x38, 0xa6, 0x5f, 0x8a, 0x4b, 0xdd, 0xae, 0x82, 0x3e, 0x5e, 0xff, 0x90, 0xdc, 0x38}, {0xd2, 0x68, 0x50, 0x70, 0xc1, 0xe6, 0x37, 0x6e, 0x63, 0x3e, 0x82, 0x52, 0x96, 0x63, 0x4f, 0xd4, 0x61, 0xfa, 0x9e, 0x5b, 0xdf, 0x21, 0x09, 0xbc, 0xeb, 0xd7, 0x35, 0xe5, 0xa9, 0x1f, 0x3e, 0x58, 0x7c, 0x5c, 0xb7, 0x82, 0xab, 0xb7, 0x97, 0xfb, 0xf6, 0xbb, 0x50, 0x74, 0xfd, 0x15, 0x42, 0xa4, 0x74, 0xf2, 0xa4, 0x5b, 0x67, 0x37, 0x63, 0xec, 0x2d, 0xb7, 0xfb, 0x99, 0xb7, 0x37, 0xbb, 0xb9}, {0x56, 0xbd, 0x0c, 0x06, 0xf1, 0x03, 0x52, 0xc3, 0xa1, 0xa9, 0xf4, 0xb4, 0xc9, 0x2f, 0x6f, 0xa2, 0xb2, 0x6d, 0xf1, 0x24, 0xb5, 0x78, 0x78, 0x35, 0x3c, 0x1f, 0xc6, 0x91, 0xc5, 0x1a, 0xbe, 0xa7, 0x7c, 0x88, 0x17, 0xda, 0xee, 0xb9, 0xfa, 0x54, 0x6b, 0x77, 0xc8, 0xda, 0xf7, 0x9d, 0x89, 0xb2, 0x2b, 0x0e, 0x1b, 0x87, 0x57, 0x4e, 0xce, 0x42, 0x37, 0x1f, 0x00, 0x23, 0x7a, 0xa9, 0xd8, 0x3a}, 0, {0x19, 0x18, 0xb7, 0x41, 0xef, 0x5f, 0x9d, 0x1d, 0x76, 0x70, 0xb0, 0x50, 0xc1, 0x52, 0xb4, 0xa4, 0xea, 0xd2, 0xc3, 0x1b, 0xe9, 0xae, 0xcb, 0x06, 0x81, 0xc0, 0xcd, 0x43, 0x24, 0x15, 0x08, 0x53}},
-    {{0xa6, 0xec, 0x25, 0x12, 0x7c, 0xa1, 0xaa, 0x4c, 0xf1, 0x6b, 0x20, 0x08, 0x4b, 0xa1, 0xe6, 0x51, 0x6b, 0xaa, 0xe4, 0xd3, 0x24, 0x22, 0x28, 0x8e, 0x9b, 0x36, 0xd8, 0xbd, 0xdd, 0x2d, 0xe3, 0x5a}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x3d, 0x7e, 0xcc, 0xa5, 0x3e, 0x33, 0xe1, 0x85, 0xa8, 0xb9, 0xbe, 0x4e, 0x76, 0x99, 0xa9, 0x7c, 0x6f, 0xf4, 0xc7, 0x95, 0x52, 0x2e, 0x59, 0x18, 0xab, 0x7c, 0xd6, 0xb6, 0x88, 0x4f, 0x67, 0xe6, 0x83, 0xf3, 0xdc}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, 0x73, 0x0b, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 1, {0xdd, 0x21, 0x0a, 0xa6, 0x62, 0x9f, 0x20, 0xbb, 0x32, 0x8e, 0x5d, 0x89, 0xda, 0xa6, 0xeb, 0x2a, 0xc3, 0xd1, 0xc6, 0x58, 0xa7, 0x25, 0x53, 0x6f, 0xf1, 0x54, 0xf3, 0x1b, 0x53, 0x6c, 0x23, 0xb2}},
-    {{0x0a, 0xf9, 0x52, 0x65, 0x9e, 0xd7, 0x6f, 0x80, 0xf5, 0x85, 0x96, 0x6b, 0x95, 0xab, 0x6e, 0x6f, 0xd6, 0x86, 0x54, 0x67, 0x28, 0x27, 0x87, 0x86, 0x84, 0xc8, 0xb5, 0x47, 0xb1, 0xb9, 0x4f, 0x5a}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x10, 0x17, 0xfd, 0x92, 0xfd, 0x31, 0x63, 0x7c, 0x26, 0xc9, 0x06, 0xb4, 0x20, 0x92, 0xe1, 0x1c, 0xc0, 0xd3, 0xaf, 0xae, 0x8d, 0x90, 0x19, 0xd2, 0x57, 0x8a, 0xf2, 0x27, 0x35, 0xce, 0x7b, 0xc4, 0x69, 0xc7, 0x2d}, {0x96, 0x52, 0xd7, 0x8b, 0xae, 0xfc, 0x02, 0x8c, 0xd3, 0x7a, 0x6a, 0x92, 0x62, 0x5b, 0x8b, 0x8f, 0x85, 0xfd, 0xe1, 0xe4, 0xc9, 0x44, 0xad, 0x3f, 0x20, 0xe1, 0x98, 0xbe, 0xf8, 0xc0, 0x2f, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xe9, 0x18, 0x70}, 0, {0x35, 0x68, 0xf2, 0xae, 0xa2, 0xe1, 0x4e, 0xf4, 0xee, 0x4a, 0x3c, 0x2a, 0x8b, 0x8d, 0x31, 0xbc, 0x5e, 0x31, 0x87, 0xba, 0x86, 0xdb, 0x10, 0x73, 0x9b, 0x4f, 0xf8, 0xec, 0x92, 0xff, 0x66, 0x55}},
-    {{0xf9, 0x0e, 0x08, 0x0c, 0x64, 0xb0, 0x58, 0x24, 0xc5, 0xa2, 0x4b, 0x25, 0x01, 0xd5, 0xae, 0xaf, 0x08, 0xaf, 0x38, 0x72, 0xee, 0x86, 0x0a, 0xa8, 0x0b, 0xdc, 0xd4, 0x30, 0xf7, 0xb6, 0x34, 0x94}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x51, 0x73, 0x76, 0x5d, 0xc2, 0x02, 0xcf, 0x02, 0x9a, 0xd3, 0xf1, 0x54, 0x79, 0x73, 0x5d, 0x57, 0x69, 0x7a, 0xf1, 0x2b, 0x01, 0x31, 0xdd, 0x21, 0x43, 0x0d, 0x57, 0x72, 0xe4, 0xef, 0x11, 0x47, 0x4d, 0x58, 0xb9}, {0x12, 0xa5, 0x0f, 0x3f, 0xaf, 0xea, 0x7c, 0x1e, 0xea, 0xda, 0x4c, 0xf8, 0xd3, 0x37, 0x77, 0x70, 0x4b, 0x77, 0x36, 0x14, 0x53, 0xaf, 0xc8, 0x3b, 0xda, 0x91, 0xee, 0xf3, 0x49, 0xae, 0x04, 0x4d, 0x20, 0x12, 0x6c, 0x62, 0x00, 0x54, 0x7e, 0xa5, 0xa6, 0x91, 0x17, 0x76, 0xc0, 0x5d, 0xee, 0x2a, 0x7f, 0x1a, 0x9b, 0xa7, 0xdf, 0xba, 0xbb, 0xbd, 0x27, 0x3c, 0x3e, 0xf2, 0x9e, 0xf4, 0x6e, 0x46}, 1, {0xe2, 0x54, 0x61, 0xfb, 0x0e, 0x4c, 0x16, 0x2e, 0x18, 0x12, 0x3e, 0xcd, 0xe8, 0x83, 0x42, 0xd5, 0x4d, 0x44, 0x96, 0x31, 0xe9, 0xb7, 0x5a, 0x26, 0x6f, 0xd9, 0x26, 0x0c, 0x2b, 0xb2, 0xf4, 0x1d}},
-};
-
-/** This is a hasher for ellswift_xdh which just returns the shared X coordinate.
- *
- * This is generally a bad idea as it means changes to the encoding of the
- * exchanged public keys do not affect the shared secret. However, it's used here
- * in tests to be able to verify the X coordinate through other means.
- */
-static int ellswift_xdh_hash_x32(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) {
-    (void)ell_a64;
-    (void)ell_b64;
-    (void)data;
-    memcpy(output, x32, 32);
-    return 1;
-}
-
-void run_ellswift_tests(void) {
-    int i = 0;
-    /* Test vectors. */
-    for (i = 0; (unsigned)i < sizeof(ellswift_xswiftec_inv_tests) / sizeof(ellswift_xswiftec_inv_tests[0]); ++i) {
-        const struct ellswift_xswiftec_inv_test *testcase = &ellswift_xswiftec_inv_tests[i];
-        int c;
-        for (c = 0; c < 8; ++c) {
-            secp256k1_fe t;
-            int ret = secp256k1_ellswift_xswiftec_inv_var(&t, &testcase->x, &testcase->u, c);
-            CHECK(ret == ((testcase->enc_bitmap >> c) & 1));
-            if (ret) {
-                secp256k1_fe x2;
-                CHECK(check_fe_equal(&t, &testcase->encs[c]));
-                secp256k1_ellswift_xswiftec_var(&x2, &testcase->u, &testcase->encs[c]);
-                CHECK(check_fe_equal(&testcase->x, &x2));
-            }
-        }
-    }
-    for (i = 0; (unsigned)i < sizeof(ellswift_decode_tests) / sizeof(ellswift_decode_tests[0]); ++i) {
-        const struct ellswift_decode_test *testcase = &ellswift_decode_tests[i];
-        secp256k1_pubkey pubkey;
-        secp256k1_ge ge;
-        int ret;
-        ret = secp256k1_ellswift_decode(CTX, &pubkey, testcase->enc);
-        CHECK(ret);
-        ret = secp256k1_pubkey_load(CTX, &ge, &pubkey);
-        CHECK(ret);
-        CHECK(check_fe_equal(&testcase->x, &ge.x));
-        CHECK(secp256k1_fe_is_odd(&ge.y) == testcase->odd_y);
-    }
-    for (i = 0; (unsigned)i < sizeof(ellswift_xdh_tests_bip324) / sizeof(ellswift_xdh_tests_bip324[0]); ++i) {
-        const struct ellswift_xdh_test *test = &ellswift_xdh_tests_bip324[i];
-        unsigned char shared_secret[32];
-        int ret;
-        int party = !test->initiating;
-        const unsigned char* ell_a64 = party ? test->ellswift_theirs : test->ellswift_ours;
-        const unsigned char* ell_b64 = party ? test->ellswift_ours   : test->ellswift_theirs;
-        ret = secp256k1_ellswift_xdh(CTX, shared_secret,
-                                     ell_a64, ell_b64,
-                                     test->priv_ours,
-                                     party,
-                                     secp256k1_ellswift_xdh_hash_function_bip324,
-                                     NULL);
-        CHECK(ret);
-        CHECK(secp256k1_memcmp_var(shared_secret, test->shared_secret, 32) == 0);
-    }
-    /* Verify that secp256k1_ellswift_encode + decode roundtrips. */
-    for (i = 0; i < 1000 * COUNT; i++) {
-        unsigned char rnd32[32];
-        unsigned char ell64[64];
-        secp256k1_ge g, g2;
-        secp256k1_pubkey pubkey, pubkey2;
-        /* Generate random public key and random randomizer. */
-        random_group_element_test(&g);
-        secp256k1_pubkey_save(&pubkey, &g);
-        secp256k1_testrand256(rnd32);
-        /* Convert the public key to ElligatorSwift and back. */
-        secp256k1_ellswift_encode(CTX, ell64, &pubkey, rnd32);
-        secp256k1_ellswift_decode(CTX, &pubkey2, ell64);
-        secp256k1_pubkey_load(CTX, &g2, &pubkey2);
-        /* Compare with original. */
-        ge_equals_ge(&g, &g2);
-    }
-    /* Verify the behavior of secp256k1_ellswift_create */
-    for (i = 0; i < 400 * COUNT; i++) {
-        unsigned char auxrnd32[32], sec32[32];
-        secp256k1_scalar sec;
-        secp256k1_gej res;
-        secp256k1_ge dec;
-        secp256k1_pubkey pub;
-        unsigned char ell64[64];
-        int ret;
-        /* Generate random secret key and random randomizer. */
-        if (i & 1) secp256k1_testrand256_test(auxrnd32);
-        random_scalar_order_test(&sec);
-        secp256k1_scalar_get_b32(sec32, &sec);
-        /* Construct ElligatorSwift-encoded public keys for that key. */
-        ret = secp256k1_ellswift_create(CTX, ell64, sec32, (i & 1) ? auxrnd32 : NULL);
-        CHECK(ret);
-        /* Decode it, and compare with traditionally-computed public key. */
-        secp256k1_ellswift_decode(CTX, &pub, ell64);
-        secp256k1_pubkey_load(CTX, &dec, &pub);
-        secp256k1_ecmult(&res, NULL, &secp256k1_scalar_zero, &sec);
-        ge_equals_gej(&dec, &res);
-    }
-    /* Verify that secp256k1_ellswift_xdh computes the right shared X coordinate. */
-    for (i = 0; i < 800 * COUNT; i++) {
-        unsigned char ell64[64], sec32[32], share32[32];
-        secp256k1_scalar sec;
-        secp256k1_ge dec, res;
-        secp256k1_fe share_x;
-        secp256k1_gej decj, resj;
-        secp256k1_pubkey pub;
-        int ret;
-        /* Generate random secret key. */
-        random_scalar_order_test(&sec);
-        secp256k1_scalar_get_b32(sec32, &sec);
-        /* Generate random ElligatorSwift encoding for the remote key and decode it. */
-        secp256k1_testrand256_test(ell64);
-        secp256k1_testrand256_test(ell64 + 32);
-        secp256k1_ellswift_decode(CTX, &pub, ell64);
-        secp256k1_pubkey_load(CTX, &dec, &pub);
-        secp256k1_gej_set_ge(&decj, &dec);
-        /* Compute the X coordinate of seckey*pubkey using ellswift_xdh. Note that we
-         * pass ell64 as claimed (but incorrect) encoding for sec32 here; this works
-         * because the "hasher" function we use here ignores the ell64 arguments. */
-        ret = secp256k1_ellswift_xdh(CTX, share32, ell64, ell64, sec32, i & 1, &ellswift_xdh_hash_x32, NULL);
-        CHECK(ret);
-        (void)secp256k1_fe_set_b32_limit(&share_x, share32); /* no overflow is possible */
-        secp256k1_fe_verify(&share_x);
-        /* Compute seckey*pubkey directly. */
-        secp256k1_ecmult(&resj, &decj, &sec, NULL);
-        secp256k1_ge_set_gej(&res, &resj);
-        /* Compare. */
-        CHECK(check_fe_equal(&res.x, &share_x));
-    }
-    /* Verify the joint behavior of secp256k1_ellswift_xdh */
-    for (i = 0; i < 200 * COUNT; i++) {
-        unsigned char auxrnd32a[32], auxrnd32b[32], auxrnd32a_bad[32], auxrnd32b_bad[32];
-        unsigned char sec32a[32], sec32b[32], sec32a_bad[32], sec32b_bad[32];
-        secp256k1_scalar seca, secb;
-        unsigned char ell64a[64], ell64b[64], ell64a_bad[64], ell64b_bad[64];
-        unsigned char share32a[32], share32b[32], share32_bad[32];
-        unsigned char prefix64[64];
-        secp256k1_ellswift_xdh_hash_function hash_function;
-        void* data;
-        int ret;
-
-        /* Pick hasher to use. */
-        if ((i % 3) == 0) {
-            hash_function = ellswift_xdh_hash_x32;
-            data = NULL;
-        } else if ((i % 3) == 1) {
-            hash_function = secp256k1_ellswift_xdh_hash_function_bip324;
-            data = NULL;
-        } else {
-            hash_function = secp256k1_ellswift_xdh_hash_function_prefix;
-            secp256k1_testrand256_test(prefix64);
-            secp256k1_testrand256_test(prefix64 + 32);
-            data = prefix64;
-        }
-
-        /* Generate random secret keys and random randomizers. */
-        secp256k1_testrand256_test(auxrnd32a);
-        secp256k1_testrand256_test(auxrnd32b);
-        random_scalar_order_test(&seca);
-        random_scalar_order_test(&secb);
-        secp256k1_scalar_get_b32(sec32a, &seca);
-        secp256k1_scalar_get_b32(sec32b, &secb);
-
-        /* Construct ElligatorSwift-encoded public keys for those keys. */
-        /* For A: */
-        ret = secp256k1_ellswift_create(CTX, ell64a, sec32a, auxrnd32a);
-        CHECK(ret);
-        /* For B: */
-        ret = secp256k1_ellswift_create(CTX, ell64b, sec32b, auxrnd32b);
-        CHECK(ret);
-
-        /* Compute the shared secret both ways and compare with each other. */
-        /* For A: */
-        ret = secp256k1_ellswift_xdh(CTX, share32a, ell64a, ell64b, sec32a, 0, hash_function, data);
-        CHECK(ret);
-        /* For B: */
-        ret = secp256k1_ellswift_xdh(CTX, share32b, ell64a, ell64b, sec32b, 1, hash_function, data);
-        CHECK(ret);
-        /* And compare: */
-        CHECK(secp256k1_memcmp_var(share32a, share32b, 32) == 0);
-
-        /* Verify that the shared secret doesn't match if other side's public key is incorrect. */
-        /* For A (using a bad public key for B): */
-        memcpy(ell64b_bad, ell64b, sizeof(ell64a_bad));
-        secp256k1_testrand_flip(ell64b_bad, sizeof(ell64b_bad));
-        ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b_bad, sec32a, 0, hash_function, data);
-        CHECK(ret); /* Mismatching encodings don't get detected by secp256k1_ellswift_xdh. */
-        CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0);
-        /* For B (using a bad public key for A): */
-        memcpy(ell64a_bad, ell64a, sizeof(ell64a_bad));
-        secp256k1_testrand_flip(ell64a_bad, sizeof(ell64a_bad));
-        ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a_bad, ell64b, sec32b, 1, hash_function, data);
-        CHECK(ret);
-        CHECK(secp256k1_memcmp_var(share32_bad, share32b, 32) != 0);
-
-        /* Verify that the shared secret doesn't match if the private key is incorrect. */
-        /* For A: */
-        memcpy(sec32a_bad, sec32a, sizeof(sec32a_bad));
-        secp256k1_testrand_flip(sec32a_bad, sizeof(sec32a_bad));
-        ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32a_bad, 0, hash_function, data);
-        CHECK(!ret || secp256k1_memcmp_var(share32_bad, share32a, 32) != 0);
-        /* For B: */
-        memcpy(sec32b_bad, sec32b, sizeof(sec32b_bad));
-        secp256k1_testrand_flip(sec32b_bad, sizeof(sec32b_bad));
-        ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32b_bad, 1, hash_function, data);
-        CHECK(!ret || secp256k1_memcmp_var(share32_bad, share32b, 32) != 0);
-
-        if (hash_function != ellswift_xdh_hash_x32) {
-            /* Verify that the shared secret doesn't match when a different encoding of the same public key is used. */
-            /* For A (changing B's public key): */
-            memcpy(auxrnd32b_bad, auxrnd32b, sizeof(auxrnd32b_bad));
-            secp256k1_testrand_flip(auxrnd32b_bad, sizeof(auxrnd32b_bad));
-            ret = secp256k1_ellswift_create(CTX, ell64b_bad, sec32b, auxrnd32b_bad);
-            CHECK(ret);
-            ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b_bad, sec32a, 0, hash_function, data);
-            CHECK(ret);
-            CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0);
-            /* For B (changing A's public key): */
-            memcpy(auxrnd32a_bad, auxrnd32a, sizeof(auxrnd32a_bad));
-            secp256k1_testrand_flip(auxrnd32a_bad, sizeof(auxrnd32a_bad));
-            ret = secp256k1_ellswift_create(CTX, ell64a_bad, sec32a, auxrnd32a_bad);
-            CHECK(ret);
-            ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a_bad, ell64b, sec32b, 1, hash_function, data);
-            CHECK(ret);
-            CHECK(secp256k1_memcmp_var(share32_bad, share32b, 32) != 0);
-
-            /* Verify that swapping sides changes the shared secret. */
-            /* For A (claiming to be B): */
-            ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32a, 1, hash_function, data);
-            CHECK(ret);
-            CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0);
-            /* For B (claiming to be A): */
-            ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32b, 0, hash_function, data);
-            CHECK(ret);
-            CHECK(secp256k1_memcmp_var(share32_bad, share32b, 32) != 0);
-        }
-    }
-
-    /* Test hash initializers. */
-    {
-        secp256k1_sha256 sha, sha_optimized;
-        static const unsigned char encode_tag[25] = "secp256k1_ellswift_encode";
-        static const unsigned char create_tag[25] = "secp256k1_ellswift_create";
-        static const unsigned char bip324_tag[26] = "bip324_ellswift_xonly_ecdh";
-
-        /* Check that hash initialized by
-         * secp256k1_ellswift_sha256_init_encode has the expected
-         * state. */
-        secp256k1_sha256_initialize_tagged(&sha, encode_tag, sizeof(encode_tag));
-        secp256k1_ellswift_sha256_init_encode(&sha_optimized);
-        test_sha256_eq(&sha, &sha_optimized);
-
-        /* Check that hash initialized by
-         * secp256k1_ellswift_sha256_init_create has the expected
-         * state. */
-        secp256k1_sha256_initialize_tagged(&sha, create_tag, sizeof(create_tag));
-        secp256k1_ellswift_sha256_init_create(&sha_optimized);
-        test_sha256_eq(&sha, &sha_optimized);
-
-        /* Check that hash initialized by
-         * secp256k1_ellswift_sha256_init_bip324 has the expected
-         * state. */
-        secp256k1_sha256_initialize_tagged(&sha, bip324_tag, sizeof(bip324_tag));
-        secp256k1_ellswift_sha256_init_bip324(&sha_optimized);
-        test_sha256_eq(&sha, &sha_optimized);
-    }
-}
-
-#endif
diff --git a/src/modules/schnorrsig/tests_impl.h b/src/modules/schnorrsig/tests_impl.h
index 90337ff..ddcb8a5 100644
--- a/src/modules/schnorrsig/tests_impl.h
+++ b/src/modules/schnorrsig/tests_impl.h
@@ -20,6 +20,17 @@ static void nonce_function_bip340_bitflip(unsigned char **args, size_t n_flip, s
     CHECK(secp256k1_memcmp_var(nonces[0], nonces[1], 32) != 0);
 }
 
+/* Tests for the equality of two sha256 structs. This function only produces a
+ * correct result if an integer multiple of 64 many bytes have been written
+ * into the hash functions. */
+static void test_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2) {
+    /* Is buffer fully consumed? */
+    CHECK((sha1->bytes & 0x3F) == 0);
+
+    CHECK(sha1->bytes == sha2->bytes);
+    CHECK(secp256k1_memcmp_var(sha1->s, sha2->s, sizeof(sha1->s)) == 0);
+}
+
 static void run_nonce_function_bip340_tests(void) {
     unsigned char tag[13] = "BIP0340/nonce";
     unsigned char aux_tag[11] = "BIP0340/aux";
diff --git a/src/tests.c b/src/tests.c
index 7b38d79..ca5a314 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -89,6 +89,16 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) {
     (*p)--;
 }
 
+static void random_field_element_test(secp256k1_fe *fe) {
+    do {
+        unsigned char b32[32];
+        secp256k1_testrand256_test(b32);
+        if (secp256k1_fe_set_b32_limit(fe, b32)) {
+            break;
+        }
+    } while(1);
+}
+
 static void random_field_element_magnitude(secp256k1_fe *fe) {
     secp256k1_fe zero;
     int n = secp256k1_testrand_int(9);
@@ -98,33 +108,17 @@ static void random_field_element_magnitude(secp256k1_fe *fe) {
     }
     secp256k1_fe_clear(&zero);
     secp256k1_fe_negate(&zero, &zero, 0);
-    secp256k1_fe_mul_int_unchecked(&zero, n - 1);
+    secp256k1_fe_mul_int(&zero, n - 1);
     secp256k1_fe_add(fe, &zero);
 #ifdef VERIFY
     CHECK(fe->magnitude == n);
 #endif
 }
 
-static void random_fe_test(secp256k1_fe *x) {
-    unsigned char bin[32];
-    do {
-        secp256k1_testrand256_test(bin);
-        if (secp256k1_fe_set_b32_limit(x, bin)) {
-            return;
-        }
-    } while(1);
-}
-
-static void random_fe_non_zero_test(secp256k1_fe *fe) {
-    do {
-        random_fe_test(fe);
-    } while(secp256k1_fe_is_zero(fe));
-}
-
 static void random_group_element_test(secp256k1_ge *ge) {
     secp256k1_fe fe;
     do {
-        random_fe_test(&fe);
+        random_field_element_test(&fe);
         if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_testrand_bits(1))) {
             secp256k1_fe_normalize(&ge->y);
             break;
@@ -135,7 +129,12 @@ static void random_group_element_test(secp256k1_ge *ge) {
 
 static void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) {
     secp256k1_fe z2, z3;
-    random_fe_non_zero_test(&gej->z);
+    do {
+        random_field_element_test(&gej->z);
+        if (!secp256k1_fe_is_zero(&gej->z)) {
+            break;
+        }
+    } while(1);
     secp256k1_fe_sqr(&z2, &gej->z);
     secp256k1_fe_mul(&z3, &z2, &gej->z);
     secp256k1_fe_mul(&gej->x, &ge->x, &z2);
@@ -698,17 +697,6 @@ static void run_sha256_counter_tests(void) {
     }
 }
 
-/* Tests for the equality of two sha256 structs. This function only produces a
- * correct result if an integer multiple of 64 many bytes have been written
- * into the hash functions. This function is used by some module tests. */
-static void test_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2) {
-    /* Is buffer fully consumed? */
-    CHECK((sha1->bytes & 0x3F) == 0);
-
-    CHECK(sha1->bytes == sha2->bytes);
-    CHECK(secp256k1_memcmp_var(sha1->s, sha2->s, sizeof(sha1->s)) == 0);
-}
-
 static 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",
@@ -2985,6 +2973,16 @@ static void random_fe(secp256k1_fe *x) {
     } while(1);
 }
 
+static void random_fe_test(secp256k1_fe *x) {
+    unsigned char bin[32];
+    do {
+        secp256k1_testrand256_test(bin);
+        if (secp256k1_fe_set_b32_limit(x, bin)) {
+            return;
+        }
+    } while(1);
+}
+
 static void random_fe_non_zero(secp256k1_fe *nz) {
     int tries = 10;
     while (--tries >= 0) {
@@ -3225,7 +3223,7 @@ static void run_field_misc(void) {
         CHECK(q.normalized && q.magnitude == 1);
 #endif
         for (j = 0; j < 6; j++) {
-            secp256k1_fe_negate_unchecked(&z, &z, j+1);
+            secp256k1_fe_negate(&z, &z, j+1);
             secp256k1_fe_normalize_var(&q);
             secp256k1_fe_cmov(&q, &z, (j&1));
 #ifdef VERIFY
@@ -3777,7 +3775,7 @@ static void test_ge(void) {
      */
     secp256k1_ge *ge = (secp256k1_ge *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_ge) * (1 + 4 * runs));
     secp256k1_gej *gej = (secp256k1_gej *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_gej) * (1 + 4 * runs));
-    secp256k1_fe zf, r;
+    secp256k1_fe zf;
     secp256k1_fe zfi2, zfi3;
 
     secp256k1_gej_set_infinity(&gej[0]);
@@ -3811,15 +3809,14 @@ static void test_ge(void) {
     }
 
     /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */
-    random_fe_non_zero_test(&zf);
+    do {
+        random_field_element_test(&zf);
+    } while(secp256k1_fe_is_zero(&zf));
     random_field_element_magnitude(&zf);
     secp256k1_fe_inv_var(&zfi3, &zf);
     secp256k1_fe_sqr(&zfi2, &zfi3);
     secp256k1_fe_mul(&zfi3, &zfi3, &zfi2);
 
-    /* Generate random r */
-    random_fe_non_zero_test(&r);
-
     for (i1 = 0; i1 < 1 + 4 * runs; i1++) {
         int i2;
         for (i2 = 0; i2 < 1 + 4 * runs; i2++) {
@@ -3932,29 +3929,6 @@ static void test_ge(void) {
         free(ge_set_all);
     }
 
-    /* Test that all elements have X coordinates on the curve. */
-    for (i = 1; i < 4 * runs + 1; i++) {
-        secp256k1_fe n;
-        CHECK(secp256k1_ge_x_on_curve_var(&ge[i].x));
-        /* And the same holds after random rescaling. */
-        secp256k1_fe_mul(&n, &zf, &ge[i].x);
-        CHECK(secp256k1_ge_x_frac_on_curve_var(&n, &zf));
-    }
-
-    /* Test correspondence of secp256k1_ge_x{,_frac}_on_curve_var with ge_set_xo. */
-    {
-        secp256k1_fe n;
-        secp256k1_ge q;
-        int ret_on_curve, ret_frac_on_curve, ret_set_xo;
-        secp256k1_fe_mul(&n, &zf, &r);
-        ret_on_curve = secp256k1_ge_x_on_curve_var(&r);
-        ret_frac_on_curve = secp256k1_ge_x_frac_on_curve_var(&n, &zf);
-        ret_set_xo = secp256k1_ge_set_xo_var(&q, &r, 0);
-        CHECK(ret_on_curve == ret_frac_on_curve);
-        CHECK(ret_on_curve == ret_set_xo);
-        if (ret_set_xo) CHECK(secp256k1_fe_equal_var(&r, &q.x));
-    }
-
     /* Test batch gej -> ge conversion with many infinities. */
     for (i = 0; i < 4 * runs + 1; i++) {
         int odd;
@@ -4035,22 +4009,15 @@ static void test_add_neg_y_diff_x(void) {
      * which this test is a regression test for.
      *
      * These points were generated in sage as
-     * # secp256k1 params
-     * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
-     * C = EllipticCurve ([F (0), F (7)])
-     * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
-     * N = FiniteField(G.order())
      *
-     * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F)
-     * x = polygen(N)
-     * lam  = (1 - x^3).roots()[1][0]
+     * load("secp256k1_params.sage")
      *
      * # random "bad pair"
      * P = C.random_element()
-     * Q = -int(lam) * P
-     * print "    P: %x %x" % P.xy()
-     * print "    Q: %x %x" % Q.xy()
-     * print "P + Q: %x %x" % (P + Q).xy()
+     * Q = -int(LAMBDA) * P
+     * print("    P: %x %x" % P.xy())
+     * print("    Q: %x %x" % Q.xy())
+     * print("P + Q: %x %x" % (P + Q).xy())
      */
     secp256k1_gej aj = SECP256K1_GEJ_CONST(
         0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30,
@@ -4135,7 +4102,10 @@ static void run_gej(void) {
         CHECK(!secp256k1_gej_eq_var(&a, &b));
 
         b = a;
-        random_fe_non_zero_test(&fe);
+        random_field_element_test(&fe);
+        if (secp256k1_fe_is_zero(&fe)) {
+            continue;
+        }
         secp256k1_gej_rescale(&a, &fe);
         CHECK(secp256k1_gej_eq_var(&a, &b));
     }
@@ -4574,7 +4544,9 @@ static void ecmult_const_mult_xonly(void) {
         random_scalar_order_test(&q);
         /* If i is odd, n=d*base.x for random non-zero d */
         if (i & 1) {
-            random_fe_non_zero_test(&d);
+            do {
+                random_field_element_test(&d);
+            } while (secp256k1_fe_normalizes_to_zero_var(&d));
             secp256k1_fe_mul(&n, &base.x, &d);
         } else {
             n = base.x;
@@ -4593,17 +4565,22 @@ static void ecmult_const_mult_xonly(void) {
 
     /* Test that secp256k1_ecmult_const_xonly correctly rejects X coordinates not on curve. */
     for (i = 0; i < 2*COUNT; ++i) {
-        secp256k1_fe x, n, d, r;
+        secp256k1_fe x, n, d, c, r;
         int res;
         secp256k1_scalar q;
         random_scalar_order_test(&q);
         /* Generate random X coordinate not on the curve. */
         do {
-            random_fe_test(&x);
-        } while (secp256k1_ge_x_on_curve_var(&x));
+            random_field_element_test(&x);
+            secp256k1_fe_sqr(&c, &x);
+            secp256k1_fe_mul(&c, &c, &x);
+            secp256k1_fe_add_int(&c, SECP256K1_B);
+        } while (secp256k1_fe_is_square_var(&c));
         /* If i is odd, n=d*x for random non-zero d. */
         if (i & 1) {
-            random_fe_non_zero_test(&d);
+            do {
+                random_field_element_test(&d);
+            } while (secp256k1_fe_normalizes_to_zero_var(&d));
             secp256k1_fe_mul(&n, &x, &d);
         } else {
             n = x;
@@ -7516,10 +7493,6 @@ static void run_ecdsa_wycheproof(void) {
 # include "modules/schnorrsig/tests_impl.h"
 #endif
 
-#ifdef ENABLE_MODULE_ELLSWIFT
-# include "modules/ellswift/tests_impl.h"
-#endif
-
 static void run_secp256k1_memczero_test(void) {
     unsigned char buf1[6] = {1, 2, 3, 4, 5, 6};
     unsigned char buf2[sizeof(buf1)];
@@ -7536,31 +7509,16 @@ static void run_secp256k1_memczero_test(void) {
 }
 
 static 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_;
+    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);
+    secp256k1_write_be32(buf, x);
+    CHECK(secp256k1_memcmp_var(buf, x_be, sizeof(buf)) == 0);
 
-        x_ = secp256k1_read_be32(buf);
-        CHECK(x == x_);
-    }
-
-    {
-        const uint64_t x = 0xCAFE0123BEEF4567;
-        const unsigned char x_be[8] = {0xCA, 0xFE, 0x01, 0x23, 0xBE, 0xEF, 0x45, 0x67};
-        unsigned char buf[8];
-        uint64_t x_;
-
-        secp256k1_write_be64(buf, x);
-        CHECK(secp256k1_memcmp_var(buf, x_be, sizeof(buf)) == 0);
-
-        x_ = secp256k1_read_be64(buf);
-        CHECK(x == x_);
-    }
+    x_ = secp256k1_read_be32(buf);
+    CHECK(x == x_);
 }
 
 static void int_cmov_test(void) {
@@ -7867,10 +7825,6 @@ int main(int argc, char **argv) {
     run_schnorrsig_tests();
 #endif
 
-#ifdef ENABLE_MODULE_ELLSWIFT
-    run_ellswift_tests();
-#endif
-
     /* util tests */
     run_secp256k1_memczero_test();
     run_secp256k1_byteorder_tests();
diff --git a/src/tests_exhaustive.c b/src/tests_exhaustive.c
index dbb6b7e..d35acdd 100644
--- a/src/tests_exhaustive.c
+++ b/src/tests_exhaustive.c
@@ -13,9 +13,6 @@
 #define EXHAUSTIVE_TEST_ORDER 13
 #endif
 
-/* These values of B are all values in [1, 8] that result in a curve with even order. */
-#define EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER (SECP256K1_B == 1 || SECP256K1_B == 6 || SECP256K1_B == 8)
-
 #ifdef USE_EXTERNAL_DEFAULT_CALLBACKS
     #pragma message("Ignoring USE_EXTERNAL_CALLBACKS in exhaustive_tests.")
     #undef USE_EXTERNAL_DEFAULT_CALLBACKS
@@ -398,10 +395,6 @@ static void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_g
 #include "modules/schnorrsig/tests_exhaustive_impl.h"
 #endif
 
-#ifdef ENABLE_MODULE_ELLSWIFT
-#include "modules/ellswift/tests_exhaustive_impl.h"
-#endif
-
 int main(int argc, char** argv) {
     int i;
     secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER];
@@ -497,15 +490,6 @@ int main(int argc, char** argv) {
 #ifdef ENABLE_MODULE_SCHNORRSIG
         test_exhaustive_schnorrsig(ctx);
 #endif
-#ifdef ENABLE_MODULE_ELLSWIFT
-    /* The ellswift algorithm does have additional edge cases when operating on
-     * curves of even order, which are not included in the code as secp256k1 is
-     * of odd order. Skip the ellswift tests if the used exhaustive tests curve
-     * is even-ordered accordingly. */
-    #if !EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER
-        test_exhaustive_ellswift(ctx, group);
-    #endif
-#endif
 
         secp256k1_context_destroy(ctx);
     }