Skip to content

Commit b941c15

Browse files
committed
Squashed 'src/secp256k1/' changes from 06bff6dec8..f473c959f0
f473c959f0 Merge bitcoin-core/secp256k1#1543: cmake: Do not modify build types when integrating by downstream project d403eea484 Merge bitcoin-core/secp256k1#1546: cmake: Rename `SECP256K1_LATE_CFLAGS` and switch to Bitcoin Core's approach d7ae25ce6f Merge bitcoin-core/secp256k1#1550: fix: typos in secp256k1.c 0e2fadb20c fix: typos in secp256k1.c 69b2192ad4 Merge bitcoin-core/secp256k1#1545: cmake: Do not set `CTEST_TEST_TARGET_ALIAS` 5dd637f3cf Merge bitcoin-core/secp256k1#1548: README: mention ellswift module 7454a53736 README: mention ellswift module 4706be2cd0 cmake: Reimplement `SECP256K1_APPEND_CFLAGS` using Bitcoin Core approach c2764dbb99 cmake: Rename `SECP256K1_LATE_CFLAGS` to `SECP256K1_APPEND_CFLAGS` f87a3589f4 cmake: Do not set `CTEST_TEST_TARGET_ALIAS` 158f9e5eae cmake: Do not modify build types when integrating by downstream project 35c0fdc86b Merge bitcoin-core/secp256k1#1529: cmake: Fix cache issue when integrating by downstream project 4392f0f717 Merge bitcoin-core/secp256k1#1533: tests: refactor: tidy up util functions (bitcoin#1491) bedffd53d8 Merge bitcoin-core/secp256k1#1488: ci: Add native macOS arm64 job 4b8d5eeacf Merge bitcoin-core/secp256k1#1532: cmake: Disable eager MSan in ctime_tests f55703ba49 autotools: Delete unneeded compiler test 396e885886 autotools: Align MSan checking code with CMake's implementation abde59f52d cmake: Report more compiler details in summary 7abf979a43 cmake: Disable `ctime_tests` if build with `-fsanitize=memory` 1791f6fce4 Merge bitcoin-core/secp256k1#1517: autotools: Disable eager MSan in ctime_tests e73f6f8fd9 tests: refactor: drop `secp256k1_` prefix from testrand.h functions 0ee7453a99 tests: refactor: add `testutil_` prefix to testutil.h functions 0c6bc76dcd tests: refactor: move `random_` helpers from tests.c to testutil.h 0fef8479be tests: refactor: rename `random_field_element_magnitude` -> `random_fe_magnitude` 59db007f0f tests: refactor: rename `random_group_element_...` -> `random_ge_...` ebfb82ee2f ci: Add job with -fsanitize-memory-param-retval e1bef0961c configure: Move "experimental" warning to bottom 55e5d975db autotools: Disable eager MSan in ctime_tests ec4c002faa cmake: Simplify `PROJECT_IS_TOP_LEVEL` emulation cae9a7ad14 cmake: Do not set emulated PROJECT_IS_TOP_LEVEL as cache variable 218f0cc93b ci: Add native macOS arm64 job git-subtree-dir: src/secp256k1 git-subtree-split: f473c959f08edcb73669142f872d2189950bc54a
1 parent ca3d945 commit b941c15

19 files changed

+580
-458
lines changed

.github/workflows/ci.yml

+66-4
Original file line numberDiff line numberDiff line change
@@ -485,18 +485,24 @@ jobs:
485485
matrix:
486486
configuration:
487487
- env_vars:
488+
CTIMETESTS: 'yes'
488489
CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g'
489490
- env_vars:
490491
ECMULTGENKB: 2
491492
ECMULTWINDOW: 2
493+
CTIMETESTS: 'yes'
492494
CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g -O3'
495+
- env_vars:
496+
# -fsanitize-memory-param-retval is clang's default, but our build system disables it
497+
# when ctime_tests when enabled.
498+
CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -fsanitize-memory-param-retval -g'
499+
CTIMETESTS: 'no'
493500

494501
env:
495502
ECDH: 'yes'
496503
RECOVERY: 'yes'
497504
SCHNORRSIG: 'yes'
498505
ELLSWIFT: 'yes'
499-
CTIMETESTS: 'yes'
500506
CC: 'clang'
501507
SECP256K1_TEST_ITERS: 32
502508
ASM: 'no'
@@ -585,10 +591,10 @@ jobs:
585591
run: env
586592
if: ${{ always() }}
587593

588-
macos-native:
589-
name: "x86_64: macOS Monterey"
594+
x86_64-macos-native:
595+
name: "x86_64: macOS Monterey, Valgrind"
590596
# See: https://github.com/actions/runner-images#available-images.
591-
runs-on: macos-12 # Use M1 once available https://github.com/github/roadmap/issues/528
597+
runs-on: macos-12
592598

593599
env:
594600
CC: 'clang'
@@ -644,6 +650,62 @@ jobs:
644650
run: env
645651
if: ${{ always() }}
646652

653+
arm64-macos-native:
654+
name: "ARM64: macOS Sonoma"
655+
# See: https://github.com/actions/runner-images#available-images.
656+
runs-on: macos-14
657+
658+
env:
659+
CC: 'clang'
660+
HOMEBREW_NO_AUTO_UPDATE: 1
661+
HOMEBREW_NO_INSTALL_CLEANUP: 1
662+
WITH_VALGRIND: 'no'
663+
CTIMETESTS: 'no'
664+
665+
strategy:
666+
fail-fast: false
667+
matrix:
668+
env_vars:
669+
- { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' }
670+
- { WIDEMUL: 'int128_struct', ECMULTGENPRECISION: 2, ECMULTWINDOW: 4 }
671+
- { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' }
672+
- { WIDEMUL: 'int128', RECOVERY: 'yes' }
673+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' }
674+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', CC: 'gcc' }
675+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', CPPFLAGS: '-DVERIFY' }
676+
- BUILD: 'distcheck'
677+
678+
steps:
679+
- name: Checkout
680+
uses: actions/checkout@v4
681+
682+
- name: Install Homebrew packages
683+
run: |
684+
brew install automake libtool gcc
685+
ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc
686+
687+
- name: CI script
688+
env: ${{ matrix.env_vars }}
689+
run: ./ci/ci.sh
690+
691+
- run: cat tests.log || true
692+
if: ${{ always() }}
693+
- run: cat noverify_tests.log || true
694+
if: ${{ always() }}
695+
- run: cat exhaustive_tests.log || true
696+
if: ${{ always() }}
697+
- run: cat ctime_tests.log || true
698+
if: ${{ always() }}
699+
- run: cat bench.log || true
700+
if: ${{ always() }}
701+
- run: cat config.log || true
702+
if: ${{ always() }}
703+
- run: cat test_env.log || true
704+
if: ${{ always() }}
705+
- name: CI env
706+
run: env
707+
if: ${{ always() }}
708+
647709
win64-native:
648710
name: ${{ matrix.configuration.job_name }}
649711
# See: https://github.com/actions/runner-images#available-images.

CMakeLists.txt

+51-34
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ project(libsecp256k1
1818
)
1919

2020
if(CMAKE_VERSION VERSION_LESS 3.21)
21-
get_directory_property(parent_directory PARENT_DIRECTORY)
22-
if(parent_directory)
23-
set(PROJECT_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
24-
set(${PROJECT_NAME}_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
21+
# Emulates CMake 3.21+ behavior.
22+
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
23+
set(PROJECT_IS_TOP_LEVEL ON)
24+
set(${PROJECT_NAME}_IS_TOP_LEVEL ON)
2525
else()
26-
set(PROJECT_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
27-
set(${PROJECT_NAME}_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
26+
set(PROJECT_IS_TOP_LEVEL OFF)
27+
set(${PROJECT_NAME}_IS_TOP_LEVEL OFF)
2828
endif()
29-
unset(parent_directory)
3029
endif()
3130

3231
# The library version is based on libtool versioning of the ABI. The set of
@@ -214,23 +213,25 @@ mark_as_advanced(
214213
CMAKE_SHARED_LINKER_FLAGS_COVERAGE
215214
)
216215

217-
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
218-
set(default_build_type "RelWithDebInfo")
219-
if(is_multi_config)
220-
set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
221-
"Supported configuration types."
222-
FORCE
223-
)
224-
else()
225-
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
226-
STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
227-
)
228-
if(NOT CMAKE_BUILD_TYPE)
229-
message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
230-
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
231-
"Choose the type of build."
216+
if(PROJECT_IS_TOP_LEVEL)
217+
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
218+
set(default_build_type "RelWithDebInfo")
219+
if(is_multi_config)
220+
set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
221+
"Supported configuration types."
232222
FORCE
233223
)
224+
else()
225+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
226+
STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
227+
)
228+
if(NOT CMAKE_BUILD_TYPE)
229+
message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
230+
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
231+
"Choose the type of build."
232+
FORCE
233+
)
234+
endif()
234235
endif()
235236
endif()
236237

@@ -263,25 +264,34 @@ endif()
263264

264265
set(CMAKE_C_VISIBILITY_PRESET hidden)
265266

266-
# Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target.
267-
# CTEST_TEST_TARGET_ALIAS is not documented but supposed to be user-facing.
268-
# See: https://gitlab.kitware.com/cmake/cmake/-/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d2
269-
set(CTEST_TEST_TARGET_ALIAS check)
267+
set(print_msan_notice)
268+
if(SECP256K1_BUILD_CTIME_TESTS)
269+
include(CheckMemorySanitizer)
270+
check_memory_sanitizer(msan_enabled)
271+
if(msan_enabled)
272+
try_append_c_flags(-fno-sanitize-memory-param-retval)
273+
set(print_msan_notice YES)
274+
endif()
275+
unset(msan_enabled)
276+
endif()
277+
270278
include(CTest)
271279
# We do not use CTest's BUILD_TESTING because a single toggle for all tests is too coarse for our needs.
272280
mark_as_advanced(BUILD_TESTING)
273281
if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUSTIVE_TESTS OR SECP256K1_BUILD_CTIME_TESTS OR SECP256K1_BUILD_EXAMPLES)
274282
enable_testing()
275283
endif()
276284

277-
set(SECP256K1_LATE_CFLAGS "" CACHE STRING "Compiler flags that are added to the command line after all other flags added by the build system.")
278-
include(AllTargetsCompileOptions)
285+
set(SECP256K1_APPEND_CFLAGS "" CACHE STRING "Compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
286+
if(SECP256K1_APPEND_CFLAGS)
287+
# Appending to this low-level rule variable is the only way to
288+
# guarantee that the flags appear at the end of the command line.
289+
string(APPEND CMAKE_C_COMPILE_OBJECT " ${SECP256K1_APPEND_CFLAGS}")
290+
endif()
279291

280292
add_subdirectory(src)
281-
all_targets_compile_options(src "${SECP256K1_LATE_CFLAGS}")
282293
if(SECP256K1_BUILD_EXAMPLES)
283294
add_subdirectory(examples)
284-
all_targets_compile_options(examples "${SECP256K1_LATE_CFLAGS}")
285295
endif()
286296

287297
message("\n")
@@ -332,7 +342,7 @@ message("Valgrind .............................. ${SECP256K1_VALGRIND}")
332342
get_directory_property(definitions COMPILE_DEFINITIONS)
333343
string(REPLACE ";" " " definitions "${definitions}")
334344
message("Preprocessor defined macros ........... ${definitions}")
335-
message("C compiler ............................ ${CMAKE_C_COMPILER}")
345+
message("C compiler ............................ ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}, ${CMAKE_C_COMPILER}")
336346
message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
337347
get_directory_property(compile_options COMPILE_OPTIONS)
338348
string(REPLACE ";" " " compile_options "${compile_options}")
@@ -355,10 +365,17 @@ else()
355365
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
356366
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
357367
endif()
358-
if(SECP256K1_LATE_CFLAGS)
359-
message("SECP256K1_LATE_CFLAGS ................. ${SECP256K1_LATE_CFLAGS}")
368+
if(SECP256K1_APPEND_CFLAGS)
369+
message("SECP256K1_APPEND_CFLAGS ............... ${SECP256K1_APPEND_CFLAGS}")
370+
endif()
371+
message("")
372+
if(print_msan_notice)
373+
message(
374+
"Note:\n"
375+
" MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to compile options\n"
376+
" to avoid false positives in ctime_tests. Pass -DSECP256K1_BUILD_CTIME_TESTS=OFF to avoid this.\n"
377+
)
360378
endif()
361-
message("\n")
362379
if(SECP256K1_EXPERIMENTAL)
363380
message(
364381
" ******\n"

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Features:
2020
* Optional module for public key recovery.
2121
* Optional module for ECDH key exchange.
2222
* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
23+
* Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki).
2324

2425
Implementation details
2526
----------------------

build-aux/m4/bitcoin_secp.m4

+16
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ fi
4545
AC_MSG_RESULT($has_valgrind)
4646
])
4747

48+
AC_DEFUN([SECP_MSAN_CHECK], [
49+
AC_MSG_CHECKING(whether MemorySanitizer is enabled)
50+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
51+
#if defined(__has_feature)
52+
# if __has_feature(memory_sanitizer)
53+
/* MemorySanitizer is enabled. */
54+
# elif
55+
# error "MemorySanitizer is disabled."
56+
# endif
57+
#else
58+
# error "__has_feature is not defined."
59+
#endif
60+
]])], [msan_enabled=yes], [msan_enabled=no])
61+
AC_MSG_RESULT([$msan_enabled])
62+
])
63+
4864
dnl SECP_TRY_APPEND_CFLAGS(flags, VAR)
4965
dnl Append flags to VAR if CC accepts them.
5066
AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [

cmake/AllTargetsCompileOptions.cmake

-12
This file was deleted.

cmake/CheckMemorySanitizer.cmake

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
include_guard(GLOBAL)
2+
include(CheckCSourceCompiles)
3+
4+
function(check_memory_sanitizer output)
5+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
6+
check_c_source_compiles("
7+
#if defined(__has_feature)
8+
# if __has_feature(memory_sanitizer)
9+
/* MemorySanitizer is enabled. */
10+
# elif
11+
# error \"MemorySanitizer is disabled.\"
12+
# endif
13+
#else
14+
# error \"__has_feature is not defined.\"
15+
#endif
16+
" HAVE_MSAN)
17+
set(${output} ${HAVE_MSAN} PARENT_SCOPE)
18+
endfunction()

configure.ac

+29-6
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,20 @@ if test x"$enable_ctime_tests" = x"auto"; then
247247
enable_ctime_tests=$enable_valgrind
248248
fi
249249

250+
print_msan_notice=no
251+
if test x"$enable_ctime_tests" = x"yes"; then
252+
SECP_MSAN_CHECK
253+
# MSan on Clang >=16 reports unitialized memory in function parameters and return values, even if
254+
# the uninitalized variable is never actually "used". This is called "eager" checking, and it's
255+
# sounds like good idea for normal use of MSan. However, it yields many false positives in the
256+
# ctime_tests because many return values depend on secret (i.e., "uninitialized") values, and
257+
# we're only interested in detecting branches (which count as "uses") on secret data.
258+
if test x"$msan_enabled" = x"yes"; then
259+
SECP_TRY_APPEND_CFLAGS([-fno-sanitize-memory-param-retval], SECP_CFLAGS)
260+
print_msan_notice=yes
261+
fi
262+
fi
263+
250264
if test x"$enable_coverage" = x"yes"; then
251265
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
252266
SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS"
@@ -426,12 +440,7 @@ fi
426440
### Check for --enable-experimental if necessary
427441
###
428442

429-
if test x"$enable_experimental" = x"yes"; then
430-
AC_MSG_NOTICE([******])
431-
AC_MSG_NOTICE([WARNING: experimental build])
432-
AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.])
433-
AC_MSG_NOTICE([******])
434-
else
443+
if test x"$enable_experimental" = x"no"; then
435444
if test x"$set_asm" = x"arm32"; then
436445
AC_MSG_ERROR([ARM32 assembly is experimental. Use --enable-experimental to allow.])
437446
fi
@@ -492,3 +501,17 @@ echo " CPPFLAGS = $CPPFLAGS"
492501
echo " SECP_CFLAGS = $SECP_CFLAGS"
493502
echo " CFLAGS = $CFLAGS"
494503
echo " LDFLAGS = $LDFLAGS"
504+
505+
if test x"$print_msan_notice" = x"yes"; then
506+
echo
507+
echo "Note:"
508+
echo " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to SECP_CFLAGS"
509+
echo " to avoid false positives in ctime_tests. Pass --disable-ctime-tests to avoid this."
510+
fi
511+
512+
if test x"$enable_experimental" = x"yes"; then
513+
echo
514+
echo "WARNING: Experimental build"
515+
echo " Experimental features do not have stable APIs or properties, and may not be safe for"
516+
echo " production use."
517+
fi

src/modules/ecdh/tests_impl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static void test_ecdh_generator_basepoint(void) {
5656
size_t point_ser_len = sizeof(point_ser);
5757
secp256k1_scalar s;
5858

59-
random_scalar_order(&s);
59+
testutil_random_scalar_order(&s);
6060
secp256k1_scalar_get_b32(s_b32, &s);
6161

6262
CHECK(secp256k1_ec_pubkey_create(CTX, &point[0], s_one) == 1);
@@ -95,7 +95,7 @@ static void test_bad_scalar(void) {
9595
secp256k1_pubkey point;
9696

9797
/* Create random point */
98-
random_scalar_order(&rand);
98+
testutil_random_scalar_order(&rand);
9999
secp256k1_scalar_get_b32(s_rand, &rand);
100100
CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_rand) == 1);
101101

@@ -127,7 +127,7 @@ static void test_result_basepoint(void) {
127127
CHECK(secp256k1_ecdh(CTX, out_base, &point, s_one, NULL, NULL) == 1);
128128

129129
for (i = 0; i < 2 * COUNT; i++) {
130-
random_scalar_order(&rand);
130+
testutil_random_scalar_order(&rand);
131131
secp256k1_scalar_get_b32(s, &rand);
132132
secp256k1_scalar_inverse(&rand, &rand);
133133
secp256k1_scalar_get_b32(s_inv, &rand);

0 commit comments

Comments
 (0)