From a5b1ba52c64615d4d92d29c24140059d9afc152c Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Fri, 1 Sep 2023 17:52:17 -0400 Subject: [PATCH 1/6] configure.ac: use AX_SUBDIRS_CONFIGURE; don't alter ac_configure_args Altering ac_configure_args to configure libsecp256k1 with options differing from those of libwally-core causes issues if the wally Makefile is out of date and needs to call autoreconf etc to regenerate itself. The secp arguments are passed back to the top level configure which changes and possibly breaks the original configuration. Instead, import and use AX_SUBDIRS_CONFIGURE from the autoconf-archive which supports sub-confiration with bespoke arguments. Because autoreconf does not recurse into subdirectories named by AX_SUBDIRS_CONFIGURE, we lose the automagic Autotools (re)generation in src/secp256k1, so add an explicit call to src/secp256k1/autogen.sh in tools/autogen.sh. --- configure.ac | 3 +- setup.py | 24 +- tools/autogen.sh | 4 + tools/build-aux/m4/ax_subdirs_configure.m4 | 334 +++++++++++++++++++++ 4 files changed, 351 insertions(+), 14 deletions(-) create mode 100644 tools/build-aux/m4/ax_subdirs_configure.m4 diff --git a/configure.ac b/configure.ac index 8d46dd3a7..dc175143e 100644 --- a/configure.ac +++ b/configure.ac @@ -404,8 +404,7 @@ export ARFLAGS export AR_FLAGS export LD export LDFLAGS -ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-experimental --enable-module-ecdh --enable-module-recovery --enable-module-ecdsa-s2c --enable-module-rangeproof --enable-module-surjectionproof --enable-module-whitelist --enable-module-generator --enable-module-extrakeys --enable-module-schnorrsig ${secp256k1_test_opt} --enable-exhaustive-tests=no --enable-benchmark=no --disable-dependency-tracking ${secp_asm}" -AC_CONFIG_SUBDIRS([src/secp256k1]) +AX_SUBDIRS_CONFIGURE([src/secp256k1], [[--disable-shared], [--enable-static], [--with-pic], [--enable-experimental], [--enable-module-ecdh], [--enable-module-recovery], [--enable-module-ecdsa-s2c], [--enable-module-rangeproof], [--enable-module-surjectionproof], [--enable-module-whitelist], [--enable-module-generator], [--enable-module-extrakeys], [--enable-module-schnorrsig], [$secp256k1_test_opt], [--enable-exhaustive-tests=no], [--enable-benchmark=no], [--disable-dependency-tracking], [$secp_asm]]) AC_OUTPUT diff --git a/setup.py b/setup.py index e403ed81a..c43952df9 100644 --- a/setup.py +++ b/setup.py @@ -3,8 +3,9 @@ import copy, os, platform, shutil import distutils.sysconfig -CONFIGURE_ARGS = '--enable-swig-python --enable-python-manylinux' -CONFIGURE_ARGS += ' --disable-swig-java --disable-tests --disable-dependency-tracking' +CONFIGURE_ARGS = ['--disable-shared', '--enable-static', '--with-pic', + '--enable-swig-python', '--enable-python-manylinux', + '--disable-swig-java', '--disable-tests', '--disable-dependency-tracking'] distutils_env = distutils.sysconfig.get_config_vars() configure_env = copy.deepcopy(os.environ) @@ -26,11 +27,11 @@ if is_x86 and not is_native: # We are cross-compiling or compiling a univeral2 binary. # Configure our source code as a cross compile to make the build work - CONFIGURE_ARGS += ' --host x86_64-apple-darwin' + CONFIGURE_ARGS += ['--host', 'x86_64-apple-darwin'] arch = 'universal2' if len(archs) > 1 else archs[0] - CONFIGURE_ARGS += ' --target {}-apple-macos'.format(arch) + CONFIGURE_ARGS += ['--target', '{}-apple-macos'.format(arch)] if len(archs) > 1: - CONFIGURE_ARGS += ' --with-asm=no' + CONFIGURE_ARGS += ['--with-asm=no'] if 'PY_CFLAGS' in distutils_env: configure_env['CFLAGS'] = distutils_env['PY_CFLAGS'] configure_env['LDFLAGS'] = distutils_env['PY_LDFLAGS'] @@ -40,18 +41,17 @@ # then build using the standard Python ext module machinery. # (Windows requires source generation to be done separately). import multiprocessing - import os import subprocess abs_path = os.path.dirname(os.path.abspath(__file__)) + '/' - def call(cmd): - subprocess.check_call(cmd.split(' '), cwd=abs_path, env=configure_env) + def call(args): + subprocess.check_call(args, cwd=abs_path, env=configure_env) - call('./tools/cleanup.sh') - call('./tools/autogen.sh') - call('./configure {}'.format(CONFIGURE_ARGS)) - call('make -j{}'.format(multiprocessing.cpu_count())) + call(['./tools/cleanup.sh']) + call(['./tools/autogen.sh']) + call(['./configure'] + CONFIGURE_ARGS) + call(['make', '-j{}'.format(multiprocessing.cpu_count())]) define_macros=[ ('SWIG_PYTHON_BUILD', None), diff --git a/tools/autogen.sh b/tools/autogen.sh index f572fe1e5..3942bcc64 100755 --- a/tools/autogen.sh +++ b/tools/autogen.sh @@ -8,3 +8,7 @@ if uname | grep "Darwin" >/dev/null 2>&1; then done done fi + +if [ -x src/secp256k1/autogen.sh ] ; then + cd src/secp256k1 && ./autogen.sh +fi diff --git a/tools/build-aux/m4/ax_subdirs_configure.m4 b/tools/build-aux/m4/ax_subdirs_configure.m4 new file mode 100644 index 000000000..01cb074b3 --- /dev/null +++ b/tools/build-aux/m4/ax_subdirs_configure.m4 @@ -0,0 +1,334 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_subdirs_configure.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_SUBDIRS_CONFIGURE( [subdirs], [mandatory arguments], [possibly merged arguments], [replacement arguments], [forbidden arguments]) +# +# DESCRIPTION +# +# AX_SUBDIRS_CONFIGURE attempts to be the equivalent of AC_CONFIG_SUBDIRS +# with customizable options for configure scripts. +# +# Run the configure script for each directory from the comma-separated m4 +# list 'subdirs'. This macro can be used multiple times. All arguments of +# this macro must be comma-separated lists. +# +# All command line arguments from the parent configure script will be +# given to the subdirectory configure script after the following +# modifications (in that order): +# +# 1. The arguments from the 'mandatory arguments' list shall always be +# appended to the argument list. +# +# 2. The arguments from the 'possibly merged arguments' list shall be +# added if not present in the arguments of the parent configure script or +# merged with the existing argument otherwise. +# +# 3. The arguments from the 'replacement arguments' list shall be added if +# not present in the arguments of the parent configure script or replace +# the existing argument otherwise. +# +# 4. The arguments from the 'forbidden arguments' list shall always be +# removed from the argument list. +# +# The lists 'mandatory arguments' and 'forbidden arguments' can hold any +# kind of argument. The 'possibly merged arguments' and 'replacement +# arguments' expect their arguments to be of the form --option-name=value. +# +# This macro aims to remain as close as possible to the AC_CONFIG_SUBDIRS +# macro. It corrects the paths for '--srcdir' and adds +# '--disable-option-checking' and '--silent' if necessary. However, it +# does not change the '--cache-file' argument: typically, configure +# scripts run with different arguments will not be able to share the same +# cache. If you wish to share a single cache, you should give an absolute +# path to '--cache-file'. +# +# This macro also sets the output variable subdirs_extra to the list of +# directories recorded with AX_SUBDIRS_CONFIGURE. This variable can be +# used in Makefile rules or substituted in configured files. +# +# This macro shall do nothing more than managing the arguments of the +# configure script. Just like when using AC_CONFIG_SUBDIRS, it is up to +# the user to check any requirements or define and substitute any required +# variable for the remainder of the project. +# +# Configure scripts recorded with AX_SUBDIRS_CONFIGURE may be executed +# before configure scripts recorded with AC_CONFIG_SUBDIRS. +# +# Without additional arguments, the behaviour of AX_SUBDIRS_CONFIGURE +# should be identical to the behaviour of AC_CONFIG_SUBDIRS, apart from +# the contents of the variables subdirs and subdirs_extra (except that +# AX_SUBDIRS_CONFIGURE expects a comma-separated m4 list): +# +# AC_CONFIG_SUBDIRS([something]) +# AX_SUBDIRS_CONFIGURE([something]) +# +# This macro may be called multiple times. +# +# Usage example: +# +# Let us assume our project has 4 dependencies, namely A, B, C and D. Here +# are some characteristics of our project and its dependencies: +# +# - A does not require any special option. +# +# - we want to build B with an optional feature which can be enabled with +# its configure script's option '--enable-special-feature'. +# +# - B's configure script is strange and has an option '--with-B=build'. +# After close inspection of its documentation, we don't want B to receive +# this option. +# +# - C and D both need B. +# +# - Just like our project, C and D can build B themselves with the option +# '--with-B=build'. +# +# - We want C and D to use the B we build instead of building it +# themselves. +# +# Our top-level configure script will be called as follows: +# +# $ --with-A=build --with-B=build --with-C=build \ +# --with-D=build --some-option +# +# Thus we have to make sure that: +# +# - neither B, C or D receive the option '--with-B=build' +# +# - C and D know where to find the headers and libraries of B. +# +# Under those conditions, we can use the AC_CONFIG_SUBDIRS macro for A, +# but need to use AX_SUBDIRS_CONFIGURE for B, C and D: +# +# - B must receive '--enable-special-feature' but cannot receive +# '--with-B=build' +# +# - C and D cannot receive '--with-B=build' (or else it would be built +# thrice) and need to be told where to find B (since we are building it, +# it would probably not be available in standard paths). +# +# Here is a configure.ac snippet that solves our problem: +# +# AC_CONFIG_SUBDIRS([dependencies/A]) +# AX_SUBDIRS_CONFIGURE( +# [dependencies/B], [--enable-special-feature], [], [], +# [--with-B=build]) +# AX_SUBDIRS_CONFIGURE( +# [[dependencies/C],[dependencies/D]], +# [], +# [[CPPFLAGS=-I${ac_top_srcdir}/dependencies/B -I${ac_top_builddir}/dependencies/B], +# [LDFLAGS=-L${ac_abs_top_builddir}/dependencies/B/.libs]], +# [--with-B=system], +# []) +# +# If using automake, the following can be added to the Makefile.am (we use +# both $(subdirs) and $(subdirs_extra) since our example above used both +# AC_CONFIG_SUBDIRS and AX_SUBDIRS_CONFIGURE): +# +# SUBDIRS = $(subdirs) $(subdirs_extra) +# +# LICENSE +# +# Copyright (c) 2017 Harenome Ranaivoarivony-Razanajato +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# Under Section 7 of GPL version 3, you are granted additional permissions +# described in the Autoconf Configure Script Exception, version 3.0, as +# published by the Free Software Foundation. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . + +#serial 6 + +AC_DEFUN([AX_SUBDIRS_CONFIGURE], +[ + dnl Calls to AC_CONFIG_SUBDIRS perform preliminary steps and build a list + dnl '$subdirs' which is used later by _AC_OUTPUT_SUBDIRS (used by AC_OUTPUT) + dnl to actually run the configure scripts. + dnl This macro performs similar preliminary steps but uses + dnl AC_CONFIG_COMMANDS_PRE to delay the final tasks instead of building an + dnl intermediary list and relying on another macro. + dnl + dnl Since each configure script can get different options, a special variable + dnl named 'ax_sub_configure_args_' is constructed for each + dnl subdirectory. + + # Various preliminary checks. + AC_REQUIRE([AC_DISABLE_OPTION_CHECKING]) + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) + AS_LITERAL_IF([$1], [], + [AC_DIAGNOSE([syntax], [$0: you should use literals])]) + + m4_foreach(subdir_path, [$1], + [ + ax_dir="subdir_path" + + dnl Build the argument list in a similar fashion to AC_CONFIG_SUBDIRS. + dnl A few arguments found in the final call to the configure script are not + dnl added here because they rely on variables that may not yet be available + dnl (see below the part that is similar to _AC_OUTPUT_SUBDIRS). + # Do not complain, so a configure script can configure whichever parts of a + # large source tree are present. + if test -d "$srcdir/$ax_dir"; then + _AC_SRCDIRS(["$ax_dir"]) + # Remove --cache-file, --srcdir, and --disable-option-checking arguments + # so they do not pile up. + ax_args= + ax_prev= + eval "set x $ac_configure_args" + shift + for ax_arg; do + if test -n "$ax_prev"; then + ax_prev= + continue + fi + case $ax_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi | --cache-f \ + | --cache- | --cache | --cach | --cac | --ca | --c) + ax_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ax_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ax_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* \ + | --p=*) + ;; + --disable-option-checking) + ;; + *) case $ax_arg in + *\'*) ax_arg=$(AS_ECHO(["$ax_arg"]) | sed "s/'/'\\\\\\\\''/g");; + esac + AS_VAR_APPEND([ax_args], [" '$ax_arg'"]) ;; + esac + done + # Always prepend --disable-option-checking to silence warnings, since + # different subdirs can have different --enable and --with options. + ax_args="--disable-option-checking $ax_args" + # Options that must be added as they are provided. + m4_ifnblank([$2], [m4_foreach(opt, [$2], [AS_VAR_APPEND(ax_args, " 'opt'") + ])]) + # New options that may need to be merged with existing options. + m4_ifnblank([$3], [m4_foreach(opt, [$3], + [ax_candidate="opt" + ax_candidate_flag="${ax_candidate%%=*}" + ax_candidate_content="${ax_candidate#*=}" + if test "x$ax_candidate" != "x" -a "x$ax_candidate_flag" != "x"; then + if echo "$ax_args" | grep -- "${ax_candidate_flag}=" >/dev/null 2>&1; then + [ax_args=$(echo $ax_args | sed "s,\(${ax_candidate_flag}=[^']*\),\1 ${ax_candidate_content},")] + else + AS_VAR_APPEND(ax_args, " 'opt'") + fi + fi + ])]) + # New options that must replace existing options. + m4_ifnblank([$4], [m4_foreach(opt, [$4], + [ax_candidate="opt" + ax_candidate_flag="${ax_candidate%%=*}" + ax_candidate_content="${ax_candidate#*=}" + if test "x$ax_candidate" != "x" -a "x$ax_candidate_flag" != "x"; then + if echo "$ax_args" | grep -- "${ax_candidate_flag}=" >/dev/null 2>&1; then + [ax_args=$(echo $ax_args | sed "s,${ax_candidate_flag}=[^']*,${ax_candidate},")] + else + AS_VAR_APPEND(ax_args, " 'opt'") + fi + fi + ])]) + # Options that must be removed. + m4_ifnblank([$5], [m4_foreach(opt, [$5], [ax_args=$(echo $ax_args | sed "s,'opt',,") + ])]) + AS_VAR_APPEND([ax_args], [" '--srcdir=$ac_srcdir'"]) + + # Add the subdirectory to the list of target subdirectories. + ax_subconfigures="$ax_subconfigures $ax_dir" + # Save the argument list for this subdirectory. + dnl $1 is a path to some subdirectory: m4_bpatsubsts() is used to convert + dnl $1 into a valid shell variable name. + dnl For instance, "ax_sub_configure_args_path/to/subdir" becomes + dnl "ax_sub_configure_args_path_to_subdir". + ax_var=$(printf "$ax_dir" | tr -c "0-9a-zA-Z_" "_") + eval "ax_sub_configure_args_$ax_var=\"$ax_args\"" + eval "ax_sub_configure_$ax_var=\"yes\"" + else + AC_MSG_WARN([could not find source tree for $ax_dir]) + fi + + dnl Add some more arguments to the argument list and then actually run the + dnl configure script. This is mostly what happens in _AC_OUTPUT_SUBDIRS + dnl except it does not iterate over an intermediary list. + AC_CONFIG_COMMANDS_PRE( + dnl This very line cannot be quoted! m4_foreach has some work here. + ax_dir="subdir_path" + [ + # Convert the path to the subdirectory into a shell variable name. + ax_var=$(printf "$ax_dir" | tr -c "0-9a-zA-Z_" "_") + ax_configure_ax_var=$(eval "echo \"\$ax_sub_configure_$ax_var\"") + if test "$no_recursion" != "yes" -a "x$ax_configure_ax_var" = "xyes"; then + AC_SUBST([subdirs_extra], ["$subdirs_extra $ax_dir"]) + ax_msg="=== configuring in $ax_dir ($(pwd)/$ax_dir)" + _AS_ECHO_LOG([$ax_msg]) + _AS_ECHO([$ax_msg]) + AS_MKDIR_P(["$ax_dir"]) + _AC_SRCDIRS(["$ax_dir"]) + + ax_popdir=$(pwd) + cd "$ax_dir" + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f "$ac_srcdir/configure.gnu"; then + ax_sub_configure=$ac_srcdir/configure.gnu + elif test -f "$ac_srcdir/configure"; then + ax_sub_configure=$ac_srcdir/configure + elif test -f "$ac_srcdir/configure.in"; then + # This should be Cygnus configure. + ax_sub_configure=$ac_aux_dir/configure + else + AC_MSG_WARN([no configuration information is in $ax_dir]) + ax_sub_configure= + fi + + if test -n "$ax_sub_configure"; then + # Get the configure arguments for the current configure. + eval "ax_sub_configure_args=\"\$ax_sub_configure_args_${ax_var}\"" + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ax_arg="--prefix=$prefix" + case $ax_arg in + *\'*) ax_arg=$(AS_ECHO(["$ax_arg"]) | sed "s/'/'\\\\\\\\''/g");; + esac + ax_sub_configure_args="'$ax_arg' $ax_sub_configure_args" + if test "$silent" = yes; then + ax_sub_configure_args="--silent $ax_sub_configure_args" + fi + + AC_MSG_NOTICE([running $SHELL $ax_sub_configure $ax_sub_configure_args --cache-file=$cache_file]) + eval "\$SHELL \"$ax_sub_configure\" $ax_sub_configure_args --cache-file=\"$cache_file\"" \ + || AC_MSG_ERROR([$ax_sub_configure failed for $ax_dir]) + fi + + cd "$ax_popdir" + fi + ]) + ]) +]) From 62a354211b041b1a75316f62f913548c82fe3e14 Mon Sep 17 00:00:00 2001 From: Jon Griffiths Date: Mon, 4 Sep 2023 14:05:44 +1200 Subject: [PATCH 2/6] secp: use the configured include path for secp headers Extracted from a patch by Matt Whitlock . Also reduce the include directories given for python wheel building. --- configure.ac | 3 +++ setup.py | 4 +--- src/Makefile.am | 6 +++--- src/ecdh.c | 4 ++-- src/elements.c | 8 ++++---- src/internal.h | 8 ++++---- src/sign.c | 2 +- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index dc175143e..165f1eb49 100644 --- a/configure.ac +++ b/configure.ac @@ -259,6 +259,9 @@ fi # # libsecp256k1 # +libsecp256k1_CFLAGS='-I$(top_srcdir)/src/secp256k1/include' +AC_SUBST([libsecp256k1_CFLAGS]) + # FIXME: This is needed to force libtool to use all object files from secp. # We can only build secp properly by recursively invoking # configure/make, and can't include it as a noinst_ library. Libtool diff --git a/setup.py b/setup.py index c43952df9..3f30e1ca2 100644 --- a/setup.py +++ b/setup.py @@ -67,10 +67,8 @@ def call(args): include_dirs=[ './', './src', - './include', './src/ccan', - './src/secp256k1', - './src/secp256k1/src/' + './src/secp256k1/include', ] if is_windows: shutil.copyfile('./src/amalgamation/windows_config/libsecp256k1-config.h', 'src/secp256k1/src/libsecp256k1-config.h') diff --git a/src/Makefile.am b/src/Makefile.am index ed5c23b8f..16bd061b2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,7 @@ if USE_SWIG_PYTHON noinst_LTLIBRARIES += libswig_python.la libswig_python_la_SOURCES = swig_python/swig_python_wrap.c -libswig_python_la_CFLAGS = -I$(top_srcdir) $(AM_CFLAGS) $(SWIG_PYTHON_CPPFLAGS) $(SWIG_WARN_CFLAGS) $(NOALIAS_CFLAGS) +libswig_python_la_CFLAGS = -I$(top_srcdir) $(libsecp256k1_CFLAGS) $(AM_CFLAGS) $(SWIG_PYTHON_CPPFLAGS) $(SWIG_WARN_CFLAGS) $(NOALIAS_CFLAGS) if PYTHON_MANYLINUX else libswig_python_la_LIBADD = $(PYTHON_LIBS) @@ -83,7 +83,7 @@ noinst_LTLIBRARIES += libswig_java.la libswig_java_la_SOURCES = \ swig_java/swig_java_wrap.c -libswig_java_la_CFLAGS = -I$(top_srcdir) $(AM_CFLAGS) $(SWIG_JAVA_CPPFLAGS) $(SWIG_WARN_CFLAGS) +libswig_java_la_CFLAGS = -I$(top_srcdir) $(libsecp256k1_CFLAGS) $(AM_CFLAGS) $(SWIG_JAVA_CPPFLAGS) $(SWIG_WARN_CFLAGS) SWIG_JOPT = $(SWIG_JAVA_OPT) -outdir swig_java -noproxy -package com.blockstream.libwally @@ -207,7 +207,7 @@ libwallycore_la_LDFLAGS += -no-undefined endif endif # SHARED_BUILD_ENABLED -libwallycore_la_CFLAGS = -I$(top_srcdir) -I$(srcdir)/ccan -DWALLY_CORE_BUILD=1 $(AM_CFLAGS) +libwallycore_la_CFLAGS = -I$(top_srcdir) -I$(srcdir)/ccan $(libsecp256k1_CFLAGS) -DWALLY_CORE_BUILD=1 $(AM_CFLAGS) libwallycore_la_LIBADD = $(LIBADD_SECP256K1) $(noinst_LTLIBRARIES) SUBDIRS = secp256k1 diff --git a/src/ecdh.c b/src/ecdh.c index f81e76c74..0130de427 100644 --- a/src/ecdh.c +++ b/src/ecdh.c @@ -1,7 +1,7 @@ #include "internal.h" #include -#include "secp256k1/include/secp256k1.h" -#include "secp256k1/include/secp256k1_ecdh.h" +#include +#include int wally_ecdh(const unsigned char *pub_key, size_t pub_key_len, const unsigned char *priv_key, size_t priv_key_len, diff --git a/src/elements.c b/src/elements.c index 9edb58ca8..cbe39ba1b 100644 --- a/src/elements.c +++ b/src/elements.c @@ -7,10 +7,10 @@ #include #include #include -#include "secp256k1/include/secp256k1_generator.h" -#include "secp256k1/include/secp256k1_rangeproof.h" -#include "src/secp256k1/include/secp256k1_surjectionproof.h" -#include "src/secp256k1/include/secp256k1_whitelist.h" +#include +#include +#include +#include static const unsigned char LABEL_STR[] = { diff --git a/src/internal.h b/src/internal.h index f99087b31..a60307afc 100644 --- a/src/internal.h +++ b/src/internal.h @@ -13,11 +13,11 @@ #pragma GCC diagnostic ignored "-Wunused-parameter" #endif /* BUILD_ELEMENTS */ #endif /* WALLY_ABI_NO_ELEMENTS */ -#include "secp256k1/include/secp256k1.h" -#include "secp256k1/include/secp256k1_recovery.h" -#include "secp256k1/include/secp256k1_extrakeys.h" +#include +#include +#include #ifndef BUILD_STANDARD_SECP -#include "secp256k1/include/secp256k1_ecdsa_s2c.h" +#include #endif #include #if defined(HAVE_MEMSET_S) diff --git a/src/sign.c b/src/sign.c index c76ab4474..f5b929fee 100644 --- a/src/sign.c +++ b/src/sign.c @@ -1,7 +1,7 @@ #include "internal.h" #include #include "script_int.h" -#include "secp256k1/include/secp256k1_schnorrsig.h" +#include #include "ccan/ccan/build_assert/build_assert.h" #define EC_FLAGS_TYPES (EC_FLAG_ECDSA | EC_FLAG_SCHNORR) From bb52971be4a2de7f24127a081694942d227b5bac Mon Sep 17 00:00:00 2001 From: Jon Griffiths Date: Wed, 30 Aug 2023 16:45:05 +1200 Subject: [PATCH 3/6] docs: update for v1.0.0 --- CHANGES.md | 11 +++++++++++ README.md | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 738c98d72..534ab0851 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,16 @@ # Changes +## Version 1.0.0 +- The library now follows semantic versioning as per https://semver.org/. +- Elements support is now enabled by default, reflecting the common library + usage. Please see the `configure --help` entries for `--disable-elements` + and `--disable-elements-abi` for details. +- The ABI of the library is now consistent by default regardless of whether + it is built with or without Elements support. +- Some functions in the c++ header wally.hpp have changed interface slightly. + Note that this header is deprecated and will be replaced in an upcoming + release with higher level wrappers in the same manner as Python and JS. + ## Version 0.9.1 - PSET: When adding an Elements transaction output to a PSET, the nonce commitment was incorrectly mapped to the PSET output blinding key field. diff --git a/README.md b/README.md index c1aa4a3e9..4947f27df 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ for cryptocurrency wallets. Read the API documentation at https://wally.readthedocs.io. -Note that library interfaces may change slightly while the library design matures. Please see the [CHANGES](./CHANGES.md) file to determine if the API has changed when upgrading. +Please see the [CHANGES](./CHANGES.md) for details of ABI changes when upgrading. Please report bugs and submit patches to [Our github repository](https://github.com/ElementsProject/libwally-core). If you wish to report a security issue, please read [Our security reporting guidelines](./SECURITY.md). From 476ac4138d6ef4c4346b8cf94b2c3337f20adb2b Mon Sep 17 00:00:00 2001 From: Jon Griffiths Date: Wed, 30 Aug 2023 16:46:17 +1200 Subject: [PATCH 4/6] Bump version to 1.0.0 --- README.md | 2 +- _CMakeLists.txt | 2 +- configure.ac | 2 +- docs/source/conf.py | 2 +- include/wally_core.h | 8 ++++---- setup.py | 2 +- src/wasm_package/package-lock.json | 4 ++-- src/wasm_package/package.json | 2 +- src/wasm_package/src/const.js | 8 ++++---- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 4947f27df..cb2621aef 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ installed. For non-development use, you can install wally with `pip` as follows: ``` -pip install wallycore==0.9.2 +pip install wallycore==1.0.0 ``` For python development, you can build and install wally using: diff --git a/_CMakeLists.txt b/_CMakeLists.txt index 23a4b7f63..e575b10c2 100644 --- a/_CMakeLists.txt +++ b/_CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20) project( libwallycore - VERSION 0.9.2 + VERSION 1.0.0 DESCRIPTION "A collection of useful primitives for cryptocurrency wallets" LANGUAGES C ) diff --git a/configure.ac b/configure.ac index 165f1eb49..37cf1a973 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.60]) -AC_INIT([libwallycore],[0.9.2]) +AC_INIT([libwallycore],[1.0.0]) AC_CONFIG_AUX_DIR([tools/build-aux]) AC_CONFIG_MACRO_DIR([tools/build-aux/m4]) AC_CONFIG_SRCDIR([src/mnemonic.h]) diff --git a/docs/source/conf.py b/docs/source/conf.py index 61da01509..e5ca68a98 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -167,7 +167,7 @@ def extract_docs(infile, outfile): # built documents. # # The short X.Y version. -version = u'0.9.2' +version = u'1.0.0' # The full version, including alpha/beta/rc tags. release = version diff --git a/include/wally_core.h b/include/wally_core.h index e5d6a958e..328b2417b 100644 --- a/include/wally_core.h +++ b/include/wally_core.h @@ -29,10 +29,10 @@ extern "C" { #define WALLY_ENOMEM -3 /** malloc() failed */ /** Library version */ -#define WALLY_MAJOR_VER 0 -#define WALLY_MINOR_VER 9 -#define WALLY_PATCH_VER 2 -#define WALLY_BUILD_VER 0x902 +#define WALLY_MAJOR_VER 1 +#define WALLY_MINOR_VER 0 +#define WALLY_PATCH_VER 0 +#define WALLY_BUILD_VER 0x10000 /** * Initialize wally. diff --git a/setup.py b/setup.py index 3f30e1ca2..fd073ef8e 100644 --- a/setup.py +++ b/setup.py @@ -91,7 +91,7 @@ def call(args): kwargs = { 'name': 'wallycore', - 'version': '0.9.2', + 'version': '1.0.0', 'description': 'libwally Bitcoin library', 'long_description': 'Python bindings for the libwally Bitcoin library', 'url': 'https://github.com/ElementsProject/libwally-core', diff --git a/src/wasm_package/package-lock.json b/src/wasm_package/package-lock.json index b2352c941..3e0bad7fd 100644 --- a/src/wasm_package/package-lock.json +++ b/src/wasm_package/package-lock.json @@ -1,12 +1,12 @@ { "name": "wallycore", - "version": "0.9.2", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "wallycore", - "version": "0.9.2", + "version": "1.0.0", "license": "(MIT or BSD)", "devDependencies": { "buffer": "^6.0.3", diff --git a/src/wasm_package/package.json b/src/wasm_package/package.json index afc68984a..604d4a23b 100644 --- a/src/wasm_package/package.json +++ b/src/wasm_package/package.json @@ -1,6 +1,6 @@ { "name": "wallycore", - "version": "0.9.2", + "version": "1.0.0", "description": "JavaScript bindings for libwally", "main": "src/index.js", "type": "module", diff --git a/src/wasm_package/src/const.js b/src/wasm_package/src/const.js index 1d65a81fa..0388fa3f4 100755 --- a/src/wasm_package/src/const.js +++ b/src/wasm_package/src/const.js @@ -109,7 +109,7 @@ export const WALLY_ADDRESS_VERSION_WIF_TESTNET = 0xEF; /** Wallet Import Format export const WALLY_BIP32_CHAIN_CODE_LEN = 32; export const WALLY_BIP32_TWEAK_SUM_LEN = 32; export const WALLY_BTC_MAX = 21000000; -export const WALLY_BUILD_VER = 0x902; +export const WALLY_BUILD_VER = 0x10000; export const WALLY_CA_PREFIX_LIQUID = 0x0c; /** Liquid v1 confidential address prefix */ export const WALLY_CA_PREFIX_LIQUID_REGTEST = 0x04; /** Liquid v1 confidential address prefix for regtest */ export const WALLY_CA_PREFIX_LIQUID_TESTNET = 0x17; /** Liquid v1 confidential address prefix for testnet */ @@ -118,14 +118,14 @@ export const WALLY_EINVAL = -2; /** Invalid argument */ export const WALLY_ENOMEM = -3; /** malloc() failed */ export const WALLY_ERROR = -1; /** General error */ export const WALLY_HOST_COMMITMENT_LEN = 32; -export const WALLY_MAJOR_VER = 0; +export const WALLY_MAJOR_VER = 1; export const WALLY_MAX_OP_RETURN_LEN = 80; /* Maximum length of OP_RETURN data push */ export const WALLY_MINISCRIPT_DEPTH_MASK = 0xffff0000; /** Mask for limiting maximum depth */ export const WALLY_MINISCRIPT_DEPTH_SHIFT = 16; /** Shift to convert maximum depth to flags */ export const WALLY_MINISCRIPT_ONLY = 0x02; /** Only allow miniscript (not descriptor) expressions */ export const WALLY_MINISCRIPT_REQUIRE_CHECKSUM = 0x04; /** Require a checksum to be present */ export const WALLY_MINISCRIPT_TAPSCRIPT = 0x01; /** Tapscript, use x-only pubkeys */ -export const WALLY_MINOR_VER = 9; +export const WALLY_MINOR_VER = 0; export const WALLY_MS_CANONICAL_NO_CHECKSUM = 0x01; /** Do not include a checksum */ export const WALLY_MS_IS_DESCRIPTOR = 0x20; /** Contains only descriptor expressions (no miniscript) */ export const WALLY_MS_IS_MULTIPATH = 0x02; /** Allows multiple paths via ```` */ @@ -142,7 +142,7 @@ export const WALLY_NETWORK_LIQUID_TESTNET = 0x05; /** Liquid v1 testnet */ export const WALLY_NETWORK_NONE = 0x00; /** Used for miniscript parsing only */ export const WALLY_NO_CODESEPARATOR = 0xffffffff; /* No BIP342 code separator position */ export const WALLY_OK = 0; /** Success */ -export const WALLY_PATCH_VER = 2; +export const WALLY_PATCH_VER = 0; export const WALLY_PSBT_EXTRACT_NON_FINAL = 0x1; /* Extract without final scriptsig and witness */ export const WALLY_PSBT_FINALIZE_NO_CLEAR = 0x1; /* Finalize without clearing redeem/witness scripts etc */ export const WALLY_PSBT_FLAG_NON_FINAL = 0x1; From e95a6d983d604011015008c0ed15acf48345d4db Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Fri, 1 Sep 2023 23:44:46 -0400 Subject: [PATCH 5/6] clean up linkage of libsecp256k1 into libwallycore and Python extension We have two levels of library embedding: * libsecp256k1.la is linked into libwallycore.la via LIBADD. The FIXME comment in configure.ac contained an assertion that seems to be irrelevant: passing libsecp256k1.la to libtool when linking libwallycore.la indeed does not embed the objects from libsecp256k1.a into libwallycore.a, but it does add a dependency on libsecp256k1.la in libwallycore.la, so any future links against libwallycore.la will automagically pull in libsecp256k1.la. This is exactly the scenario that libtool was conceived to facilitate. Do note one caveat: if both --enable-shared and --enable-static are passed to configure, then libwallycore.la will *not* specify a dependency on libsecp256k1.la, but this is irrelevant since any future links against libwallycore.la will link against libwallycore.so, which *does* contain all of the symbols from libsecp256k1.a, so there is no additional dependency. * libwallycore.la is linked into the Python native extension library. Previously this wasn't really being done at all; rather, all of the libwally-core code was being recompiled into some "combined" objects that would then be linked into the Python extension. This was a needless duplication of work since the compiled objects already exist in libwallycore.a and libsecp256k1.a. Simply link those libraries into the extension. Note that libwally-core does need to be compiled as PIC for this to work, so setup.py passes --with-pic to configure. Additional cleanup: adjust several #include directives to reference libsecp256k1 headers in the configured header search path rather than explicitly specifying paths to the instances beneath src/secp256k1/. --- configure.ac | 23 ++--------------------- setup.py | 9 ++++++--- src/Makefile.am | 2 +- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/configure.ac b/configure.ac index 37cf1a973..9d8bb0749 100644 --- a/configure.ac +++ b/configure.ac @@ -260,28 +260,9 @@ fi # libsecp256k1 # libsecp256k1_CFLAGS='-I$(top_srcdir)/src/secp256k1/include' +libsecp256k1_LIBS='$(top_srcdir)/src/secp256k1/libsecp256k1.la' AC_SUBST([libsecp256k1_CFLAGS]) - -# FIXME: This is needed to force libtool to use all object files from secp. -# We can only build secp properly by recursively invoking -# configure/make, and can't include it as a noinst_ library. Libtool -# assumes that such libraries will be installed along with our library -# target and so won't force all object files in the library to be -# included in ours - despite the fact that we are making a shared -# library and linking to a static one. This is broken and we work -# around it by hacking the secp objects directly into the library -# via the _LDADD variable for wallycore. -# We previously achieved this by adding the libsecp256k1.a archive, -# but changes to libtool and apples linkers mean that -# archives-within-archives no longer work. -# Because automake tries to police its users very strictly and fails -# hard when flags are passed in this way, we have to substitute the -# flags here. -# Because libtool both intercepts -Wl and arbitrarily re-orders its -# command line inputs, we have to concoct a single expression to -# enforce linking that cannot be split, hence the below expression. -LIBADD_SECP256K1="-Wl,secp256k1/src/libsecp256k1_la-secp256k1.${OBJEXT},secp256k1/src/libsecp256k1_precomputed_la-precomputed_ecmult_gen.${OBJEXT},secp256k1/src/libsecp256k1_precomputed_la-precomputed_ecmult.${OBJEXT}" -AC_SUBST([LIBADD_SECP256K1]) +AC_SUBST([libsecp256k1_LIBS]) # # Python facilities diff --git a/setup.py b/setup.py index fd073ef8e..91137e2eb 100644 --- a/setup.py +++ b/setup.py @@ -67,12 +67,11 @@ def call(args): include_dirs=[ './', './src', - './src/ccan', './src/secp256k1/include', ] if is_windows: shutil.copyfile('./src/amalgamation/windows_config/libsecp256k1-config.h', 'src/secp256k1/src/libsecp256k1-config.h') - include_dirs = ['./src/amalgamation/windows_config'] + include_dirs + include_dirs = ['./src/amalgamation/windows_config'] + include_dirs + ['./src/ccan'] extra_compile_args = ['-flax-vector-conversions'] @@ -80,12 +79,16 @@ def call(args): '_wallycore', define_macros=define_macros, include_dirs=include_dirs, + library_dirs=['src/.libs', 'src/secp256k1/.libs'], + libraries=['wallycore', 'secp256k1'], extra_compile_args=extra_compile_args, sources=[ - 'src/swig_python/swig_wrap.c' if is_windows else 'src/swig_python/swig_python_wrap.c', + 'src/swig_python/swig_wrap.c', 'src/amalgamation/combined.c', 'src/amalgamation/combined_ccan.c', 'src/amalgamation/combined_ccan2.c', + ] if is_windows else [ + 'src/swig_python/swig_python_wrap.c', ], ) diff --git a/src/Makefile.am b/src/Makefile.am index 16bd061b2..f42702cb0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -208,7 +208,7 @@ endif endif # SHARED_BUILD_ENABLED libwallycore_la_CFLAGS = -I$(top_srcdir) -I$(srcdir)/ccan $(libsecp256k1_CFLAGS) -DWALLY_CORE_BUILD=1 $(AM_CFLAGS) -libwallycore_la_LIBADD = $(LIBADD_SECP256K1) $(noinst_LTLIBRARIES) +libwallycore_la_LIBADD = $(libsecp256k1_LIBS) $(noinst_LTLIBRARIES) SUBDIRS = secp256k1 From 9b451a817d8c36b2a46b9e722d1461f1bc2337e7 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sat, 2 Sep 2023 00:04:00 -0400 Subject: [PATCH 6/6] setup.py: support optionally building libwally-core as a shared library Iff the environment contains WALLY_ABI_PY_WHEEL_USE_DSO=1, then: * setup.py will configure and build libwally-core as a shared library; * the Python native extension library will not contain any libwally-core or libsecp256k1 code; and * the dynamic linker will need to find and load libwallycore.so.1 whenever the Python native extension is loaded. --- setup.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 91137e2eb..0d4db4500 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,13 @@ import copy, os, platform, shutil import distutils.sysconfig -CONFIGURE_ARGS = ['--disable-shared', '--enable-static', '--with-pic', +build_shared = os.environ.get('WALLY_ABI_PY_WHEEL_USE_DSO', '').lower() not in ['', '0', 'false', 'no', 'n', 'off'] +if build_shared: + CONFIGURE_ARGS = ['--enable-shared', '--disable-static'] +else: + CONFIGURE_ARGS = ['--disable-shared', '--enable-static', '--with-pic'] + +CONFIGURE_ARGS += [ '--enable-swig-python', '--enable-python-manylinux', '--disable-swig-java', '--disable-tests', '--disable-dependency-tracking'] @@ -79,8 +85,8 @@ def call(args): '_wallycore', define_macros=define_macros, include_dirs=include_dirs, - library_dirs=['src/.libs', 'src/secp256k1/.libs'], - libraries=['wallycore', 'secp256k1'], + library_dirs=['src/.libs'] + ([] if build_shared else ['src/secp256k1/.libs']), + libraries=['wallycore'] + ([] if build_shared else ['secp256k1']), extra_compile_args=extra_compile_args, sources=[ 'src/swig_python/swig_wrap.c',