commit
fec57a49f5
@ -0,0 +1,25 @@ |
||||
name: test |
||||
on: [push] |
||||
|
||||
jobs: |
||||
build: |
||||
name: test |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
- run: lscpu |
||||
- run: sudo apt install valgrind |
||||
- run: make bin/pairing.exe -j4 |
||||
- run: valgrind bin/pairing.exe |
||||
- run: make clean |
||||
# - run: wget https://software.intel.com/content/dam/develop/external/us/en/documents/downloads/sde-external-8.63.0-2021-01-18-lin.tar.bz2 |
||||
# - run: bzip2 -dc sde-external-8.63.0-2021-01-18-lin.tar.bz2 | tar xvf - |
||||
# - run: make bin/bn_test.exe DEBUG=1 -j4 |
||||
# - run: sde-external-8.63.0-2021-01-18-lin/sde64 -hsw -- bin/bn_test.exe |
||||
- run: make test_ci DEBUG=1 -j4 |
||||
- run: make clean |
||||
- run: make test_ci DEBUG=1 -j4 CXX=clang++ |
||||
- run: make clean |
||||
# - run: make test_go |
||||
# - run: sudo apt install openjdk-8-jdk |
||||
# - run: make -C ffi/java test JAVA_INC=-I/usr/lib/jvm/java-8-openjdk-amd64/include |
@ -1,17 +0,0 @@ |
||||
sudo: true |
||||
dist: trusty |
||||
language: cpp |
||||
compiler: |
||||
- gcc |
||||
- clang |
||||
addons: |
||||
apt: |
||||
packages: |
||||
- libgmp-dev |
||||
script: |
||||
- make test_ci DEBUG=1 -j3 |
||||
- make clean |
||||
- make test_ci CFLAGS_USER=-DMCL_DONT_USE_XBYAK -j3 |
||||
- make clean |
||||
- make test_go |
||||
|
@ -1,209 +1,395 @@ |
||||
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) |
||||
|
||||
set(CMAKE_BUILD_TYPE "Release") |
||||
|
||||
option( |
||||
MCL_MAX_BIT_SIZE |
||||
"max bit size for Fp" |
||||
0 |
||||
384 |
||||
) |
||||
option( |
||||
DOWNLOAD_SOURCE |
||||
"download cybozulib_ext" |
||||
MCL_STATIC_LIB |
||||
"build static library" |
||||
OFF |
||||
) |
||||
if(MSVC) |
||||
option( |
||||
MCL_DOWNLOAD_SOURCE |
||||
"download cybozulib_ext" |
||||
OFF |
||||
) |
||||
endif() |
||||
option( |
||||
USE_OPENSSL |
||||
MCL_USE_OPENSSL |
||||
"use openssl" |
||||
ON |
||||
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( |
||||
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 |
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> |
||||
$<INSTALL_INTERFACE:$CMAKE_INSTALL_DIR/include>) |
||||
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 |
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> |
||||
$<INSTALL_INTERFACE:$CMAKE_INSTALL_DIR/include>) |
||||
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) |
||||
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") |
||||
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 -DNDEBUG -O3 -fPIC) |
||||
|
||||
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) |
||||
if (MCL_STATIC_LIB) |
||||
add_library(mclbn${bit} STATIC src/bn_c${bit}.cpp) |
||||
else() |
||||
add_library(mclbn${bit} SHARED src/bn_c${bit}.cpp) |
||||
endif() |
||||
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() |
||||
|
||||
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 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 |
||||
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) |
||||
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() |
||||
|
@ -0,0 +1,548 @@ |
||||
# C API |
||||
|
||||
## News |
||||
|
||||
APIs for old ethreum hash functions are removed. |
||||
`mclBn_setMapToMode` supports only `MCL_MAP_TO_MODE_ETH2`. |
||||
|
||||
## Minimum sample |
||||
|
||||
[sample/pairing_c.c](sample/pairing_c.c) is a sample of how to use BLS12-381 pairing. |
||||
|
||||
``` |
||||
cd mcl |
||||
make -j4 |
||||
make bin/pairing_c.exe && bin/pairing_c.exe |
||||
``` |
||||
|
||||
## Header and libraries |
||||
|
||||
To use BLS12-381, include `mcl/bn_c384_256.h` and link |
||||
- libmclbn384_256.{a,so} |
||||
- libmcl.{a,so} ; core library |
||||
|
||||
`384_256` means the max bit size of `Fp` is 384 and that size of `Fr` is 256. |
||||
|
||||
## Notation |
||||
|
||||
The elliptic equation of a curve E is `E: y^2 = x^3 + b`. |
||||
|
||||
- `Fp` ; a finite field of a prime order `p`, where curves is defined over. |
||||
- `Fr` ; a finite field of a prime order `r`. |
||||
- `Fp2` ; the field extension over Fp with degree 2. Fp[i] / (i^2 + 1). |
||||
- `Fp6` ; the field extension over Fp2 with degree 3. Fp2[v] / (v^3 - Xi) where Xi = i + 1. |
||||
- `Fp12` ; the field extension over Fp6 with degree 2. Fp6[w] / (w^2 - v). |
||||
- `G1` ; the cyclic subgroup of E(Fp). |
||||
- `G2` ; the cyclic subgroup of the inverse image of E'(Fp^2) under a twisting isomorphism from E' to E. |
||||
- `GT` ; the cyclie subgroup of Fp12. |
||||
- `G1`, `G2` and `GT` have the order `r`. |
||||
|
||||
The pairing e: G1 x G2 -> GT is the optimal ate pairing. |
||||
|
||||
mcl treats `G1` and `G2` as an additive group and `GT` as a multiplicative group. |
||||
|
||||
- `mclSize` ; `unsigned int` if WebAssembly else `size_t` |
||||
|
||||
### Curve Parameter |
||||
r = |G1| = |G2| = |GT| |
||||
|
||||
curveType | b| r and p | |
||||
------------|--|------------------| |
||||
BN254 | 2|r = 0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d <br> p = 0x2523648240000001ba344d80000000086121000000000013a700000000000013 | |
||||
BLS12-381 | 4|r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 <br> p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab | |
||||
BN381 | 2|r = 0x240026400f3d82b2e42de125b00158405b710818ac000007e0042f008e3e00000000001080046200000000000000000d <br> p = 0x240026400f3d82b2e42de125b00158405b710818ac00000840046200950400000000001380052e000000000000000013 | |
||||
|
||||
## Structures |
||||
|
||||
### `mclBnFp` |
||||
This is a struct of `Fp`. The value is stored as Montgomery representation. |
||||
|
||||
### `mclBnFr` |
||||
This is a struct of `Fr`. The value is stored as Montgomery representation. |
||||
|
||||
### `mclBnFp2` |
||||
This is a struct of `Fp2` which has a member `mclBnFp d[2]`. |
||||
|
||||
An element `x` of `Fp2` is represented as `x = d[0] + d[1] i` where `i^2 = -1`. |
||||
|
||||
### `mclBnG1` |
||||
This is a struct of `G1` which has three members `x`, `y`, `z` of type `mclBnFp`. |
||||
|
||||
An element `P` of `G1` is represented as `P = [x:y:z]` of a Jacobi coordinate. |
||||
|
||||
### `mclBnG2` |
||||
This is a struct of `G2` which has three members `x`, `y`, `z` of type `mclBnFp2`. |
||||
|
||||
An element `Q` of `G2` is represented as `Q = [x:y:z]` of a Jacobi coordinate. |
||||
|
||||
### `mclBnGT` |
||||
|
||||
This is a struct of `GT` which has a member `mclBnFp d[12]`. |
||||
|
||||
### sizeof |
||||
|
||||
library |MCLBN_FR_UNIT_SIZE|MCLBN_FP_UNIT_SIZE|sizeof Fr|sizeof Fp| |
||||
------------------|------------------|------------------|---------|---------| |
||||
libmclbn256.a | 4 | 4 | 32 | 32 | |
||||
libmclbn384_256.a | 4 | 6 | 32 | 48 | |
||||
libmclbn384.a | 6 | 6 | 48 | 48 | |
||||
|
||||
## Thread safety |
||||
All functions except for initialization and changing global setting are thread-safe. |
||||
|
||||
## Initialization |
||||
|
||||
Initialize mcl library. Call this function at first before calling the other functions. |
||||
|
||||
``` |
||||
int mclBn_init(int curve, int compiledTimeVar); |
||||
``` |
||||
|
||||
- `curve` ; specify the curve type |
||||
- MCL_BN254 ; BN254 (a little faster if including `mcl/bn_c256.h` and linking `libmclbn256.{a,so}`) |
||||
- MCL_BN_SNARK1 ; the same parameter used in libsnark |
||||
- MCL_BLS12_381 ; BLS12-381 |
||||
- MCL_BN381_1 ; BN381 (include `mcl/bn_c384.h` and link `libmclbn384.{a,so}`) |
||||
- `compiledTimeVar` ; set `MCLBN_COMPILED_TIME_VAR`, which macro is used to make sure that |
||||
the values are the same when the library is built and used. |
||||
- return 0 if success. |
||||
- This is not thread safe. |
||||
|
||||
## Global setting |
||||
|
||||
``` |
||||
int mclBn_setMapToMode(int mode); |
||||
``` |
||||
The map-to-G2 function if `mode = MCL_MAP_TO_MODE_HASH_TO_CURVE`. |
||||
|
||||
### Control to verify that a point of the elliptic curve has the order `r`. |
||||
|
||||
This function affects `setStr()` and `deserialize()` for G1/G2. |
||||
``` |
||||
void mclBn_verifyOrderG1(int doVerify); |
||||
void mclBn_verifyOrderG2(int doVerify); |
||||
``` |
||||
- verify if `doVerify` is 1 or does not. The default parameter is 0 because the cost of verification is not small. |
||||
- Set `doVerify = 1` if considering subgroup attack is necessary. |
||||
- This is not thread safe. |
||||
|
||||
## Setter / Getter |
||||
|
||||
### Clear |
||||
Set `x` is zero. |
||||
``` |
||||
void mclBnFr_clear(mclBnFr *x); |
||||
void mclBnFp_clear(mclBnFp *x); |
||||
void mclBnFp2_clear(mclBnFp2 *x); |
||||
void mclBnG1_clear(mclBnG1 *x); |
||||
void mclBnG2_clear(mclBnG2 *x); |
||||
void mclBnGT_clear(mclBnGT *x); |
||||
``` |
||||
|
||||
### Set `x` to `y`. |
||||
``` |
||||
void mclBnFp_setInt(mclBnFp *y, mclInt x); |
||||
void mclBnFr_setInt(mclBnFr *y, mclInt x); |
||||
void mclBnGT_setInt(mclBnGT *y, mclInt x); |
||||
``` |
||||
|
||||
### Set `buf[0..bufSize-1]` to `x` with masking according to the following way. |
||||
``` |
||||
int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize); |
||||
int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize); |
||||
``` |
||||
1. set x = buf[0..bufSize-1] as little endian |
||||
2. x &= (1 << bitLen(r)) - 1 |
||||
3. if (x >= r) x &= (1 << (bitLen(r) - 1)) - 1 |
||||
|
||||
- always return 0 |
||||
|
||||
### Set (`buf[0..bufSize-1]` mod `p` or `r`) to `x`. |
||||
``` |
||||
int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize); |
||||
int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize); |
||||
``` |
||||
- return 0 if bufSize <= (sizeof(*x) * 8 * 2) else -1 |
||||
|
||||
### Get little endian byte sequence `buf` corresponding to `x` |
||||
``` |
||||
mclSize mclBnFr_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFr *x); |
||||
mclSize mclBnFp_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFp *x); |
||||
``` |
||||
- write `x` to `buf` as little endian |
||||
- return the written size if sucess else 0 |
||||
- NOTE: `buf[0] = 0` and return 1 if `x` is zero. |
||||
|
||||
### Serialization |
||||
### Serialize |
||||
``` |
||||
mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mclBnFr *x); |
||||
mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x); |
||||
mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x); |
||||
mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x); |
||||
mclSize mclBnFp_serialize(void *buf, mclSize maxBufSize, const mclBnFp *x); |
||||
mclSize mclBnFp2_serialize(void *buf, mclSize maxBufSize, const mclBnFp2 *x); |
||||
``` |
||||
- serialize `x` into `buf[0..maxBufSize-1]` |
||||
- return written byte size if success else 0 |
||||
|
||||
### Serialization format |
||||
- `Fp`(resp. `Fr`) ; a little endian byte sequence with a fixed size |
||||
- the size is the return value of `mclBn_getFpByteSize()` (resp. `mclBn_getFpByteSize()`). |
||||
- `G1` ; a compressed fixed size |
||||
- the size is equal to `mclBn_getG1ByteSize()` (=`mclBn_getFpByteSize()`). |
||||
- `G2` ; a compressed fixed size |
||||
- the size is equal to `mclBn_getG1ByteSize() * 2`. |
||||
|
||||
pseudo-code to serialize of `P` of `G1` (resp. `G2`) |
||||
``` |
||||
size = mclBn_getG1ByteSize() # resp. mclBn_getG1ByteSize() * 2 |
||||
if P is zero: |
||||
return [0] * size |
||||
else: |
||||
P = P.normalize() |
||||
s = P.x.serialize() |
||||
# x in Fp2 is odd <=> x.a is odd |
||||
if P.y is odd: # resp. P.y.d[0] is odd |
||||
s[byte-length(s) - 1] |= 0x80 |
||||
return s |
||||
``` |
||||
|
||||
### Ethereum serialization mode for BLS12-381 |
||||
``` |
||||
void mclBn_setETHserialization(int ETHserialization); |
||||
``` |
||||
- serialize according to [serialization of BLS12-381](https://github.com/zkcrypto/pairing/blob/master/src/bls12_381/README.md#serialization) if BLS12-381 is used and `ETHserialization = 1` (default 0). |
||||
|
||||
### Deserialize |
||||
``` |
||||
mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize bufSize); |
||||
mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize); |
||||
mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize); |
||||
mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize); |
||||
mclSize mclBnFp_deserialize(mclBnFp *x, const void *buf, mclSize bufSize); |
||||
mclSize mclBnFp2_deserialize(mclBnFp2 *x, const void *buf, mclSize bufSize); |
||||
``` |
||||
- deserialize `x` from `buf[0..bufSize-1]` |
||||
- return read size if success else 0 |
||||
|
||||
## String conversion |
||||
### Get string |
||||
``` |
||||
mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnFr *x, int ioMode); |
||||
mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode); |
||||
mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode); |
||||
mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode); |
||||
mclSize mclBnFp_getStr(char *buf, mclSize maxBufSize, const mclBnFp *x, int ioMode); |
||||
``` |
||||
- write `x` to `buf` according to `ioMode` |
||||
- `ioMode` |
||||
- 10 ; decimal number |
||||
- 16 ; hexadecimal number |
||||
- `MCLBN_IO_EC_PROJ` ; output as Jacobi coordinate |
||||
- return `strlen(buf)` if success else 0. |
||||
|
||||
The meaning of the output of `G1`. |
||||
- `0` ; infinity |
||||
- `1 <x> <y>` ; affine coordinate |
||||
- `4 <x> <y> <z>` ; Jacobi coordinate |
||||
- the element `<x>` of `G2` outputs `d[0] d[1]`. |
||||
|
||||
### Set string |
||||
``` |
||||
int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, int ioMode); |
||||
int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode); |
||||
int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode); |
||||
int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode); |
||||
int mclBnFp_setStr(mclBnFp *x, const char *buf, mclSize bufSize, int ioMode); |
||||
``` |
||||
- set `buf[0..bufSize-1]` to `x` accoring to `ioMode` |
||||
- return 0 if success else -1 |
||||
|
||||
If you want to use the same generators of BLS12-381 with [zkcrypto](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#g2) then, |
||||
|
||||
``` |
||||
mclBnG1 P; |
||||
mclBnG1_setStr(&P, "1 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569", 10); |
||||
|
||||
mclBnG2 Q; |
||||
mclBnG2_setStr(&Q, "1 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582"); |
||||
``` |
||||
|
||||
|
||||
## Set random value |
||||
Set `x` by cryptographically secure pseudo random number generator. |
||||
``` |
||||
int mclBnFr_setByCSPRNG(mclBnFr *x); |
||||
int mclBnFp_setByCSPRNG(mclBnFp *x); |
||||
``` |
||||
|
||||
### Change random generator function |
||||
``` |
||||
void mclBn_setRandFunc( |
||||
void *self, |
||||
unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize) |
||||
); |
||||
``` |
||||
- `self` ; user-defined pointer |
||||
- `readFunc` ; user-defined function, which writes random `bufSize` bytes to `buf` and returns `bufSize` if success else returns 0. |
||||
- `readFunc` must be thread-safe. |
||||
- Set the default random function if `self == 0` and `readFunc == 0`. |
||||
- This is not thread safe. |
||||
|
||||
## Arithmetic operations |
||||
### neg / inv / sqr / add / sub / mul / div of `Fr`, `Fp`, `Fp2`, `GT`. |
||||
``` |
||||
void mclBnFr_neg(mclBnFr *y, const mclBnFr *x); |
||||
void mclBnFr_inv(mclBnFr *y, const mclBnFr *x); |
||||
void mclBnFr_sqr(mclBnFr *y, const mclBnFr *x); |
||||
void mclBnFr_add(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); |
||||
void mclBnFr_sub(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); |
||||
void mclBnFr_mul(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); |
||||
void mclBnFr_div(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); |
||||
|
||||
void mclBnFp_neg(mclBnFp *y, const mclBnFp *x); |
||||
void mclBnFp_inv(mclBnFp *y, const mclBnFp *x); |
||||
void mclBnFp_sqr(mclBnFp *y, const mclBnFp *x); |
||||
void mclBnFp_add(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); |
||||
void mclBnFp_sub(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); |
||||
void mclBnFp_mul(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); |
||||
void mclBnFp_div(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); |
||||
|
||||
void mclBnFp2_neg(mclBnFp2 *y, const mclBnFp2 *x); |
||||
void mclBnFp2_inv(mclBnFp2 *y, const mclBnFp2 *x); |
||||
void mclBnFp2_sqr(mclBnFp2 *y, const mclBnFp2 *x); |
||||
void mclBnFp2_add(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); |
||||
void mclBnFp2_sub(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); |
||||
void mclBnFp2_mul(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); |
||||
void mclBnFp2_div(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); |
||||
|
||||
void mclBnGT_inv(mclBnGT *y, const mclBnGT *x); // y = a - bw for x = a + bw where Fp12 = Fp6[w] |
||||
void mclBnGT_sqr(mclBnGT *y, const mclBnGT *x); |
||||
void mclBnGT_mul(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); |
||||
void mclBnGT_div(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); |
||||
``` |
||||
- use `mclBnGT_invGeneric` for an element in Fp12 - GT. |
||||
|
||||
- NOTE: The following functions do NOT return a GT element because GT is multiplicative group. |
||||
|
||||
``` |
||||
void mclBnGT_neg(mclBnGT *y, const mclBnGT *x); |
||||
void mclBnGT_add(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); |
||||
void mclBnGT_sub(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); |
||||
``` |
||||
|
||||
### Square root of `x`. |
||||
``` |
||||
int mclBnFr_squareRoot(mclBnFr *y, const mclBnFr *x); |
||||
int mclBnFp_squareRoot(mclBnFp *y, const mclBnFp *x); |
||||
int mclBnFp2_squareRoot(mclBnFp2 *y, const mclBnFp2 *x); |
||||
``` |
||||
- `y` is one of square root of `x` if `y` exists. |
||||
- return 0 if success else -1 |
||||
|
||||
### add / sub / dbl / neg for `G1` and `G2`. |
||||
``` |
||||
void mclBnG1_neg(mclBnG1 *y, const mclBnG1 *x); |
||||
void mclBnG1_dbl(mclBnG1 *y, const mclBnG1 *x); |
||||
void mclBnG1_add(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y); |
||||
void mclBnG1_sub(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y); |
||||
|
||||
void mclBnG2_neg(mclBnG2 *y, const mclBnG2 *x); |
||||
void mclBnG2_dbl(mclBnG2 *y, const mclBnG2 *x); |
||||
void mclBnG2_add(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y); |
||||
void mclBnG2_sub(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y); |
||||
``` |
||||
|
||||
### Convert a point from Jacobi coordinate to affine. |
||||
``` |
||||
void mclBnG1_normalize(mclBnG1 *y, const mclBnG1 *x); |
||||
void mclBnG2_normalize(mclBnG2 *y, const mclBnG2 *x); |
||||
``` |
||||
- convert `[x:y:z]` to `[x:y:1]` if `z != 0` else `[*:*:0]` |
||||
|
||||
### scalar multiplication |
||||
``` |
||||
void mclBnG1_mul(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y); |
||||
void mclBnG2_mul(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y); |
||||
void mclBnGT_pow(mclBnGT *z, const mclBnGT *x, const mclBnFr *y); |
||||
``` |
||||
- z = x * y for G1 / G2 |
||||
- z = pow(x, y) for GT |
||||
|
||||
- use `mclBnGT_powGeneric` for an element in Fp12 - GT. |
||||
|
||||
### multi scalar multiplication |
||||
``` |
||||
void mclBnG1_mulVec(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y, mclSize n); |
||||
void mclBnG2_mulVec(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y, mclSize n); |
||||
void mclBnGT_powVec(mclBnGT *z, const mclBnGT *x, const mclBnFr *y, mclSize n); |
||||
``` |
||||
- z = sum_{i=0}^{n-1} mul(x[i], y[i]) for G1 / G2. |
||||
- z = prod_{i=0}^{n-1} pow(x[i], y[i]) for GT. |
||||
|
||||
## hash and mapTo functions |
||||
### Set hash of `buf[0..bufSize-1]` to `x` |
||||
``` |
||||
int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize); |
||||
int mclBnFp_setHashOf(mclBnFp *x, const void *buf, mclSize bufSize); |
||||
``` |
||||
- always return 0 |
||||
- use SHA-256 if sizeof(*x) <= 256 else SHA-512 |
||||
- set accoring to the same way as `setLittleEndian` |
||||
- support the other wasy if you want in the future |
||||
|
||||
### map `x` to G1 / G2. |
||||
``` |
||||
int mclBnFp_mapToG1(mclBnG1 *y, const mclBnFp *x); |
||||
int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x); |
||||
``` |
||||
- See `struct MapTo` in `mcl/bn.hpp` for the detail of the algorithm. |
||||
- return 0 if success else -1 |
||||
|
||||
### hash and map to G1 / G2. |
||||
``` |
||||
int mclBnG1_hashAndMapTo(mclBnG1 *x, const void *buf, mclSize bufSize); |
||||
int mclBnG2_hashAndMapTo(mclBnG2 *x, const void *buf, mclSize bufSize); |
||||
``` |
||||
- Combine `setHashOf` and `mapTo` functions |
||||
|
||||
## Pairing operations |
||||
The pairing function `e(P, Q)` is consist of two parts: |
||||
- `MillerLoop(P, Q)` |
||||
- `finalExp(x)` |
||||
|
||||
`finalExp` satisfies the following properties: |
||||
- `e(P, Q) = finalExp(MillerLoop(P, Q))` |
||||
- `e(P1, Q1) e(P2, Q2) = finalExp(MillerLoop(P1, Q1) MillerLoop(P2, Q2))` |
||||
|
||||
### pairing |
||||
``` |
||||
void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y); |
||||
``` |
||||
### millerLoop |
||||
``` |
||||
void mclBn_millerLoop(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y); |
||||
``` |
||||
### finalExp |
||||
``` |
||||
void mclBn_finalExp(mclBnGT *y, const mclBnGT *x); |
||||
``` |
||||
|
||||
## Variants of MillerLoop |
||||
### multi pairing |
||||
``` |
||||
void mclBn_millerLoopVec(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y, mclSize n); |
||||
``` |
||||
- This function is for multi-pairing |
||||
- computes prod_{i=0}^{n-1} MillerLoop(x[i], y[i]) |
||||
- prod_{i=0}^{n-1} e(x[i], y[i]) = finalExp(prod_{i=0}^{n-1} MillerLoop(x[i], y[i])) |
||||
|
||||
### pairing for a fixed point of G2 |
||||
``` |
||||
int mclBn_getUint64NumToPrecompute(void); |
||||
void mclBn_precomputeG2(uint64_t *Qbuf, const mclBnG2 *Q); |
||||
void mclBn_precomputedMillerLoop(mclBnGT *f, const mclBnG1 *P, const uint64_t *Qbuf); |
||||
``` |
||||
These functions is the same computation of `pairing(P, Q);` as the followings: |
||||
``` |
||||
uint64_t *Qbuf = (uint64_t*)malloc(mclBn_getUint64NumToPrecompute() * sizeof(uint64_t)); |
||||
mclBn_precomputeG2(Qbuf, Q); // precomputing of Q |
||||
mclBn_precomputedMillerLoop(f, P, Qbuf); // pairing of any P of G1 and the fixed Q |
||||
free(p); |
||||
``` |
||||
|
||||
``` |
||||
void mclBn_precomputedMillerLoop2( |
||||
mclBnGT *f, |
||||
const mclBnG1 *P1, const uint64_t *Q1buf, |
||||
const mclBnG1 *P2, const uint64_t *Q2buf |
||||
); |
||||
``` |
||||
- compute `MillerLoop(P1, Q1buf) * MillerLoop(P2, Q2buf)` |
||||
|
||||
|
||||
``` |
||||
void mclBn_precomputedMillerLoop2mixed( |
||||
mclBnGT *f, |
||||
const mclBnG1 *P1, const mclBnG2 *Q1, |
||||
const mclBnG1 *P2, const uint64_t *Q2buf |
||||
); |
||||
``` |
||||
- compute `MillerLoop(P1, Q2) * MillerLoop(P2, Q2buf)` |
||||
|
||||
## Check value |
||||
### Check validness |
||||
``` |
||||
int mclBnFr_isValid(const mclBnFr *x); |
||||
int mclBnFp_isValid(const mclBnFp *x); |
||||
int mclBnG1_isValid(const mclBnG1 *x); |
||||
int mclBnG2_isValid(const mclBnG2 *x); |
||||
``` |
||||
- return 1 if true else 0 |
||||
|
||||
### Check the order of a point |
||||
``` |
||||
int mclBnG1_isValidOrder(const mclBnG1 *x); |
||||
int mclBnG2_isValidOrder(const mclBnG2 *x); |
||||
``` |
||||
- Check whether the order of `x` is valid or not |
||||
- return 1 if true else 0 |
||||
- This function always cheks according to `mclBn_verifyOrderG1` and `mclBn_verifyOrderG2`. |
||||
|
||||
### Is equal / zero / one / isOdd |
||||
``` |
||||
int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y); |
||||
int mclBnFr_isZero(const mclBnFr *x); |
||||
int mclBnFr_isOne(const mclBnFr *x); |
||||
int mclBnFr_isOdd(const mclBnFr *x); |
||||
|
||||
int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y); |
||||
int mclBnFp_isZero(const mclBnFp *x); |
||||
int mclBnFp_isOne(const mclBnFp *x); |
||||
int mclBnFp_isOdd(const mclBnFp *x); |
||||
|
||||
int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y); |
||||
int mclBnFp2_isZero(const mclBnFp2 *x); |
||||
int mclBnFp2_isOne(const mclBnFp2 *x); |
||||
|
||||
int mclBnG1_isEqual(const mclBnG1 *x, const mclBnG1 *y); |
||||
int mclBnG1_isZero(const mclBnG1 *x); |
||||
|
||||
int mclBnG2_isEqual(const mclBnG2 *x, const mclBnG2 *y); |
||||
int mclBnG2_isZero(const mclBnG2 *x); |
||||
|
||||
int mclBnGT_isEqual(const mclBnGT *x, const mclBnGT *y); |
||||
int mclBnGT_isZero(const mclBnGT *x); |
||||
int mclBnGT_isOne(const mclBnGT *x); |
||||
``` |
||||
- return 1 if true else 0 |
||||
|
||||
### isNegative |
||||
``` |
||||
int mclBnFr_isNegative(const mclBnFr *x); |
||||
int mclBnFp_isNegative(const mclBnFr *x); |
||||
``` |
||||
return 1 if x >= half where half = (r + 1) / 2 (resp. (p + 1) / 2). |
||||
|
||||
## Lagrange interpolation |
||||
|
||||
``` |
||||
int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k); |
||||
int mclBn_G1LagrangeInterpolation(mclBnG1 *out, const mclBnFr *xVec, const mclBnG1 *yVec, mclSize k); |
||||
int mclBn_G2LagrangeInterpolation(mclBnG2 *out, const mclBnFr *xVec, const mclBnG2 *yVec, mclSize k); |
||||
``` |
||||
- Lagrange interpolation |
||||
- recover out = y(0) from {(xVec[i], yVec[i])} for {i=0..k-1} |
||||
- return 0 if success else -1 |
||||
- satisfy that xVec[i] != 0, xVec[i] != xVec[j] for i != j |
||||
|
||||
``` |
||||
int mclBn_FrEvaluatePolynomial(mclBnFr *out, const mclBnFr *cVec, mclSize cSize, const mclBnFr *x); |
||||
int mclBn_G1EvaluatePolynomial(mclBnG1 *out, const mclBnG1 *cVec, mclSize cSize, const mclBnFr *x); |
||||
int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, mclSize cSize, const mclBnFr *x); |
||||
``` |
||||
- Evaluate polynomial |
||||
- out = f(x) = c[0] + c[1] * x + ... + c[cSize - 1] * x^{cSize - 1} |
||||
- return 0 if success else -1 |
||||
- satisfy cSize >= 1 |
@ -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 |
@ -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) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<TargetFramework>netstandard2.1</TargetFramework> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<Compile Remove="CVS\**" /> |
||||
<EmbeddedResource Remove="CVS\**" /> |
||||
<None Remove="CVS\**" /> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,24 @@ |
||||
# C# binding of mcl library |
||||
|
||||
# How to build `bin/mclbn384_256.dll`. |
||||
|
||||
``` |
||||
git clone https://github.com/herumi/mcl |
||||
cd mcl |
||||
mklib dll |
||||
``` |
||||
|
||||
Open `mcl/ffi/cs/mcl.sln` and Set the directory of `mcl/bin` to `workingDirectory` at `Debug` of test project. |
||||
|
||||
# Remark |
||||
- `bn256.cs` is an old code. It will be removed in the future. |
||||
- `mcl/mcl.cs` is a new version. It support `BN254`, `BN_SNARK` and `BLS12_381` curve, which requires `mclbn384_256.dll`. |
||||
|
||||
# `ETHmode` with `BLS12_381` |
||||
|
||||
If you need the map-to-G1/G2 function defined in [Hashing to Elliptic Curves](https://www.ietf.org/id/draft-irtf-cfrg-hash-to-curve-09.html), |
||||
then initialize this library as the followings: |
||||
``` |
||||
MCL.Init(BLS12_381); |
||||
MCL.ETHmode(); |
||||
``` |
@ -0,0 +1,408 @@ |
||||
using System; |
||||
|
||||
namespace mcl { |
||||
using static MCL; |
||||
class MCLTest { |
||||
static int err = 0; |
||||
static void assert(string msg, bool b) |
||||
{ |
||||
if (b) return; |
||||
Console.WriteLine("ERR {0}", msg); |
||||
err++; |
||||
} |
||||
static void Main() |
||||
{ |
||||
err = 0; |
||||
try { |
||||
Console.WriteLine("BN254"); |
||||
TestCurve(BN254); |
||||
Console.WriteLine("BN_SNARK"); |
||||
TestCurve(BN_SNARK); |
||||
Console.WriteLine("BLS12_381"); |
||||
TestCurve(BLS12_381); |
||||
Console.WriteLine("BLS12_381 eth"); |
||||
ETHmode(); |
||||
TestETH(); |
||||
if (err == 0) { |
||||
Console.WriteLine("all tests succeed"); |
||||
} else { |
||||
Console.WriteLine("err={0}", err); |
||||
} |
||||
} catch (Exception e) { |
||||
Console.WriteLine("ERR={0}", e); |
||||
} |
||||
} |
||||
|
||||
static void TestCurve(int curveType) |
||||
{ |
||||
Init(curveType); |
||||
TestFr(); |
||||
TestFp(); |
||||
TestG1(); |
||||
TestG2(); |
||||
TestPairing(); |
||||
TestSS(); |
||||
} |
||||
static void TestFr() |
||||
{ |
||||
Console.WriteLine("TestFr"); |
||||
Fr x = new Fr(); |
||||
assert("x.isZero", x.IsZero()); |
||||
x.Clear(); |
||||
assert("0", x.GetStr(10) == "0"); |
||||
assert("0.IzZero", x.IsZero()); |
||||
assert("!0.IzOne", !x.IsOne()); |
||||
x.SetInt(1); |
||||
assert("1", x.GetStr(10) == "1"); |
||||
assert("!1.IzZero", !x.IsZero()); |
||||
assert("1.IzOne", x.IsOne()); |
||||
x.SetInt(3); |
||||
assert("3", x.GetStr(10) == "3"); |
||||
assert("!3.IzZero", !x.IsZero()); |
||||
assert("!3.IzOne", !x.IsOne()); |
||||
x.SetInt(-5); |
||||
x = -x; |
||||
assert("5", x.GetStr(10) == "5"); |
||||
x.SetInt(4); |
||||
x = x * x; |
||||
assert("16", x.GetStr(10) == "16"); |
||||
assert("10", x.GetStr(16) == "10"); |
||||
Fr y; |
||||
y = x; |
||||
assert("x == y", x.Equals(y)); |
||||
x.SetInt(123); |
||||
assert("123", x.GetStr(10) == "123"); |
||||
assert("7b", x.GetStr(16) == "7b"); |
||||
assert("y != x", !x.Equals(y)); |
||||
Console.WriteLine("exception test"); |
||||
try { |
||||
x.SetStr("1234567891234x", 10); |
||||
Console.WriteLine("x = {0}", x); |
||||
} catch (Exception e) { |
||||
Console.WriteLine("OK ; expected exception: {0}", e); |
||||
} |
||||
x.SetStr("1234567891234", 10); |
||||
assert("1234567891234", x.GetStr(10) == "1234567891234"); |
||||
{ |
||||
byte[] buf = x.Serialize(); |
||||
y.Deserialize(buf); |
||||
assert("x == y", x.Equals(y)); |
||||
} |
||||
} |
||||
static void TestFp() |
||||
{ |
||||
Console.WriteLine("TestFp"); |
||||
Fp x = new Fp(); |
||||
assert("x.isZero", x.IsZero()); |
||||
x.Clear(); |
||||
assert("0", x.GetStr(10) == "0"); |
||||
assert("0.IzZero", x.IsZero()); |
||||
assert("!0.IzOne", !x.IsOne()); |
||||
x.SetInt(1); |
||||
assert("1", x.GetStr(10) == "1"); |
||||
assert("!1.IzZero", !x.IsZero()); |
||||
assert("1.IzOne", x.IsOne()); |
||||
x.SetInt(3); |
||||
assert("3", x.GetStr(10) == "3"); |
||||
assert("!3.IzZero", !x.IsZero()); |
||||
assert("!3.IzOne", !x.IsOne()); |
||||
x.SetInt(-5); |
||||
x = -x; |
||||
assert("5", x.GetStr(10) == "5"); |
||||
x.SetInt(4); |
||||
x = x * x; |
||||
assert("16", x.GetStr(10) == "16"); |
||||
assert("10", x.GetStr(16) == "10"); |
||||
Fp y; |
||||
y = x; |
||||
assert("x == y", x.Equals(y)); |
||||
x.SetInt(123); |
||||
assert("123", x.GetStr(10) == "123"); |
||||
assert("7b", x.GetStr(16) == "7b"); |
||||
assert("y != x", !x.Equals(y)); |
||||
Console.WriteLine("exception test"); |
||||
try { |
||||
x.SetStr("1234567891234x", 10); |
||||
Console.WriteLine("x = {0}", x); |
||||
} catch (Exception e) { |
||||
Console.WriteLine("OK ; expected exception: {0}", e); |
||||
} |
||||
x.SetStr("1234567891234", 10); |
||||
assert("1234567891234", x.GetStr(10) == "1234567891234"); |
||||
{ |
||||
byte[] buf = x.Serialize(); |
||||
y.Deserialize(buf); |
||||
assert("x == y", x.Equals(y)); |
||||
} |
||||
} |
||||
static void TestG1() |
||||
{ |
||||
Console.WriteLine("TestG1"); |
||||
G1 P = new G1(); |
||||
assert("P.isZero", P.IsZero()); |
||||
P.Clear(); |
||||
assert("P.IsValid", P.IsValid()); |
||||
assert("P.IsZero", P.IsZero()); |
||||
P.HashAndMapTo("abc"); |
||||
assert("P.IsValid", P.IsValid()); |
||||
assert("!P.IsZero", !P.IsZero()); |
||||
G1 Q = new G1(); |
||||
Q = P; |
||||
assert("P == Q", Q.Equals(P)); |
||||
Q.Neg(P); |
||||
Q.Add(Q, P); |
||||
assert("P = Q", Q.IsZero()); |
||||
Q.Dbl(P); |
||||
G1 R = new G1(); |
||||
R.Add(P, P); |
||||
assert("Q == R", Q.Equals(R)); |
||||
Fr x = new Fr(); |
||||
x.SetInt(3); |
||||
R.Add(R, P); |
||||
Q.Mul(P, x); |
||||
assert("Q == R", Q.Equals(R)); |
||||
{ |
||||
byte[] buf = P.Serialize(); |
||||
Q.Clear(); |
||||
Q.Deserialize(buf); |
||||
assert("P == Q", P.Equals(Q)); |
||||
} |
||||
{ |
||||
const int n = 5; |
||||
G1[] xVec = new G1[n]; |
||||
Fr[] yVec = new Fr[n]; |
||||
P.Clear(); |
||||
for (int i = 0; i < n; i++) { |
||||
xVec[i].HashAndMapTo(i.ToString()); |
||||
yVec[i].SetByCSPRNG(); |
||||
Q.Mul(xVec[i], yVec[i]); |
||||
P.Add(P, Q); |
||||
} |
||||
MulVec(ref Q, xVec, yVec); |
||||
assert("mulVecG1", P.Equals(Q)); |
||||
} |
||||
G1 W = G1.Zero(); |
||||
assert("W.IsZero", W.IsZero()); |
||||
} |
||||
static void TestG2() |
||||
{ |
||||
Console.WriteLine("TestG2"); |
||||
G2 P = new G2(); |
||||
assert("P.isZero", P.IsZero()); |
||||
P.Clear(); |
||||
assert("P is valid", P.IsValid()); |
||||
assert("P is zero", P.IsZero()); |
||||
P.HashAndMapTo("abc"); |
||||
assert("P is valid", P.IsValid()); |
||||
assert("P is not zero", !P.IsZero()); |
||||
G2 Q = new G2(); |
||||
Q = P; |
||||
assert("P == Q", Q.Equals(P)); |
||||
Q.Neg(P); |
||||
Q.Add(Q, P); |
||||
assert("Q is zero", Q.IsZero()); |
||||
Q.Dbl(P); |
||||
G2 R = new G2(); |
||||
R.Add(P, P); |
||||
assert("Q == R", Q.Equals(R)); |
||||
Fr x = new Fr(); |
||||
x.SetInt(3); |
||||
R.Add(R, P); |
||||
Q.Mul(P, x); |
||||
assert("Q == R", Q.Equals(R)); |
||||
{ |
||||
byte[] buf = P.Serialize(); |
||||
Q.Clear(); |
||||
Q.Deserialize(buf); |
||||
assert("P == Q", P.Equals(Q)); |
||||
} |
||||
{ |
||||
const int n = 5; |
||||
G2[] xVec = new G2[n]; |
||||
Fr[] yVec = new Fr[n]; |
||||
P.Clear(); |
||||
for (int i = 0; i < n; i++) { |
||||
xVec[i].HashAndMapTo(i.ToString()); |
||||
yVec[i].SetByCSPRNG(); |
||||
Q.Mul(xVec[i], yVec[i]); |
||||
P.Add(P, Q); |
||||
} |
||||
MulVec(ref Q, xVec, yVec); |
||||
assert("mulVecG2", P.Equals(Q)); |
||||
} |
||||
G2 W = G2.Zero(); |
||||
assert("W.IsZero", W.IsZero()); |
||||
} |
||||
static void TestPairing() |
||||
{ |
||||
Console.WriteLine("TestG2"); |
||||
G1 P = new G1(); |
||||
P.HashAndMapTo("123"); |
||||
G2 Q = new G2(); |
||||
Q.HashAndMapTo("1"); |
||||
Fr a = new Fr(); |
||||
Fr b = new Fr(); |
||||
a.SetStr("12345678912345673453", 10); |
||||
b.SetStr("230498230982394243424", 10); |
||||
G1 aP = new G1(); |
||||
G2 bQ = new G2(); |
||||
aP.Mul(P, a); |
||||
bQ.Mul(Q, b); |
||||
GT e1 = new GT(); |
||||
GT e2 = new GT(); |
||||
GT e3 = new GT(); |
||||
e1.Pairing(P, Q); |
||||
e2.Pairing(aP, Q); |
||||
e3.Pow(e1, a); |
||||
assert("e2.Equals(e3)", e2.Equals(e3)); |
||||
e2.Pairing(P, bQ); |
||||
e3.Pow(e1, b); |
||||
assert("e2.Equals(e3)", e2.Equals(e3)); |
||||
} |
||||
static void TestETH_mapToG1() |
||||
{ |
||||
var tbl = new[] { |
||||
new { |
||||
msg = "asdf", |
||||
x = "a72df17570d0eb81260042edbea415ad49bdb94a1bc1ce9d1bf147d0d48268170764bb513a3b994d662e1faba137106", |
||||
y = "122b77eca1ed58795b7cd456576362f4f7bd7a572a29334b4817898a42414d31e9c0267f2dc481a4daf8bcf4a460322", |
||||
}, |
||||
}; |
||||
G1 P = new G1(); |
||||
Fp x = new Fp(); |
||||
Fp y = new Fp(); |
||||
foreach (var v in tbl) { |
||||
P.HashAndMapTo(v.msg); |
||||
x.SetStr(v.x, 16); |
||||
y.SetStr(v.y, 16); |
||||
Normalize(ref P, P); |
||||
Console.WriteLine("x={0}", P.x.GetStr(16)); |
||||
Console.WriteLine("y={0}", P.y.GetStr(16)); |
||||
assert("P.x", P.x.Equals(x)); |
||||
assert("P.y", P.y.Equals(y)); |
||||
} |
||||
} |
||||
static void TestETH() |
||||
{ |
||||
TestETH_mapToG1(); |
||||
} |
||||
static void TestSS_Fr() |
||||
{ |
||||
const int n = 5; |
||||
const int k = 3; // can't change because the following loop |
||||
Fr[] cVec = new Fr[k]; |
||||
// init polynomial coefficient |
||||
for (int i = 0; i < k; i++) { |
||||
cVec[i].SetByCSPRNG(); |
||||
} |
||||
|
||||
Fr[] xVec = new Fr[n]; |
||||
Fr[] yVec = new Fr[n]; |
||||
// share cVec[0] with yVec[0], ..., yVec[n-1] |
||||
for (int i = 0; i < n; i++) { |
||||
xVec[i].SetHashOf(i.ToString()); |
||||
MCL.Share(ref yVec[i], cVec, xVec[i]); |
||||
} |
||||
// recover cVec[0] from xVecSubset and yVecSubset |
||||
Fr[] xVecSubset = new Fr[k]; |
||||
Fr[] yVecSubset = new Fr[k]; |
||||
for (int i0 = 0; i0 < n; i0++) { |
||||
xVecSubset[0] = xVec[i0]; |
||||
yVecSubset[0] = yVec[i0]; |
||||
for (int i1 = i0 + 1; i1 < n; i1++) { |
||||
xVecSubset[1] = xVec[i1]; |
||||
yVecSubset[1] = yVec[i1]; |
||||
for (int i2 = i1 + 1; i2 < n; i2++) { |
||||
xVecSubset[2] = xVec[i2]; |
||||
yVecSubset[2] = yVec[i2]; |
||||
Fr s = new Fr(); |
||||
MCL.Recover(ref s, xVecSubset, yVecSubset); |
||||
assert("Recover", s.Equals(cVec[0])); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
static void TestSS_G1() |
||||
{ |
||||
const int n = 5; |
||||
const int k = 3; // can't change because the following loop |
||||
G1[] cVec = new G1[k]; |
||||
// init polynomial coefficient |
||||
for (int i = 0; i < k; i++) { |
||||
Fr x = new Fr(); |
||||
x.SetByCSPRNG(); |
||||
cVec[i].SetHashOf(x.GetStr(16)); |
||||
} |
||||
|
||||
Fr[] xVec = new Fr[n]; |
||||
G1[] yVec = new G1[n]; |
||||
// share cVec[0] with yVec[0], ..., yVec[n-1] |
||||
for (int i = 0; i < n; i++) { |
||||
xVec[i].SetHashOf(i.ToString()); |
||||
MCL.Share(ref yVec[i], cVec, xVec[i]); |
||||
} |
||||
// recover cVec[0] from xVecSubset and yVecSubset |
||||
Fr[] xVecSubset = new Fr[k]; |
||||
G1[] yVecSubset = new G1[k]; |
||||
for (int i0 = 0; i0 < n; i0++) { |
||||
xVecSubset[0] = xVec[i0]; |
||||
yVecSubset[0] = yVec[i0]; |
||||
for (int i1 = i0 + 1; i1 < n; i1++) { |
||||
xVecSubset[1] = xVec[i1]; |
||||
yVecSubset[1] = yVec[i1]; |
||||
for (int i2 = i1 + 1; i2 < n; i2++) { |
||||
xVecSubset[2] = xVec[i2]; |
||||
yVecSubset[2] = yVec[i2]; |
||||
G1 s = new G1(); |
||||
MCL.Recover(ref s, xVecSubset, yVecSubset); |
||||
assert("Recover", s.Equals(cVec[0])); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
static void TestSS_G2() |
||||
{ |
||||
const int n = 5; |
||||
const int k = 3; // can't change because the following loop |
||||
G2[] cVec = new G2[k]; |
||||
// init polynomial coefficient |
||||
for (int i = 0; i < k; i++) { |
||||
Fr x = new Fr(); |
||||
x.SetByCSPRNG(); |
||||
cVec[i].SetHashOf(x.GetStr(16)); |
||||
} |
||||
|
||||
Fr[] xVec = new Fr[n]; |
||||
G2[] yVec = new G2[n]; |
||||
// share cVec[0] with yVec[0], ..., yVec[n-1] |
||||
for (int i = 0; i < n; i++) { |
||||
xVec[i].SetHashOf(i.ToString()); |
||||
MCL.Share(ref yVec[i], cVec, xVec[i]); |
||||
} |
||||
// recover cVec[0] from xVecSubset and yVecSubset |
||||
Fr[] xVecSubset = new Fr[k]; |
||||
G2[] yVecSubset = new G2[k]; |
||||
for (int i0 = 0; i0 < n; i0++) { |
||||
xVecSubset[0] = xVec[i0]; |
||||
yVecSubset[0] = yVec[i0]; |
||||
for (int i1 = i0 + 1; i1 < n; i1++) { |
||||
xVecSubset[1] = xVec[i1]; |
||||
yVecSubset[1] = yVec[i1]; |
||||
for (int i2 = i1 + 1; i2 < n; i2++) { |
||||
xVecSubset[2] = xVec[i2]; |
||||
yVecSubset[2] = yVec[i2]; |
||||
G2 s = new G2(); |
||||
MCL.Recover(ref s, xVecSubset, yVecSubset); |
||||
assert("Recover", s.Equals(cVec[0])); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
static void TestSS() |
||||
{ |
||||
TestSS_Fr(); |
||||
TestSS_G1(); |
||||
TestSS_G2(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<ItemGroup> |
||||
<Compile Remove="CVS\**" /> |
||||
<EmbeddedResource Remove="CVS\**" /> |
||||
<None Remove="CVS\**" /> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<ProjectReference Include="..\mcl\mcl.csproj" /> |
||||
</ItemGroup> |
||||
|
||||
<PropertyGroup> |
||||
<OutputType>Exe</OutputType> |
||||
<TargetFramework>netcoreapp3.1</TargetFramework> |
||||
</PropertyGroup> |
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> |
||||
<PlatformTarget>x64</PlatformTarget> |
||||
<OutputPath></OutputPath> |
||||
</PropertyGroup> |
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
<PlatformTarget>x64</PlatformTarget> |
||||
<OutputPath></OutputPath> |
||||
</PropertyGroup> |
||||
|
||||
</Project> |
@ -1,104 +0,0 @@ |
||||
import java.io.*; |
||||
import com.herumi.mcl.*; |
||||
|
||||
/* |
||||
Bn256Test |
||||
*/ |
||||
public class Bn256Test { |
||||
static { |
||||
String lib = "mcl_bn256"; |
||||
String libName = System.mapLibraryName(lib); |
||||
System.out.println("libName : " + libName); |
||||
System.loadLibrary(lib); |
||||
} |
||||
public static void assertEquals(String msg, String x, String y) { |
||||
if (x.equals(y)) { |
||||
System.out.println("OK : " + msg); |
||||
} else { |
||||
System.out.println("NG : " + msg + ", x = " + x + ", y = " + y); |
||||
} |
||||
} |
||||
public static void assertBool(String msg, boolean b) { |
||||
if (b) { |
||||
System.out.println("OK : " + msg); |
||||
} else { |
||||
System.out.println("NG : " + msg); |
||||
} |
||||
} |
||||
public static void main(String argv[]) { |
||||
try { |
||||
Bn256.SystemInit(); |
||||
Fr x = new Fr(5); |
||||
Fr y = new Fr(-2); |
||||
Fr z = new Fr(5); |
||||
assertBool("x != y", !x.equals(y)); |
||||
assertBool("x == z", x.equals(z)); |
||||
assertEquals("x == 5", x.toString(), "5"); |
||||
Bn256.add(x, x, y); |
||||
assertEquals("x == 3", x.toString(), "3"); |
||||
Bn256.mul(x, x, x); |
||||
assertEquals("x == 9", x.toString(), "9"); |
||||
G1 P = new G1(); |
||||
System.out.println("P=" + P); |
||||
P.set("-1", "1"); |
||||
System.out.println("P=" + P); |
||||
Bn256.neg(P, P); |
||||
System.out.println("P=" + P); |
||||
|
||||
String xa = "12723517038133731887338407189719511622662176727675373276651903807414909099441"; |
||||
String xb = "4168783608814932154536427934509895782246573715297911553964171371032945126671"; |
||||
String ya = "13891744915211034074451795021214165905772212241412891944830863846330766296736"; |
||||
String yb = "7937318970632701341203597196594272556916396164729705624521405069090520231616"; |
||||
|
||||
G2 Q = new G2(xa, xb, ya, yb); |
||||
|
||||
P.hashAndMapToG1("This is a pen"); |
||||
{ |
||||
String s = P.toString(); |
||||
G1 P1 = new G1(); |
||||
P1.setStr(s); |
||||
assertBool("P == P1", P1.equals(P)); |
||||
} |
||||
|
||||
GT e = new GT(); |
||||
Bn256.pairing(e, P, Q); |
||||
GT e1 = new GT(); |
||||
GT e2 = new GT(); |
||||
Fr c = new Fr("1234567890123234928348230428394234"); |
||||
G2 cQ = new G2(Q); |
||||
Bn256.mul(cQ, Q, c); // cQ = Q * c
|
||||
Bn256.pairing(e1, P, cQ); |
||||
Bn256.pow(e2, e, c); // e2 = e^c
|
||||
assertBool("e1 == e2", e1.equals(e2)); |
||||
|
||||
G1 cP = new G1(P); |
||||
Bn256.mul(cP, P, c); // cP = P * c
|
||||
Bn256.pairing(e1, cP, Q); |
||||
assertBool("e1 == e2", e1.equals(e2)); |
||||
|
||||
BLSsignature(Q); |
||||
} catch (RuntimeException e) { |
||||
System.out.println("unknown exception :" + e); |
||||
} |
||||
} |
||||
public static void BLSsignature(G2 Q) |
||||
{ |
||||
Fr s = new Fr(); |
||||
s.setRand(); // secret key
|
||||
System.out.println("secret key " + s); |
||||
G2 pub = new G2(); |
||||
Bn256.mul(pub, Q, s); // public key = sQ
|
||||
|
||||
String m = "signature test"; |
||||
G1 H = new G1(); |
||||
H.hashAndMapToG1(m); // H = Hash(m)
|
||||
G1 sign = new G1(); |
||||
Bn256.mul(sign, H, s); // signature of m = s H
|
||||
|
||||
GT e1 = new GT(); |
||||
GT e2 = new GT(); |
||||
Bn256.pairing(e1, H, pub); // e1 = e(H, s Q)
|
||||
Bn256.pairing(e2, sign, Q); // e2 = e(s H, Q);
|
||||
assertBool("verify signature", e1.equals(e2)); |
||||
} |
||||
} |
@ -0,0 +1,160 @@ |
||||
import java.io.*; |
||||
import com.herumi.mcl.*; |
||||
|
||||
/* |
||||
MclTest |
||||
*/ |
||||
public class MclTest { |
||||
static { |
||||
String lib = "mcljava"; |
||||
String libName = System.mapLibraryName(lib); |
||||
System.out.println("libName : " + libName); |
||||
System.loadLibrary(lib); |
||||
} |
||||
public static int errN = 0; |
||||
public static void assertEquals(String msg, String x, String y) { |
||||
if (x.equals(y)) { |
||||
System.out.println("OK : " + msg); |
||||
} else { |
||||
System.out.println("NG : " + msg + ", x = " + x + ", y = " + y); |
||||
errN++; |
||||
} |
||||
} |
||||
public static void assertBool(String msg, boolean b) { |
||||
if (b) { |
||||
System.out.println("OK : " + msg); |
||||
} else { |
||||
System.out.println("NG : " + msg); |
||||
errN++; |
||||
} |
||||
} |
||||
public static void testCurve(int curveType, String name) { |
||||
try { |
||||
System.out.println("curve=" + name); |
||||
Mcl.SystemInit(curveType); |
||||
Fr x = new Fr(5); |
||||
Fr y = new Fr(-2); |
||||
Fr z = new Fr(5); |
||||
assertBool("x != y", !x.equals(y)); |
||||
assertBool("x == z", x.equals(z)); |
||||
assertEquals("x == 5", x.toString(), "5"); |
||||
Mcl.add(x, x, y); |
||||
assertEquals("x == 3", x.toString(), "3"); |
||||
Mcl.mul(x, x, x); |
||||
assertEquals("x == 9", x.toString(), "9"); |
||||
assertEquals("x == 12", (new Fr("12")).toString(), "12"); |
||||
assertEquals("x == 18", (new Fr("12", 16)).toString(), "18"); |
||||
assertEquals("x == ff", (new Fr("255")).toString(16), "ff"); |
||||
Mcl.inv(y, x); |
||||
Mcl.mul(x, y, x); |
||||
assertBool("x == 1", x.isOne()); |
||||
|
||||
{ |
||||
byte[] b = x.serialize(); |
||||
Fr t = new Fr(); |
||||
t.deserialize(b); |
||||
assertBool("serialize", x.equals(t)); |
||||
t.setLittleEndianMod(b); |
||||
assertBool("setLittleEndianMod", x.equals(t)); |
||||
t.setHashOf(b); |
||||
assertBool("setHashOf", !x.equals(t)); |
||||
Fr u = new Fr(); |
||||
u.setHashOf(new byte[]{1,2,3}); |
||||
assertBool("setHashOf - different", !u.equals(t)); |
||||
} |
||||
G1 P = new G1(); |
||||
System.out.println("P=" + P); |
||||
Mcl.hashAndMapToG1(P, "test".getBytes()); |
||||
System.out.println("P=" + P); |
||||
byte[] buf = { 1, 2, 3, 4 }; |
||||
Mcl.hashAndMapToG1(P, buf); |
||||
System.out.println("P=" + P); |
||||
Mcl.neg(P, P); |
||||
System.out.println("P=" + P); |
||||
{ |
||||
byte[] b = P.serialize(); |
||||
G1 t = new G1(); |
||||
t.deserialize(b); |
||||
assertBool("serialize", P.equals(t)); |
||||
} |
||||
|
||||
G2 Q = new G2(); |
||||
Mcl.hashAndMapToG2(Q, "abc".getBytes()); |
||||
System.out.println("Q=" + Q); |
||||
|
||||
Mcl.hashAndMapToG1(P, "This is a pen".getBytes()); |
||||
{ |
||||
String s = P.toString(); |
||||
G1 P1 = new G1(); |
||||
P1.setStr(s); |
||||
assertBool("P == P1", P1.equals(P)); |
||||
} |
||||
{ |
||||
byte[] b = Q.serialize(); |
||||
G2 t = new G2(); |
||||
t.deserialize(b); |
||||
assertBool("serialize", Q.equals(t)); |
||||
} |
||||
|
||||
GT e = new GT(); |
||||
Mcl.pairing(e, P, Q); |
||||
GT e1 = new GT(); |
||||
GT e2 = new GT(); |
||||
Fr c = new Fr("1234567890123234928348230428394234"); |
||||
System.out.println("c=" + c); |
||||
G2 cQ = new G2(Q); |
||||
Mcl.mul(cQ, Q, c); // cQ = Q * c
|
||||
Mcl.pairing(e1, P, cQ); |
||||
Mcl.pow(e2, e, c); // e2 = e^c
|
||||
assertBool("e1 == e2", e1.equals(e2)); |
||||
{ |
||||
byte[] b = e1.serialize(); |
||||
GT t = new GT(); |
||||
t.deserialize(b); |
||||
assertBool("serialize", e1.equals(t)); |
||||
} |
||||
G1 cP = new G1(P); |
||||
Mcl.mul(cP, P, c); // cP = P * c
|
||||
Mcl.pairing(e1, cP, Q); |
||||
assertBool("e1 == e2", e1.equals(e2)); |
||||
Mcl.inv(e1, e1); |
||||
Mcl.mul(e1, e1, e2); |
||||
e2.setStr("1 0 0 0 0 0 0 0 0 0 0 0"); |
||||
assertBool("e1 == 1", e1.equals(e2)); |
||||
assertBool("e1 == 1", e1.isOne()); |
||||
|
||||
BLSsignature(Q); |
||||
if (errN == 0) { |
||||
System.out.println("all test passed"); |
||||
} else { |
||||
System.out.println("ERR=" + errN); |
||||
} |
||||
} catch (RuntimeException e) { |
||||
System.out.println("unknown exception :" + e); |
||||
} |
||||
} |
||||
public static void BLSsignature(G2 Q) |
||||
{ |
||||
Fr s = new Fr(); |
||||
s.setByCSPRNG(); // secret key
|
||||
System.out.println("secret key " + s); |
||||
G2 pub = new G2(); |
||||
Mcl.mul(pub, Q, s); // public key = sQ
|
||||
|
||||
byte[] m = "signature test".getBytes(); |
||||
G1 H = new G1(); |
||||
Mcl.hashAndMapToG1(H, m); // H = Hash(m)
|
||||
G1 sign = new G1(); |
||||
Mcl.mul(sign, H, s); // signature of m = s H
|
||||
|
||||
GT e1 = new GT(); |
||||
GT e2 = new GT(); |
||||
Mcl.pairing(e1, H, pub); // e1 = e(H, s Q)
|
||||
Mcl.pairing(e2, sign, Q); // e2 = e(s H, Q);
|
||||
assertBool("verify signature", e1.equals(e2)); |
||||
} |
||||
public static void main(String argv[]) { |
||||
testCurve(Mcl.BN254, "BN254"); |
||||
testCurve(Mcl.BLS12_381, "BLS12_381"); |
||||
} |
||||
} |
@ -0,0 +1,39 @@ |
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS) |
||||
|
||||
LOCAL_CPP_EXTENSION := .cpp .ll .cxx
|
||||
LOCAL_MODULE := mcljava
|
||||
|
||||
LOCAL_MCL_DIR := $(LOCAL_PATH)/../../../../
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),x86_64) |
||||
MY_BIT := 64
|
||||
endif |
||||
ifeq ($(TARGET_ARCH_ABI),arm64-v8a) |
||||
MY_BIT := 64
|
||||
endif |
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) |
||||
MY_BIT := 32
|
||||
endif |
||||
ifeq ($(TARGET_ARCH_ABI),x86) |
||||
MY_BIT := 32
|
||||
endif |
||||
ifeq ($(MY_BIT),64) |
||||
MY_BASE_LL := $(LOCAL_MCL_DIR)/src/base64.ll
|
||||
LOCAL_CPPFLAGS += -DMCL_SIZEOF_UNIT=8
|
||||
endif |
||||
ifeq ($(MY_BIT),32) |
||||
MY_BASE_LL := $(LOCAL_MCL_DIR)/src/base32.ll
|
||||
LOCAL_CPPFLAGS += -DMCL_SIZEOF_UNIT=4
|
||||
endif |
||||
LOCAL_SRC_FILES := $(LOCAL_MCL_DIR)/ffi/java/mcl_wrap.cxx $(LOCAL_MCL_DIR)/src/bn_c384_256.cpp $(LOCAL_MCL_DIR)/src/fp.cpp $(MY_BASE_LL)
|
||||
LOCAL_C_INCLUDES := $(LOCAL_MCL_DIR)/include $(LOCAL_MCL_DIR)/src $(LOCAL_MCL_DIR)/ffi/java
|
||||
LOCAL_CPPFLAGS += -DMCL_DONT_USE_XBYAK
|
||||
LOCAL_CPPFLAGS += -O3 -DNDEBUG -fPIC -DMCL_DONT_USE_OPENSSL -DMCL_LLVM_BMI2=0 -DMCL_USE_LLVM=1 -DMCL_USE_VINT -DMCL_VINT_FIXED_BUFFER -DMCL_MAX_BIT_SIZE=384
|
||||
LOCAL_CPPFLAGS += -fno-threadsafe-statics
|
||||
#LOCAL_CPPFLAGS+=-fno-exceptions -fno-rtti -DCYBOZU_DONT_USE_EXCEPTION -DCYBOZU_DONT_USE_STRING -std=c++03
|
||||
|
||||
#LOCAL_CPPFLAGS += -DBLS_ETH
|
||||
#LOCAL_LDLIBS := -llog #-Wl,--no-warn-shared-textrel
|
||||
#include $(BUILD_STATIC_LIBRARY)
|
||||
include $(BUILD_SHARED_LIBRARY) |
@ -0,0 +1,4 @@ |
||||
APP_ABI := arm64-v8a armeabi-v7a x86_64
|
||||
APP_PLATFORM := android-19
|
||||
APP_STL := c++_static
|
||||
APP_CPPFLAGS := -fexceptions
|
@ -1,31 +0,0 @@ |
||||
%module Bn256 |
||||
|
||||
%include "std_string.i" |
||||
%include "std_except.i" |
||||
|
||||
|
||||
%{ |
||||
#include <cybozu/random_generator.hpp> |
||||
#include <cybozu/crypto.hpp> |
||||
#include <mcl/bn256.hpp> |
||||
struct Param { |
||||
cybozu::RandomGenerator rg; |
||||
static inline Param& getParam() |
||||
{ |
||||
static Param p; |
||||
return p; |
||||
} |
||||
}; |
||||
|
||||
static void HashAndMapToG1(mcl::bn256::G1& P, const std::string& m) |
||||
{ |
||||
std::string digest = cybozu::crypto::Hash::digest(cybozu::crypto::Hash::N_SHA256, m); |
||||
mcl::bn256::Fp t; |
||||
t.setArrayMask(digest.c_str(), digest.size()); |
||||
mcl::bn256::BN::param.mapTo.calcG1(P, t); |
||||
} |
||||
|
||||
#include "bn256_impl.hpp" |
||||
%} |
||||
|
||||
%include "bn256_impl.hpp" |
@ -1,249 +0,0 @@ |
||||
#include <mcl/bn256.hpp> |
||||
#include <stdint.h> |
||||
#include <sstream> |
||||
|
||||
void SystemInit() throw(std::exception) |
||||
{ |
||||
mcl::bn256::initPairing(); |
||||
} |
||||
|
||||
class G1; |
||||
class G2; |
||||
class GT; |
||||
/*
|
||||
Fr = Z / rZ |
||||
*/ |
||||
class Fr { |
||||
mcl::bn256::Fr self_; |
||||
friend class G1; |
||||
friend class G2; |
||||
friend class GT; |
||||
friend void neg(Fr& y, const Fr& x); |
||||
friend void add(Fr& z, const Fr& x, const Fr& y); |
||||
friend void sub(Fr& z, const Fr& x, const Fr& y); |
||||
friend void mul(Fr& z, const Fr& x, const Fr& y); |
||||
friend void mul(G1& z, const G1& x, const Fr& y); |
||||
friend void mul(G2& z, const G2& x, const Fr& y); |
||||
friend void div(Fr& z, const Fr& x, const Fr& y); |
||||
friend void pow(GT& z, const GT& x, const Fr& y); |
||||
public: |
||||
Fr() {} |
||||
Fr(const Fr& rhs) : self_(rhs.self_) {} |
||||
Fr(int x) : self_(x) {} |
||||
Fr(const std::string& str) throw(std::exception) |
||||
: self_(str) {} |
||||
bool equals(const Fr& rhs) const { return self_ == rhs.self_; } |
||||
void setStr(const std::string& str) throw(std::exception) |
||||
{ |
||||
self_.setStr(str); |
||||
} |
||||
void setInt(int x) |
||||
{ |
||||
self_ = x; |
||||
} |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
void setRand() |
||||
{ |
||||
self_.setRand(Param::getParam().rg); |
||||
} |
||||
std::string toString() const throw(std::exception) |
||||
{ |
||||
return self_.getStr(); |
||||
} |
||||
}; |
||||
|
||||
void neg(Fr& y, const Fr& x) |
||||
{ |
||||
mcl::bn256::Fr::neg(y.self_, x.self_); |
||||
} |
||||
|
||||
void add(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn256::Fr::add(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void sub(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn256::Fr::sub(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void mul(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn256::Fr::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void div(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn256::Fr::div(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
/*
|
||||
#G1 = r |
||||
*/ |
||||
class G1 { |
||||
mcl::bn256::G1 self_; |
||||
friend void neg(G1& y, const G1& x); |
||||
friend void dbl(G1& y, const G1& x); |
||||
friend void add(G1& z, const G1& x, const G1& y); |
||||
friend void sub(G1& z, const G1& x, const G1& y); |
||||
friend void mul(G1& z, const G1& x, const Fr& y); |
||||
friend void pairing(GT& e, const G1& P, const G2& Q); |
||||
public: |
||||
G1() {} |
||||
G1(const G1& rhs) : self_(rhs.self_) {} |
||||
G1(const std::string& x, const std::string& y) throw(std::exception) |
||||
: self_(mcl::bn256::Fp(x), mcl::bn256::Fp(y)) |
||||
{ |
||||
} |
||||
bool equals(const G1& rhs) const { return self_ == rhs.self_; } |
||||
void set(const std::string& x, const std::string& y) |
||||
{ |
||||
self_.set(mcl::bn256::Fp(x), mcl::bn256::Fp(y)); |
||||
} |
||||
void hashAndMapToG1(const std::string& m) throw(std::exception) |
||||
{ |
||||
HashAndMapToG1(self_, m); |
||||
} |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
/*
|
||||
compressed format |
||||
*/ |
||||
void setStr(const std::string& str) throw(std::exception) |
||||
{ |
||||
self_.setStr(str); |
||||
} |
||||
std::string toString() const throw(std::exception) |
||||
{ |
||||
return self_.getStr(); |
||||
} |
||||
}; |
||||
|
||||
void neg(G1& y, const G1& x) |
||||
{ |
||||
mcl::bn256::G1::neg(y.self_, x.self_); |
||||
} |
||||
void dbl(G1& y, const G1& x) |
||||
{ |
||||
mcl::bn256::G1::dbl(y.self_, x.self_); |
||||
} |
||||
void add(G1& z, const G1& x, const G1& y) |
||||
{ |
||||
mcl::bn256::G1::add(z.self_, x.self_, y.self_); |
||||
} |
||||
void sub(G1& z, const G1& x, const G1& y) |
||||
{ |
||||
mcl::bn256::G1::sub(z.self_, x.self_, y.self_); |
||||
} |
||||
void mul(G1& z, const G1& x, const Fr& y) |
||||
{ |
||||
mcl::bn256::G1::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
/*
|
||||
#G2 = r |
||||
*/ |
||||
class G2 { |
||||
mcl::bn256::G2 self_; |
||||
friend void neg(G2& y, const G2& x); |
||||
friend void dbl(G2& y, const G2& x); |
||||
friend void add(G2& z, const G2& x, const G2& y); |
||||
friend void sub(G2& z, const G2& x, const G2& y); |
||||
friend void mul(G2& z, const G2& x, const Fr& y); |
||||
friend void pairing(GT& e, const G1& P, const G2& Q); |
||||
public: |
||||
G2() {} |
||||
G2(const G2& rhs) : self_(rhs.self_) {} |
||||
G2(const std::string& xa, const std::string& xb, const std::string& ya, const std::string& yb) throw(std::exception) |
||||
: self_(mcl::bn256::Fp2(xa, xb), mcl::bn256::Fp2(ya, yb)) |
||||
{ |
||||
} |
||||
bool equals(const G2& rhs) const { return self_ == rhs.self_; } |
||||
void set(const std::string& xa, const std::string& xb, const std::string& ya, const std::string& yb) |
||||
{ |
||||
self_.set(mcl::bn256::Fp2(xa, xb), mcl::bn256::Fp2(ya, yb)); |
||||
} |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
/*
|
||||
compressed format |
||||
*/ |
||||
void setStr(const std::string& str) throw(std::exception) |
||||
{ |
||||
self_.setStr(str); |
||||
} |
||||
std::string toString() const throw(std::exception) |
||||
{ |
||||
return self_.getStr(); |
||||
} |
||||
}; |
||||
|
||||
void neg(G2& y, const G2& x) |
||||
{ |
||||
mcl::bn256::G2::neg(y.self_, x.self_); |
||||
} |
||||
void dbl(G2& y, const G2& x) |
||||
{ |
||||
mcl::bn256::G2::dbl(y.self_, x.self_); |
||||
} |
||||
void add(G2& z, const G2& x, const G2& y) |
||||
{ |
||||
mcl::bn256::G2::add(z.self_, x.self_, y.self_); |
||||
} |
||||
void sub(G2& z, const G2& x, const G2& y) |
||||
{ |
||||
mcl::bn256::G2::sub(z.self_, x.self_, y.self_); |
||||
} |
||||
void mul(G2& z, const G2& x, const Fr& y) |
||||
{ |
||||
mcl::bn256::G2::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
/*
|
||||
#GT = r |
||||
*/ |
||||
class GT { |
||||
mcl::bn256::Fp12 self_; |
||||
friend void mul(GT& z, const GT& x, const GT& y); |
||||
friend void pow(GT& z, const GT& x, const Fr& y); |
||||
friend void pairing(GT& e, const G1& P, const G2& Q); |
||||
public: |
||||
GT() {} |
||||
GT(const GT& rhs) : self_(rhs.self_) {} |
||||
bool equals(const GT& rhs) const { return self_ == rhs.self_; } |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
void setStr(const std::string& str) throw(std::exception) |
||||
{ |
||||
std::istringstream iss(str); |
||||
iss >> self_; |
||||
} |
||||
std::string toString() const throw(std::exception) |
||||
{ |
||||
std::ostringstream oss; |
||||
oss << self_; |
||||
return oss.str(); |
||||
} |
||||
}; |
||||
|
||||
void mul(GT& z, const GT& x, const GT& y) |
||||
{ |
||||
mcl::bn256::Fp12::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
void pow(GT& z, const GT& x, const Fr& y) |
||||
{ |
||||
mcl::bn256::Fp12::pow(z.self_, x.self_, y.self_); |
||||
} |
||||
void pairing(GT& e, const G1& P, const G2& Q) |
||||
{ |
||||
mcl::bn256::pairing(e.self_, P.self_, Q.self_); |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class CipherText { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected CipherText(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(CipherText obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
ElgamalJNI.delete_CipherText(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public String toStr() { |
||||
return ElgamalJNI.CipherText_toStr(swigCPtr, this); |
||||
} |
||||
|
||||
public String toString() { |
||||
return ElgamalJNI.CipherText_toString(swigCPtr, this); |
||||
} |
||||
|
||||
public void fromStr(String str) { |
||||
ElgamalJNI.CipherText_fromStr(swigCPtr, this, str); |
||||
} |
||||
|
||||
public void add(CipherText c) { |
||||
ElgamalJNI.CipherText_add(swigCPtr, this, CipherText.getCPtr(c), c); |
||||
} |
||||
|
||||
public void mul(int m) { |
||||
ElgamalJNI.CipherText_mul__SWIG_0(swigCPtr, this, m); |
||||
} |
||||
|
||||
public void mul(String str) { |
||||
ElgamalJNI.CipherText_mul__SWIG_1(swigCPtr, this, str); |
||||
} |
||||
|
||||
public CipherText() { |
||||
this(ElgamalJNI.new_CipherText(), true); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,38 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class Elgamal { |
||||
public static SWIGTYPE_p_bool new_p_bool() { |
||||
long cPtr = ElgamalJNI.new_p_bool(); |
||||
return (cPtr == 0) ? null : new SWIGTYPE_p_bool(cPtr, false); |
||||
} |
||||
|
||||
public static SWIGTYPE_p_bool copy_p_bool(boolean value) { |
||||
long cPtr = ElgamalJNI.copy_p_bool(value); |
||||
return (cPtr == 0) ? null : new SWIGTYPE_p_bool(cPtr, false); |
||||
} |
||||
|
||||
public static void delete_p_bool(SWIGTYPE_p_bool obj) { |
||||
ElgamalJNI.delete_p_bool(SWIGTYPE_p_bool.getCPtr(obj)); |
||||
} |
||||
|
||||
public static void p_bool_assign(SWIGTYPE_p_bool obj, boolean value) { |
||||
ElgamalJNI.p_bool_assign(SWIGTYPE_p_bool.getCPtr(obj), value); |
||||
} |
||||
|
||||
public static boolean p_bool_value(SWIGTYPE_p_bool obj) { |
||||
return ElgamalJNI.p_bool_value(SWIGTYPE_p_bool.getCPtr(obj)); |
||||
} |
||||
|
||||
public static void SystemInit(String param) { |
||||
ElgamalJNI.SystemInit(param); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,51 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class ElgamalJNI { |
||||
public final static native long new_p_bool(); |
||||
public final static native long copy_p_bool(boolean jarg1); |
||||
public final static native void delete_p_bool(long jarg1); |
||||
public final static native void p_bool_assign(long jarg1, boolean jarg2); |
||||
public final static native boolean p_bool_value(long jarg1); |
||||
public final static native void SystemInit(String jarg1); |
||||
public final static native String CipherText_toStr(long jarg1, CipherText jarg1_); |
||||
public final static native String CipherText_toString(long jarg1, CipherText jarg1_); |
||||
public final static native void CipherText_fromStr(long jarg1, CipherText jarg1_, String jarg2); |
||||
public final static native void CipherText_add(long jarg1, CipherText jarg1_, long jarg2, CipherText jarg2_); |
||||
public final static native void CipherText_mul__SWIG_0(long jarg1, CipherText jarg1_, int jarg2); |
||||
public final static native void CipherText_mul__SWIG_1(long jarg1, CipherText jarg1_, String jarg2); |
||||
public final static native long new_CipherText(); |
||||
public final static native void delete_CipherText(long jarg1); |
||||
public final static native String PublicKey_toStr(long jarg1, PublicKey jarg1_); |
||||
public final static native String PublicKey_toString(long jarg1, PublicKey jarg1_); |
||||
public final static native void PublicKey_fromStr(long jarg1, PublicKey jarg1_, String jarg2); |
||||
public final static native void PublicKey_save(long jarg1, PublicKey jarg1_, String jarg2); |
||||
public final static native void PublicKey_load(long jarg1, PublicKey jarg1_, String jarg2); |
||||
public final static native void PublicKey_enc__SWIG_0(long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, int jarg3); |
||||
public final static native void PublicKey_enc__SWIG_1(long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, String jarg3); |
||||
public final static native void PublicKey_rerandomize(long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_); |
||||
public final static native void PublicKey_add__SWIG_0(long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, int jarg3); |
||||
public final static native void PublicKey_add__SWIG_1(long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, String jarg3); |
||||
public final static native long new_PublicKey(); |
||||
public final static native void delete_PublicKey(long jarg1); |
||||
public final static native String PrivateKey_toStr(long jarg1, PrivateKey jarg1_); |
||||
public final static native String PrivateKey_toString(long jarg1, PrivateKey jarg1_); |
||||
public final static native void PrivateKey_fromStr(long jarg1, PrivateKey jarg1_, String jarg2); |
||||
public final static native void PrivateKey_save(long jarg1, PrivateKey jarg1_, String jarg2); |
||||
public final static native void PrivateKey_load(long jarg1, PrivateKey jarg1_, String jarg2); |
||||
public final static native void PrivateKey_init(long jarg1, PrivateKey jarg1_); |
||||
public final static native long PrivateKey_getPublicKey(long jarg1, PrivateKey jarg1_); |
||||
public final static native int PrivateKey_dec__SWIG_0(long jarg1, PrivateKey jarg1_, long jarg2, CipherText jarg2_, long jarg3); |
||||
public final static native int PrivateKey_dec__SWIG_1(long jarg1, PrivateKey jarg1_, long jarg2, CipherText jarg2_); |
||||
public final static native void PrivateKey_setCache(long jarg1, PrivateKey jarg1_, int jarg2, int jarg3); |
||||
public final static native void PrivateKey_clearCache(long jarg1, PrivateKey jarg1_); |
||||
public final static native long new_PrivateKey(); |
||||
public final static native void delete_PrivateKey(long jarg1); |
||||
} |
@ -0,0 +1,105 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class Fp { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected Fp(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(Fp obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
MclJNI.delete_Fp(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public Fp() { |
||||
this(MclJNI.new_Fp__SWIG_0(), true); |
||||
} |
||||
|
||||
public Fp(Fp rhs) { |
||||
this(MclJNI.new_Fp__SWIG_1(Fp.getCPtr(rhs), rhs), true); |
||||
} |
||||
|
||||
public Fp(int x) { |
||||
this(MclJNI.new_Fp__SWIG_2(x), true); |
||||
} |
||||
|
||||
public Fp(String str, int base) { |
||||
this(MclJNI.new_Fp__SWIG_3(str, base), true); |
||||
} |
||||
|
||||
public Fp(String str) { |
||||
this(MclJNI.new_Fp__SWIG_4(str), true); |
||||
} |
||||
|
||||
public boolean equals(Fp rhs) { |
||||
return MclJNI.Fp_equals(swigCPtr, this, Fp.getCPtr(rhs), rhs); |
||||
} |
||||
|
||||
public boolean isZero() { |
||||
return MclJNI.Fp_isZero(swigCPtr, this); |
||||
} |
||||
|
||||
public boolean isOne() { |
||||
return MclJNI.Fp_isOne(swigCPtr, this); |
||||
} |
||||
|
||||
public void setStr(String str, int base) { |
||||
MclJNI.Fp_setStr__SWIG_0(swigCPtr, this, str, base); |
||||
} |
||||
|
||||
public void setStr(String str) { |
||||
MclJNI.Fp_setStr__SWIG_1(swigCPtr, this, str); |
||||
} |
||||
|
||||
public void setInt(int x) { |
||||
MclJNI.Fp_setInt(swigCPtr, this, x); |
||||
} |
||||
|
||||
public void clear() { |
||||
MclJNI.Fp_clear(swigCPtr, this); |
||||
} |
||||
|
||||
public void setByCSPRNG() { |
||||
MclJNI.Fp_setByCSPRNG(swigCPtr, this); |
||||
} |
||||
|
||||
public String toString(int base) { |
||||
return MclJNI.Fp_toString__SWIG_0(swigCPtr, this, base); |
||||
} |
||||
|
||||
public String toString() { |
||||
return MclJNI.Fp_toString__SWIG_1(swigCPtr, this); |
||||
} |
||||
|
||||
public void deserialize(byte[] cbuf) { |
||||
MclJNI.Fp_deserialize(swigCPtr, this, cbuf); |
||||
} |
||||
|
||||
public byte[] serialize() { return MclJNI.Fp_serialize(swigCPtr, this); } |
||||
|
||||
} |
@ -0,0 +1,113 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class Fr { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected Fr(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(Fr obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
MclJNI.delete_Fr(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public Fr() { |
||||
this(MclJNI.new_Fr__SWIG_0(), true); |
||||
} |
||||
|
||||
public Fr(Fr rhs) { |
||||
this(MclJNI.new_Fr__SWIG_1(Fr.getCPtr(rhs), rhs), true); |
||||
} |
||||
|
||||
public Fr(int x) { |
||||
this(MclJNI.new_Fr__SWIG_2(x), true); |
||||
} |
||||
|
||||
public Fr(String str, int base) { |
||||
this(MclJNI.new_Fr__SWIG_3(str, base), true); |
||||
} |
||||
|
||||
public Fr(String str) { |
||||
this(MclJNI.new_Fr__SWIG_4(str), true); |
||||
} |
||||
|
||||
public boolean equals(Fr rhs) { |
||||
return MclJNI.Fr_equals(swigCPtr, this, Fr.getCPtr(rhs), rhs); |
||||
} |
||||
|
||||
public boolean isZero() { |
||||
return MclJNI.Fr_isZero(swigCPtr, this); |
||||
} |
||||
|
||||
public boolean isOne() { |
||||
return MclJNI.Fr_isOne(swigCPtr, this); |
||||
} |
||||
|
||||
public void setStr(String str, int base) { |
||||
MclJNI.Fr_setStr__SWIG_0(swigCPtr, this, str, base); |
||||
} |
||||
|
||||
public void setStr(String str) { |
||||
MclJNI.Fr_setStr__SWIG_1(swigCPtr, this, str); |
||||
} |
||||
|
||||
public void setInt(int x) { |
||||
MclJNI.Fr_setInt(swigCPtr, this, x); |
||||
} |
||||
|
||||
public void clear() { |
||||
MclJNI.Fr_clear(swigCPtr, this); |
||||
} |
||||
|
||||
public void setByCSPRNG() { |
||||
MclJNI.Fr_setByCSPRNG(swigCPtr, this); |
||||
} |
||||
|
||||
public String toString(int base) { |
||||
return MclJNI.Fr_toString__SWIG_0(swigCPtr, this, base); |
||||
} |
||||
|
||||
public String toString() { |
||||
return MclJNI.Fr_toString__SWIG_1(swigCPtr, this); |
||||
} |
||||
|
||||
public void deserialize(byte[] cbuf) { |
||||
MclJNI.Fr_deserialize(swigCPtr, this, cbuf); |
||||
} |
||||
|
||||
public void setLittleEndianMod(byte[] cbuf) { |
||||
MclJNI.Fr_setLittleEndianMod(swigCPtr, this, cbuf); |
||||
} |
||||
|
||||
public void setHashOf(byte[] cbuf) { |
||||
MclJNI.Fr_setHashOf(swigCPtr, this, cbuf); |
||||
} |
||||
|
||||
public byte[] serialize() { return MclJNI.Fr_serialize(swigCPtr, this); } |
||||
|
||||
} |
@ -0,0 +1,93 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class G1 { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected G1(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(G1 obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
MclJNI.delete_G1(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public G1() { |
||||
this(MclJNI.new_G1__SWIG_0(), true); |
||||
} |
||||
|
||||
public G1(G1 rhs) { |
||||
this(MclJNI.new_G1__SWIG_1(G1.getCPtr(rhs), rhs), true); |
||||
} |
||||
|
||||
public G1(Fp x, Fp y) { |
||||
this(MclJNI.new_G1__SWIG_2(Fp.getCPtr(x), x, Fp.getCPtr(y), y), true); |
||||
} |
||||
|
||||
public boolean equals(G1 rhs) { |
||||
return MclJNI.G1_equals(swigCPtr, this, G1.getCPtr(rhs), rhs); |
||||
} |
||||
|
||||
public boolean isZero() { |
||||
return MclJNI.G1_isZero(swigCPtr, this); |
||||
} |
||||
|
||||
public boolean isValidOrder() { |
||||
return MclJNI.G1_isValidOrder(swigCPtr, this); |
||||
} |
||||
|
||||
public void set(Fp x, Fp y) { |
||||
MclJNI.G1_set(swigCPtr, this, Fp.getCPtr(x), x, Fp.getCPtr(y), y); |
||||
} |
||||
|
||||
public void clear() { |
||||
MclJNI.G1_clear(swigCPtr, this); |
||||
} |
||||
|
||||
public void setStr(String str, int base) { |
||||
MclJNI.G1_setStr__SWIG_0(swigCPtr, this, str, base); |
||||
} |
||||
|
||||
public void setStr(String str) { |
||||
MclJNI.G1_setStr__SWIG_1(swigCPtr, this, str); |
||||
} |
||||
|
||||
public String toString(int base) { |
||||
return MclJNI.G1_toString__SWIG_0(swigCPtr, this, base); |
||||
} |
||||
|
||||
public String toString() { |
||||
return MclJNI.G1_toString__SWIG_1(swigCPtr, this); |
||||
} |
||||
|
||||
public void deserialize(byte[] cbuf) { |
||||
MclJNI.G1_deserialize(swigCPtr, this, cbuf); |
||||
} |
||||
|
||||
public byte[] serialize() { return MclJNI.G1_serialize(swigCPtr, this); } |
||||
|
||||
} |
@ -0,0 +1,89 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class G2 { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected G2(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(G2 obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
MclJNI.delete_G2(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public G2() { |
||||
this(MclJNI.new_G2__SWIG_0(), true); |
||||
} |
||||
|
||||
public G2(G2 rhs) { |
||||
this(MclJNI.new_G2__SWIG_1(G2.getCPtr(rhs), rhs), true); |
||||
} |
||||
|
||||
public G2(Fp ax, Fp ay, Fp bx, Fp by) { |
||||
this(MclJNI.new_G2__SWIG_2(Fp.getCPtr(ax), ax, Fp.getCPtr(ay), ay, Fp.getCPtr(bx), bx, Fp.getCPtr(by), by), true); |
||||
} |
||||
|
||||
public boolean equals(G2 rhs) { |
||||
return MclJNI.G2_equals(swigCPtr, this, G2.getCPtr(rhs), rhs); |
||||
} |
||||
|
||||
public boolean isZero() { |
||||
return MclJNI.G2_isZero(swigCPtr, this); |
||||
} |
||||
|
||||
public void set(Fp ax, Fp ay, Fp bx, Fp by) { |
||||
MclJNI.G2_set(swigCPtr, this, Fp.getCPtr(ax), ax, Fp.getCPtr(ay), ay, Fp.getCPtr(bx), bx, Fp.getCPtr(by), by); |
||||
} |
||||
|
||||
public void clear() { |
||||
MclJNI.G2_clear(swigCPtr, this); |
||||
} |
||||
|
||||
public void setStr(String str, int base) { |
||||
MclJNI.G2_setStr__SWIG_0(swigCPtr, this, str, base); |
||||
} |
||||
|
||||
public void setStr(String str) { |
||||
MclJNI.G2_setStr__SWIG_1(swigCPtr, this, str); |
||||
} |
||||
|
||||
public String toString(int base) { |
||||
return MclJNI.G2_toString__SWIG_0(swigCPtr, this, base); |
||||
} |
||||
|
||||
public String toString() { |
||||
return MclJNI.G2_toString__SWIG_1(swigCPtr, this); |
||||
} |
||||
|
||||
public void deserialize(byte[] cbuf) { |
||||
MclJNI.G2_deserialize(swigCPtr, this, cbuf); |
||||
} |
||||
|
||||
public byte[] serialize() { return MclJNI.G2_serialize(swigCPtr, this); } |
||||
|
||||
} |
@ -0,0 +1,81 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class GT { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected GT(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(GT obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
MclJNI.delete_GT(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public GT() { |
||||
this(MclJNI.new_GT__SWIG_0(), true); |
||||
} |
||||
|
||||
public GT(GT rhs) { |
||||
this(MclJNI.new_GT__SWIG_1(GT.getCPtr(rhs), rhs), true); |
||||
} |
||||
|
||||
public boolean equals(GT rhs) { |
||||
return MclJNI.GT_equals(swigCPtr, this, GT.getCPtr(rhs), rhs); |
||||
} |
||||
|
||||
public boolean isOne() { |
||||
return MclJNI.GT_isOne(swigCPtr, this); |
||||
} |
||||
|
||||
public void clear() { |
||||
MclJNI.GT_clear(swigCPtr, this); |
||||
} |
||||
|
||||
public void setStr(String str, int base) { |
||||
MclJNI.GT_setStr__SWIG_0(swigCPtr, this, str, base); |
||||
} |
||||
|
||||
public void setStr(String str) { |
||||
MclJNI.GT_setStr__SWIG_1(swigCPtr, this, str); |
||||
} |
||||
|
||||
public String toString(int base) { |
||||
return MclJNI.GT_toString__SWIG_0(swigCPtr, this, base); |
||||
} |
||||
|
||||
public String toString() { |
||||
return MclJNI.GT_toString__SWIG_1(swigCPtr, this); |
||||
} |
||||
|
||||
public void deserialize(byte[] cbuf) { |
||||
MclJNI.GT_deserialize(swigCPtr, this, cbuf); |
||||
} |
||||
|
||||
public byte[] serialize() { return MclJNI.GT_serialize(swigCPtr, this); } |
||||
|
||||
} |
@ -0,0 +1,128 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class Mcl implements MclConstants { |
||||
public static void SystemInit(int curveType) { |
||||
MclJNI.SystemInit(curveType); |
||||
} |
||||
|
||||
public static void neg(Fr y, Fr x) { |
||||
MclJNI.neg__SWIG_0(Fr.getCPtr(y), y, Fr.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void inv(Fr y, Fr x) { |
||||
MclJNI.inv__SWIG_0(Fr.getCPtr(y), y, Fr.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void add(Fr z, Fr x, Fr y) { |
||||
MclJNI.add__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void sub(Fr z, Fr x, Fr y) { |
||||
MclJNI.sub__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void mul(Fr z, Fr x, Fr y) { |
||||
MclJNI.mul__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void mul(G1 z, G1 x, Fr y) { |
||||
MclJNI.mul__SWIG_1(G1.getCPtr(z), z, G1.getCPtr(x), x, Fr.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void mul(G2 z, G2 x, Fr y) { |
||||
MclJNI.mul__SWIG_2(G2.getCPtr(z), z, G2.getCPtr(x), x, Fr.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void div(Fr z, Fr x, Fr y) { |
||||
MclJNI.div__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void pow(GT z, GT x, Fr y) { |
||||
MclJNI.pow(GT.getCPtr(z), z, GT.getCPtr(x), x, Fr.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void neg(Fp y, Fp x) { |
||||
MclJNI.neg__SWIG_1(Fp.getCPtr(y), y, Fp.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void inv(Fp y, Fp x) { |
||||
MclJNI.inv__SWIG_1(Fp.getCPtr(y), y, Fp.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void add(Fp z, Fp x, Fp y) { |
||||
MclJNI.add__SWIG_1(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void sub(Fp z, Fp x, Fp y) { |
||||
MclJNI.sub__SWIG_1(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void mul(Fp z, Fp x, Fp y) { |
||||
MclJNI.mul__SWIG_3(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void div(Fp z, Fp x, Fp y) { |
||||
MclJNI.div__SWIG_1(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void neg(G1 y, G1 x) { |
||||
MclJNI.neg__SWIG_2(G1.getCPtr(y), y, G1.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void dbl(G1 y, G1 x) { |
||||
MclJNI.dbl__SWIG_0(G1.getCPtr(y), y, G1.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void add(G1 z, G1 x, G1 y) { |
||||
MclJNI.add__SWIG_2(G1.getCPtr(z), z, G1.getCPtr(x), x, G1.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void sub(G1 z, G1 x, G1 y) { |
||||
MclJNI.sub__SWIG_2(G1.getCPtr(z), z, G1.getCPtr(x), x, G1.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void pairing(GT e, G1 P, G2 Q) { |
||||
MclJNI.pairing(GT.getCPtr(e), e, G1.getCPtr(P), P, G2.getCPtr(Q), Q); |
||||
} |
||||
|
||||
public static void hashAndMapToG1(G1 P, byte[] cbuf) { |
||||
MclJNI.hashAndMapToG1(G1.getCPtr(P), P, cbuf); |
||||
} |
||||
|
||||
public static void neg(G2 y, G2 x) { |
||||
MclJNI.neg__SWIG_3(G2.getCPtr(y), y, G2.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void dbl(G2 y, G2 x) { |
||||
MclJNI.dbl__SWIG_1(G2.getCPtr(y), y, G2.getCPtr(x), x); |
||||
} |
||||
|
||||
public static void add(G2 z, G2 x, G2 y) { |
||||
MclJNI.add__SWIG_3(G2.getCPtr(z), z, G2.getCPtr(x), x, G2.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void sub(G2 z, G2 x, G2 y) { |
||||
MclJNI.sub__SWIG_3(G2.getCPtr(z), z, G2.getCPtr(x), x, G2.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void hashAndMapToG2(G2 P, byte[] cbuf) { |
||||
MclJNI.hashAndMapToG2(G2.getCPtr(P), P, cbuf); |
||||
} |
||||
|
||||
public static void mul(GT z, GT x, GT y) { |
||||
MclJNI.mul__SWIG_4(GT.getCPtr(z), z, GT.getCPtr(x), x, GT.getCPtr(y), y); |
||||
} |
||||
|
||||
public static void inv(GT y, GT x) { |
||||
MclJNI.inv__SWIG_2(GT.getCPtr(y), y, GT.getCPtr(x), x); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,14 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public interface MclConstants { |
||||
public final static int BN254 = 0; |
||||
public final static int BLS12_381 = 5; |
||||
} |
@ -0,0 +1,120 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class MclJNI { |
||||
public final static native void SystemInit(int jarg1); |
||||
public final static native void neg__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_); |
||||
public final static native void inv__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_); |
||||
public final static native void add__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); |
||||
public final static native void sub__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); |
||||
public final static native void mul__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); |
||||
public final static native void mul__SWIG_1(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_, long jarg3, Fr jarg3_); |
||||
public final static native void mul__SWIG_2(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_, long jarg3, Fr jarg3_); |
||||
public final static native void div__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); |
||||
public final static native void pow(long jarg1, GT jarg1_, long jarg2, GT jarg2_, long jarg3, Fr jarg3_); |
||||
public final static native long new_Fr__SWIG_0(); |
||||
public final static native long new_Fr__SWIG_1(long jarg1, Fr jarg1_); |
||||
public final static native long new_Fr__SWIG_2(int jarg1); |
||||
public final static native long new_Fr__SWIG_3(String jarg1, int jarg2); |
||||
public final static native long new_Fr__SWIG_4(String jarg1); |
||||
public final static native boolean Fr_equals(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_); |
||||
public final static native boolean Fr_isZero(long jarg1, Fr jarg1_); |
||||
public final static native boolean Fr_isOne(long jarg1, Fr jarg1_); |
||||
public final static native void Fr_setStr__SWIG_0(long jarg1, Fr jarg1_, String jarg2, int jarg3); |
||||
public final static native void Fr_setStr__SWIG_1(long jarg1, Fr jarg1_, String jarg2); |
||||
public final static native void Fr_setInt(long jarg1, Fr jarg1_, int jarg2); |
||||
public final static native void Fr_clear(long jarg1, Fr jarg1_); |
||||
public final static native void Fr_setByCSPRNG(long jarg1, Fr jarg1_); |
||||
public final static native String Fr_toString__SWIG_0(long jarg1, Fr jarg1_, int jarg2); |
||||
public final static native String Fr_toString__SWIG_1(long jarg1, Fr jarg1_); |
||||
public final static native void Fr_deserialize(long jarg1, Fr jarg1_, byte[] jarg2); |
||||
public final static native void Fr_setLittleEndianMod(long jarg1, Fr jarg1_, byte[] jarg2); |
||||
public final static native void Fr_setHashOf(long jarg1, Fr jarg1_, byte[] jarg2); |
||||
public final static native byte[] Fr_serialize(long jarg1, Fr jarg1_); |
||||
public final static native void delete_Fr(long jarg1); |
||||
public final static native void neg__SWIG_1(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); |
||||
public final static native void inv__SWIG_1(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); |
||||
public final static native void add__SWIG_1(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); |
||||
public final static native void sub__SWIG_1(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); |
||||
public final static native void mul__SWIG_3(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); |
||||
public final static native void div__SWIG_1(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); |
||||
public final static native long new_Fp__SWIG_0(); |
||||
public final static native long new_Fp__SWIG_1(long jarg1, Fp jarg1_); |
||||
public final static native long new_Fp__SWIG_2(int jarg1); |
||||
public final static native long new_Fp__SWIG_3(String jarg1, int jarg2); |
||||
public final static native long new_Fp__SWIG_4(String jarg1); |
||||
public final static native boolean Fp_equals(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); |
||||
public final static native boolean Fp_isZero(long jarg1, Fp jarg1_); |
||||
public final static native boolean Fp_isOne(long jarg1, Fp jarg1_); |
||||
public final static native void Fp_setStr__SWIG_0(long jarg1, Fp jarg1_, String jarg2, int jarg3); |
||||
public final static native void Fp_setStr__SWIG_1(long jarg1, Fp jarg1_, String jarg2); |
||||
public final static native void Fp_setInt(long jarg1, Fp jarg1_, int jarg2); |
||||
public final static native void Fp_clear(long jarg1, Fp jarg1_); |
||||
public final static native void Fp_setByCSPRNG(long jarg1, Fp jarg1_); |
||||
public final static native String Fp_toString__SWIG_0(long jarg1, Fp jarg1_, int jarg2); |
||||
public final static native String Fp_toString__SWIG_1(long jarg1, Fp jarg1_); |
||||
public final static native void Fp_deserialize(long jarg1, Fp jarg1_, byte[] jarg2); |
||||
public final static native byte[] Fp_serialize(long jarg1, Fp jarg1_); |
||||
public final static native void delete_Fp(long jarg1); |
||||
public final static native void neg__SWIG_2(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_); |
||||
public final static native void dbl__SWIG_0(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_); |
||||
public final static native void add__SWIG_2(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_, long jarg3, G1 jarg3_); |
||||
public final static native void sub__SWIG_2(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_, long jarg3, G1 jarg3_); |
||||
public final static native void pairing(long jarg1, GT jarg1_, long jarg2, G1 jarg2_, long jarg3, G2 jarg3_); |
||||
public final static native void hashAndMapToG1(long jarg1, G1 jarg1_, byte[] jarg2); |
||||
public final static native long new_G1__SWIG_0(); |
||||
public final static native long new_G1__SWIG_1(long jarg1, G1 jarg1_); |
||||
public final static native long new_G1__SWIG_2(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); |
||||
public final static native boolean G1_equals(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_); |
||||
public final static native boolean G1_isZero(long jarg1, G1 jarg1_); |
||||
public final static native boolean G1_isValidOrder(long jarg1, G1 jarg1_); |
||||
public final static native void G1_set(long jarg1, G1 jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); |
||||
public final static native void G1_clear(long jarg1, G1 jarg1_); |
||||
public final static native void G1_setStr__SWIG_0(long jarg1, G1 jarg1_, String jarg2, int jarg3); |
||||
public final static native void G1_setStr__SWIG_1(long jarg1, G1 jarg1_, String jarg2); |
||||
public final static native String G1_toString__SWIG_0(long jarg1, G1 jarg1_, int jarg2); |
||||
public final static native String G1_toString__SWIG_1(long jarg1, G1 jarg1_); |
||||
public final static native void G1_deserialize(long jarg1, G1 jarg1_, byte[] jarg2); |
||||
public final static native byte[] G1_serialize(long jarg1, G1 jarg1_); |
||||
public final static native void delete_G1(long jarg1); |
||||
public final static native void neg__SWIG_3(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_); |
||||
public final static native void dbl__SWIG_1(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_); |
||||
public final static native void add__SWIG_3(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_, long jarg3, G2 jarg3_); |
||||
public final static native void sub__SWIG_3(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_, long jarg3, G2 jarg3_); |
||||
public final static native void hashAndMapToG2(long jarg1, G2 jarg1_, byte[] jarg2); |
||||
public final static native long new_G2__SWIG_0(); |
||||
public final static native long new_G2__SWIG_1(long jarg1, G2 jarg1_); |
||||
public final static native long new_G2__SWIG_2(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_, long jarg4, Fp jarg4_); |
||||
public final static native boolean G2_equals(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_); |
||||
public final static native boolean G2_isZero(long jarg1, G2 jarg1_); |
||||
public final static native void G2_set(long jarg1, G2 jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_, long jarg4, Fp jarg4_, long jarg5, Fp jarg5_); |
||||
public final static native void G2_clear(long jarg1, G2 jarg1_); |
||||
public final static native void G2_setStr__SWIG_0(long jarg1, G2 jarg1_, String jarg2, int jarg3); |
||||
public final static native void G2_setStr__SWIG_1(long jarg1, G2 jarg1_, String jarg2); |
||||
public final static native String G2_toString__SWIG_0(long jarg1, G2 jarg1_, int jarg2); |
||||
public final static native String G2_toString__SWIG_1(long jarg1, G2 jarg1_); |
||||
public final static native void G2_deserialize(long jarg1, G2 jarg1_, byte[] jarg2); |
||||
public final static native byte[] G2_serialize(long jarg1, G2 jarg1_); |
||||
public final static native void delete_G2(long jarg1); |
||||
public final static native void mul__SWIG_4(long jarg1, GT jarg1_, long jarg2, GT jarg2_, long jarg3, GT jarg3_); |
||||
public final static native void inv__SWIG_2(long jarg1, GT jarg1_, long jarg2, GT jarg2_); |
||||
public final static native long new_GT__SWIG_0(); |
||||
public final static native long new_GT__SWIG_1(long jarg1, GT jarg1_); |
||||
public final static native boolean GT_equals(long jarg1, GT jarg1_, long jarg2, GT jarg2_); |
||||
public final static native boolean GT_isOne(long jarg1, GT jarg1_); |
||||
public final static native void GT_clear(long jarg1, GT jarg1_); |
||||
public final static native void GT_setStr__SWIG_0(long jarg1, GT jarg1_, String jarg2, int jarg3); |
||||
public final static native void GT_setStr__SWIG_1(long jarg1, GT jarg1_, String jarg2); |
||||
public final static native String GT_toString__SWIG_0(long jarg1, GT jarg1_, int jarg2); |
||||
public final static native String GT_toString__SWIG_1(long jarg1, GT jarg1_); |
||||
public final static native void GT_deserialize(long jarg1, GT jarg1_, byte[] jarg2); |
||||
public final static native byte[] GT_serialize(long jarg1, GT jarg1_); |
||||
public final static native void delete_GT(long jarg1); |
||||
} |
@ -0,0 +1,87 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class PrivateKey { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected PrivateKey(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(PrivateKey obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
ElgamalJNI.delete_PrivateKey(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public String toStr() { |
||||
return ElgamalJNI.PrivateKey_toStr(swigCPtr, this); |
||||
} |
||||
|
||||
public String toString() { |
||||
return ElgamalJNI.PrivateKey_toString(swigCPtr, this); |
||||
} |
||||
|
||||
public void fromStr(String str) { |
||||
ElgamalJNI.PrivateKey_fromStr(swigCPtr, this, str); |
||||
} |
||||
|
||||
public void save(String fileName) { |
||||
ElgamalJNI.PrivateKey_save(swigCPtr, this, fileName); |
||||
} |
||||
|
||||
public void load(String fileName) { |
||||
ElgamalJNI.PrivateKey_load(swigCPtr, this, fileName); |
||||
} |
||||
|
||||
public void init() { |
||||
ElgamalJNI.PrivateKey_init(swigCPtr, this); |
||||
} |
||||
|
||||
public PublicKey getPublicKey() { |
||||
return new PublicKey(ElgamalJNI.PrivateKey_getPublicKey(swigCPtr, this), true); |
||||
} |
||||
|
||||
public int dec(CipherText c, SWIGTYPE_p_bool b) { |
||||
return ElgamalJNI.PrivateKey_dec__SWIG_0(swigCPtr, this, CipherText.getCPtr(c), c, SWIGTYPE_p_bool.getCPtr(b)); |
||||
} |
||||
|
||||
public int dec(CipherText c) { |
||||
return ElgamalJNI.PrivateKey_dec__SWIG_1(swigCPtr, this, CipherText.getCPtr(c), c); |
||||
} |
||||
|
||||
public void setCache(int rangeMin, int rangeMax) { |
||||
ElgamalJNI.PrivateKey_setCache(swigCPtr, this, rangeMin, rangeMax); |
||||
} |
||||
|
||||
public void clearCache() { |
||||
ElgamalJNI.PrivateKey_clearCache(swigCPtr, this); |
||||
} |
||||
|
||||
public PrivateKey() { |
||||
this(ElgamalJNI.new_PrivateKey(), true); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,83 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class PublicKey { |
||||
private transient long swigCPtr; |
||||
protected transient boolean swigCMemOwn; |
||||
|
||||
protected PublicKey(long cPtr, boolean cMemoryOwn) { |
||||
swigCMemOwn = cMemoryOwn; |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected static long getCPtr(PublicKey obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
protected void finalize() { |
||||
delete(); |
||||
} |
||||
|
||||
public synchronized void delete() { |
||||
if (swigCPtr != 0) { |
||||
if (swigCMemOwn) { |
||||
swigCMemOwn = false; |
||||
ElgamalJNI.delete_PublicKey(swigCPtr); |
||||
} |
||||
swigCPtr = 0; |
||||
} |
||||
} |
||||
|
||||
public String toStr() { |
||||
return ElgamalJNI.PublicKey_toStr(swigCPtr, this); |
||||
} |
||||
|
||||
public String toString() { |
||||
return ElgamalJNI.PublicKey_toString(swigCPtr, this); |
||||
} |
||||
|
||||
public void fromStr(String str) { |
||||
ElgamalJNI.PublicKey_fromStr(swigCPtr, this, str); |
||||
} |
||||
|
||||
public void save(String fileName) { |
||||
ElgamalJNI.PublicKey_save(swigCPtr, this, fileName); |
||||
} |
||||
|
||||
public void load(String fileName) { |
||||
ElgamalJNI.PublicKey_load(swigCPtr, this, fileName); |
||||
} |
||||
|
||||
public void enc(CipherText c, int m) { |
||||
ElgamalJNI.PublicKey_enc__SWIG_0(swigCPtr, this, CipherText.getCPtr(c), c, m); |
||||
} |
||||
|
||||
public void enc(CipherText c, String str) { |
||||
ElgamalJNI.PublicKey_enc__SWIG_1(swigCPtr, this, CipherText.getCPtr(c), c, str); |
||||
} |
||||
|
||||
public void rerandomize(CipherText c) { |
||||
ElgamalJNI.PublicKey_rerandomize(swigCPtr, this, CipherText.getCPtr(c), c); |
||||
} |
||||
|
||||
public void add(CipherText c, int m) { |
||||
ElgamalJNI.PublicKey_add__SWIG_0(swigCPtr, this, CipherText.getCPtr(c), c, m); |
||||
} |
||||
|
||||
public void add(CipherText c, String str) { |
||||
ElgamalJNI.PublicKey_add__SWIG_1(swigCPtr, this, CipherText.getCPtr(c), c, str); |
||||
} |
||||
|
||||
public PublicKey() { |
||||
this(ElgamalJNI.new_PublicKey(), true); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,26 @@ |
||||
/* ---------------------------------------------------------------------------- |
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 4.0.2 |
||||
* |
||||
* Do not make changes to this file unless you know what you are doing--modify |
||||
* the SWIG interface file instead. |
||||
* ----------------------------------------------------------------------------- */ |
||||
|
||||
package com.herumi.mcl; |
||||
|
||||
public class SWIGTYPE_p_bool { |
||||
private transient long swigCPtr; |
||||
|
||||
protected SWIGTYPE_p_bool(long cPtr, @SuppressWarnings("unused") boolean futureUse) { |
||||
swigCPtr = cPtr; |
||||
} |
||||
|
||||
protected SWIGTYPE_p_bool() { |
||||
swigCPtr = 0; |
||||
} |
||||
|
||||
protected static long getCPtr(SWIGTYPE_p_bool obj) { |
||||
return (obj == null) ? 0 : obj.swigCPtr; |
||||
} |
||||
} |
||||
|
@ -0,0 +1,29 @@ |
||||
%module Mcl |
||||
|
||||
%include "std_string.i" |
||||
%include "std_except.i" |
||||
|
||||
%apply(char *STRING, size_t LENGTH) { (const char *cbuf, size_t bufSize) }; |
||||
%{ |
||||
#include <mcl/bls12_381.hpp> |
||||
|
||||
#include "mcl_impl.hpp" |
||||
|
||||
%} |
||||
|
||||
%typemap(jtype) void serialize "byte[]" |
||||
%typemap(jstype) void serialize "byte[]" |
||||
%typemap(jni) void serialize "jbyteArray" |
||||
%typemap(javaout) void serialize { return $jnicall; } |
||||
%typemap(in, numinputs=0) std::string& out (std::string buf) "$1=&buf;" |
||||
%typemap(argout) std::string& out { |
||||
$result = JCALL1(NewByteArray, jenv, $1->size()); |
||||
JCALL4(SetByteArrayRegion, jenv, $result, 0, $1->size(), (const jbyte*)$1->c_str()); |
||||
} |
||||
|
||||
%include "mcl_impl.hpp" |
||||
|
||||
%javaconst(1); |
||||
#define BN254 0 |
||||
#define BLS12_381 5 |
||||
|
@ -0,0 +1,436 @@ |
||||
#include <mcl/bls12_381.hpp> |
||||
#include <stdint.h> |
||||
#include <sstream> |
||||
|
||||
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__) && !defined(__clang__) |
||||
#pragma GCC diagnostic push |
||||
#pragma GCC diagnostic ignored "-Wdeprecated" |
||||
#endif |
||||
|
||||
void SystemInit(int curveType) throw(std::exception) |
||||
{ |
||||
mcl::CurveParam cp; |
||||
switch (curveType) { |
||||
case MCL_BN254: cp = mcl::BN254; break; |
||||
case MCL_BN_SNARK1: cp = mcl::BN_SNARK1; break; |
||||
case MCL_BLS12_381: cp = mcl::BLS12_381; break; |
||||
default: |
||||
throw std::runtime_error("bad curveType"); |
||||
} |
||||
mcl::bn::initPairing(cp); |
||||
} |
||||
|
||||
template<class T> |
||||
void deserializeT(T& x, const char *cbuf, size_t bufSize) |
||||
{ |
||||
if (x.deserialize(cbuf, bufSize) == 0) { |
||||
throw std::runtime_error("deserialize"); |
||||
} |
||||
} |
||||
|
||||
template<class T> |
||||
void setLittleEndianModT(T& x, const char *cbuf, size_t bufSize) |
||||
{ |
||||
x.setLittleEndianMod(cbuf, bufSize); |
||||
} |
||||
|
||||
template<class T> |
||||
void setHashOfT(T& x, const char *cbuf, size_t bufSize) |
||||
{ |
||||
x.setHashOf(cbuf, bufSize); |
||||
} |
||||
|
||||
template<class T> |
||||
void serializeT(std::string& out, const T& x) |
||||
{ |
||||
out.resize(48 * 12); |
||||
size_t n = x.serialize(&out[0], out.size()); |
||||
if (n == 0) throw std::runtime_error("serializeT"); |
||||
out.resize(n); |
||||
} |
||||
|
||||
class G1; |
||||
class G2; |
||||
class GT; |
||||
/*
|
||||
Fr = Z / rZ |
||||
*/ |
||||
class Fr { |
||||
mcl::bn::Fr self_; |
||||
friend class G1; |
||||
friend class G2; |
||||
friend class GT; |
||||
friend void neg(Fr& y, const Fr& x); |
||||
friend void inv(Fr& y, const Fr& x); |
||||
friend void add(Fr& z, const Fr& x, const Fr& y); |
||||
friend void sub(Fr& z, const Fr& x, const Fr& y); |
||||
friend void mul(Fr& z, const Fr& x, const Fr& y); |
||||
friend void mul(G1& z, const G1& x, const Fr& y); |
||||
friend void mul(G2& z, const G2& x, const Fr& y); |
||||
friend void div(Fr& z, const Fr& x, const Fr& y); |
||||
friend void pow(GT& z, const GT& x, const Fr& y); |
||||
public: |
||||
Fr() {} |
||||
Fr(const Fr& rhs) : self_(rhs.self_) {} |
||||
Fr(int x) : self_(x) {} |
||||
Fr(const std::string& str, int base = 0) throw(std::exception) |
||||
: self_(str, base) {} |
||||
bool equals(const Fr& rhs) const { return self_ == rhs.self_; } |
||||
bool isZero() const { return self_.isZero(); } |
||||
bool isOne() const { return self_.isOne(); } |
||||
void setStr(const std::string& str, int base = 0) throw(std::exception) |
||||
{ |
||||
self_.setStr(str, base); |
||||
} |
||||
void setInt(int x) |
||||
{ |
||||
self_ = x; |
||||
} |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
void setByCSPRNG() |
||||
{ |
||||
self_.setByCSPRNG(); |
||||
} |
||||
std::string toString(int base = 0) const throw(std::exception) |
||||
{ |
||||
return self_.getStr(base); |
||||
} |
||||
void deserialize(const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
deserializeT(self_, cbuf, bufSize); |
||||
} |
||||
void setLittleEndianMod(const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
setLittleEndianModT(self_, cbuf, bufSize); |
||||
} |
||||
void setHashOf(const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
setHashOfT(self_, cbuf, bufSize); |
||||
} |
||||
void serialize(std::string& out) const throw(std::exception) |
||||
{ |
||||
serializeT(out, self_); |
||||
} |
||||
}; |
||||
|
||||
void neg(Fr& y, const Fr& x) |
||||
{ |
||||
mcl::bn::Fr::neg(y.self_, x.self_); |
||||
} |
||||
|
||||
void inv(Fr& y, const Fr& x) |
||||
{ |
||||
mcl::bn::Fr::inv(y.self_, x.self_); |
||||
} |
||||
|
||||
void add(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn::Fr::add(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void sub(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn::Fr::sub(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void mul(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn::Fr::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void div(Fr& z, const Fr& x, const Fr& y) |
||||
{ |
||||
mcl::bn::Fr::div(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
class Fp { |
||||
mcl::bn::Fp self_; |
||||
friend class G1; |
||||
friend class G2; |
||||
friend class GT; |
||||
friend void neg(Fp& y, const Fp& x); |
||||
friend void inv(Fp& y, const Fp& x); |
||||
friend void add(Fp& z, const Fp& x, const Fp& y); |
||||
friend void sub(Fp& z, const Fp& x, const Fp& y); |
||||
friend void mul(Fp& z, const Fp& x, const Fp& y); |
||||
friend void div(Fp& z, const Fp& x, const Fp& y); |
||||
public: |
||||
Fp() {} |
||||
Fp(const Fp& rhs) : self_(rhs.self_) {} |
||||
Fp(int x) : self_(x) {} |
||||
Fp(const std::string& str, int base = 0) throw(std::exception) |
||||
: self_(str, base) {} |
||||
bool equals(const Fp& rhs) const { return self_ == rhs.self_; } |
||||
bool isZero() const { return self_.isZero(); } |
||||
bool isOne() const { return self_.isOne(); } |
||||
void setStr(const std::string& str, int base = 0) throw(std::exception) |
||||
{ |
||||
self_.setStr(str, base); |
||||
} |
||||
void setInt(int x) |
||||
{ |
||||
self_ = x; |
||||
} |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
void setByCSPRNG() |
||||
{ |
||||
self_.setByCSPRNG(); |
||||
} |
||||
std::string toString(int base = 0) const throw(std::exception) |
||||
{ |
||||
return self_.getStr(base); |
||||
} |
||||
void deserialize(const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
deserializeT(self_, cbuf, bufSize); |
||||
} |
||||
void serialize(std::string& out) const throw(std::exception) |
||||
{ |
||||
serializeT(out, self_); |
||||
} |
||||
}; |
||||
|
||||
void neg(Fp& y, const Fp& x) |
||||
{ |
||||
mcl::bn::Fp::neg(y.self_, x.self_); |
||||
} |
||||
|
||||
void inv(Fp& y, const Fp& x) |
||||
{ |
||||
mcl::bn::Fp::inv(y.self_, x.self_); |
||||
} |
||||
|
||||
void add(Fp& z, const Fp& x, const Fp& y) |
||||
{ |
||||
mcl::bn::Fp::add(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void sub(Fp& z, const Fp& x, const Fp& y) |
||||
{ |
||||
mcl::bn::Fp::sub(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void mul(Fp& z, const Fp& x, const Fp& y) |
||||
{ |
||||
mcl::bn::Fp::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
void div(Fp& z, const Fp& x, const Fp& y) |
||||
{ |
||||
mcl::bn::Fp::div(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
|
||||
/*
|
||||
#G1 = r |
||||
*/ |
||||
class G1 { |
||||
mcl::bn::G1 self_; |
||||
friend void neg(G1& y, const G1& x); |
||||
friend void dbl(G1& y, const G1& x); |
||||
friend void add(G1& z, const G1& x, const G1& y); |
||||
friend void sub(G1& z, const G1& x, const G1& y); |
||||
friend void mul(G1& z, const G1& x, const Fr& y); |
||||
friend void pairing(GT& e, const G1& P, const G2& Q); |
||||
friend void hashAndMapToG1(G1& P, const char *cbuf, size_t bufSize) throw(std::exception); |
||||
public: |
||||
G1() {} |
||||
G1(const G1& rhs) : self_(rhs.self_) {} |
||||
G1(const Fp& x, const Fp& y) throw(std::exception) |
||||
: self_(x.self_, y.self_) { } |
||||
bool equals(const G1& rhs) const { return self_ == rhs.self_; } |
||||
bool isZero() const { return self_.isZero(); } |
||||
bool isValidOrder() const { return self_.isValidOrder(); } |
||||
void set(const Fp& x, const Fp& y) throw(std::exception) |
||||
{ |
||||
self_.set(x.self_, y.self_); |
||||
} |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
/*
|
||||
compressed format |
||||
*/ |
||||
void setStr(const std::string& str, int base = 0) throw(std::exception) |
||||
{ |
||||
self_.setStr(str, base); |
||||
} |
||||
std::string toString(int base = 0) const throw(std::exception) |
||||
{ |
||||
return self_.getStr(base); |
||||
} |
||||
void deserialize(const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
deserializeT(self_, cbuf, bufSize); |
||||
} |
||||
void serialize(std::string& out) const throw(std::exception) |
||||
{ |
||||
serializeT(out, self_); |
||||
} |
||||
}; |
||||
|
||||
void neg(G1& y, const G1& x) |
||||
{ |
||||
mcl::bn::G1::neg(y.self_, x.self_); |
||||
} |
||||
void dbl(G1& y, const G1& x) |
||||
{ |
||||
mcl::bn::G1::dbl(y.self_, x.self_); |
||||
} |
||||
void add(G1& z, const G1& x, const G1& y) |
||||
{ |
||||
mcl::bn::G1::add(z.self_, x.self_, y.self_); |
||||
} |
||||
void sub(G1& z, const G1& x, const G1& y) |
||||
{ |
||||
mcl::bn::G1::sub(z.self_, x.self_, y.self_); |
||||
} |
||||
void mul(G1& z, const G1& x, const Fr& y) |
||||
{ |
||||
mcl::bn::G1::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
/*
|
||||
#G2 = r |
||||
*/ |
||||
class G2 { |
||||
mcl::bn::G2 self_; |
||||
friend void neg(G2& y, const G2& x); |
||||
friend void dbl(G2& y, const G2& x); |
||||
friend void add(G2& z, const G2& x, const G2& y); |
||||
friend void sub(G2& z, const G2& x, const G2& y); |
||||
friend void mul(G2& z, const G2& x, const Fr& y); |
||||
friend void pairing(GT& e, const G1& P, const G2& Q); |
||||
friend void hashAndMapToG2(G2& P, const char *cbuf, size_t bufSize) throw(std::exception); |
||||
public: |
||||
G2() {} |
||||
G2(const G2& rhs) : self_(rhs.self_) {} |
||||
G2(const Fp& ax, const Fp& ay, const Fp& bx, const Fp& by) throw(std::exception) |
||||
: self_(mcl::bn::Fp2(ax.self_, ay.self_), mcl::bn::Fp2(bx.self_, by.self_)) |
||||
{ |
||||
} |
||||
bool equals(const G2& rhs) const { return self_ == rhs.self_; } |
||||
bool isZero() const { return self_.isZero(); } |
||||
void set(const Fp& ax, const Fp& ay, const Fp& bx, const Fp& by) throw(std::exception) |
||||
{ |
||||
self_.set(mcl::bn::Fp2(ax.self_, ay.self_), mcl::bn::Fp2(bx.self_, by.self_)); |
||||
} |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
/*
|
||||
compressed format |
||||
*/ |
||||
void setStr(const std::string& str, int base = 0) throw(std::exception) |
||||
{ |
||||
self_.setStr(str, base); |
||||
} |
||||
std::string toString(int base = 0) const throw(std::exception) |
||||
{ |
||||
return self_.getStr(base); |
||||
} |
||||
void deserialize(const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
deserializeT(self_, cbuf, bufSize); |
||||
} |
||||
void serialize(std::string& out) const throw(std::exception) |
||||
{ |
||||
serializeT(out, self_); |
||||
} |
||||
}; |
||||
|
||||
void neg(G2& y, const G2& x) |
||||
{ |
||||
mcl::bn::G2::neg(y.self_, x.self_); |
||||
} |
||||
void dbl(G2& y, const G2& x) |
||||
{ |
||||
mcl::bn::G2::dbl(y.self_, x.self_); |
||||
} |
||||
void add(G2& z, const G2& x, const G2& y) |
||||
{ |
||||
mcl::bn::G2::add(z.self_, x.self_, y.self_); |
||||
} |
||||
void sub(G2& z, const G2& x, const G2& y) |
||||
{ |
||||
mcl::bn::G2::sub(z.self_, x.self_, y.self_); |
||||
} |
||||
void mul(G2& z, const G2& x, const Fr& y) |
||||
{ |
||||
mcl::bn::G2::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
|
||||
/*
|
||||
#GT = r |
||||
*/ |
||||
class GT { |
||||
mcl::bn::Fp12 self_; |
||||
friend void mul(GT& z, const GT& x, const GT& y); |
||||
friend void inv(GT& y, GT& x); |
||||
friend void pow(GT& z, const GT& x, const Fr& y); |
||||
friend void pairing(GT& e, const G1& P, const G2& Q); |
||||
public: |
||||
GT() {} |
||||
GT(const GT& rhs) : self_(rhs.self_) {} |
||||
bool equals(const GT& rhs) const { return self_ == rhs.self_; } |
||||
bool isOne() const { return self_.isOne(); } |
||||
void clear() |
||||
{ |
||||
self_.clear(); |
||||
} |
||||
void setStr(const std::string& str, int base = 0) throw(std::exception) |
||||
{ |
||||
self_.setStr(str, base); |
||||
} |
||||
std::string toString(int base = 0) const throw(std::exception) |
||||
{ |
||||
return self_.getStr(base); |
||||
} |
||||
void deserialize(const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
deserializeT(self_, cbuf, bufSize); |
||||
} |
||||
void serialize(std::string& out) const throw(std::exception) |
||||
{ |
||||
serializeT(out, self_); |
||||
} |
||||
}; |
||||
|
||||
void mul(GT& z, const GT& x, const GT& y) |
||||
{ |
||||
mcl::bn::Fp12::mul(z.self_, x.self_, y.self_); |
||||
} |
||||
void inv(GT& y, GT& x) |
||||
{ |
||||
mcl::bn::Fp12::unitaryInv(y.self_, x.self_); |
||||
} |
||||
void pow(GT& z, const GT& x, const Fr& y) |
||||
{ |
||||
mcl::bn::Fp12::pow(z.self_, x.self_, y.self_); |
||||
} |
||||
void pairing(GT& e, const G1& P, const G2& Q) |
||||
{ |
||||
mcl::bn::pairing(e.self_, P.self_, Q.self_); |
||||
} |
||||
|
||||
void hashAndMapToG1(G1& P, const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
mcl::bn::hashAndMapToG1(P.self_, cbuf, bufSize); |
||||
} |
||||
|
||||
void hashAndMapToG2(G2& P, const char *cbuf, size_t bufSize) throw(std::exception) |
||||
{ |
||||
mcl::bn::hashAndMapToG2(P.self_, cbuf, bufSize); |
||||
} |
||||
|
||||
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__) && !defined(__clang__) |
||||
#pragma GCC diagnostic pop |
||||
#endif |
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@ |
||||
@echo off |
||||
echo [[compile Bn256Test.java]] |
||||
%JAVA_DIR%\bin\javac Bn256Test.java |
||||
|
||||
echo [[run Bn256Test]] |
||||
set TOP_DIR=..\.. |
||||
pushd %TOP_DIR%\bin |
||||
%JAVA_DIR%\bin\java -classpath ../ffi/java Bn256Test %1 %2 %3 %4 %5 %6 |
||||
popd |
@ -0,0 +1,9 @@ |
||||
@echo off |
||||
echo [[compile MclTest.java]] |
||||
%JAVA_DIR%\bin\javac MclTest.java |
||||
|
||||
echo [[run MclTest]] |
||||
set TOP_DIR=..\.. |
||||
pushd %TOP_DIR%\bin |
||||
%JAVA_DIR%\bin\java -classpath ../ffi/java MclTest %1 %2 %3 %4 %5 %6 |
||||
popd |
@ -0,0 +1,9 @@ |
||||
include ../../common.mk |
||||
|
||||
SHE384_256_SLIB=libmclshe384_256.$(LIB_SUF)
|
||||
|
||||
she_test: ../../lib/$(SHE384_256_SLIB) |
||||
cd ../../lib && env LD_LIBRARY_PATH=./ python3 ../ffi/python/she.py
|
||||
|
||||
../../lib/$(SHE384_256_SLIB): |
||||
make -C ../../ lib/$(SHE384_256_SLIB)
|
@ -0,0 +1,7 @@ |
||||
# sample for Python |
||||
|
||||
## SHE |
||||
|
||||
``` |
||||
make she_test |
||||
``` |
@ -0,0 +1,146 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief atomic operation |
||||
|
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@author MITSUNARI Shigeo |
||||
*/ |
||||
#include <cybozu/inttype.hpp> |
||||
#ifdef _WIN32 |
||||
#ifndef WIN32_LEAN_AND_MEAN |
||||
#define WIN32_LEAN_AND_MEAN |
||||
#endif |
||||
#include <windows.h> |
||||
#include <intrin.h> |
||||
#else |
||||
#include <emmintrin.h> |
||||
#endif |
||||
|
||||
namespace cybozu { |
||||
|
||||
namespace atomic_local { |
||||
|
||||
template<size_t S> |
||||
struct Tag {}; |
||||
|
||||
template<> |
||||
struct Tag<4> { |
||||
template<class T> |
||||
static inline T AtomicAddSub(T *p, T y) |
||||
{ |
||||
#ifdef _WIN32 |
||||
return (T)_InterlockedExchangeAdd((long*)p, (long)y); |
||||
#else |
||||
return static_cast<T>(__sync_fetch_and_add(p, y)); |
||||
#endif |
||||
} |
||||
|
||||
template<class T> |
||||
static inline T AtomicCompareExchangeSub(T *p, T newValue, T oldValue) |
||||
{ |
||||
#ifdef _WIN32 |
||||
return (T)_InterlockedCompareExchange((long*)p, (long)newValue, (long)oldValue); |
||||
#else |
||||
return static_cast<T>(__sync_val_compare_and_swap(p, oldValue, newValue)); |
||||
#endif |
||||
} |
||||
|
||||
template<class T> |
||||
static inline T AtomicExchangeSub(T *p, T newValue) |
||||
{ |
||||
#ifdef _WIN32 |
||||
return (T)_InterlockedExchange((long*)p, (long)newValue); |
||||
#else |
||||
return static_cast<T>(__sync_lock_test_and_set(p, newValue)); |
||||
#endif |
||||
} |
||||
}; |
||||
|
||||
template<> |
||||
struct Tag<8> { |
||||
#if (CYBOZU_OS_BIT == 64) |
||||
template<class T> |
||||
static inline T AtomicAddSub(T *p, T y) |
||||
{ |
||||
#ifdef _WIN32 |
||||
return (T)_InterlockedExchangeAdd64((int64_t*)p, (int64_t)y); |
||||
#else |
||||
return static_cast<T>(__sync_fetch_and_add(p, y)); |
||||
#endif |
||||
} |
||||
#endif |
||||
|
||||
template<class T> |
||||
static inline T AtomicCompareExchangeSub(T *p, T newValue, T oldValue) |
||||
{ |
||||
#ifdef _WIN32 |
||||
return (T)_InterlockedCompareExchange64((int64_t*)p, (int64_t)newValue, (int64_t)oldValue); |
||||
#else |
||||
return static_cast<T>(__sync_val_compare_and_swap(p, oldValue, newValue)); |
||||
#endif |
||||
} |
||||
|
||||
#if (CYBOZU_OS_BIT == 64) |
||||
template<class T> |
||||
static inline T AtomicExchangeSub(T *p, T newValue) |
||||
{ |
||||
#ifdef _WIN32 |
||||
return (T)_InterlockedExchange64((int64_t*)p, (int64_t)newValue); |
||||
#else |
||||
return static_cast<T>(__sync_lock_test_and_set(p, newValue)); |
||||
#endif |
||||
} |
||||
#endif |
||||
}; |
||||
|
||||
} // atomic_local
|
||||
|
||||
/**
|
||||
atomic operation |
||||
see http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Atomic-Builtins.html
|
||||
http://msdn.microsoft.com/en-us/library/ms683504(VS.85).aspx
|
||||
*/ |
||||
/**
|
||||
tmp = *p; |
||||
*p += y; |
||||
return tmp; |
||||
*/ |
||||
template<class T> |
||||
T AtomicAdd(T *p, T y) |
||||
{ |
||||
return atomic_local::Tag<sizeof(T)>::AtomicAddSub(p, y); |
||||
} |
||||
|
||||
/**
|
||||
tmp = *p; |
||||
if (*p == oldValue) *p = newValue; |
||||
return tmp; |
||||
*/ |
||||
template<class T> |
||||
T AtomicCompareExchange(T *p, T newValue, T oldValue) |
||||
{ |
||||
return atomic_local::Tag<sizeof(T)>::AtomicCompareExchangeSub(p, newValue, oldValue); |
||||
} |
||||
|
||||
/**
|
||||
tmp = *p; |
||||
*p = newValue; |
||||
return tmp; |
||||
*/ |
||||
template<class T> |
||||
T AtomicExchange(T *p, T newValue) |
||||
{ |
||||
return atomic_local::Tag<sizeof(T)>::AtomicExchangeSub(p, newValue); |
||||
} |
||||
|
||||
inline void mfence() |
||||
{ |
||||
#ifdef _MSC_VER |
||||
MemoryBarrier(); |
||||
#else |
||||
_mm_mfence(); |
||||
#endif |
||||
} |
||||
|
||||
} // cybozu
|
@ -0,0 +1,626 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief file class and operations |
||||
|
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@remark mingw requires -lshlwapi option |
||||
*/ |
||||
|
||||
#include <assert.h> |
||||
#include <sys/stat.h> // for stat |
||||
#include <cybozu/exception.hpp> |
||||
#include <vector> |
||||
#include <ios> |
||||
#ifdef _WIN32 |
||||
#include <shlwapi.h> |
||||
#include <io.h> |
||||
#include <fcntl.h> |
||||
#include <shlobj.h> |
||||
#include <direct.h> |
||||
#ifndef WIN32_LEAN_AND_MEAN |
||||
#define WIN32_LEAN_AND_MEAN |
||||
#endif |
||||
#include <windows.h> |
||||
#ifdef _MSC_VER |
||||
#pragma comment(lib, "shlwapi.lib") |
||||
#pragma comment(lib, "shell32.lib") |
||||
#pragma comment(lib, "User32.lib") |
||||
#endif |
||||
#else |
||||
#include <stdio.h> |
||||
#include <unistd.h> |
||||
#include <sys/types.h> |
||||
#include <fcntl.h> |
||||
#include <dirent.h> |
||||
#endif |
||||
#ifdef __APPLE__ |
||||
#include <mach-o/dyld.h> |
||||
#endif |
||||
|
||||
namespace cybozu { |
||||
|
||||
class File { |
||||
std::string name_; // used for only errmsg
|
||||
#ifdef _WIN32 |
||||
typedef HANDLE handleType; |
||||
#else |
||||
typedef int handleType; |
||||
enum { |
||||
INVALID_HANDLE_VALUE = -1 |
||||
}; |
||||
#endif |
||||
handleType hdl_; |
||||
bool doClose_; |
||||
bool isReadOnly_; |
||||
File(const File&); |
||||
void operator=(const File&); |
||||
#ifdef _WIN32 |
||||
void openSub() |
||||
{ |
||||
} |
||||
#endif |
||||
void verifyMode(std::ios::openmode mode) |
||||
{ |
||||
doClose_ = true; |
||||
bool isCorrectMode = true; |
||||
if (!!(mode & std::ios::in) == !!(mode & std::ios::out)) { |
||||
isCorrectMode = false; |
||||
} else { |
||||
if (mode & std::ios::in) { |
||||
isReadOnly_ = true; |
||||
if ((mode & std::ios::app) || (mode & std::ios::trunc)) isCorrectMode = false; |
||||
} else { |
||||
isReadOnly_ = false; |
||||
if ((mode & std::ios::app) && (mode & std::ios::trunc)) isCorrectMode = false; |
||||
} |
||||
} |
||||
if (!isCorrectMode) { |
||||
throw cybozu::Exception("File:open:bad mode") << name_ << mode; |
||||
} |
||||
} |
||||
#ifdef _WIN32 |
||||
HANDLE createFile(const std::string& name, DWORD access, DWORD share, DWORD disposition) |
||||
{ |
||||
return ::CreateFileA(name.c_str(), access, share, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL); |
||||
} |
||||
HANDLE createFile(const std::wstring& name, DWORD access, DWORD share, DWORD disposition) |
||||
{ |
||||
return ::CreateFileW(name.c_str(), access, share, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL); |
||||
} |
||||
template<class T> |
||||
void setHandle(const T& name, std::ios::openmode mode) |
||||
{ |
||||
DWORD access = GENERIC_READ; |
||||
DWORD disposition = OPEN_EXISTING; |
||||
DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE; |
||||
if (mode & std::ios::out) { |
||||
access = GENERIC_WRITE; |
||||
disposition = CREATE_ALWAYS; |
||||
if (mode & std::ios::app) { |
||||
disposition = OPEN_ALWAYS; |
||||
} |
||||
} |
||||
hdl_ = createFile(name, access, share, disposition); |
||||
} |
||||
#else |
||||
void setHandle(const std::string& name, std::ios::openmode mode) |
||||
{ |
||||
int flags = O_RDONLY; // | O_NOATIME; /* can't use on NFS */
|
||||
mode_t access = 0644; |
||||
if (mode & std::ios::out) { |
||||
flags = O_WRONLY | O_CREAT; |
||||
if (mode & std::ios::app) { |
||||
flags |= O_APPEND; |
||||
} else { |
||||
flags |= O_TRUNC; |
||||
} |
||||
} |
||||
hdl_ = ::open(name.c_str(), flags, access); |
||||
} |
||||
#endif |
||||
template<class T> |
||||
void openSub(const T& name, std::ios::openmode mode) |
||||
{ |
||||
if (isOpen()) throw cybozu::Exception("File:open:alread opened") << name_; |
||||
verifyMode(mode); |
||||
setHandle(name, mode); |
||||
if (isOpen()) { |
||||
if (mode & std::ios::app) { |
||||
seek(getSize(), std::ios::beg); |
||||
} |
||||
return; |
||||
} |
||||
throw cybozu::Exception("File:open") << name_ << cybozu::ErrorNo() << static_cast<int>(mode); |
||||
} |
||||
public: |
||||
File() |
||||
: hdl_(INVALID_HANDLE_VALUE) |
||||
, doClose_(true) |
||||
, isReadOnly_(false) |
||||
{ |
||||
} |
||||
File(const std::string& name, std::ios::openmode mode) |
||||
: hdl_(INVALID_HANDLE_VALUE) |
||||
, doClose_(true) |
||||
, isReadOnly_(false) |
||||
{ |
||||
open(name, mode); |
||||
} |
||||
/*
|
||||
construct with file handle |
||||
@param hdl [in] file handle |
||||
*/ |
||||
explicit File(handleType hdl) |
||||
: hdl_(hdl) |
||||
, doClose_(false) |
||||
, isReadOnly_(false) |
||||
|
||||
{ |
||||
} |
||||
~File() CYBOZU_NOEXCEPT |
||||
{ |
||||
if (!doClose_) return; |
||||
try { |
||||
sync(); |
||||
close(); |
||||
} catch (std::exception& e) { |
||||
fprintf(stderr, "File:dstr:%s\n", e.what()); |
||||
} catch (...) { |
||||
fprintf(stderr, "File:dstr:unknown\n"); |
||||
} |
||||
} |
||||
bool isOpen() const CYBOZU_NOEXCEPT { return hdl_ != INVALID_HANDLE_VALUE; } |
||||
/**
|
||||
support mode |
||||
always binary mode |
||||
ios::in : read only |
||||
ios::out : write only(+truncate) |
||||
ios::out + ios::app(append) |
||||
*/ |
||||
void open(const std::string& name, std::ios::openmode mode) |
||||
{ |
||||
name_ = name; |
||||
openSub(name, mode); |
||||
} |
||||
void openW(const std::string& name) |
||||
{ |
||||
open(name, std::ios::out | std::ios::binary | std::ios::trunc); |
||||
} |
||||
void openR(const std::string& name) |
||||
{ |
||||
open(name, std::ios::in | std::ios::binary); |
||||
} |
||||
#ifdef _WIN32 |
||||
void open(const std::wstring& name, std::ios::openmode mode) |
||||
{ |
||||
name_ = cybozu::exception::wstr2str(name); |
||||
openSub(name, mode); |
||||
} |
||||
File(const std::wstring& name, std::ios::openmode mode) |
||||
: hdl_(INVALID_HANDLE_VALUE) |
||||
{ |
||||
open(name, mode); |
||||
} |
||||
void openW(const std::wstring& name) |
||||
{ |
||||
open(name, std::ios::out | std::ios::binary | std::ios::trunc); |
||||
} |
||||
void openR(const std::wstring& name) |
||||
{ |
||||
open(name, std::ios::in | std::ios::binary); |
||||
} |
||||
#endif |
||||
void close() |
||||
{ |
||||
if (!isOpen()) return; |
||||
#ifdef _WIN32 |
||||
bool isOK = ::CloseHandle(hdl_) != 0; |
||||
#else |
||||
bool isOK = ::close(hdl_) == 0; |
||||
#endif |
||||
hdl_ = INVALID_HANDLE_VALUE; |
||||
if (isOK) return; |
||||
throw cybozu::Exception("File:close") << name_ << cybozu::ErrorNo(); |
||||
} |
||||
/*
|
||||
sync |
||||
@param doFullSync [in] call sync(for only Linux) |
||||
*/ |
||||
void sync(bool doFullSync = false) |
||||
{ |
||||
cybozu::disable_warning_unused_variable(doFullSync); |
||||
if (!isOpen()) return; |
||||
if (isReadOnly_) return; |
||||
#ifdef _WIN32 |
||||
/* fail if isReadOnly_ */ |
||||
if (!::FlushFileBuffers(hdl_)) goto ERR_EXIT; |
||||
#elif defined(__linux__) || defined(__CYGWIN__) |
||||
if (doFullSync) { |
||||
if (::fsync(hdl_)) goto ERR_EXIT; |
||||
} else { |
||||
if (::fdatasync(hdl_)) goto ERR_EXIT; |
||||
} |
||||
#else |
||||
if (::fcntl(hdl_, F_FULLFSYNC)) goto ERR_EXIT; |
||||
#endif |
||||
return; |
||||
ERR_EXIT: |
||||
throw cybozu::Exception("File:sync") << name_ << cybozu::ErrorNo(); |
||||
} |
||||
void write(const void *buf, size_t bufSize) |
||||
{ |
||||
const char *p = static_cast<const char *>(buf); |
||||
while (bufSize > 0) { |
||||
uint32_t size = static_cast<uint32_t>(std::min<size_t>(0x7fffffff, bufSize)); |
||||
#ifdef _WIN32 |
||||
DWORD writeSize; |
||||
if (!::WriteFile(hdl_, p, size, &writeSize, NULL)) goto ERR_EXIT; |
||||
#else |
||||
ssize_t writeSize = ::write(hdl_, p, size); |
||||
if (writeSize < 0) { |
||||
if (errno == EINTR) continue; |
||||
goto ERR_EXIT; |
||||
} |
||||
#endif |
||||
p += writeSize; |
||||
bufSize -= writeSize; |
||||
} |
||||
return; |
||||
ERR_EXIT: |
||||
throw cybozu::Exception("File:write") << name_ << cybozu::ErrorNo(); |
||||
} |
||||
size_t readSome(void *buf, size_t bufSize) |
||||
{ |
||||
uint32_t size = static_cast<uint32_t>(std::min<size_t>(0x7fffffff, bufSize)); |
||||
#ifdef _WIN32 |
||||
DWORD readSize; |
||||
if (!::ReadFile(hdl_, buf, size, &readSize, NULL)) goto ERR_EXIT; |
||||
#else |
||||
RETRY: |
||||
ssize_t readSize = ::read(hdl_, buf, size); |
||||
if (readSize < 0) { |
||||
if (errno == EINTR) goto RETRY; |
||||
goto ERR_EXIT; |
||||
} |
||||
#endif |
||||
return readSize; |
||||
ERR_EXIT: |
||||
throw cybozu::Exception("File:read") << name_ << cybozu::ErrorNo(); |
||||
} |
||||
void read(void *buf, size_t bufSize) |
||||
{ |
||||
char *p = static_cast<char *>(buf); |
||||
while (bufSize > 0) { |
||||
size_t readSize = readSome(p, bufSize); |
||||
p += readSize; |
||||
bufSize -= readSize; |
||||
} |
||||
} |
||||
void seek(int64_t pos, std::ios::seek_dir dir) |
||||
{ |
||||
#ifdef _WIN32 |
||||
LARGE_INTEGER largePos; |
||||
largePos.QuadPart = pos; |
||||
DWORD posMode = FILE_BEGIN; |
||||
switch (dir) { |
||||
case std::ios::beg: |
||||
posMode = FILE_BEGIN; |
||||
break; |
||||
case std::ios::cur: |
||||
default: |
||||
posMode = FILE_CURRENT; |
||||
break; |
||||
case std::ios::end: |
||||
posMode = FILE_END; |
||||
break; |
||||
} |
||||
bool isOK = SetFilePointerEx(hdl_, largePos, NULL, posMode) != 0; |
||||
#else |
||||
int whence; |
||||
switch (dir) { |
||||
case std::ios::beg: |
||||
whence = SEEK_SET; |
||||
break; |
||||
case std::ios::cur: |
||||
default: |
||||
whence = SEEK_CUR; |
||||
break; |
||||
case std::ios::end: |
||||
whence = SEEK_END; |
||||
break; |
||||
} |
||||
bool isOK = lseek(hdl_, pos, whence) >= 0; |
||||
#endif |
||||
if (isOK) return; |
||||
throw cybozu::Exception("File:seek") << name_ << cybozu::ErrorNo() << pos << static_cast<int>(dir); |
||||
} |
||||
uint64_t getSize() const |
||||
{ |
||||
uint64_t fileSize; |
||||
#ifdef _WIN32 |
||||
LARGE_INTEGER size; |
||||
bool isOK = GetFileSizeEx(hdl_, &size) != 0; |
||||
fileSize = size.QuadPart; |
||||
#else |
||||
struct stat stat; |
||||
bool isOK = fstat(hdl_, &stat) == 0; |
||||
fileSize = stat.st_size; |
||||
#endif |
||||
if (isOK) return fileSize; |
||||
throw cybozu::Exception("File:getSize") << name_ << cybozu::ErrorNo(); |
||||
} |
||||
}; |
||||
|
||||
/*
|
||||
name has extension |
||||
*/ |
||||
inline bool HasExtension(const std::string& name, const std::string& extension) |
||||
{ |
||||
const size_t extensionSize = extension.size(); |
||||
if (extensionSize == 0) return true; |
||||
const size_t nameSize = name.size(); |
||||
if (nameSize < extensionSize + 1) return false; |
||||
const char *p = &name[nameSize - extensionSize - 1]; |
||||
return *p == '.' && memcmp(p + 1, &extension[0], extensionSize) == 0; |
||||
} |
||||
/*
|
||||
split name as basename.suffix |
||||
*/ |
||||
inline std::string GetBaseName(const std::string& name, std::string *suffix = 0) |
||||
{ |
||||
size_t pos = name.find_last_of('.'); |
||||
if (pos == std::string::npos) { |
||||
if (suffix) suffix->clear(); |
||||
return name; |
||||
} |
||||
if (suffix) { |
||||
*suffix = name.substr(pos + 1); |
||||
} |
||||
return name.substr(0, pos); |
||||
} |
||||
|
||||
/**
|
||||
replace \ with / |
||||
*/ |
||||
inline void ReplaceBackSlash(std::string& str) |
||||
{ |
||||
for (size_t i = 0, n = str.size(); i < n; i++) { |
||||
if (str[i] == '\\') str[i] = '/'; |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
get exe path and baseNamme |
||||
@note file name is the form "xxx.exe" then baseName = xxx |
||||
*/ |
||||
inline std::string GetExePath(std::string *baseName = 0) |
||||
{ |
||||
std::string path; |
||||
path.resize(4096); |
||||
#ifdef _WIN32 |
||||
if (!GetModuleFileNameA(NULL, &path[0], static_cast<int>(path.size()) - 2)) { |
||||
return ""; |
||||
} |
||||
PathRemoveExtensionA(&path[0]); |
||||
if (baseName) { |
||||
*baseName = PathFindFileNameA(&path[0]); |
||||
} |
||||
if (::PathRemoveFileSpecA(&path[0])) { |
||||
::PathAddBackslashA(&path[0]); |
||||
path[0] = static_cast<char>(tolower(path[0])); |
||||
path.resize(strlen(&path[0])); |
||||
ReplaceBackSlash(path); |
||||
} |
||||
#else |
||||
#if defined(__APPLE__) |
||||
uint32_t size = (uint32_t)path.size(); |
||||
if (_NSGetExecutablePath(&path[0], &size) != 0) { |
||||
return ""; |
||||
} |
||||
path.resize(strlen(&path[0])); |
||||
#else |
||||
int ret = readlink("/proc/self/exe", &path[0], path.size() - 2); |
||||
if (ret < 0) return ""; |
||||
path.resize(ret); |
||||
#endif |
||||
size_t pos = path.find_last_of('/'); |
||||
if (pos != std::string::npos) { |
||||
if (baseName) { |
||||
const std::string name = path.substr(pos + 1); |
||||
std::string suffix; |
||||
std::string base = GetBaseName(name, &suffix); |
||||
if (suffix == "exe") { |
||||
*baseName = base; |
||||
} else { |
||||
*baseName = name; |
||||
} |
||||
} |
||||
path.resize(pos + 1); |
||||
} |
||||
#endif |
||||
return path; |
||||
} |
||||
|
||||
/**
|
||||
get file size |
||||
*/ |
||||
inline uint64_t GetFileSize(const std::string& name) |
||||
{ |
||||
#ifdef _WIN32 |
||||
struct __stat64 buf; |
||||
bool isOK = _stat64(name.c_str(), &buf) == 0; |
||||
#else |
||||
struct stat buf; |
||||
bool isOK = stat(name.c_str(), &buf) == 0; |
||||
#endif |
||||
if (isOK) return buf.st_size; |
||||
throw cybozu::Exception("GetFileSize") << name << cybozu::ErrorNo(); |
||||
} |
||||
|
||||
/**
|
||||
verify whether path exists or not |
||||
*/ |
||||
inline bool DoesFileExist(const std::string& path) |
||||
{ |
||||
if (path.empty()) return false; |
||||
std::string p = path; |
||||
char c = p[p.size() - 1]; |
||||
if (c == '/' || c == '\\') { |
||||
p.resize(p.size() - 1); |
||||
} |
||||
#ifdef _WIN32 |
||||
struct _stat buf; |
||||
return _stat(p.c_str(), &buf) == 0; |
||||
#else |
||||
struct stat buf; |
||||
return stat(p.c_str(), &buf) == 0; |
||||
#endif |
||||
} |
||||
|
||||
inline void RenameFile(const std::string& from, const std::string& to) |
||||
{ |
||||
if (DoesFileExist(to)) { |
||||
throw cybozu::Exception("RenameFile:file already exist") << from << to; |
||||
} |
||||
#ifdef _WIN32 |
||||
bool isOK = ::MoveFileExA(from.c_str(), to.c_str(), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH) != 0; |
||||
#else |
||||
bool isOK = ::rename(from.c_str(), to.c_str()) == 0; |
||||
#endif |
||||
if (!isOK) { |
||||
throw cybozu::Exception("RenameFile") << from << to << cybozu::ErrorNo(); |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
remove file |
||||
*/ |
||||
inline void RemoveFile(const std::string& name) |
||||
{ |
||||
#ifdef _WIN32 |
||||
bool isOK = DeleteFileA(name.c_str()) != 0; |
||||
#else |
||||
bool isOK = unlink(name.c_str()) == 0; |
||||
#endif |
||||
if (!isOK) { |
||||
throw cybozu::Exception("RemoveFile") << name << cybozu::ErrorNo(); |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
remark of isFile() |
||||
not directory on Windows |
||||
not contain symbolic link on Linux |
||||
*/ |
||||
struct FileInfo { |
||||
std::string name; |
||||
uint32_t attr; // dwFileAttributes for Windows, d_type for Linux
|
||||
#ifdef _WIN32 |
||||
bool isUnknown() const { return attr == 0; } |
||||
bool isDirectory() const { verify(); return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; } |
||||
bool isFile() const { verify(); return !isDirectory(); } |
||||
#else |
||||
bool isUnknown() const { return attr == DT_UNKNOWN; } |
||||
bool isDirectory() const { verify(); return attr == DT_DIR; } |
||||
bool isFile() const { verify(); return attr == DT_REG; } |
||||
#endif |
||||
FileInfo() : attr(0) {} |
||||
FileInfo(const std::string& name, uint32_t attr) : name(name), attr(attr) {} |
||||
void verify() const |
||||
{ |
||||
if (isUnknown()) throw cybozu::Exception("FileInfo:unknown attr") << name; |
||||
} |
||||
}; |
||||
|
||||
typedef std::vector<FileInfo> FileList; |
||||
|
||||
|
||||
namespace file_local { |
||||
|
||||
inline void filterAndPush(FileList& list, const FileInfo& fi, const std::string& extension, bool cond(const std::string&, const std::string&)) |
||||
{ |
||||
if (fi.name == "." || fi.name == "..") { |
||||
return; |
||||
} |
||||
if (cond(fi.name, extension)) { |
||||
list.push_back(fi); |
||||
} |
||||
} |
||||
|
||||
} // cybozu::file_local
|
||||
|
||||
/**
|
||||
get file name in dir |
||||
@param list [out] FileList |
||||
@param dir [in] directory |
||||
@param extension [in] select files(including directory) having extension such as "cpp" ; select all if suffix is empty |
||||
@param cond [in] filter function (select if cond(targetFile, suffix) is true) |
||||
@note "." and ".." are excluded |
||||
*/ |
||||
inline bool GetFileList(FileList &list, const std::string& dir, const std::string& extension = "", bool (*cond)(const std::string&, const std::string&) = cybozu::HasExtension) |
||||
{ |
||||
#ifdef _WIN32 |
||||
std::string path = dir + "/*"; |
||||
WIN32_FIND_DATAA fd; |
||||
struct Handle { |
||||
Handle(HANDLE hdl) |
||||
: hdl_(hdl) |
||||
{ |
||||
} |
||||
~Handle() |
||||
{ |
||||
if (hdl_ != INVALID_HANDLE_VALUE) { |
||||
FindClose(hdl_); |
||||
} |
||||
} |
||||
HANDLE hdl_; |
||||
}; |
||||
Handle hdl(FindFirstFileA(path.c_str(), &fd)); |
||||
if (hdl.hdl_ == INVALID_HANDLE_VALUE) { |
||||
return false; |
||||
} |
||||
do { |
||||
FileInfo fi(fd.cFileName, fd.dwFileAttributes); |
||||
file_local::filterAndPush(list, fi, extension, cond); |
||||
} while (FindNextFileA(hdl.hdl_, &fd) != 0); |
||||
return true; |
||||
#else |
||||
struct Handle { |
||||
DIR *dir_; |
||||
Handle(DIR *dir) |
||||
: dir_(dir) |
||||
{ |
||||
if (dir_ == 0) { |
||||
perror("opendir"); |
||||
} |
||||
} |
||||
~Handle() |
||||
{ |
||||
if (dir_) { |
||||
if (::closedir(dir_)) { |
||||
perror("closedir"); |
||||
} |
||||
} |
||||
} |
||||
bool isValid() const { return dir_ != 0; } |
||||
}; |
||||
Handle hdl(::opendir(dir.c_str())); |
||||
if (!hdl.isValid()) return false; |
||||
for (;;) { |
||||
struct dirent *dp = ::readdir(hdl.dir_); |
||||
if (dp == 0) return true; |
||||
FileInfo fi(dp->d_name, (uint8_t)dp->d_type); |
||||
file_local::filterAndPush(list, fi, extension, cond); |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
inline FileList GetFileList(const std::string& dir, const std::string& extension = "", bool (*cond)(const std::string&, const std::string&) = cybozu::HasExtension) |
||||
{ |
||||
FileList fl; |
||||
if (GetFileList(fl, dir, extension, cond)) return fl; |
||||
throw cybozu::Exception("cybozu:GetFileList") << dir << cybozu::ErrorNo(); |
||||
} |
||||
|
||||
} // cybozu
|
@ -0,0 +1,785 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief tiny socket class
|
||||
|
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@author MITSUNARI Shigeo |
||||
@remark mingw requires -lws2_32 option |
||||
*/ |
||||
#include <errno.h> |
||||
#include <assert.h> |
||||
#include <stdio.h> |
||||
#ifdef _WIN32 |
||||
#ifndef WIN32_LEAN_AND_MEAN |
||||
#define WIN32_LEAN_AND_MEAN |
||||
#endif |
||||
#include <windows.h> |
||||
#include <winsock2.h> |
||||
#include <ws2tcpip.h> // for socklen_t |
||||
#ifdef _MSC_VER |
||||
#pragma comment(lib, "ws2_32.lib") |
||||
#pragma comment(lib, "iphlpapi.lib") |
||||
#pragma warning(push) |
||||
#pragma warning(disable : 4127) // constant condition
|
||||
#endif |
||||
#else |
||||
#include <unistd.h> |
||||
#include <sys/socket.h> |
||||
#include <sys/ioctl.h> |
||||
#include <netinet/tcp.h> |
||||
#include <arpa/inet.h> |
||||
#include <netdb.h> |
||||
#include <memory.h> |
||||
#include <signal.h> |
||||
#endif |
||||
#ifndef NDEBUG |
||||
#include <stdio.h> |
||||
#endif |
||||
|
||||
#include <cybozu/atomic.hpp> |
||||
#include <cybozu/exception.hpp> |
||||
#include <cybozu/itoa.hpp> |
||||
#include <string> |
||||
|
||||
#ifdef __linux__ |
||||
// #define CYBOZU_SOCKET_USE_EPOLL
|
||||
#include <sys/epoll.h> |
||||
#endif |
||||
|
||||
namespace cybozu { |
||||
|
||||
#ifdef _MSC_VER |
||||
struct NetErrorNo : public cybozu::ErrorNo { |
||||
NetErrorNo(NativeErrorNo err) |
||||
: cybozu::ErrorNo(err) |
||||
{ |
||||
} |
||||
NetErrorNo() |
||||
: cybozu::ErrorNo(WSAGetLastError()) |
||||
{ |
||||
} |
||||
}; |
||||
#else |
||||
typedef cybozu::ErrorNo NetErrorNo; |
||||
#endif |
||||
|
||||
#ifdef CYBOZU_SOCKET_USE_EPOLL |
||||
|
||||
namespace experimental { |
||||
|
||||
struct EpollEvent { |
||||
struct epoll_event ev_; |
||||
EpollEvent() |
||||
{ |
||||
memset(&ev_, 0, sizeof(ev_)); |
||||
} |
||||
void set(int fd, uint32_t events = EPOLLIN) |
||||
{ |
||||
ev_.events = events; |
||||
ev_.data.fd = fd; |
||||
} |
||||
int getFd() const { return ev_.data.fd; } |
||||
}; |
||||
|
||||
class Epoll { |
||||
int efd_; |
||||
bool verify(const char *msg, int ret, int *err) const { |
||||
if (ret >= 0) return true; |
||||
if (err == 0) throw cybozu::Exception(msg) << cybozu::NetErrorNo(); |
||||
*err = errno; |
||||
return false; |
||||
} |
||||
public: |
||||
Epoll() : efd_(-1) {} |
||||
bool init(int *err = 0) |
||||
{ |
||||
efd_ = ::epoll_create1(0); |
||||
return verify("Epoll:init", efd_, err); |
||||
} |
||||
~Epoll() |
||||
{ |
||||
if (efd_ >= 0) ::close(efd_); |
||||
} |
||||
/*
|
||||
throw if err == NULL |
||||
*/ |
||||
bool ctrl(int op, int fd, EpollEvent *ev, int *err = 0) { |
||||
int ret = ::epoll_ctl(efd_, op, fd, &ev->ev_); |
||||
return verify("Epoll:ctrl", ret, err); |
||||
} |
||||
bool add(int fd, uint32_t events = EPOLLIN, int *err = 0) { |
||||
EpollEvent ev; |
||||
ev.set(fd, events); |
||||
return ctrl(EPOLL_CTL_ADD, fd, &ev, err); |
||||
} |
||||
bool del(int fd, int *err = 0) { |
||||
return ctrl(EPOLL_CTL_DEL, fd, NULL, err); |
||||
} |
||||
/*
|
||||
msec : 0 : block |
||||
*/ |
||||
int wait(EpollEvent *ev, int maxEv, int msec = 0) |
||||
{ |
||||
/*
|
||||
0 : return immediately |
||||
-1 : block indefinitely |
||||
*/ |
||||
if (msec == 0) { |
||||
msec = -1; |
||||
} else if (msec == -1) { |
||||
msec = 0; |
||||
} |
||||
int ret = ::epoll_wait(efd_, &ev->ev_, maxEv, msec); |
||||
if (ret == 0) return 0; // timeout
|
||||
if (ret < 0) return -errno; |
||||
return ret; |
||||
} |
||||
}; |
||||
|
||||
struct AutoLock { |
||||
Epoll& ep_; |
||||
int fd_; |
||||
AutoLock(Epoll& ep, int fd, int events = EPOLLIN) |
||||
: ep_(ep) |
||||
, fd_(fd) |
||||
{ |
||||
ep_.add(fd, events); |
||||
} |
||||
~AutoLock() |
||||
{ |
||||
int err; |
||||
ep_.del(fd_, &err); |
||||
} |
||||
}; |
||||
|
||||
} // cybozu::experimental
|
||||
#endif |
||||
|
||||
namespace ssl { |
||||
class ClientSocket; |
||||
}; |
||||
|
||||
namespace socket_local { |
||||
|
||||
#ifdef _WIN32 |
||||
typedef SOCKET SocketHandle; |
||||
#else |
||||
typedef int SocketHandle; |
||||
#endif |
||||
|
||||
struct InitTerm { |
||||
/** call once for init */ |
||||
InitTerm() |
||||
{ |
||||
#ifdef _WIN32 |
||||
WSADATA data; |
||||
int err = ::WSAStartup(MAKEWORD(2, 2), &data); |
||||
if (err) { |
||||
fprintf(stderr, "WSAStartup failed : %d\n", err); |
||||
exit(1); |
||||
} |
||||
#else |
||||
::signal(SIGPIPE, SIG_IGN); |
||||
#endif |
||||
} |
||||
/** call once for term */ |
||||
~InitTerm() |
||||
{ |
||||
#ifdef _WIN32 |
||||
::WSACleanup(); |
||||
#endif |
||||
} |
||||
void dummyCall() { } |
||||
}; |
||||
|
||||
template<int dummy = 0> |
||||
struct InstanceIsHere { static InitTerm it_; }; |
||||
|
||||
template<int dummy> |
||||
InitTerm InstanceIsHere<dummy>::it_; |
||||
|
||||
struct DummyCall { |
||||
DummyCall() { InstanceIsHere<>::it_.dummyCall(); } |
||||
}; |
||||
|
||||
} // cybozu::socket_local
|
||||
|
||||
class SocketAddr { |
||||
union { |
||||
// http://www.coins.tsukuba.ac.jp/~syspro/2010/No6_files/sockaddr.html
|
||||
struct sockaddr sa; /* 16byte */ |
||||
struct sockaddr_in v4; /* 16byte */ |
||||
struct sockaddr_in6 v6; |
||||
} addr_; |
||||
socklen_t addrlen_; |
||||
int family_; |
||||
friend class Socket; |
||||
void verify() // call in only Socket::accept
|
||||
{ |
||||
if (addrlen_ == sizeof(addr_.v4) && addr_.sa.sa_family == AF_INET) { |
||||
family_ = AF_INET; |
||||
return; |
||||
} |
||||
if (addrlen_ == sizeof(addr_.v6) && addr_.sa.sa_family == AF_INET6) { |
||||
family_ = AF_INET6; |
||||
return; |
||||
} |
||||
throw cybozu::Exception("cybozu:SocketAddr:verify") << addrlen_; |
||||
} |
||||
public: |
||||
SocketAddr() |
||||
: addrlen_(0) |
||||
, family_(0) |
||||
{ |
||||
} |
||||
SocketAddr(const std::string& address, uint16_t port, bool forceIpV6 = false) |
||||
{ |
||||
set(address, port, forceIpV6); |
||||
} |
||||
void set(const std::string& address, uint16_t port, bool forceIpV6 = false) |
||||
{ |
||||
char portStr[16]; |
||||
CYBOZU_SNPRINTF(portStr, sizeof(portStr), "%d", port); |
||||
memset(&addr_, 0, sizeof(addr_)); |
||||
addrlen_ = 0; |
||||
family_ = 0; |
||||
|
||||
struct addrinfo *result = 0; |
||||
struct addrinfo hints; |
||||
memset(&hints, 0, sizeof(struct addrinfo)); |
||||
hints.ai_family = AF_INET; |
||||
hints.ai_socktype = SOCK_STREAM; |
||||
hints.ai_protocol = IPPROTO_TCP; |
||||
hints.ai_flags = AI_NUMERICSERV; // AI_PASSIVE;
|
||||
const int s = getaddrinfo(address.c_str(), portStr, &hints, &result); |
||||
// s == EAI_AGAIN
|
||||
if (s || forceIpV6) { |
||||
hints.ai_family = AF_INET6; |
||||
hints.ai_flags |= AI_V4MAPPED; |
||||
if (getaddrinfo(address.c_str(), portStr, &hints, &result)) { |
||||
goto ERR_EXIT; |
||||
} |
||||
} |
||||
{ |
||||
bool found = false; |
||||
for (const struct addrinfo *p = result; p; p = p->ai_next) { |
||||
const int family = p->ai_family; |
||||
if (family == hints.ai_family) { |
||||
if (p->ai_addrlen > sizeof(addr_)) { |
||||
break; |
||||
} |
||||
memcpy(&addr_, p->ai_addr, p->ai_addrlen); |
||||
addrlen_ = (socklen_t)p->ai_addrlen; |
||||
family_ = family; |
||||
found = true; |
||||
break; |
||||
} |
||||
} |
||||
freeaddrinfo(result); |
||||
if (found) return; |
||||
} |
||||
ERR_EXIT: |
||||
throw cybozu::Exception("SocketAddr:set") << address << port << cybozu::NetErrorNo(); |
||||
} |
||||
socklen_t getSize() const { return addrlen_; } |
||||
int getFamily() const { return family_; } |
||||
const struct sockaddr *get() const { return &addr_.sa; } |
||||
uint16_t getPort() const { |
||||
if (family_ == AF_INET) { |
||||
return ntohs(addr_.v4.sin_port); |
||||
} else if (family_ == AF_INET6) { |
||||
return ntohs(addr_.v6.sin6_port); |
||||
} |
||||
throw cybozu::Exception("SocketAddr:getPort:bad family") << family_; |
||||
} |
||||
// compare addr without port
|
||||
bool hasSameAddr(const SocketAddr& rhs) const |
||||
{ |
||||
const uint8_t *v4 = 0; |
||||
const uint8_t *v6 = 0; |
||||
if (family_ == AF_INET) { |
||||
if (rhs.family_ == AF_INET) return memcmp(&addr_.v4.sin_addr, &rhs.addr_.v4.sin_addr, sizeof(in_addr)) == 0; |
||||
if (rhs.family_ != AF_INET6) return false; |
||||
v4 = (const uint8_t*)&addr_.v4.sin_addr; |
||||
v6 = (const uint8_t*)&rhs.addr_.v6.sin6_addr; |
||||
} else if (family_ != AF_INET6) { |
||||
return false; |
||||
} else { |
||||
if (rhs.family_ == AF_INET6) return memcmp(&addr_.v6.sin6_addr, &rhs.addr_.v6.sin6_addr, sizeof(in6_addr)) == 0; |
||||
if (rhs.family_ != AF_INET) return false; |
||||
v4 = (const uint8_t*)&rhs.addr_.v4.sin_addr; |
||||
v6 = (const uint8_t*)&addr_.v6.sin6_addr; |
||||
} |
||||
// Ipv6-mapped?
|
||||
const uint8_t header[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; |
||||
return memcmp(v6, header, 12) == 0 && memcmp(v6 + 12, v4, 4) == 0; |
||||
} |
||||
std::string toStr() const |
||||
{ |
||||
if (family_ == AF_INET || family_ == AF_INET6) { |
||||
char buf[INET6_ADDRSTRLEN]; |
||||
assert(INET_ADDRSTRLEN <= INET6_ADDRSTRLEN); |
||||
const bool isIPv4 = family_ == AF_INET; |
||||
const void *pa = isIPv4 ? (const void*)&addr_.v4.sin_addr : (const void*)&addr_.v6.sin6_addr; |
||||
// not "const void*" because of vc
|
||||
const char *p = inet_ntop(family_, const_cast<void*>(pa), buf, sizeof(buf)); |
||||
if (!p) throw cybozu::Exception("cybozu:SocketAddr:toStr") << cybozu::NetErrorNo(); |
||||
if (isIPv4) return std::string(p) + ':' + cybozu::itoa(getPort()); |
||||
return std::string("[") + p + "]:" + cybozu::itoa(getPort()); |
||||
} |
||||
throw cybozu::Exception("cybozu:SocketAddr:toStr:bad family_") << family_; |
||||
} |
||||
}; |
||||
/*
|
||||
socket class
|
||||
@note ower is moved if copied |
||||
*/ |
||||
class Socket { |
||||
friend class cybozu::ssl::ClientSocket; |
||||
private: |
||||
cybozu::socket_local::SocketHandle sd_; |
||||
Socket(const Socket&); |
||||
void operator=(const Socket&); |
||||
#ifdef WIN32 |
||||
void setTimeout(int type, int msec) |
||||
{ |
||||
setSocketOption(type, msec); |
||||
} |
||||
/* return msec */ |
||||
int getTimeout(int type) const |
||||
{ |
||||
return getSocketOption(type); |
||||
} |
||||
#else |
||||
void setTimeout(int type, int msec) |
||||
{ |
||||
struct timeval t; |
||||
t.tv_sec = msec / 1000; |
||||
t.tv_usec = (msec % 1000) * 1000; |
||||
setSocketOption(type, t); |
||||
} |
||||
/* return msec */ |
||||
int getTimeout(int type) const |
||||
{ |
||||
struct timeval t; |
||||
getSocketOption(type, &t); |
||||
return t.tv_sec * 1000 + t.tv_usec / 1000; /* msec */ |
||||
} |
||||
#endif |
||||
void setBlocking(bool isBlocking) |
||||
{ |
||||
#ifdef _WIN32 |
||||
u_long val = isBlocking ? 0 : 1; |
||||
int ret = ::ioctlsocket(sd_, FIONBIO, &val); |
||||
#else |
||||
int val = isBlocking ? 0 : 1; |
||||
int ret = ::ioctl(sd_, FIONBIO, &val); |
||||
#endif |
||||
if (ret < 0) throw cybozu::Exception("Socket:setBlocking") << cybozu::NetErrorNo() << isBlocking; |
||||
} |
||||
public: |
||||
#ifndef _WIN32 |
||||
static const int INVALID_SOCKET = -1; |
||||
#endif |
||||
Socket() |
||||
: sd_(INVALID_SOCKET) |
||||
{ |
||||
} |
||||
|
||||
bool isValid() const { return sd_ != INVALID_SOCKET; } |
||||
|
||||
// move
|
||||
#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 |
||||
Socket(Socket&& rhs) |
||||
: sd_(INVALID_SOCKET) |
||||
{ |
||||
sd_ = cybozu::AtomicExchange(&rhs.sd_, sd_); |
||||
} |
||||
#endif |
||||
// close and move
|
||||
void moveFrom(Socket& rhs) |
||||
{ |
||||
close(); |
||||
sd_ = cybozu::AtomicExchange(&rhs.sd_, INVALID_SOCKET); |
||||
} |
||||
#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 |
||||
void operator=(Socket&& rhs) |
||||
#else |
||||
void operator=(Socket& rhs) |
||||
#endif |
||||
{ |
||||
moveFrom(rhs); |
||||
} |
||||
|
||||
~Socket() |
||||
{ |
||||
close(cybozu::DontThrow); |
||||
} |
||||
|
||||
bool close(bool dontThrow = false) |
||||
{ |
||||
cybozu::socket_local::SocketHandle sd = cybozu::AtomicExchange(&sd_, INVALID_SOCKET); |
||||
if (sd == INVALID_SOCKET) return true; |
||||
#ifdef _WIN32 |
||||
// ::shutdown(sd, SD_SEND);
|
||||
// shutdown is called in closesocket
|
||||
bool isOK = ::closesocket(sd) == 0; |
||||
#else |
||||
bool isOK = ::close(sd) == 0; |
||||
#endif |
||||
if (!dontThrow && !isOK) throw cybozu::Exception("Socket:close") << cybozu::NetErrorNo(); |
||||
return isOK; |
||||
} |
||||
/*
|
||||
how 0 : SHUTRD ; disallow read |
||||
1 : SHUT_WR ; disallow write |
||||
2 : SHUT_RDWR ; disallow read/write |
||||
*/ |
||||
bool shutdown(int how, bool dontThrow = false) |
||||
{ |
||||
bool isOK = ::shutdown(sd_, how) == 0; |
||||
if (!dontThrow && !isOK) throw cybozu::Exception("Socket:waitForClose:shutdown") << cybozu::NetErrorNo(); |
||||
return isOK; |
||||
} |
||||
/*
|
||||
send FIN and wait for remote's close(). |
||||
this function is used for the following situation. |
||||
sock.write() |
||||
sock.waitForClose() |
||||
sock.close() |
||||
*/ |
||||
void waitForClose() |
||||
{ |
||||
if (sd_ == INVALID_SOCKET) return; |
||||
// send FIN and this socket can't write any data.
|
||||
shutdown(1); |
||||
// wait for FIN from the peer.
|
||||
char buf[1]; |
||||
ssize_t readSize = readSome(buf, sizeof(buf)); |
||||
if (readSize != 0) { |
||||
throw cybozu::Exception("Socket:waitForClose:readSome:bad size") << readSize; |
||||
} |
||||
} |
||||
|
||||
/*!
|
||||
receive data |
||||
@param buf [out] receive buffer |
||||
@param bufSize [in] receive buffer size(byte) |
||||
@note return read size |
||||
*/ |
||||
size_t readSome(void *buf, size_t bufSize) |
||||
{ |
||||
int size = (int)(std::min)((size_t)0x7fffffff, bufSize); |
||||
#ifdef _WIN32 |
||||
int readSize = ::recv(sd_, (char *)buf, size, 0); |
||||
#else |
||||
RETRY: |
||||
ssize_t readSize = ::read(sd_, buf, size); |
||||
if (readSize < 0 && errno == EINTR) goto RETRY; |
||||
#endif |
||||
if (readSize < 0) throw cybozu::Exception("Socket:readSome") << cybozu::NetErrorNo() << bufSize; |
||||
return readSize; |
||||
} |
||||
|
||||
/*!
|
||||
receive all data unless timeout |
||||
@param buf [out] receive buffer |
||||
@param bufSize [in] receive buffer size(byte) |
||||
*/ |
||||
void read(void *buf, size_t bufSize) |
||||
{ |
||||
char *p = (char *)buf; |
||||
while (bufSize > 0) { |
||||
size_t readSize = readSome(p, bufSize); |
||||
if (readSize == 0) throw cybozu::Exception("Socket:read:readSize is zero"); |
||||
p += readSize; |
||||
bufSize -= readSize; |
||||
} |
||||
} |
||||
/*!
|
||||
write all data |
||||
@param buf [out] send buffer |
||||
@param bufSize [in] send buffer size(byte) |
||||
*/ |
||||
void write(bool *pb, const void *buf, size_t bufSize) |
||||
{ |
||||
const char *p = (const char *)buf; |
||||
while (bufSize > 0) { |
||||
int size = (int)(std::min)(size_t(0x7fffffff), bufSize); |
||||
#ifdef _WIN32 |
||||
int writeSize = ::send(sd_, p, size, 0); |
||||
#else |
||||
int writeSize = ::write(sd_, p, size); |
||||
if (writeSize < 0 && errno == EINTR) continue; |
||||
#endif |
||||
if (writeSize < 0) { |
||||
*pb = false; |
||||
return; |
||||
} |
||||
p += writeSize; |
||||
bufSize -= writeSize; |
||||
} |
||||
*pb = true; |
||||
} |
||||
void write(const void *buf, size_t bufSize) |
||||
{ |
||||
bool b; |
||||
write(&b, buf, bufSize); |
||||
if (!b) throw cybozu::Exception("Socket:write") << cybozu::NetErrorNo() << bufSize; |
||||
} |
||||
/**
|
||||
connect to address:port |
||||
@param address [in] address |
||||
@param port [in] port |
||||
@param msec: 0 : block |
||||
*/ |
||||
void connect(const std::string& address, uint16_t port, int msec = 0) |
||||
{ |
||||
SocketAddr addr; |
||||
addr.set(address, port); |
||||
connect(addr, msec); |
||||
} |
||||
/**
|
||||
connect to resolved socket addr |
||||
*/ |
||||
void connect(const cybozu::SocketAddr& addr, int msec = 0) |
||||
{ |
||||
if (isValid()) throw cybozu::Exception("Socket:connect:already connect"); |
||||
sd_ = ::socket(addr.getFamily(), SOCK_STREAM, IPPROTO_TCP); |
||||
if (!isValid()) { |
||||
throw cybozu::Exception("Socket:connect:socket") << cybozu::NetErrorNo(); |
||||
} |
||||
if (msec == 0) { |
||||
if (::connect(sd_, addr.get(), addr.getSize()) < 0) { |
||||
throw cybozu::Exception("Socket:connect") << cybozu::NetErrorNo() << addr.toStr(); |
||||
} |
||||
} else { |
||||
setBlocking(false); |
||||
if (::connect(sd_, addr.get(), addr.getSize()) < 0) { |
||||
#ifdef _WIN32 |
||||
bool inProgress = WSAGetLastError() == WSAEWOULDBLOCK; |
||||
#else |
||||
bool inProgress = errno == EINPROGRESS; |
||||
#endif |
||||
if (!inProgress) throw cybozu::Exception("Socket:connect:not in progress") << cybozu::NetErrorNo() << addr.toStr(); |
||||
if (!queryAccept(msec, false)) throw cybozu::Exception("Socket:connect:timeout") << addr.toStr(); |
||||
int err = getSocketOption(SO_ERROR); |
||||
if (err != 0) throw cybozu::Exception("Socket::connect:bad socket") << cybozu::NetErrorNo(err); |
||||
} |
||||
setBlocking(true); |
||||
} |
||||
} |
||||
|
||||
static const int allowIPv4 = 1; |
||||
static const int allowIPv6 = 2; |
||||
/**
|
||||
init for server |
||||
@param port [in] port number |
||||
*/ |
||||
void bind(uint16_t port, int mode = allowIPv4 | allowIPv6) |
||||
{ |
||||
const int family = (mode & allowIPv6) ? AF_INET6 : AF_INET; |
||||
sd_ = ::socket(family, SOCK_STREAM, IPPROTO_TCP); |
||||
if (!isValid()) { |
||||
throw cybozu::Exception("Socket:bind:socket") << cybozu::NetErrorNo(); |
||||
} |
||||
setSocketOption(SO_REUSEADDR, 1); |
||||
struct sockaddr_in6 addr6; |
||||
struct sockaddr_in addr4; |
||||
struct sockaddr *addr; |
||||
socklen_t addrLen; |
||||
if (mode & allowIPv6) { |
||||
setSocketOption(IPV6_V6ONLY, (mode & allowIPv4) ? 0 : 1, IPPROTO_IPV6); |
||||
memset(&addr6, 0, sizeof(addr6)); |
||||
addr6.sin6_family = AF_INET6; |
||||
addr6.sin6_port = htons(port); |
||||
addr = (struct sockaddr*)&addr6; |
||||
addrLen = sizeof(addr6); |
||||
} else { |
||||
memset(&addr4, 0, sizeof(addr4)); |
||||
addr4.sin_family = AF_INET; |
||||
addr4.sin_port = htons(port); |
||||
addr = (struct sockaddr*)&addr4; |
||||
addrLen = sizeof(addr4); |
||||
} |
||||
if (::bind(sd_, addr, addrLen) == 0) { |
||||
if (::listen(sd_, SOMAXCONN) == 0) { |
||||
return; |
||||
} |
||||
} |
||||
cybozu::NetErrorNo keep; |
||||
close(cybozu::DontThrow); |
||||
throw cybozu::Exception("Socket:bind") << keep; |
||||
} |
||||
|
||||
/**
|
||||
return positive if accepted |
||||
return zero if timeout |
||||
return negative(-errno) if error |
||||
*/ |
||||
int queryAcceptNoThrow(int msec = 1000, bool checkWrite = true) |
||||
{ |
||||
if (sd_ == INVALID_SOCKET) return -EBADF; |
||||
#ifdef CYBOZU_SOCKET_USE_EPOLL |
||||
int err; |
||||
experimental::Epoll ep; |
||||
if (!ep.init(&err)) return -err; |
||||
uint32_t events = checkWrite ? EPOLLIN : EPOLLOUT; |
||||
experimental::AutoLock al(ep, sd_, events); |
||||
experimental::EpollEvent ev; |
||||
int ret = ep.wait(&ev, 1, msec); |
||||
if (ret != 1) return ret; |
||||
assert(ev.getFd() == sd_); |
||||
return ret; |
||||
#else |
||||
#ifndef _WIN32 |
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms739169.aspx
|
||||
if (sd_ >= FD_SETSIZE) return -EMFILE; |
||||
#endif |
||||
struct timeval timeout; |
||||
timeout.tv_sec = msec / 1000; |
||||
timeout.tv_usec = (msec % 1000) * 1000; |
||||
fd_set fds; |
||||
FD_ZERO(&fds); |
||||
FD_SET((unsigned)sd_, &fds); |
||||
int fdNum; |
||||
if (checkWrite) { |
||||
fdNum = ::select((int)sd_ + 1, &fds, 0, 0, &timeout); |
||||
} else { |
||||
fdNum = ::select((int)sd_ + 1, 0, &fds, 0, &timeout); |
||||
} |
||||
if (fdNum < 0) return -errno; |
||||
return fdNum; |
||||
#endif |
||||
} |
||||
/**
|
||||
return true if acceptable, otherwise false |
||||
return false if one second passed |
||||
while (!server.queryAccept()) { |
||||
} |
||||
client.accept(server); |
||||
*/ |
||||
bool queryAccept(int msec = 1000, bool checkWrite = true) |
||||
{ |
||||
int ret = queryAcceptNoThrow(msec, checkWrite); |
||||
if (ret < 0) throw cybozu::Exception("Socket:queryAccept") << cybozu::NetErrorNo(-ret); |
||||
return ret > 0; |
||||
} |
||||
|
||||
/**
|
||||
accept for server |
||||
*/ |
||||
void accept(Socket& client, SocketAddr *paddr = 0) const |
||||
{ |
||||
if (paddr) { |
||||
struct sockaddr *psa = &paddr->addr_.sa; |
||||
paddr->addrlen_ = sizeof(paddr->addr_); |
||||
client.sd_ = ::accept(sd_, psa, &paddr->addrlen_); |
||||
paddr->verify(); |
||||
} else { |
||||
client.sd_ = ::accept(sd_, 0, 0); |
||||
} |
||||
if (!client.isValid()) throw cybozu::Exception("Socket:accept") << cybozu::NetErrorNo(); |
||||
} |
||||
|
||||
template<typename T> |
||||
void setSocketOption(int optname, const T& value, int level = SOL_SOCKET) |
||||
{ |
||||
bool isOK = setsockopt(sd_, level, optname, cybozu::cast<const char*>(&value), sizeof(T)) == 0; |
||||
if (!isOK) throw cybozu::Exception("Socket:setSocketOption") << cybozu::NetErrorNo(); |
||||
} |
||||
template<typename T> |
||||
void getSocketOption(int optname, T* value, int level = SOL_SOCKET) const |
||||
{ |
||||
socklen_t len = (socklen_t)sizeof(T); |
||||
bool isOK = getsockopt(sd_, level, optname, cybozu::cast<char*>(value), &len) == 0; |
||||
if (!isOK) throw cybozu::Exception("Socket:getSocketOption") << cybozu::NetErrorNo(); |
||||
} |
||||
int getSocketOption(int optname) const |
||||
{ |
||||
int ret; |
||||
getSocketOption(optname, &ret); |
||||
return ret; |
||||
} |
||||
/**
|
||||
setup linger |
||||
*/ |
||||
void setLinger(uint16_t l_onoff, uint16_t l_linger) |
||||
{ |
||||
struct linger linger; |
||||
linger.l_onoff = l_onoff; |
||||
linger.l_linger = l_linger; |
||||
setSocketOption(SO_LINGER, &linger); |
||||
} |
||||
/**
|
||||
get receive buffer size |
||||
@retval positive buffer size(byte) |
||||
@retval -1 error |
||||
*/ |
||||
int getReceiveBufferSize() const |
||||
{ |
||||
return getSocketOption(SO_RCVBUF); |
||||
} |
||||
/**
|
||||
set receive buffer size |
||||
@param size [in] buffer size(byte) |
||||
*/ |
||||
void setReceiveBufferSize(int size) |
||||
{ |
||||
setSocketOption(SO_RCVBUF, size); |
||||
} |
||||
/**
|
||||
get send buffer size |
||||
@retval positive buffer size(byte) |
||||
@retval -1 error |
||||
*/ |
||||
int getSendBufferSize() const |
||||
{ |
||||
return getSocketOption(SO_SNDBUF); |
||||
} |
||||
/**
|
||||
sed send buffer size |
||||
@param size [in] buffer size(byte) |
||||
*/ |
||||
void setSendBufferSize(int size) |
||||
{ |
||||
setSocketOption(SO_SNDBUF, size); |
||||
} |
||||
/**
|
||||
set send timeout |
||||
@param msec [in] msec |
||||
*/ |
||||
void setSendTimeout(int msec) |
||||
{ |
||||
setTimeout(SO_SNDTIMEO, msec); |
||||
} |
||||
/**
|
||||
set receive timeout |
||||
@param msec [in] msec |
||||
*/ |
||||
void setReceiveTimeout(int msec) |
||||
{ |
||||
setTimeout(SO_RCVTIMEO, msec); |
||||
} |
||||
/**
|
||||
get send timeout(msec) |
||||
*/ |
||||
int getSendTimeout() const |
||||
{ |
||||
return getTimeout(SO_SNDTIMEO); |
||||
} |
||||
/**
|
||||
get receive timeout(msec) |
||||
*/ |
||||
int getReceiveTimeout() const |
||||
{ |
||||
return getTimeout(SO_RCVTIMEO); |
||||
} |
||||
}; |
||||
|
||||
} // cybozu
|
||||
|
||||
#ifdef _MSC_VER |
||||
#pragma warning(pop) |
||||
#endif |
@ -0,0 +1,281 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief tiny time class
|
||||
|
||||
@author MITSUNARI Shigeo(@herumi) |
||||
*/ |
||||
#include <ctime> |
||||
#include <cybozu/exception.hpp> |
||||
#include <cybozu/atoi.hpp> |
||||
#include <cybozu/itoa.hpp> |
||||
#ifdef _WIN32 |
||||
#include <sys/timeb.h> |
||||
#else |
||||
#include <sys/time.h> |
||||
#endif |
||||
|
||||
namespace cybozu { |
||||
|
||||
/**
|
||||
time struct with time_t and msec |
||||
@note time MUST be latesr than 1970/1/1 |
||||
*/ |
||||
class Time { |
||||
static const uint64_t epochBias = 116444736000000000ull; |
||||
std::time_t time_; |
||||
int msec_; |
||||
public: |
||||
explicit Time(std::time_t time = 0, int msec = 0) |
||||
: time_(time) |
||||
, msec_(msec) |
||||
{ |
||||
} |
||||
explicit Time(bool doSet) |
||||
{ |
||||
if (doSet) setCurrentTime(); |
||||
} |
||||
Time& setTime(std::time_t time, int msec = 0) |
||||
{ |
||||
time_ = time; |
||||
msec_ = msec; |
||||
return *this; |
||||
} |
||||
/*
|
||||
Windows FILETIME is defined as |
||||
struct FILETILME { |
||||
DWORD dwLowDateTime; |
||||
DWORD dwHighDateTime; |
||||
}; |
||||
the value represents the number of 100-nanosecond intervals since January 1, 1601 (UTC). |
||||
*/ |
||||
void setByFILETIME(uint32_t low, uint32_t high) |
||||
{ |
||||
const uint64_t fileTime = (((uint64_t(high) << 32) | low) - epochBias) / 10000; |
||||
time_ = fileTime / 1000; |
||||
msec_ = fileTime % 1000; |
||||
} |
||||
/*
|
||||
DWORD is defined as unsigned long in windows |
||||
*/ |
||||
template<class dword> |
||||
void getFILETIME(dword& low, dword& high) const |
||||
{ |
||||
const uint64_t fileTime = (time_ * 1000 + msec_) * 10000 + epochBias; |
||||
low = dword(fileTime); |
||||
high = dword(fileTime >> 32); |
||||
} |
||||
explicit Time(const std::string& in) |
||||
{ |
||||
fromString(in); |
||||
} |
||||
explicit Time(const char *in) |
||||
{ |
||||
fromString(in, in + strlen(in)); |
||||
} |
||||
const std::time_t& getTime() const { return time_; } |
||||
int getMsec() const { return msec_; } |
||||
double getTimeSec() const { return time_ + msec_ * 1e-3; } |
||||
void addSec(int sec) { time_ += sec; } |
||||
bool operator<(const Time& rhs) const { return (time_ < rhs.time_) || (time_ == rhs.time_ && msec_ < rhs.msec_); } |
||||
// bool operator<=(const Time& rhs) const { return (*this < rhs) || (*this == rhs); }
|
||||
// bool operator>(const Time& rhs) const { return rhs < *this; }
|
||||
bool operator==(const Time& rhs) const { return (time_ == rhs.time_) && (msec_ == rhs.msec_); } |
||||
bool operator!=(const Time& rhs) const { return !(*this == rhs); } |
||||
/**
|
||||
set time from string such as |
||||
2009-Jan-23T02:53:44Z |
||||
2009-Jan-23T02:53:44.078Z |
||||
2009-01-23T02:53:44Z |
||||
2009-01-23T02:53:44.078Z |
||||
@note 'T' may be ' '. '-' may be '/'. last char 'Z' is omissible |
||||
*/ |
||||
void fromString(bool *pb, const std::string& in) { fromString(pb, &in[0], &in[0] + in.size()); } |
||||
void fromString(const std::string& in) { fromString(0, in); } |
||||
|
||||
void fromString(bool *pb, const char *begin, const char *end) |
||||
{ |
||||
const size_t len = end - begin; |
||||
if (len >= 19) { |
||||
const char *p = begin; |
||||
struct tm tm; |
||||
int num; |
||||
bool b; |
||||
tm.tm_year = getNum(&b, p, 4, 1970, 3000) - 1900; |
||||
if (!b) goto ERR; |
||||
p += 4; |
||||
char sep = *p++; |
||||
if (sep != '-' && sep != '/') goto ERR; |
||||
|
||||
p = getMonth(&num, p); |
||||
if (p == 0) goto ERR; |
||||
tm.tm_mon = num; |
||||
if (*p++ != sep) goto ERR; |
||||
|
||||
tm.tm_mday = getNum(&b, p, 2, 1, 31); |
||||
if (!b) goto ERR; |
||||
p += 2; |
||||
if (*p != ' ' && *p != 'T') goto ERR; |
||||
p++; |
||||
|
||||
tm.tm_hour = getNum(&b, p, 2, 0, 23); |
||||
if (!b) goto ERR; |
||||
p += 2; |
||||
if (*p++ != ':') goto ERR; |
||||
|
||||
tm.tm_min = getNum(&b, p, 2, 0, 59); |
||||
if (!b) goto ERR; |
||||
p += 2; |
||||
if (*p++ != ':') goto ERR; |
||||
|
||||
tm.tm_sec = getNum(&b, p, 2, 0, 59); |
||||
if (!b) goto ERR; |
||||
p += 2; |
||||
|
||||
if (p == end) { |
||||
msec_ = 0; |
||||
} else if (p + 1 == end && *p == 'Z') { |
||||
msec_ = 0; |
||||
p++; |
||||
} else if (*p == '.' && (p + 4 == end || (p + 5 == end && *(p + 4) == 'Z'))) { |
||||
msec_ = getNum(&b, p + 1, 3, 0, 999); |
||||
if (!b) goto ERR; |
||||
// p += 4;
|
||||
} else { |
||||
goto ERR; |
||||
} |
||||
#ifdef _WIN32 |
||||
time_ = _mkgmtime64(&tm); |
||||
if (time_ == -1) goto ERR; |
||||
#else |
||||
time_ = timegm(&tm); |
||||
#endif |
||||
if (pb) { |
||||
*pb = true; |
||||
} |
||||
return; |
||||
} |
||||
ERR: |
||||
if (pb) { |
||||
*pb = false; |
||||
return; |
||||
} |
||||
throw cybozu::Exception("time::fromString") << std::string(begin, 24); |
||||
} |
||||
void fromString(const char *begin, const char *end) { fromString(0, begin, end); } |
||||
|
||||
/**
|
||||
get current time with format |
||||
@param out [out] output string |
||||
@param format [in] foramt for strftime and append three digits for msec |
||||
@param appendMsec [in] appemd <mmm> |
||||
@param doClear (append to out if false) |
||||
@note ex. "%Y-%b-%d %H:%M:%S." to get 2009-Jan-23 02:53:44.078 |
||||
*/ |
||||
void toString(std::string& out, const char *format, bool appendMsec = true, bool doClear = true) const |
||||
{ |
||||
if (doClear) out.clear(); |
||||
char buf[128]; |
||||
struct tm tm; |
||||
#ifdef _WIN32 |
||||
bool isOK = _gmtime64_s(&tm, &time_) == 0; |
||||
#else |
||||
bool isOK = gmtime_r(&time_, &tm) != 0; |
||||
#endif |
||||
if (!isOK) throw cybozu::Exception("time::toString") << time_; |
||||
#ifdef __GNUC__ |
||||
#pragma GCC diagnostic push |
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" |
||||
#endif |
||||
if (std::strftime(buf, sizeof(buf), format, &tm) == 0) { |
||||
throw cybozu::Exception("time::toString::too long") << format << time_; |
||||
} |
||||
#ifdef __GNUC__ |
||||
#pragma GCC diagnostic pop |
||||
#endif |
||||
out += buf; |
||||
if (appendMsec) { |
||||
out += cybozu::itoaWithZero(msec_, 3); |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
get current time such as 2009-01-23 02:53:44.078 |
||||
@param out [out] sink string |
||||
*/ |
||||
void toString(std::string& out, bool appendMsec = true, bool doClear = true) const |
||||
{ |
||||
const char *format = appendMsec ? "%Y-%m-%d %H:%M:%S." : "%Y-%m-%d %H:%M:%S"; |
||||
toString(out, format, appendMsec, doClear); |
||||
} |
||||
std::string toString(bool appendMsec = true) const { std::string out; toString(out, appendMsec); return out; } |
||||
/**
|
||||
get current time |
||||
*/ |
||||
Time& setCurrentTime() |
||||
{ |
||||
#ifdef _WIN32 |
||||
struct _timeb timeb; |
||||
_ftime_s(&timeb); |
||||
time_ = timeb.time; |
||||
msec_ = timeb.millitm; |
||||
#else |
||||
struct timeval tv; |
||||
gettimeofday(&tv, 0); |
||||
time_ = tv.tv_sec; |
||||
msec_ = tv.tv_usec / 1000; |
||||
#endif |
||||
return *this; |
||||
} |
||||
private: |
||||
|
||||
int getNum(bool *b, const char *in, size_t len, int min, int max) const |
||||
{ |
||||
int ret = cybozu::atoi(b, in, len); |
||||
if (min <= ret && ret <= max) { |
||||
return ret; |
||||
} else { |
||||
*b = false; |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
convert month-str to [0, 11] |
||||
@param ret [out] return idx |
||||
@param p [in] month-str |
||||
@retval next pointer or null |
||||
*/ |
||||
const char *getMonth(int *ret, const char *p) const |
||||
{ |
||||
static const char monthTbl[12][4] = { |
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" |
||||
}; |
||||
|
||||
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(monthTbl); i++) { |
||||
if (memcmp(p, monthTbl[i], 3) == 0) { |
||||
*ret = (int)i; |
||||
return p + 3; |
||||
} |
||||
} |
||||
bool b; |
||||
*ret = getNum(&b, p, 2, 1, 12) - 1; |
||||
if (b) { |
||||
return p + 2; |
||||
} else { |
||||
return 0; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const cybozu::Time& time) |
||||
{ |
||||
return os << time.toString(); |
||||
} |
||||
|
||||
inline double GetCurrentTimeSec() |
||||
{ |
||||
return cybozu::Time(true).getTimeSec(); |
||||
} |
||||
|
||||
} // cybozu
|
@ -1,76 +0,0 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief 192/256-bit additive homomorphic encryption by lifted-ElGamal |
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@license modified new BSD license |
||||
http://opensource.org/licenses/BSD-3-Clause
|
||||
*/ |
||||
#include <mcl/elgamal.hpp> |
||||
#include <mcl/ecparam.hpp> |
||||
|
||||
namespace mcl { |
||||
|
||||
#ifdef MCL_USE_AHE192 |
||||
namespace ahe192 { |
||||
|
||||
const mcl::EcParam& para = mcl::ecparam::NIST_P192; |
||||
|
||||
typedef mcl::FpT<mcl::FpTag, 192> Fp; |
||||
typedef mcl::FpT<mcl::ZnTag, 192> Zn; |
||||
typedef mcl::EcT<Fp> Ec; |
||||
typedef mcl::ElgamalT<Ec, Zn> ElgamalEc; |
||||
typedef ElgamalEc::PrivateKey SecretKey; |
||||
typedef ElgamalEc::PublicKey PublicKey; |
||||
typedef ElgamalEc::CipherText CipherText; |
||||
|
||||
static inline void initAhe() |
||||
{ |
||||
Fp::init(para.p); |
||||
Zn::init(para.n); |
||||
Ec::init(para.a, para.b); |
||||
Ec::setIoMode(16); |
||||
Zn::setIoMode(16); |
||||
} |
||||
|
||||
static inline void initSecretKey(SecretKey& sec) |
||||
{ |
||||
const Ec P(Fp(para.gx), Fp(para.gy)); |
||||
sec.init(P, Zn::getBitSize()); |
||||
} |
||||
|
||||
} //mcl::ahe192
|
||||
#endif |
||||
|
||||
#ifdef MCL_USE_AHE256 |
||||
namespace ahe256 { |
||||
|
||||
const mcl::EcParam& para = mcl::ecparam::NIST_P256; |
||||
|
||||
typedef mcl::FpT<mcl::FpTag, 256> Fp; |
||||
typedef mcl::FpT<mcl::ZnTag, 256> Zn; |
||||
typedef mcl::EcT<Fp> Ec; |
||||
typedef mcl::ElgamalT<Ec, Zn> ElgamalEc; |
||||
typedef ElgamalEc::PrivateKey SecretKey; |
||||
typedef ElgamalEc::PublicKey PublicKey; |
||||
typedef ElgamalEc::CipherText CipherText; |
||||
|
||||
static inline void initAhe() |
||||
{ |
||||
Fp::init(para.p); |
||||
Zn::init(para.n); |
||||
Ec::init(para.a, para.b); |
||||
Ec::setIoMode(16); |
||||
Zn::setIoMode(16); |
||||
} |
||||
|
||||
static inline void initSecretKey(SecretKey& sec) |
||||
{ |
||||
const Ec P(Fp(para.gx), Fp(para.gy)); |
||||
sec.init(P, Zn::getBitSize()); |
||||
} |
||||
|
||||
} //mcl::ahe256
|
||||
#endif |
||||
|
||||
} // mcl
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief constant macro |
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@license modified new BSD license |
||||
http://opensource.org/licenses/BSD-3-Clause
|
||||
*/ |
||||
#include <cybozu/inttype.hpp> |
||||
|
||||
#ifndef MCL_SIZEOF_UNIT |
||||
#if defined(CYBOZU_OS_BIT) && (CYBOZU_OS_BIT == 32) |
||||
#define MCL_SIZEOF_UNIT 4 |
||||
#else |
||||
#define MCL_SIZEOF_UNIT 8 |
||||
#endif |
||||
#endif |
||||
|
||||
#ifndef MCL_MAX_BIT_SIZE |
||||
#define MCL_MAX_BIT_SIZE 512 |
||||
#endif |
||||
|
||||
namespace mcl { |
||||
|
||||
namespace fp { |
||||
|
||||
#if MCL_SIZEOF_UNIT == 8 |
||||
typedef uint64_t Unit; |
||||
#else |
||||
typedef uint32_t Unit; |
||||
#endif |
||||
#define MCL_UNIT_BIT_SIZE (MCL_SIZEOF_UNIT * 8) |
||||
|
||||
} } // mcl::fp
|
File diff suppressed because it is too large
Load Diff
@ -1,105 +0,0 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief C interface of ECDSA |
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@license modified new BSD license |
||||
http://opensource.org/licenses/BSD-3-Clause
|
||||
*/ |
||||
#include <stdint.h> // for uint64_t, uint8_t |
||||
#include <stdlib.h> // for size_t |
||||
|
||||
#if defined(_MSC_VER) |
||||
#ifdef ECDSA_DLL_EXPORT |
||||
#define ECDSA_DLL_API __declspec(dllexport) |
||||
#else |
||||
#define ECDSA_DLL_API __declspec(dllimport) |
||||
#ifndef ECDSA_NO_AUTOLINK |
||||
#pragma comment(lib, "mclecdsa.lib") |
||||
#endif |
||||
#endif |
||||
#elif defined(__EMSCRIPTEN__) |
||||
#define ECDSA_DLL_API __attribute__((used)) |
||||
#else |
||||
#define ECDSA_DLL_API |
||||
#endif |
||||
|
||||
#ifndef mclSize |
||||
#ifdef __EMSCRIPTEN__ |
||||
// avoid 64-bit integer
|
||||
#define mclSize unsigned int |
||||
#define mclInt int |
||||
#else |
||||
// use #define for cgo
|
||||
#define mclSize size_t |
||||
#define mclInt int64_t |
||||
#endif |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#ifdef ECDSA_NOT_DEFINE_STRUCT |
||||
|
||||
typedef struct ecdsaSecretKey ecdsaSecretKey; |
||||
typedef struct ecdsaPublicKey ecdsaPublicKey; |
||||
typedef struct ecdsaSignature ecdsaSignature; |
||||
|
||||
#else |
||||
|
||||
typedef struct { |
||||
uint64_t d[4]; |
||||
} ecdsaSecretKey; |
||||
|
||||
typedef struct { |
||||
uint64_t d[4 * 3]; |
||||
} ecdsaPublicKey; |
||||
|
||||
typedef struct { |
||||
uint64_t d[4 * 2]; |
||||
} ecdsaSignature; |
||||
|
||||
#endif |
||||
|
||||
struct ecdsaPrecomputedPublicKey; |
||||
|
||||
/*
|
||||
init library |
||||
return 0 if success |
||||
@note not threadsafe |
||||
*/ |
||||
ECDSA_DLL_API int ecdsaInit(void); |
||||
|
||||
// return written byte size if success else 0
|
||||
ECDSA_DLL_API mclSize ecdsaSecretKeySerialize(void *buf, mclSize maxBufSize, const ecdsaSecretKey *sec); |
||||
ECDSA_DLL_API mclSize ecdsaPublicKeySerialize(void *buf, mclSize maxBufSize, const ecdsaPublicKey *pub); |
||||
ECDSA_DLL_API mclSize ecdsaSignatureSerialize(void *buf, mclSize maxBufSize, const ecdsaSignature *sig); |
||||
|
||||
// return read byte size if sucess else 0
|
||||
ECDSA_DLL_API mclSize ecdsaSecretKeyDeserialize(ecdsaSecretKey* sec, const void *buf, mclSize bufSize); |
||||
ECDSA_DLL_API mclSize ecdsaPublicKeyDeserialize(ecdsaPublicKey* pub, const void *buf, mclSize bufSize); |
||||
ECDSA_DLL_API mclSize ecdsaSignatureDeserialize(ecdsaSignature* sig, const void *buf, mclSize bufSize); |
||||
|
||||
// return 0 if success
|
||||
ECDSA_DLL_API int ecdsaSecretKeySetByCSPRNG(ecdsaSecretKey *sec); |
||||
|
||||
ECDSA_DLL_API void ecdsaGetPublicKey(ecdsaPublicKey *pub, const ecdsaSecretKey *sec); |
||||
|
||||
ECDSA_DLL_API void ecdsaSign(ecdsaSignature *sig, const ecdsaSecretKey *sec, const void *m, mclSize size); |
||||
|
||||
// return 1 if valid
|
||||
ECDSA_DLL_API int ecdsaVerify(const ecdsaSignature *sig, const ecdsaPublicKey *pub, const void *m, mclSize size); |
||||
ECDSA_DLL_API int ecdsaVerifyPrecomputed(const ecdsaSignature *sig, const ecdsaPrecomputedPublicKey *pub, const void *m, mclSize size); |
||||
|
||||
// return nonzero if success
|
||||
ECDSA_DLL_API ecdsaPrecomputedPublicKey *ecdsaPrecomputedPublicKeyCreate(); |
||||
// call this function to avoid memory leak
|
||||
ECDSA_DLL_API void ecdsaPrecomputedPublicKeyDestroy(ecdsaPrecomputedPublicKey *ppub); |
||||
// return 0 if success
|
||||
ECDSA_DLL_API int ecdsaPrecomputedPublicKeyInit(ecdsaPrecomputedPublicKey *ppub, const ecdsaPublicKey *pub); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
@ -1,257 +0,0 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief ECDSA |
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@license modified new BSD license |
||||
http://opensource.org/licenses/BSD-3-Clause
|
||||
*/ |
||||
#include <mcl/fp.hpp> |
||||
#include <mcl/ec.hpp> |
||||
#include <mcl/ecparam.hpp> |
||||
#include <mcl/window_method.hpp> |
||||
|
||||
namespace mcl { namespace ecdsa { |
||||
|
||||
namespace local { |
||||
|
||||
#ifndef MCLSHE_WIN_SIZE |
||||
#define MCLSHE_WIN_SIZE 10 |
||||
#endif |
||||
static const size_t winSize = MCLSHE_WIN_SIZE; |
||||
|
||||
struct FpTag; |
||||
struct ZnTag; |
||||
|
||||
} // mcl::ecdsa::local
|
||||
|
||||
typedef mcl::FpT<local::FpTag, 256> Fp; |
||||
typedef mcl::FpT<local::ZnTag, 256> Zn; |
||||
typedef mcl::EcT<Fp> Ec; |
||||
|
||||
namespace local { |
||||
|
||||
struct Param { |
||||
mcl::EcParam ecParam; |
||||
Ec P; |
||||
mcl::fp::WindowMethod<Ec> Pbase; |
||||
}; |
||||
|
||||
inline Param& getParam() |
||||
{ |
||||
static Param p; |
||||
return p; |
||||
} |
||||
|
||||
inline void be32toZn(Zn& x, const mcl::fp::Unit *buf) |
||||
{ |
||||
const size_t n = 32; |
||||
const unsigned char *p = (const unsigned char*)buf; |
||||
unsigned char be[n]; |
||||
for (size_t i = 0; i < n; i++) { |
||||
be[i] = p[n - 1 - i]; |
||||
} |
||||
x.setArrayMaskMod(be, n); |
||||
} |
||||
|
||||
/*
|
||||
y = x mod n |
||||
*/ |
||||
inline void FpToZn(Zn& y, const Fp& x) |
||||
{ |
||||
fp::Block b; |
||||
x.getBlock(b); |
||||
y.setArrayMaskMod(b.p, b.n); |
||||
} |
||||
|
||||
inline void setHashOf(Zn& x, const void *msg, size_t msgSize) |
||||
{ |
||||
mcl::fp::Unit xBuf[256 / 8 / sizeof(mcl::fp::Unit)]; |
||||
uint32_t hashSize = mcl::fp::sha256(xBuf, sizeof(xBuf), msg, (uint32_t)msgSize); |
||||
assert(hashSize == sizeof(xBuf)); |
||||
(void)hashSize; |
||||
be32toZn(x, xBuf); |
||||
} |
||||
|
||||
} // mcl::ecdsa::local
|
||||
|
||||
const local::Param& param = local::getParam(); |
||||
|
||||
inline void init(bool *pb) |
||||
{ |
||||
const mcl::EcParam& ecParam = mcl::ecparam::secp256k1; |
||||
Zn::init(pb, ecParam.n); |
||||
if (!*pb) return; |
||||
Fp::init(pb, ecParam.p); |
||||
if (!*pb) return; |
||||
Ec::init(pb, ecParam.a, ecParam.b); |
||||
if (!*pb) return; |
||||
Zn::setIoMode(16); |
||||
Fp::setIoMode(16); |
||||
Ec::setIoMode(mcl::IoEcAffine); |
||||
local::Param& p = local::getParam(); |
||||
p.ecParam = ecParam; |
||||
Fp x, y; |
||||
x.setStr(pb, ecParam.gx); |
||||
if (!*pb) return; |
||||
y.setStr(pb, ecParam.gy); |
||||
if (!*pb) return; |
||||
p.P.set(pb, x, y); |
||||
if (!*pb) return; |
||||
p.Pbase.init(pb, p.P, ecParam.bitSize, local::winSize); |
||||
} |
||||
|
||||
#ifndef CYBOZU_DONT_USE_EXCEPTION |
||||
inline void init() |
||||
{ |
||||
bool b; |
||||
init(&b); |
||||
if (!b) throw cybozu::Exception("ecdsa:init"); |
||||
} |
||||
#endif |
||||
|
||||
typedef Zn SecretKey; |
||||
typedef Ec PublicKey; |
||||
|
||||
struct PrecomputedPublicKey { |
||||
mcl::fp::WindowMethod<Ec> pubBase_; |
||||
void init(bool *pb, const PublicKey& pub) |
||||
{ |
||||
pubBase_.init(pb, pub, param.ecParam.bitSize, local::winSize); |
||||
} |
||||
#ifndef CYBOZU_DONT_USE_EXCEPTION |
||||
void init(const PublicKey& pub) |
||||
{ |
||||
bool b; |
||||
init(&b, pub); |
||||
if (!b) throw cybozu::Exception("ecdsa:PrecomputedPublicKey:init"); |
||||
} |
||||
#endif |
||||
}; |
||||
|
||||
inline void getPublicKey(PublicKey& pub, const SecretKey& sec) |
||||
{ |
||||
Ec::mul(pub, param.P, sec); |
||||
pub.normalize(); |
||||
} |
||||
|
||||
struct Signature : public mcl::fp::Serializable<Signature> { |
||||
Zn r, s; |
||||
template<class InputStream> |
||||
void load(bool *pb, InputStream& is, int ioMode = IoSerialize) |
||||
{ |
||||
r.load(pb, is, ioMode); if (!*pb) return; |
||||
s.load(pb, is, ioMode); |
||||
} |
||||
template<class OutputStream> |
||||
void save(bool *pb, OutputStream& os, int ioMode = IoSerialize) const |
||||
{ |
||||
const char sep = *fp::getIoSeparator(ioMode); |
||||
r.save(pb, os, ioMode); if (!*pb) return; |
||||
if (sep) { |
||||
cybozu::writeChar(pb, os, sep); |
||||
if (!*pb) return; |
||||
} |
||||
s.save(pb, os, ioMode); |
||||
} |
||||
#ifndef CYBOZU_DONT_USE_EXCEPTION |
||||
template<class InputStream> |
||||
void load(InputStream& is, int ioMode = IoSerialize) |
||||
{ |
||||
bool b; |
||||
load(&b, is, ioMode); |
||||
if (!b) throw cybozu::Exception("ecdsa:Signature:load"); |
||||
} |
||||
template<class OutputStream> |
||||
void save(OutputStream& os, int ioMode = IoSerialize) const |
||||
{ |
||||
bool b; |
||||
save(&b, os, ioMode); |
||||
if (!b) throw cybozu::Exception("ecdsa:Signature:save"); |
||||
} |
||||
#endif |
||||
#ifndef CYBOZU_DONT_USE_STRING |
||||
friend std::istream& operator>>(std::istream& is, Signature& self) |
||||
{ |
||||
self.load(is, fp::detectIoMode(Ec::getIoMode(), is)); |
||||
return is; |
||||
} |
||||
friend std::ostream& operator<<(std::ostream& os, const Signature& self) |
||||
{ |
||||
self.save(os, fp::detectIoMode(Ec::getIoMode(), os)); |
||||
return os; |
||||
} |
||||
#endif |
||||
}; |
||||
|
||||
inline void sign(Signature& sig, const SecretKey& sec, const void *msg, size_t msgSize) |
||||
{ |
||||
Zn& r = sig.r; |
||||
Zn& s = sig.s; |
||||
Zn z, k; |
||||
local::setHashOf(z, msg, msgSize); |
||||
Ec Q; |
||||
for (;;) { |
||||
k.setByCSPRNG(); |
||||
param.Pbase.mul(Q, k); |
||||
if (Q.isZero()) continue; |
||||
Q.normalize(); |
||||
local::FpToZn(r, Q.x); |
||||
if (r.isZero()) continue; |
||||
Zn::mul(s, r, sec); |
||||
s += z; |
||||
if (s.isZero()) continue; |
||||
s /= k; |
||||
return; |
||||
} |
||||
} |
||||
|
||||
namespace local { |
||||
|
||||
inline void mulDispatch(Ec& Q, const PublicKey& pub, const Zn& y) |
||||
{ |
||||
Ec::mul(Q, pub, y); |
||||
} |
||||
|
||||
inline void mulDispatch(Ec& Q, const PrecomputedPublicKey& ppub, const Zn& y) |
||||
{ |
||||
ppub.pubBase_.mul(Q, y); |
||||
} |
||||
|
||||
template<class Pub> |
||||
inline bool verify(const Signature& sig, const Pub& pub, const void *msg, size_t msgSize) |
||||
{ |
||||
const Zn& r = sig.r; |
||||
const Zn& s = sig.s; |
||||
if (r.isZero() || s.isZero()) return false; |
||||
Zn z, w, u1, u2; |
||||
local::setHashOf(z, msg, msgSize); |
||||
Zn::inv(w, s); |
||||
Zn::mul(u1, z, w); |
||||
Zn::mul(u2, r, w); |
||||
Ec Q1, Q2; |
||||
param.Pbase.mul(Q1, u1); |
||||
// Ec::mul(Q2, pub, u2);
|
||||
local::mulDispatch(Q2, pub, u2); |
||||
Q1 += Q2; |
||||
if (Q1.isZero()) return false; |
||||
Q1.normalize(); |
||||
Zn x; |
||||
local::FpToZn(x, Q1.x); |
||||
return r == x; |
||||
} |
||||
|
||||
} // mcl::ecdsa::local
|
||||
|
||||
inline bool verify(const Signature& sig, const PublicKey& pub, const void *msg, size_t msgSize) |
||||
{ |
||||
return local::verify(sig, pub, msg, msgSize); |
||||
} |
||||
|
||||
inline bool verify(const Signature& sig, const PrecomputedPublicKey& ppub, const void *msg, size_t msgSize) |
||||
{ |
||||
return local::verify(sig, ppub, msg, msgSize); |
||||
} |
||||
|
||||
} } // mcl::ecdsa
|
||||
|
@ -0,0 +1,572 @@ |
||||
#pragma once |
||||
/**
|
||||
@file |
||||
@brief map to G2 on BLS12-381 (must be included from mcl/bn.hpp) |
||||
@author MITSUNARI Shigeo(@herumi) |
||||
@license modified new BSD license |
||||
http://opensource.org/licenses/BSD-3-Clause
|
||||
ref. https://eprint.iacr.org/2019/403 , https://github.com/algorand/bls_sigs_ref
|
||||
*/ |
||||
namespace mcl { |
||||
|
||||
namespace local { |
||||
|
||||
// y^2 = x^3 + 4(1 + i)
|
||||
template<class F> |
||||
struct PointT { |
||||
typedef F Fp; |
||||
F x, y, z; |
||||
static F a_; |
||||
static F b_; |
||||
static int specialA_; |
||||
bool isZero() const |
||||
{ |
||||
return z.isZero(); |
||||
} |
||||
void clear() |
||||
{ |
||||
x.clear(); |
||||
y.clear(); |
||||
z.clear(); |
||||
} |
||||
bool isEqual(const PointT<F>& rhs) const |
||||
{ |
||||
return ec::isEqualJacobi(*this, rhs); |
||||
} |
||||
}; |
||||
|
||||
template<class F> F PointT<F>::a_; |
||||
template<class F> F PointT<F>::b_; |
||||
template<class F> int PointT<F>::specialA_; |
||||
|
||||
} // mcl::local
|
||||
|
||||
template<class Fp, class G1, class Fp2, class G2> |
||||
struct MapTo_WB19 { |
||||
typedef local::PointT<Fp> E1; |
||||
typedef local::PointT<Fp2> E2; |
||||
mpz_class sqrtConst; // (p^2 - 9) / 16
|
||||
Fp2 g2A; |
||||
Fp2 g2B; |
||||
Fp2 root4[4]; |
||||
Fp2 etas[4]; |
||||
Fp2 xnum[4]; |
||||
Fp2 xden[3]; |
||||
Fp2 ynum[4]; |
||||
Fp2 yden[4]; |
||||
Fp g1A, g1B, g1c1, g1c2; |
||||
Fp g1xnum[12]; |
||||
Fp g1xden[11]; |
||||
Fp g1ynum[16]; |
||||
Fp g1yden[16]; |
||||
mpz_class g1cofactor; |
||||
int g1Z; |
||||
void init() |
||||
{ |
||||
bool b; |
||||
g2A.a = 0; |
||||
g2A.b = 240; |
||||
g2B.a = 1012; |
||||
g2B.b = 1012; |
||||
E1::a_.clear(); |
||||
E1::b_ = 4; |
||||
E1::specialA_ = ec::Zero; |
||||
E2::a_.clear(); |
||||
E2::b_.a = 4; |
||||
E2::b_.b = 4; |
||||
E2::specialA_ = ec::Zero; |
||||
sqrtConst = Fp::getOp().mp; |
||||
sqrtConst *= sqrtConst; |
||||
sqrtConst -= 9; |
||||
sqrtConst /= 16; |
||||
const char *rv1Str = "0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"; |
||||
root4[0].a = 1; |
||||
root4[0].b.clear(); |
||||
root4[1].a.clear(); |
||||
root4[1].b = 1; |
||||
root4[2].a.setStr(&b, rv1Str); |
||||
assert(b); (void)b; |
||||
root4[2].b = root4[2].a; |
||||
root4[3].a = root4[2].a; |
||||
Fp::neg(root4[3].b, root4[3].a); |
||||
const char *ev1Str = "0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90"; |
||||
const char *ev2Str = "0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5"; |
||||
const char *ev3Str = "0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17"; |
||||
const char *ev4Str = "0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1"; |
||||
Fp& ev1 = etas[0].a; |
||||
Fp& ev2 = etas[0].b; |
||||
Fp& ev3 = etas[2].a; |
||||
Fp& ev4 = etas[2].b; |
||||
ev1.setStr(&b, ev1Str); |
||||
assert(b); (void)b; |
||||
ev2.setStr(&b, ev2Str); |
||||
assert(b); (void)b; |
||||
Fp::neg(etas[1].a, ev2); |
||||
etas[1].b = ev1; |
||||
ev3.setStr(&b, ev3Str); |
||||
assert(b); (void)b; |
||||
ev4.setStr(&b, ev4Str); |
||||
assert(b); (void)b; |
||||
Fp::neg(etas[3].a, ev4); |
||||
etas[3].b = ev3; |
||||
init_iso3(); |
||||
{ |
||||
const char *A = "0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d"; |
||||
const char *B = "0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0"; |
||||
const char *c1 = "0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaaa"; |
||||
const char *c2 = "0x3d689d1e0e762cef9f2bec6130316806b4c80eda6fc10ce77ae83eab1ea8b8b8a407c9c6db195e06f2dbeabc2baeff5"; |
||||
g1A.setStr(&b, A); |
||||
assert(b); (void)b; |
||||
g1B.setStr(&b, B); |
||||
assert(b); (void)b; |
||||
g1c1.setStr(&b, c1); |
||||
assert(b); (void)b; |
||||
g1c2.setStr(&b, c2); |
||||
assert(b); (void)b; |
||||
g1Z = 11; |
||||
gmp::setStr(&b, g1cofactor, "d201000000010001", 16); |
||||
assert(b); (void)b; |
||||
} |
||||
init_iso11(); |
||||
} |
||||
void initArray(Fp *dst, const char **s, size_t n) const |
||||
{ |
||||
bool b; |
||||
for (size_t i = 0; i < n; i++) { |
||||
dst[i].setStr(&b, s[i]); |
||||
assert(b); |
||||
(void)b; |
||||
} |
||||
} |
||||
void init_iso3() |
||||
{ |
||||
const char *tbl[] = { |
||||
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6", |
||||
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a", |
||||
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e", |
||||
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d", |
||||
"0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1", |
||||
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63", |
||||
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f", |
||||
"0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706", |
||||
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be", |
||||
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c", |
||||
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f", |
||||
"0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10", |
||||
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb", |
||||
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3", |
||||
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99", |
||||
}; |
||||
bool b; |
||||
xnum[0].a.setStr(&b, tbl[0]); assert(b); (void)b; |
||||
xnum[0].b = xnum[0].a; |
||||
xnum[1].a.clear(); |
||||
xnum[1].b.setStr(&b, tbl[1]); assert(b); (void)b; |
||||
xnum[2].a.setStr(&b, tbl[2]); assert(b); (void)b; |
||||
xnum[2].b.setStr(&b, tbl[3]); assert(b); (void)b; |
||||
xnum[3].a.setStr(&b, tbl[4]); assert(b); (void)b; |
||||
xnum[3].b.clear(); |
||||
xden[0].a.clear(); |
||||
xden[0].b.setStr(&b, tbl[5]); assert(b); (void)b; |
||||
xden[1].a = 0xc; |
||||
xden[1].b.setStr(&b, tbl[6]); assert(b); (void)b; |
||||
xden[2].a = 1; |
||||
xden[2].b = 0; |
||||
ynum[0].a.setStr(&b, tbl[7]); assert(b); (void)b; |
||||
ynum[0].b = ynum[0].a; |
||||
ynum[1].a.clear(); |
||||
ynum[1].b.setStr(&b, tbl[8]); assert(b); (void)b; |
||||
ynum[2].a.setStr(&b, tbl[9]); assert(b); (void)b; |
||||
ynum[2].b.setStr(&b, tbl[10]); assert(b); (void)b; |
||||
ynum[3].a.setStr(&b, tbl[11]); assert(b); (void)b; |
||||
ynum[3].b.clear(); |
||||
yden[0].a.setStr(&b, tbl[12]); assert(b); (void)b; |
||||
yden[0].b = yden[0].a; |
||||
yden[1].a.clear(); |
||||
yden[1].b.setStr(&b, tbl[13]); assert(b); (void)b; |
||||
yden[2].a = 0x12; |
||||
yden[2].b.setStr(&b, tbl[14]); assert(b); (void)b; |
||||
yden[3].a = 1; |
||||
yden[3].b.clear(); |
||||
} |
||||
void init_iso11() |
||||
{ |
||||
const char *xnumStr[] = { |
||||
"0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7", |
||||
"0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb", |
||||
"0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0", |
||||
"0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861", |
||||
"0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9", |
||||
"0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983", |
||||
"0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84", |
||||
"0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e", |
||||
"0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317", |
||||
"0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e", |
||||
"0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b", |
||||
"0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229", |
||||
}; |
||||
const char *xdenStr[] = { |
||||
"0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c", |
||||
"0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff", |
||||
"0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19", |
||||
"0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8", |
||||
"0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e", |
||||
"0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5", |
||||
"0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a", |
||||
"0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e", |
||||
"0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641", |
||||
"0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a", |
||||
"0x1", |
||||
}; |
||||
const char *ynumStr[] = { |
||||
"0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33", |
||||
"0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696", |
||||
"0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6", |
||||
"0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb", |
||||
"0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb", |
||||
"0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0", |
||||
"0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2", |
||||
"0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29", |
||||
"0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587", |
||||
"0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30", |
||||
"0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132", |
||||
"0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e", |
||||
"0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8", |
||||
"0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133", |
||||
"0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b", |
||||
"0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604", |
||||
}; |
||||
const char *ydenStr[] = { |
||||
"0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1", |
||||
"0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d", |
||||
"0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2", |
||||
"0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416", |
||||
"0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d", |
||||
"0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac", |
||||
"0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c", |
||||
"0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9", |
||||
"0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a", |
||||
"0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55", |
||||
"0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8", |
||||
"0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092", |
||||
"0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc", |
||||
"0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7", |
||||
"0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f", |
||||
"0x1", |
||||
}; |
||||
initArray(g1xnum, xnumStr, CYBOZU_NUM_OF_ARRAY(xnumStr)); |
||||
initArray(g1xden, xdenStr, CYBOZU_NUM_OF_ARRAY(xdenStr)); |
||||
initArray(g1ynum, ynumStr, CYBOZU_NUM_OF_ARRAY(ynumStr)); |
||||
initArray(g1yden, ydenStr, CYBOZU_NUM_OF_ARRAY(ydenStr)); |
||||
} |
||||
template<class F, size_t N> |
||||
void evalPoly(F& y, const F& x, const F *zpows, const F (&cof)[N]) const |
||||
{ |
||||
y = cof[N - 1]; // always zpows[0] = 1
|
||||
for (size_t i = 1; i < N; i++) { |
||||
y *= x; |
||||
F t; |
||||
F::mul(t, zpows[i - 1], cof[N - 1 - i]); |
||||
y += t; |
||||
} |
||||
} |
||||
// refer (xnum, xden, ynum, yden)
|
||||
void iso3(G2& Q, const E2& P) const |
||||
{ |
||||
Fp2 zpows[3]; |
||||
Fp2::sqr(zpows[0], P.z); |
||||
Fp2::sqr(zpows[1], zpows[0]); |
||||
Fp2::mul(zpows[2], zpows[1], zpows[0]); |
||||
Fp2 mapvals[4]; |
||||
evalPoly(mapvals[0], P.x, zpows, xnum); |
||||
evalPoly(mapvals[1], P.x, zpows, xden); |
||||
evalPoly(mapvals[2], P.x, zpows, ynum); |
||||
evalPoly(mapvals[3], P.x, zpows, yden); |
||||
mapvals[1] *= zpows[0]; |
||||
mapvals[2] *= P.y; |
||||
mapvals[3] *= zpows[0]; |
||||
mapvals[3] *= P.z; |
||||
Fp2::mul(Q.z, mapvals[1], mapvals[3]); |
||||
Fp2::mul(Q.x, mapvals[0], mapvals[3]); |
||||
Q.x *= Q.z; |
||||
Fp2 t; |
||||
Fp2::sqr(t, Q.z); |
||||
Fp2::mul(Q.y, mapvals[2], mapvals[1]); |
||||
Q.y *= t; |
||||
} |
||||
template<class X, class C, size_t N> |
||||
X evalPoly2(const X& x, const C (&c)[N]) const |
||||
{ |
||||
X ret = c[N - 1]; |
||||
for (size_t i = 1; i < N; i++) { |
||||
ret *= x; |
||||
ret += c[N - 1 - i]; |
||||
} |
||||
return ret; |
||||
} |
||||
// refer (g1xnum, g1xden, g1ynum, g1yden)
|
||||
void iso11(G1& Q, E1& P) const |
||||
{ |
||||
ec::normalizeJacobi(P); |
||||
Fp xn, xd, yn, yd; |
||||
xn = evalPoly2(P.x, g1xnum); |
||||
xd = evalPoly2(P.x, g1xden); |
||||
yn = evalPoly2(P.x, g1ynum); |
||||
yd = evalPoly2(P.x, g1yden); |
||||
/*
|
||||
[xn/xd:y * yn/yd:1] = [xn xd yd^2:y yn xd^3 yd^2:xd yd] |
||||
=[xn yd z:y yn xd z^2:z] where z = xd yd |
||||
*/ |
||||
Fp::mul(Q.z, xd, yd); |
||||
Fp::mul(Q.x, xn, yd); |
||||
Q.x *= Q.z; |
||||
Fp::mul(Q.y, P.y, yn); |
||||
Q.y *= xd; |
||||
Fp::sqr(xd, Q.z); |
||||
Q.y *= xd; |
||||
} |
||||
/*
|
||||
xi = -2-i |
||||
(a+bi)*(-2-i) = (b-2a)-(a+2b)i |
||||
*/ |
||||
void mul_xi(Fp2& y, const Fp2& x) const |
||||
{ |
||||
Fp t; |
||||
Fp::sub(t, x.b, x.a); |
||||
t -= x.a; |
||||
Fp::add(y.b, x.b, x.b); |
||||
y.b += x.a; |
||||
Fp::neg(y.b, y.b); |
||||
y.a = t; |
||||
} |
||||
bool isNegSign(const Fp& x) const |
||||
{ |
||||
return x.isOdd(); |
||||
} |
||||
bool isNegSign(const Fp2& x) const |
||||
{ |
||||
bool sign0 = isNegSign(x.a); |
||||
bool zero0 = x.a.isZero(); |
||||
bool sign1 = isNegSign(x.b); |
||||
return sign0 || (zero0 & sign1); |
||||
} |
||||
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#appendix-D.3.5
|
||||
void sswuG1(Fp& xn, Fp& xd, Fp& y, const Fp& u) const |
||||
{ |
||||
const Fp& A = g1A; |
||||
const Fp& B = g1B; |
||||
const Fp& c1 = g1c1; |
||||
const Fp& c2 = g1c2; |
||||
const int Z = g1Z; |
||||
Fp u2, u2Z, t, t2, t3; |
||||
|
||||
Fp::sqr(u2, u); |
||||
Fp::mulUnit(u2Z, u2, Z); |
||||
Fp::sqr(t, u2Z); |
||||
Fp::add(xd, t, u2Z); |
||||
if (xd.isZero()) { |
||||
Fp::mulUnit(xd, A, Z); |
||||
xn = B; |
||||
} else { |
||||
Fp::add(xn, xd, Fp::one()); |
||||
xn *= B; |
||||
xd *= A; |
||||
Fp::neg(xd, xd); |
||||
} |
||||
Fp::sqr(t, xd); |
||||
Fp::mul(t2, t, xd); |
||||
t *= A; |
||||
Fp::sqr(t3, xn); |
||||
t3 += t; |
||||
t3 *= xn; |
||||
Fp::mul(t, t2, B); |
||||
t3 += t; |
||||
Fp::sqr(y, t2); |
||||
Fp::mul(t, t3, t2); |
||||
y *= t; |
||||
Fp::pow(y, y, c1); |
||||
y *= t; |
||||
Fp::sqr(t, y); |
||||
t *= t2; |
||||
if (t != t3) { |
||||
xn *= u2Z; |
||||
y *= c2; |
||||
y *= u2; |
||||
y *= u; |
||||
} |
||||
if (isNegSign(u) != isNegSign(y)) { |
||||
Fp::neg(y, y); |
||||
} |
||||
} |
||||
void sswuG1(E1& pt, const Fp& u) const |
||||
{ |
||||
Fp xn, y; |
||||
Fp& xd = pt.z; |
||||
sswuG1(xn, xd, y, u); |
||||
Fp::mul(pt.x, xn, xd); |
||||
Fp::sqr(pt.y, xd); |
||||
pt.y *= xd; |
||||
pt.y *= y; |
||||
} |
||||
// https://github.com/algorand/bls_sigs_ref
|
||||
void sswuG2(E2& P, const Fp2& t) const |
||||
{ |
||||
Fp2 t2, t2xi; |
||||
Fp2::sqr(t2, t); |
||||
Fp2 den, den2; |
||||
mul_xi(t2xi, t2); |
||||
den = t2xi; |
||||
Fp2::sqr(den2, den); |
||||
// (t^2 * xi)^2 + (t^2 * xi)
|
||||
den += den2; |
||||
Fp2 x0_num, x0_den; |
||||
Fp2::add(x0_num, den, 1); |
||||
x0_num *= g2B; |
||||
if (den.isZero()) { |
||||
mul_xi(x0_den, g2A); |
||||
} else { |
||||
Fp2::mul(x0_den, -g2A, den); |
||||
} |
||||
Fp2 x0_den2, x0_den3, gx0_den, gx0_num; |
||||
Fp2::sqr(x0_den2, x0_den); |
||||
Fp2::mul(x0_den3, x0_den2, x0_den); |
||||
gx0_den = x0_den3; |
||||
|
||||
Fp2::mul(gx0_num, g2B, gx0_den); |
||||
Fp2 tmp, tmp1, tmp2; |
||||
Fp2::mul(tmp, g2A, x0_num); |
||||
tmp *= x0_den2; |
||||
gx0_num += tmp; |
||||
Fp2::sqr(tmp, x0_num); |
||||
tmp *= x0_num; |
||||
gx0_num += tmp; |
||||
|
||||
Fp2::sqr(tmp1, gx0_den); // x^2
|
||||
Fp2::sqr(tmp2, tmp1); // x^4
|
||||
tmp1 *= tmp2; |
||||
tmp1 *= gx0_den; // x^7
|
||||
Fp2::mul(tmp2, gx0_num, tmp1); |
||||
tmp1 *= tmp2; |
||||
tmp1 *= gx0_den; |
||||
Fp2 candi; |
||||
Fp2::pow(candi, tmp1, sqrtConst); |
||||
candi *= tmp2; |
||||
bool isNegT = isNegSign(t); |
||||
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(root4); i++) { |
||||
Fp2::mul(P.y, candi, root4[i]); |
||||
Fp2::sqr(tmp, P.y); |
||||
tmp *= gx0_den; |
||||
if (tmp == gx0_num) { |
||||
if (isNegSign(P.y) != isNegT) { |
||||
Fp2::neg(P.y, P.y); |
||||
} |
||||
Fp2::mul(P.x, x0_num, x0_den); |
||||
P.y *= x0_den3; |
||||
P.z = x0_den; |
||||
return; |
||||
} |
||||
} |
||||
Fp2 x1_num, x1_den, gx1_num, gx1_den; |
||||
Fp2::mul(x1_num, t2xi, x0_num); |
||||
x1_den = x0_den; |
||||
Fp2::mul(gx1_num, den2, t2xi); |
||||
gx1_num *= gx0_num; |
||||
gx1_den = gx0_den; |
||||
candi *= t2; |
||||
candi *= t; |
||||
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(etas); i++) { |
||||
Fp2::mul(P.y, candi, etas[i]); |
||||
Fp2::sqr(tmp, P.y); |
||||
tmp *= gx1_den; |
||||
if (tmp == gx1_num) { |
||||
if (isNegSign(P.y) != isNegT) { |
||||
Fp2::neg(P.y, P.y); |
||||
} |
||||
Fp2::mul(P.x, x1_num, x1_den); |
||||
Fp2::sqr(tmp, x1_den); |
||||
P.y *= tmp; |
||||
P.y *= x1_den; |
||||
P.z = x1_den; |
||||
return; |
||||
} |
||||
} |
||||
assert(0); |
||||
} |
||||
template<class T> |
||||
void put(const T& P) const |
||||
{ |
||||
const int base = 10; |
||||
printf("x=%s\n", P.x.getStr(base).c_str()); |
||||
printf("y=%s\n", P.y.getStr(base).c_str()); |
||||
printf("z=%s\n", P.z.getStr(base).c_str()); |
||||
} |
||||
void Fp2ToG2(G2& P, const Fp2& t, const Fp2 *t2 = 0) const |
||||
{ |
||||
E2 Pp; |
||||
sswuG2(Pp, t); |
||||
if (t2) { |
||||
E2 P2; |
||||
sswuG2(P2, *t2); |
||||
ec::addJacobi(Pp, Pp, P2); |
||||
} |
||||
iso3(P, Pp); |
||||
mcl::local::mulByCofactorBLS12fast(P, P); |
||||
} |
||||
void hashToFp2(Fp2 out[2], const void *msg, size_t msgSize, const void *dst, size_t dstSize) const |
||||
{ |
||||
uint8_t md[256]; |
||||
mcl::fp::expand_message_xmd(md, sizeof(md), msg, msgSize, dst, dstSize); |
||||
Fp *x = out[0].getFp0(); |
||||
for (size_t i = 0; i < 4; i++) { |
||||
bool b; |
||||
x[i].setBigEndianMod(&b, &md[64 * i], 64); |
||||
assert(b); (void)b; |
||||
} |
||||
} |
||||
void msgToG2(G2& out, const void *msg, size_t msgSize, const void *dst, size_t dstSize) const |
||||
{ |
||||
Fp2 t[2]; |
||||
hashToFp2(t, msg, msgSize, dst, dstSize); |
||||
Fp2ToG2(out, t[0], &t[1]); |
||||
} |
||||
void msgToG2(G2& out, const void *msg, size_t msgSize) const |
||||
{ |
||||
const char *dst = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; |
||||
const size_t dstSize = strlen(dst); |
||||
msgToG2(out, msg, msgSize, dst, dstSize); |
||||
} |
||||
void FpToG1(G1& out, const Fp& u0, const Fp *u1 = 0) const |
||||
{ |
||||
E1 P1; |
||||
sswuG1(P1, u0); |
||||
if (u1) { |
||||
E1 P2; |
||||
sswuG1(P2, *u1); |
||||
ec::addJacobi(P1, P1, P2); |
||||
} |
||||
iso11(out, P1); |
||||
G1::mulGeneric(out, out, g1cofactor); |
||||
} |
||||
void msgToG1(G1& out, const void *msg, size_t msgSize, const char *dst, size_t dstSize) const |
||||
{ |
||||
uint8_t md[128]; |
||||
mcl::fp::expand_message_xmd(md, sizeof(md), msg, msgSize, dst, dstSize); |
||||
Fp u[2]; |
||||
for (size_t i = 0; i < 2; i++) { |
||||
bool b; |
||||
u[i].setBigEndianMod(&b, &md[64 * i], 64); |
||||
assert(b); (void)b; |
||||
} |
||||
FpToG1(out, u[0], &u[1]); |
||||
} |
||||
|
||||
void msgToG1(G1& out, const void *msg, size_t msgSize) const |
||||
{ |
||||
const char *dst = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_"; |
||||
const size_t dstSize = strlen(dst); |
||||
msgToG1(out, msg, msgSize, dst, dstSize); |
||||
} |
||||
}; |
||||
|
||||
} // mcl
|
||||
|
@ -0,0 +1,6 @@ |
||||
all: low_test |
||||
|
||||
CFLAGS=-I ../include/ -m32 -Ofast -Wall -Wextra -DNDEBUG
|
||||
|
||||
low_test: low_test.cpp ../src/low_func_wasm.hpp |
||||
$(CXX) -o low_test low_test.cpp $(CFLAGS)
|
@ -0,0 +1,234 @@ |
||||
#include <stdio.h> |
||||
#include <stdint.h> |
||||
|
||||
void dump(const char *msg, const uint32_t *x, size_t n) |
||||
{ |
||||
printf("%s", msg); |
||||
for (size_t i = 0; i < n; i++) { |
||||
printf("%08x", x[n - 1 - i]); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
#include "../src/low_func_wasm.hpp" |
||||
|
||||
#define MCL_USE_VINT |
||||
#define MCL_VINT_FIXED_BUFFER |
||||
#define MCL_SIZEOF_UNIT 4 |
||||
#define MCL_MAX_BIT_SIZE 768 |
||||
#include <mcl/vint.hpp> |
||||
#include <cybozu/test.hpp> |
||||
#include <cybozu/xorshift.hpp> |
||||
#include <cybozu/benchmark.hpp> |
||||
#include <mcl/util.hpp> |
||||
|
||||
const int C = 10000; |
||||
|
||||
template<class RG> |
||||
void setRand(uint32_t *x, size_t n, RG& rg) |
||||
{ |
||||
for (size_t i = 0; i < n; i++) { |
||||
x[i] = rg.get32(); |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
g++ -Ofast -DNDEBUG -Wall -Wextra -m32 -I ./include/ misc/low_test.cpp |
||||
Core i7-8700 |
||||
mulT karatsuba |
||||
N = 6, 182clk 225clk |
||||
N = 8, 300clk 350clk |
||||
N = 12, 594clk 730clk |
||||
*/ |
||||
template<size_t N> |
||||
void mulTest() |
||||
{ |
||||
printf("N=%zd (%zdbit)\n", N, N * 32); |
||||
cybozu::XorShift rg; |
||||
uint32_t x[N]; |
||||
uint32_t y[N]; |
||||
uint32_t z[N * 2]; |
||||
for (size_t i = 0; i < 1000; i++) { |
||||
setRand(x, N, rg); |
||||
setRand(y, N, rg); |
||||
// remove MSB
|
||||
x[N - 1] &= 0x7fffffff; |
||||
y[N - 1] &= 0x7fffffff; |
||||
mcl::Vint vx, vy; |
||||
vx.setArray(x, N); |
||||
vy.setArray(y, N); |
||||
vx *= vy; |
||||
mcl::mulT<N>(z, x, y); |
||||
CYBOZU_TEST_EQUAL_ARRAY(z, vx.getUnit(), N * 2); |
||||
memset(z, 0, sizeof(z)); |
||||
mcl::karatsubaT<N>(z, x, y); |
||||
CYBOZU_TEST_EQUAL_ARRAY(z, vx.getUnit(), N * 2); |
||||
} |
||||
CYBOZU_BENCH_C("mulT", C, mcl::mulT<N>, z, x, y); |
||||
CYBOZU_BENCH_C("kara", C, mcl::karatsubaT<N>, z, x, y); |
||||
} |
||||
|
||||
CYBOZU_TEST_AUTO(mulT) |
||||
{ |
||||
mulTest<8>(); |
||||
mulTest<12>(); |
||||
} |
||||
|
||||
template<size_t N> |
||||
void sqrTest() |
||||
{ |
||||
printf("N=%zd (%zdbit)\n", N, N * 32); |
||||
cybozu::XorShift rg; |
||||
uint32_t x[N]; |
||||
uint32_t y[N * 2]; |
||||
for (size_t i = 0; i < 1000; i++) { |
||||
setRand(x, N, rg); |
||||
// remove MSB
|
||||
x[N - 1] &= 0x7fffffff; |
||||
mcl::Vint vx; |
||||
vx.setArray(x, N); |
||||
vx *= vx; |
||||
mcl::sqrT<N>(y, x); |
||||
CYBOZU_TEST_EQUAL_ARRAY(y, vx.getUnit(), N * 2); |
||||
} |
||||
CYBOZU_BENCH_C("sqrT", C, mcl::sqrT<N>, y, x); |
||||
} |
||||
|
||||
CYBOZU_TEST_AUTO(sqrT) |
||||
{ |
||||
sqrTest<8>(); |
||||
sqrTest<12>(); |
||||
} |
||||
|
||||
struct Montgomery { |
||||
mcl::Vint p_; |
||||
mcl::Vint R_; // (1 << (pn_ * 64)) % p
|
||||
mcl::Vint RR_; // (R * R) % p
|
||||
uint32_t rp_; // rp * p = -1 mod M = 1 << 64
|
||||
size_t pn_; |
||||
Montgomery() {} |
||||
explicit Montgomery(const mcl::Vint& p) |
||||
{ |
||||
p_ = p; |
||||
rp_ = mcl::fp::getMontgomeryCoeff(p.getUnit()[0]); |
||||
pn_ = p.getUnitSize(); |
||||
R_ = 1; |
||||
R_ = (R_ << (pn_ * 64)) % p_; |
||||
RR_ = (R_ * R_) % p_; |
||||
} |
||||
|
||||
void toMont(mcl::Vint& x) const { mul(x, x, RR_); } |
||||
void fromMont(mcl::Vint& x) const { mul(x, x, 1); } |
||||
|
||||
void mul(mcl::Vint& z, const mcl::Vint& x, const mcl::Vint& y) const |
||||
{ |
||||
const size_t ySize = y.getUnitSize(); |
||||
mcl::Vint c = x * y.getUnit()[0]; |
||||
uint32_t q = c.getUnit()[0] * rp_; |
||||
c += p_ * q; |
||||
c >>= sizeof(uint32_t) * 8; |
||||
for (size_t i = 1; i < pn_; i++) { |
||||
if (i < ySize) { |
||||
c += x * y.getUnit()[i]; |
||||
} |
||||
uint32_t q = c.getUnit()[0] * rp_; |
||||
c += p_ * q; |
||||
c >>= sizeof(uint32_t) * 8; |
||||
} |
||||
if (c >= p_) { |
||||
c -= p_; |
||||
} |
||||
z = c; |
||||
} |
||||
void mod(mcl::Vint& z, const mcl::Vint& xy) const |
||||
{ |
||||
z = xy; |
||||
for (size_t i = 0; i < pn_; i++) { |
||||
uint32_t q = z.getUnit()[0] * rp_; |
||||
mcl::Vint t = q; |
||||
z += p_ * t; |
||||
z >>= 32; |
||||
} |
||||
if (z >= p_) { |
||||
z -= p_; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
template<size_t N> |
||||
void mulMontTest(const char *pStr) |
||||
{ |
||||
mcl::Vint vp; |
||||
vp.setStr(pStr); |
||||
Montgomery mont(vp); |
||||
|
||||
cybozu::XorShift rg; |
||||
uint32_t x[N]; |
||||
uint32_t y[N]; |
||||
uint32_t z[N]; |
||||
uint32_t _p[N + 1]; |
||||
uint32_t *const p = _p + 1; |
||||
vp.getArray(p, N); |
||||
p[-1] = mont.rp_; |
||||
|
||||
for (size_t i = 0; i < 1000; i++) { |
||||
setRand(x, N, rg); |
||||
setRand(y, N, rg); |
||||
// remove MSB
|
||||
x[N - 1] &= 0x7fffffff; |
||||
y[N - 1] &= 0x7fffffff; |
||||
mcl::Vint vx, vy, vz; |
||||
vx.setArray(x, N); |
||||
vy.setArray(y, N); |
||||
mont.mul(vz, vx, vy); |
||||
mcl::mulMontT<N>(z, x, y, p); |
||||
CYBOZU_TEST_EQUAL_ARRAY(z, vz.getUnit(), N); |
||||
|
||||
mont.mul(vz, vx, vx); |
||||
mcl::sqrMontT<N>(z, x, p); |
||||
CYBOZU_TEST_EQUAL_ARRAY(z, vz.getUnit(), N); |
||||
} |
||||
CYBOZU_BENCH_C("mulMontT", C, mcl::mulMontT<N>, x, x, y, p); |
||||
CYBOZU_BENCH_C("sqrMontT", C, mcl::sqrMontT<N>, x, x, p); |
||||
} |
||||
|
||||
template<size_t N> |
||||
void modTest(const char *pStr) |
||||
{ |
||||
mcl::Vint vp; |
||||
vp.setStr(pStr); |
||||
Montgomery mont(vp); |
||||
|
||||
cybozu::XorShift rg; |
||||
uint32_t xy[N * 2]; |
||||
uint32_t z[N]; |
||||
uint32_t _p[N + 1]; |
||||
uint32_t *const p = _p + 1; |
||||
vp.getArray(p, N); |
||||
p[-1] = mont.rp_; |
||||
|
||||
for (size_t i = 0; i < 1000; i++) { |
||||
setRand(xy, N * 2, rg); |
||||
// remove MSB
|
||||
xy[N * 2 - 1] &= 0x7fffffff; |
||||
mcl::Vint vxy, vz; |
||||
vxy.setArray(xy, N * 2); |
||||
mont.mod(vz, vxy); |
||||
mcl::modT<N>(z, xy, p); |
||||
CYBOZU_TEST_EQUAL_ARRAY(z, vz.getUnit(), N); |
||||
} |
||||
CYBOZU_BENCH_C("modT", C, mcl::modT<N>, z, xy, p); |
||||
} |
||||
|
||||
CYBOZU_TEST_AUTO(mont) |
||||
{ |
||||
const char *pBN254 = "0x2523648240000001ba344d80000000086121000000000013a700000000000013"; |
||||
puts("BN254"); |
||||
mulMontTest<8>(pBN254); |
||||
modTest<8>(pBN254); |
||||
|
||||
const char *pBLS12_381 = "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"; |
||||
puts("BLS12"); |
||||
mulMontTest<12>(pBLS12_381); |
||||
modTest<12>(pBLS12_381); |
||||
} |
||||
|
@ -0,0 +1,119 @@ |
||||
P ; generator |
||||
x ; secret key |
||||
xP ; public key |
||||
Enc(m;r) = (mP + rxP, rP) |
||||
|
||||
c = (S, T) |
||||
dec(c) := S - xT |
||||
dec(Enc(m;r)) = (mP + rxP) - x(rP) = mP |
||||
DLP(mP) := m |
||||
Dec(c) := DLP(dec(c)) |
||||
|
||||
ZKP of dec(c) = m |
||||
|
||||
z := Enc(m;0) = (mP, 0) |
||||
|
||||
c - z = (rxP, rP) ; r is unknown |
||||
|
||||
ZKP of dec(c - z) = 0 |
||||
(P1, P2) := (P, rP) |
||||
(A1, A2) := (xP, xrP) |
||||
|
||||
Prover shows that x(P1, P2) = (A1, A2) without revealing x. |
||||
b ; rand |
||||
B = (b P1, b P2) |
||||
h = Hash(P2, A1, A2, B1, B2) |
||||
d = b + h a |
||||
pi = (d, h) |
||||
|
||||
Verifier |
||||
Bi := d Pi - h Ai |
||||
verify h = Hash(P2, A1, A2, B1, B2) |
||||
----------------------------------------------------------------------------- |
||||
CipherTextGT |
||||
P ; generator of GT, GT=<P> |
||||
x1, x2 ; secrect key |
||||
(P0, P1, P2, P3) := (P, x1 P, x2 P, x1 x2 P) ; public information |
||||
|
||||
CipherText c = (A0, A1, A2, A3) |
||||
dec(c) = 0 <=> A0 = x2 A1 + x1 A2 - x1 x2 A3 ; (*) |
||||
|
||||
F(a1, a2, a3) := a2 A1 + a1 A2 - a3 A3 |
||||
|
||||
dec(c) = 0 <=> A0 = F(x1, x2, x1 x2) |
||||
|
||||
Sigma-protocol for dec(c) = 0, i.e., show (*) |
||||
|
||||
Prover: |
||||
b1, b2, b3 ; rand |
||||
Bi := bi P (i = 1, 2, 3) |
||||
X := F(b1, b2, b3) |
||||
send (B1, B2, B3, X) to Verfier |
||||
|
||||
Verifier: |
||||
takes h randomly and send to Prover |
||||
|
||||
Prover: |
||||
d1 := b1 + h x1 |
||||
d2 := b2 + h x2 |
||||
d3 := b3 + h x1 x2 |
||||
send (d1, d2, d3) to Verifier |
||||
|
||||
Verifier: |
||||
verify |
||||
di P = Bi + h Pi (i = 1, 2, 3) |
||||
X = F(d1, d2, d3) - h A0 |
||||
and accept it |
||||
|
||||
Fiat-Shamir transform: |
||||
|
||||
Prover: |
||||
b1, b2, b3 ; random value |
||||
Bi := bi P (i = 1, 2, 3) |
||||
X := F(b1, b2, b3) |
||||
h := Hash(P0, ..., P3, A0, ..., A3, B1, B2, B3, X) |
||||
d1 := b1 + h x1 |
||||
d2 := b2 + h x2 |
||||
d3 := b3 + h x1 x2 |
||||
pi := (d1, d2, d3, h) |
||||
|
||||
Verifier: |
||||
(pi, {Pi}, {Ai}) given |
||||
Bi' := di P - h Pi for i = 1, 2, 3 |
||||
X' := F(d1, d2, d3) - h A0 |
||||
verify Hash({Pi}, {Ai}, {Bi'}, X') = h |
||||
|
||||
Completeness |
||||
|
||||
B1' = d1 P - h P1 = (b1 + h x1) P - h x1 P = b1 P = B1 |
||||
B2' = d2 P - h P2 = (b2 + h x2) P - h x2 P = b2 P = B2 |
||||
B3' = d3 P - h P3 = (b3 + h x1 x2) P - h x1 x2 P = B3 |
||||
X' = F(b1 + h x1, b2 + h x2, b3 + h x1 x2) - h A0 |
||||
= F(b1, b2, b3) + h F(x1, x2, x1 x2) - h A0 |
||||
= F(b1, b2, b3) + h (F(x1, x2, x1 x2) - A0) |
||||
= F(b1, b2, b3) = X |
||||
OK |
||||
|
||||
Soundness |
||||
{Ai}, pi=(d1, d2, d3, h) ; given |
||||
compute Bi', X' as above |
||||
Suppose Hash({Pi}, {Ai}, {Bi'}, X') = h |
||||
|
||||
define |
||||
b1 := d1 - h x1 |
||||
b2 := d2 - h x2 |
||||
b3 := d3 - h x1 x2 |
||||
where x1, x2 are unknown |
||||
d1, d2, d3 are free parameters, so b1, b2, b3 are also free. |
||||
|
||||
B1' = d1 P - h P1 = b1 P |
||||
B2' = b2 P |
||||
B3' = b3 P |
||||
|
||||
Y := F(x1, x2, x1 x2) - A0; unknown, but it is fixed |
||||
X' = F(d1, d2, d3) - h A0 = F(b1 + h x1, b2 + h x2, b3 + h x1 x2) - h A0 |
||||
= F(b1, b2, b3) + h(F(x1, x2, x1 x2) - A0) |
||||
= F(b1, b2, b3) + h Y |
||||
|
||||
Hash({Pi}, {Ai}, b1 P, b2 P, b3 P, F(b1, b2, b3) + h Y) = h |
||||
To found {b1, b2, b3, h} to hold this equation, Y must be 0. |
@ -0,0 +1,18 @@ |
||||
p=21888242871839275222246405745257275088696311157297823662689037894645226208583 |
||||
|
||||
print("over 253 bit") |
||||
for i in range (10): |
||||
print(i, (p * i) >> 253) |
||||
|
||||
def maxarg(x): |
||||
return x // p |
||||
|
||||
print("maxarg") |
||||
for i in range(16): |
||||
print(i, maxarg(i << 253)) |
||||
|
||||
|
||||
x=0x2c130429c1d4802eb8703197d038ebd5109f96aee333bd027963094f5bb33ad |
||||
|
||||
y = x * 9 |
||||
print(hex(y)) |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue