diff --git a/cmake/modules/InstallationHelper.cmake b/cmake/modules/InstallationHelper.cmake index 391ec13fc..800ca96bf 100644 --- a/cmake/modules/InstallationHelper.cmake +++ b/cmake/modules/InstallationHelper.cmake @@ -1,71 +1,74 @@ # This file contains facilities for installing the files. include(GNUInstallDirs) function(install_target _target) install( TARGETS ${_target} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT ${PROJECT_NAME} + ARCHIVE + DESTINATION "${CMAKE_INSTALL_LIBDIR}" + COMPONENT ${PROJECT_NAME} LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT ${PROJECT_NAME} PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" COMPONENT ${PROJECT_NAME} ) endfunction() function(install_shared_library NAME) cmake_parse_arguments(ARG "" "" "PUBLIC_HEADER" ${ARGN} ) set(_sources ${ARG_UNPARSED_ARGUMENTS}) get_target_property(_target_type ${NAME} TYPE) if(_target_type STREQUAL "SHARED_LIBRARY") set(_shared_name "${NAME}") target_sources(${NAME} PRIVATE ${_sources}) else() set(_shared_name "${NAME}-shared") add_library(${_shared_name} SHARED ${_sources}) target_link_libraries(${_shared_name} ${NAME}) endif() if(ARG_PUBLIC_HEADER) set_property(TARGET ${_shared_name} PROPERTY PUBLIC_HEADER ${ARG_PUBLIC_HEADER}) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # FIXME For compatibility reason with autotools, the version is set # to 0.0.0 (major being actually 0). This is obviously wrong and the # version of the library should reflect the version of the release. # On platforms other than linux, only the major version (0) is used. # Replace the VERSION line with the statement below to set the # correct version: # set(_properties VERSION "${CMAKE_PROJECT_VERSION}") list(APPEND _properties VERSION "${CMAKE_PROJECT_VERSION_MAJOR}.0.0") else() list(APPEND _properties VERSION "${CMAKE_PROJECT_VERSION_MAJOR}") endif() # For autotools compatibility, rename the library to ${OUTPUT_NAME}-0.dll if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") list(APPEND _properties OUTPUT_NAME "${NAME}-${CMAKE_PROJECT_VERSION_MAJOR}") # DLL_EXPORT is defined by libtool, and is expected by some sources. target_compile_definitions(${_shared_name} PRIVATE DLL_EXPORT) else() list(APPEND _properties OUTPUT_NAME "${NAME}") endif() list(APPEND _properties SOVERSION "${CMAKE_PROJECT_VERSION_MAJOR}") set_target_properties(${_shared_name} PROPERTIES ${_properties}) install_target(${_shared_name}) endfunction() diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 508cb13c0..32f6b915f 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,178 +1,183 @@ --- name: "bitcoin-abc-linux" enable_cache: true distro: "debian" suites: - "buster" architectures: - "amd64" multiarch: - "i386" packages: - "autoconf" - "automake" - "binutils-aarch64-linux-gnu" - "binutils-arm-linux-gnueabihf" - "binutils-gold" - "bsdmainutils" - "build-essential" - "ca-certificates" - "cmake" - "curl" - "faketime" - "g++-aarch64-linux-gnu" - "g++-arm-linux-gnueabihf" - "gcc-aarch64-linux-gnu" - "gcc-arm-linux-gnueabihf" - "git" - "gperf" - "lib32stdc++-8-dev" - "libc6-dev:i386" - "libtool" - "ninja-build" - "pkg-config" - "python3" # FIXME: these dependencies are only required to make CMake happy when building # native tools. They can be removed when the `NativeExecutable.cmake` gets # improved to avoid requiring all the bitcoin-abc dependencies. - "libboost-all-dev" - "libevent-dev" - "libssl-dev" remotes: - "url": "https://github.com/Bitcoin-ABC/bitcoin-abc.git" "dir": "bitcoin" files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" # CMake toolchain file name differ from host name declare -A CMAKE_TOOLCHAIN_FILE CMAKE_TOOLCHAIN_FILE[i686-pc-linux-gnu]=Linux32.cmake CMAKE_TOOLCHAIN_FILE[x86_64-linux-gnu]=Linux64.cmake CMAKE_TOOLCHAIN_FILE[arm-linux-gnueabihf]=LinuxARM.cmake CMAKE_TOOLCHAIN_FILE[aarch64-linux-gnu]=LinuxAArch64.cmake + INSTALL_COMPONENTS="bitcoind bitcoin-qt bitcoin-seeder" + FAKETIME_HOST_PROGS="" FAKETIME_PROGS="date ar ranlib nm" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" HOST_LDFLAGS=-static-libstdc++ export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export GZIP="-9n" export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} export BASE_CACHE=${GBUILD_PACKAGE_CACHE} mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} cd bitcoin SOURCEDIR=`pwd` BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} mkdir -p source_package pushd source_package cmake -GNinja .. \ -DBUILD_BITCOIN_WALLET=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_SEEDER=OFF \ -DBUILD_BITCOIN_CLI=OFF \ -DBUILD_BITCOIN_TX=OFF \ -DBUILD_BITCOIN_QT=OFF \ -DBUILD_LIBBITCOINCONSENSUS=OFF \ -DENABLE_QRCODE=OFF \ -DENABLE_UPNP=OFF ninja package_source SOURCEDIST=`echo bitcoin-abc-*.tar.gz` mv ${SOURCEDIST} .. popd DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` # Correct tar file order mkdir -p temp pushd temp tar xf ../$SOURCEDIST find bitcoin-abc-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} INSTALLPATH=`pwd`/installed/${DISTNAME} mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${SOURCEDIR}/cmake/platforms/${CMAKE_TOOLCHAIN_FILE[${i}]} \ -DCLIENT_VERSION_IS_RELEASE=ON \ -DENABLE_REDUCE_EXPORTS=ON \ -DENABLE_STATIC_LIBSTDCXX=ON \ -DENABLE_GLIBC_BACK_COMPAT=ON \ -DCMAKE_INSTALL_PREFIX=${INSTALLPATH} \ -DCCACHE=OFF ninja ninja check-security ninja check-symbols - ninja install + + for _component in ${INSTALL_COMPONENTS}; do + cmake -DCOMPONENT=${_component} -P cmake_install.cmake + done cd installed find ${DISTNAME}/bin -type f -executable -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \; find ${DISTNAME}/lib -type f -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \; find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz cd ../../ rm -rf distsrc-${i} done mkdir -p $OUTDIR/src mv $SOURCEDIST $OUTDIR/src diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 497110559..f2f0f045a 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,198 +1,203 @@ --- name: "bitcoin-abc-osx" enable_cache: true distro: "debian" suites: - "buster" architectures: - "amd64" packages: - "autoconf" - "automake" - "bsdmainutils" - "ca-certificates" - "cmake" - "curl" - "faketime" - "fonts-tuffy" - "g++" - "git" - "imagemagick" - "libbz2-dev" - "libcap-dev" - "librsvg2-bin" - "libtiff-tools" - "libtinfo5" - "libtool" - "libz-dev" - "ninja-build" - "pkg-config" - "python3" - "python3-dev" - "python3-setuptools" # FIXME: these dependencies are only required to make CMake happy when building # native tools. They can be removed when the `NativeExecutable.cmake` gets # improved to avoid requiring all the bitcoin-abc dependencies. - "libboost-all-dev" - "libevent-dev" - "libssl-dev" remotes: - "url": "https://github.com/Bitcoin-ABC/bitcoin-abc.git" "dir": "bitcoin" files: - "MacOSX10.11.sdk.tar.gz" script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin14" # CMake toolchain file name differ from host name declare -A CMAKE_TOOLCHAIN_FILE CMAKE_TOOLCHAIN_FILE[x86_64-apple-darwin14]=OSX.cmake + INSTALL_COMPONENTS="bitcoind bitcoin-qt bitcoin-seeder" + FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export GZIP="-9n" export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} export BASE_CACHE=${GBUILD_PACKAGE_CACHE} mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi export ZERO_AR_DATE=1 function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} cd bitcoin SOURCEDIR=`pwd` BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} mkdir -p source_package pushd source_package cmake -GNinja .. \ -DBUILD_BITCOIN_WALLET=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_SEEDER=OFF \ -DBUILD_BITCOIN_CLI=OFF \ -DBUILD_BITCOIN_TX=OFF \ -DBUILD_BITCOIN_QT=OFF \ -DBUILD_LIBBITCOINCONSENSUS=OFF \ -DENABLE_QRCODE=OFF \ -DENABLE_UPNP=OFF ninja package_source SOURCEDIST=`echo bitcoin-abc-*.tar.gz` mv ${SOURCEDIST} .. popd DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` # Correct tar file order mkdir -p temp pushd temp tar xf ../$SOURCEDIST find bitcoin-abc-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} INSTALLPATH=`pwd`/installed/${DISTNAME} mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${SOURCEDIR}/cmake/platforms/${CMAKE_TOOLCHAIN_FILE[${i}]} \ -DCLIENT_VERSION_IS_RELEASE=ON \ -DENABLE_REDUCE_EXPORTS=ON \ -DCMAKE_INSTALL_PREFIX=${INSTALLPATH} \ -DCCACHE=OFF \ -DGENISOIMAGE_EXECUTABLE="${WRAP_DIR}/genisoimage" ninja - ninja install + + for _component in ${INSTALL_COMPONENTS}; do + cmake -DCOMPONENT=${_component} -P cmake_install.cmake + done export PYTHONPATH="${BASEPREFIX}/${i}/native/lib/python3/dist-packages:${PYTHONPATH}" ninja osx-deploydir OSX_VOLNAME="$(cat osx_volname)" mkdir -p unsigned-app-${i} cp osx_volname unsigned-app-${i}/ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i} cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i} cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff mv dist unsigned-app-${i} pushd unsigned-app-${i} find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz popd ninja osx-dmg ${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg cd installed # The install/strip target should do exactly that. However there is a bug in # in the Buster CMake version that causes strip to be called with the wrong # parameters when an Apple strip tool is used. This is fixed starting with # CMake versions >= 3.14, see: # https://gitlab.kitware.com/cmake/cmake/merge_requests/2892 find -path "*.app*" -type f -executable -exec mv {} ${DISTNAME}/bin/bitcoin-qt \; find ${DISTNAME}/bin -type f -executable -exec ${i}-strip -u -r {} \; find ${DISTNAME}/lib -type f -executable -exec ${i}-strip -x {} \; find ${DISTNAME} -not -path "*.app*" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done mkdir -p $OUTDIR/src mv $SOURCEDIST $OUTDIR/src mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-osx64.tar.gz diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index cb8b6163f..0e8af01ab 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,209 +1,215 @@ --- name: "bitcoin-abc-win" enable_cache: true distro: "debian" suites: - "buster" architectures: - "amd64" packages: - "autoconf" - "automake" - "bsdmainutils" - "ca-certificates" - "cmake" - "curl" - "faketime" - "g++" - "g++-mingw-w64" - "git" - "libtool" - "ninja-build" - "mingw-w64" - "nsis" - "pkg-config" - "python3" - "zip" # FIXME: these dependencies are only required to make CMake happy when building # native tools. They can be removed when the `NativeExecutable.cmake` gets # improved to avoid requiring all the bitcoin-abc dependencies. - "libboost-all-dev" - "libevent-dev" - "libssl-dev" remotes: - "url": "https://github.com/Bitcoin-ABC/bitcoin-abc.git" "dir": "bitcoin" files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-w64-mingw32 x86_64-w64-mingw32" # CMake toolchain file name differ from host name declare -A CMAKE_TOOLCHAIN_FILE CMAKE_TOOLCHAIN_FILE[i686-w64-mingw32]=Win32.cmake CMAKE_TOOLCHAIN_FILE[x86_64-w64-mingw32]=Win64.cmake + INSTALL_COMPONENTS="bitcoind bitcoin-qt" + FAKETIME_HOST_PROGS="ar ranlib nm windres strip objcopy" FAKETIME_PROGS="date makensis zip" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export GZIP="-9n" export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} export BASE_CACHE=${GBUILD_PACKAGE_CACHE} mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } function create_per-host_linker_wrapper { # This is only needed for trusty, as the mingw linker leaks a few bytes of # heap, causing non-determinism. See discussion in https://github.com/bitcoin/bitcoin/pull/6900 for i in $HOSTS; do mkdir -p ${WRAP_DIR}/${i} for prog in collect2; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}/${prog} REAL=$(${i}-gcc -print-prog-name=${prog}) echo "export MALLOC_PERTURB_=255" >> ${WRAP_DIR}/${i}/${prog} echo "${REAL} \$@" >> $WRAP_DIR/${i}/${prog} chmod +x ${WRAP_DIR}/${i}/${prog} done for prog in gcc g++; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog}-posix | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" create_per-host_linker_wrapper "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} cd bitcoin SOURCEDIR=`pwd` BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_linker_wrapper "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} mkdir -p source_package pushd source_package cmake -GNinja .. \ -DBUILD_BITCOIN_WALLET=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_SEEDER=OFF \ -DBUILD_BITCOIN_CLI=OFF \ -DBUILD_BITCOIN_TX=OFF \ -DBUILD_BITCOIN_QT=OFF \ -DBUILD_LIBBITCOINCONSENSUS=OFF \ -DENABLE_QRCODE=OFF \ -DENABLE_UPNP=OFF ninja package_source SOURCEDIST=`echo bitcoin-abc-*.tar.gz` mv ${SOURCEDIST} .. popd DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` # Correct tar file order mkdir -p temp pushd temp tar xf ../$SOURCEDIST find bitcoin-abc-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST mkdir -p $OUTDIR/src cp ../$SOURCEDIST $OUTDIR/src popd # Allow extra cmake option to be specified for each host declare -A CMAKE_EXTRA_OPTIONS CMAKE_EXTRA_OPTIONS[i686-w64-mingw32]="-DCPACK_PACKAGE_FILE_NAME=${DISTNAME}-win32-setup-unsigned" CMAKE_EXTRA_OPTIONS[x86_64-w64-mingw32]="-DCPACK_PACKAGE_FILE_NAME=${DISTNAME}-win64-setup-unsigned" ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${WRAP_DIR}:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} INSTALLPATH=`pwd`/installed/${DISTNAME} mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${SOURCEDIR}/cmake/platforms/${CMAKE_TOOLCHAIN_FILE[${i}]} \ -DCLIENT_VERSION_IS_RELEASE=ON \ -DENABLE_REDUCE_EXPORTS=ON \ -DBUILD_BITCOIN_SEEDER=OFF \ -DCPACK_STRIP_FILES=ON \ -DCMAKE_INSTALL_PREFIX=${INSTALLPATH} \ -DCCACHE=OFF \ ${CMAKE_EXTRA_OPTIONS[${i}]} ninja ninja check-security - ninja install + + for _component in ${INSTALL_COMPONENTS}; do + cmake -DCOMPONENT=${_component} -P cmake_install.cmake + done + ninja package cp -f bitcoin-abc-*-setup-unsigned.exe ${OUTDIR}/ cd installed mkdir -p ${DISTNAME}/lib mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ find ${DISTNAME}/bin -type f -executable -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; find ${DISTNAME}/lib -type f -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; find ${DISTNAME} -not -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip find ${DISTNAME} -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}-debug.zip cd ../../ rm -rf distsrc-${i} done cd $OUTDIR find . -name "*-setup-unsigned.exe" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.zip ${OUTDIR}/${DISTNAME}-win64-debug.zip mv ${OUTDIR}/${DISTNAME}-i686-*-debug.zip ${OUTDIR}/${DISTNAME}-win32-debug.zip mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml index 5ba7b9cad..4d7d3d370 100644 --- a/src/secp256k1/.travis.yml +++ b/src/secp256k1/.travis.yml @@ -1,102 +1,103 @@ language: c os: linux dist: xenial addons: apt: sources: - sourceline: 'deb https://apt.kitware.com/ubuntu/ xenial main' key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc' packages: - cmake - libgmp-dev - ninja-build compiler: - clang - gcc env: global: - FIELD=auto - BIGNUM=auto - SCALAR=auto - ENDOMORPHISM=no - STATICPRECOMPUTATION=yes - ASM=no - - BUILD=check + - AUTOTOOLS_TARGET=check + - CMAKE_TARGET=check-secp256k1 - AUTOTOOLS_EXTRA_FLAGS= - CMAKE_EXTRA_FLAGS= - HOST= - ECDH=no - RECOVERY=no - SCHNORR=yes - EXPERIMENTAL=no - JNI=no jobs: - SCALAR=32bit RECOVERY=yes - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes - SCALAR=64bit - FIELD=64bit RECOVERY=yes - FIELD=64bit ENDOMORPHISM=yes - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes - FIELD=64bit ASM=x86_64 - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - FIELD=32bit ENDOMORPHISM=yes - BIGNUM=no - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes - BIGNUM=no STATICPRECOMPUTATION=no - - BUILD=distcheck + - AUTOTOOLS_TARGET=distcheck CMAKE_TARGET=install - AUTOTOOLS_EXTRA_FLAGS=CPPFLAGS=-DDETERMINISTIC CMAKE_EXTRA_FLAGS=-DCMAKE_C_FLAGS=-DDETERMINISTIC - AUTOTOOLS_EXTRA_FLAGS=CFLAGS=-O0 CMAKE_EXTRA_FLAGS=-DCMAKE_C_FLAGS=-O0 - - BUILD=check-java JNI=yes ECDH=yes EXPERIMENTAL=yes + - AUTOTOOLS_TARGET=check-java CMAKE_TARGET=check-secp256k1-java JNI=yes ECDH=yes EXPERIMENTAL=yes - SCHNORR=no jobs: fast_finish: true include: - compiler: clang env: HOST=i686-linux-gnu ENDOMORPHISM=yes addons: apt: sources: - sourceline: 'deb https://apt.kitware.com/ubuntu/ xenial main' key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc' packages: - cmake - gcc-multilib - libgmp-dev:i386 - ninja-build - compiler: clang env: HOST=i686-linux-gnu BIGNUM=no addons: apt: sources: - sourceline: 'deb https://apt.kitware.com/ubuntu/ xenial main' key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc' packages: - cmake - gcc-multilib - ninja-build - compiler: gcc env: HOST=i686-linux-gnu ENDOMORPHISM=yes BIGNUM=no addons: apt: sources: - sourceline: 'deb https://apt.kitware.com/ubuntu/ xenial main' key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc' packages: - cmake - gcc-multilib - ninja-build - compiler: gcc env: HOST=i686-linux-gnu addons: apt: sources: - sourceline: 'deb https://apt.kitware.com/ubuntu/ xenial main' key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc' packages: - cmake - gcc-multilib - libgmp-dev:i386 - ninja-build script: - ./travis/build_autotools.sh - ./travis/build_cmake.sh diff --git a/src/secp256k1/CMakeLists.txt b/src/secp256k1/CMakeLists.txt index 6fab0c5ad..85e00f43d 100644 --- a/src/secp256k1/CMakeLists.txt +++ b/src/secp256k1/CMakeLists.txt @@ -1,288 +1,307 @@ # Copyright (c) 2017 The Bitcoin developers cmake_minimum_required(VERSION 3.13) -project(secp256k1 LANGUAGES C) +project(secp256k1 LANGUAGES C VERSION 0.1.0) # Add path for custom modules when building as a standalone project list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) include(AddCompilerFlags) # libsecp256k1 use a different set of flags. add_c_compiler_flags( -pedantic -Wall -Wextra -Wcast-align -Wshadow -Wno-unused-function -Wno-overlength-strings -std=c89 -Wnested-externs -Wstrict-prototypes -Wno-long-long ) # Default visibility is hidden on all targets. set(CMAKE_C_VISIBILITY_PRESET hidden) include_directories( . src # For the config ${CMAKE_CURRENT_BINARY_DIR}/src ) # The library add_library(secp256k1 src/secp256k1.c) target_include_directories(secp256k1 PUBLIC include) +set(SECP256K1_PUBLIC_HEADERS + include/secp256k1.h + include/secp256k1_preallocated.h +) + option(SECP256K1_ENABLE_BIGNUM "Use the GMP bignum implementation" OFF) if(SECP256K1_ENABLE_BIGNUM) # We need to link in GMP find_package(GMP REQUIRED) target_include_directories(secp256k1 PUBLIC ${GMP_INCLUDE_DIR}) target_link_libraries(secp256k1 ${GMP_LIBRARY}) set(USE_NUM_GMP 1) set(USE_FIELD_INV_NUM 1) set(USE_SCALAR_INV_NUM 1) else() set(USE_NUM_NONE 1) set(USE_FIELD_INV_BUILTIN 1) set(USE_SCALAR_INV_BUILTIN 1) endif() # We check if amd64 asm is supported. check_c_source_compiles(" #include int main() { uint64_t a = 11, tmp; __asm__ __volatile__(\"movq \$0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\"); return 0; } " USE_ASM_X86_64) # We make sure __int128 is defined include(CheckTypeSize) check_type_size(__int128 SIZEOF___INT128) if(SIZEOF___INT128 EQUAL 16) set(HAVE___INT128 1) else() # If we do not support __int128, we should be falling back # on 32bits implementations for field and scalar. endif() # Select the finite field implementation to use. # This can be autodetected or forced by setting USE_FIELD to 32bit or 64bit. # See the truth table below: # +----------------------------------------------------------------------------------------------------------------------+ # | USE_FIELD=64bit | USE_FIELD=32bit | HAVE___INT128 | USE_ASM_X86_64 | USE_FIELD_5X52 | USE_FIELD_10x26 | Config error | # +----------------------------------------------------------------------------------------------------------------------+ # | 0 | 0 | 0 | 0 | 0 | 1 | 0 | # | 0 | 0 | 0 | 1 | 1 | 0 | 0 | # | 0 | 0 | 1 | 0 | 1 | 0 | 0 | # | 0 | 0 | 1 | 1 | 1 | 0 | 0 | # | 0 | 1 | 0 | 0 | 0 | 1 | 0 | # | 0 | 1 | 0 | 1 | 0 | 1 | 0 | # | 0 | 1 | 1 | 0 | 0 | 1 | 0 | # | 0 | 1 | 1 | 1 | 0 | 1 | 0 | # | 1 | 0 | 0 | 0 | 0 | 0 | 1 | # | 1 | 0 | 0 | 1 | 1 | 0 | 0 | # | 1 | 0 | 1 | 0 | 1 | 0 | 0 | # | 1 | 0 | 1 | 1 | 1 | 0 | 0 | # +----------------------------------------------------------------------------------------------------------------------+ set(USE_FIELD "" CACHE STRING "Force the finite field implementation to use (can be 32bit or 64bit)") if(USE_FIELD STREQUAL "64bit" AND NOT (HAVE___INT128 OR USE_ASM_X86_64)) message(SEND_ERROR "64 finite field requested but the compiler does not support __int128 or inline assembly") elseif(NOT USE_FIELD STREQUAL "32bit" AND (HAVE___INT128 OR USE_ASM_X86_64)) set(USE_FIELD_5X52 1) else() set(USE_FIELD_10X26 1) endif() # Select the scalar implementation to use. # This can be autodetected or forced by setting USE_SCALAR to 32bit or 64bit. # See the truth table below: # +--------------------------------------------------------------------------------------------------------+ # | USE_SCALAR=64bit | USE_SCALAR=32bit | HAVE___INT128 | USE_SCALAR_4X64 | USE_SCALAR_8X32 | Config error | # +--------------------------------------------------------------------------------------------------------+ # | 0 | 0 | 0 | 0 | 1 | 0 | # | 0 | 0 | 1 | 1 | 0 | 0 | # | 0 | 1 | 0 | 0 | 1 | 0 | # | 0 | 1 | 1 | 0 | 1 | 0 | # | 1 | 0 | 0 | 0 | 0 | 1 | # | 1 | 0 | 1 | 1 | 0 | 0 | # +--------------------------------------------------------------------------------------------------------+ set(USE_SCALAR "" CACHE STRING "Force the scalar implementation to use (can be 32bit or 64bit)") if(USE_SCALAR STREQUAL "64bit" AND NOT HAVE___INT128) message(SEND_ERROR "64 scalar requested but the compiler does not support __int128") elseif(NOT USE_SCALAR STREQUAL "32bit" AND HAVE___INT128) set(USE_SCALAR_4X64 1) else() set(USE_SCALAR_8X32 1) endif() # Executable internal to secp256k1 need to have the HAVE_CONFIG_H define set. # For convenience, we wrap this into a function. function(link_secp256k1_internal NAME) target_link_libraries(${NAME} secp256k1) target_compile_definitions(${NAME} PRIVATE HAVE_CONFIG_H SECP256K1_BUILD) endfunction(link_secp256k1_internal) # Phony target to build benchmarks add_custom_target(bench-secp256k1) function(add_secp256k1_bench NAME) set(EXECUTABLE_NAME "${NAME}-bench") add_executable(${EXECUTABLE_NAME} EXCLUDE_FROM_ALL ${ARGN}) link_secp256k1_internal(${EXECUTABLE_NAME}) set(BENCH_NAME "bench-secp256k1-${NAME}") add_custom_target(${BENCH_NAME} COMMAND ${EXECUTABLE_NAME} USES_TERMINAL) add_dependencies(bench-secp256k1 ${BENCH_NAME}) endfunction(add_secp256k1_bench) # ECDH module option(SECP256K1_ENABLE_MODULE_ECDH "Build libsecp256k1's ECDH module" OFF) if(SECP256K1_ENABLE_MODULE_ECDH) set(ENABLE_MODULE_ECDH 1) add_secp256k1_bench(ecdh src/bench_ecdh.c) + list(APPEND SECP256K1_PUBLIC_HEADERS include/secp256k1_ecdh.h) endif() # MultiSet module option(SECP256K1_ENABLE_MODULE_MULTISET "Build libsecp256k1's MULTISET module" ON) if(SECP256K1_ENABLE_MODULE_MULTISET) set(ENABLE_MODULE_MULTISET 1) add_secp256k1_bench(multiset src/bench_multiset.c) + list(APPEND SECP256K1_PUBLIC_HEADERS include/secp256k1_multiset.h) endif() # Recovery module option(SECP256K1_ENABLE_MODULE_RECOVERY "Build libsecp256k1's recovery module" ON) if(SECP256K1_ENABLE_MODULE_RECOVERY) set(ENABLE_MODULE_RECOVERY 1) add_secp256k1_bench(recover src/bench_recover.c) + list(APPEND SECP256K1_PUBLIC_HEADERS include/secp256k1_recovery.h) endif() # Schnorr module option(SECP256K1_ENABLE_MODULE_SCHNORR "Build libsecp256k1's Schnorr module" ON) if(SECP256K1_ENABLE_MODULE_SCHNORR) set(ENABLE_MODULE_SCHNORR 1) + list(APPEND SECP256K1_PUBLIC_HEADERS include/secp256k1_schnorr.h) endif() # Endomorphism option(SECP256K1_ENABLE_ENDOMORPHISM "Enable endomorphism" OFF) if(SECP256K1_ENABLE_ENDOMORPHISM) set(USE_ENDOMORPHISM 1) endif() # Make the emult window size customizable. set(SECP256K1_ECMULT_WINDOW_SIZE 15 CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24].") # Static precomputation for elliptic curve multiplication option(SECP256K1_ECMULT_STATIC_PRECOMPUTATION "Precompute libsecp256k1's elliptic curve multiplication tables" ON) if(SECP256K1_ECMULT_STATIC_PRECOMPUTATION) set(USE_ECMULT_STATIC_PRECOMPUTATION 1) if(${SECP256K1_ECMULT_WINDOW_SIZE} LESS 2 OR ${SECP256K1_ECMULT_WINDOW_SIZE} GREATER 24) message(FATAL_ERROR "SECP256K1_ECMULT_WINDOW_SIZE must be an integer in range [2..24]") endif() include(NativeExecutable) native_add_cmake_flags( "-DSECP256K1_ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE}" ) add_native_executable(gen_context src/gen_context.c) add_custom_command( OUTPUT src/ecmult_static_context.h COMMAND gen_context ) target_sources(secp256k1 PRIVATE src/ecmult_static_context.h) endif() +include(InstallationHelper) +if(BUILD_SHARED_LIBS) + install_shared_library(secp256k1 PUBLIC_HEADER ${SECP256K1_PUBLIC_HEADERS}) +else() + set_property(TARGET secp256k1 PROPERTY PUBLIC_HEADER ${SECP256K1_PUBLIC_HEADERS}) + install_target(secp256k1) +endif() + # Generate the config configure_file(src/libsecp256k1-config.h.cmake.in src/libsecp256k1-config.h ESCAPE_QUOTES) target_compile_definitions(secp256k1 PRIVATE HAVE_CONFIG_H SECP256K1_BUILD) # Build the Java binding option(SECP256K1_ENABLE_JNI "Enable the Java Native Interface binding" OFF) if(SECP256K1_ENABLE_JNI) if(NOT SECP256K1_ENABLE_MODULE_ECDH) message(FATAL_ERROR "The secp256k1 JNI support requires ECDH. Try again with -DSECP256K1_ENABLE_MODULE_ECDH=ON.") endif() find_package(Java REQUIRED) find_package(JNI REQUIRED) include(UseJava) add_library(secp256k1_jni SHARED src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c ) + install_shared_library(secp256k1_jni) + target_include_directories(secp256k1_jni PUBLIC ${JNI_INCLUDE_DIRS}) # As per CMake documentation: the POSITION_INDEPENDENT_CODE property is set # when a target is created. It defaults to True for SHARED or MODULE library # targets and False otherwise. # The secp256ki_jni library being shared, the property is set and it will # build with PIC enabled. But the secp256k1 dependency might not have the # property set, so it's associated source files won't be built with PIC # enabled. That would cause the linker to fail. # Forcing the property for the secp256k1 library fixes the issue. set_target_properties(secp256k1 PROPERTIES POSITION_INDEPENDENT_CODE ON) link_secp256k1_internal(secp256k1_jni) endif() # Tests option(SECP256K1_BUILD_TEST "Build secp256k1's unit tests" ON) if(SECP256K1_BUILD_TEST) include(TestSuite) create_test_suite(secp256k1) function(create_secp256k1_test NAME FILES) add_test_to_suite(secp256k1 ${NAME} EXCLUDE_FROM_ALL ${FILES}) link_secp256k1_internal(${NAME}) endfunction() create_secp256k1_test(tests src/tests.c) target_compile_definitions(tests PRIVATE VERIFY) create_secp256k1_test(exhaustive_tests src/tests_exhaustive.c) # This should not be enabled at the same time as coverage is. # TODO: support coverage. target_compile_definitions(exhaustive_tests PRIVATE VERIFY) if(SECP256K1_ENABLE_JNI) set(SECP256k1_JNI_TEST_JAR "secp256k1-jni-test") set(CMAKE_JNI_TARGET TRUE) add_jar(secp256k1-jni-test-jar SOURCES src/java/org/bitcoin/NativeSecp256k1.java src/java/org/bitcoin/NativeSecp256k1Test.java src/java/org/bitcoin/NativeSecp256k1Util.java src/java/org/bitcoin/Secp256k1Context.java ENTRY_POINT org/bitcoin/NativeSecp256k1Test OUTPUT_NAME "${SECP256k1_JNI_TEST_JAR}" ) add_dependencies(secp256k1-jni-test-jar secp256k1_jni) add_custom_target(check-secp256k1-java COMMAND "${Java_JAVA_EXECUTABLE}" "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}" "-jar" "${SECP256k1_JNI_TEST_JAR}.jar" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) add_dependencies(check-secp256k1-java secp256k1-jni-test-jar) add_dependencies(check-secp256k1 check-secp256k1-java) endif() endif(SECP256K1_BUILD_TEST) # Benchmarks add_secp256k1_bench(verify src/bench_verify.c) add_secp256k1_bench(sign src/bench_sign.c) add_secp256k1_bench(internal src/bench_internal.c) add_secp256k1_bench(ecmult src/bench_ecmult.c) diff --git a/src/secp256k1/README.md b/src/secp256k1/README.md index 928bc4703..d3dd393e6 100644 --- a/src/secp256k1/README.md +++ b/src/secp256k1/README.md @@ -1,78 +1,79 @@ libsecp256k1 ============ [![Build Status](https://travis-ci.org/bitcoin-abc/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-abc/secp256k1) Optimized C library for cryptographic operations on curve secp256k1. This library is used for consensus critical cryptographic operations on the Bitcoin Cash network. It is maintained within the Bitcoin ABC repository, and is mirrored as a separate repository for ease of reuse in other Bitcoin Cash projects. Developers who want to contribute may do so at [reviews.bitcoinabc.org](https://reviews.bitcoinabc.org/). Use at your own risk. Features: * secp256k1 ECDSA signing/verification and key generation. * secp256k1 Schnorr signing/verification ([Bitcoin Cash Schnorr variant](https://www.bitcoincash.org/spec/2019-05-15-schnorr.html)). * Adding/multiplying private/public keys. * Serialization/parsing of private keys, public keys, signatures. * Constant time, constant memory access signing and pubkey generation. * Derandomized DSA (via RFC6979 or with a caller provided function.) * Very efficient implementation. Implementation details ---------------------- * General * No runtime heap allocation. * Extensive testing infrastructure. * Structured to facilitate review and analysis. * Intended to be portable to any system with a C89 compiler and uint64_t support. * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") * Field operations * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). * Using 10 26-bit limbs. * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman). * Scalar operations * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. * Using 4 64-bit limbs (relying on __int128 support in the compiler). * Using 8 32-bit limbs. * Group operations * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). * Use addition between points in Jacobian and affine coordinates where possible. * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. * Point multiplication for verification (a*P + b*G). * Use wNAF notation for point multiplicands. * Use a much larger window for multiples of G, using precomputed multiples. * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. * Point multiplication for signing * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. * Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains) * Access the table with branch-free conditional moves so memory access is uniform. * No data-dependent branches * Optional runtime blinding which attempts to frustrate differential power analysis. * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally. Build steps ----------- libsecp256k1 can be built using autotools: ```bash ./autogen.sh mkdir build cd build ../configure make make check sudo make install # optional ``` Or using CMake: ```bash mkdir build cd build cmake -GNinja .. ninja ninja check-secp256k1 +sudo ninja install # optional ``` diff --git a/src/secp256k1/travis/build_autotools.sh b/src/secp256k1/travis/build_autotools.sh index d7c59799f..ccfeb8cf7 100755 --- a/src/secp256k1/travis/build_autotools.sh +++ b/src/secp256k1/travis/build_autotools.sh @@ -1,36 +1,36 @@ #!/usr/bin/env bash export LC_ALL=C set -ex if [ -n "$HOST" ]; then USE_HOST="--host=$HOST" fi if [ "x$HOST" = "xi686-linux-gnu" ]; then CC="$CC -m32" fi ./autogen.sh mkdir buildautotools pushd buildautotools ../configure \ --enable-experimental=$EXPERIMENTAL \ --enable-endomorphism=$ENDOMORPHISM \ --with-field=$FIELD \ --with-bignum=$BIGNUM \ --with-scalar=$SCALAR \ --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION \ --enable-module-ecdh=$ECDH \ --enable-module-recovery=$RECOVERY \ --enable-module-schnorr=$SCHNORR \ --enable-jni=$JNI \ $AUTOTOOLS_EXTRA_FLAGS \ $USE_HOST -make -j2 $BUILD +make -j2 $AUTOTOOLS_TARGET popd diff --git a/src/secp256k1/travis/build_cmake.sh b/src/secp256k1/travis/build_cmake.sh index 9b6e677dc..f252b8598 100755 --- a/src/secp256k1/travis/build_cmake.sh +++ b/src/secp256k1/travis/build_cmake.sh @@ -1,33 +1,34 @@ #!/usr/bin/env bash export LC_ALL=C set -ex if [ "x$HOST" = "xi686-linux-gnu" ]; then CMAKE_EXTRA_FLAGS="-DCMAKE_C_FLAGS=-m32" fi -mkdir -p buildcmake +mkdir -p buildcmake/install pushd buildcmake # Use the cmake version installed via APT instead of the Travis custom one. CMAKE_COMMAND=/usr/bin/cmake ${CMAKE_COMMAND} --version ${CMAKE_COMMAND} -GNinja .. \ + -DCMAKE_INSTALL_PREFIX=install \ -DSECP256K1_ECMULT_STATIC_PRECOMPUTATION=$STATICPRECOMPUTATION \ -DSECP256K1_ENABLE_MODULE_ECDH=$ECDH \ -DSECP256K1_ENABLE_MODULE_RECOVERY=$RECOVERY \ -DSECP256K1_ENABLE_MODULE_SCHNORR=$SCHNORR \ -DSECP256K1_ENABLE_JNI=$JNI \ -DSECP256K1_ENABLE_ENDOMORPHISM=$ENDOMORPHISM \ -DSECP256K1_ENABLE_BIGNUM=$BIGNUM \ -DUSE_ASM_X86_64=$ASM \ -DUSE_FIELD=$FIELD \ -DUSE_SCALAR=$SCALAR \ $CMAKE_EXTRA_FLAGS -ninja check-secp256k1 +ninja $CMAKE_TARGET popd