csecp256k1

Haskell FFI bindings to bitcoin-core/secp256k1 (docs.ppad.tech/csecp256k1).
git clone git://git.ppad.tech/csecp256k1.git
Log | Files | Refs | README | LICENSE

CMakeLists.txt (16952B)


      1 cmake_minimum_required(VERSION 3.13)
      2 
      3 if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15)
      4   # MSVC runtime library flags are selected by the CMAKE_MSVC_RUNTIME_LIBRARY abstraction.
      5   cmake_policy(SET CMP0091 NEW)
      6   # MSVC warning flags are not in CMAKE_<LANG>_FLAGS by default.
      7   cmake_policy(SET CMP0092 NEW)
      8 endif()
      9 
     10 project(libsecp256k1
     11   # The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
     12   # the API. All changes in experimental modules are treated as
     13   # backwards-compatible and therefore at most increase the minor version.
     14   VERSION 0.4.2
     15   DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
     16   HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
     17   LANGUAGES C
     18 )
     19 
     20 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.")
     25   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.")
     28   endif()
     29   unset(parent_directory)
     30 endif()
     31 
     32 # The library version is based on libtool versioning of the ABI. The set of
     33 # rules for updating the version can be found here:
     34 # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
     35 # All changes in experimental modules are treated as if they don't affect the
     36 # interface and therefore only increase the revision.
     37 set(${PROJECT_NAME}_LIB_VERSION_CURRENT 3)
     38 set(${PROJECT_NAME}_LIB_VERSION_REVISION 2)
     39 set(${PROJECT_NAME}_LIB_VERSION_AGE 1)
     40 
     41 set(CMAKE_C_STANDARD 90)
     42 set(CMAKE_C_EXTENSIONS OFF)
     43 
     44 list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
     45 
     46 option(BUILD_SHARED_LIBS "Build shared libraries." ON)
     47 option(SECP256K1_DISABLE_SHARED "Disable shared library. Overrides BUILD_SHARED_LIBS." OFF)
     48 if(SECP256K1_DISABLE_SHARED)
     49   set(BUILD_SHARED_LIBS OFF)
     50 endif()
     51 
     52 option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL})
     53 
     54 ## Modules
     55 
     56 # We declare all options before processing them, to make sure we can express
     57 # dependendencies while processing.
     58 option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
     59 option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
     60 option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
     61 option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
     62 option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
     63 
     64 # Processing must be done in a topological sorting of the dependency graph
     65 # (dependent module first).
     66 if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
     67   add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
     68 endif()
     69 
     70 if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
     71   if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS)
     72     message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.")
     73   endif()
     74   set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON)
     75   add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1)
     76 endif()
     77 
     78 if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
     79   add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1)
     80 endif()
     81 
     82 if(SECP256K1_ENABLE_MODULE_RECOVERY)
     83   add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
     84 endif()
     85 
     86 if(SECP256K1_ENABLE_MODULE_ECDH)
     87   add_compile_definitions(ENABLE_MODULE_ECDH=1)
     88 endif()
     89 
     90 option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
     91 if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS)
     92   add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1)
     93 endif()
     94 
     95 set(SECP256K1_ECMULT_WINDOW_SIZE "AUTO" CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. \"AUTO\" is a reasonable setting for desktop machines (currently 15). [default=AUTO]")
     96 set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS "AUTO" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
     97 include(CheckStringOptionValue)
     98 check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE)
     99 if(SECP256K1_ECMULT_WINDOW_SIZE STREQUAL "AUTO")
    100   set(SECP256K1_ECMULT_WINDOW_SIZE 15)
    101 endif()
    102 add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE})
    103 
    104 set(SECP256K1_ECMULT_GEN_PREC_BITS "AUTO" CACHE STRING "Precision bits to tune the precomputed table size for signing, specified as integer 2, 4 or 8. \"AUTO\" is a reasonable setting for desktop machines (currently 4). [default=AUTO]")
    105 set_property(CACHE SECP256K1_ECMULT_GEN_PREC_BITS PROPERTY STRINGS "AUTO" 2 4 8)
    106 check_string_option_value(SECP256K1_ECMULT_GEN_PREC_BITS)
    107 if(SECP256K1_ECMULT_GEN_PREC_BITS STREQUAL "AUTO")
    108   set(SECP256K1_ECMULT_GEN_PREC_BITS 4)
    109 endif()
    110 add_compile_definitions(ECMULT_GEN_PREC_BITS=${SECP256K1_ECMULT_GEN_PREC_BITS})
    111 
    112 set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]")
    113 set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64")
    114 check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
    115 if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
    116   string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value)
    117   add_compile_definitions(USE_FORCE_WIDEMUL_${widemul_upper_value}=1)
    118 endif()
    119 mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
    120 
    121 set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]")
    122 set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32")
    123 check_string_option_value(SECP256K1_ASM)
    124 if(SECP256K1_ASM STREQUAL "arm32")
    125   enable_language(ASM)
    126   include(CheckArm32Assembly)
    127   check_arm32_assembly()
    128   if(HAVE_ARM32_ASM)
    129     add_compile_definitions(USE_EXTERNAL_ASM=1)
    130   else()
    131     message(FATAL_ERROR "ARM32 assembly requested but not available.")
    132   endif()
    133 elseif(SECP256K1_ASM)
    134   include(CheckX86_64Assembly)
    135   check_x86_64_assembly()
    136   if(HAVE_X86_64_ASM)
    137     set(SECP256K1_ASM "x86_64")
    138     add_compile_definitions(USE_ASM_X86_64=1)
    139   elseif(SECP256K1_ASM STREQUAL "AUTO")
    140     set(SECP256K1_ASM "OFF")
    141   else()
    142     message(FATAL_ERROR "x86_64 assembly requested but not available.")
    143   endif()
    144 endif()
    145 
    146 option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF)
    147 if(NOT SECP256K1_EXPERIMENTAL)
    148   if(SECP256K1_ASM STREQUAL "arm32")
    149     message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
    150   endif()
    151 endif()
    152 
    153 set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]")
    154 set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON")
    155 check_string_option_value(SECP256K1_VALGRIND)
    156 if(SECP256K1_VALGRIND)
    157   find_package(Valgrind MODULE)
    158   if(Valgrind_FOUND)
    159     set(SECP256K1_VALGRIND ON)
    160     include_directories(${Valgrind_INCLUDE_DIR})
    161     add_compile_definitions(VALGRIND)
    162   elseif(SECP256K1_VALGRIND STREQUAL "AUTO")
    163     set(SECP256K1_VALGRIND OFF)
    164   else()
    165     message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.")
    166   endif()
    167 endif()
    168 
    169 option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON)
    170 option(SECP256K1_BUILD_TESTS "Build tests." ON)
    171 option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON)
    172 option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND})
    173 option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF)
    174 
    175 # Redefine configuration flags.
    176 # We leave assertions on, because they are only used in the examples, and we want them always on there.
    177 if(MSVC)
    178   string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
    179   string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
    180   string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
    181 else()
    182   string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
    183   string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
    184   string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
    185   # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
    186   string(REGEX REPLACE "-O3[ \t\r\n]*" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
    187 endif()
    188 
    189 # Define custom "Coverage" build type.
    190 set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
    191   "Flags used by the C compiler during \"Coverage\" builds."
    192   FORCE
    193 )
    194 set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
    195   "Flags used for linking binaries during \"Coverage\" builds."
    196   FORCE
    197 )
    198 set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
    199   "Flags used by the shared libraries linker during \"Coverage\" builds."
    200   FORCE
    201 )
    202 mark_as_advanced(
    203   CMAKE_C_FLAGS_COVERAGE
    204   CMAKE_EXE_LINKER_FLAGS_COVERAGE
    205   CMAKE_SHARED_LINKER_FLAGS_COVERAGE
    206 )
    207 
    208 get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
    209 set(default_build_type "RelWithDebInfo")
    210 if(is_multi_config)
    211   set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
    212     "Supported configuration types."
    213     FORCE
    214   )
    215 else()
    216   set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
    217     STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
    218   )
    219   if(NOT CMAKE_BUILD_TYPE)
    220     message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
    221     set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
    222       "Choose the type of build."
    223       FORCE
    224     )
    225   endif()
    226 endif()
    227 
    228 include(TryAppendCFlags)
    229 if(MSVC)
    230   # Keep the following commands ordered lexicographically.
    231   try_append_c_flags(/W3) # Production quality warning level.
    232   try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
    233   try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
    234   try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
    235   # Eliminate deprecation warnings for the older, less secure functions.
    236   add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
    237 else()
    238   # Keep the following commands ordered lexicographically.
    239   try_append_c_flags(-pedantic)
    240   try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers.
    241   try_append_c_flags(-Wcast-align) # GCC >= 2.95.
    242   try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0.
    243   try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only.
    244   try_append_c_flags(-Wextra) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
    245   try_append_c_flags(-Wnested-externs)
    246   try_append_c_flags(-Wno-long-long) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
    247   try_append_c_flags(-Wno-overlength-strings) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
    248   try_append_c_flags(-Wno-unused-function) # GCC >= 3.0, -Wunused-function is implied by -Wall.
    249   try_append_c_flags(-Wreserved-identifier) # Clang >= 13.0 only.
    250   try_append_c_flags(-Wshadow)
    251   try_append_c_flags(-Wstrict-prototypes)
    252   try_append_c_flags(-Wundef)
    253 endif()
    254 
    255 set(CMAKE_C_VISIBILITY_PRESET hidden)
    256 
    257 # Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target.
    258 # CTEST_TEST_TARGET_ALIAS is not documented but supposed to be user-facing.
    259 # See: https://gitlab.kitware.com/cmake/cmake/-/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d2
    260 set(CTEST_TEST_TARGET_ALIAS check)
    261 include(CTest)
    262 # We do not use CTest's BUILD_TESTING because a single toggle for all tests is too coarse for our needs.
    263 mark_as_advanced(BUILD_TESTING)
    264 if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUSTIVE_TESTS OR SECP256K1_BUILD_CTIME_TESTS OR SECP256K1_BUILD_EXAMPLES)
    265   enable_testing()
    266 endif()
    267 
    268 set(SECP256K1_LATE_CFLAGS "" CACHE STRING "Compiler flags that are added to the command line after all other flags added by the build system.")
    269 include(AllTargetsCompileOptions)
    270 
    271 add_subdirectory(src)
    272 all_targets_compile_options(src "${SECP256K1_LATE_CFLAGS}")
    273 if(SECP256K1_BUILD_EXAMPLES)
    274   add_subdirectory(examples)
    275   all_targets_compile_options(examples "${SECP256K1_LATE_CFLAGS}")
    276 endif()
    277 
    278 message("\n")
    279 message("secp256k1 configure summary")
    280 message("===========================")
    281 message("Build artifacts:")
    282 if(BUILD_SHARED_LIBS)
    283   set(library_type "Shared")
    284 else()
    285   set(library_type "Static")
    286 endif()
    287 
    288 message("  library type ........................ ${library_type}")
    289 message("Optional modules:")
    290 message("  ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}")
    291 message("  ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}")
    292 message("  extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}")
    293 message("  schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
    294 message("  ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
    295 message("Parameters:")
    296 message("  ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
    297 message("  ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}")
    298 message("Optional features:")
    299 message("  assembly ............................ ${SECP256K1_ASM}")
    300 message("  external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}")
    301 if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
    302   message("  wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}")
    303 endif()
    304 message("Optional binaries:")
    305 message("  benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}")
    306 message("  noverify_tests ...................... ${SECP256K1_BUILD_TESTS}")
    307 set(tests_status "${SECP256K1_BUILD_TESTS}")
    308 if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
    309   set(tests_status OFF)
    310 endif()
    311 message("  tests ............................... ${tests_status}")
    312 message("  exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}")
    313 message("  ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}")
    314 message("  examples ............................ ${SECP256K1_BUILD_EXAMPLES}")
    315 message("")
    316 if(CMAKE_CROSSCOMPILING)
    317   set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
    318 else()
    319   set(cross_status "FALSE")
    320 endif()
    321 message("Cross compiling ....................... ${cross_status}")
    322 message("Valgrind .............................. ${SECP256K1_VALGRIND}")
    323 get_directory_property(definitions COMPILE_DEFINITIONS)
    324 string(REPLACE ";" " " definitions "${definitions}")
    325 message("Preprocessor defined macros ........... ${definitions}")
    326 message("C compiler ............................ ${CMAKE_C_COMPILER}")
    327 message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
    328 get_directory_property(compile_options COMPILE_OPTIONS)
    329 string(REPLACE ";" " " compile_options "${compile_options}")
    330 message("Compile options ....................... " ${compile_options})
    331 if(NOT is_multi_config)
    332   message("Build type:")
    333   message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
    334   string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
    335   message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
    336   message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
    337   message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
    338 else()
    339   message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
    340   message("RelWithDebInfo configuration:")
    341   message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
    342   message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
    343   message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
    344   message("Debug configuration:")
    345   message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
    346   message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
    347   message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
    348 endif()
    349 if(SECP256K1_LATE_CFLAGS)
    350   message("SECP256K1_LATE_CFLAGS ................. ${SECP256K1_LATE_CFLAGS}")
    351 endif()
    352 message("\n")
    353 if(SECP256K1_EXPERIMENTAL)
    354   message(
    355     "  ******\n"
    356     "  WARNING: experimental build\n"
    357     "  Experimental features do not have stable APIs or properties, and may not be safe for production use.\n"
    358     "  ******\n"
    359   )
    360 endif()