diff --git a/.gitignore b/.gitignore index f5edb37..547e7a0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ GTAGS *.exe *.swp .cvsignore +build/ +external/ +Testing/ diff --git a/CMakeLists.txt b/CMakeLists.txt index d56f24c..fd0237e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,219 +1,415 @@ -cmake_minimum_required (VERSION 3.0) -project(mcl CXX ASM) -set(SRCS src/fp.cpp) +cmake_minimum_required (VERSION 3.8) + +project(mcl + VERSION 1.22 + LANGUAGES CXX C ASM) option( MCL_MAX_BIT_SIZE "max bit size for Fp" 0 ) +if(MSVC) + option( + MCL_DOWNLOAD_SOURCE + "download cybozulib_ext" + OFF + ) +endif() option( - DOWNLOAD_SOURCE - "download cybozulib_ext" - OFF -) -option( - USE_OPENSSL + MCL_USE_OPENSSL "use openssl" OFF ) option( - USE_GMP + MCL_USE_GMP "use gmp" ON ) option( - USE_ASM + MCL_USE_ASM "use asm" ON ) option( - USE_XBYAK + MCL_USE_XBYAK "use xbyak" ON ) option( - USE_LLVM + MCL_USE_LLVM "use base64.ll with -DCMAKE_CXX_COMPILER=clang++" OFF ) option( - ONLY_LIB - "only lib" + MCL_BUILD_SAMPLE + "Build mcl samples" OFF ) option( - MSVC_RUNTIME_DLL - "use dynamic runtime /MD in msvc builds" + MCL_BUILD_TESTING + "Build mcl tests" OFF ) +if(MSVC) + option( + MCL_MSVC_RUNTIME_DLL + "use dynamic runtime /MD in msvc builds" + OFF + ) +endif() + + +if(MSVC) + set(MCL_CYBOZULIB_EXT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../cybozulib_ext" + CACHE PATH "external cybozulib_ext directory") +endif() + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -if(USE_LLVM) +if(MCL_USE_LLVM AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") + message(WARNING "MCL_USE_LLVM will not be used: requiring clang/clang++.") +endif() + +add_library(mcl SHARED src/fp.cpp) +add_library(mcl::mcl ALIAS mcl) +target_compile_definitions(mcl PUBLIC MCL_NO_AUTOLINK MCLBN_NO_AUTOLINK) +target_include_directories(mcl PUBLIC + $ + $) +set_target_properties(mcl PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(mcl PROPERTIES + OUTPUT_NAME mcl + VERSION ${mcl_VERSION} + SOVERSION ${mcl_VERSION_MAJOR}) +# For semantics of ABI compatibility including when you must bump SOVERSION, see: +# https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B#The_Do.27s_and_Don.27ts + +add_library(mcl_st STATIC src/fp.cpp) +add_library(mcl::mcl_st ALIAS mcl_st) +target_compile_definitions(mcl_st PUBLIC MCL_NO_AUTOLINK MCLBN_NO_AUTOLINK) +target_include_directories(mcl_st PUBLIC + $ + $) +set_target_properties(mcl_st PROPERTIES + OUTPUT_NAME mcl + POSITION_INDEPENDENT_CODE ON) +#set_target_properties(mcl_st PROPERTIES PREFIX "lib") + +if(MCL_USE_LLVM AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_executable(gen src/gen.cpp) - add_custom_target(base64.ll - DEPENDS gen - SOURCES base64.ll - ) + target_include_directories(gen PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/include) + if(MCL_USE_GMP) + find_package(GMP REQUIRED) + target_link_libraries(gen PRIVATE GMP::GMPXX GMP::GMP) + endif() + add_custom_command(OUTPUT base64.ll COMMAND gen > base64.ll - ) - add_custom_target(base64.o - DEPENDS base64.ll - SOURCES base64.o - ) + DEPENDS gen + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_target(gen_base64.ll + SOURCES ${CMAKE_CURRENT_BINARY_DIR}/base64.ll) + add_custom_command(OUTPUT base64.o COMMAND ${CMAKE_CXX_COMPILER} -c -o base64.o base64.ll -O3 -fPIC - ) + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/base64.ll + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_target(gen_base64.o + SOURCES ${CMAKE_CURRENT_BINARY_DIR}/base64.o) + + target_link_libraries(mcl PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/base64.o) + add_dependencies(mcl gen_base64.o) + target_link_libraries(mcl_st PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/base64.o) + add_dependencies(mcl_st gen_base64.o) endif() if(MSVC) - if(MSVC_RUNTIME_DLL) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MD /W4 /Oy /Ox /EHsc /GS- /Zi /DNDEBUG /DNOMINMAX") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /MDd /W4 /DNOMINMAX") - else() - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MT /W4 /Oy /Ox /EHsc /GS- /Zi /DNDEBUG /DNOMINMAX") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /MTd /W4 /DNOMINMAX") - endif() - link_directories(${CMAKE_SOURCE_DIR}/../cybozulib_ext/lib) - link_directories(${CMAKE_SOURCE_DIR}/lib) -else() - if("${CFLAGS_OPT_USER}" STREQUAL "") - set(CFLAGS_OPT_USER "-O3 -DNDEBUG -march=native") + if(MCL_MSVC_RUNTIME_DLL) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MD /Oy /Ox /EHsc /GS- /Zi /DNDEBUG") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /MDd") + else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MT /Oy /Ox /EHsc /GS- /Zi /DNDEBUG") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /MTd") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wformat=2 -Wcast-qual -Wcast-align -Wwrite-strings -Wfloat-equal -Wpointer-arith ${CFLAGS_OPT_USER}") + target_compile_definitions(mcl PUBLIC NOMINMAX) + target_compile_definitions(mcl_st PUBLIC NOMINMAX) + # set compiler flags for warnings level + set(MCL_COMPILE_OPTIONS /W4) + target_compile_options(mcl PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_options(mcl_st PRIVATE ${MCL_COMPILE_OPTIONS}) +else() + # Set compiler flags for warnings + set(MCL_COMPILE_OPTIONS -Wall -Wextra -Wformat=2 -Wcast-qual -Wcast-align + -Wwrite-strings -Wfloat-equal -Wpointer-arith -march=native) + + target_compile_options(mcl PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_options(mcl_st PRIVATE ${MCL_COMPILE_OPTIONS}) + set_target_properties(mcl PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + set_target_properties(mcl_st PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + target_compile_features(mcl PUBLIC cxx_std_11) + target_compile_features(mcl_st PUBLIC cxx_std_11) if(${MCL_MAX_BIT_SIZE} GREATER 0) - add_definitions(-DMCL_MAX_BIT_SIZE=${MCL_MAX_BIT_SIZE}) + target_compile_definitions(mcl PUBLIC MCL_MAX_BIT_SIZE=${MCL_MAX_BIT_SIZE}) + target_compile_definitions(mcl_st PUBLIC MCL_MAX_BIT_SIZE=${MCL_MAX_BIT_SIZE}) endif() - if(USE_LLVM) - add_definitions(-DMCL_USE_LLVM=1 -DMCL_LLVM_BMI2=0) - elseif(USE_ASM) + if(MCL_USE_LLVM AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1 MCL_LLVM_BMI2=0) + target_compile_definitions(mcl_st PUBLIC MCL_USE_LLVM=1 MCL_LLVM_BMI2=0) + elseif(MCL_USE_ASM) if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") - add_definitions(-DMCL_USE_LLVM=1) - set(SRCS ${SRCS} src/asm/aarch64.s) + target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) + target_compile_definitions(mcl_st PUBLIC MCL_USE_LLVM=1) + target_sources(mcl PRIVATE src/asm/aarch64.s) + target_sources(mcl_st PRIVATE src/asm/aarch64.s) set(CPU arch64) elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm") - add_definitions(-DMCL_USE_LLVM=1) - set(SRCS ${SRCS} src/asm/arm.s) + target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) + target_compile_definitions(mcl_st PUBLIC MCL_USE_LLVM=1) + target_sources(mcl PRIVATE src/asm/arm.s) + target_sources(mcl_st PRIVATE src/asm/arm.s) set(CPU arm) elseif(APPLE) - add_definitions(-DMCL_USE_LLVM=1) - set(SRCS ${SRCS} src/asm/x86-64mac.s src/asm/x86-64mac.bmi2.s) + target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) + target_compile_definitions(mcl_st PUBLIC MCL_USE_LLVM=1) + target_sources(mcl PRIVATE src/asm/x86-64mac.s src/asm/x86-64mac.bmi2.s) + target_sources(mcl_st PRIVATE src/asm/x86-64mac.s src/asm/x86-64mac.bmi2.s) set(CPU x86-64) elseif(UNIX) - add_definitions(-DMCL_USE_LLVM=1) - set(SRCS ${SRCS} src/asm/x86-64.s src/asm/x86-64.bmi2.s) + target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) + target_compile_definitions(mcl_st PUBLIC MCL_USE_LLVM=1) + target_sources(mcl PRIVATE src/asm/x86-64.s src/asm/x86-64.bmi2.s) + target_sources(mcl_st PRIVATE src/asm/x86-64.s src/asm/x86-64.bmi2.s) set(CPU x86-64) endif() endif() - if(USE_GMP) - set(EXT_LIBS ${EXT_LIBS} gmp gmpxx) + if(MCL_USE_GMP) + find_package(GMP REQUIRED) + target_link_libraries(mcl PUBLIC GMP::GMPXX GMP::GMP) + target_link_libraries(mcl_st PUBLIC GMP::GMPXX GMP::GMP) endif() - if(USE_OPENSSL) - set(EXT_LIBS ${EXT_LIBS} crypto) + if(MCL_USE_OPENSSL) + find_package(OpenSSL REQUIRED) + target_link_libraries(mcl PUBLIC OpenSSL::Crypto) + target_link_libraries(mcl_st PUBLIC OpenSSL::Crypto) endif() endif() -if(NOT USE_GMP) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMCL_USE_VINT -DMCL_VINT_FIXED_BUFFER") +if(NOT MCL_USE_GMP) + target_compile_definitions(mcl PUBLIC MCL_USE_VINT MCL_VINT_FIXED_BUFFER) + target_compile_definitions(mcl_st PUBLIC MCL_USE_VINT MCL_VINT_FIXED_BUFFER) endif() -if(NOT USE_OPENSSL) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMCL_DONT_USE_OPENSSL") +if(NOT MCL_USE_OPENSSL) + target_compile_definitions(mcl PUBLIC MCL_DONT_USE_OPENSSL) + target_compile_definitions(mcl_st PUBLIC MCL_DONT_USE_OPENSSL) endif() -if(NOT USE_XBYAK) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMCL_DONT_USE_XBYAK") +if(NOT MCL_USE_XBYAK) + target_compile_definitions(mcl PUBLIC MCL_DONT_USE_XBYAK) + target_compile_definitions(mcl_st PUBLIC MCL_DONT_USE_XBYAK) endif() -if(DOWNLOAD_SOURCE) +if(MCL_DOWNLOAD_SOURCE) if(MSVC) + set(CYBOZULIB_EXT_DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/cybozulib_ext) set(CYBOZULIB_EXT_TAG release20170521) set(FILES config.h gmp-impl.h gmp-mparam.h gmp.h gmpxx.h longlong.h mpir.h mpirxx.h) foreach(file IN ITEMS ${FILES}) - file(DOWNLOAD https://raw.githubusercontent.com/herumi/cybozulib_ext/${CYBOZULIB_EXT_TAG}/include/${file} ${mcl_SOURCE_DIR}/include/cybozulib_ext/${file}) + file(DOWNLOAD https://raw.githubusercontent.com/herumi/cybozulib_ext/${CYBOZULIB_EXT_TAG}/include/${file} ${CYBOZULIB_EXT_DOWNLOAD_DIR}/include/${file}) message("download cybozulib_ext/" ${file}) endforeach() set(FILES aes.h applink.c asn1.h asn1_mac.h asn1t.h bio.h blowfish.h bn.h buffer.h camellia.h cast.h cmac.h cms.h comp.h conf.h conf_api.h crypto.h des.h des_old.h dh.h dsa.h dso.h dtls1.h e_os2.h ebcdic.h ec.h ecdh.h ecdsa.h engine.h err.h evp.h hmac.h idea.h krb5_asn.h kssl.h lhash.h md4.h md5.h mdc2.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pem2.h pkcs12.h pkcs7.h pqueue.h rand.h rc2.h rc4.h ripemd.h rsa.h safestack.h seed.h sha.h srp.h srtp.h ssl.h ssl2.h ssl23.h ssl3.h stack.h symhacks.h tls1.h ts.h txt_db.h ui.h ui_compat.h whrlpool.h x509.h x509_vfy.h x509v3.h) foreach(file IN ITEMS ${FILES}) - file(DOWNLOAD https://raw.githubusercontent.com/herumi/cybozulib_ext/${CYBOZULIB_EXT_TAG}/include/openssl/${file} ${mcl_SOURCE_DIR}/include/cybozulib_ext/openssl/${file}) + file(DOWNLOAD + https://raw.githubusercontent.com/herumi/cybozulib_ext/${CYBOZULIB_EXT_TAG}/include/openssl/${file} ${CYBOZULIB_EXT_DOWNLOAD_DIR}/include/openssl/${file}) message("download cybozulib_ext/openssl/" ${file}) endforeach() set(FILES mpir.lib mpirxx.lib mpirxx.pdb ssleay32.lib libeay32.lib mpir.pdb) foreach(file IN ITEMS ${FILES}) - file(DOWNLOAD https://raw.githubusercontent.com/herumi/cybozulib_ext/${CYBOZULIB_EXT_TAG}/lib/mt/14/${file} ${mcl_SOURCE_DIR}/lib/mt/14/${file}) + file(DOWNLOAD + https://raw.githubusercontent.com/herumi/cybozulib_ext/${CYBOZULIB_EXT_TAG}/lib/mt/14/${file} ${CYBOZULIB_EXT_DOWNLOAD_DIR}/lib/mt/14/${file}) message("download lib/mt/14/" ${file}) endforeach() - if(MSVC) - include_directories( - ${mcl_SOURCE_DIR}/include/cybozulib_ext - ) - endif() + + # mpir + add_library(cybozulib_ext::mpir STATIC IMPORTED) + set_target_properties(cybozulib_ext::mpir PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CYBOZULIB_EXT_DOWNLOAD_DIR}/include + IMPORTED_LOCATION ${CYBOZULIB_EXT_DOWNLOAD_DIR}/lib/mt/14/mpir.lib) + # mpirxx + add_library(cybozulib_ext::mpirxx STATIC IMPORTED) + set_target_properties(cybozulib_ext::mpirxx PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CYBOZULIB_EXT_DOWNLOAD_DIR}/include + IMPORTED_LOCATION ${CYBOZULIB_EXT_DOWNLOAD_DIR}/lib/mt/14/mpirxx.lib) + # libeay32 + add_library(cybozulib_ext::libeay32 STATIC IMPORTED) + set_target_properties(cybozulib_ext::libeay32 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CYBOZULIB_EXT_DOWNLOAD_DIR}/include + IMPORTED_LOCATION ${CYBOZULIB_EXT_DOWNLOAD_DIR}/lib/mt/14/libeay32.lib) + # ssleay32 + add_library(cybozulib_ext::ssleay32 STATIC IMPORTED) + set_target_properties(cybozulib_ext::ssleay32 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CYBOZULIB_EXT_DOWNLOAD_DIR}/include + IMPORTED_LOCATION ${CYBOZULIB_EXT_DOWNLOAD_DIR}/lib/mt/14/ssleay32.lib) + # abstracted cybozulib_ext libraries + add_library(windows_specific INTERFACE) + add_library(mcl::windows_specific ALIAS windows_specific) + target_link_libraries(windows_specific INTERFACE + -LIBPATH:${CYBOZULIB_EXT_DOWNLOAD_DIR}/lib + -LIBPATH:${CYBOZULIB_EXT_DOWNLOAD_DIR}/lib/mt/14 + cybozulib_ext::mpir + cybozulib_ext::mpirxx + cybozulib_ext::libeay32 + cybozulib_ext::ssleay32) + + target_link_libraries(mcl PUBLIC mcl::windows_specific) + target_link_libraries(mcl_st PUBLIC mcl::windows_specific) endif() else() if(MSVC) - include_directories( - ${mcl_SOURCE_DIR}/../cybozulib_ext/include - ) + # mpir + add_library(cybozulib_ext::mpir STATIC IMPORTED) + set_target_properties(cybozulib_ext::mpir PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${MCL_CYBOZULIB_EXT_DIR}/include + IMPORTED_LOCATION ${MCL_CYBOZULIB_EXT_DIR}/lib/mt/14/mpir.lib) + # mpirxx + add_library(cybozulib_ext::mpirxx STATIC IMPORTED) + set_target_properties(cybozulib_ext::mpirxx PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${MCL_CYBOZULIB_EXT_DIR}/include + IMPORTED_LOCATION ${MCL_CYBOZULIB_EXT_DIR}/lib/mt/14/mpirxx.lib) + # libeay32 + add_library(cybozulib_ext::libeay32 STATIC IMPORTED) + set_target_properties(cybozulib_ext::libeay32 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${MCL_CYBOZULIB_EXT_DIR}/include + IMPORTED_LOCATION ${MCL_CYBOZULIB_EXT_DIR}/lib/mt/14/libeay32.lib) + # ssleay32 + add_library(cybozulib_ext::ssleay32 STATIC IMPORTED) + set_target_properties(cybozulib_ext::ssleay32 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${MCL_CYBOZULIB_EXT_DIR}/include + IMPORTED_LOCATION ${MCL_CYBOZULIB_EXT_DIR}/lib/mt/14/ssleay32.lib) + # abstracted cybozulib_ext libraries + add_library(windows_specific INTERFACE) + add_library(mcl::windows_specific ALIAS windows_specific) + target_link_libraries(windows_specific INTERFACE + -LIBPATH:${MCL_CYBOZULIB_EXT_DIR}/lib + -LIBPATH:${MCL_CYBOZULIB_EXT_DIR}/lib/mt/14 + cybozulib_ext::mpir + cybozulib_ext::mpirxx + cybozulib_ext::libeay32 + cybozulib_ext::ssleay32) + + target_link_libraries(mcl PUBLIC mcl::windows_specific) + target_link_libraries(mcl_st PUBLIC mcl::windows_specific) endif() endif() -include_directories( - ${mcl_SOURCE_DIR}/include -) +# mclbnXXX +foreach(bit IN ITEMS 256 384 384_256 512) + add_library(mclbn${bit} SHARED src/bn_c${bit}.cpp) + add_library(mcl::mclbn${bit} ALIAS mclbn${bit}) + set_target_properties(mclbn${bit} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + target_compile_options(mclbn${bit} PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_definitions(mclbn${bit} + PUBLIC MCL_NO_AUTOLINK MCLBN_NO_AUTOLINK) + target_link_libraries(mclbn${bit} PUBLIC mcl::mcl) + set_target_properties(mclbn${bit} PROPERTIES + VERSION ${mcl_VERSION} + SOVERSION ${mcl_VERSION_MAJOR}) +endforeach() + +# mclsheXXX +foreach(bit IN ITEMS 256 384 384_256) + add_library(mclshe${bit} SHARED src/she_c${bit}.cpp) + add_library(mcl::mclshe${bit} ALIAS mclshe${bit}) + set_target_properties(mclshe${bit} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + target_compile_options(mclshe${bit} PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_definitions(mclshe${bit} + PUBLIC MCL_NO_AUTOLINK MCLBN_NO_AUTOLINK MCLSHE_NO_AUTOLINK) + target_link_libraries(mclshe${bit} PUBLIC mcl::mcl) + set_target_properties(mclshe${bit} PROPERTIES + VERSION ${mcl_VERSION} + SOVERSION ${mcl_VERSION_MAJOR}) +endforeach() + +# ECDSA +add_library(mclecdsa SHARED src/ecdsa_c.cpp) +add_library(mcl::mclecdsa ALIAS mclecdsa) +set_target_properties(mclecdsa PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) +set_target_properties(mclecdsa PROPERTIES + VERSION ${mcl_VERSION} + SOVERSION ${mcl_VERSION_MAJOR}) +target_link_libraries(mclecdsa PUBLIC mcl::mcl) -if(USE_LLVM) - add_library(mcl SHARED ${SRCS} base64.o) - add_library(mcl_st STATIC ${SRCS} base64.o) - add_dependencies(mcl base64.o) - add_dependencies(mcl_st base64.o) +if(MSVC) + install(TARGETS mcl mcl_st mclbn256 mclbn384 mclbn384_256 mclbn512 mclshe256 + mclshe384 mclshe384_256 windows_specific + EXPORT mclTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION lib) else() - add_library(mcl SHARED ${SRCS}) - add_library(mcl_st STATIC ${SRCS}) + install(TARGETS mcl mcl_st mclbn256 mclbn384 mclbn384_256 mclbn512 mclshe256 + mclshe384 mclshe384_256 + EXPORT mclTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION lib) endif() -target_link_libraries(mcl ${EXT_LIBS}) -target_link_libraries(mcl_st ${EXT_LIBS}) -set_target_properties(mcl_st PROPERTIES OUTPUT_NAME mcl) -#set_target_properties(mcl_st PROPERTIES PREFIX "lib") -#set_target_properties(mcl PROPERTIES OUTPUT_NAME mcl VERSION 1.0.0 SOVERSION 1) -# For semantics of ABI compatibility including when you must bump SOVERSION, see: -# https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B#The_Do.27s_and_Don.27ts +install(DIRECTORY include/mcl + DESTINATION include + FILES_MATCHING PATTERN "*.hpp" + PATTERN "curve_type.h" + PATTERN "bn.h" + PATTERN "bn_c256.h" + PATTERN "bn_c384_256.h" + PATTERN "bn_c384.h") +install(DIRECTORY include/cybozu + DESTINATION include + FILES_MATCHING PATTERN "*.hpp") -set(LIBS mcl ${EXT_LIBS}) -foreach(bit IN ITEMS 256 384 384_256 512) - add_library(mclbn${bit} SHARED src/bn_c${bit}.cpp) - target_link_libraries(mclbn${bit} ${LIBS}) - add_executable(bn_c${bit}_test test/bn_c${bit}_test.cpp) - target_link_libraries(bn_c${bit}_test mclbn${bit}) -endforeach() +install(EXPORT mclTargets + FILE mclTargets.cmake + NAMESPACE mcl:: + DESTINATION lib/cmake/mcl) -file(GLOB MCL_HEADERS include/mcl/*.hpp include/mcl/bn.h include/mcl/curve_type.h include/mcl/bn_c256.h include/mcl/bn_c384_256.h include/mcl/bn_c384.h) -file(GLOB CYBOZULIB_HEADERS include/cybozu/*.hpp) - -install(TARGETS mcl DESTINATION lib) -install(TARGETS mcl_st DESTINATION lib) -install(TARGETS mclbn256 DESTINATION lib) -install(TARGETS mclbn384 DESTINATION lib) -install(TARGETS mclbn384_256 DESTINATION lib) -install(TARGETS mclbn512 DESTINATION lib) -install(FILES ${MCL_HEADERS} DESTINATION include/mcl) -install(FILES include/mcl/impl/bn_c_impl.hpp DESTINATION include/mcl/impl) -install(FILES ${CYBOZULIB_HEADERS} DESTINATION include/cybozu) - -if(NOT ONLY_LIB) - set(TEST_BASE fp_test ec_test fp_util_test window_method_test elgamal_test fp_tower_test gmp_test bn_test glv_test) - #set(TEST_BASE bn_test) - foreach(base IN ITEMS ${TEST_BASE}) - add_executable( - ${base} - test/${base}.cpp - ) - target_link_libraries( - ${base} - ${LIBS} - ) - endforeach() +# support local build-tree export to allow import from external projects +export(EXPORT mclTargets + FILE mclTargets.cmake + NAMESPACE mcl::) +set(CMAKE_EXPORT_PACKAGE_REGISTRY ON) +export(PACKAGE mcl) + + +# Tests +if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR MCL_BUILD_TESTING) + AND BUILD_TESTING) + enable_testing() + add_subdirectory(test) +endif() + +if(MCL_BUILD_SAMPLE) + # sample code + add_subdirectory(sample) endif() diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..a2041a2 --- /dev/null +++ b/build.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +BUILD_DIR=${1:-build} + + +windows_build() +{ + if [ -d "${SCRIPT_DIR}/../cybozulib_ext" ]; then + DOWNLOAD_CYBOZULIB_EXT="OFF" + CYBOZULIB_EXT_OPTION="-DMCL_CYBOZULIB_EXT_DIR:PATH=${SCRIPT_DIR}/../cybozulib_ext" + else + DOWNLOAD_CYBOZULIB_EXT="ON" + CYBOZULIB_EXT_OPTION="" + fi + + cmake -E remove_directory ${BUILD_DIR} + cmake -E make_directory ${BUILD_DIR} + cmake -H${SCRIPT_DIR} -B${BUILD_DIR} -A x64 \ + -DBUILD_TESTING=ON \ + -DMCL_BUILD_SAMPLE=ON \ + -DCMAKE_INSTALL_PREFIX=${BUILD_DIR}/install \ + -DMCL_DOWNLOAD_SOURCE=${DOWNLOAD_CYBOZULIB_EXT} ${CYBOZULIB_EXT_OPTION} + cmake --build ${BUILD_DIR} --clean-first --config Release --parallel +} + +linux_build() +{ + cmake -E remove_directory ${BUILD_DIR} + cmake -E make_directory ${BUILD_DIR} + cmake -H${SCRIPT_DIR} -B${BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DMCL_BUILD_SAMPLE=ON \ + -DMCL_USE_LLVM=ON \ + -DMCL_USE_OPENSSL=ON \ + -DCMAKE_INSTALL_PREFIX=${BUILD_DIR}/install + cmake --build ${BUILD_DIR} --clean-first -- -j +} + +osx_build() +{ + OPENSSL_ROOT_DIR="/usr/local/opt/openssl" + + cmake -E remove_directory ${BUILD_DIR} + cmake -E make_directory ${BUILD_DIR} + cmake -H${SCRIPT_DIR} -B${BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DMCL_BUILD_SAMPLE=ON \ + -DMCL_USE_LLVM=ON \ + -DMCL_USE_OPENSSL=ON \ + -DOPENSSL_ROOT_DIR="${OPENSSL_ROOT_DIR}" \ + -DCMAKE_INSTALL_PREFIX=${BUILD_DIR}/install + cmake --build ${BUILD_DIR} --clean-first -- -j +} + +os=`uname -s` +case "${os}" in + CYGWIN*|MINGW32*|MSYS*|MINGW*) + windows_build + ;; + Darwin*) + osx_build + ;; + *) + linux_build + ;; +esac diff --git a/cmake/FindGMP.cmake b/cmake/FindGMP.cmake new file mode 100644 index 0000000..58c9b96 --- /dev/null +++ b/cmake/FindGMP.cmake @@ -0,0 +1,88 @@ +# FindGMP.cmake +# +# Finds the GNU Multiple Precision Arithmetic Library (GMP) +# See http://gmplib.org/ +# +# This will define the following variables:: +# +# GMP_FOUND +# GMP_VERSION +# GMP_DEFINITIONS +# GMP_INCLUDE_DIR +# GMP_LIBRARY +# GMP_GMPXX_DEFINITIONS +# GMP_GMPXX_INCLUDE_DIR +# GMP_GMPXX_LIBRARY +# +# and the following imported targets:: +# +# GMP::GMP +# GMP::GMPXX + +find_package(PkgConfig QUIET) +pkg_check_modules(PC_GMP QUIET gmp gmpxx) + +set(GMP_VERSION ${PC_GMP_gmp_VERSION}) + +find_library(GMP_LIBRARY + NAMES gmp libgmp + HINTS + ${PC_GMP_gmp_LIBDIR} + ${PC_GMP_gmp_LIBRARY_DIRS}) + +find_path(GMP_INCLUDE_DIR + NAMES gmp.h + HINTS + ${PC_GMP_gmp_INCLUDEDIR} + ${PC_GMP_gmp_INCLUDE_DIRS}) + +find_library(GMP_GMPXX_LIBRARY + NAMES gmpxx libgmpxx + HINTS + ${PC_GMP_gmpxx_LIBDIR} + ${PC_GMP_gmpxx_LIBRARY_DIRS}) + +find_path(GMP_GMPXX_INCLUDE_DIR + NAMES gmpxx.h + HINTS + ${PC_GMP_gmpxx_INCLUDEDIR} + ${PC_GMP_gmpxx_INCLUDE_DIRS}) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GMP + REQUIRED_VARS + GMP_INCLUDE_DIR + GMP_LIBRARY + GMP_GMPXX_INCLUDE_DIR + GMP_GMPXX_LIBRARY + VERSION_VAR GMP_VERSION) + +if(GMP_FOUND) + set(GMP_LIBRARIES ${GMP_LIBRARY}) + set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) + set(GMP_DEFINITIONS ${PC_GMP_gmp_CFLAGS_OTHER}) + set(GMP_GMPXX_LIBRARIES ${GMP_GMPXX_LIBRARY}) + set(GMP_GMPXX_INCLUDE_DIRS ${GMP_GMPXX_INCLUDE_DIR}) + set(GMP_GMPXX_DEFINITIONS ${PC_GMP_gmpxx_CFLAGS_OTHER}) + + if(NOT TARGET GMP::GMP) + add_library(GMP::GMP UNKNOWN IMPORTED) + set_target_properties(GMP::GMP PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_GMP_gmp_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${GMP_INCLUDE_DIR}" + IMPORTED_LOCATION "${GMP_LIBRARY}") + endif() + + if(NOT TARGET GMP::GMPXX) + add_library(GMP::GMPXX UNKNOWN IMPORTED) + set_target_properties(GMP::GMPXX PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_GMP_gmpxx_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${GMP_GMPXX_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES GMP::GMP + IMPORTED_LOCATION "${GMP_GMPXX_LIBRARY}") + endif() +endif() + +mark_as_advanced(GMP_FOUND GMP_INCLUDE_DIR GMP_LIBRARY) +mark_as_advanced(GMP_GMPXX_INCLUDE_DIR GMP_GMPXX_LIBRARY) diff --git a/readme.md b/readme.md index 4548086..cf6ed15 100644 --- a/readme.md +++ b/readme.md @@ -152,6 +152,11 @@ cmake .. -A x64 msbuild mcl.sln /p:Configuration=Release /m ``` +For your convenience you could use the build script `build.sh` on Linux, macOS and +Windows (requires Git Bash). + +On Windows, `build.sh` expects [cybozulib_ext](https://github.com/herumi/cybozulib_ext) to be within the same parent directory, otherwise, it will be downloaded into `external\cybozulib_ext` directory. + ## options ``` diff --git a/sample/CMakeLists.txt b/sample/CMakeLists.txt new file mode 100644 index 0000000..f0fffbd --- /dev/null +++ b/sample/CMakeLists.txt @@ -0,0 +1,17 @@ +# Samples +set(MCL_SAMPLE bench ecdh random rawbench vote pairing large tri-dh bls_sig she_smpl) +foreach(sample IN ITEMS ${MCL_SAMPLE}) + add_executable(sample_${sample} ${sample}.cpp) + target_link_libraries(sample_${sample} PRIVATE mcl::mcl) + set_target_properties(sample_${sample} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + target_compile_options(sample_${sample} PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_definitions(sample_${sample} PRIVATE MCL_DONT_EXPORT) +endforeach() + +# C interface Sample +add_executable(sample_pairing_c_min pairing_c.c) +target_link_libraries(sample_pairing_c_min PRIVATE mcl::mclbn384_256) +target_compile_definitions(sample_pairing_c_min PRIVATE MCL_DONT_EXPORT) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..22efd78 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,62 @@ +# Tests +set(MCL_TEST_BASE fp_test ec_test fp_util_test window_method_test elgamal_test + fp_tower_test gmp_test bn_test glv_test) +foreach(base IN ITEMS ${MCL_TEST_BASE}) + add_executable(${base} ${base}.cpp) + target_link_libraries(${base} PRIVATE mcl::mcl) + set_target_properties(${base} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + target_compile_options(${base} PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_definitions(${base} PRIVATE MCL_DONT_EXPORT) + add_test(NAME ${base} COMMAND ${base}) +endforeach() + +# Tests for mclbnXXX +foreach(bit IN ITEMS 256 384 384_256 512) + add_executable(bn_c${bit}_test bn_c${bit}_test.cpp) + target_link_libraries(bn_c${bit}_test PRIVATE mcl::mclbn${bit}) + set_target_properties(bn_c${bit}_test PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + target_compile_options(bn_c${bit}_test PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_definitions(bn_c${bit}_test PRIVATE MCLBN_DONT_EXPORT) + add_test(NAME bn_c${bit}_test COMMAND bn_c${bit}_test) +endforeach() + +# Tests for mclsheXXX +foreach(bit IN ITEMS 256 384 384_256) + add_executable(she_c${bit}_test she_c${bit}_test.cpp) + target_link_libraries(she_c${bit}_test PRIVATE mcl::mclshe${bit}) + set_target_properties(she_c${bit}_test PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + target_compile_options(she_c${bit}_test PRIVATE ${MCL_COMPILE_OPTIONS}) + target_compile_definitions(she_c${bit}_test PRIVATE MCLBN_DONT_EXPORT) + add_test(NAME she_c${bit}_test COMMAND she_c${bit}_test) +endforeach() + +# ecdsa_test +add_executable(ecdsa_test ecdsa_test.cpp) +target_link_libraries(ecdsa_test PRIVATE mcl::mclecdsa) +set_target_properties(ecdsa_test PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) +target_compile_options(ecdsa_test PRIVATE ${MCL_COMPILE_OPTIONS}) +target_compile_definitions(ecdsa_test PRIVATE MCLBN_DONT_EXPORT) +add_test(NAME ecdsa_test COMMAND ecdsa_test) + +# ecdsa_c_test +add_executable(ecdsa_c_test ecdsa_c_test.cpp) +target_link_libraries(ecdsa_c_test PRIVATE mcl::mclecdsa) +set_target_properties(ecdsa_c_test PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) +target_compile_options(ecdsa_c_test PRIVATE ${MCL_COMPILE_OPTIONS}) +target_compile_definitions(ecdsa_c_test PRIVATE MCLBN_DONT_EXPORT) +add_test(NAME ecdsa_c_test COMMAND ecdsa_c_test)