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) |
cmake_minimum_required (VERSION 3.8) |
||||||
project(mcl CXX ASM) |
|
||||||
set(SRCS src/fp.cpp) |
project(mcl |
||||||
|
VERSION 1.22 |
||||||
|
LANGUAGES CXX C ASM) |
||||||
|
|
||||||
|
set(CMAKE_BUILD_TYPE "Release") |
||||||
|
|
||||||
option( |
option( |
||||||
MCL_MAX_BIT_SIZE |
MCL_MAX_BIT_SIZE |
||||||
"max bit size for Fp" |
"max bit size for Fp" |
||||||
0 |
384 |
||||||
) |
) |
||||||
option( |
option( |
||||||
DOWNLOAD_SOURCE |
MCL_STATIC_LIB |
||||||
"download cybozulib_ext" |
"build static library" |
||||||
OFF |
OFF |
||||||
) |
) |
||||||
|
if(MSVC) |
||||||
|
option( |
||||||
|
MCL_DOWNLOAD_SOURCE |
||||||
|
"download cybozulib_ext" |
||||||
|
OFF |
||||||
|
) |
||||||
|
endif() |
||||||
option( |
option( |
||||||
USE_OPENSSL |
MCL_USE_OPENSSL |
||||||
"use openssl" |
"use openssl" |
||||||
ON |
OFF |
||||||
) |
) |
||||||
option( |
option( |
||||||
USE_GMP |
MCL_USE_GMP |
||||||
"use gmp" |
"use gmp" |
||||||
ON |
ON |
||||||
) |
) |
||||||
option( |
option( |
||||||
USE_ASM |
MCL_USE_ASM |
||||||
"use asm" |
"use asm" |
||||||
ON |
ON |
||||||
) |
) |
||||||
option( |
option( |
||||||
USE_XBYAK |
MCL_USE_XBYAK |
||||||
"use xbyak" |
"use xbyak" |
||||||
ON |
ON |
||||||
) |
) |
||||||
option( |
option( |
||||||
USE_LLVM |
MCL_USE_LLVM |
||||||
"use base64.ll with -DCMAKE_CXX_COMPILER=clang++" |
"use base64.ll with -DCMAKE_CXX_COMPILER=clang++" |
||||||
OFF |
OFF |
||||||
) |
) |
||||||
option( |
option( |
||||||
ONLY_LIB |
MCL_BUILD_SAMPLE |
||||||
"only lib" |
"Build mcl samples" |
||||||
OFF |
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_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) |
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) |
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) |
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) |
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_executable(gen src/gen.cpp) |
||||||
add_custom_target(base64.ll |
target_include_directories(gen PRIVATE |
||||||
DEPENDS gen |
${CMAKE_CURRENT_SOURCE_DIR}/include) |
||||||
SOURCES base64.ll |
if(MCL_USE_GMP) |
||||||
) |
find_package(GMP REQUIRED) |
||||||
|
target_link_libraries(gen PRIVATE GMP::GMPXX GMP::GMP) |
||||||
|
endif() |
||||||
|
|
||||||
add_custom_command(OUTPUT base64.ll |
add_custom_command(OUTPUT base64.ll |
||||||
COMMAND gen > base64.ll |
COMMAND gen > base64.ll |
||||||
) |
DEPENDS gen |
||||||
add_custom_target(base64.o |
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) |
||||||
DEPENDS base64.ll |
add_custom_target(gen_base64.ll |
||||||
SOURCES base64.o |
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/base64.ll) |
||||||
) |
|
||||||
add_custom_command(OUTPUT base64.o |
add_custom_command(OUTPUT base64.o |
||||||
COMMAND ${CMAKE_CXX_COMPILER} -c -o base64.o base64.ll -O3 -fPIC |
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() |
endif() |
||||||
|
|
||||||
if(MSVC) |
if(MSVC) |
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MT /W4 /Oy /Ox /EHsc /GS- /Zi /DNDEBUG /DNOMINMAX") |
if(MCL_MSVC_RUNTIME_DLL) |
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /MTd /W4 /DNOMINMAX") |
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MD /Oy /Ox /EHsc /GS- /Zi /DNDEBUG") |
||||||
link_directories(${CMAKE_SOURCE_DIR}/../cybozulib_ext/lib) |
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /MDd") |
||||||
link_directories(${CMAKE_SOURCE_DIR}/lib) |
else() |
||||||
else() |
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MT /Oy /Ox /EHsc /GS- /Zi /DNDEBUG") |
||||||
if("${CFLAGS_OPT_USER}" STREQUAL "") |
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /MTd") |
||||||
set(CFLAGS_OPT_USER "-O3 -DNDEBUG -march=native") |
|
||||||
endif() |
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) |
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() |
endif() |
||||||
|
|
||||||
if(USE_LLVM) |
if(MCL_USE_LLVM AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") |
||||||
add_definitions(-DMCL_USE_LLVM=1 -DMCL_LLVM_BMI2=0) |
target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1 MCL_LLVM_BMI2=0) |
||||||
elseif(USE_ASM) |
target_compile_definitions(mcl_st PUBLIC MCL_USE_LLVM=1 MCL_LLVM_BMI2=0) |
||||||
|
elseif(MCL_USE_ASM) |
||||||
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") |
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") |
||||||
add_definitions(-DMCL_USE_LLVM=1) |
target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) |
||||||
set(SRCS ${SRCS} src/asm/aarch64.s) |
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) |
set(CPU arch64) |
||||||
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm") |
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm") |
||||||
add_definitions(-DMCL_USE_LLVM=1) |
target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) |
||||||
set(SRCS ${SRCS} src/asm/arm.s) |
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) |
set(CPU arm) |
||||||
elseif(APPLE) |
elseif(APPLE) |
||||||
add_definitions(-DMCL_USE_LLVM=1) |
target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) |
||||||
set(SRCS ${SRCS} src/asm/x86-64mac.s src/asm/x86-64mac.bmi2.s) |
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) |
set(CPU x86-64) |
||||||
elseif(UNIX) |
elseif(UNIX) |
||||||
add_definitions(-DMCL_USE_LLVM=1) |
target_compile_definitions(mcl PUBLIC MCL_USE_LLVM=1) |
||||||
set(SRCS ${SRCS} src/asm/x86-64.s src/asm/x86-64.bmi2.s) |
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) |
set(CPU x86-64) |
||||||
endif() |
endif() |
||||||
endif() |
endif() |
||||||
if(USE_GMP) |
if(MCL_USE_GMP) |
||||||
set(EXT_LIBS ${EXT_LIBS} gmp gmpxx) |
find_package(GMP REQUIRED) |
||||||
|
target_link_libraries(mcl PUBLIC GMP::GMPXX GMP::GMP) |
||||||
|
target_link_libraries(mcl_st PUBLIC GMP::GMPXX GMP::GMP) |
||||||
endif() |
endif() |
||||||
if(USE_OPENSSL) |
if(MCL_USE_OPENSSL) |
||||||
set(EXT_LIBS ${EXT_LIBS} crypto) |
find_package(OpenSSL REQUIRED) |
||||||
|
target_link_libraries(mcl PUBLIC OpenSSL::Crypto) |
||||||
|
target_link_libraries(mcl_st PUBLIC OpenSSL::Crypto) |
||||||
endif() |
endif() |
||||||
endif() |
endif() |
||||||
|
|
||||||
if(NOT USE_GMP) |
if(NOT MCL_USE_GMP) |
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMCL_USE_VINT -DMCL_VINT_FIXED_BUFFER") |
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() |
endif() |
||||||
if(NOT USE_OPENSSL) |
if(NOT MCL_USE_OPENSSL) |
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMCL_DONT_USE_OPENSSL") |
target_compile_definitions(mcl PUBLIC MCL_DONT_USE_OPENSSL) |
||||||
|
target_compile_definitions(mcl_st PUBLIC MCL_DONT_USE_OPENSSL) |
||||||
endif() |
endif() |
||||||
if(NOT USE_XBYAK) |
if(NOT MCL_USE_XBYAK) |
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMCL_DONT_USE_XBYAK") |
target_compile_definitions(mcl PUBLIC MCL_DONT_USE_XBYAK) |
||||||
|
target_compile_definitions(mcl_st PUBLIC MCL_DONT_USE_XBYAK) |
||||||
endif() |
endif() |
||||||
|
|
||||||
if(DOWNLOAD_SOURCE) |
if(MCL_DOWNLOAD_SOURCE) |
||||||
if(MSVC) |
if(MSVC) |
||||||
|
set(CYBOZULIB_EXT_DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/cybozulib_ext) |
||||||
set(CYBOZULIB_EXT_TAG release20170521) |
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) |
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}) |
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}) |
message("download cybozulib_ext/" ${file}) |
||||||
endforeach() |
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) |
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}) |
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}) |
message("download cybozulib_ext/openssl/" ${file}) |
||||||
endforeach() |
endforeach() |
||||||
set(FILES mpir.lib mpirxx.lib mpirxx.pdb ssleay32.lib libeay32.lib mpir.pdb) |
set(FILES mpir.lib mpirxx.lib mpirxx.pdb ssleay32.lib libeay32.lib mpir.pdb) |
||||||
foreach(file IN ITEMS ${FILES}) |
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}) |
message("download lib/mt/14/" ${file}) |
||||||
endforeach() |
endforeach() |
||||||
if(MSVC) |
|
||||||
include_directories( |
# mpir |
||||||
${mcl_SOURCE_DIR}/include/cybozulib_ext |
add_library(cybozulib_ext::mpir STATIC IMPORTED) |
||||||
) |
set_target_properties(cybozulib_ext::mpir PROPERTIES |
||||||
endif() |
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() |
endif() |
||||||
else() |
else() |
||||||
if(MSVC) |
if(MSVC) |
||||||
include_directories( |
# mpir |
||||||
${mcl_SOURCE_DIR}/../cybozulib_ext/include |
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() |
||||||
endif() |
endif() |
||||||
|
|
||||||
include_directories( |
# mclbnXXX |
||||||
${mcl_SOURCE_DIR}/include |
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) |
if(MSVC) |
||||||
add_library(mcl SHARED ${SRCS} base64.o) |
install(TARGETS mcl mcl_st mclbn256 mclbn384 mclbn384_256 windows_specific |
||||||
add_library(mcl_st STATIC ${SRCS} base64.o) |
EXPORT mclTargets |
||||||
add_dependencies(mcl base64.o) |
LIBRARY DESTINATION lib |
||||||
add_dependencies(mcl_st base64.o) |
ARCHIVE DESTINATION lib |
||||||
|
RUNTIME DESTINATION lib) |
||||||
else() |
else() |
||||||
add_library(mcl SHARED ${SRCS}) |
install(TARGETS mcl mcl_st mclbn256 mclbn384 mclbn384_256 |
||||||
add_library(mcl_st STATIC ${SRCS}) |
EXPORT mclTargets |
||||||
|
LIBRARY DESTINATION lib |
||||||
|
ARCHIVE DESTINATION lib |
||||||
|
RUNTIME DESTINATION lib) |
||||||
endif() |
endif() |
||||||
target_link_libraries(mcl ${EXT_LIBS}) |
install(DIRECTORY include/mcl |
||||||
target_link_libraries(mcl_st ${EXT_LIBS}) |
DESTINATION include |
||||||
set_target_properties(mcl_st PROPERTIES OUTPUT_NAME mcl) |
FILES_MATCHING PATTERN "*.hpp" |
||||||
#set_target_properties(mcl_st PROPERTIES PREFIX "lib") |
PATTERN "curve_type.h" |
||||||
#set_target_properties(mcl PROPERTIES OUTPUT_NAME mcl VERSION 1.0.0 SOVERSION 1) |
PATTERN "bn.h" |
||||||
# For semantics of ABI compatibility including when you must bump SOVERSION, see: |
PATTERN "bn_c256.h" |
||||||
# https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B#The_Do.27s_and_Don.27ts |
PATTERN "bn_c384_256.h" |
||||||
|
PATTERN "bn_c384.h") |
||||||
|
install(DIRECTORY include/cybozu |
||||||
|
DESTINATION include |
||||||
|
FILES_MATCHING PATTERN "*.hpp") |
||||||
|
|
||||||
set(LIBS mcl ${EXT_LIBS}) |
install(EXPORT mclTargets |
||||||
foreach(bit IN ITEMS 256 384 384_256 512) |
FILE mclTargets.cmake |
||||||
add_library(mclbn${bit} SHARED src/bn_c${bit}.cpp) |
NAMESPACE mcl:: |
||||||
target_link_libraries(mclbn${bit} ${LIBS}) |
DESTINATION lib/cmake/mcl) |
||||||
add_executable(bn_c${bit}_test test/bn_c${bit}_test.cpp) |
|
||||||
target_link_libraries(bn_c${bit}_test mclbn${bit}) |
|
||||||
endforeach() |
|
||||||
|
|
||||||
file(GLOB MCL_HEADERS include/mcl/*.hpp include/mcl/bn.h include/mcl/curve_type.h) |
# support local build-tree export to allow import from external projects |
||||||
file(GLOB CYBOZULIB_HEADERS include/cybozu/*.hpp) |
export(EXPORT mclTargets |
||||||
|
FILE mclTargets.cmake |
||||||
install(TARGETS mcl DESTINATION lib) |
NAMESPACE mcl::) |
||||||
install(TARGETS mcl_st DESTINATION lib) |
set(CMAKE_EXPORT_PACKAGE_REGISTRY ON) |
||||||
install(TARGETS mclbn256 DESTINATION lib) |
export(PACKAGE mcl) |
||||||
install(TARGETS mclbn384 DESTINATION lib) |
|
||||||
install(TARGETS mclbn384_256 DESTINATION lib) |
|
||||||
install(TARGETS mclbn512 DESTINATION lib) |
# Tests |
||||||
install(FILES ${MCL_HEADERS} DESTINATION include/mcl) |
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR MCL_BUILD_TESTING) |
||||||
install(FILES include/mcl/impl/bn_c_impl.hpp DESTINATION include/mcl/impl) |
AND BUILD_TESTING) |
||||||
install(FILES ${CYBOZULIB_HEADERS} DESTINATION include/cybozu) |
enable_testing() |
||||||
|
add_subdirectory(test) |
||||||
if(NOT ONLY_LIB) |
endif() |
||||||
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) |
if(MCL_BUILD_SAMPLE) |
||||||
foreach(base IN ITEMS ${TEST_BASE}) |
# sample code |
||||||
add_executable( |
add_subdirectory(sample) |
||||||
${base} |
|
||||||
test/${base}.cpp |
|
||||||
) |
|
||||||
target_link_libraries( |
|
||||||
${base} |
|
||||||
${LIBS} |
|
||||||
) |
|
||||||
endforeach() |
|
||||||
endif() |
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