Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d509942
descriptor: WIF handling fixes
odudex Sep 25, 2026
ddd3c39
tx: use the Elements tapscript leaf version for script path sighashes
odudex Sep 25, 2026
c37ece0
descriptor: use the Elements tapscript leaf version for eltr() taptrees
odudex Sep 25, 2026
f238b5b
bech32: require an exact witness program in wally_addr_segwit_from_bytes
odudex Sep 25, 2026
1e4b193
bech32: skip clearing when encoding fails
odudex Sep 25, 2026
8314305
base58: reject encode/decode lengths that overflow the bignum size
odudex Sep 25, 2026
0ecab8f
descriptor: always treat elip150 ct() descriptors as Elements
odudex Sep 25, 2026
045ceff
descriptor: check for overflow when computing the canonical length
odudex Sep 25, 2026
58563dd
internal: check for overflow when growing arrays
odudex Sep 25, 2026
f1f9f61
hex: reject lengths that overflow the hex string size
odudex Sep 25, 2026
19daeaa
base64: reject lengths that overflow the encoded length
odudex Sep 25, 2026
21b8d82
tx: reject invalid input index for segwit v0 signature hashes
odudex Sep 25, 2026
43bdb7b
elements: limit the number of values in wally_asset_final_vbf to 255
jgriffiths Sep 29, 2026
20e7266
tx: check for overflow when allocating input, output and witness arrays
odudex Sep 25, 2026
705123c
psbt: check for overflow when allocating input and output arrays
odudex Sep 25, 2026
bedbe5a
map: check for overflow when allocating map items
odudex Sep 25, 2026
7b6c74f
psbt: init new PSBT v0 inputs/outputs to init map validators
kkdao Sep 26, 2026
c0c1a92
build: fix the mbed-tls option in CMake and the configure help text
odudex Sep 4, 2026
0c9e7b7
hmac: derive the HMAC block size from the hash, not the context layout
odudex Sep 4, 2026
65c8bd8
script: reject malformed script integers, add tests
jgriffiths Sep 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _cmake/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#cmakedefine HAVE_INLINE_ASM @HAVE_INLINE_ASM@

/* Define to 1 if you have the <mbedtls/sha256.h,> header file. */
#cmakedefine HAVE_MBEDTLS_SHA256_H_ @HAVE_MBEDTLS_SHA256_H@
#cmakedefine HAVE_MBEDTLS_SHA256_H @HAVE_MBEDTLS_SHA256_H@

/* Define to 1 if you have the <mbedtls/sha512.h> header file. */
#cmakedefine HAVE_MBEDTLS_SHA512_H @HAVE_MBEDTLS_SHA512_H@
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ AC_ARG_ENABLE(minimal,
AS_HELP_STRING([--enable-minimal],[enable minimal size/memory footprint build (default: no)]),
[minimal=$enableval], [minimal=no])
AC_ARG_ENABLE(mbed-tls,
AS_HELP_STRING([--enable-mbed-tls],[enable minimal size/memory footprint build (default: no)]),
AS_HELP_STRING([--enable-mbed-tls],[use mbed-tls hashing functions where available (default: no)]),
[mbedtls=$enableval], [mbedtls=no])
AC_ARG_ENABLE(secp256k1-tests,
AS_HELP_STRING([--enable-secp256k1-tests],[enable secp256k1 tests (default: no)]),
Expand Down
3 changes: 2 additions & 1 deletion include/wally_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ extern "C" {
#define WALLY_SCRIPTPUBKEY_P2WSH_LEN 34 /** OP_0 [SHA256] */
#define WALLY_SCRIPTPUBKEY_P2TR_LEN 34 /** OP_1 [X-ONLY-PUBKEY] */

#define WALLY_LEAF_VERSION_TAPSCRIPT 0xc0 /** BIP-342 tapscript leaf version */
#define WALLY_LEAF_VERSION_TAPSCRIPT 0xc0 /** BIP-342 tapscript leaf version */
#define WALLY_LEAF_VERSION_TAPSCRIPT_ELEMENTS 0xc4 /** Elements tapscript leaf version */

#define WALLY_SCRIPTPUBKEY_OP_RETURN_MAX_LEN 83 /** OP_RETURN [80 bytes of data] */

Expand Down
6 changes: 4 additions & 2 deletions include/wally_transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -894,8 +894,10 @@ WALLY_CORE_API int wally_tx_get_signature_hash(
*| uint64/host endiannes. For non-taproot signing, only the value
*| of ``index`` is required.
* :param script: For segwit v0 signing, the scriptcode of the input to sign
*| for. For taproot, the leaf script to sign with if any. Ignored for
*| pre-segwit signing.
*| for. For taproot, the leaf script to sign with if any. Its leaf version
*| is taken to be ``WALLY_LEAF_VERSION_TAPSCRIPT``, or
*| ``WALLY_LEAF_VERSION_TAPSCRIPT_ELEMENTS`` for Elements transactions.
*| Ignored for pre-segwit signing.
* :param script_len: Length of ``script`` in bytes.
* :param key_version: For taproot signing, the version of the pubkey
*| in ``script`` when signing with a script path. Currently must be ``1``
Expand Down
25 changes: 17 additions & 8 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -224,28 +224,29 @@ SUBDIRS = secp256k1
endif

TESTS =
TESTS_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include -I$(srcdir)/ccan -I$(top_srcdir)/src/secp256k1/include $(AM_CFLAGS)
noinst_PROGRAMS =
if RUN_TESTS
TESTS += test_bech32
noinst_PROGRAMS += test_bech32
test_bech32_SOURCES = ctest/test_bech32.c
test_bech32_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
test_bech32_CFLAGS = $(TESTS_CFLAGS)
test_bech32_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_bech32_LDADD += $(PYTHON_LIBS)
endif
TESTS += test_psbt
noinst_PROGRAMS += test_psbt
test_psbt_SOURCES = ctest/test_psbt.c ccan/ccan/str/hex/hex.c
test_psbt_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS) -I$(srcdir)/ccan
test_psbt_CFLAGS = $(TESTS_CFLAGS)
test_psbt_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_psbt_LDADD += $(PYTHON_LIBS)
endif
TESTS += test_psbt_limits
noinst_PROGRAMS += test_psbt_limits
test_psbt_limits_SOURCES = ctest/test_psbt_limits.c ccan/ccan/str/hex/hex.c
test_psbt_limits_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS) -I$(srcdir)/ccan
test_psbt_limits_CFLAGS = $(TESTS_CFLAGS)
test_psbt_limits_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_psbt_limits_LDADD += $(PYTHON_LIBS)
Expand All @@ -254,7 +255,7 @@ if USE_PTHREAD
TESTS += test_clear
noinst_PROGRAMS += test_clear
test_clear_SOURCES = ctest/test_clear.c
test_clear_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir) -I$(top_srcdir)/src/secp256k1/include $(PTHREAD_CFLAGS) $(AM_CFLAGS) $(NOOPT_CFLAGS) $(NOBUILTIN_CFLAGS)
test_clear_CFLAGS = $(TESTS_CFLAGS) $(PTHREAD_CFLAGS) $(AM_CFLAGS) $(NOOPT_CFLAGS) $(NOBUILTIN_CFLAGS)
test_clear_LIBS = $(PTHREAD_LIBS)
test_clear_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
Expand All @@ -264,23 +265,31 @@ endif
TESTS += test_coinselection
noinst_PROGRAMS += test_coinselection
test_coinselection_SOURCES = ctest/test_coinselection.c
test_coinselection_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
test_coinselection_CFLAGS = $(TESTS_CFLAGS)
test_coinselection_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_coinselection_LDADD += $(PYTHON_LIBS)
endif
TESTS += test_script
noinst_PROGRAMS += test_script
test_script_SOURCES = ctest/test_script.c
test_script_CFLAGS = $(TESTS_CFLAGS)
test_script_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_script_LDADD += $(PYTHON_LIBS)
endif
TESTS += test_tx
noinst_PROGRAMS += test_tx
test_tx_SOURCES = ctest/test_tx.c
test_tx_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
test_tx_CFLAGS = $(TESTS_CFLAGS)
test_tx_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_tx_LDADD += $(PYTHON_LIBS)
endif
TESTS += test_descriptor
noinst_PROGRAMS += test_descriptor
test_descriptor_SOURCES = ctest/test_descriptor.c
test_descriptor_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
test_descriptor_CFLAGS = $(TESTS_CFLAGS)
test_descriptor_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_descriptor_LDADD += $(PYTHON_LIBS)
Expand All @@ -289,7 +298,7 @@ if BUILD_ELEMENTS
TESTS += test_elements_tx
noinst_PROGRAMS += test_elements_tx
test_elements_tx_SOURCES = ctest/test_elements_tx.c
test_elements_tx_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
test_elements_tx_CFLAGS = $(TESTS_CFLAGS)
test_elements_tx_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
if PYTHON_MANYLINUX
test_elements_tx_LDADD += $(PYTHON_LIBS)
Expand Down
4 changes: 4 additions & 0 deletions src/base_58.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ static int base58_decode(const char *base58, size_t base58_len,

/* Take 6 bits to store each 58 bit number, rounded up to the next byte,
* then round that up to a uint32_t word boundary. */
if (base58_len > (SIZE_MAX - 7) / 6)
return WALLY_EINVAL; /* Too long: bn_words would overflow */
bn_words = ((base58_len * 6 + 7) / 8 + 3) / 4;

/* Allocate our bignum buffer if it won't fit on the stack */
Expand Down Expand Up @@ -201,6 +203,8 @@ int wally_base58_from_bytes(const unsigned char *bytes, size_t bytes_len,
return WALLY_OK; /* All 0's */
}

if (bytes_len - zeros > SIZE_MAX / 138)
goto cleanup; /* Too long: bn_bytes would overflow */
bn_bytes = (bytes_len - zeros) * 138 / 100 + 1; /* log(256)/log(58) rounded up */

/* Allocate our bignum buffer if it won't fit on the stack */
Expand Down
2 changes: 2 additions & 0 deletions src/base_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ int wally_base64_from_bytes(const unsigned char *bytes, size_t bytes_len,

if (!bytes || !bytes_len || flags || !output)
return WALLY_EINVAL;
if (bytes_len > (SIZE_MAX - 1) / 4 * 3)
return WALLY_EINVAL; /* Encoded length would overflow */

encoded_len = base64_encoded_length(bytes_len) + 1; /* +1 for NUL */
if ((encoded = wally_malloc(encoded_len)) == NULL)
Expand Down
15 changes: 2 additions & 13 deletions src/bech32.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ static int segwit_addr_encode(char *output, const char *hrp, size_t hrp_len, uin
++datalen;
return bech32_encode(output, hrp, hrp_len, data, datalen, 90, witver != 0);
fail:
wally_clear_2(data, sizeof(data), (void *)witprog, witprog_len);
return 0;
}

Expand Down Expand Up @@ -209,24 +208,14 @@ int wally_addr_segwit_from_bytes(const unsigned char *bytes, size_t bytes_len,
char **output)
{
char result[90 + 1]; /* Max encoded length plus NUL */
size_t push_size;
int ret;
size_t witver;
size_t addr_family_len = addr_family ? strlen(addr_family) : 0;

if (output)
*output = 0;

if (!addr_family || flags || !bytes || !bytes_len || !output)
return WALLY_EINVAL;

if (!script_is_op_n(bytes[0], true, &witver))
return WALLY_EINVAL;

ret = script_get_push_size_from_bytes(bytes + 1, bytes_len - 1, &push_size);
if (ret != WALLY_OK)
return WALLY_EINVAL;
else if (witver == 0 && push_size != HASH160_LEN && push_size != SHA256_LEN)
if (!scriptpubkey_is_witness_program(bytes, bytes_len, &witver) ||
!addr_family || flags || !output)
return WALLY_EINVAL;

result[0] = '\0';
Expand Down
11 changes: 11 additions & 0 deletions src/ctest/_CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,14 @@ add_executable(test_psbt_limits test_psbt_limits.c)
target_include_directories(test_psbt_limits PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(test_psbt_limits PRIVATE wallycore)
add_test(test_psbt_limits test_psbt_limits)

# TODO: Requires static linking or exposing scriptint_from_bytes w/WALLY_INTERNAL_API
#add_executable(test_script test_script.c)
#target_include_directories(test_script PRIVATE ${CMAKE_BINARY_DIR} $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src>)
#target_link_libraries(test_script PRIVATE wallycore)
#add_test(test_script test_script)

add_executable(test_tx test_tx.c)
target_include_directories(test_tx PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(test_tx PRIVATE wallycore)
add_test(test_tx test_tx)
Loading
Loading